diff --git a/src/cooling/grackle/cooling.h b/src/cooling/grackle/cooling.h index 57ca5ed87ae087e8578fe1f059a4c96e1471893a..5b968d4fbed9a6a17c1b66bd36fc9ff85d95b681 100644 --- a/src/cooling/grackle/cooling.h +++ b/src/cooling/grackle/cooling.h @@ -271,179 +271,180 @@ __attribute__((always_inline)) INLINE static void cooling_print_backend( } /** - * @brief allocate required field - * - * @param data the #grackle_field_data + * @brief copy a single field from the grackle data to a #xpart + * + * @param data The #grackle_field_data + * @param xp The #xpart + * @param rho Particle density + * @param field The field to copy */ -__attribute__((always_inline)) INLINE static void cooling_malloc_data( - grackle_field_data* data) { - -#if COOLING_GRACKLE_MODE >= 1 - /* primordial chemistry >= 1 */ - data->HI_density = malloc(sizeof(gr_float)); - data->HII_density = malloc(sizeof(gr_float)); - data->HeI_density = malloc(sizeof(gr_float)); - data->HeII_density = malloc(sizeof(gr_float)); - data->HeIII_density = malloc(sizeof(gr_float)); - data->e_density = malloc(sizeof(gr_float)); -#endif // MODE >= 1 - -#if COOLING_GRACKLE_MODE >= 2 - /* primordial chemistry >= 2 */ - data->HM_density = malloc(sizeof(gr_float)); - data->H2I_density = malloc(sizeof(gr_float)); - data->H2II_density = malloc(sizeof(gr_float)); -#endif // MODE 2 - -#if COOLING_GRACKLE_MODE >= 3 - /* primordial chemistry >= 3 */ - data->DI_density = malloc(sizeof(gr_float)); - data->DII_density = malloc(sizeof(gr_float)); - data->HDI_density = malloc(sizeof(gr_float)); -#endif // MODE >= 3 - - /* metal cooling = 1 */ - data->metal_density = malloc(sizeof(gr_float)); +#define cooling_copy_field_from_grackle(data, xp, rho, field) \ + xp->cooling_data.field ## _frac = *data.field ## _density / rho; - /* /\* volumetric heating rate *\/ */ - /* data->volumetric_heating_rate = NULL; */ +/** + * @brief copy a single field from a #xpart to the grackle data + * + * @param data The #grackle_field_data + * @param xp The #xpart + * @param rho Particle density + * @param field The field to copy + */ +#define cooling_copy_field_to_grackle(data, xp, rho, field) \ + gr_float grackle_ ## field = xp->cooling_data.field ## _frac * rho; \ + data.field ## _density = &grackle_ ## field; - /* /\* specific heating rate *\/ */ - /* data->specific_heating_rate = NULL; */ -} /** - * @brief free the allocated memory + * @brief copy a #xpart to the grackle data * - * @param data the #grackle_field_data + * Warning this function creates some variable, therefore the grackle call + * should be in a block that still has the variables. + * + * @param data The #grackle_field_data + * @param p The #part + * @param xp The #xpart + * @param rho Particle density */ - -__attribute__((always_inline)) INLINE static void cooling_free_data( - grackle_field_data* data) { - -#if COOLING_GRACKLE_MODE >= 1 - /* primordial chemistry >= 1 */ - free(data->HI_density); - free(data->HII_density); - free(data->HeI_density); - free(data->HeII_density); - free(data->HeIII_density); - free(data->e_density); -#endif // MODE >= 1 - -#if COOLING_GRACKLE_MODE >= 2 - /* primordial chemistry >= 2 */ - free(data->HM_density); - free(data->H2I_density); - free(data->H2II_density); -#endif // MODE 2 - -#if COOLING_GRACKLE_MODE >= 3 - /* primordial chemistry >= 3 */ - free(data->DI_density); - free(data->DII_density); - free(data->HDI_density); -#endif // MODE >= 3 - - /* metal cooling = 1 */ - free(data->metal_density); - - /* /\* volumetric heating rate *\/ */ - /* data->volumetric_heating_rate = NULL; */ - - /* /\* specific heating rate *\/ */ - /* data->specific_heating_rate = NULL; */ -} +#if COOLING_GRACKLE_MODE > 0 +#define cooling_copy_to_grackle1(data, p, xp, rho) \ + cooling_copy_field_to_grackle(data, xp, rho, HI); \ + cooling_copy_field_to_grackle(data, xp, rho, HII); \ + cooling_copy_field_to_grackle(data, xp, rho, HeI); \ + cooling_copy_field_to_grackle(data, xp, rho, HeII); \ + cooling_copy_field_to_grackle(data, xp, rho, HeIII); \ + cooling_copy_field_to_grackle(data, xp, rho, e); +#else +#define cooling_copy_to_grackle1(data, p, xp, rho) +#endif /** - * @brief copy xp to data - * - * requires the particle to have been transformed into density + * @brief copy a #xpart to the grackle data * - * @param data the #grackle_field_data - * @param xp the #xpart + * Warning this function creates some variable, therefore the grackle call + * should be in a block that still has the variables. + * + * @param data The #grackle_field_data + * @param p The #part + * @param xp The #xpart + * @param rho Particle density */ -__attribute__((always_inline)) INLINE static void cooling_copy_to_data( - grackle_field_data* data, const struct part* p, - const struct xpart* xp, const gr_float rho) { - -#if COOLING_GRACKLE_MODE >= 1 - /* primordial chemistry >= 1 */ - data->HI_density[0] = xp->cooling_data.HI_frac * rho; - data->HII_density[0] = xp->cooling_data.HII_frac * rho; - data->HeI_density[0] = xp->cooling_data.HeI_frac * rho; - data->HeII_density[0] = xp->cooling_data.HeII_frac * rho; - data->HeIII_density[0] = xp->cooling_data.HeIII_frac * rho; - data->e_density[0] = xp->cooling_data.e_frac * rho; -#endif // MODE >= 1 - -#if COOLING_GRACKLE_MODE >= 2 - /* primordial chemistry >= 2 */ - data->HM_density[0] = xp->cooling_data.HM_frac * rho; - data->H2I_density[0] = xp->cooling_data.H2I_frac * rho; - data->H2II_density[0] = xp->cooling_data.H2II_frac * rho; -#endif // MODE 2 - -#if COOLING_GRACKLE_MODE >= 3 - /* primordial chemistry >= 3 */ - data->DI_density[0] = xp->cooling_data.DI_frac * rho; - data->DII_density[0] = xp->cooling_data.DII_frac * rho; - data->HDI_density[0] = xp->cooling_data.HDI_frac * rho; -#endif // MODE >= 3 - - /* metal cooling = 1 */ - const float Z = chemistry_metal_mass_fraction(p, xp); - data->metal_density[0] = Z * rho; - - /* volumetric heating rate */ - data->volumetric_heating_rate = NULL; - - /* specific heating rate */ - data->specific_heating_rate = NULL; -} +#if COOLING_GRACKLE_MODE > 1 +#define cooling_copy_to_grackle2(data, p, xp, rho) \ + cooling_copy_field_to_grackle(data, xp, rho, HM); \ + cooling_copy_field_to_grackle(data, xp, rho, H2I); \ + cooling_copy_field_to_grackle(data, xp, rho, H2II); +#else +#define cooling_copy_to_grackle2(data, p, xp, rho) +#endif /** - * @brief copy data to xp + * @brief copy a #xpart to the grackle data * - * @param data the #grackle_field_data - * @param xp the #xpart + * Warning this function creates some variable, therefore the grackle call + * should be in a block that still has the variables. + * + * @param data The #grackle_field_data + * @param p The #part + * @param xp The #xpart + * @param rho Particle density */ -__attribute__((always_inline)) INLINE static void cooling_copy_to_particle( - const grackle_field_data* data, struct xpart* xp, const gr_float rho) { +#if COOLING_GRACKLE_MODE > 2 +#define cooling_copy_to_grackle3(data, p, xp, rho) \ + cooling_copy_field_to_grackle(data, xp, rho, DI); \ + cooling_copy_field_to_grackle(data, xp, rho, DII); \ + cooling_copy_field_to_grackle(data, xp, rho, HDI); +#else +#define cooling_copy_to_grackle3(data, p, xp, rho) +#endif -#if COOLING_GRACKLE_MODE >= 1 - /* primordial chemistry >= 1 */ - xp->cooling_data.HI_frac = data->HI_density[0] / rho; - xp->cooling_data.HII_frac = data->HII_density[0] / rho; - xp->cooling_data.HeI_frac = data->HeI_density[0] / rho; - xp->cooling_data.HeII_frac = data->HeII_density[0] / rho; - xp->cooling_data.HeIII_frac = data->HeIII_density[0] / rho; - xp->cooling_data.e_frac = data->e_density[0] / rho; -#endif // MODE >= 1 +/** + * @brief copy the grackle data to a #xpart + * + * @param data The #grackle_field_data + * @param p The #part + * @param xp The #xpart + * @param rho Particle density + */ +#if COOLING_GRACKLE_MODE > 0 +#define cooling_copy_from_grackle1(data, p, xp, rho) \ + cooling_copy_field_from_grackle(data, xp, rho, HI); \ + cooling_copy_field_from_grackle(data, xp, rho, HII); \ + cooling_copy_field_from_grackle(data, xp, rho, HeI); \ + cooling_copy_field_from_grackle(data, xp, rho, HeII); \ + cooling_copy_field_from_grackle(data, xp, rho, HeIII); \ + cooling_copy_field_from_grackle(data, xp, rho, e); +#else +#define cooling_copy_from_grackle1(data, p, xp, rho) +#endif -#if COOLING_GRACKLE_MODE >= 2 - /* primordial chemistry >= 2 */ - xp->cooling_data.HM_frac = data->HM_density[0] / rho; - xp->cooling_data.H2I_frac = data->H2I_density[0] / rho; - xp->cooling_data.H2II_frac = data->H2II_density[0] / rho; -#endif // MODE 2 +/** + * @brief copy the grackle data to a #xpart + * + * @param data The #grackle_field_data + * @param p The #part + * @param xp The #xpart + * @param rho Particle density + */ +#if COOLING_GRACKLE_MODE > 1 +#define cooling_copy_from_grackle2(data, p, xp, rho) \ + cooling_copy_field_from_grackle(data, xp, rho, HM); \ + cooling_copy_field_from_grackle(data, xp, rho, H2I); \ + cooling_copy_field_from_grackle(data, xp, rho, H2II); +#else +#define cooling_copy_from_grackle2(data, p, xp, rho) +#endif -#if COOLING_GRACKLE_MODE >= 3 - /* primordial chemistry >= 3 */ - xp->cooling_data.DI_frac = data->DI_density[0] / rho; - xp->cooling_data.DII_frac = data->DII_density[0] / rho; - xp->cooling_data.HDI_frac = data->HDI_density[0] / rho; -#endif // MODE >= 3 +/** + * @brief copy the grackle data to a #xpart + * + * @param data The #grackle_field_data + * @param p The #part + * @param xp The #xpart + * @param rho Particle density + */ +#if COOLING_GRACKLE_MODE > 2 +#define cooling_copy_from_grackle3(data, p, xp, rho) \ + cooling_copy_field_from_grackle(data, xp, rho, DI); \ + cooling_copy_field_from_grackle(data, xp, rho, DII); \ + cooling_copy_field_from_grackle(data, xp, rho, HDI); +#else +#define cooling_copy_from_grackle3(data, p, xp, rho) +#endif - /* metal cooling = 1 */ - xp->cooling_data.metal_frac = data->metal_density[0] / rho; - /* /\* volumetric heating rate *\/ */ - /* data->volumetric_heating_rate = NULL; */ +/** + * @brief copy a #xpart to the grackle data + * + * Warning this function creates some variable, therefore the grackle call + * should be in a block that still has the variables. + * + * @param data The #grackle_field_data + * @param p The #part + * @param xp The #xpart + * @param rho Particle density + */ +#define cooling_copy_to_grackle(data, p, xp, rho) \ + cooling_copy_to_grackle1(data, p, xp, rho); \ + cooling_copy_to_grackle2(data, p, xp, rho); \ + cooling_copy_to_grackle3(data, p, xp, rho); \ + gr_float metal_density = chemistry_metal_mass_fraction(p, xp) * rho; \ + data.metal_density = &metal_density; - /* /\* specific heating rate *\/ */ - /* data->specific_heating_rate = NULL; */ -} +/** + * @brief copy a #xpart to the grackle data + * + * Warning this function creates some variable, therefore the grackle call + * should be in a block that still has the variables. + * + * @param data The #grackle_field_data + * @param p The #part + * @param xp The #xpart + * @param rho Particle density + */ +#define cooling_copy_from_grackle(data, p, xp, rho) \ + cooling_copy_from_grackle1(data, p, xp, rho); \ + cooling_copy_from_grackle2(data, p, xp, rho); \ + cooling_copy_from_grackle3(data, p, xp, rho); /** * @brief Compute the cooling rate and update the particle chemistry data @@ -501,11 +502,8 @@ __attribute__((always_inline)) INLINE static gr_float cooling_rate( data.y_velocity = NULL; data.z_velocity = NULL; - /* allocate grackle data */ - cooling_malloc_data(&data); - - /* copy data from particle to grackle data */ - cooling_copy_to_data(&data, p, xp, density); + /* copy to grackle structure */ + cooling_copy_to_grackle(data, p, xp, density); /* solve chemistry with table */ if (solve_chemistry(&units, &data, dt) == 0) { @@ -513,10 +511,7 @@ __attribute__((always_inline)) INLINE static gr_float cooling_rate( } /* copy from grackle data to particle */ - cooling_copy_to_particle(&data, xp, density); - - /* free allocated memory */ - cooling_free_data(&data); + cooling_copy_from_grackle(data, p, xp, density); /* compute rate */ return (energy - energy_before) / dt; @@ -572,11 +567,8 @@ __attribute__((always_inline)) INLINE static gr_float cooling_time( data.y_velocity = NULL; data.z_velocity = NULL; - /* allocate grackle data */ - cooling_malloc_data(&data); - /* copy data from particle to grackle data */ - cooling_copy_to_data(&data, p, xp, density); + cooling_copy_to_grackle(data, p, xp, density); /* Compute cooling time */ gr_float cooling_time; @@ -585,10 +577,7 @@ __attribute__((always_inline)) INLINE static gr_float cooling_time( } /* copy from grackle data to particle */ - cooling_copy_to_particle(&data, xp, density); - - /* free allocated memory */ - cooling_free_data(&data); + cooling_copy_from_grackle(data, p, xp, density); /* compute rate */ return cooling_time;