Skip to content
Snippets Groups Projects
Commit 7e89fa07 authored by Jacob Kegerreis's avatar Jacob Kegerreis
Browse files

Add Minimal Multi-Material hydro scheme (untested WIP)

parent 557ab4d2
Branches
Tags
1 merge request!545Add support for equations of state related to planetary physics
...@@ -779,7 +779,7 @@ fi ...@@ -779,7 +779,7 @@ fi
# Hydro scheme. # Hydro scheme.
AC_ARG_WITH([hydro], AC_ARG_WITH([hydro],
[AS_HELP_STRING([--with-hydro=<scheme>], [AS_HELP_STRING([--with-hydro=<scheme>],
[Hydro dynamics to use @<:@gadget2, minimal, hopkins, default, gizmo, shadowfax debug default: gadget2@:>@] [Hydro dynamics to use @<:@gadget2, minimal, hopkins, default, gizmo, shadowfax, minimal-multi-mat debug default: gadget2@:>@]
)], )],
[with_hydro="$withval"], [with_hydro="$withval"],
[with_hydro="gadget2"] [with_hydro="gadget2"]
...@@ -803,6 +803,9 @@ case "$with_hydro" in ...@@ -803,6 +803,9 @@ case "$with_hydro" in
shadowfax) shadowfax)
AC_DEFINE([SHADOWFAX_SPH], [1], [Shadowfax SPH]) AC_DEFINE([SHADOWFAX_SPH], [1], [Shadowfax SPH])
;; ;;
minimal-multi-mat)
AC_DEFINE([MINIMAL_MULTI_MAT_SPH], [1], [Minimal Multiple Material SPH])
;;
*) *)
AC_MSG_ERROR([Unknown hydrodynamics scheme: $with_hydro]) AC_MSG_ERROR([Unknown hydrodynamics scheme: $with_hydro])
...@@ -890,7 +893,7 @@ esac ...@@ -890,7 +893,7 @@ esac
# Equation of state # Equation of state
AC_ARG_WITH([equation-of-state], AC_ARG_WITH([equation-of-state],
[AS_HELP_STRING([--with-equation-of-state=<EoS>], [AS_HELP_STRING([--with-equation-of-state=<EoS>],
[equation of state @<:@ideal-gas, isothermal-gas, tillotson-iron default: ideal-gas@:>@] [equation of state @<:@ideal-gas, isothermal-gas, tillotson default: ideal-gas@:>@]
)], )],
[with_eos="$withval"], [with_eos="$withval"],
[with_eos="ideal-gas"] [with_eos="ideal-gas"]
...@@ -902,8 +905,8 @@ case "$with_eos" in ...@@ -902,8 +905,8 @@ case "$with_eos" in
isothermal-gas) isothermal-gas)
AC_DEFINE([EOS_ISOTHERMAL_GAS], [1], [Isothermal gas equation of state]) AC_DEFINE([EOS_ISOTHERMAL_GAS], [1], [Isothermal gas equation of state])
;; ;;
tillotson-iron) tillotson)
AC_DEFINE([EOS_TILLOTSON_IRON], [1], [Tillotson iron equation of state]) AC_DEFINE([EOS_TILLOTSON], [1], [Tillotson equation of state])
;; ;;
*) *)
AC_MSG_ERROR([Unknown equation of state: $with_eos]) AC_MSG_ERROR([Unknown equation of state: $with_eos])
......
...@@ -52,6 +52,8 @@ ...@@ -52,6 +52,8 @@
#include "./hydro/Gizmo/hydro_debug.h" #include "./hydro/Gizmo/hydro_debug.h"
#elif defined(SHADOWFAX_SPH) #elif defined(SHADOWFAX_SPH)
#include "./hydro/Shadowswift/hydro_debug.h" #include "./hydro/Shadowswift/hydro_debug.h"
#elif defined(MINIMAL_MULTI_MAT_SPH)
#include "./hydro/MinimalMultiMat/hydro_debug.h"
#else #else
#error "Invalid choice of SPH variant" #error "Invalid choice of SPH variant"
#endif #endif
......
...@@ -52,6 +52,10 @@ ...@@ -52,6 +52,10 @@
#include "./hydro/Shadowswift/hydro_iact.h" #include "./hydro/Shadowswift/hydro_iact.h"
#define SPH_IMPLEMENTATION \ #define SPH_IMPLEMENTATION \
"Shadowfax moving mesh (Vandenbroucke and De Rijcke 2016)" "Shadowfax moving mesh (Vandenbroucke and De Rijcke 2016)"
#elif defined(MINIMAL_MULTI_MAT_SPH)
#include "./hydro/MinimalMultiMat/hydro.h"
#include "./hydro/MinimalMultiMat/hydro_iact.h"
#define SPH_IMPLEMENTATION "Minimal version of SPH with multiple materials"
#else #else
#error "Invalid choice of SPH variant" #error "Invalid choice of SPH variant"
#endif #endif
......
/*******************************************************************************
* This file is part of SWIFT.
* Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
*
* 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_MINIMAL_MULTI_MAT_HYDRO_H
#define SWIFT_MINIMAL_MULTI_MAT_HYDRO_H
/**
* @file MinimalMultiMat/hydro.h
* @brief Minimal conservative implementation of SPH (Non-neighbour loop
* equations) with multiple materials.
*
* The thermal variable is the internal energy (u). Simple constant
* viscosity term without switches is implemented. No thermal conduction
* term is implemented.
*
* This corresponds to equations (43), (44), (45), (101), (103) and (104) with
* \f$\beta=3\f$ and \f$\alpha_u=0\f$ of Price, D., Journal of Computational
* Physics, 2012, Volume 231, Issue 3, pp. 759-794.
*/
#include "adiabatic_index.h"
#include "approx_math.h"
#include "cosmology.h"
#include "dimension.h"
#include "equation_of_state.h"
#include "hydro_properties.h"
#include "hydro_space.h"
#include "kernel_hydro.h"
#include "minmax.h"
/**
* @brief Returns the comoving internal energy of a particle
*
* For implementations where the main thermodynamic variable
* is not internal energy, this function computes the internal
* energy from the thermodynamic variable.
*
* @param p The particle of interest
*/
__attribute__((always_inline)) INLINE static float
hydro_get_comoving_internal_energy(const struct part *restrict p) {
return p->u;
}
/**
* @brief Returns the physical internal energy of a particle
*
* For implementations where the main thermodynamic variable
* is not internal energy, this function computes the internal
* energy from the thermodynamic variable and converts it to
* physical coordinates.
*
* @param p The particle of interest.
* @param cosmo The cosmological model.
*/
__attribute__((always_inline)) INLINE static float
hydro_get_physical_internal_energy(const struct part *restrict p,
const struct cosmology *cosmo) {
return p->u * cosmo->a_factor_internal_energy;
}
/**
* @brief Returns the comoving pressure of a particle
*
* Computes the pressure based on the particle's properties.
*
* @param p The particle of interest
*/
__attribute__((always_inline)) INLINE static float hydro_get_comoving_pressure(
const struct part *restrict p) {
return gas_pressure_from_internal_energy(p->rho, p->u, p->mat_id);
}
/**
* @brief Returns the physical pressure of a particle
*
* Computes the pressure based on the particle's properties and
* convert it to physical coordinates.
*
* @param p The particle of interest
* @param cosmo The cosmological model.
*/
__attribute__((always_inline)) INLINE static float hydro_get_physical_pressure(
const struct part *restrict p, const struct cosmology *cosmo) {
return cosmo->a_factor_pressure *
gas_pressure_from_internal_energy(p->rho, p->u, p->mat_id);
}
/**
* @brief Returns the comoving entropy of a particle
*
* For implementations where the main thermodynamic variable
* is not entropy, this function computes the entropy from
* the thermodynamic variable.
*
* @param p The particle of interest
*/
__attribute__((always_inline)) INLINE static float hydro_get_comoving_entropy(
const struct part *restrict p) {
return gas_entropy_from_internal_energy(p->rho, p->u, p->mat_id);
}
/**
* @brief Returns the physical entropy of a particle
*
* For implementations where the main thermodynamic variable
* is not entropy, this function computes the entropy from
* the thermodynamic variable and converts it to
* physical coordinates.
*
* @param p The particle of interest
* @param cosmo The cosmological model.
*/
__attribute__((always_inline)) INLINE static float hydro_get_physical_entropy(
const struct part *restrict p, const struct cosmology *cosmo) {
/* Note: no cosmological conversion required here with our choice of
* coordinates. */
return gas_entropy_from_internal_energy(p->rho, p->u, p->mat_id);
}
/**
* @brief Returns the comoving sound speed of a particle
*
* @param p The particle of interest
*/
__attribute__((always_inline)) INLINE static float
hydro_get_comoving_soundspeed(const struct part *restrict p) {
return p->force.soundspeed;
}
/**
* @brief Returns the physical sound speed of a particle
*
* @param p The particle of interest
* @param cosmo The cosmological model.
*/
__attribute__((always_inline)) INLINE static float
hydro_get_physical_soundspeed(const struct part *restrict p,
const struct cosmology *cosmo) {
return cosmo->a_factor_sound_speed * p->force.soundspeed;
}
/**
* @brief Returns the comoving density of a particle
*
* @param p The particle of interest
*/
__attribute__((always_inline)) INLINE static float hydro_get_comoving_density(
const struct part *restrict p) {
return p->rho;
}
/**
* @brief Returns the comoving density of a particle.
*
* @param p The particle of interest
* @param cosmo The cosmological model.
*/
__attribute__((always_inline)) INLINE static float hydro_get_physical_density(
const struct part *restrict p, const struct cosmology *cosmo) {
return cosmo->a3_inv * p->rho;
}
/**
* @brief Returns the mass of a particle
*
* @param p The particle of interest
*/
__attribute__((always_inline)) INLINE static float hydro_get_mass(
const struct part *restrict p) {
return p->mass;
}
/**
* @brief Sets the mass of a particle
*
* @param p The particle of interest
* @param m The mass to set.
*/
__attribute__((always_inline)) INLINE static void hydro_set_mass(
struct part *restrict p, float m) {
p->mass = m;
}
/**
* @brief Returns the velocities drifted to the current time of a particle.
*
* @param p The particle of interest
* @param xp The extended data of the particle.
* @param dt_kick_hydro The time (for hydro accelerations) since the last kick.
* @param dt_kick_grav The time (for gravity accelerations) since the last kick.
* @param v (return) The velocities at the current time.
*/
__attribute__((always_inline)) INLINE static void hydro_get_drifted_velocities(
const struct part *restrict p, const struct xpart *xp, float dt_kick_hydro,
float dt_kick_grav, float v[3]) {
v[0] = xp->v_full[0] + p->a_hydro[0] * dt_kick_hydro +
xp->a_grav[0] * dt_kick_grav;
v[1] = xp->v_full[1] + p->a_hydro[1] * dt_kick_hydro +
xp->a_grav[1] * dt_kick_grav;
v[2] = xp->v_full[2] + p->a_hydro[2] * dt_kick_hydro +
xp->a_grav[2] * dt_kick_grav;
}
/**
* @brief Returns the time derivative of internal energy of a particle
*
* We assume a constant density.
*
* @param p The particle of interest
*/
__attribute__((always_inline)) INLINE static float hydro_get_internal_energy_dt(
const struct part *restrict p) {
return p->u_dt;
}
/**
* @brief Returns the time derivative of internal energy of a particle
*
* We assume a constant density.
*
* @param p The particle of interest.
* @param du_dt The new time derivative of the internal energy.
*/
__attribute__((always_inline)) INLINE static void hydro_set_internal_energy_dt(
struct part *restrict p, float du_dt) {
p->u_dt = du_dt;
}
/**
* @brief Computes the hydro time-step of a given particle
*
* This function returns the time-step of a particle given its hydro-dynamical
* state. A typical time-step calculation would be the use of the CFL condition.
*
* @param p Pointer to the particle data
* @param xp Pointer to the extended particle data
* @param hydro_properties The SPH parameters
* @param cosmo The cosmological model.
*/
__attribute__((always_inline)) INLINE static float hydro_compute_timestep(
const struct part *restrict p, const struct xpart *restrict xp,
const struct hydro_props *restrict hydro_properties,
const struct cosmology *restrict cosmo) {
const float CFL_condition = hydro_properties->CFL_condition;
/* CFL condition */
const float dt_cfl = 2.f * kernel_gamma * CFL_condition * cosmo->a * p->h /
(cosmo->a_factor_sound_speed * p->force.v_sig);
return dt_cfl;
}
/**
* @brief Does some extra hydro operations once the actual physical time step
* for the particle is known.
*
* @param p The particle to act upon.
* @param dt Physical time step of the particle during the next step.
*/
__attribute__((always_inline)) INLINE static void hydro_timestep_extra(
struct part *p, float dt) {}
/**
* @brief Prepares a particle for the density calculation.
*
* Zeroes all the relevant arrays in preparation for the sums taking place in
* the various density loop over neighbours. Typically, all fields of the
* density sub-structure of a particle get zeroed in here.
*
* @param p The particle to act upon
* @param hs #hydro_space containing hydro specific space information.
*/
__attribute__((always_inline)) INLINE static void hydro_init_part(
struct part *restrict p, const struct hydro_space *hs) {
p->density.wcount = 0.f;
p->density.wcount_dh = 0.f;
p->rho = 0.f;
p->density.rho_dh = 0.f;
}
/**
* @brief Finishes the density calculation.
*
* Multiplies the density and number of neighbours by the appropiate constants
* and add the self-contribution term.
* Additional quantities such as velocity gradients will also get the final
* terms added to them here.
*
* Also adds/multiplies the cosmological terms if need be.
*
* @param p The particle to act upon
* @param cosmo The cosmological model.
*/
__attribute__((always_inline)) INLINE static void hydro_end_density(
struct part *restrict p, const struct cosmology *cosmo) {
/* Some smoothing length multiples. */
const float h = p->h;
const float h_inv = 1.0f / h; /* 1/h */
const float h_inv_dim = pow_dimension(h_inv); /* 1/h^d */
const float h_inv_dim_plus_one = h_inv_dim * h_inv; /* 1/h^(d+1) */
/* Final operation on the density (add self-contribution). */
p->rho += p->mass * kernel_root;
p->density.rho_dh -= hydro_dimension * p->mass * kernel_root;
p->density.wcount += kernel_root;
p->density.wcount_dh -= hydro_dimension * kernel_root;
/* Finish the calculation by inserting the missing h-factors */
p->rho *= h_inv_dim;
p->density.rho_dh *= h_inv_dim_plus_one;
p->density.wcount *= h_inv_dim;
p->density.wcount_dh *= h_inv_dim_plus_one;
}
/**
* @brief Sets all particle fields to sensible values when the #part has 0 ngbs.
*
* In the desperate case where a particle has no neighbours (likely because
* of the h_max ceiling), set the particle fields to something sensible to avoid
* NaNs in the next calculations.
*
* @param p The particle to act upon
* @param xp The extended particle data to act upon
* @param cosmo The cosmological model.
*/
__attribute__((always_inline)) INLINE static void hydro_part_has_no_neighbours(
struct part *restrict p, struct xpart *restrict xp,
const struct cosmology *cosmo) {
/* Some smoothing length multiples. */
const float h = p->h;
const float h_inv = 1.0f / h; /* 1/h */
const float h_inv_dim = pow_dimension(h_inv); /* 1/h^d */
/* Re-set problematic values */
p->rho = p->mass * kernel_root * h_inv_dim;
p->density.wcount = kernel_root * kernel_norm * h_inv_dim;
p->density.rho_dh = 0.f;
p->density.wcount_dh = 0.f;
}
/**
* @brief Prepare a particle for the force calculation.
*
* This function is called in the ghost task to convert some quantities coming
* from the density loop over neighbours into quantities ready to be used in the
* force loop over neighbours. Quantities are typically read from the density
* sub-structure and written to the force sub-structure.
* Examples of calculations done here include the calculation of viscosity term
* constants, thermal conduction terms, hydro conversions, etc.
*
* @param p The particle to act upon
* @param xp The extended particle data to act upon
* @param cosmo The current cosmological model.
*/
__attribute__((always_inline)) INLINE static void hydro_prepare_force(
struct part *restrict p, struct xpart *restrict xp,
const struct cosmology *cosmo) {
/* Compute the pressure */
const float pressure = gas_pressure_from_internal_energy(p->rho, p->u);
/* Compute the sound speed */
const float soundspeed = gas_soundspeed_from_pressure(p->rho, pressure);
/* Compute the "grad h" term */
const float rho_inv = 1.f / p->rho;
const float grad_h_term =
1.f / (1.f + hydro_dimension_inv * p->h * p->density.rho_dh * rho_inv);
/* Update variables. */
p->force.f = grad_h_term;
p->force.pressure = pressure;
p->force.soundspeed = soundspeed;
}
/**
* @brief Reset acceleration fields of a particle
*
* Resets all hydro acceleration and time derivative fields in preparation
* for the sums taking place in the various force tasks.
*
* @param p The particle to act upon
*/
__attribute__((always_inline)) INLINE static void hydro_reset_acceleration(
struct part *restrict p) {
/* Reset the acceleration. */
p->a_hydro[0] = 0.0f;
p->a_hydro[1] = 0.0f;
p->a_hydro[2] = 0.0f;
/* Reset the time derivatives. */
p->u_dt = 0.0f;
p->force.h_dt = 0.0f;
p->force.v_sig = 0.0f;
}
/**
* @brief Sets the values to be predicted in the drifts to their values at a
* kick time
*
* @param p The particle.
* @param xp The extended data of this particle.
*/
__attribute__((always_inline)) INLINE static void hydro_reset_predicted_values(
struct part *restrict p, const struct xpart *restrict xp) {
/* Re-set the predicted velocities */
p->v[0] = xp->v_full[0];
p->v[1] = xp->v_full[1];
p->v[2] = xp->v_full[2];
/* Re-set the entropy */
p->u = xp->u_full;
}
/**
* @brief Predict additional particle fields forward in time when drifting
*
* Additional hydrodynamic quantites are drifted forward in time here. These
* include thermal quantities (thermal energy or total energy or entropy, ...).
*
* Note the different time-step sizes used for the different quantities as they
* include cosmological factors.
*
* @param p The particle.
* @param xp The extended data of the particle.
* @param dt_drift The drift time-step for positions.
* @param dt_therm The drift time-step for thermal quantities.
*/
__attribute__((always_inline)) INLINE static void hydro_predict_extra(
struct part *restrict p, const struct xpart *restrict xp, float dt_drift,
float dt_therm) {
const float h_inv = 1.f / p->h;
/* Predict smoothing length */
const float w1 = p->force.h_dt * h_inv * dt_drift;
if (fabsf(w1) < 0.2f)
p->h *= approx_expf(w1); /* 4th order expansion of exp(w) */
else
p->h *= expf(w1);
/* Predict density */
const float w2 = -hydro_dimension * w1;
if (fabsf(w2) < 0.2f)
p->rho *= approx_expf(w2); /* 4th order expansion of exp(w) */
else
p->rho *= expf(w2);
/* Predict the internal energy */
p->u += p->u_dt * dt_therm;
/* Compute the new pressure */
const float pressure = gas_pressure_from_internal_energy(p->rho, p->u);
/* Compute the new sound speed */
const float soundspeed = gas_soundspeed_from_pressure(p->rho, pressure);
p->force.pressure = pressure;
p->force.soundspeed = soundspeed;
}
/**
* @brief Finishes the force calculation.
*
* Multiplies the force and accelerations by the appropiate constants
* and add the self-contribution term. In most cases, there is little
* to do here.
*
* Cosmological terms are also added/multiplied here.
*
* @param p The particle to act upon
* @param cosmo The current cosmological model.
*/
__attribute__((always_inline)) INLINE static void hydro_end_force(
struct part *restrict p, const struct cosmology *cosmo) {
p->force.h_dt *= p->h * hydro_dimension_inv;
}
/**
* @brief Kick the additional variables
*
* Additional hydrodynamic quantites are kicked forward in time here. These
* include thermal quantities (thermal energy or total energy or entropy, ...).
*
* @param p The particle to act upon.
* @param xp The particle extended data to act upon.
* @param dt_therm The time-step for this kick (for thermodynamic quantities).
* @param cosmo The cosmological model.
* @param hydro_props The constants used in the scheme
*/
__attribute__((always_inline)) INLINE static void hydro_kick_extra(
struct part *restrict p, struct xpart *restrict xp, float dt_therm,
const struct cosmology *cosmo, const struct hydro_props *hydro_props) {
/* Do not decrease the energy by more than a factor of 2*/
if (dt_therm > 0. && p->u_dt * dt_therm < -0.5f * xp->u_full) {
p->u_dt = -0.5f * xp->u_full / dt_therm;
}
xp->u_full += p->u_dt * dt_therm;
/* Apply the minimal energy limit */
const float min_energy =
hydro_props->minimal_internal_energy * cosmo->a_factor_internal_energy;
if (xp->u_full < min_energy) {
xp->u_full = min_energy;
p->u_dt = 0.f;
}
/* Compute the pressure */
const float pressure = gas_pressure_from_internal_energy(p->rho, xp->u_full, p->mat_id);
/* Compute the sound speed */
const float soundspeed = gas_soundspeed_from_internal_energy(p->rho, p->u, p->mat_id);
p->force.pressure = pressure;
p->force.soundspeed = soundspeed;
}
/**
* @brief Converts hydro quantity of a particle at the start of a run
*
* This function is called once at the end of the engine_init_particle()
* routine (at the start of a calculation) after the densities of
* particles have been computed.
* This can be used to convert internal energy into entropy for instance.
*
* @param p The particle to act upon
* @param xp The extended particle to act upon
* @param cosmo The cosmological model.
*/
__attribute__((always_inline)) INLINE static void hydro_convert_quantities(
struct part *restrict p, struct xpart *restrict xp,
const struct cosmology *cosmo) {
/* Compute the pressure */
const float pressure = gas_pressure_from_internal_energy(p->rho, p->u, p->mat_id);
/* Compute the sound speed */
const float soundspeed = gas_soundspeed_from_internal_energy(p->rho, p->u, p->mat_id);
p->force.pressure = pressure;
p->force.soundspeed = soundspeed;
}
/**
* @brief Initialises the particles for the first time
*
* This function is called only once just after the ICs have been
* read in to do some conversions or assignments between the particle
* and extended particle fields.
*
* @param p The particle to act upon
* @param xp The extended particle data to act upon
*/
__attribute__((always_inline)) INLINE static void hydro_first_init_part(
struct part *restrict p, struct xpart *restrict xp) {
p->time_bin = 0;
xp->v_full[0] = p->v[0];
xp->v_full[1] = p->v[1];
xp->v_full[2] = p->v[2];
xp->a_grav[0] = 0.f;
xp->a_grav[1] = 0.f;
xp->a_grav[2] = 0.f;
xp->u_full = p->u;
hydro_reset_acceleration(p);
hydro_init_part(p, NULL);
}
/**
* @brief Overwrite the initial internal energy of a particle.
*
* Note that in the cases where the thermodynamic variable is not
* internal energy but gets converted later, we must overwrite that
* field. The conversion to the actual variable happens later after
* the initial fake time-step.
*
* @param p The #part to write to.
* @param u_init The new initial internal energy.
*/
__attribute__((always_inline)) INLINE static void
hydro_set_init_internal_energy(struct part *p, float u_init) {
p->u = u_init;
}
#endif /* SWIFT_MINIMAL_MULTI_MAT_HYDRO_H */
/*******************************************************************************
* This file is part of SWIFT.
* Coypright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
*
* 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_MINIMAL_MULTI_MAT_HYDRO_DEBUG_H
#define SWIFT_MINIMAL_MULTI_MAT_HYDRO_DEBUG_H
/**
* @file MinimalMultiMat/hydro_debug.h
* @brief MinimalMultiMat conservative implementation of SPH (Debugging routines)
*
* The thermal variable is the internal energy (u). Simple constant
* viscosity term without switches is implemented. No thermal conduction
* term is implemented.
*
* This corresponds to equations (43), (44), (45), (101), (103) and (104) with
* \f$\beta=3\f$ and \f$\alpha_u=0\f$ of
* Price, D., Journal of Computational Physics, 2012, Volume 231, Issue 3,
* pp. 759-794.
*/
__attribute__((always_inline)) INLINE static void hydro_debug_particle(
const struct part* p, const struct xpart* xp) {
printf(
"x=[%.3e,%.3e,%.3e], "
"v=[%.3e,%.3e,%.3e],v_full=[%.3e,%.3e,%.3e] \n a=[%.3e,%.3e,%.3e], "
"u=%.3e, du/dt=%.3e v_sig=%.3e, P=%.3e\n"
"h=%.3e, dh/dt=%.3e wcount=%d, m=%.3e, dh_drho=%.3e, rho=%.3e, "
"time_bin=%d, mat_id=%d\n",
p->x[0], p->x[1], p->x[2], p->v[0], p->v[1], p->v[2], xp->v_full[0],
xp->v_full[1], xp->v_full[2], p->a_hydro[0], p->a_hydro[1], p->a_hydro[2],
p->u, p->u_dt, p->force.v_sig, hydro_get_comoving_pressure(p), p->h,
p->force.h_dt, (int)p->density.wcount, p->mass, p->density.rho_dh, p->rho,
p->time_bin, p->mat_id);
}
#endif /* SWIFT_MINIMAL_MULTI_MAT_HYDRO_DEBUG_H */
/*******************************************************************************
* This file is part of SWIFT.
* Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
*
* 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_MINIMAL_MULTI_MAT_HYDRO_IACT_H
#define SWIFT_MINIMAL_MULTI_MAT_HYDRO_IACT_H
/**
* @file MinimalMultiMat/hydro_iact.h
* @brief MinimalMultiMat conservative implementation of SPH (Neighbour loop equations)
*
* The thermal variable is the internal energy (u). Simple constant
* viscosity term without switches is implemented. No thermal conduction
* term is implemented.
*
* This corresponds to equations (43), (44), (45), (101), (103) and (104) with
* \f$\beta=3\f$ and \f$\alpha_u=0\f$ of Price, D., Journal of Computational
* Physics, 2012, Volume 231, Issue 3, pp. 759-794.
*/
#include "adiabatic_index.h"
#include "minmax.h"
/**
* @brief Density interaction between two particles.
*
* @param r2 Comoving square distance between the two particles.
* @param dx Comoving vector separating both particles (pi - pj).
* @param hi Comoving smoothing-length of particle i.
* @param hj Comoving smoothing-length of particle j.
* @param pi First particle.
* @param pj Second particle.
* @param a Current scale factor.
* @param H Current Hubble parameter.
*/
__attribute__((always_inline)) INLINE static void runner_iact_density(
float r2, const float *dx, float hi, float hj, struct part *restrict pi,
struct part *restrict pj, float a, float H) {
float wi, wj, wi_dx, wj_dx;
/* Get r. */
const float r_inv = 1.0f / sqrtf(r2);
const float r = r2 * r_inv;
/* Get the masses. */
const float mi = pi->mass;
const float mj = pj->mass;
/* Compute density of pi. */
const float hi_inv = 1.f / hi;
const float ui = r * hi_inv;
kernel_deval(ui, &wi, &wi_dx);
pi->rho += mj * wi;
pi->density.rho_dh -= mj * (hydro_dimension * wi + ui * wi_dx);
pi->density.wcount += wi;
pi->density.wcount_dh -= (hydro_dimension * wi + ui * wi_dx);
/* Compute density of pj. */
const float hj_inv = 1.f / hj;
const float uj = r * hj_inv;
kernel_deval(uj, &wj, &wj_dx);
pj->rho += mi * wj;
pj->density.rho_dh -= mi * (hydro_dimension * wj + uj * wj_dx);
pj->density.wcount += wj;
pj->density.wcount_dh -= (hydro_dimension * wj + uj * wj_dx);
}
/**
* @brief Density interaction between two particles (non-symmetric).
*
* @param r2 Comoving square distance between the two particles.
* @param dx Comoving vector separating both particles (pi - pj).
* @param hi Comoving smoothing-length of particle i.
* @param hj Comoving smoothing-length of particle j.
* @param pi First particle.
* @param pj Second particle (not updated).
* @param a Current scale factor.
* @param H Current Hubble parameter.
*/
__attribute__((always_inline)) INLINE static void runner_iact_nonsym_density(
float r2, const float *dx, float hi, float hj, struct part *restrict pi,
const struct part *restrict pj, float a, float H) {
float wi, wi_dx;
/* Get the masses. */
const float mj = pj->mass;
/* Get r. */
const float r_inv = 1.0f / sqrtf(r2);
const float r = r2 * r_inv;
const float h_inv = 1.f / hi;
const float ui = r * h_inv;
kernel_deval(ui, &wi, &wi_dx);
pi->rho += mj * wi;
pi->density.rho_dh -= mj * (hydro_dimension * wi + ui * wi_dx);
pi->density.wcount += wi;
pi->density.wcount_dh -= (hydro_dimension * wi + ui * wi_dx);
}
/**
* @brief Force interaction between two particles.
*
* @param r2 Comoving square distance between the two particles.
* @param dx Comoving vector separating both particles (pi - pj).
* @param hi Comoving smoothing-length of particle i.
* @param hj Comoving smoothing-length of particle j.
* @param pi First particle.
* @param pj Second particle.
* @param a Current scale factor.
* @param H Current Hubble parameter.
*/
__attribute__((always_inline)) INLINE static void runner_iact_force(
float r2, const float *dx, float hi, float hj, struct part *restrict pi,
struct part *restrict pj, float a, float H) {
/* Cosmological factors entering the EoMs */
const float fac_mu = pow_three_gamma_minus_five_over_two(a);
const float a2_Hubble = a * a * H;
/* Get r and r inverse. */
const float r_inv = 1.0f / sqrtf(r2);
const float r = r2 * r_inv;
/* Recover some data */
const float mi = pi->mass;
const float mj = pj->mass;
const float rhoi = pi->rho;
const float rhoj = pj->rho;
const float pressurei = pi->force.pressure;
const float pressurej = pj->force.pressure;
/* Get the kernel for hi. */
const float hi_inv = 1.0f / hi;
const float hid_inv = pow_dimension_plus_one(hi_inv); /* 1/h^(d+1) */
const float xi = r * hi_inv;
float wi, wi_dx;
kernel_deval(xi, &wi, &wi_dx);
const float wi_dr = hid_inv * wi_dx;
/* Get the kernel for hj. */
const float hj_inv = 1.0f / hj;
const float hjd_inv = pow_dimension_plus_one(hj_inv); /* 1/h^(d+1) */
const float xj = r * hj_inv;
float wj, wj_dx;
kernel_deval(xj, &wj, &wj_dx);
const float wj_dr = hjd_inv * wj_dx;
/* Compute gradient terms */
const float P_over_rho2_i = pressurei / (rhoi * rhoi) * pi->force.f;
const float P_over_rho2_j = pressurej / (rhoj * rhoj) * pj->force.f;
/* Compute dv dot r. */
const float dvdr = (pi->v[0] - pj->v[0]) * dx[0] +
(pi->v[1] - pj->v[1]) * dx[1] +
(pi->v[2] - pj->v[2]) * dx[2] + a2_Hubble * r2;
/* Are the particles moving towards each others ? */
const float omega_ij = min(dvdr, 0.f);
const float mu_ij = fac_mu * r_inv * omega_ij; /* This is 0 or negative */
/* Compute sound speeds and signal velocity */
const float ci = pi->force.soundspeed;
const float cj = pj->force.soundspeed;
const float v_sig = ci + cj - 3.f * mu_ij;
/* Construct the full viscosity term */
const float rho_ij = 0.5f * (rhoi + rhoj);
const float visc = -0.5f * const_viscosity_alpha * v_sig * mu_ij / rho_ij;
/* Convolve with the kernel */
const float visc_acc_term = 0.5f * visc * (wi_dr + wj_dr) * r_inv;
/* SPH acceleration term */
const float sph_acc_term =
(P_over_rho2_i * wi_dr + P_over_rho2_j * wj_dr) * r_inv;
/* Assemble the acceleration */
const float acc = sph_acc_term + visc_acc_term;
/* Use the force Luke ! */
pi->a_hydro[0] -= mj * acc * dx[0];
pi->a_hydro[1] -= mj * acc * dx[1];
pi->a_hydro[2] -= mj * acc * dx[2];
pj->a_hydro[0] += mi * acc * dx[0];
pj->a_hydro[1] += mi * acc * dx[1];
pj->a_hydro[2] += mi * acc * dx[2];
/* Get the time derivative for u. */
const float sph_du_term_i = P_over_rho2_i * dvdr * r_inv * wi_dr;
const float sph_du_term_j = P_over_rho2_j * dvdr * r_inv * wj_dr;
/* Viscosity term */
const float visc_du_term = 0.5f * visc_acc_term * dvdr;
/* Assemble the energy equation term */
const float du_dt_i = sph_du_term_i + visc_du_term;
const float du_dt_j = sph_du_term_j + visc_du_term;
/* Internal energy time derivatibe */
pi->u_dt += du_dt_i * mj;
pj->u_dt += du_dt_j * mi;
/* Get the time derivative for h. */
pi->force.h_dt -= mj * dvdr * r_inv / rhoj * wi_dr;
pj->force.h_dt -= mi * dvdr * r_inv / rhoi * wj_dr;
/* Update the signal velocity. */
pi->force.v_sig = max(pi->force.v_sig, v_sig);
pj->force.v_sig = max(pj->force.v_sig, v_sig);
}
/**
* @brief Force interaction between two particles (non-symmetric).
*
* @param r2 Comoving square distance between the two particles.
* @param dx Comoving vector separating both particles (pi - pj).
* @param hi Comoving smoothing-length of particle i.
* @param hj Comoving smoothing-length of particle j.
* @param pi First particle.
* @param pj Second particle (not updated).
* @param a Current scale factor.
* @param H Current Hubble parameter.
*/
__attribute__((always_inline)) INLINE static void runner_iact_nonsym_force(
float r2, const float *dx, float hi, float hj, struct part *restrict pi,
const struct part *restrict pj, float a, float H) {
/* Cosmological factors entering the EoMs */
const float fac_mu = pow_three_gamma_minus_five_over_two(a);
const float a2_Hubble = a * a * H;
/* Get r and r inverse. */
const float r_inv = 1.0f / sqrtf(r2);
const float r = r2 * r_inv;
/* Recover some data */
// const float mi = pi->mass;
const float mj = pj->mass;
const float rhoi = pi->rho;
const float rhoj = pj->rho;
const float pressurei = pi->force.pressure;
const float pressurej = pj->force.pressure;
/* Get the kernel for hi. */
const float hi_inv = 1.0f / hi;
const float hid_inv = pow_dimension_plus_one(hi_inv); /* 1/h^(d+1) */
const float xi = r * hi_inv;
float wi, wi_dx;
kernel_deval(xi, &wi, &wi_dx);
const float wi_dr = hid_inv * wi_dx;
/* Get the kernel for hj. */
const float hj_inv = 1.0f / hj;
const float hjd_inv = pow_dimension_plus_one(hj_inv); /* 1/h^(d+1) */
const float xj = r * hj_inv;
float wj, wj_dx;
kernel_deval(xj, &wj, &wj_dx);
const float wj_dr = hjd_inv * wj_dx;
/* Compute gradient terms */
const float P_over_rho2_i = pressurei / (rhoi * rhoi) * pi->force.f;
const float P_over_rho2_j = pressurej / (rhoj * rhoj) * pj->force.f;
/* Compute dv dot r. */
const float dvdr = (pi->v[0] - pj->v[0]) * dx[0] +
(pi->v[1] - pj->v[1]) * dx[1] +
(pi->v[2] - pj->v[2]) * dx[2] + a2_Hubble * r2;
/* Are the particles moving towards each others ? */
const float omega_ij = min(dvdr, 0.f);
const float mu_ij = fac_mu * r_inv * omega_ij; /* This is 0 or negative */
/* Compute sound speeds and signal velocity */
const float ci = pi->force.soundspeed;
const float cj = pj->force.soundspeed;
const float v_sig = ci + cj - 3.f * mu_ij;
/* Construct the full viscosity term */
const float rho_ij = 0.5f * (rhoi + rhoj);
const float visc = -0.5f * const_viscosity_alpha * v_sig * mu_ij / rho_ij;
/* Convolve with the kernel */
const float visc_acc_term = 0.5f * visc * (wi_dr + wj_dr) * r_inv;
/* SPH acceleration term */
const float sph_acc_term =
(P_over_rho2_i * wi_dr + P_over_rho2_j * wj_dr) * r_inv;
/* Assemble the acceleration */
const float acc = sph_acc_term + visc_acc_term;
/* Use the force Luke ! */
pi->a_hydro[0] -= mj * acc * dx[0];
pi->a_hydro[1] -= mj * acc * dx[1];
pi->a_hydro[2] -= mj * acc * dx[2];
/* Get the time derivative for u. */
const float sph_du_term_i = P_over_rho2_i * dvdr * r_inv * wi_dr;
/* Viscosity term */
const float visc_du_term = 0.5f * visc_acc_term * dvdr;
/* Assemble the energy equation term */
const float du_dt_i = sph_du_term_i + visc_du_term;
/* Internal energy time derivatibe */
pi->u_dt += du_dt_i * mj;
/* Get the time derivative for h. */
pi->force.h_dt -= mj * dvdr * r_inv / rhoj * wi_dr;
/* Update the signal velocity. */
pi->force.v_sig = max(pi->force.v_sig, v_sig);
}
#endif /* SWIFT_MINIMAL_MULTI_MAT_HYDRO_IACT_H */
/*******************************************************************************
* This file is part of SWIFT.
* Coypright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
*
* 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_MINIMAL_MULTI_MAT_HYDRO_IO_H
#define SWIFT_MINIMAL_MULTI_MAT_HYDRO_IO_H
/**
* @file MinimalMultiMat/hydro_io.h
* @brief MinimalMultiMat conservative implementation of SPH (i/o routines)
*
* The thermal variable is the internal energy (u). Simple constant
* viscosity term without switches is implemented. No thermal conduction
* term is implemented.
*
* This corresponds to equations (43), (44), (45), (101), (103) and (104) with
* \f$\beta=3\f$ and \f$\alpha_u=0\f$ of
* Price, D., Journal of Computational Physics, 2012, Volume 231, Issue 3,
* pp. 759-794.
*/
#include "adiabatic_index.h"
#include "hydro.h"
#include "io_properties.h"
#include "kernel_hydro.h"
/**
* @brief Specifies which particle fields to read from a dataset
*
* @param parts The particle array.
* @param list The list of i/o properties to read.
* @param num_fields The number of i/o fields to read.
*/
void hydro_read_particles(struct part* parts, struct io_props* list,
int* num_fields) {
*num_fields = 8;
/* List what we want to read */
list[0] = io_make_input_field("Coordinates", DOUBLE, 3, COMPULSORY,
UNIT_CONV_LENGTH, parts, x);
list[1] = io_make_input_field("Velocities", FLOAT, 3, COMPULSORY,
UNIT_CONV_SPEED, parts, v);
list[2] = io_make_input_field("Masses", FLOAT, 1, COMPULSORY, UNIT_CONV_MASS,
parts, mass);
list[3] = io_make_input_field("SmoothingLength", FLOAT, 1, COMPULSORY,
UNIT_CONV_LENGTH, parts, h);
list[4] = io_make_input_field("InternalEnergy", FLOAT, 1, COMPULSORY,
UNIT_CONV_ENERGY_PER_UNIT_MASS, parts, u);
list[5] = io_make_input_field("ParticleIDs", ULONGLONG, 1, COMPULSORY,
UNIT_CONV_NO_UNITS, parts, id);
list[6] = io_make_input_field("Accelerations", FLOAT, 3, OPTIONAL,
UNIT_CONV_ACCELERATION, parts, a_hydro);
list[7] = io_make_input_field("Density", FLOAT, 1, OPTIONAL,
UNIT_CONV_DENSITY, parts, rho);
list[8] = io_make_input_field("MaterialID", INT, 1, OPTIONAL, 1, parts,
mat_id);
}
void convert_S(const struct engine* e, const struct part* p,
const struct xpart* xp, float* ret) {
ret[0] = hydro_get_comoving_entropy(p);
}
void convert_P(const struct engine* e, const struct part* p,
const struct xpart* xp, float* ret) {
ret[0] = hydro_get_comoving_pressure(p);
}
void convert_part_pos(const struct engine* e, const struct part* p,
const struct xpart* xp, double* ret) {
if (e->s->periodic) {
ret[0] = box_wrap(p->x[0], 0.0, e->s->dim[0]);
ret[1] = box_wrap(p->x[1], 0.0, e->s->dim[1]);
ret[2] = box_wrap(p->x[2], 0.0, e->s->dim[2]);
} else {
ret[0] = p->x[0];
ret[1] = p->x[1];
ret[2] = p->x[2];
}
}
void convert_part_vel(const struct engine* e, const struct part* p,
const struct xpart* xp, float* ret) {
const int with_cosmology = (e->policy & engine_policy_cosmology);
const struct cosmology* cosmo = e->cosmology;
const integertime_t ti_current = e->ti_current;
const double time_base = e->time_base;
const integertime_t ti_beg = get_integer_time_begin(ti_current, p->time_bin);
const integertime_t ti_end = get_integer_time_end(ti_current, p->time_bin);
/* Get time-step since the last kick */
float dt_kick_grav, dt_kick_hydro;
if (with_cosmology) {
dt_kick_grav = cosmology_get_grav_kick_factor(cosmo, ti_beg, ti_current);
dt_kick_grav -=
cosmology_get_grav_kick_factor(cosmo, ti_beg, (ti_beg + ti_end) / 2);
dt_kick_hydro = cosmology_get_hydro_kick_factor(cosmo, ti_beg, ti_current);
dt_kick_hydro -=
cosmology_get_hydro_kick_factor(cosmo, ti_beg, (ti_beg + ti_end) / 2);
} else {
dt_kick_grav = (ti_current - ((ti_beg + ti_end) / 2)) * time_base;
dt_kick_hydro = (ti_current - ((ti_beg + ti_end) / 2)) * time_base;
}
/* Extrapolate the velocites to the current time */
hydro_get_drifted_velocities(p, xp, dt_kick_hydro, dt_kick_grav, ret);
/* Conversion from internal units to peculiar velocities */
ret[0] *= cosmo->a2_inv;
ret[1] *= cosmo->a2_inv;
ret[2] *= cosmo->a2_inv;
}
void convert_part_potential(const struct engine* e, const struct part* p,
const struct xpart* xp, float* ret) {
if (p->gpart != NULL)
ret[0] = gravity_get_comoving_potential(p->gpart);
else
ret[0] = 0.f;
}
/**
* @brief Specifies which particle fields to write to a dataset
*
* @param parts The particle array.
* @param xparts The extended particle array.
* @param list The list of i/o properties to write.
* @param num_fields The number of i/o fields to write.
*/
void hydro_write_particles(const struct part* parts, const struct xpart* xparts,
struct io_props* list, int* num_fields) {
*num_fields = 10;
/* List what we want to write */
list[0] = io_make_output_field_convert_part("Coordinates", DOUBLE, 3,
UNIT_CONV_LENGTH, parts, xparts,
convert_part_pos);
list[1] = io_make_output_field_convert_part(
"Velocities", FLOAT, 3, UNIT_CONV_SPEED, parts, xparts, convert_part_vel);
list[2] =
io_make_output_field("Masses", FLOAT, 1, UNIT_CONV_MASS, parts, mass);
list[3] = io_make_output_field("SmoothingLength", FLOAT, 1, UNIT_CONV_LENGTH,
parts, h);
list[4] = io_make_output_field("InternalEnergy", FLOAT, 1,
UNIT_CONV_ENERGY_PER_UNIT_MASS, parts, u);
list[5] = io_make_output_field("ParticleIDs", ULONGLONG, 1,
UNIT_CONV_NO_UNITS, parts, id);
list[6] =
io_make_output_field("Density", FLOAT, 1, UNIT_CONV_DENSITY, parts, rho);
list[7] = io_make_output_field_convert_part("Entropy", FLOAT, 1,
UNIT_CONV_ENTROPY_PER_UNIT_MASS,
parts, xparts, convert_S);
list[8] = io_make_output_field_convert_part("MaterialID", INT, 1, 1, parts,
mat_id);
list[8] = io_make_output_field_convert_part(
"Pressure", FLOAT, 1, UNIT_CONV_PRESSURE, parts, xparts, convert_P);
list[9] = io_make_output_field_convert_part("Potential", FLOAT, 1,
UNIT_CONV_POTENTIAL, parts,
xparts, convert_part_potential);
}
/**
* @brief Writes the current model of SPH to the file
* @param h_grpsph The HDF5 group in which to write
*/
void hydro_write_flavour(hid_t h_grpsph) {
/* Viscosity and thermal conduction */
/* Nothing in this minimal model... */
io_write_attribute_s(h_grpsph, "Thermal Conductivity Model", "No treatment");
io_write_attribute_s(h_grpsph, "Viscosity Model",
"Minimal treatment as in Monaghan (1992)");
/* Time integration properties */
io_write_attribute_f(h_grpsph, "Maximal Delta u change over dt",
const_max_u_change);
}
/**
* @brief Are we writing entropy in the internal energy field ?
*
* @return 1 if entropy is in 'internal energy', 0 otherwise.
*/
int writeEntropyFlag() { return 0; }
#endif /* SWIFT_MINIMAL_MULTI_MAT_HYDRO_IO_H */
/*******************************************************************************
* This file is part of SWIFT.
* Copyright (c) 2016 Matthieu Schaller (matthieu.schaller@durham.ac.uk)
*
* 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_MINIMAL_MULTI_MAT_HYDRO_PART_H
#define SWIFT_MINIMAL_MULTI_MAT_HYDRO_PART_H
/**
* @file MinimalMultiMat/hydro_part.h
* @brief MinimalMultiMat conservative implementation of SPH (Particle definition)
*
* The thermal variable is the internal energy (u). Simple constant
* viscosity term without switches is implemented. No thermal conduction
* term is implemented.
*
* This corresponds to equations (43), (44), (45), (101), (103) and (104) with
* \f$\beta=3\f$ and \f$\alpha_u=0\f$ of Price, D., Journal of Computational
* Physics, 2012, Volume 231, Issue 3, pp. 759-794.
*/
#include "chemistry_struct.h"
#include "cooling_struct.h"
/**
* @brief Particle fields not needed during the SPH loops over neighbours.
*
* This structure contains the particle fields that are not used in the
* density or force loops. Quantities should be used in the kick, drift and
* potentially ghost tasks only.
*/
struct xpart {
/*! Offset between current position and position at last tree rebuild. */
float x_diff[3];
/*! Offset between the current position and position at the last sort. */
float x_diff_sort[3];
/*! Velocity at the last full step. */
float v_full[3];
/*! Gravitational acceleration at the last full step. */
float a_grav[3];
/*! Internal energy at the last full step. */
float u_full;
/*! Additional data used to record cooling information */
struct cooling_xpart_data cooling_data;
} SWIFT_STRUCT_ALIGN;
/**
* @brief Particle fields for the SPH particles
*
* The density and force substructures are used to contain variables only used
* within the density and force loops over neighbours. All more permanent
* variables should be declared in the main part of the part structure,
*/
struct part {
/*! Particle unique ID. */
long long id;
/*! Pointer to corresponding gravity part. */
struct gpart* gpart;
/*! Particle position. */
double x[3];
/*! Particle predicted velocity. */
float v[3];
/*! Particle acceleration. */
float a_hydro[3];
/*! Particle mass. */
float mass;
/*! Particle smoothing length. */
float h;
/*! Particle internal energy. */
float u;
/*! Time derivative of the internal energy. */
float u_dt;
/*! Particle density. */
float rho;
/*! Material identifier flag (integer) */
material_id mat_id;
/* Store density/force specific stuff. */
union {
/**
* @brief Structure for the variables only used in the density loop over
* neighbours.
*
* Quantities in this sub-structure should only be accessed in the density
* loop over neighbours and the ghost task.
*/
struct {
/*! Neighbour number count. */
float wcount;
/*! Derivative of the neighbour number with respect to h. */
float wcount_dh;
/*! Derivative of density with respect to h */
float rho_dh;
} density;
/**
* @brief Structure for the variables only used in the force loop over
* neighbours.
*
* Quantities in this sub-structure should only be accessed in the force
* loop over neighbours and the ghost, drift and kick tasks.
*/
struct {
/*! "Grad h" term */
float f;
/*! Particle pressure. */
float pressure;
/*! Particle soundspeed. */
float soundspeed;
/*! Particle signal velocity */
float v_sig;
/*! Time derivative of smoothing length */
float h_dt;
} force;
};
/* Chemistry information */
struct chemistry_part_data chemistry_data;
/*! Time-step length */
timebin_t time_bin;
#ifdef SWIFT_DEBUG_CHECKS
/* Time of the last drift */
integertime_t ti_drift;
/* Time of the last kick */
integertime_t ti_kick;
#endif
} SWIFT_STRUCT_ALIGN;
#endif /* SWIFT_MINIMAL_MULTI_MAT_HYDRO_PART_H */
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
#include "./hydro/Gizmo/hydro_io.h" #include "./hydro/Gizmo/hydro_io.h"
#elif defined(SHADOWFAX_SPH) #elif defined(SHADOWFAX_SPH)
#include "./hydro/Shadowswift/hydro_io.h" #include "./hydro/Shadowswift/hydro_io.h"
#elif defined(MINIMAL_MULTI_MAT_SPH)
#include "./hydro/MinimalMultiMat/hydro_io.h"
#else #else
#error "Invalid choice of SPH variant" #error "Invalid choice of SPH variant"
#endif #endif
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment