From 156600bff2381f723c029a1707a043dfed56c43d Mon Sep 17 00:00:00 2001 From: Matthieu Schaller <schaller@strw.leidenuniv.nl> Date: Thu, 5 Oct 2023 14:34:48 +0000 Subject: [PATCH] Add forcing terms to the hydro equations --- configure.ac | 25 +++ examples/parameter_example.yml | 13 ++ src/Makefile.am | 3 + src/engine.c | 10 ++ src/engine.h | 5 + src/forcing.c | 51 ++++++ src/forcing.h | 45 +++++ src/forcing/none/forcing.h | 109 ++++++++++++ src/forcing/roberts_flow/forcing.h | 136 +++++++++++++++ .../roberts_flow_acceleration/forcing.h | 157 ++++++++++++++++++ src/runner_others.c | 7 + src/swift.h | 1 + src/timestep.h | 9 +- swift.c | 12 +- swift_fof.c | 1 + 15 files changed, 579 insertions(+), 5 deletions(-) create mode 100644 src/forcing.c create mode 100644 src/forcing.h create mode 100644 src/forcing/none/forcing.h create mode 100644 src/forcing/roberts_flow/forcing.h create mode 100644 src/forcing/roberts_flow_acceleration/forcing.h diff --git a/configure.ac b/configure.ac index 136d607645..0eac6e9da2 100644 --- a/configure.ac +++ b/configure.ac @@ -2621,6 +2621,30 @@ case "$with_sink" in ;; esac +# Forcing terms +AC_ARG_WITH([forcing], + [AS_HELP_STRING([--with-forcing=<term>], + [Hydrodynamics forcing terms @<:@none, roberts-flow, roberts-flow-acceleration default: none@:>@] + )], + [with_forcing="$withval"], + [with_forcing="none"] +) +case "$with_forcing" in + none) + AC_DEFINE([FORCING_NONE], [1], [No external forcing terms]) + ;; + roberts-flow) + AC_DEFINE([FORCING_ROBERTS_FLOW], [1], [Roberts' flow external forcing terms]) + ;; + roberts-flow-acceleration) + AC_DEFINE([FORCING_ROBERTS_FLOW_ACCELERATION], [1], [Roberts' flow external forcing terms entering the equations as an acceleration term]) + ;; + *) + AC_MSG_ERROR([Unknown external forcing term: $with_forcing]) + ;; +esac + + # External potential AC_ARG_WITH([ext-potential], [AS_HELP_STRING([--with-ext-potential=<pot>], @@ -3041,6 +3065,7 @@ AC_MSG_RESULT([ No gravity below ID : $no_gravity_below_id Make gravity glass : $gravity_glass_making External potential : $with_potential + Forcing terms : $with_forcing Pressure floor : $with_pressure_floor Entropy floor : $with_entropy_floor diff --git a/examples/parameter_example.yml b/examples/parameter_example.yml index 0e5cac61fc..5e1cdcd036 100644 --- a/examples/parameter_example.yml +++ b/examples/parameter_example.yml @@ -438,6 +438,19 @@ MWPotential2014Potential: r_c_kpc: 1.9 # Cut-off radius of the bulge (in kpc) potential_factors: [0.4367419745056084, 1.002641971008805, 0.022264787598364262] # Coefficients that adjust the strength of the halo (1st component), the disk (2nd component) and the bulge (3rd component) +# Parameters related to forcing terms ---------------------------------------------- + +# Roberts' flow (Tilgner & Brandenburg, 2008, MNRAS, 391, 1477) where the velocity is imposed +RobertsFlowForcing: + u0: 1.5 # Forcing velocity (internal units) + Vz_factor: 1.0 # (optional) Scaling of the velocity along the z axis + +# Roberts' flow (Tilgner & Brandenburg, 2008, MNRAS, 391, 1477) where the forcing is an acceleration +RobertsFlowAccelerationForcing: + u0: 1.5 # Forcing velocity (internal units) + nu: 1.0 # Viscosity (internal units) to convert velocities to accelerations. + Vz_factor: 1.0 # (optional) Scaling of the velocity along the z axis + # Parameters related to entropy floors ---------------------------------------------- EAGLEEntropyFloor: diff --git a/src/Makefile.am b/src/Makefile.am index b0ad938f55..ac7ea7da7f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -74,6 +74,7 @@ include_HEADERS += lightcone/lightcone.h lightcone/lightcone_particle_io.h light include_HEADERS += lightcone/lightcone_crossing.h lightcone/lightcone_array.h lightcone/lightcone_map.h include_HEADERS += lightcone/lightcone_map_types.h lightcone/projected_kernel.h lightcone/lightcone_shell.h include_HEADERS += lightcone/healpix_util.h lightcone/pixel_index.h +include_HEADERS += forcing.h include_HEADERS += power_spectrum.h include_HEADERS += ghost_stats.h @@ -186,6 +187,7 @@ AM_SOURCES += lightcone/lightcone.c lightcone/lightcone_particle_io.c lightcone/ AM_SOURCES += lightcone/healpix_util.c lightcone/lightcone_array.c lightcone/lightcone_map.c AM_SOURCES += lightcone/lightcone_map_types.c lightcone/projected_kernel.c lightcone/lightcone_shell.c AM_SOURCES += power_spectrum.c +AM_SOURCES += forcing.c AM_SOURCES += ghost_stats.c AM_SOURCES += $(EAGLE_EXTRA_IO_SOURCES) AM_SOURCES += $(QLA_COOLING_SOURCES) $(QLA_EAGLE_COOLING_SOURCES) @@ -363,6 +365,7 @@ nobase_noinst_HEADERS += stars/EAGLE/stars.h stars/EAGLE/stars_iact.h stars/EAGL nobase_noinst_HEADERS += stars/EAGLE/stars_debug.h stars/EAGLE/stars_part.h nobase_noinst_HEADERS += stars/GEAR/stars.h stars/GEAR/stars_iact.h stars/GEAR/stars_io.h nobase_noinst_HEADERS += stars/GEAR/stars_debug.h stars/GEAR/stars_csds.h stars/GEAR/stars_part.h +nobase_noinst_HEADERS += forcing/none/forcing.h forcing/roberts_flow/forcing.h forcing/roberts_flow_acceleration/forcing.h nobase_noinst_HEADERS += potential/none/potential.h potential/point_mass/potential.h nobase_noinst_HEADERS += potential/isothermal/potential.h potential/disc_patch/potential.h nobase_noinst_HEADERS += potential/sine_wave/potential.h potential/constant/potential.h diff --git a/src/engine.c b/src/engine.c index 0873b83322..b545fd66d1 100644 --- a/src/engine.c +++ b/src/engine.c @@ -70,6 +70,7 @@ #include "extra_io.h" #include "feedback.h" #include "fof.h" +#include "forcing.h" #include "gravity.h" #include "gravity_cache.h" #include "hydro.h" @@ -3065,6 +3066,7 @@ void engine_init( struct pressure_floor_props *pressure_floor, struct rt_props *rt, struct pm_mesh *mesh, struct power_spectrum_data *pow_data, const struct external_potential *potential, + const struct forcing_terms *forcing_terms, struct cooling_function_data *cooling_func, const struct star_formation *starform, const struct chemistry_global_data *chemistry, @@ -3205,6 +3207,7 @@ void engine_init( e->mesh = mesh; e->power_data = pow_data; e->external_potential = potential; + e->forcing_terms = forcing_terms; e->cooling_func = cooling_func; e->star_formation = starform; e->feedback_props = feedback; @@ -3644,6 +3647,7 @@ void engine_clean(struct engine *e, const int fof, const int restart) { free((void *)e->parameter_file); free((void *)e->output_options); free((void *)e->external_potential); + free((void *)e->forcing_terms); free((void *)e->black_holes_properties); free((void *)e->pressure_floor_props); free((void *)e->rt_props); @@ -3718,6 +3722,7 @@ void engine_struct_dump(struct engine *e, FILE *stream) { pm_mesh_struct_dump(e->mesh, stream); power_spectrum_struct_dump(e->power_data, stream); potential_struct_dump(e->external_potential, stream); + forcing_terms_struct_dump(e->forcing_terms, stream); cooling_struct_dump(e->cooling_func, stream); starformation_struct_dump(e->star_formation, stream); feedback_struct_dump(e->feedback_props, stream); @@ -3833,6 +3838,11 @@ void engine_struct_restore(struct engine *e, FILE *stream) { potential_struct_restore(external_potential, stream); e->external_potential = external_potential; + struct forcing_terms *forcing_terms = + (struct forcing_terms *)malloc(sizeof(struct forcing_terms)); + forcing_terms_struct_restore(forcing_terms, stream); + e->forcing_terms = forcing_terms; + struct cooling_function_data *cooling_func = (struct cooling_function_data *)malloc( sizeof(struct cooling_function_data)); diff --git a/src/engine.h b/src/engine.h index 11394dca3e..2760fc4c23 100644 --- a/src/engine.h +++ b/src/engine.h @@ -54,6 +54,7 @@ struct black_holes_properties; struct extra_io_properties; struct external_potential; +struct forcing_terms; /** * @brief The different policies the #engine can follow. @@ -536,6 +537,9 @@ struct engine { /* Properties of external gravitational potential */ const struct external_potential *external_potential; + /* Properties of the hydrodynamics forcing terms */ + const struct forcing_terms *forcing_terms; + /* Properties of the cooling scheme */ struct cooling_function_data *cooling_func; @@ -713,6 +717,7 @@ void engine_init( struct pressure_floor_props *pressure_floor, struct rt_props *rt, struct pm_mesh *mesh, struct power_spectrum_data *pow_data, const struct external_potential *potential, + const struct forcing_terms *forcing_terms, struct cooling_function_data *cooling_func, const struct star_formation *starform, const struct chemistry_global_data *chemistry, diff --git a/src/forcing.c b/src/forcing.c new file mode 100644 index 0000000000..2a1cfbea97 --- /dev/null +++ b/src/forcing.c @@ -0,0 +1,51 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2023 Matthieu Schaller (schaller@strw.leidenuniv.nl) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ + +/* Config parameters. */ +#include <config.h> + +/* This object's header. */ +#include "forcing.h" +#include "restart.h" + +/** + * @brief Write an forcing_terms struct to the given FILE as a stream of + * bytes. + * + * @param terms the struct + * @param stream the file stream + */ +void forcing_terms_struct_dump(const struct forcing_terms* terms, + FILE* stream) { + restart_write_blocks((void*)terms, sizeof(struct forcing_terms), 1, stream, + "forcingterms", "forcing terms"); +} + +/** + * @brief Restore a forcing_terms struct from the given FILE as a stream of + * bytes. + * + * @param terms the struct + * @param stream the file stream + */ +void forcing_terms_struct_restore(const struct forcing_terms* terms, + FILE* stream) { + restart_read_blocks((void*)terms, sizeof(struct forcing_terms), 1, stream, + NULL, "forcing terms"); +} diff --git a/src/forcing.h b/src/forcing.h new file mode 100644 index 0000000000..8b1d748658 --- /dev/null +++ b/src/forcing.h @@ -0,0 +1,45 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2023 Matthieu Schaller (schaller@strw.leidenuniv.nl) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_FORCING_H +#define SWIFT_FORCING_H + +/** + * @file src/potential.h + * @brief Branches between the different external gravitational potentials. + */ + +/* Config parameters. */ +#include <config.h> + +/* Import the right external potential definition */ +#if defined(FORCING_NONE) +#include "./forcing/none/forcing.h" +#elif defined(FORCING_ROBERTS_FLOW) +#include "./forcing/roberts_flow/forcing.h" +#elif defined(FORCING_ROBERTS_FLOW_ACCELERATION) +#include "./forcing/roberts_flow_acceleration/forcing.h" +#else +#error "Invalid choice of forcing terms" +#endif + +void forcing_terms_struct_dump(const struct forcing_terms* terms, FILE* stream); +void forcing_terms_struct_restore(const struct forcing_terms* terms, + FILE* stream); + +#endif /* SWIFT_FORCING_H */ diff --git a/src/forcing/none/forcing.h b/src/forcing/none/forcing.h new file mode 100644 index 0000000000..52b811ae90 --- /dev/null +++ b/src/forcing/none/forcing.h @@ -0,0 +1,109 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2023 Matthieu Schaller (schaller@strw.leidenuniv.nl) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_FORCING_NONE_H +#define SWIFT_FORCING_NONE_H + +/* Config parameters. */ +#include <config.h> + +/* Standard includes. */ +#include <float.h> + +/* Local includes. */ +#include "error.h" +#include "parser.h" +#include "part.h" +#include "physical_constants.h" +#include "space.h" +#include "units.h" + +/** + * @brief Forcing Term Properties + */ +struct forcing_terms {}; + +/** + * @brief Computes the forcing terms. + * + * We do nothing in this 'none' scheme. + * + * @param time The current time. + * @param terms The properties of the forcing terms. + * @param s The #space we act on. + * @param phys_const The physical constants in internal units. + * @param p Pointer to the particle data. + * @param xp Pointer to the extended particle data. + */ +__attribute__((always_inline)) INLINE static void forcing_terms_apply( + const double time, const struct forcing_terms* terms, const struct space* s, + const struct phys_const* phys_const, struct part* p, struct xpart* xp) { + /* Nothing to do here */ +} + +/** + * @brief Computes the time-step condition due to the forcing terms. + * + * Nothing to do here. --> Return FLT_MAX. + * + * @param time The current time. + * @param terms The properties of the forcing terms. + * @param phys_const The physical constants in internal units. + * @param p Pointer to the particle data. + * @param xp Pointer to the extended particle data. + */ +__attribute__((always_inline)) INLINE static float forcing_terms_timestep( + double time, const struct forcing_terms* terms, + const struct phys_const* phys_const, const struct part* p, + const struct xpart* xp) { + + /* No time-step size limit */ + return FLT_MAX; +} + +/** + * @brief Prints the properties of the forcing terms to stdout. + * + * @param terms The #forcing_terms properties of the run. + */ +static INLINE void forcing_terms_print(const struct forcing_terms* terms) { + + message("Forcing terms is 'No forcing terms'."); +} + +/** + * @brief Initialises the forcing term properties + * + * Nothing to do here. + * + * @param parameter_file The parsed parameter file + * @param phys_const Physical constants in internal units + * @param us The current internal system of units + * @param s The #space object. + * @param terms The forcing term properties to initialize + */ +static INLINE void forcing_terms_init(struct swift_params* parameter_file, + const struct phys_const* phys_const, + const struct unit_system* us, + const struct space* s, + struct forcing_terms* terms) { + + /* Nothing to do here */ +} + +#endif /* SWIFT_FORCING_NONE_H */ diff --git a/src/forcing/roberts_flow/forcing.h b/src/forcing/roberts_flow/forcing.h new file mode 100644 index 0000000000..5c8f38e147 --- /dev/null +++ b/src/forcing/roberts_flow/forcing.h @@ -0,0 +1,136 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2023 Matthieu Schaller (schaller@strw.leidenuniv.nl) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_FORCING_ROBERTS_FLOW_H +#define SWIFT_FORCING_ROBERTS_FLOW_H + +/* Config parameters. */ +#include <config.h> + +/* Standard includes. */ +#include <float.h> + +/* Local includes. */ +#include "error.h" +#include "parser.h" +#include "part.h" +#include "physical_constants.h" +#include "space.h" +#include "units.h" + +/** + * @brief Forcing Term Properties + */ +struct forcing_terms { + + /*! Reference velocity (internal units) */ + float u0; + + /*! Velocity scaling along the z direction */ + float Vz_factor; +}; + +/** + * @brief Computes the forcing terms. + * + * Based on Tilgner & Brandenburg, 2008, MNRAS, 391, 1477. + * This version differs from the paper by imposing the velocity directly rather + * than by giving the particles an acceleration. + * + * @param time The current time. + * @param terms The properties of the forcing terms. + * @param s The #space we act on. + * @param phys_const The physical constants in internal units. + * @param p Pointer to the particle data. + * @param xp Pointer to the extended particle data. + */ +__attribute__((always_inline)) INLINE static void forcing_terms_apply( + const double time, const struct forcing_terms* terms, const struct space* s, + const struct phys_const* phys_const, struct part* p, struct xpart* xp) { + + const double L = s->dim[0]; + const float u0 = terms->u0; + const float Vz_factor = terms->Vz_factor; + const double k0 = 2. * M_PI / L; + const double kf = M_SQRT2 * k0; + + /* Eq. 8 of Tilgner & Brandenburg, 2008, MNRAS, 391, 1477 */ + const double Psi = (u0 / k0) * cos(k0 * p->x[0]) * cos(k0 * p->x[1]); + + /* Eq. 7 of Tilgner & Brandenburg, 2008, MNRAS, 391, 1477 */ + const double v_Rob[3] = {u0 * cos(k0 * p->x[0]) * sin(k0 * p->x[1]), + -u0 * sin(k0 * p->x[0]) * cos(k0 * p->x[1]), + kf * Psi}; + + /* Force the velocity and possibly scale the z-direction */ + xp->v_full[0] = v_Rob[0]; + xp->v_full[1] = v_Rob[1]; + xp->v_full[2] = v_Rob[2] * Vz_factor; +} + +/** + * @brief Computes the time-step condition due to the forcing terms. + * + * Nothing to do here. --> Return FLT_MAX. + * + * @param time The current time. + * @param terms The properties of the forcing terms. + * @param phys_const The physical constants in internal units. + * @param p Pointer to the particle data. + * @param xp Pointer to the extended particle data. + */ +__attribute__((always_inline)) INLINE static float forcing_terms_timestep( + double time, const struct forcing_terms* terms, + const struct phys_const* phys_const, const struct part* p, + const struct xpart* xp) { + + return FLT_MAX; +} + +/** + * @brief Prints the properties of the forcing terms to stdout. + * + * @param terms The #forcing_terms properties of the run. + */ +static INLINE void forcing_terms_print(const struct forcing_terms* terms) { + + message("Forcing terms is 'Roberts flow'. U0: %.5f / Vz factor: %.5f.", + terms->u0, terms->Vz_factor); +} + +/** + * @brief Initialises the forcing term properties + * + * @param parameter_file The parsed parameter file + * @param phys_const Physical constants in internal units + * @param us The current internal system of units + * @param s The #space object. + * @param terms The forcing term properties to initialize + */ +static INLINE void forcing_terms_init(struct swift_params* parameter_file, + const struct phys_const* phys_const, + const struct unit_system* us, + const struct space* s, + struct forcing_terms* terms) { + + terms->u0 = parser_get_param_double(parameter_file, "RobertsFlowForcing:u0"); + terms->Vz_factor = parser_get_opt_param_float( + parameter_file, "RobertsFlowForcing:Vz_factor", 1.f); +} + +#endif /* SWIFT_FORCING_ROBERTS_FLOW_H */ diff --git a/src/forcing/roberts_flow_acceleration/forcing.h b/src/forcing/roberts_flow_acceleration/forcing.h new file mode 100644 index 0000000000..9a9d33d3c8 --- /dev/null +++ b/src/forcing/roberts_flow_acceleration/forcing.h @@ -0,0 +1,157 @@ +/******************************************************************************* + * This file is part of SWIFT. + * Copyright (c) 2023 Matthieu Schaller (schaller@strw.leidenuniv.nl) + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + ******************************************************************************/ +#ifndef SWIFT_FORCING_ROBERTS_FLOW_ACCELERATION_H +#define SWIFT_FORCING_ROBERTS_FLOW_ACCELERATION_H + +/* Config parameters. */ +#include <config.h> + +/* Standard includes. */ +#include <float.h> + +/* Local includes. */ +#include "error.h" +#include "hydro.h" +#include "parser.h" +#include "part.h" +#include "physical_constants.h" +#include "space.h" +#include "units.h" + +/** + * @brief Forcing Term Properties + */ +struct forcing_terms { + + /*! Reference velocity (internal units) */ + float u0; + + /*! 'viscosity' to convert from velocity to acceleration (internal units) */ + float nu; + + /*! Velocity scaling along the z direction */ + float Vz_factor; +}; + +/** + * @brief Computes the forcing terms. + * + * Based on Tilgner & Brandenburg, 2008, MNRAS, 391, 1477 + * + * @param time The current time. + * @param terms The properties of the forcing terms. + * @param s The #space we act on. + * @param phys_const The physical constants in internal units. + * @param p Pointer to the particle data. + * @param xp Pointer to the extended particle data. + */ +__attribute__((always_inline)) INLINE static void forcing_terms_apply( + const double time, const struct forcing_terms* terms, const struct space* s, + const struct phys_const* phys_const, struct part* p, struct xpart* xp) { + + const float v_sig = hydro_get_signal_velocity(p); + const double L = s->dim[0]; + const float u0 = terms->u0; + const float nu = terms->nu * p->viscosity.alpha * v_sig * p->h; + const float Vz_factor = terms->Vz_factor; + const double k0 = 2. * M_PI / L; + const double kf = M_SQRT2 * k0; + + /* Eq. 8 of Tilgner & Brandenburg, 2008, MNRAS, 391, 1477 */ + const double Psi = (u0 / k0) * cos(k0 * p->x[0]) * cos(k0 * p->x[1]); + + /* Eq. 7 of Tilgner & Brandenburg, 2008, MNRAS, 391, 1477 + * (with optional scaling along z) */ + const double v_Rob[3] = {u0 * cos(k0 * p->x[0]) * sin(k0 * p->x[1]), + -u0 * sin(k0 * p->x[0]) * cos(k0 * p->x[1]), + kf * Psi * Vz_factor}; + + /* Eq. 6 of Tilgner & Brandenburg, 2008, MNRAS, 391, 1477 */ + const double f[3] = {nu * kf * kf * v_Rob[0], nu * kf * kf * v_Rob[1], + nu * kf * kf * v_Rob[2]}; + + /* Update the accelerations */ + p->a_hydro[0] += f[0]; + p->a_hydro[1] += f[1]; + p->a_hydro[2] += f[2]; + + if (time == 0.f) { + /* Force the velocity */ + xp->v_full[0] = v_Rob[0]; + xp->v_full[1] = v_Rob[1]; + xp->v_full[2] = v_Rob[2]; + } +} + +/** + * @brief Computes the time-step condition due to the forcing terms. + * + * Nothing to do here. --> Return FLT_MAX. + * + * @param time The current time. + * @param terms The properties of the forcing terms. + * @param phys_const The physical constants in internal units. + * @param p Pointer to the particle data. + * @param xp Pointer to the extended particle data. + */ +__attribute__((always_inline)) INLINE static float forcing_terms_timestep( + double time, const struct forcing_terms* terms, + const struct phys_const* phys_const, const struct part* p, + const struct xpart* xp) { + + return FLT_MAX; +} + +/** + * @brief Prints the properties of the forcing terms to stdout. + * + * @param terms The #forcing_terms properties of the run. + */ +static INLINE void forcing_terms_print(const struct forcing_terms* terms) { + + message( + "Forcing terms is 'Roberts flow using accelerations'. U0: %.5f. nu: " + "%.5f. Vz factor: %.5f.", + terms->u0, terms->nu, terms->Vz_factor); +} + +/** + * @brief Initialises the forcing term properties + * + * @param parameter_file The parsed parameter file + * @param phys_const Physical constants in internal units + * @param us The current internal system of units + * @param s The #space object. + * @param terms The forcing term properties to initialize + */ +static INLINE void forcing_terms_init(struct swift_params* parameter_file, + const struct phys_const* phys_const, + const struct unit_system* us, + const struct space* s, + struct forcing_terms* terms) { + + terms->u0 = parser_get_param_double(parameter_file, + "RobertsFlowAccelerationForcing:u0"); + terms->nu = parser_get_param_double(parameter_file, + "RobertsFlowAccelerationForcing:nu"); + terms->Vz_factor = parser_get_opt_param_float( + parameter_file, "RobertsFlowAccelerationForcing:Vz_factor", 1.f); +} + +#endif /* SWIFT_FORCING_ROBERTS_FLOW_ACCELERATION_H */ diff --git a/src/runner_others.c b/src/runner_others.c index 2112a7a2b4..c70bc0ccb5 100644 --- a/src/runner_others.c +++ b/src/runner_others.c @@ -48,6 +48,7 @@ #include "error.h" #include "feedback.h" #include "fof.h" +#include "forcing.h" #include "gravity.h" #include "hydro.h" #include "potential.h" @@ -634,12 +635,14 @@ void runner_do_end_hydro_force(struct runner *r, struct cell *c, int timer) { const struct cosmology *cosmo = e->cosmology; const int count = c->hydro.count; struct part *restrict parts = c->hydro.parts; + struct xpart *restrict xparts = c->hydro.xparts; /* Loop over the gas particles in this cell. */ for (int k = 0; k < count; k++) { /* Get a handle on the part. */ struct part *restrict p = &parts[k]; + struct xpart *restrict xp = &xparts[k]; double dt = 0; if (part_is_active(p, e)) { @@ -661,6 +664,10 @@ void runner_do_end_hydro_force(struct runner *r, struct cell *c, int timer) { timestep_limiter_end_force(p); chemistry_end_force(p, cosmo, with_cosmology, e->time, dt); + /* Apply the forcing terms (if any) */ + forcing_terms_apply(e->time, e->forcing_terms, e->s, + e->physical_constants, p, xp); + #ifdef SWIFT_BOUNDARY_PARTICLES /* Get the ID of the part */ diff --git a/src/swift.h b/src/swift.h index 9cee769a6e..d0dc2e890f 100644 --- a/src/swift.h +++ b/src/swift.h @@ -46,6 +46,7 @@ #include "feedback.h" #include "feedback_properties.h" #include "fof.h" +#include "forcing.h" #include "gravity.h" #include "gravity_derivatives.h" #include "gravity_properties.h" diff --git a/src/timestep.h b/src/timestep.h index 851befc3b5..a77a2ebdc4 100644 --- a/src/timestep.h +++ b/src/timestep.h @@ -25,6 +25,7 @@ /* Local headers. */ #include "cooling.h" #include "debug.h" +#include "forcing.h" #include "potential.h" #include "rt.h" #include "timeline.h" @@ -173,14 +174,18 @@ __attribute__((always_inline)) INLINE static integertime_t get_part_timestep( new_dt_grav = min(new_dt_self_grav, new_dt_ext_grav); } + /* Compute the next timestep (forcing terms condition) */ + const float new_dt_forcing = forcing_terms_timestep( + e->time, e->forcing_terms, e->physical_constants, p, xp); + /* Compute the next timestep (chemistry condition, e.g. diffusion) */ const float new_dt_chemistry = chemistry_timestep(e->physical_constants, e->cosmology, e->internal_units, e->hydro_properties, e->chemistry, p); /* Take the minimum of all */ - float new_dt = min5(new_dt_hydro, new_dt_cooling, new_dt_grav, new_dt_mhd, - new_dt_chemistry); + float new_dt = min3(new_dt_hydro, new_dt_cooling, new_dt_grav); + new_dt = min4(new_dt, new_dt_mhd, new_dt_chemistry, new_dt_forcing); /* Limit change in smoothing length */ const float dt_h_change = diff --git a/swift.c b/swift.c index f877b0b16f..4507ac055c 100644 --- a/swift.c +++ b/swift.c @@ -90,6 +90,7 @@ int main(int argc, char *argv[]) { struct cooling_function_data cooling_func; struct cosmology cosmo; struct external_potential potential; + struct forcing_terms forcing_terms; struct extra_io_properties extra_io_props; struct star_formation starform; struct pm_mesh mesh; @@ -1416,6 +1417,11 @@ int main(int argc, char *argv[]) { potential_init(params, &prog_const, &us, &s, &potential); if (myrank == 0) potential_print(&potential); + /* Initialise the forcing terms */ + bzero(&forcing_terms, sizeof(struct forcing_terms)); + forcing_terms_init(params, &prog_const, &us, &s, &forcing_terms); + if (myrank == 0) forcing_terms_print(&forcing_terms); + /* Initialise the long-range gravity mesh */ if (with_self_gravity && periodic) { #ifdef HAVE_FFTW @@ -1534,9 +1540,9 @@ int main(int argc, char *argv[]) { &gravity_properties, &stars_properties, &black_holes_properties, &sink_properties, &neutrino_properties, &neutrino_response, &feedback_properties, &pressure_floor_props, &rt_properties, - &mesh, &pow_data, &potential, &cooling_func, &starform, - &chemistry, &extra_io_props, &fof_properties, &los_properties, - &lightcone_array_properties, &ics_metadata); + &mesh, &pow_data, &potential, &forcing_terms, &cooling_func, + &starform, &chemistry, &extra_io_props, &fof_properties, + &los_properties, &lightcone_array_properties, &ics_metadata); engine_config(/*restart=*/0, /*fof=*/0, &e, params, nr_nodes, myrank, nr_threads, nr_pool_threads, with_aff, talking, restart_dir, restart_file, &reparttype); diff --git a/swift_fof.c b/swift_fof.c index 996015bae3..af7aefd784 100644 --- a/swift_fof.c +++ b/swift_fof.c @@ -660,6 +660,7 @@ int main(int argc, char *argv[]) { /*neutrino_response=*/NULL, /*feedback_properties=*/NULL, /*pressure_floor_properties=*/NULL, /*rt_properties=*/NULL, &mesh, /*pow_data=*/NULL, /*potential=*/NULL, + /*forcing_terms=*/NULL, /*cooling_func=*/NULL, /*starform=*/NULL, /*chemistry=*/NULL, /*extra_io_props=*/NULL, &fof_properties, /*los_properties=*/NULL, /*lightcone_properties=*/NULL, &ics_metadata); -- GitLab