Commit 13bd7b92 authored by lhausamm's avatar lhausamm
Browse files

Remove Omega in grackle and add metallicity to gear chemistry

parent b4868c7e
...@@ -191,7 +191,6 @@ GrackleCooling: ...@@ -191,7 +191,6 @@ GrackleCooling:
OutputMode: 0 # (optional) Write in output corresponding primordial chemistry mode OutputMode: 0 # (optional) Write in output corresponding primordial chemistry mode
MaxSteps: 10000 # (optional) Max number of step when computing the initial composition MaxSteps: 10000 # (optional) Max number of step when computing the initial composition
ConvergenceLimit: 1e-2 # (optional) Convergence threshold (relative) for initial composition ConvergenceLimit: 1e-2 # (optional) Convergence threshold (relative) for initial composition
Omega: 0.8 # (optional) Over relaxation coefficient for initial composition (< 1 avoid oscillation, > 1 speedup convergence)
# Parameters related to chemistry models ----------------------------------------------- # Parameters related to chemistry models -----------------------------------------------
......
...@@ -51,6 +51,18 @@ chemistry_get_element_name(enum chemistry_element elem) { ...@@ -51,6 +51,18 @@ chemistry_get_element_name(enum chemistry_element elem) {
return chemistry_element_names[elem]; return chemistry_element_names[elem];
} }
/**
* @brief Compute the metal mass fraction
*
* @param p Pointer to the particle data.
* @param xp Pointer to the extended particle data.
* @param data The global chemistry information.
*/
__attribute__((always_inline)) INLINE static float chemistry_metal_mass_fraction(
const struct part* restrict p, const struct xpart* restrict xp) {
return p->chemistry_data.Z;
}
/** /**
* @brief Initialises the chemistry properties. * @brief Initialises the chemistry properties.
* *
...@@ -145,6 +157,8 @@ __attribute__((always_inline)) INLINE static void chemistry_end_density( ...@@ -145,6 +157,8 @@ __attribute__((always_inline)) INLINE static void chemistry_end_density(
__attribute__((always_inline)) INLINE static void chemistry_first_init_part( __attribute__((always_inline)) INLINE static void chemistry_first_init_part(
struct part* restrict p, struct xpart* restrict xp, struct part* restrict p, struct xpart* restrict xp,
const struct chemistry_global_data* data) { const struct chemistry_global_data* data) {
p->chemistry_data.Z = data->initial_metallicity;
chemistry_init_part(p, data); chemistry_init_part(p, data);
} }
......
...@@ -31,6 +31,7 @@ ...@@ -31,6 +31,7 @@
/* Local includes. */ /* Local includes. */
#include "../config.h" #include "../config.h"
#include "chemistry.h"
#include "cooling_io.h" #include "cooling_io.h"
#include "error.h" #include "error.h"
#include "hydro.h" #include "hydro.h"
...@@ -61,7 +62,7 @@ static double cooling_rate( ...@@ -61,7 +62,7 @@ static double cooling_rate(
* @param xp The #xpart to print * @param xp The #xpart to print
*/ */
__attribute__((always_inline)) INLINE static void cooling_print_fractions( __attribute__((always_inline)) INLINE static void cooling_print_fractions(
struct xpart* restrict xp) { const struct xpart* restrict xp) {
const struct cooling_xpart_data tmp = xp->cooling_data; const struct cooling_xpart_data tmp = xp->cooling_data;
#if COOLING_GRACKLE_MODE > 0 #if COOLING_GRACKLE_MODE > 0
...@@ -82,100 +83,80 @@ __attribute__((always_inline)) INLINE static void cooling_print_fractions( ...@@ -82,100 +83,80 @@ __attribute__((always_inline)) INLINE static void cooling_print_fractions(
message("Metal: %g", tmp.metal_frac); message("Metal: %g", tmp.metal_frac);
} }
#define cooling_check(old, new, limit, print, step, field, field_name) \
({ \
float err = fabsf((old->field - new->field) / new->field); \
if (err > limit) \
{ \
if (print == 1) \
{ \
char *msg = "Step: %5i, Element %5s need to converge: %e"; \
printf(msg, step, field_name, err); \
} \
else if (print == 2) \
{ \
char *msg = "\rStep: %5i, Element %5s need to converge: %e"; \
printf(msg, step, field_name, err); \
} \
return 0; \
} \
})
/** /**
* @brief Check if the equilibrium as been reached * @brief Check if the equilibrium as been reached
* *
* @param old Previous step particle * @param old Previous step particle
* @param xp Current step particle * @param xp Current step particle
* @param limit Convergence limit
* @param print Print message
* @param step Current step
* *
* @return Value of the test * @return Value of the test
*/ */
__attribute__((always_inline)) INLINE static int cooling_check_convergence( __attribute__((always_inline)) INLINE static int cooling_check_convergence(
const struct xpart* restrict old, const struct xpart* restrict xp, const struct xpart* restrict old, const struct xpart* restrict xp,
const float limit) { const float limit, const int print, const int step) {
#if COOLING_GRACKLE_MODE > 0 #if COOLING_GRACKLE_MODE > 0
const struct cooling_xpart_data *old_data = &old->cooling_data; const struct cooling_xpart_data *old_data = &old->cooling_data;
const struct cooling_xpart_data *new_data = &xp->cooling_data; const struct cooling_xpart_data *new_data = &xp->cooling_data;
if (fabsf((old_data->HI_frac - new_data->HI_frac) / new_data->HI_frac) > limit) cooling_check(old_data, new_data, limit, print, step, HI_frac, "HI");
return 0;
if (fabsf((old_data->HII_frac - new_data->HII_frac) / new_data->HII_frac) > limit) cooling_check(old_data, new_data, limit, print, step, HII_frac, "HII");
return 0;
if (fabsf((old_data->HeI_frac - new_data->HeI_frac) / new_data->HeI_frac) > limit) cooling_check(old_data, new_data, limit, print, step, HeI_frac, "HeI");
return 0;
if (fabsf((old_data->HeII_frac - new_data->HeII_frac) / new_data->HeII_frac) > limit) cooling_check(old_data, new_data, limit, print, step, HeII_frac, "HeII");
return 0;
if (fabsf((old_data->HeIII_frac - new_data->HeIII_frac) / new_data->HeIII_frac) > limit) cooling_check(old_data, new_data, limit, print, step, HeIII_frac, "HeIII");
return 0;
if (fabsf((old_data->e_frac - new_data->e_frac) / new_data->e_frac) > limit) cooling_check(old_data, new_data, limit, print, step, e_frac, "e");
return 0;
#endif // COOLING_GRACKLE_MODE > 0 #endif // COOLING_GRACKLE_MODE > 0
#if COOLING_GRACKLE_MODE > 1 #if COOLING_GRACKLE_MODE > 1
if (fabsf((old_data->HM_frac - new_data->HM_frac) / new_data->HM_frac) > limit) cooling_check(old_data, new_data, limit, print, step, HM_frac, "HM");
return 0;
if (fabsf((old_data->H2I_frac - new_data->H2I_frac) / new_data->H2I_frac) > limit) cooling_check(old_data, new_data, limit, print, step, H2I_frac, "H2I");
return 0;
if (fabsf((old_data->H2II_frac - new_data->H2II_frac) / new_data->H2II_frac) > limit) cooling_check(old_data, new_data, limit, print, step, H2II_frac, "H2II");
return 0;
#endif // COOLING_GRACKLE_MODE > 1 #endif // COOLING_GRACKLE_MODE > 1
#if COOLING_GRACKLE_MODE > 2 #if COOLING_GRACKLE_MODE > 2
if (fabsf((old_data->DI_frac - new_data->DI_frac) / new_data->DI_frac) > limit) cooling_check(old_data, new_data, limit, print, step, DI_frac, "DI");
return 0;
if (fabsf((old_data->DII_frac - new_data->DII_frac) / new_data->DII_frac) > limit)
return 0;
if (fabsf((old_data->HDI_frac - new_data->HDI_frac) / new_data->HDI_frac) > limit)
return 0;
#endif // COOLING_GRACKLE_MODE > 2 cooling_check(old_data, new_data, limit, print, step, DII_frac, "DII");
return 1; cooling_check(old_data, new_data, limit, print, step, HDI_frac, "HDI");
}
__attribute__((always_inline)) INLINE static void cooling_over_relaxation( #endif // COOLING_GRACKLE_MODE > 2
struct xpart* restrict xp, const struct xpart* restrict xp_1, const float coeff) {
#if COOLING_GRACKLE_MODE > 0
struct cooling_xpart_data data = xp->cooling_data;
const struct cooling_xpart_data data_1 = xp_1->cooling_data;
data.HI_frac = data.HI_frac * coeff + data_1.HI_frac * (1. - coeff);
data.HII_frac = data.HII_frac * coeff + data_1.HII_frac * (1. - coeff);
data.HeI_frac = data.HeI_frac * coeff + data_1.HeI_frac * (1. - coeff);
data.HeII_frac = data.HeII_frac * coeff + data_1.HeII_frac * (1. - coeff);
data.HeIII_frac = data.HeIII_frac * coeff + data_1.HeIII_frac * (1. - coeff);
data.e_frac = data.e_frac * coeff + data_1.e_frac * (1. - coeff);
#endif // COOLING_GRACKLE_MODE > 0
#if COOLING_GRACKLE_MODE > 1
data.HM_frac = data.HM_frac * coeff + data_1.HM_frac * (1. - coeff);
data.H2I_frac = data.H2I_frac * coeff + data_1.H2I_frac * (1. - coeff);
data.H2II_frac = data.H2II_frac * coeff + data_1.H2II_frac * (1. - coeff);
#endif
#if COOLING_GRACKLE_MODE > 2
data.DI_frac = data.DI_frac * coeff + data_1.DI_frac * (1. - coeff);
data.DII_frac = data.DII_frac * coeff + data_1.DII_frac * (1. - coeff);
data.HDI_frac = data.HDI_frac * coeff + data_1.HDI_frac * (1. - coeff);
#endif return 1;
} }
/** /**
...@@ -187,24 +168,27 @@ __attribute__((always_inline)) INLINE static void cooling_over_relaxation( ...@@ -187,24 +168,27 @@ __attribute__((always_inline)) INLINE static void cooling_over_relaxation(
*/ */
__attribute__((always_inline)) INLINE static void cooling_compute_equilibrium_fractions( __attribute__((always_inline)) INLINE static void cooling_compute_equilibrium_fractions(
const struct cooling_function_data* restrict cooling, const struct cooling_function_data* restrict cooling,
const struct part* restrict p, struct xpart* restrict xp) { const struct part* restrict p, struct xpart* restrict xp,
const int restart) {
struct cooling_function_data tmp_cooling = *cooling; struct cooling_function_data tmp_cooling = *cooling;
/* disable energy updates */
tmp_cooling.chemistry.with_radiative_cooling = 0;
#if COOLING_GRACKLE_MODE == 0 #if COOLING_GRACKLE_MODE == 0
error("This function should not be called in primordial chemistry = 0"); error("This function should not be called in primordial chemistry = 0");
#endif #endif
/* a few constants */
const float limit = tmp_cooling.convergence_limit;
double dt = 0.1 * fabs(cooling_time(&tmp_cooling, p, xp));
/* define a few variables */ /* define a few variables */
struct xpart xp_1 = *xp; struct xpart xp_1 = *xp;
int step = 0; int step = 0;
int print = 0;
/* a few constants */
const float limit = tmp_cooling.convergence_limit;
const double dt = 0.01 * fabs(cooling_time(&tmp_cooling, p, xp));
/* disable energy updates */
tmp_cooling.chemistry.with_radiative_cooling = 0;
/* compute equilibrium fractions */ /* compute equilibrium fractions */
do { do {
...@@ -212,21 +196,28 @@ __attribute__((always_inline)) INLINE static void cooling_compute_equilibrium_fr ...@@ -212,21 +196,28 @@ __attribute__((always_inline)) INLINE static void cooling_compute_equilibrium_fr
step += 1; step += 1;
xp_1 = *xp; xp_1 = *xp;
#ifdef SWIFT_DEBUG_CHECKS
/* update type printing */
if (step > 0)
print = 2; // clear line
else if (step > 1)
print = 1; // end line
#endif
/* compute cooling rate */ /* compute cooling rate */
cooling_rate(NULL, NULL, &tmp_cooling, p, xp, dt); cooling_rate(NULL, NULL, &tmp_cooling, p, xp, dt);
cooling_over_relaxation(xp, &xp_1, cooling->omega); } while(!cooling_check_convergence(&xp_1, xp, limit, print, step) &&
} while(!cooling_check_convergence(&xp_1, xp, limit) &&
step < tmp_cooling.max_step); step < tmp_cooling.max_step);
if (print > 0)
printf("\n");
/* check if converged */ /* check if converged */
if (step >= cooling->max_step) { if (step >= cooling->max_step) {
error("A particle failed to reach equilibrium. " message("WARNING: A particle failed to reach equilibrium. "
"You can change GrackleCooling:MaxStep or " "You can change GrackleCooling:MaxStep or "
"GrackleCooling:ConvergenceLimit to avoid this problem"); "GrackleCooling:ConvergenceLimit to avoid this problem");
} }
} }
/** /**
...@@ -243,9 +234,6 @@ __attribute__((always_inline)) INLINE static void cooling_first_init_part( ...@@ -243,9 +234,6 @@ __attribute__((always_inline)) INLINE static void cooling_first_init_part(
xp->cooling_data.radiated_energy = 0.f; xp->cooling_data.radiated_energy = 0.f;
/* metal cooling = 1 */
xp->cooling_data.metal_frac = cooling->chemistry.SolarMetalFractionByMass;
#if COOLING_GRACKLE_MODE >= 1 #if COOLING_GRACKLE_MODE >= 1
gr_float zero = 1.e-20; gr_float zero = 1.e-20;
...@@ -275,10 +263,9 @@ __attribute__((always_inline)) INLINE static void cooling_first_init_part( ...@@ -275,10 +263,9 @@ __attribute__((always_inline)) INLINE static void cooling_first_init_part(
xp->cooling_data.HDI_frac = zero; xp->cooling_data.HDI_frac = zero;
#endif // MODE >= 3 #endif // MODE >= 3
#if COOLING_GRACKLE_MODE > 0 #if COOLING_GRACKLE_MODE > 0
/* compute equilibrium */ /* compute equilibrium */
cooling_compute_equilibrium_fractions(cooling, p, xp); cooling_compute_equilibrium_fractions(cooling, p, xp, 0);
#endif #endif
} }
...@@ -417,7 +404,8 @@ __attribute__((always_inline)) INLINE static void cooling_free_data( ...@@ -417,7 +404,8 @@ __attribute__((always_inline)) INLINE static void cooling_free_data(
* @param xp the #xpart * @param xp the #xpart
*/ */
__attribute__((always_inline)) INLINE static void cooling_copy_to_data( __attribute__((always_inline)) INLINE static void cooling_copy_to_data(
grackle_field_data* data, const struct xpart* xp, const gr_float rho) { grackle_field_data* data, const struct part* p,
const struct xpart* xp, const gr_float rho) {
#if COOLING_GRACKLE_MODE >= 1 #if COOLING_GRACKLE_MODE >= 1
/* primordial chemistry >= 1 */ /* primordial chemistry >= 1 */
...@@ -444,7 +432,8 @@ __attribute__((always_inline)) INLINE static void cooling_copy_to_data( ...@@ -444,7 +432,8 @@ __attribute__((always_inline)) INLINE static void cooling_copy_to_data(
#endif // MODE >= 3 #endif // MODE >= 3
/* metal cooling = 1 */ /* metal cooling = 1 */
data->metal_density[0] = xp->cooling_data.metal_frac * rho; const float Z = chemistry_metal_mass_fraction(p, xp);
data->metal_density[0] = Z * rho;
/* volumetric heating rate */ /* volumetric heating rate */
data->volumetric_heating_rate = NULL; data->volumetric_heating_rate = NULL;
...@@ -556,7 +545,7 @@ __attribute__((always_inline)) INLINE static double cooling_rate( ...@@ -556,7 +545,7 @@ __attribute__((always_inline)) INLINE static double cooling_rate(
cooling_malloc_data(&data); cooling_malloc_data(&data);
/* copy data from particle to grackle data */ /* copy data from particle to grackle data */
cooling_copy_to_data(&data, xp, density); cooling_copy_to_data(&data, p, xp, density);
/* solve chemistry with table */ /* solve chemistry with table */
if (solve_chemistry(&units, &data, dt) == 0) { if (solve_chemistry(&units, &data, dt) == 0) {
...@@ -627,7 +616,7 @@ __attribute__((always_inline)) INLINE static gr_float cooling_time( ...@@ -627,7 +616,7 @@ __attribute__((always_inline)) INLINE static gr_float cooling_time(
cooling_malloc_data(&data); cooling_malloc_data(&data);
/* copy data from particle to grackle data */ /* copy data from particle to grackle data */
cooling_copy_to_data(&data, xp, density); cooling_copy_to_data(&data, p, xp, density);
/* Compute cooling time */ /* Compute cooling time */
gr_float cooling_time; gr_float cooling_time;
......
...@@ -156,8 +156,6 @@ __attribute__((always_inline)) INLINE static void cooling_read_parameters( ...@@ -156,8 +156,6 @@ __attribute__((always_inline)) INLINE static void cooling_read_parameters(
cooling->convergence_limit = cooling->convergence_limit =
parser_get_opt_param_double(parameter_file, "GrackleCooling:ConvergenceLimit", 1e-2); parser_get_opt_param_double(parameter_file, "GrackleCooling:ConvergenceLimit", 1e-2);
cooling->omega =
parser_get_opt_param_double(parameter_file, "GrackleCooling:Omega", 0.8);
} }
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment