diff --git a/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-All.md b/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-All.md index 9129bf3665..833a1ff590 100644 --- a/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-All.md +++ b/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-All.md @@ -54,6 +54,7 @@ For variables with `Default/Min/Max` labeled as `Depend`, click the parameter na | [[ DT__CR_DIFFUSION \| Runtime-Parameters:-Timestep#DT__CR_DIFFUSION ]] | 3.0e-1 | 0.0 | None | dt criterion: cosmic-ray diffusion CFL factor [0.3] ##CR_DIFFUSION only## | | [[ DT__FLUID \| Runtime-Parameters:-Timestep#DT__FLUID ]] | -1.0 | None | None | dt criterion: fluid solver CFL factor (<0=auto) [-1.0] | | [[ DT__FLUID_INIT \| Runtime-Parameters:-Timestep#DT__FLUID_INIT ]] | -1.0 | None | None | dt criterion: DT__FLUID at the first step (<0=auto) [-1.0] | +| [[ DT__GRACKLE_COOLING \| Runtime-Parameters:-Timestep#DT__GRACKLE_COOLING ]] | -1.0 | None | None | dt criterion: factor for Grackle cooling time (<0=off) [-1.0] ##SUPPORT_GRACKLE only## | | [[ DT__GRAVITY \| Runtime-Parameters:-Timestep#DT__GRAVITY ]] | -1.0 | None | None | dt criterion: gravity solver safety factor (<0=auto) [-1.0] | | DT__HYBRID_CFL | -1.0 | None | None | dt criterion: hybrid solver CFL factor (<0=auto) (diffusion) [-1.0] ## ELBDM_HYBRID ONLY## | | DT__HYBRID_CFL_INIT | -1.0 | None | None | dt criterion: DT__HYBRID_CFL in the first step (<0=auto) [-1.0] ## ELBDM_HYBRID ONLY## | @@ -122,16 +123,19 @@ For variables with `Default/Min/Max` labeled as `Depend`, click the parameter na | [[ GFUNC_COEFF0 \| Runtime-Parameters:-Gravity#GFUNC_COEFF0 ]] | -1.0 | None | None | Green's function coefficient at the origin for the isolated BC (<0=auto) [-1.0] | | [[ GPU_NSTREAM \| Runtime-Parameters:-GPU#GPU_NSTREAM ]] | -1 | None | None | number of CUDA streams for the asynchronous memory copy in GPU (<=0=auto) [-1] | | [[ GRACKLE_ACTIVATE \| Runtime-Parameters:-Chemistry-and-Radiation#GRACKLE_ACTIVATE ]] | 1 | None | None | enable Grackle [1] | -| GRACKLE_CIE_COOLING | 0 | None | None | 0: off; 1:on | +| [[ GRACKLE_CIE_COOLING \| Runtime-Parameters:-Chemistry-and-Radiation#GRACKLE_CIE_COOLING ]] | 0 | None | None | map to "cie_cooling" [0] | | [[ GRACKLE_CLOUDY_TABLE \| Runtime-Parameters:-Chemistry-and-Radiation#GRACKLE_CLOUDY_TABLE ]] | None | None | None | "grackle_data_file" | | [[ GRACKLE_CMB_FLOOR \| Runtime-Parameters:-Chemistry-and-Radiation#GRACKLE_CMB_FLOOR ]] | 1 | None | None | map to "cmb_temperature_floor" [1] | | [[ GRACKLE_COOLING \| Runtime-Parameters:-Chemistry-and-Radiation#GRACKLE_COOLING ]] | 1 | None | None | map to "with_radiative_cooling" [1] | -| GRACKLE_H2_OPA_APPROX | 0 | 0 | 1 | H2 opacity from Ripamonti+04; 0:off, 1:Ripomonti+04 | +| [[ GRACKLE_H2_OPA_APPROX \| Runtime-Parameters:-Chemistry-and-Radiation#GRACKLE_H2_OPA_APPROX ]] | 0 | 0 | 1 | map to "h2_optical_depth_approximation" (0=off, 1=Ripomonti+04) [0] | +| [[ GRACKLE_HYDROGEN_MFRAC \| Runtime-Parameters:-Chemistry-and-Radiation#GRACKLE_HYDROGEN_MFRAC ]] | 0.76 | 0.0 | 1.0 | map to "HydrogenFractionByMass" (NOT set to Grackle when GRACKLE_PRIMORDIAL==0) [0.76] | | [[ GRACKLE_METAL \| Runtime-Parameters:-Chemistry-and-Radiation#GRACKLE_METAL ]] | 0 | None | None | map to "metal_cooling" (must increase NCOMP_PASSIVE_USER by 1) [0] | | [[ GRACKLE_PE_HEATING \| Runtime-Parameters:-Chemistry-and-Radiation#GRACKLE_PE_HEATING ]] | 0 | None | None | map to "photoelectric_heating" [0] | -| [[ GRACKLE_PE_HEATING_RATE \| Runtime-Parameters:-Chemistry-and-Radiation#GRACKLE_PE_HEATING_RATE ]] | 8.5e-26 | 0.0 | None | map to "photoelectric_heating_rate (in erg/cm^3/s)" [8.5e-26] | -| [[ GRACKLE_PRIMORDIAL \| Runtime-Parameters:-Chemistry-and-Radiation#GRACKLE_PRIMORDIAL ]] | 0 | 0 | 3 | map to "primordial_chemistry" (0=Cloudy, 1/2/3=6-/9-/12-species) [0] (must increase NCOMP_PASSIVE_USER by 6/9/12, respectively) | -| GRACKLE_THREE_BODY_RATE | 0 | 0 | 5 | used Glover+08 rate | +| [[ GRACKLE_PE_HEATING_RATE \| Runtime-Parameters:-Chemistry-and-Radiation#GRACKLE_PE_HEATING_RATE ]] | 8.5e-26 | 0.0 | None | map to "photoelectric_heating_rate" (in erg/cm^3/s/n_H) [8.5e-26] | +| [[ GRACKLE_PRIMORDIAL \| Runtime-Parameters:-Chemistry-and-Radiation#GRACKLE_PRIMORDIAL ]] | 0 | 0 | 3 | map to "primordial_chemistry" (0=Cloudy, 1/2/3=6-/9-/12-species) (must increase NCOMP_PASSIVE_USER by 6/9/12, respectively) [0] | +| [[ GRACKLE_THREE_BODY_RATE \| Runtime-Parameters:-Chemistry-and-Radiation#GRACKLE_THREE_BODY_RATE ]] | 0 | 0 | 5 | map to "three_body_rate" (0=Abel+02, 1=Palla+83, 2=Cohen+83, 3=Flower+07, 4=Glover+08, 5=Forrey+13) [0] | +| [[ GRACKLE_USE_S_HEATING_RATE \| Runtime-Parameters:-Chemistry-and-Radiation#GRACKLE_USE_S_HEATING_RATE ]] | 0 | None | None | map to "use_specific_heating_rate" [0] | +| [[ GRACKLE_USE_V_HEATING_RATE \| Runtime-Parameters:-Chemistry-and-Radiation#GRACKLE_USE_V_HEATING_RATE ]] | 0 | None | None | map to "use_volumetric_heating_rate" [0] | | [[ GRACKLE_UV \| Runtime-Parameters:-Chemistry-and-Radiation#GRACKLE_UV ]] | 0 | None | None | map to "UVbackground" [0] | | [[ GRACKLE_VERBOSE \| Runtime-Parameters:-Chemistry-and-Radiation#GRACKLE_VERBOSE ]] | 1 | None | None | map to "grackle_verbose" [1] | @@ -229,6 +233,7 @@ For variables with `Default/Min/Max` labeled as `Depend`, click the parameter na | [[ OPT__FIXUP_FLUX \| Runtime-Parameters:-Hydro#OPT__FIXUP_FLUX ]] | Depend | Depend | Depend | correct coarse grids by the fine-grid boundary fluxes [1] ##HYDRO and ELBDM ONLY## | | [[ OPT__FIXUP_RESTRICT \| Runtime-Parameters:-Hydro#OPT__FIXUP_RESTRICT ]] | 1 | None | None | correct coarse grids by averaging the fine-grid data [1] | | [[ OPT__FLAG_ANGULAR \| Runtime-Parameters:-Refinement#OPT__FLAG_ANGULAR ]] | 0 | None | None | flag: angular resolution (Input__Flag_AngularResolution) [0] | +| [[ OPT__FLAG_COOLING_LEN \| Runtime-Parameters:-Refinement#OPT__FLAG_COOLING_LEN ]] | 0 | None | None | flag: cooling length (Input__Flag_CoolingLen) [0] ##HYDRO+SUPPORT_GRACKLE ONLY## | | [[ OPT__FLAG_CRAY \| Runtime-Parameters:-Refinement#OPT__FLAG_CRAY ]] | 0 | None | None | flag: cosmic-ray energy (Input__Flag_CRay) [0] ##COSMIC_RAY ONLY## | | [[ OPT__FLAG_CURRENT \| Runtime-Parameters:-Refinement#OPT__FLAG_CURRENT ]] | 0 | None | None | flag: current density in MHD (Input__Flag_Current) [0] ##MHD ONLY## | | OPT__FLAG_ENGY_DENSITY | 0 | None | None | flag: energy density (Input_Flag_EngyDensity) [0] ##ELBDM ONLY## | @@ -289,6 +294,9 @@ For variables with `Default/Min/Max` labeled as `Depend`, click the parameter na | [[ OPT__OUTPUT_DIVVEL \| Runtime-Parameters:-Outputs#OPT__OUTPUT_DIVVEL ]] | 0 | None | None | output divergence(velocity) [0] ##HYDRO ONLY## | | [[ OPT__OUTPUT_ENTHALPY \| Runtime-Parameters:-Outputs#OPT__OUTPUT_ENTHALPY ]] | 1 | None | None | output reduced enthalpy [1] ##SRHD ONLY## | | [[ OPT__OUTPUT_ENTR \| Runtime-Parameters:-Outputs#OPT__OUTPUT_ENTR ]] | 0 | None | None | output gas entropy [0] ##HYDRO ONLY## | +| [[ OPT__OUTPUT_GRACKLE_MU \| Runtime-Parameters:-Outputs#OPT__OUTPUT_GRACKLE_MU ]] | 0 | None | None | output the mean molecular weight calculated by Grackle [0] ##SUPPORT_GRACKLE only## | +| [[ OPT__OUTPUT_GRACKLE_TCOOL \| Runtime-Parameters:-Outputs#OPT__OUTPUT_GRACKLE_TCOOL ]] | 0 | None | None | output the cooling time calculated by Grackle [0] ##SUPPORT_GRACKLE only## | +| [[ OPT__OUTPUT_GRACKLE_TEMP \| Runtime-Parameters:-Outputs#OPT__OUTPUT_GRACKLE_TEMP ]] | 0 | None | None | output the temperature calculated by Grackle [0] ##SUPPORT_GRACKLE only## | | [[ OPT__OUTPUT_LORENTZ \| Runtime-Parameters:-Outputs#OPT__OUTPUT_LORENTZ ]] | 0 | None | None | output Lorentz factor [0] ##SRHD ONLY## | | [[ OPT__OUTPUT_MACH \| Runtime-Parameters:-Outputs#OPT__OUTPUT_MACH ]] | 0 | None | None | output mach number [0] ##HYDRO ONLY## | | [[ OPT__OUTPUT_MODE \| Runtime-Parameters:-Outputs#OPT__OUTPUT_MODE ]] | -1 | 1 | 3 | (1=const step, 2=const dt, 3=dump table) -> edit "Input__DumpTable" for 3 | @@ -341,6 +349,7 @@ For variables with `Default/Min/Max` labeled as `Depend`, click the parameter na | [[ OPT__UM_IC_NLEVEL \| Runtime-Parameters:-Initial-Conditions#OPT__UM_IC_NLEVEL ]] | 1 | 1 | None | number of AMR levels UM_IC [1] --> edit "Input__UM_IC_RefineRegion" if >1 | | [[ OPT__UM_IC_NVAR \| Runtime-Parameters:-Initial-Conditions#OPT__UM_IC_NVAR ]] | Depend | Depend | Depend | number of variables in UM_IC: (1~NCOMP_TOTAL; <=0=auto) [HYDRO=5+passive/ELBDM=2] | | [[ OPT__UM_IC_REFINE \| Runtime-Parameters:-Initial-Conditions#OPT__UM_IC_REFINE ]] | 1 | None | None | refine UM_IC from level OPT__UM_IC_LEVEL to MAX_LEVEL [1] | +| [[ OPT__UNFREEZE_GRACKLE \| Runtime-Parameters:-Chemistry-and-Radiation#OPT__UNFREEZE_GRACKLE ]] | 0 | None | None | allow the evolution by Grackle solver when the fluid is frozen (for OPT__FREEZE_FLUID==1 only) [0] | | [[ OPT__UNIT \| Runtime-Parameters:-Units#OPT__UNIT ]] | 0 | None | None | specify code units -> must set exactly 3 basic units below [0] ##USELESS FOR COMOVING## | | [[ OPT__VERBOSE \| Runtime-Parameters:-Miscellaneous#OPT__VERBOSE ]] | 0 | None | None | output the simulation progress in detail [0] | | [[ OUTPUT_DIR \| Runtime-Parameters:-Outputs#OUTPUT_DIR ]] | "." | None | None | set the output directory [.] | @@ -404,7 +413,7 @@ For variables with `Default/Min/Max` labeled as `Depend`, click the parameter na # T | Name | Default | Min | Max | Short description | | :--- | :--- | :--- | :--- | :--- | -| [[ TESTPROB_ID \| Runtime-Parameters:-General#TESTPROB_ID ]] | 0 | 0 | None | test problem ID [0]
0: none
1: HYDRO blast wave [+MHD]
2: HYDRO acoustic wave
3: HYDRO Bondi accretion (+GRAVITY)
4: HYDRO cluster merger vs. Flash (+GRAVITY & PARTICLE)
5: HYDRO AGORA isolated galaxy (+GRAVITY & PARTICLE & STAR_FORMATION & GRACKLE)
6: HYDRO caustic wave
7: HYDRO spherical collapse (+GRAVITY & COMOVING)
8: HYDRO Kelvin Helmholtz instability
9: HYDRO Riemann problems [+MHD]
10: HYDRO jet(s)
11: HYDRO Plummer cloud(s) (+GRAVITY & PARTICLE)
12: HYDRO gravity (+GRAVITY)
13: HYDRO MHD Arnold-Beltrami-Childress (ABC) flow (+MHD)
14: HYDRO MHD Orszag-Tang vortex (+MHD)
15: HYDRO MHD linear wave (+MHD)
16: HYDRO Jeans instability (+GRAVITY) [+MHD]
17: HYDRO particle in equilibrium (+GRAVITY & PARTICLE)
19: HYDRO energy power spectrum
20: HYDRO MHD Cosmic Ray Soundwave
21: HYDRO MHD Cosmic Ray Shocktube
23: HYDRO MHD Cosmic Ray Diffusion
100: HYDRO CDM cosmological simulation (+GRAVITY & COMOVING & PARTICLE)
101: HYDRO Zeldovich pancake collapse (+GRAVITY & COMOVING & PARTICLE)
1000: ELBDM external potential (+GRAVITY)
1001: ELBDM Jeans instability in the comoving frame (+GRAVITY, +COMOVING)
1002: ELBDM Jeans instability in the physical frame (+GRAVITY)
1003: ELBDM soliton merger (+GRAVITY)
1004: ELBDM self-similar halo (+GRAVITY, +COMOVING)
1005: ELBDM rotating vortex pair
1006: ELBDM vortex pair in linear motion
1007: ELBDM halo extracted from a large-scale structure simulation (+GRAVITY)
1008: ELBDM 1D Gaussian wave packet
1009: ELBDM large-scale structure simulation (+GRAVITY, +COMOVING)
1010: ELBDM plane wave
1011: ELBDM small wave perturbations on homogeneous background | +| [[ TESTPROB_ID \| Runtime-Parameters:-General#TESTPROB_ID ]] | 0 | 0 | None | test problem ID [0]
0: none
1: HYDRO blast wave [+MHD]
2: HYDRO acoustic wave
3: HYDRO Bondi accretion (+GRAVITY)
4: HYDRO cluster merger vs. Flash (+GRAVITY & PARTICLE)
5: HYDRO AGORA isolated galaxy (+GRAVITY & PARTICLE & STAR_FORMATION & GRACKLE)
6: HYDRO caustic wave
7: HYDRO spherical collapse (+GRAVITY & COMOVING)
8: HYDRO Kelvin Helmholtz instability
9: HYDRO Riemann problems [+MHD]
10: HYDRO jet(s)
11: HYDRO Plummer cloud(s) (+GRAVITY & PARTICLE)
12: HYDRO gravity (+GRAVITY)
13: HYDRO MHD Arnold-Beltrami-Childress (ABC) flow (+MHD)
14: HYDRO MHD Orszag-Tang vortex (+MHD)
15: HYDRO MHD linear wave (+MHD)
16: HYDRO Jeans instability (+GRAVITY) [+MHD]
17: HYDRO particle in equilibrium (+GRAVITY & PARTICLE)
19: HYDRO energy power spectrum
20: HYDRO MHD Cosmic Ray Soundwave
21: HYDRO MHD Cosmic Ray Shocktube
23: HYDRO MHD Cosmic Ray Diffusion
24: HYDRO Grackle Test (+SUPPORT_GRACKLE)
100: HYDRO CDM cosmological simulation (+GRAVITY & COMOVING & PARTICLE)
101: HYDRO Zeldovich pancake collapse (+GRAVITY & COMOVING & PARTICLE)
1000: ELBDM external potential (+GRAVITY)
1001: ELBDM Jeans instability in the comoving frame (+GRAVITY, +COMOVING)
1002: ELBDM Jeans instability in the physical frame (+GRAVITY)
1003: ELBDM soliton merger (+GRAVITY)
1004: ELBDM self-similar halo (+GRAVITY, +COMOVING)
1005: ELBDM rotating vortex pair
1006: ELBDM vortex pair in linear motion
1007: ELBDM halo extracted from a large-scale structure simulation (+GRAVITY)
1008: ELBDM 1D Gaussian wave packet
1009: ELBDM large-scale structure simulation (+GRAVITY, +COMOVING)
1010: ELBDM plane wave
1011: ELBDM small wave perturbations on homogeneous background | # U | Name | Default | Min | Max | Short description | diff --git a/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-Chemistry-and-Radiation.md b/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-Chemistry-and-Radiation.md index e097fd3a77..8588f2e2b1 100644 --- a/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-Chemistry-and-Radiation.md +++ b/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-Chemistry-and-Radiation.md @@ -9,6 +9,13 @@ Parameters described on this page: [GRACKLE_PE_HEATING](#GRACKLE_PE_HEATING),   [GRACKLE_PE_HEATING_RATE](#GRACKLE_PE_HEATING_RATE),   [GRACKLE_CLOUDY_TABLE](#GRACKLE_CLOUDY_TABLE)   +[GRACKLE_THREE_BODY_RATE](#GRACKLE_THREE_BODY_RATE)   +[GRACKLE_CIE_COOLING](#GRACKLE_CIE_COOLING)   +[GRACKLE_H2_OPA_APPROX](#GRACKLE_H2_OPA_APPROX)   +[GRACKLE_USE_V_HEATING_RATE](#GRACKLE_USE_V_HEATING_RATE)   +[GRACKLE_USE_S_HEATING_RATE](#GRACKLE_USE_S_HEATING_RATE)   +[GRACKLE_HYDROGEN_MFRAC](#GRACKLE_HYDROGEN_MFRAC)   +[OPT__UNFREEZE_GRACKLE](#OPT__UNFREEZE_GRACKLE)   Parameters below are shown in the format:   **`Name`   (Valid Values)   [Default Value]** @@ -24,28 +31,28 @@ Only applicable when enabling the compilation option * #### `GRACKLE_VERBOSE`   (0=off, 1=on)   [1] * **Description:** -Map to the "grackle_verbose" option in GRACKLE. +Map to the ["grackle_verbose" option in GRACKLE](https://grackle.readthedocs.io/en/latest/Interaction.html#enabling-output). * **Restriction:** * #### `GRACKLE_COOLING`   (0=off, 1=on)   [1] * **Description:** -Map to the "with_radiative_cooling" runtime parameter in GRACKLE. +Map to the ["with_radiative_cooling" runtime parameter in GRACKLE](https://grackle.readthedocs.io/en/latest/Parameters.html#c.with_radiative_cooling). * **Restriction:** * #### `GRACKLE_PRIMORDIAL`   (0=Cloudy, 1=6-species, 2=9-species, 3=12-species)   [0] * **Description:** -Map to the "primordial_chemistry" runtime parameter in GRACKLE. +Map to the ["primordial_chemistry" runtime parameter in GRACKLE](https://grackle.readthedocs.io/en/latest/Parameters.html#c.primordial_chemistry). One must increase [[--passive | Installation:-Option-List#--passive]] -by 3, 6, or 9 for GRACKLE_PRIMORDIAL=1, 2, or 3, respectively. +by 6, 9, or 12 for GRACKLE_PRIMORDIAL=1, 2, or 3, respectively. * **Restriction:** * #### `GRACKLE_METAL`   (0=off, 1=on)   [0] * **Description:** -Map to the "metal_cooling" runtime parameter in GRACKLE. One must increase +Map to the ["metal_cooling" runtime parameter in GRACKLE](https://grackle.readthedocs.io/en/latest/Parameters.html#c.metal_cooling). One must increase [[--passive | Installation:-Option-List#--passive]] by 1 and initialize the field `Metal` using the field index `Idx_Metal` properly. * **Restriction:** @@ -53,33 +60,81 @@ by 1 and initialize the field `Metal` using the field index `Idx_Metal` properly * #### `GRACKLE_UV`   (0=off, 1=on)   [0] * **Description:** -Map to the "UVbackground" runtime parameter in GRACKLE. +Map to the ["UVbackground" runtime parameter in GRACKLE](https://grackle.readthedocs.io/en/latest/Parameters.html#c.UVbackground). * **Restriction:** * #### `GRACKLE_CMB_FLOOR`   (0=off, 1=on)   [1] * **Description:** -Map to the "cmb_temperature_floor" runtime parameter in GRACKLE. +Map to the ["cmb_temperature_floor" runtime parameter in GRACKLE](https://grackle.readthedocs.io/en/latest/Parameters.html#c.cmb_temperature_floor). * **Restriction:** * #### `GRACKLE_PE_HEATING`   (0=off, 1=on)   [0] * **Description:** -Map to the "photoelectric_heating" runtime parameter in GRACKLE. +Map to the ["photoelectric_heating" runtime parameter in GRACKLE](https://grackle.readthedocs.io/en/latest/Parameters.html#c.photoelectric_heating). * **Restriction:** * #### `GRACKLE_PE_HEATING_RATE`   (≥0.0)   [8.5e-26] * **Description:** -Map to the "photoelectric_heating_rate" runtime parameter in GRACKLE. +Map to the ["photoelectric_heating_rate" runtime parameter in GRACKLE](https://grackle.readthedocs.io/en/latest/Parameters.html#c.photoelectric_heating_rate). Note that the input value should always be in units of -ergcm-3s-1. +ergcm-3s-1nH-1. * **Restriction:** * #### `GRACKLE_CLOUDY_TABLE`   (string)   [none] * **Description:** -Map to the "grackle_data_file" runtime parameter in GRACKLE. +Map to the ["grackle_data_file" runtime parameter in GRACKLE](https://grackle.readthedocs.io/en/latest/Parameters.html#c.grackle_data_file). + * **Restriction:** + + +* #### `GRACKLE_THREE_BODY_RATE`   (0=Abel+02, 1=Palla+83, 2=Cohen+83, 3=Flower+07, 4=Glover+08, 5=Forrey+13)   [0] + * **Description:** +Map to the ["three_body_rate" runtime parameter in GRACKLE](https://grackle.readthedocs.io/en/latest/Parameters.html#c.three_body_rate). + * **Restriction:** + + +* #### `GRACKLE_CIE_COOLING`   (0=off, 1=on)   [0] + * **Description:** +Map to the ["cie_cooling" runtime parameter in GRACKLE](https://grackle.readthedocs.io/en/latest/Parameters.html#c.cie_cooling). + * **Restriction:** + + +* #### `GRACKLE_H2_OPA_APPROX`   (0=off, 1=Ripomonti+04)   [0] + * **Description:** +Map to the ["h2_optical_depth_approximation" runtime parameter in GRACKLE](https://grackle.readthedocs.io/en/latest/Parameters.html#c.h2_optical_depth_approximation). + * **Restriction:** + + +* #### `GRACKLE_USE_V_HEATING_RATE`   (0=off, 1=on)   [0] + * **Description:** +Map to the ["use_volumetric_heating_rate" runtime parameter in GRACKLE](https://grackle.readthedocs.io/en/latest/Parameters.html#c.use_volumetric_heating_rate). + * **Restriction:** + + +* #### `GRACKLE_USE_S_HEATING_RATE`   (0=off, 1=on)   [0] + * **Description:** +Map to the ["use_specific_heating_rate" runtime parameter in GRACKLE](https://grackle.readthedocs.io/en/latest/Parameters.html#c.use_specific_heating_rate). + * **Restriction:** + + +* #### `GRACKLE_PE_HEATING_RATE`   (≥0.0)   [0.76] + * **Description:** +Map to the ["HydrogenFractionByMass" runtime parameter in GRACKLE](https://grackle.readthedocs.io/en/latest/Parameters.html#c.HydrogenFractionByMass). +Note that the input value will only set to Grackle when it is in non-equilibrium mode [GRACKLE_PRIMORDIAL](#GRACKLE_PRIMORDIAL)>0, +because the tables for tabulated mode were created assuming hydrogen mass fraction of about 0.716. +See the Grackle document for the details. +When in tabulated mode ([GRACKLE_PRIMORDIAL](#GRACKLE_PRIMORDIAL)==0), this value may still be used elsewhere in GAMER and +it may be different from HydrogenFractionByMass inside Grackle. + * **Restriction:** + + +* #### `OPT__UNFREEZE_GRACKLE`   (0=off, 1=on)   [0] + * **Description:** +Allow the evolution by Grackle solver when the fluid is frozen +(for [[OPT__FREEZE_FLUID | Runtime-Parameters:-Hydro#OPT__FREEZE_FLUID]]==1 only). * **Restriction:** diff --git a/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-Outputs.md b/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-Outputs.md index 71dbedb1c9..7eb26c61b2 100644 --- a/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-Outputs.md +++ b/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-Outputs.md @@ -21,6 +21,9 @@ Parameters described on this page: [OPT__OUTPUT_LORENTZ](#OPT__OUTPUT_LORENTZ),   [OPT__OUTPUT_3VELOCITY](#OPT__OUTPUT_3VELOCITY),   [OPT__OUTPUT_ENTHALPY](#OPT__OUTPUT_ENTHALPY),   +[OPT__OUTPUT_GRACKLE_TEMP](#OPT__OUTPUT_GRACKLE_TEMP),   +[OPT__OUTPUT_GRACKLE_MU](#OPT__OUTPUT_GRACKLE_MU),   +[OPT__OUTPUT_GRACKLE_TCOOL](#OPT__OUTPUT_GRACKLE_TCOOL),   [OPT__OUTPUT_USER_FIELD](#OPT__OUTPUT_USER_FIELD),   [OPT__OUTPUT_MODE](#OPT__OUTPUT_MODE),   [OPT__OUTPUT_RESTART](#OPT__OUTPUT_RESTART),   @@ -211,6 +214,27 @@ Output the SRHD reduced enthalpy on grids. * **Restriction:** For [[--srhd | Installation:-Option-List#--srhd]] only. + +* #### `OPT__OUTPUT_GRACKLE_TEMP`   (0=off, 1=on)   [0] + * **Description:** +Output the temperature calculated by Grackle. + * **Restriction:** +For [[--grackle | Installation:-Option-List#--grackle]] only. + + +* #### `OPT__OUTPUT_GRACKLE_MU`   (0=off, 1=on)   [0] + * **Description:** +Output the mean molecular weight calculated by Grackle. + * **Restriction:** +For [[--grackle | Installation:-Option-List#--grackle]] only. + + +* #### `OPT__OUTPUT_GRACKLE_TCOOL`   (0=off, 1=on)   [0] + * **Description:** +Output the cooling time calculated by Grackle. + * **Restriction:** +For [[--grackle | Installation:-Option-List#--grackle]] only. + * #### `OPT__OUTPUT_MODE`   (1=const step, 2=const dt, 3=dump table)   [none] * **Description:** diff --git a/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-Refinement.md b/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-Refinement.md index 9c8ff3f3b8..c9161b4dfe 100644 --- a/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-Refinement.md +++ b/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-Refinement.md @@ -34,6 +34,7 @@ Parameters described on this page: [OPT__FLAG_LRTZ_GRADIENT](#OPT__FLAG_LRTZ_GRADIENT),   [OPT__FLAG_VORTICITY](#OPT__FLAG_VORTICITY),   [OPT__FLAG_JEANS](#OPT__FLAG_JEANS),   +[OPT__FLAG_COOLING_LEN](#OPT__FLAG_COOLING_LEN),   [OPT__FLAG_CURRENT](#OPT__FLAG_CURRENT),   [OPT__FLAG_CRAY](#OPT__FLAG_CRAY),   [OPT__FLAG_LOHNER_DENS](#OPT__FLAG_LOHNER_DENS),   @@ -225,6 +226,23 @@ An example file can be found at `example/input/Input__Flag_Jeans`. Recommended values: ≥4. * **Restriction:** + +* #### `OPT__FLAG_COOLING_LEN`   (0=off, 1=on)   [0] + * **Description:** +Refinement criterion: gas cooling length. It ensures that the cooling length +is resolved by at least N cells. Specifically, a cell +on level l will be flagged for refinement if its estimated +cooling length Lcool satisfies +Lcool ≡tcoolcs  < NlΔξl, +where tcool is the cooling time (currently calculated by Grackle), cs is sound speed of gas, Δξl is the cell width along ξ on level l, and Nl is the refinement threshold on level l. +Specify the refinement +thresholds on different levels in the input file `Input__Flag_CoolingLen` +with the [[specific format | Runtime-Parameters:-Input__Flag_*]]. +An example file can be found at `example/input/Input__Flag_CoolingLen`. +Recommended values: ≥1. + * **Restriction:** +Must compile with [[--grackle | Installation:-Option-List#--grackle]]. + * #### `OPT__FLAG_CURRENT`   (0=off, 1=on)   [0] * **Description:** diff --git a/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-Timestep.md b/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-Timestep.md index ba8000e787..094a5cba4e 100644 --- a/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-Timestep.md +++ b/doc/wiki/Runtime-Parameters-related/Runtime-Parameters:-Timestep.md @@ -18,6 +18,7 @@ Parameters described on this page: [DT__PARVEL](#DT__PARVEL),   [DT__PARVEL_MAX](#DT__PARVEL_MAX),   [DT__PARACC](#DT__PARACC),   +[DT__GRACKLE_COOLING](#DT__GRACKLE_COOLING),   [DT__CR_DIFFUSION](#DT__CR_DIFFUSION),   [DT__MAX_DELTA_A](#DT__MAX_DELTA_A),   [DT__SYNC_PARENT_LV](#DT__SYNC_PARENT_LV),   @@ -108,6 +109,14 @@ for the exact formula. Only applicable when adopting the compilation option [[--store_par_acc | Installation:-Option-List#--store_par_acc]]. + +* #### `DT__GRACKLE_COOLING`   (≥0.0; <0.0 → off)   [-1.0] + * **Description:** +Factor for Grackle cooling time. + * **Restriction:** +Only applicable when adopting the compilation option +[[--grackle | Installation:-Option-List#--grackle]]. + * #### `DT__CR_DIFFUSION`   (≥0.0)   [0.3] * **Description:** diff --git a/example/input/Input__Flag_CoolingLen b/example/input/Input__Flag_CoolingLen new file mode 100644 index 0000000000..9e1eeeca26 --- /dev/null +++ b/example/input/Input__Flag_CoolingLen @@ -0,0 +1,13 @@ +# Level cooling_length/cell_size + 0 1.0 + 1 1.0 + 2 1.0 + 3 1.0 + 4 1.0 + 5 1.0 + 6 1.0 + 7 1.0 + 8 1.0 + 9 1.0 + 10 1.0 + 11 1.0 diff --git a/example/test_problem/Hydro/AGORA_IsolatedGalaxy/Input_Options/Input__Parameter.high-res b/example/test_problem/Hydro/AGORA_IsolatedGalaxy/Input_Options/Input__Parameter.high-res index 40ea1be1a9..deabb8c93a 100644 --- a/example/test_problem/Hydro/AGORA_IsolatedGalaxy/Input_Options/Input__Parameter.high-res +++ b/example/test_problem/Hydro/AGORA_IsolatedGalaxy/Input_Options/Input__Parameter.high-res @@ -131,8 +131,15 @@ GRACKLE_METAL 1 # ... "metal_cooling" (must increas GRACKLE_UV 1 # ... "UVbackground" [0] GRACKLE_CMB_FLOOR 1 # ... "cmb_temperature_floor" [1] GRACKLE_PE_HEATING 1 # ... "photoelectric_heating" [0] -GRACKLE_PE_HEATING_RATE 8.5e-26 # ... "photoelectric_heating_rate (in erg/cm^3/s)" [8.5e-26] +GRACKLE_PE_HEATING_RATE 8.5e-26 # ... "photoelectric_heating_rate" (in erg/cm^3/s/n_H) [8.5e-26] GRACKLE_CLOUDY_TABLE CloudyData_UVB=HM2012.h5 # "grackle_data_file" +GRACKLE_THREE_BODY_RATE 0 # map to "three_body_rate" (0=Abel+02, 1=Palla+83, 2=Cohen+83, 3=Flower+07, 4=Glover+08, 5=Forrey+13) [0] +GRACKLE_CIE_COOLING 0 # map to "cie_cooling" [0] +GRACKLE_H2_OPA_APPROX 0 # map to "h2_optical_depth_approximation" (0=off, 1=Ripomonti+04) [0] +GRACKLE_USE_V_HEATING_RATE 0 # map to "use_volumetric_heating_rate" [0] +GRACKLE_USE_S_HEATING_RATE 0 # map to "use_specific_heating_rate" [0] +GRACKLE_HYDROGEN_MFRAC 0.76 # map to "HydrogenFractionByMass" (NOT set to Grackle when GRACKLE_PRIMORDIAL==0) [0.76] +OPT__UNFREEZE_GRACKLE 0 # allow the evolution by Grackle solver when the fluid is frozen (for OPT__FREEZE_FLUID==1 only) [0] CHE_GPU_NPGROUP -1 # number of patch groups sent into the CPU/GPU Grackle solver (<=0=auto) [-1] diff --git a/example/test_problem/Hydro/AGORA_IsolatedGalaxy/Input_Options/Input__Parameter.low-res b/example/test_problem/Hydro/AGORA_IsolatedGalaxy/Input_Options/Input__Parameter.low-res index 41980091c2..2e256ec991 100644 --- a/example/test_problem/Hydro/AGORA_IsolatedGalaxy/Input_Options/Input__Parameter.low-res +++ b/example/test_problem/Hydro/AGORA_IsolatedGalaxy/Input_Options/Input__Parameter.low-res @@ -131,8 +131,15 @@ GRACKLE_METAL 1 # ... "metal_cooling" (must increas GRACKLE_UV 1 # ... "UVbackground" [0] GRACKLE_CMB_FLOOR 1 # ... "cmb_temperature_floor" [1] GRACKLE_PE_HEATING 1 # ... "photoelectric_heating" [0] -GRACKLE_PE_HEATING_RATE 8.5e-26 # ... "photoelectric_heating_rate (in erg/cm^3/s)" [8.5e-26] +GRACKLE_PE_HEATING_RATE 8.5e-26 # ... "photoelectric_heating_rate" (in erg/cm^3/s/n_H) [8.5e-26] GRACKLE_CLOUDY_TABLE CloudyData_UVB=HM2012.h5 # "grackle_data_file" +GRACKLE_THREE_BODY_RATE 0 # map to "three_body_rate" (0=Abel+02, 1=Palla+83, 2=Cohen+83, 3=Flower+07, 4=Glover+08, 5=Forrey+13) [0] +GRACKLE_CIE_COOLING 0 # map to "cie_cooling" [0] +GRACKLE_H2_OPA_APPROX 0 # map to "h2_optical_depth_approximation" (0=off, 1=Ripomonti+04) [0] +GRACKLE_USE_V_HEATING_RATE 0 # map to "use_volumetric_heating_rate" [0] +GRACKLE_USE_S_HEATING_RATE 0 # map to "use_specific_heating_rate" [0] +GRACKLE_HYDROGEN_MFRAC 0.76 # map to "HydrogenFractionByMass" (NOT set to Grackle when GRACKLE_PRIMORDIAL==0) [0.76] +OPT__UNFREEZE_GRACKLE 0 # allow the evolution by Grackle solver when the fluid is frozen (for OPT__FREEZE_FLUID==1 only) [0] CHE_GPU_NPGROUP -1 # number of patch groups sent into the CPU/GPU Grackle solver (<=0=auto) [-1] diff --git a/example/test_problem/Hydro/CMZ/Input__Parameter b/example/test_problem/Hydro/CMZ/Input__Parameter index d6ff47aa8e..11d7c374d9 100644 --- a/example/test_problem/Hydro/CMZ/Input__Parameter +++ b/example/test_problem/Hydro/CMZ/Input__Parameter @@ -137,11 +137,15 @@ GRACKLE_METAL 1 # ... "metal_cooling" (must increas GRACKLE_UV 1 # ... "UVbackground" [0] GRACKLE_CMB_FLOOR 1 # ... "cmb_temperature_floor" [1] GRACKLE_PE_HEATING 1 # ... "photoelectric_heating" [0] -GRACKLE_PE_HEATING_RATE 8.5e-26 # ... "photoelectric_heating_rate (in erg/cm^3/s)" [8.5e-26] +GRACKLE_PE_HEATING_RATE 8.5e-26 # ... "photoelectric_heating_rate" (in erg/cm^3/s/n_H) [8.5e-26] GRACKLE_CLOUDY_TABLE CloudyData_UVB=HM2012.h5 # "grackle_data_file" -GRACKLE_THREE_BODY_RATE 0 # used Glover+08 rate -GRACKLE_CIE_COOLING 0 # 0: off; 1:on -GRACKLE_H2_OPA_APPROX 0 # H2 opacity from Ripamonti+04; 0:off, 1:Ripomonti+04 +GRACKLE_THREE_BODY_RATE 0 # map to "three_body_rate" (0=Abel+02, 1=Palla+83, 2=Cohen+83, 3=Flower+07, 4=Glover+08, 5=Forrey+13) [0] +GRACKLE_CIE_COOLING 0 # map to "cie_cooling" [0] +GRACKLE_H2_OPA_APPROX 0 # map to "h2_optical_depth_approximation" (0=off, 1=Ripomonti+04) [0] +GRACKLE_USE_V_HEATING_RATE 0 # map to "use_volumetric_heating_rate" [0] +GRACKLE_USE_S_HEATING_RATE 0 # map to "use_specific_heating_rate" [0] +GRACKLE_HYDROGEN_MFRAC 0.76 # map to "HydrogenFractionByMass" (NOT set to Grackle when GRACKLE_PRIMORDIAL==0) [0.76] +OPT__UNFREEZE_GRACKLE 0 # allow the evolution by Grackle solver when the fluid is frozen (for OPT__FREEZE_FLUID==1 only) [0] CHE_GPU_NPGROUP -1 # number of patch groups sent into the CPU/GPU Grackle solver (<=0=auto) [-1] diff --git a/example/test_problem/Hydro/CR_Diffusion/Input__Parameter b/example/test_problem/Hydro/CR_Diffusion/Input__Parameter index 1d4e672346..a5f483f1fb 100644 --- a/example/test_problem/Hydro/CR_Diffusion/Input__Parameter +++ b/example/test_problem/Hydro/CR_Diffusion/Input__Parameter @@ -160,11 +160,15 @@ GRACKLE_METAL 0 # ... "metal_cooling" (must increas GRACKLE_UV 0 # ... "UVbackground" [0] GRACKLE_CMB_FLOOR 1 # ... "cmb_temperature_floor" [1] GRACKLE_PE_HEATING 0 # ... "photoelectric_heating" [0] -GRACKLE_PE_HEATING_RATE 8.5e-26 # ... "photoelectric_heating_rate (in erg/cm^3/s)" [8.5e-26] +GRACKLE_PE_HEATING_RATE 8.5e-26 # ... "photoelectric_heating_rate" (in erg/cm^3/s/n_H) [8.5e-26] GRACKLE_CLOUDY_TABLE CloudyData_noUVB.h5 # "grackle_data_file" -GRACKLE_THREE_BODY_RATE 4 # used Glover+08 rate -GRACKLE_CIE_COOLING 1 # 0: off; 1:on -GRACKLE_H2_OPA_APPROX 1 # H2 opacity from Ripamonti+04; 0:off, 1:Ripomonti+04 +GRACKLE_THREE_BODY_RATE 0 # map to "three_body_rate" (0=Abel+02, 1=Palla+83, 2=Cohen+83, 3=Flower+07, 4=Glover+08, 5=Forrey+13) [0] +GRACKLE_CIE_COOLING 0 # map to "cie_cooling" [0] +GRACKLE_H2_OPA_APPROX 0 # map to "h2_optical_depth_approximation" (0=off, 1=Ripomonti+04) [0] +GRACKLE_USE_V_HEATING_RATE 0 # map to "use_volumetric_heating_rate" [0] +GRACKLE_USE_S_HEATING_RATE 0 # map to "use_specific_heating_rate" [0] +GRACKLE_HYDROGEN_MFRAC 0.76 # map to "HydrogenFractionByMass" (NOT set to Grackle when GRACKLE_PRIMORDIAL==0) [0.76] +OPT__UNFREEZE_GRACKLE 0 # allow the evolution by Grackle solver when the fluid is frozen (for OPT__FREEZE_FLUID==1 only) [0] CHE_GPU_NPGROUP -1 # number of patch groups sent into the CPU/GPU Grackle solver (<=0=auto) [-1] diff --git a/example/test_problem/Hydro/CR_ShockTube/Input__Parameter b/example/test_problem/Hydro/CR_ShockTube/Input__Parameter index 0360331616..3d6daf305d 100644 --- a/example/test_problem/Hydro/CR_ShockTube/Input__Parameter +++ b/example/test_problem/Hydro/CR_ShockTube/Input__Parameter @@ -159,11 +159,15 @@ GRACKLE_METAL 0 # ... "metal_cooling" (must increas GRACKLE_UV 0 # ... "UVbackground" [0] GRACKLE_CMB_FLOOR 1 # ... "cmb_temperature_floor" [1] GRACKLE_PE_HEATING 0 # ... "photoelectric_heating" [0] -GRACKLE_PE_HEATING_RATE 8.5e-26 # ... "photoelectric_heating_rate (in erg/cm^3/s)" [8.5e-26] +GRACKLE_PE_HEATING_RATE 8.5e-26 # ... "photoelectric_heating_rate" (in erg/cm^3/s/n_H) [8.5e-26] GRACKLE_CLOUDY_TABLE CloudyData_noUVB.h5 # "grackle_data_file" -GRACKLE_THREE_BODY_RATE 4 # used Glover+08 rate -GRACKLE_CIE_COOLING 1 # 0: off; 1:on -GRACKLE_H2_OPA_APPROX 1 # H2 opacity from Ripamonti+04; 0:off, 1:Ripomonti+04 +GRACKLE_THREE_BODY_RATE 0 # map to "three_body_rate" (0=Abel+02, 1=Palla+83, 2=Cohen+83, 3=Flower+07, 4=Glover+08, 5=Forrey+13) [0] +GRACKLE_CIE_COOLING 0 # map to "cie_cooling" [0] +GRACKLE_H2_OPA_APPROX 0 # map to "h2_optical_depth_approximation" (0=off, 1=Ripomonti+04) [0] +GRACKLE_USE_V_HEATING_RATE 0 # map to "use_volumetric_heating_rate" [0] +GRACKLE_USE_S_HEATING_RATE 0 # map to "use_specific_heating_rate" [0] +GRACKLE_HYDROGEN_MFRAC 0.76 # map to "HydrogenFractionByMass" (NOT set to Grackle when GRACKLE_PRIMORDIAL==0) [0.76] +OPT__UNFREEZE_GRACKLE 0 # allow the evolution by Grackle solver when the fluid is frozen (for OPT__FREEZE_FLUID==1 only) [0] CHE_GPU_NPGROUP -1 # number of patch groups sent into the CPU/GPU Grackle solver (<=0=auto) [-1] diff --git a/example/test_problem/Hydro/CR_SoundWave/Input__Parameter b/example/test_problem/Hydro/CR_SoundWave/Input__Parameter index acc884ac52..6bd277bb8c 100644 --- a/example/test_problem/Hydro/CR_SoundWave/Input__Parameter +++ b/example/test_problem/Hydro/CR_SoundWave/Input__Parameter @@ -158,11 +158,15 @@ GRACKLE_METAL 0 # ... "metal_cooling" (must increas GRACKLE_UV 0 # ... "UVbackground" [0] GRACKLE_CMB_FLOOR 1 # ... "cmb_temperature_floor" [1] GRACKLE_PE_HEATING 0 # ... "photoelectric_heating" [0] -GRACKLE_PE_HEATING_RATE 8.5e-26 # ... "photoelectric_heating_rate (in erg/cm^3/s)" [8.5e-26] +GRACKLE_PE_HEATING_RATE 8.5e-26 # ... "photoelectric_heating_rate" (in erg/cm^3/s/n_H) [8.5e-26] GRACKLE_CLOUDY_TABLE CloudyData_noUVB.h5 # "grackle_data_file" -GRACKLE_THREE_BODY_RATE 4 # used Glover+08 rate -GRACKLE_CIE_COOLING 1 # 0: off; 1:on -GRACKLE_H2_OPA_APPROX 1 # H2 opacity from Ripamonti+04; 0:off, 1:Ripomonti+04 +GRACKLE_THREE_BODY_RATE 0 # map to "three_body_rate" (0=Abel+02, 1=Palla+83, 2=Cohen+83, 3=Flower+07, 4=Glover+08, 5=Forrey+13) [0] +GRACKLE_CIE_COOLING 0 # map to "cie_cooling" [0] +GRACKLE_H2_OPA_APPROX 0 # map to "h2_optical_depth_approximation" (0=off, 1=Ripomonti+04) [0] +GRACKLE_USE_V_HEATING_RATE 0 # map to "use_volumetric_heating_rate" [0] +GRACKLE_USE_S_HEATING_RATE 0 # map to "use_specific_heating_rate" [0] +GRACKLE_HYDROGEN_MFRAC 0.76 # map to "HydrogenFractionByMass" (NOT set to Grackle when GRACKLE_PRIMORDIAL==0) [0.76] +OPT__UNFREEZE_GRACKLE 0 # allow the evolution by Grackle solver when the fluid is frozen (for OPT__FREEZE_FLUID==1 only) [0] CHE_GPU_NPGROUP -1 # number of patch groups sent into the CPU/GPU Grackle solver (<=0=auto) [-1] diff --git a/example/test_problem/Hydro/GrackleTest/Input__Flag_CoolingLen b/example/test_problem/Hydro/GrackleTest/Input__Flag_CoolingLen new file mode 100644 index 0000000000..3836537ce2 --- /dev/null +++ b/example/test_problem/Hydro/GrackleTest/Input__Flag_CoolingLen @@ -0,0 +1,13 @@ +# Level cooling_length/cell_size + 0 8.0 + 1 8.0 + 2 8.0 + 3 8.0 + 4 8.0 + 5 8.0 + 6 8.0 + 7 8.0 + 8 8.0 + 9 8.0 + 10 8.0 + 11 8.0 diff --git a/example/test_problem/Hydro/GrackleTest/Input__Parameter b/example/test_problem/Hydro/GrackleTest/Input__Parameter new file mode 100644 index 0000000000..3429a6051d --- /dev/null +++ b/example/test_problem/Hydro/GrackleTest/Input__Parameter @@ -0,0 +1,239 @@ + + +# ================================================================================================================= +# NOTE: +# 1. Comment symbol: # +# 2. [*]: defaults +# 3. Parameters set to "auto" (usually by setting to a negative value) do not have deterministic default values +# and will be set according to the adopted compilation options and/or other runtime parameters +# 4. To add new parameters, please edit "Init/Init_Load_Parameter.cpp" +# 5. All dimensional variables should be set consistently with the code units (set by UNIT_L/M/T/V/D) +# 6. For boolean options: 0/1 -> off/on +# ================================================================================================================= + + +# simulation scale +BOX_SIZE 8.0 # box size along the longest side (in Mpc/h if COMOVING is adopted) +NX0_TOT_X 128 # number of base-level cells along x +NX0_TOT_Y 128 # number of base-level cells along y +NX0_TOT_Z 32 # number of base-level cells along z +OMP_NTHREAD -1 # number of OpenMP threads (<=0=auto) [-1] ##OPENMP ONLY## +END_T -1.0 # end physical time (<0=auto -> must be set by test problems or restart) [-1.0] +END_STEP -1 # end step (<0=auto -> must be set by test problems or restart) [-1] + + +# test problems +TESTPROB_ID 24 # test problem ID [0] + # 24: HYDRO Grackle Test (+SUPPORT_GRACKLE) + + +# code units (in cgs) +OPT__UNIT 1 # specify code units -> must set exactly 3 basic units below [0] ##USELESS FOR COMOVING## +UNIT_L 3.08567758149e21 # length unit (<=0 -> set to UNIT_V*UNIT_T or (UNIT_M/UNIT_D)^(1/3)) [-1.0] +UNIT_M 1.9885e42 # mass unit (<=0 -> set to UNIT_D*UNIT_L^3) [-1.0] +UNIT_T 3.15569252e13 # time unit (<=0 -> set to UNIT_L/UNIT_V) [-1.0] +UNIT_V -1.0 # velocity unit (<=0 -> set to UNIT_L/UNIT_T) [-1.0] +UNIT_D -1.0 # mass density unit (<=0 -> set to UNIT_M/UNIT_L^3) [-1.0] + + +# boundary conditions +OPT__BC_FLU_XM 1 # fluid boundary condition at the -x face: (1=periodic, 2=outflow, 3=reflecting, 4=user, 5=diode) +OPT__BC_FLU_XP 1 # fluid boundary condition at the +x face: (1=periodic, 2=outflow, 3=reflecting, 4=user, 5=diode) +OPT__BC_FLU_YM 1 # fluid boundary condition at the -y face: (1=periodic, 2=outflow, 3=reflecting, 4=user, 5=diode) +OPT__BC_FLU_YP 1 # fluid boundary condition at the +y face: (1=periodic, 2=outflow, 3=reflecting, 4=user, 5=diode) +OPT__BC_FLU_ZM 1 # fluid boundary condition at the -z face: (1=periodic, 2=outflow, 3=reflecting, 4=user, 5=diode) +OPT__BC_FLU_ZP 1 # fluid boundary condition at the +z face: (1=periodic, 2=outflow, 3=reflecting, 4=user, 5=diode) +OPT__BC_POT 1 # gravity boundary condition: (1=periodic, 2=isolated) + + +# time-step +DT__MAX 1.0 # dt criterion: maximum allowed dt (<0=off) [-1.0] +DT__FLUID 0.5 # dt criterion: fluid solver CFL factor (<0=auto) [-1.0] +DT__FLUID_INIT -1.0 # dt criterion: DT__FLUID at the first step (<0=auto) [-1.0] +DT__GRAVITY 0.35355 # dt criterion: gravity solver safety factor (<0=auto) [-1.0] +DT__PARVEL 0.5 # dt criterion: particle velocity safety factor [0.5] +DT__PARVEL_MAX -1.0 # dt criterion: maximum allowed dt from particle velocity (<0=off) [-1.0] +DT__PARACC 0.0 # dt criterion: particle acceleration safety factor (0=off) [0.5] ##STORE_PAR_ACC ONLY## +DT__GRACKLE_COOLING 0.25 # dt criterion: factor for Grackle cooling time (<0=off) [-1.0] ##SUPPORT_GRACKLE only## +DT__SYNC_PARENT_LV 0.05 # dt criterion: allow dt to adjust by (1.0+DT__SYNC_PARENT) in order to synchronize + # with the parent level (for OPT__DT_LEVEL==3 only) [0.1] +DT__SYNC_CHILDREN_LV 0.1 # dt criterion: allow dt to adjust by (1.0-DT__SYNC_CHILDREN) in order to synchronize + # with the children level (for OPT__DT_LEVEL==3 only; 0=off) [0.1] +OPT__DT_USER 0 # dt criterion: user-defined -> edit "Mis_GetTimeStep_UserCriteria.cpp" [0] +OPT__DT_LEVEL 3 # dt at different AMR levels (1=shared, 2=differ by two, 3=flexible) [3] +OPT__RECORD_DT 1 # record info of the dt determination [1] +AUTO_REDUCE_DT 1 # reduce dt automatically when the program fails (for OPT__DT_LEVEL==3 only) [1] +AUTO_REDUCE_DT_FACTOR 1.0 # reduce dt by a factor of AUTO_REDUCE_DT_FACTOR when the program fails [1.0] +AUTO_REDUCE_DT_FACTOR_MIN 0.1 # minimum allowed AUTO_REDUCE_DT_FACTOR after consecutive failures [0.1] +AUTO_REDUCE_MINMOD_FACTOR 0.8 # reduce MINMOD_COEFF by this factor together with AUTO_REDUCE_DT (1.0=off) [0.8] ##HYDRO ONLY## +AUTO_REDUCE_MINMOD_MIN 1.0e-2 # minimum allowed MINMOD_COEFF after consecutive failures [1.0e-2] ##HYDRO ONLY## +AUTO_REDUCE_INT_MONO_FACTOR 0.8 # reduce INT_MONO_COEFF(_B) by this factor together with AUTO_REDUCE_DT (1.0=off) [0.8] +AUTO_REDUCE_INT_MONO_MIN 1.0e-2 # minimum allowed INT_MONO_COEFF(_B) after consecutive failures [1.0e-2] + + +# grid refinement (examples of Input__Flag_XXX tables are put at "example/input/") +REGRID_COUNT 1 # refine every REGRID_COUNT sub-step [4] +FLAG_BUFFER_SIZE -1 # number of buffer cells for the flag operation (0~PATCH_SIZE; <0=auto -> PATCH_SIZE) [-1] +FLAG_BUFFER_SIZE_MAXM1_LV 2 # FLAG_BUFFER_SIZE at the level MAX_LEVEL-1 (<0=auto -> REGRID_COUNT) [-1] +FLAG_BUFFER_SIZE_MAXM2_LV -1 # FLAG_BUFFER_SIZE at the level MAX_LEVEL-2 (<0=auto) [-1] +MAX_LEVEL 0 # maximum refinement level (0~NLEVEL-1) [NLEVEL-1] +OPT__FLAG_RHO 0 # flag: density (Input__Flag_Rho) [0] +OPT__FLAG_RHO_GRADIENT 0 # flag: density gradient (Input__Flag_RhoGradient) [0] +OPT__FLAG_PRES_GRADIENT 0 # flag: pressure gradient (Input__Flag_PresGradient) [0] ##HYDRO ONLY## +OPT__FLAG_VORTICITY 0 # flag: vorticity (Input__Flag_Vorticity) [0] ##HYDRO ONLY## +OPT__FLAG_JEANS 0 # flag: Jeans length (Input__Flag_Jeans) [0] ##HYDRO ONLY## +OPT__FLAG_COOLING_LEN 1 # flag: cooling length (Input__Flag_CoolingLen) [0] ##HYDRO+SUPPORT_GRACKLE ONLY## +OPT__FLAG_LOHNER_DENS 0 # flag: Lohner for mass density (Input__Flag_Lohner) [0] ##BOTH HYDRO AND ELBDM## +OPT__FLAG_LOHNER_ENGY 0 # flag: Lohner for energy density (Input__Flag_Lohner) [0] ##HYDRO ONLY## +OPT__FLAG_LOHNER_PRES 0 # flag: Lohner for pressure (Input__Flag_Lohner) [0] ##HYDRO ONLY## +OPT__FLAG_LOHNER_TEMP 0 # flag: Lohner for temperature (Input__Flag_Lohner) [0] ##HYDRO ONLY## +OPT__FLAG_LOHNER_ENTR 0 # flag: Lohner for entropy (Input__Flag_Lohner) [0] ##HYDRO ONLY## +OPT__FLAG_LOHNER_FORM 2 # form of Lohner: (1=FLASH-1, 2=FLASH-2, 3=form-invariant-1, 4=form-invariant-2) [2] +OPT__FLAG_USER 0 # flag: user-defined (Input__Flag_User) -> edit "Flag_User.cpp" [0] +OPT__FLAG_REGION 0 # flag: specify the regions **allowed** to be refined -> edit "Flag_Region.cpp" [0] +OPT__FLAG_NPAR_PATCH 0 # flag: # of particles per patch (Input__Flag_NParPatch): (0=off, 1=itself, 2=itself+siblings) [0] +OPT__FLAG_NPAR_CELL 0 # flag: # of particles per cell (Input__Flag_NParCell) [0] +OPT__FLAG_PAR_MASS_CELL 0 # flag: total particle mass per cell (Input__Flag_ParMassCell) [0] +OPT__NO_FLAG_NEAR_BOUNDARY 0 # flag: disallow refinement near the boundaries [0] +OPT__PATCH_COUNT 1 # record the # of patches at each level: (0=off, 1=every step, 2=every sub-step) [1] +OPT__PARTICLE_COUNT 1 # record the # of particles at each level: (0=off, 1=every step, 2=every sub-step) [1] +OPT__REUSE_MEMORY 2 # reuse patch memory to reduce memory fragmentation: (0=off, 1=on, 2=aggressive) [2] +OPT__MEMORY_POOL 0 # preallocate patches for OPT__REUSE_MEMORY=1/2 (Input__MemoryPool) [0] + + +# load balance (LOAD_BALANCE only) +LB_INPUT__WLI_MAX 0.1 # weighted-load-imbalance (WLI) threshold for redistributing all patches [0.1] +LB_INPUT__PAR_WEIGHT 0.0 # load-balance weighting of one particle over one cell [0.0] +OPT__RECORD_LOAD_BALANCE 1 # record the load-balance info [1] +OPT__MINIMIZE_MPI_BARRIER 0 # minimize MPI barriers to improve load balance, especially with particles [0] + # (STORE_POT_GHOST, PAR_IMPROVE_ACC=1, OPT__TIMING_BARRIER=0 only; recommend AUTO_REDUCE_DT=0) + + +# Grackle library for chemistry and radiative cooling (SUPPORT_GRACKLE only) +GRACKLE_ACTIVATE 1 # enable Grackle [1] +GRACKLE_VERBOSE 1 # map to "grackle_verbose" [1] +GRACKLE_COOLING 1 # map to "with_radiative_cooling" [1] +GRACKLE_PRIMORDIAL 3 # map to "primordial_chemistry" (0=Cloudy, 1/2/3=6-/9-/12-species) (must increase NCOMP_PASSIVE_USER by 6/9/12, respectively) [0] +GRACKLE_METAL 1 # map to "metal_cooling" (must increase NCOMP_PASSIVE_USER by 1) [0] +GRACKLE_UV 1 # map to "UVbackground" [0] +GRACKLE_CMB_FLOOR 1 # map to "cmb_temperature_floor" [1] +GRACKLE_PE_HEATING 1 # map to "photoelectric_heating" [0] +GRACKLE_PE_HEATING_RATE 8.5e-26 # map to "photoelectric_heating_rate" (in erg/cm^3/s/n_H) [8.5e-26] +GRACKLE_CLOUDY_TABLE CloudyData_UVB=HM2012.h5 # "grackle_data_file" +GRACKLE_THREE_BODY_RATE 0 # map to "three_body_rate" (0=Abel+02, 1=Palla+83, 2=Cohen+83, 3=Flower+07, 4=Glover+08, 5=Forrey+13) [0] +GRACKLE_CIE_COOLING 0 # map to "cie_cooling" [0] +GRACKLE_H2_OPA_APPROX 0 # map to "h2_optical_depth_approximation" (0=off, 1=Ripomonti+04) [0] +GRACKLE_USE_V_HEATING_RATE 0 # map to "use_volumetric_heating_rate" [0] +GRACKLE_USE_S_HEATING_RATE 0 # map to "use_specific_heating_rate" [0] +GRACKLE_HYDROGEN_MFRAC 0.76 # map to "HydrogenFractionByMass" (NOT set to Grackle when GRACKLE_PRIMORDIAL==0) [0.76] +OPT__UNFREEZE_GRACKLE 1 # allow the evolution by Grackle solver when the fluid is frozen (for OPT__FREEZE_FLUID==1 only) [0] +CHE_GPU_NPGROUP -1 # number of patch groups sent into the CPU/GPU Grackle solver (<=0=auto) [-1] + + +# fluid solver in HYDRO (MODEL==HYDRO only) +GAMMA 1.666667 # ratio of specific heats (i.e., adiabatic index) [5.0/3.0] +MOLECULAR_WEIGHT 0.6 # mean molecular weight -> currently only for post-processing [0.6] +MINMOD_COEFF 1.0 # coefficient of the generalized MinMod limiter (1.0~2.0) [1.5] +MINMOD_MAX_ITER 0 # maximum number of iterations to reduce MINMOD_COEFF when data reconstruction fails (0=off) [0] +OPT__LR_LIMITER -1 # slope limiter of data reconstruction in the MHM/MHM_RP/CTU schemes: + # (-1=auto, 0=none, 1=vanLeer, 2=generalized MinMod, 3=vanAlbada, 4=vanLeer+generalized MinMod, 6=central, 7=Athena) [-1] +OPT__1ST_FLUX_CORR -1 # correct unphysical results (defined by MIN_DENS/PRES) by the 1st-order fluxes: + # (<0=auto, 0=off, 1=3D, 2=3D+1D) [-1] ##MHM/MHM_RP/CTU ONLY## +OPT__1ST_FLUX_CORR_SCHEME -1 # Riemann solver for OPT__1ST_FLUX_CORR (<0=auto, 0=none, 1=Roe, 2=HLLC, 3=HLLE, 4=HLLD) [-1] +DUAL_ENERGY_SWITCH 2.0e-1 # apply dual-energy if E_int/E_kin < DUAL_ENERGY_SWITCH [2.0e-2] ##DUAL_ENERGY ONLY## + + +# fluid solvers in all models +FLU_GPU_NPGROUP -1 # number of patch groups sent into the GPU fluid solver (<=0=auto) [-1] +GPU_NSTREAM -1 # number of CUDA streams for the asynchronous memory copy in GPU (<=0=auto) [-1] +OPT__FIXUP_FLUX 1 # correct coarse grids by the fine-grid boundary fluxes [1] ##HYDRO and ELBDM ONLY## +OPT__FIXUP_RESTRICT 1 # correct coarse grids by averaging the fine-grid data [1] +OPT__CORR_AFTER_ALL_SYNC -1 # apply various corrections after all levels are synchronized (see "Flu_CorrAfterAllSync"): + # (-1=auto, 0=off, 1=every step, 2=before dump) [-1] +OPT__NORMALIZE_PASSIVE 0 # ensure "sum(passive_scalar_density) == gas_density" [1] +OPT__RESET_FLUID 0 # reset fluid variables after each update -> edit "Flu_ResetByUser.cpp" [0] +OPT__FREEZE_FLUID 1 # do not evolve fluid at all [0] +MIN_DENS 0.0 # minimum mass density (must >= 0.0) [0.0] ##HYDRO, MHD, and ELBDM ONLY## +MIN_PRES 0.0 # minimum pressure (must >= 0.0) [0.0] ##HYDRO and MHD ONLY## +MIN_EINT 0.0 # minimum internal energy (must >= 0.0) [0.0] ##HYDRO and MHD ONLY## +MIN_ENTR 0.0 # minimum entropy (must >= 0.0) [0.0] ##HYDRO and MHD ONLY## +JEANS_MIN_PRES 1 # minimum pressure estimated from the Jeans length [0] ##HYDRO/MHD and GRAVITY ONLY## +JEANS_MIN_PRES_LEVEL -1 # for JEANS_MIN_PRES; ensure Jeans length is resolved by JEANS_MIN_PRES_NCELL*dh[JEANS_MIN_PRES_LEVEL] + # (<0=auto -> MAX_LEVEL) [-1] +JEANS_MIN_PRES_NCELL 4 # for JEANS_MIN_PRES; see JEANS_MIN_PRES_LEVEL [4] + + +# initialization +OPT__INIT 1 # initialization option: (1=FUNCTION, 2=RESTART, 3=FILE->"UM_IC") +RESTART_LOAD_NRANK 256 # number of parallel I/O (i.e., number of MPI ranks) for restart [1] +OPT__INIT_RESTRICT 1 # restrict all data during the initialization [1] +OPT__GPUID_SELECT -1 # GPU ID selection mode: (-3=Laohu, -2=CUDA, -1=MPI rank, >=0=input) [-1] +INIT_SUBSAMPLING_NCELL 0 # perform sub-sampling during initialization: (0=off, >0=# of sub-sampling cells) [0] + + +# interpolation schemes: (-1=auto, 1=MinMod-3D, 2=MinMod-1D, 3=vanLeer, 4=CQuad, 5=Quad, 6=CQuar, 7=Quar) +OPT__FLU_INT_SCHEME -1 # ghost-zone fluid variables for the fluid solver [-1] +OPT__REF_FLU_INT_SCHEME -1 # newly allocated fluid variables during grid refinement [-1] +OPT__POT_INT_SCHEME 4 # ghost-zone potential for the Poisson solver (only supports 4 & 5) [4] +OPT__RHO_INT_SCHEME 4 # ghost-zone mass density for the Poisson solver [4] +OPT__GRA_INT_SCHEME 4 # ghost-zone potential for the gravity solver (for UNSPLIT_GRAVITY as well) [4] +OPT__REF_POT_INT_SCHEME 4 # newly allocated potential during grid refinement [4] +INT_MONO_COEFF 2.0 # coefficient for ensuring the interpolation monotonicity (1.0~4.0) [2.0] +MONO_MAX_ITER 10 # maximum number of iterations to reduce INT_MONO_COEFF when interpolation fails (0=off) [10] + + +# data dump +OPT__OUTPUT_TOTAL 1 # output the simulation snapshot: (0=off, 1=HDF5, 2=C-binary) [1] +OPT__OUTPUT_PART 1 # output a single line or slice: (0=off, 1=xy, 2=yz, 3=xz, 4=x, 5=y, 6=z, 7=diag, 8=entire box) [0] +OPT__OUTPUT_USER 0 # output the user-specified data -> edit "Output_User.cpp" [0] +OPT__OUTPUT_PAR_MODE 0 # output the particle data: (0=off, 1=text-file, 2=C-binary) [0] ##PARTICLE ONLY## +OPT__OUTPUT_POT 1 # output gravitational potential [1] ##OPT__OUTPUT_TOTAL ONLY## +OPT__OUTPUT_PAR_DENS 1 # output the particle or total mass density on grids: + # (0=off, 1=particle mass density, 2=total mass density) [1] ##OPT__OUTPUT_TOTAL ONLY## +OPT__OUTPUT_PRES 1 # output gas pressure [0] ##HYDRO ONLY## +OPT__OUTPUT_TEMP 1 # output gas temperature [0] ##HYDRO ONLY## +OPT__OUTPUT_ENTR 0 # output gas entropy [0] ##HYDRO ONLY## +OPT__OUTPUT_CS 1 # output sound speed [0] ##HYDRO ONLY## +OPT__OUTPUT_DIVVEL 0 # output divergence(velocity) [0] ##HYDRO ONLY## +OPT__OUTPUT_MACH 0 # output mach number [0] ##HYDRO ONLY## +OPT__OUTPUT_DIVMAG 0 # output |divergence(B)*dh/|B|| [0] ##MHD ONLY## +OPT__OUTPUT_LORENTZ 0 # output Lorentz factor [0] ##SRHD ONLY## +OPT__OUTPUT_3VELOCITY 0 # output 3-velocities [0] ##SRHD ONLY## +OPT__OUTPUT_GRACKLE_TEMP 1 # output the temperature calculated by Grackle [0] ##SUPPORT_GRACKLE only## +OPT__OUTPUT_GRACKLE_MU 1 # output the mean molecular weight calculated by Grackle [0] ##SUPPORT_GRACKLE only## +OPT__OUTPUT_GRACKLE_TCOOL 1 # output the cooling time calculated by Grackle [0] ##SUPPORT_GRACKLE only## +OPT__OUTPUT_USER_FIELD 0 # output user-defined derived fields [0] -> edit "Flu_DerivedField_User.cpp" +OPT__OUTPUT_MODE 1 # (1=const step, 2=const dt, 3=dump table) -> edit "Input__DumpTable" for 3 +OUTPUT_STEP 1 # output data every OUTPUT_STEP step ##OPT__OUTPUT_MODE==1 ONLY## +OUTPUT_DT 1.0 # output data every OUTPUT_DT time interval ##OPT__OUTPUT_MODE==2 ONLY## +OUTPUT_PART_X -1.0 # x coordinate for OPT__OUTPUT_PART [-1.0] +OUTPUT_PART_Y -1.0 # y coordinate for OPT__OUTPUT_PART [-1.0] +OUTPUT_PART_Z 1.0 # z coordinate for OPT__OUTPUT_PART [-1.0] +INIT_DUMPID -1 # set the first dump ID (<0=auto) [-1] + + +# miscellaneous +OPT__VERBOSE 0 # output the simulation progress in detail [0] +OPT__TIMING_BARRIER -1 # synchronize before timing -> more accurate, but may slow down the run (<0=auto) [-1] +OPT__TIMING_BALANCE 0 # record the max/min elapsed time in various code sections for checking load balance [0] +OPT__TIMING_MPI 0 # record the MPI bandwidth achieved in various code sections [0] ##LOAD_BALANCE ONLY## +OPT__RECORD_MEMORY 1 # record the memory consumption [1] +OPT__RECORD_PERFORMANCE 1 # record the code performance [1] +OPT__MANUAL_CONTROL 1 # support manually dump data or stop run during the runtime + # (by generating the file DUMP_GAMER_DUMP or STOP_GAMER_STOP) [1] +OPT__RECORD_USER 0 # record the user-specified info -> edit "Aux_Record_User.cpp" [0] +OPT__OPTIMIZE_AGGRESSIVE 1 # apply aggressive optimizations (experimental) [0] + + +# checks +OPT__CK_REFINE 0 # check the grid refinement [0] +OPT__CK_PROPER_NESTING 0 # check the proper-nesting condition [0] +OPT__CK_CONSERVATION 1 # check the conservation law [0] +OPT__CK_NORMALIZE_PASSIVE 0 # check the normalization of passive scalars [0] ##OPT__NORMALIZE_PASSIVE ONLY## +OPT__CK_RESTRICT 0 # check the data restriction [0] +OPT__CK_FINITE 0 # check if all variables are finite [0] +OPT__CK_PATCH_ALLOCATE 0 # check if all patches are properly allocated [0] +OPT__CK_FLUX_ALLOCATE 0 # check if all flux arrays are properly allocated ##HYDRO and ELBDM ONLY## [0] +OPT__CK_NEGATIVE 0 # check the negative values: (0=off, 1=density, 2=pressure and entropy, 3=both) [0] ##HYDRO ONLY## +OPT__CK_MEMFREE 1.0 # check the free memory in GB (0=off, >0=threshold) [1.0] +OPT__CK_PARTICLE 0 # check the particle allocation [0] diff --git a/example/test_problem/Hydro/GrackleTest/Input__TestProb b/example/test_problem/Hydro/GrackleTest/Input__TestProb new file mode 100644 index 0000000000..a132b595a8 --- /dev/null +++ b/example/test_problem/Hydro/GrackleTest/Input__TestProb @@ -0,0 +1,21 @@ +# problem-specific runtime parameters +GrackleTest_DefaultTestMode 0 # Default test mode (0=none, >=1: see README) [0] +GrackleTest_MassDensity_Min 1.0e-29 # Minimum total mass density in the box (in g cm^-3) [1.0e-29] +GrackleTest_MassDensity_Max 1.0e-21 # Maximum total mass density in the box (in g cm^-3) [1.0e-21] +GrackleTest_TempOverMMW_Min 1.0e+00 # Minimum temperature over mean molecular weight (T/mu) in the box (in K) [1.0e+00] +GrackleTest_TempOverMMW_Max 1.0e+08 # Maximum temperature over mean molecular weight (T/mu) in the box (in K) [1.0e+08] +GrackleTest_MFrac_Metal 0.01295 # Metal mass fraction (GRACKLE_METAL only) [0.01295] +GrackleTest_MFrac_e 0.0 # Electron mass fraction (GRACKLE_PRIMORDIAL >= 1 only) [0.0] +GrackleTest_MFrac_HI 0.750158 # HI mass fraction (GRACKLE_PRIMORDIAL >= 1 only) [0.750158] +GrackleTest_MFrac_HII 0.0 # HII mass fraction (GRACKLE_PRIMORDIAL >= 1 only) [0.0] +GrackleTest_MFrac_HeI 0.236892 # HeI mass fraction (GRACKLE_PRIMORDIAL >= 1 only) [0.236892] +GrackleTest_MFrac_HeII 0.0 # HeII mass fraction (GRACKLE_PRIMORDIAL >= 1 only) [0.0] +GrackleTest_MFrac_HeIII 0.0 # HeIII mass fraction (GRACKLE_PRIMORDIAL >= 1 only) [0.0] +GrackleTest_MFrac_HM 0.0 # HM mass fraction (GRACKLE_PRIMORDIAL >= 2 only) [0.0] +GrackleTest_MFrac_H2I 0.0 # H2I mass fraction (GRACKLE_PRIMORDIAL >= 2 only) [0.0] +GrackleTest_MFrac_H2II 0.0 # H2II mass fraction (GRACKLE_PRIMORDIAL >= 2 only) [0.0] +GrackleTest_MFrac_DI 0.0 # DI mass fraction (GRACKLE_PRIMORDIAL >= 3 only) [0.0] +GrackleTest_MFrac_DII 0.0 # DII mass fraction (GRACKLE_PRIMORDIAL >= 3 only) [0.0] +GrackleTest_MFrac_HDI 0.0 # HDI mass fraction (GRACKLE_PRIMORDIAL >= 3 only) [0.0] +GrackleTest_HeatingRate 0.0 # User-provided heating rate (in erg cm^-3 s^-1 n_H^-1) [0.0] +GrackleTest_CoolingRate 0.0 # User-provided cooling rate (in erg cm^-3 s^-1 n_H^-2) [0.0] diff --git a/example/test_problem/Hydro/GrackleTest/README b/example/test_problem/Hydro/GrackleTest/README new file mode 100644 index 0000000000..94e11b9f34 --- /dev/null +++ b/example/test_problem/Hydro/GrackleTest/README @@ -0,0 +1,119 @@ +Compilation flags: +======================================== +Enable : MODEL=HYDRO, SUPPORT_GRACKLE +Disable: COMOVING, PARTICLE, GRAVITY + + +Default setup: +======================================== +1. Units: + (1) External (for Input__TestProb only): + See the comment of each runtime variable + + (2) Internal (for all other input files and internal usage): + [L] = kpc + [M] = 1.0e9 Msun + [T] = Myr + -->[V] = [L]/[T] ~ 9.8e2 km/s + -->[D] = [M]/[L]^3 ~ 6.8e-23 g/cm^3 + +2. BOX_SIZE 8.0 kpc + NX0_TOT_X 128 + NX0_TOT_Y 128 + NX0_TOT_Z 32 + +3. MAX_LEVEL 0 + OPT__FLAG_COOLING_LEN 1 + REGRID_COUNT 1 + +4. DT__MAX 1.00 Myr + DT__GRACKLE_COOLING 0.25 + +5. GRACKLE_ACTIVATE 1 + OPT__FREEZE_FLUID 1 + OPT__UNFREEZE_GRACKLE 1 + +6. OPT__OUTPUT_TEMP 1 + OPT__OUTPUT_GRACKLE_TEMP 1 + OPT__OUTPUT_GRACKLE_MU 1 + OPT__OUTPUT_GRACKLE_TCOOL 1 + OUTPUT_STEP 1 + +7. END_STEP 10 Steps + END_T 10.0 Myr or 10 * DT__GRACKLE_COOLING * cooling time + + +Note: +======================================== +1. Test the functionality and the interface to the Grackle library + +2. The initial conditions of varying phases + - In the x direction, linearly varying log( mass density ) + from `GrackleTest_MassDensity_Min` to `GrackleTest_MassDensity_Max` + - In the y direction, linearly varying log( temperature / mean molecular weight ) + from `GrackleTest_TempOverMMW_Min to `GrackleTest_TempOverMMW_Max` + - No variation in the z direction + +3. The chemical composition + - During the compilation, one must set `NCOMP_PASSIVE_USER` (`--passive` in `generate_make.sh`) + to the total number of chemical species (e.g., 13 for metal + 12 primordial species) + - One must turn on the corresponding `GRACKLE_METAL` and `GRACKLE_PRIMORDIAL` in `Input__Parameter` + - The mass fraction of each species can be set by `GrackleTest_MFrac_*` in `Input__TestProb` + - Currently, the mass fractions are assumed to be spatially uniform initially + --> Modify SetGridIC() if they are not + +4. The user-provided heating and cooling + - Turn on `GRACKLE_USE_V_HEATING_RATE` in `Input__Parameter` + - Set `GrackleTest_HeatingRate` and `GrackleTest_CoolingRate` in `Input__TestProb` + - Edit `Grackle_vHeatingRate_GrackleTest()` to set the distribution + +5. The default test mode can be set by `GrackleTest_DefaultTestMode` in `Input__TestProb` + - 0: + --> Non-default, one can choose the parameters freely + - 1: + - The density range is from 1.0e-29 g cm^-3 to 1.0e-21 g cm^-3 + - The T/mu range is from 1 K to 1e8 K + --> To see the cooling rates across the phase diagram + - 2: + - The density is uniformly 1.0e-24 g cm^-3 + - The T/mu is uniformly 1e4 K + --> To see the time evolution of temperature and composition for a given initial phase + - 3: + - The density is uniformly 1.0e-28 g cm^-3 + - The T/mu is uniformly 1e6 K + - The metal mass fraction is 0 + - `GRACKLE_PRIMORDIAL` should be 0 + - `GRACKLE_UV`, `GRACKLE_CMB_FLOOR`, `GRACKLE_PE_HEATING` should all be 0 + - `GRACKLE_USE_V_HEATING_RATE` should be 1 + - `GrackleTest_HeatingRate` = 1.0e-24 erg cm^-3 s^-1 n_H^-1 + - `GrackleTest_CoolingRate` = 1.6e-20 erg cm^-3 s^-1 n_H^-2 + --> To see the time evolution and spatial distribution of temperature for the given + user-provided one heating and one cooling 2D Gaussian distributions (as a demo) + +6. The evolution of fluid + - The fluid is not evolved by hydrodynamics (`OPT__FREEZE_FLUID`) + - But it is evolved by Grackle solver (`OPT__UNFREEZE_GRACKLE`) + +7. The default time step is set to min( 0.25x the minimum cooling time, 0.1 Myr ) + - Set `DT__GRACKLE_COOLING` and `DT__MAX` to change it + +8. Output the Grackle-calculated fields in the snapshots for analysis + - Turn on `OPT__OUTPUT_GRACKLE_TEMP`, `OPT__OUTPUT_GRACKLE_MU`, and `OPT__OUTPUT_GRACKLE_TCOOL` + +9. Refine the grids by the cooling length (= cooling time x sound speed) + - Turn on `OPT__FLAG_COOLING_LEN` + - Set the critera in `Input__Flag_CoolingLen` + - Set the target `MAX_LEVEL` + +10. Some handy yt analysis scripts are put at "yt_script" + - `plot_projection.py`: to plot the spatial distribution of gas quantities + - `plot_time_evolution.py`: to plot the time evolution of gas quantities + +11. CloudyData_UVB table + - Source: https://github.com/grackle-project/grackle_data_files/tree/main/input + - The default table `CloudyData_UVB=HM2012.h5` can be downloaded by `sh download_CloudyData_UVB.sh` + + +First-time GRACKLE installation guide (on NTU clusters as an example): +======================================== +Please refer to the README file at "./example/grackle/" diff --git a/example/test_problem/Hydro/GrackleTest/clean.sh b/example/test_problem/Hydro/GrackleTest/clean.sh new file mode 100644 index 0000000000..6a330bb25b --- /dev/null +++ b/example/test_problem/Hydro/GrackleTest/clean.sh @@ -0,0 +1,6 @@ +rm -f Record__Note Record__Timing Record__TimeStep Record__PatchCount Record__Dump Record__MemInfo Record__L1Err \ + Record__Conservation Data* stderr stdout log XYslice* YZslice* XZslice* Xline* Yline* Zline* \ + Diag* BaseXYslice* BaseYZslice* BaseXZslice* BaseXline* BaseYline* BaseZline* BaseDiag* \ + PowerSpec_* Particle_* nohup.out Record__Performance Record__TimingMPI_* \ + Record__ParticleCount Record__User Patch_* Record__NCorrUnphy FailedPatchGroup* *.pyc Record__LoadBalance \ + GRACKLE_INFO diff --git a/example/test_problem/Hydro/GrackleTest/download_CloudyData_UVB.sh b/example/test_problem/Hydro/GrackleTest/download_CloudyData_UVB.sh new file mode 100644 index 0000000000..4edd38919e --- /dev/null +++ b/example/test_problem/Hydro/GrackleTest/download_CloudyData_UVB.sh @@ -0,0 +1,10 @@ +#!/bin/bash +LOCAL_FILENAME="CloudyData_UVB=HM2012.h5" +FILE_ID="677ca211999605c485c8de6c" +FILE_SHA256="8715f1b39e90a7296ec2adcd442fa13a3d45d2ad021c6fa2fae9e4ab7a4700b2" + +# file download +curl -L https://hub.yt/api/v1/item/${FILE_ID}/download -o "${LOCAL_FILENAME}" + +# compare sha256sum +! [ `sha256sum ${LOCAL_FILENAME} | awk '{print $1}'` = "${FILE_SHA256}" ] && echo "File broken: ${LOCAL_FILENAME}" diff --git a/example/test_problem/Hydro/GrackleTest/generate_make.sh b/example/test_problem/Hydro/GrackleTest/generate_make.sh new file mode 100644 index 0000000000..bc933ccf2d --- /dev/null +++ b/example/test_problem/Hydro/GrackleTest/generate_make.sh @@ -0,0 +1,5 @@ +# This script should run in the same directory as configure.py + +PYTHON=python3 + +${PYTHON} configure.py --mpi=true --hdf5=true --gpu=true --model=HYDRO --grackle=true --passive=13 "$@" diff --git a/example/test_problem/Hydro/GrackleTest/yt_script/plot_projection.py b/example/test_problem/Hydro/GrackleTest/yt_script/plot_projection.py new file mode 100644 index 0000000000..b4eda9629e --- /dev/null +++ b/example/test_problem/Hydro/GrackleTest/yt_script/plot_projection.py @@ -0,0 +1,124 @@ +import argparse +import sys +import yt +import numpy as np + +# load the command-line parameters +parser = argparse.ArgumentParser( description='Plot the gas projections' ) + +parser.add_argument( '-p', action='store', required=False, type=str, dest='prefix', + help='path prefix [%(default)s]', default='../' ) +parser.add_argument( '-s', action='store', required=True, type=int, dest='idx_start', + help='first data index' ) +parser.add_argument( '-e', action='store', required=True, type=int, dest='idx_end', + help='last data index' ) +parser.add_argument( '-d', action='store', required=False, type=int, dest='didx', + help='delta data index [%(default)d]', default=1 ) + +args=parser.parse_args() + +# take note +print( '\nCommand-line arguments:' ) +print( '-------------------------------------------------------------------' ) +print( ' '.join(map(str, sys.argv)) ) +print( '-------------------------------------------------------------------\n' ) + + +idx_start = args.idx_start +idx_end = args.idx_end +didx = args.didx +prefix = args.prefix + + +yt.enable_parallelism() + +ts = yt.DatasetSeries( [ prefix+'/Data_%06d'%idx for idx in range(idx_start, idx_end+1, didx) ] ) + + +# target fields and their colorbar limits +zlim = { + 'density' : ( 1.0e-29, 1.0e-21 ), + 'temperature' : ( 1.0e+00, 1.0e+08 ), + 'thermal_energy_density' : ( 1.0e-21, 1.0e-05 ), + 'sound_speed' : ( 1.0e+04, 1.0e+08 ), + 'electron_density' : ( 1.0e-29, 1.0e-21 ), + 'DI_density' : ( 1.0e-29, 1.0e-21 ), + 'DII_density' : ( 1.0e-29, 1.0e-21 ), + 'H2I_density' : ( 1.0e-29, 1.0e-21 ), + 'H2II_density' : ( 1.0e-29, 1.0e-21 ), + 'HDI_density' : ( 1.0e-29, 1.0e-21 ), + 'HI_density' : ( 1.0e-29, 1.0e-21 ), + 'HII_density' : ( 1.0e-29, 1.0e-21 ), + 'HM_density' : ( 1.0e-29, 1.0e-21 ), + 'HeI_density' : ( 1.0e-29, 1.0e-21 ), + 'HeII_density' : ( 1.0e-29, 1.0e-21 ), + 'HeIII_density' : ( 1.0e-29, 1.0e-21 ), + 'metal_density' : ( 1.0e-29, 1.0e-21 ), + 'grackle_T_over_mu' : ( 1.0e+00, 1.0e+08 ), + 'grackle_temperature' : ( 1.0e+00, 1.0e+08 ), + 'grackle_mu' : ( 5.0e-01, 1.5e+00 ), + 'grackle_cooling_rate' : ( -1.0e-24, 1.0e-24 ), + 'grackle_cooling_strength' : ( -1.0e+03, 1.0e+03 ), + 'grackle_cooling_length' : ( 1.0e-04, 1.0e+00 ), + 'grackle_cooling_length_over_dh' : ( 5.0e-02, 2.0e+01 ), + } + + +def set_derived_fields( ds ): + + def _grackle_T_over_mu( field, data ): + return data['grackle_temperature'] / data['grackle_mu'] + ds.add_field( ('gas', 'grackle_T_over_mu'), function=_grackle_T_over_mu, sampling_type='cell', units='K', display_name='Grackle $T/\mu$' ) + + def _grackle_cooling_rate( field, data ): + return data['thermal_energy_density'] / data['grackle_cooling_time'] + ds.add_field( ('gas', 'grackle_cooling_rate'), function=_grackle_cooling_rate, sampling_type='cell', units='erg/cm**3/s' ) + + def _grackle_cooling_strength( field, data ): + return 1.0 / data['grackle_cooling_time'] + ds.add_field( ('gas', 'grackle_cooling_strength'), function=_grackle_cooling_strength, sampling_type='cell', units='Myr**-1' ) + + def _grackle_cooling_length( field, data ): + factor = np.where( data['grackle_cooling_time'] < 0.0, 1.0, np.inf ) + return factor * np.abs( data['grackle_cooling_time'] ) * data['sound_speed'] + ds.add_field( ('gas', 'grackle_cooling_length'), function=_grackle_cooling_length, sampling_type='cell', units='kpc' ) + + def _grackle_cooling_length_over_dh( field, data ): + return data['grackle_cooling_length'] / data['dx'] + ds.add_field( ('gas', 'grackle_cooling_length_over_dh'), function=_grackle_cooling_length_over_dh, sampling_type='cell', units='dimensionless', display_name='Grackle Cooling Length / dh' ) + + +for ds in ts.piter(): + + set_derived_fields( ds ) + + ad = ds.all_data() + + # plot the projections + for field in zlim.keys(): + + if ds.parameters["Grackle_Primordial"] < 3 and (field == 'DI_density' or field == 'DII_density' or field == 'HDI_density'): + continue + if ds.parameters["Grackle_Primordial"] < 2 and (field == 'H2I_density' or field == 'H2II_density' or field == 'HM_density'): + continue + if ds.parameters["Grackle_Primordial"] < 1 and (field == 'HI_density' or field == 'HII_density' or field == 'HeI_density' or field == 'HeII_density' or field == 'HeIII_density' or field == 'electron_density'): + continue + if ds.parameters["Grackle_Metal"] == 0 and field == 'metal_density': + continue + + # Projection weighted by 1 -> get the average + pz = yt.ProjectionPlot( ds, 'z', field, weight_field=('index','ones'), center='c', data_source=ad ) + pz.set_axes_unit( 'kpc' ) + pz.set_zlim( field, zlim[field][0], zlim[field][1] ) + + pz.annotate_text( (0.1,0.9), + "min = {: >11.3e}\nmax = {: >11.3e}".format(ad[field].min(),ad[field].max()), + coord_system='axis', text_args={"color": "grey"} ) + + pz.annotate_timestamp( time_unit='Myr', corner='upper_right' ) + + pz.save( 'fig_%s_Projection_z_%s.png'%(ds, field), mpl_kwargs={'dpi':150} ) + + if field == 'grackle_cooling_length' or field == 'grackle_cooling_length_over_dh': + pz.annotate_grids() + pz.save( 'fig_%s_Projection_z_%s_withgrids.png'%(ds, field), mpl_kwargs={'dpi':150} ) diff --git a/example/test_problem/Hydro/GrackleTest/yt_script/plot_time_evolution.py b/example/test_problem/Hydro/GrackleTest/yt_script/plot_time_evolution.py new file mode 100644 index 0000000000..afac47176c --- /dev/null +++ b/example/test_problem/Hydro/GrackleTest/yt_script/plot_time_evolution.py @@ -0,0 +1,161 @@ +import argparse +import sys +import yt +import matplotlib.pyplot as plt +import numpy as np + +# load the command-line parameters +parser = argparse.ArgumentParser( description='Plot the gas time evolution' ) + +parser.add_argument( '-p', action='store', required=False, type=str, dest='prefix', + help='path prefix [%(default)s]', default='../' ) +parser.add_argument( '-s', action='store', required=True, type=int, dest='idx_start', + help='first data index' ) +parser.add_argument( '-e', action='store', required=True, type=int, dest='idx_end', + help='last data index' ) +parser.add_argument( '-d', action='store', required=False, type=int, dest='didx', + help='delta data index [%(default)d]', default=1 ) + +args=parser.parse_args() + +# take note +print( '\nCommand-line arguments:' ) +print( '-------------------------------------------------------------------' ) +print( ' '.join(map(str, sys.argv)) ) +print( '-------------------------------------------------------------------\n' ) + + +idx_start = args.idx_start +idx_end = args.idx_end +didx = args.didx +prefix = args.prefix + + +yt.enable_parallelism() + +ts = yt.DatasetSeries( [ prefix+'/Data_%06d'%idx for idx in range(idx_start, idx_end+1, didx) ] ) + + +time = np.array([]) +density = np.array([]) +metal_density = np.array([]) +electron_density = np.array([]) +HI_density = np.array([]) +HII_density = np.array([]) +HeI_density = np.array([]) +HeII_density = np.array([]) +HeIII_density = np.array([]) +HM_density = np.array([]) +H2I_density = np.array([]) +H2II_density = np.array([]) +DI_density = np.array([]) +DII_density = np.array([]) +HDI_density = np.array([]) +temperature = np.array([]) +gr_temperature = np.array([]) +gr_mu = np.array([]) +temperature_max = np.array([]) +temperature_min = np.array([]) +gr_temperature_max = np.array([]) +gr_temperature_min = np.array([]) + + +# collect the results +for ds in ts.piter(): + + time = np.append( time , ds.current_time.in_units('Myr').d ) + density = np.append( density , np.average(ds.all_data()['density' ].in_units('g/cm**3').d) ) + + if ds.parameters['Grackle_Metal'] == 1: + metal_density = np.append( metal_density , np.average(ds.all_data()['metal_density' ].in_units('g/cm**3').d) ) + + if ds.parameters['Grackle_Primordial'] >= 1: + electron_density = np.append( electron_density , np.average(ds.all_data()['electron_density' ].in_units('g/cm**3').d) ) + HI_density = np.append( HI_density , np.average(ds.all_data()['HI_density' ].in_units('g/cm**3').d) ) + HII_density = np.append( HII_density , np.average(ds.all_data()['HII_density' ].in_units('g/cm**3').d) ) + HeI_density = np.append( HeI_density , np.average(ds.all_data()['HeI_density' ].in_units('g/cm**3').d) ) + HeII_density = np.append( HeII_density , np.average(ds.all_data()['HeII_density' ].in_units('g/cm**3').d) ) + HeIII_density = np.append( HeIII_density , np.average(ds.all_data()['HeIII_density' ].in_units('g/cm**3').d) ) + + if ds.parameters['Grackle_Primordial'] >= 2: + HM_density = np.append( HM_density , np.average(ds.all_data()['HM_density' ].in_units('g/cm**3').d) ) + H2I_density = np.append( H2I_density , np.average(ds.all_data()['H2I_density' ].in_units('g/cm**3').d) ) + H2II_density = np.append( H2II_density , np.average(ds.all_data()['H2II_density' ].in_units('g/cm**3').d) ) + + if ds.parameters['Grackle_Primordial'] >= 3: + DI_density = np.append( DI_density , np.average(ds.all_data()['DI_density' ].in_units('g/cm**3').d) ) + DII_density = np.append( DII_density , np.average(ds.all_data()['DII_density' ].in_units('g/cm**3').d) ) + HDI_density = np.append( HDI_density , np.average(ds.all_data()['HDI_density' ].in_units('g/cm**3').d) ) + + temperature = np.append( temperature , np.average(ds.all_data()['temperature' ].in_units('K').d) ) + gr_temperature = np.append( gr_temperature , np.average(ds.all_data()['grackle_temperature'].in_units('K').d) ) + gr_mu = np.append( gr_mu , np.average(ds.all_data()['grackle_mu' ].d) ) + + temperature_max = np.append( temperature_max , np.max( ds.all_data()['temperature' ].in_units('K').d) ) + temperature_min = np.append( temperature_min , np.min( ds.all_data()['temperature' ].in_units('K').d) ) + gr_temperature_max = np.append( gr_temperature_max, np.max( ds.all_data()['grackle_temperature'].in_units('K').d) ) + gr_temperature_min = np.append( gr_temperature_min, np.min( ds.all_data()['grackle_temperature'].in_units('K').d) ) + + +# plot the results +f, ax = plt.subplots( 1, 2, figsize=(12.8, 4.8) ) + + +# plot the temperature evolution +ax[0].plot( time, gr_temperature, 'k-s', label='Grackle T' ) +ax[0].plot( time, temperature, 'k--', label='GAMER T' ) +ax[0].plot( time, gr_temperature/gr_mu, 'k:', label='Grackle T/mu' ) + +if ds.parameters['GrackleTest_DefaultTestMode'] == 3: + # plot the expected temperature evolution for the given heating and cooling rates + r_heat = ds.parameters['GrackleTest_HeatingRate'] * ds.parameters['Grackle_HydrogenMFrac'] * (ds.parameters['Gamma']-1) * ds.parameters['MolecularWeight'] / ds.units.boltzmann_constant.in_units('erg/K').v *(1.*ds.units.Myr).in_units('s').v + r_cool = (density[0]*ds.parameters['Grackle_HydrogenMFrac']/ds.units.hydrogen_mass.in_units('g').v*ds.parameters['GrackleTest_CoolingRate']) * ds.parameters['Grackle_HydrogenMFrac'] * (ds.parameters['Gamma']-1) * ds.parameters['MolecularWeight'] / ds.units.boltzmann_constant.in_units('erg/K').v *(1.*ds.units.Myr).in_units('s').v + ax[0].plot( time, temperature_max[0]+time*r_heat, 'g-.', label='Analytical max(T)' ) + ax[0].plot( time, temperature_min[0]-time*r_cool, 'y-.', label='Analytical min(T)' ) + + # plot the maximum and minimum temperature evolution as the results of the given heating and cooling rates + ax[0].plot( time, temperature_max, 'r--', label='max(T)' ) + ax[0].plot( time, temperature_min, 'b--', label='min(T)' ) + +ax[0].set_yscale( 'log' ) +ax[0].set_xlim( 0.0, 1.33*np.max(time) ) +ax[0].set_ylim( 0.1*np.min(gr_temperature_min), 10.0*np.max(gr_temperature_max) ) +ax[0].set_xlabel( 'Time (Myr)', fontsize='large' ) +ax[0].set_ylabel( 'Temperature (K)', fontsize='large' ) +ax[0].legend() + + +# plot the density evolution +ax[1].plot( time, density, 'k-s', label='' ) + +if ds.parameters['Grackle_Metal'] == 1: + ax[1].plot( time, metal_density, 'g-', label='Metal' ) + +if ds.parameters['Grackle_Primordial'] >= 1: + ax[1].plot( time, electron_density, 'g--', label='e' ) + ax[1].plot( time, HI_density, 'r-', label='HI' ) + ax[1].plot( time, HII_density, 'r--', label='HII' ) + ax[1].plot( time, HeI_density, 'b-', label='HeI' ) + ax[1].plot( time, HeII_density, 'b--', label='HeII' ) + ax[1].plot( time, HeIII_density, 'b-.', label='HEIII' ) + +if ds.parameters['Grackle_Primordial'] >= 2: + ax[1].plot( time, HM_density, 'r:', label='HM' ) + ax[1].plot( time, H2I_density, 'm--', label='H2I' ) + ax[1].plot( time, H2II_density, 'm-', label='H2II' ) + +if ds.parameters['Grackle_Primordial'] >= 3: + ax[1].plot( time, DI_density, 'c-', label='DI' ) + ax[1].plot( time, DII_density, 'c--', label='DII' ) + ax[1].plot( time, HDI_density, 'y-', label='HDI' ) + +ax[1].set_yscale( 'log' ) +ax[1].set_xlim( 0.0, 1.33*np.max(time) ) +ax[1].set_ylim( 3.0e-6*np.min(density), 3.0*np.max(density) ) +ax[1].set_xlabel( 'Time (Myr)', fontsize='large' ) +ax[1].set_ylabel( 'Density (g/cm$^3$)', fontsize='large' ) +ax[1].legend() + + +f.subplots_adjust( wspace=0.2 ) +f.savefig( 'fig_time_evolution.png', bbox_inches='tight', pad_inches=0.05, dpi=150 ) diff --git a/example/test_problem/Hydro/GrackleTest/yt_script/yt.toml b/example/test_problem/Hydro/GrackleTest/yt_script/yt.toml new file mode 100644 index 0000000000..db8ca3d31d --- /dev/null +++ b/example/test_problem/Hydro/GrackleTest/yt_script/yt.toml @@ -0,0 +1,201 @@ +[fields.gamer.GrackleTemp] +aliases = ["grackle_temperature"] +units = "code_temperature" +display_name = "Grackle Temperature" + +[fields.gamer.GrackleMu] +aliases = ["grackle_mu"] +units = "dimensionless" +display_name = "Grackle Mean Molecular Weight" + +[fields.gamer.GrackleTCool] +aliases = ["grackle_cooling_time"] +units = "code_time" +display_name = "Grackle Cooling Time" + +[fields.gamer.Metal] +aliases = ["metal_density"] +units = "code_density" +display_name = "Metal Mass Density" + +[fields.gamer.Electron] +aliases = ["electron_density"] +units = "code_density" +display_name = "Electron Mass Density" + +[fields.gamer.HI] +aliases = ["HI_density"] +units = "code_density" +display_name = "HI Mass Density" + +[fields.gamer.HII] +aliases = ["HII_density"] +units = "code_density" +display_name = "HII Mass Density" + +[fields.gamer.HeI] +aliases = ["HeI_density"] +units = "code_density" +display_name = "HeI Mass Density" + +[fields.gamer.HeII] +aliases = ["HeII_density"] +units = "code_density" +display_name = "HeII Mass Density" + +[fields.gamer.HeIII] +aliases = ["HeIII_density"] +units = "code_density" +display_name = "HeIII Mass Density" + +[fields.gamer.HM] +aliases = ["HM_density"] +units = "code_density" +display_name = "HM Mass Density" + +[fields.gamer.H2I] +aliases = ["H2I_density"] +units = "code_density" +display_name = "H2I Mass Density" + +[fields.gamer.H2II] +aliases = ["H2II_density"] +units = "code_density" +display_name = "H2II Mass Density" + +[fields.gamer.DI] +aliases = ["DI_density"] +units = "code_density" +display_name = "DI Mass Density" + +[fields.gamer.DII] +aliases = ["DII_density"] +units = "code_density" +display_name = "DII Mass Density" + +[fields.gamer.HDI] +aliases = ["HDI_density"] +units = "code_density" +display_name = "HDI Mass Density" + +[plot.gas.density] +cmap = "viridis" +log = true +units = "g/cm**3" + +[plot.gas.metal_density] +cmap = "viridis" +log = true +units = "g/cm**3" + +[plot.gas.HI_density] +cmap = "viridis" +log = true +units = "g/cm**3" + +[plot.gas.HII_density] +cmap = "viridis" +log = true +units = "g/cm**3" + +[plot.gas.HeI_density] +cmap = "viridis" +log = true +units = "g/cm**3" + +[plot.gas.HeII_density] +cmap = "viridis" +log = true +units = "g/cm**3" + +[plot.gas.HeIII_density] +cmap = "viridis" +log = true +units = "g/cm**3" + +[plot.gas.electron_density] +cmap = "viridis" +log = true +units = "g/cm**3" + +[plot.gas.H2I_density] +cmap = "viridis" +log = true +units = "g/cm**3" + +[plot.gas.H2II_density] +cmap = "viridis" +log = true +units = "g/cm**3" + +[plot.gas.HM_density] +cmap = "viridis" +log = true +units = "g/cm**3" + +[plot.gas.DI_density] +cmap = "viridis" +log = true +units = "g/cm**3" + +[plot.gas.DII_density] +cmap = "viridis" +log = true +units = "g/cm**3" + +[plot.gas.HDI_density] +cmap = "viridis" +log = true +units = "g/cm**3" + +[plot.gas.temperature] +cmap = "magma" +log = true +units = "K" + +[plot.gas.grackle_temperature] +cmap = "magma" +log = true +units = "K" + +[plot.gas.grackle_T_over_mu] +cmap = "magma" +log = true +units = "K" + +[plot.gas.thermal_energy_density] +cmap = "magma" +log = true +units = "erg/cm**3" + +[plot.gas.sound_speed] +cmap = "magma" +log = true +units = "cm/s" + +[plot.gas.grackle_mu] +cmap = "cividis" +log = false +units = "dimensionless" + +[plot.gas.grackle_cooling_rate] +cmap = "bwr" +log = true +linthresh=1.0e-29 +units = "erg/cm**3/s" + +[plot.gas.grackle_cooling_strength] +cmap = "bwr" +log = true +linthresh=1.0e-3 +units = "Myr**-1" + +[plot.gas.grackle_cooling_length] +cmap = "Blues_r" +log = true +units = "kpc" + +[plot.gas.grackle_cooling_length_over_dh] +cmap = "PiYG" +log = true +units = "dimensionless" diff --git a/example/test_problem/Template/Input__Parameter b/example/test_problem/Template/Input__Parameter index d7742ab30f..eb3c429009 100644 --- a/example/test_problem/Template/Input__Parameter +++ b/example/test_problem/Template/Input__Parameter @@ -47,6 +47,7 @@ TESTPROB_ID 0 # test problem ID [0] # 20: HYDRO MHD Cosmic Ray Soundwave # 21: HYDRO MHD Cosmic Ray Shocktube # 23: HYDRO MHD Cosmic Ray Diffusion + # 24: HYDRO Grackle Test (+SUPPORT_GRACKLE) # 100: HYDRO CDM cosmological simulation (+GRAVITY & COMOVING & PARTICLE) # 101: HYDRO Zeldovich pancake collapse (+GRAVITY & COMOVING & PARTICLE) # 1000: ELBDM external potential (+GRAVITY) @@ -121,6 +122,7 @@ DT__HYBRID_VELOCITY_INIT -1.0 # dt criterion: DT__HYBRID_VELOCITY in DT__PARVEL 0.5 # dt criterion: particle velocity safety factor [0.5] DT__PARVEL_MAX -1.0 # dt criterion: maximum allowed dt from particle velocity (<0=off) [-1.0] DT__PARACC 0.5 # dt criterion: particle acceleration safety factor (0=off) [0.5] ##STORE_PAR_ACC ONLY## +DT__GRACKLE_COOLING -1.0 # dt criterion: factor for Grackle cooling time (<0=off) [-1.0] ##SUPPORT_GRACKLE only## DT__CR_DIFFUSION 0.3 # dt criterion: cosmic-ray diffusion CFL factor [0.3] ##CR_DIFFUSION only## DT__MAX_DELTA_A 0.01 # dt criterion: maximum variation of the cosmic scale factor [0.01] DT__SYNC_PARENT_LV 0.1 # dt criterion: allow dt to adjust by (1.0+DT__SYNC_PARENT) in order to synchronize @@ -152,6 +154,7 @@ OPT__FLAG_PRES_GRADIENT 0 # flag: pressure gradient (Input__Flag OPT__FLAG_LRTZ_GRADIENT 0 # flag: Lorentz factor gradient (Input__Flag_LrtzGradient) [0] ##SRHD ONLY## OPT__FLAG_VORTICITY 0 # flag: vorticity (Input__Flag_Vorticity) [0] ##HYDRO ONLY## OPT__FLAG_JEANS 0 # flag: Jeans length (Input__Flag_Jeans) [0] ##HYDRO ONLY## +OPT__FLAG_COOLING_LEN 0 # flag: cooling length (Input__Flag_CoolingLen) [0] ##HYDRO+SUPPORT_GRACKLE ONLY## OPT__FLAG_CURRENT 0 # flag: current density in MHD (Input__Flag_Current) [0] ##MHD ONLY## OPT__FLAG_CRAY 0 # flag: cosmic-ray energy (Input__Flag_CRay) [0] ##COSMIC_RAY ONLY## OPT__FLAG_ENGY_DENSITY 0 # flag: energy density (Input_Flag_EngyDensity) [0] ##ELBDM ONLY## @@ -205,17 +208,20 @@ SRC_GPU_NPGROUP -1 # number of patch groups sent into the GRACKLE_ACTIVATE 1 # enable Grackle [1] GRACKLE_VERBOSE 1 # map to "grackle_verbose" [1] GRACKLE_COOLING 1 # map to "with_radiative_cooling" [1] -GRACKLE_PRIMORDIAL 0 # map to "primordial_chemistry" (0=Cloudy, 1/2/3=6-/9-/12-species) [0] - # (must increase NCOMP_PASSIVE_USER by 6/9/12, respectively) +GRACKLE_PRIMORDIAL 0 # map to "primordial_chemistry" (0=Cloudy, 1/2/3=6-/9-/12-species) (must increase NCOMP_PASSIVE_USER by 6/9/12, respectively) [0] GRACKLE_METAL 0 # map to "metal_cooling" (must increase NCOMP_PASSIVE_USER by 1) [0] GRACKLE_UV 0 # map to "UVbackground" [0] GRACKLE_CMB_FLOOR 1 # map to "cmb_temperature_floor" [1] GRACKLE_PE_HEATING 0 # map to "photoelectric_heating" [0] -GRACKLE_PE_HEATING_RATE 8.5e-26 # map to "photoelectric_heating_rate (in erg/cm^3/s)" [8.5e-26] +GRACKLE_PE_HEATING_RATE 8.5e-26 # map to "photoelectric_heating_rate" (in erg/cm^3/s/n_H) [8.5e-26] GRACKLE_CLOUDY_TABLE CloudyData_noUVB.h5 # "grackle_data_file" -GRACKLE_THREE_BODY_RATE 4 # used Glover+08 rate -GRACKLE_CIE_COOLING 1 # 0: off; 1:on -GRACKLE_H2_OPA_APPROX 1 # H2 opacity from Ripamonti+04; 0:off, 1:Ripomonti+04 +GRACKLE_THREE_BODY_RATE 0 # map to "three_body_rate" (0=Abel+02, 1=Palla+83, 2=Cohen+83, 3=Flower+07, 4=Glover+08, 5=Forrey+13) [0] +GRACKLE_CIE_COOLING 0 # map to "cie_cooling" [0] +GRACKLE_H2_OPA_APPROX 0 # map to "h2_optical_depth_approximation" (0=off, 1=Ripomonti+04) [0] +GRACKLE_USE_V_HEATING_RATE 0 # map to "use_volumetric_heating_rate" [0] +GRACKLE_USE_S_HEATING_RATE 0 # map to "use_specific_heating_rate" [0] +GRACKLE_HYDROGEN_MFRAC 0.76 # map to "HydrogenFractionByMass" (NOT set to Grackle when GRACKLE_PRIMORDIAL==0) [0.76] +OPT__UNFREEZE_GRACKLE 0 # allow the evolution by Grackle solver when the fluid is frozen (for OPT__FREEZE_FLUID==1 only) [0] CHE_GPU_NPGROUP -1 # number of patch groups sent into the CPU/GPU Grackle solver (<=0=auto) [-1] @@ -401,6 +407,9 @@ OPT__OUTPUT_DIVMAG 0 # output |divergence(B)*dh/|B|| [0] ## OPT__OUTPUT_LORENTZ 0 # output Lorentz factor [0] ##SRHD ONLY## OPT__OUTPUT_3VELOCITY 0 # output 3-velocities [0] ##SRHD ONLY## OPT__OUTPUT_ENTHALPY 1 # output reduced enthalpy [1] ##SRHD ONLY## +OPT__OUTPUT_GRACKLE_TEMP 0 # output the temperature calculated by Grackle [0] ##SUPPORT_GRACKLE only## +OPT__OUTPUT_GRACKLE_MU 0 # output the mean molecular weight calculated by Grackle [0] ##SUPPORT_GRACKLE only## +OPT__OUTPUT_GRACKLE_TCOOL 0 # output the cooling time calculated by Grackle [0] ##SUPPORT_GRACKLE only## OPT__OUTPUT_USER_FIELD 0 # output user-defined derived fields [0] -> edit "Flu_DerivedField_User.cpp" OPT__OUTPUT_MODE 1 # (1=const step, 2=const dt, 3=dump table) -> edit "Input__DumpTable" for 3 OPT__OUTPUT_RESTART 0 # output data immediately after restart [0] diff --git a/include/Global.h b/include/Global.h index aabea2f5b6..c8e8834ce5 100644 --- a/include/Global.h +++ b/include/Global.h @@ -278,6 +278,16 @@ extern char GRACKLE_CLOUDY_TABLE[MAX_STRING]; extern int GRACKLE_THREE_BODY_RATE; extern bool GRACKLE_CIE_COOLING; extern int GRACKLE_H2_OPA_APPROX; +extern bool GRACKLE_USE_V_HEATING_RATE; +extern bool GRACKLE_USE_S_HEATING_RATE; +extern double GRACKLE_HYDROGEN_MFRAC; +extern bool OPT__UNFREEZE_GRACKLE; +extern bool OPT__OUTPUT_GRACKLE_TEMP; +extern bool OPT__OUTPUT_GRACKLE_MU; +extern bool OPT__OUTPUT_GRACKLE_TCOOL; +extern bool OPT__FLAG_COOLING_LEN; +extern double FlagTable_CoolingLen[NLEVEL-1]; +extern double DT__GRACKLE_COOLING; extern int CHE_GPU_NPGROUP; #endif diff --git a/include/HDF5_Typedef.h b/include/HDF5_Typedef.h index edde083e3b..aeb60bfd99 100644 --- a/include/HDF5_Typedef.h +++ b/include/HDF5_Typedef.h @@ -479,6 +479,9 @@ struct InputPara_t # ifdef CR_DIFFUSION double Dt__CR_Diffusion; # endif +# ifdef SUPPORT_GRACKLE + double Dt__GrackleCooling; +# endif # ifdef COMOVING double Dt__MaxDeltaA; # endif @@ -527,6 +530,9 @@ struct InputPara_t # ifdef SRHD int Opt__Flag_LrtzGradient; # endif +# ifdef SUPPORT_GRACKLE + int Opt__Flag_CoolingLen; +# endif # ifdef COSMIC_RAY int Opt__Flag_CRay; # endif @@ -699,6 +705,10 @@ struct InputPara_t int Grackle_ThreeBodyRate; int Grackle_CIE_Cooling; int Grackle_H2_OpaApprox; + int Grackle_UseVHeatingRate; + int Grackle_UseSHeatingRate; + double Grackle_HydrogenMFrac; + int Opt__UnfreezeGrackle; int Che_GPU_NPGroup; # endif @@ -831,6 +841,11 @@ struct InputPara_t int Opt__Output_3Velocity; int Opt__Output_Enthalpy; # endif +# ifdef SUPPORT_GRACKLE + int Opt__Output_GrackleTemp; + int Opt__Output_GrackleMu; + int Opt__Output_GrackleTCool; +# endif # endif // #if ( MODEL == HYDRO ) int Opt__Output_UserField; int Opt__Output_Mode; @@ -913,6 +928,9 @@ struct InputPara_t # ifdef SRHD double FlagTable_LrtzGradient[NLEVEL-1]; # endif +# ifdef SUPPORT_GRACKLE + double FlagTable_CoolingLen [NLEVEL-1]; +# endif # ifdef COSMIC_RAY double FlagTable_CRay [NLEVEL-1]; # endif diff --git a/include/Prototype.h b/include/Prototype.h index 767fd31d06..d7ca6d52cb 100644 --- a/include/Prototype.h +++ b/include/Prototype.h @@ -368,7 +368,8 @@ void FindFather( const int lv, const int Mode ); void Flag_Real( const int lv, const UseLBFunc_t UseLBFunc ); bool Flag_Check( const int lv, const int PID, const int i, const int j, const int k, const real dv, const real Fluid[][PS1][PS1][PS1], const real Pot[][PS1][PS1], const real MagCC[][PS1][PS1][PS1], - const real Vel[][PS1][PS1][PS1], const real Pres[][PS1][PS1], const real Lrtz[][PS1][PS1], + const real Vel[][PS1][PS1][PS1], const real Pres[][PS1][PS1], const real Lrtz[][PS1][PS1], + const real Lcool[][PS1][PS1], const real *Lohner_Var, const real *Lohner_Ave, const real *Lohner_Slope, const int Lohner_NVar, const real ParCount[][PS1][PS1], const real ParDens[][PS1][PS1], const real JeansCoeff, const real *Interf_Var, const real Spectral_Cond ); @@ -814,16 +815,18 @@ void CPU_SrcSolver( const real h_Flu_Array_In [][FLU_NIN_S ][ CUBE(SRC_NXT) // Grackle #ifdef SUPPORT_GRACKLE -void Grackle_Init(); -void Grackle_Init_FieldData(); -void Grackle_End(); -void Init_MemAllocate_Grackle( const int Che_NPG ); -void End_MemFree_Grackle(); -void Grackle_Prepare( const int lv, real_che h_Che_Array[], const int NPG, const int *PID0_List ); -void Grackle_Close( const int lv, const int SaveSg, const real_che h_Che_Array[], const int NPG, const int *PID0_List ); -void Grackle_AdvanceDt( const int lv, const double TimeNew, const double TimeOld, const double dt, const int SaveSg, - const bool OverlapMPI, const bool Overlap_Sync ); -void CPU_GrackleSolver( grackle_field_data *Che_FieldData, code_units Che_Units, const int NPatchGroup, const real dt ); +void Grackle_Init(); +void Grackle_Init_FieldData(); +void Grackle_End(); +void Init_MemAllocate_Grackle( const int Che_NPG ); +void End_MemFree_Grackle(); +void Grackle_Prepare( const int lv, real_che h_Che_Array[], const int NPG, const int *PID0_List ); +void Grackle_Close( const int lv, const int SaveSg, const real_che h_Che_Array[], const int NPG, const int *PID0_List ); +void Grackle_AdvanceDt( const int lv, const double TimeNew, const double TimeOld, const double dt, const int SaveSg, + const bool OverlapMPI, const bool Overlap_Sync ); +void CPU_GrackleSolver( grackle_field_data *Che_FieldData, code_units Che_Units, const int NPatchGroup, const real dt ); +void Grackle_Calculate( real Out[], const GrackleFieldBIdx_t TFields, const int lv, const int NPG, const int *PID0_List ); +double Grackle_GetTimeStep_CoolingTime( const int lv ); #endif // #ifdef SUPPORT_GRACKLE diff --git a/include/TestProb.h b/include/TestProb.h index e9d4a43afe..17b384c1ff 100644 --- a/include/TestProb.h +++ b/include/TestProb.h @@ -120,6 +120,10 @@ extern int (*FB_User_Ptr)( const int lv, const double TimeNew, const double Tim real (*Fluid)[FB_NXT][FB_NXT][FB_NXT], const double EdgeL[], const double dh, bool CoarseFine[], const int TID, RandomNumber_t *RNG ); #endif +#ifdef SUPPORT_GRACKLE +extern real_che (*Grackle_vHeatingRate_User_Ptr)( const double x, const double y, const double z, const double Time, const double n_H ); +extern real_che (*Grackle_sHeatingRate_User_Ptr)( const double x, const double y, const double z, const double Time ); +#endif diff --git a/include/Typedef.h b/include/Typedef.h index c2d767a47e..f6053aa92c 100644 --- a/include/Typedef.h +++ b/include/Typedef.h @@ -93,6 +93,7 @@ const TestProbID_t TESTPROB_HYDRO_CR_SOUNDWAVE = 20, TESTPROB_HYDRO_CR_SHOCKTUBE = 21, TESTPROB_HYDRO_CR_DIFFUSION = 23, + TESTPROB_HYDRO_GRACKLE_TEST = 24, TESTPROB_HYDRO_BARRED_POT = 51, TESTPROB_HYDRO_JET_ICM_WALL = 52, TESTPROB_HYDRO_CDM_LSS = 100, @@ -521,6 +522,13 @@ const GracklePriChe_t GRACKLE_PRI_CHE_NSPE6 = 1, GRACKLE_PRI_CHE_NSPE9 = 2, GRACKLE_PRI_CHE_NSPE12 = 3; + +// bitwise field indices used by Grackle +typedef long GrackleFieldBIdx_t; +const GrackleFieldBIdx_t + _GRACKLE_TEMP = ( 1L << 0 ), + _GRACKLE_MU = ( 1L << 1 ), + _GRACKLE_TCOOL = ( 1L << 2 ); #endif diff --git a/src/Auxiliary/Aux_Check_Parameter.cpp b/src/Auxiliary/Aux_Check_Parameter.cpp index a018831b4b..ed2bc78cb5 100644 --- a/src/Auxiliary/Aux_Check_Parameter.cpp +++ b/src/Auxiliary/Aux_Check_Parameter.cpp @@ -310,8 +310,13 @@ void Aux_Check_Parameter() { int NDerField = UserDerField_Num; # if ( MODEL == HYDRO ) - if ( OPT__OUTPUT_DIVVEL ) NDerField ++; - if ( OPT__OUTPUT_MACH ) NDerField ++; + if ( OPT__OUTPUT_DIVVEL ) NDerField ++; + if ( OPT__OUTPUT_MACH ) NDerField ++; +# ifdef SUPPORT_GRACKLE + if ( OPT__OUTPUT_GRACKLE_TEMP ) NDerField ++; + if ( OPT__OUTPUT_GRACKLE_MU ) NDerField ++; + if ( OPT__OUTPUT_GRACKLE_TCOOL ) NDerField ++; +# endif # endif if ( NDerField > DER_NOUT_MAX ) @@ -428,6 +433,9 @@ void Aux_Check_Parameter() # ifdef SRHD Flag |= OPT__FLAG_LRTZ_GRADIENT; # endif +# ifdef SUPPORT_GRACKLE + Flag |= OPT__FLAG_COOLING_LEN; +# endif # ifdef COSMIC_RAY Flag |= OPT__FLAG_CRAY; Flag |= OPT__FLAG_LOHNER_CRAY; @@ -1793,6 +1801,21 @@ void Aux_Check_Parameter() # error : ERROR : SUPPORT_GRACKLE must work with EOS_GAMMA/EOS_COSMIC_RAY !! # endif + if ( OPT__OUTPUT_GRACKLE_TEMP && ! GRACKLE_ACTIVATE ) + Aux_Error( ERROR_INFO, "OPT__OUTPUT_GRACKLE_TEMP requires the option GRACKLE_ACTIVATE !!\n"); + + if ( OPT__OUTPUT_GRACKLE_MU && ! GRACKLE_ACTIVATE ) + Aux_Error( ERROR_INFO, "OPT__OUTPUT_GRACKLE_MU requires the option GRACKLE_ACTIVATE !!\n"); + + if ( OPT__OUTPUT_GRACKLE_TCOOL && ! GRACKLE_ACTIVATE ) + Aux_Error( ERROR_INFO, "OPT__OUTPUT_GRACKLE_TCOOL requires the option GRACKLE_ACTIVATE !!\n"); + + if ( OPT__FLAG_COOLING_LEN && ! GRACKLE_ACTIVATE ) + Aux_Error( ERROR_INFO, "OPT__FLAG_COOLING_LEN requires the option GRACKLE_ACTIVATE !!\n"); + + if ( DT__GRACKLE_COOLING >= 0.0 && ! GRACKLE_ACTIVATE ) + Aux_Error( ERROR_INFO, "DT__GRACKLE_COOLING requires the option GRACKLE_ACTIVATE !!\n"); + // warning // ------------------------------ if ( MPI_Rank == 0 ) { @@ -1803,6 +1826,25 @@ void Aux_Check_Parameter() if ( GRACKLE_PRIMORDIAL > 0 ) Aux_Message( stderr, "WARNING : adiabatic index gamma is currently fixed to %13.7e for Grackle !!\n", GAMMA ); + if ( OPT__UNFREEZE_GRACKLE && ! OPT__FREEZE_FLUID ) + Aux_Message( stderr, "WARNING : OPT__UNFREEZE_GRACKLE is useless when OPT__FREEZE_FLUID is off !!\n" ); + + if ( OPT__UNFREEZE_GRACKLE && OPT__FREEZE_FLUID ) + Aux_Message( stderr, "REMINDER : OPT__UNFREEZE_GRACKLE will allow fluid variables to be updated by Grackle solver even with OPT__FREEZE_FLUID enabled !!\n" ); + + if ( OPT__OUTPUT_GRACKLE_TEMP && OPT__OUTPUT_TEMP ) + { + Aux_Message( stderr, "WARNING : temperature field calculated by Grackle is named \"GrackleTemp\"\n" ); + Aux_Message( stderr, " and it is different from the default temperature field \"Temp\" !!\n" ); + } + + if ( GRACKLE_PRIMORDIAL == GRACKLE_PRI_CHE_CLOUDY ) + { + Aux_Message( stderr, "WARNING : For GRACKLE_PRIMORDIAL == %d, GRACKLE_HYDROGEN_MFRAC = %13.7e is only used outside Grackle\n", + GRACKLE_PRI_CHE_CLOUDY, GRACKLE_HYDROGEN_MFRAC ); + Aux_Message( stderr, " and it can be different from HydrogenFractionByMass determined by and used inside Grackle !!\n" ); + } + } // if ( MPI_Rank == 0 ) #endif // #ifdef SUPPORT_GRACKLE diff --git a/src/Auxiliary/Aux_TakeNote.cpp b/src/Auxiliary/Aux_TakeNote.cpp index ef833f01fb..7e800e2966 100644 --- a/src/Auxiliary/Aux_TakeNote.cpp +++ b/src/Auxiliary/Aux_TakeNote.cpp @@ -980,6 +980,9 @@ void Aux_TakeNote() # ifdef CR_DIFFUSION fprintf( Note, "DT__CR_DIFFUSION % 14.7e\n", DT__CR_DIFFUSION ); # endif +# ifdef SUPPORT_GRACKLE + fprintf( Note, "DT__GRACKLE_COOLING % 14.7e\n", DT__GRACKLE_COOLING ); +# endif # ifdef COMOVING fprintf( Note, "DT__MAX_DELTA_A % 14.7e\n", DT__MAX_DELTA_A ); # endif @@ -1022,6 +1025,9 @@ void Aux_TakeNote() # ifdef SRHD fprintf( Note, "OPT__FLAG_LRTZ_GRADIENT % d\n", OPT__FLAG_LRTZ_GRADIENT ); # endif +# ifdef SUPPORT_GRACKLE + fprintf( Note, "OPT__FLAG_COOLING_LEN % d\n", OPT__FLAG_COOLING_LEN ); +# endif # endif # if ( MODEL == ELBDM ) fprintf( Note, "OPT__FLAG_ENGY_DENSITY % d\n", OPT__FLAG_ENGY_DENSITY ); @@ -1123,21 +1129,25 @@ void Aux_TakeNote() # ifdef SUPPORT_GRACKLE fprintf( Note, "Parameters of Grackle\n" ); fprintf( Note, "***********************************************************************************\n" ); - fprintf( Note, "GRACKLE_ACTIVATE % d\n", GRACKLE_ACTIVATE ); + fprintf( Note, "GRACKLE_ACTIVATE % d\n", GRACKLE_ACTIVATE ); if ( GRACKLE_ACTIVATE ) { - fprintf( Note, "GRACKLE_VERBOSE % d\n", GRACKLE_VERBOSE ); - fprintf( Note, "GRACKLE_COOLING % d\n", GRACKLE_COOLING ); - fprintf( Note, "GRACKLE_PRIMORDIAL % d\n", GRACKLE_PRIMORDIAL ); - fprintf( Note, "GRACKLE_METAL % d\n", GRACKLE_METAL ); - fprintf( Note, "GRACKLE_UV % d\n", GRACKLE_UV ); - fprintf( Note, "GRACKLE_CMB_FLOOR % d\n", GRACKLE_CMB_FLOOR ); - fprintf( Note, "GRACKLE_PE_HEATING % d\n", GRACKLE_PE_HEATING ); - fprintf( Note, "GRACKLE_PE_HEATING_RATE % 14.7e\n", GRACKLE_PE_HEATING_RATE ); - fprintf( Note, "GRACKLE_CLOUDY_TABLE %s\n", GRACKLE_CLOUDY_TABLE ); - fprintf( Note, "GRACKLE_THREE_BODY_RATE % d\n", GRACKLE_THREE_BODY_RATE ); - fprintf( Note, "GRACKLE_CIE_COOLING % d\n", GRACKLE_CIE_COOLING ); - fprintf( Note, "GRACKLE_H2_OPA_APPROX % d\n", GRACKLE_H2_OPA_APPROX ); - fprintf( Note, "CHE_GPU_NPGROUP % d\n", CHE_GPU_NPGROUP ); } + fprintf( Note, "GRACKLE_VERBOSE % d\n", GRACKLE_VERBOSE ); + fprintf( Note, "GRACKLE_COOLING % d\n", GRACKLE_COOLING ); + fprintf( Note, "GRACKLE_PRIMORDIAL % d\n", GRACKLE_PRIMORDIAL ); + fprintf( Note, "GRACKLE_METAL % d\n", GRACKLE_METAL ); + fprintf( Note, "GRACKLE_UV % d\n", GRACKLE_UV ); + fprintf( Note, "GRACKLE_CMB_FLOOR % d\n", GRACKLE_CMB_FLOOR ); + fprintf( Note, "GRACKLE_PE_HEATING % d\n", GRACKLE_PE_HEATING ); + fprintf( Note, "GRACKLE_PE_HEATING_RATE % 14.7e\n", GRACKLE_PE_HEATING_RATE ); + fprintf( Note, "GRACKLE_CLOUDY_TABLE %s\n", GRACKLE_CLOUDY_TABLE ); + fprintf( Note, "GRACKLE_THREE_BODY_RATE % d\n", GRACKLE_THREE_BODY_RATE ); + fprintf( Note, "GRACKLE_CIE_COOLING % d\n", GRACKLE_CIE_COOLING ); + fprintf( Note, "GRACKLE_H2_OPA_APPROX % d\n", GRACKLE_H2_OPA_APPROX ); + fprintf( Note, "GRACKLE_USE_V_HEATING_RATE % d\n", GRACKLE_USE_V_HEATING_RATE ); + fprintf( Note, "GRACKLE_USE_S_HEATING_RATE % d\n", GRACKLE_USE_S_HEATING_RATE ); + fprintf( Note, "GRACKLE_HYDROGEN_MFRAC % 14.7e\n", GRACKLE_HYDROGEN_MFRAC ); + fprintf( Note, "OPT__UNFREEZE_GRACKLE % d\n", OPT__UNFREEZE_GRACKLE ); + fprintf( Note, "CHE_GPU_NPGROUP % d\n", CHE_GPU_NPGROUP ); } fprintf( Note, "***********************************************************************************\n" ); fprintf( Note, "\n\n" ); # endif // #ifdef SUPPORT_GRACKLE @@ -1619,7 +1629,6 @@ void Aux_TakeNote() fprintf( Note, "OPT__OUTPUT_CS % d\n", OPT__OUTPUT_CS ); fprintf( Note, "OPT__OUTPUT_DIVVEL % d\n", OPT__OUTPUT_DIVVEL ); fprintf( Note, "OPT__OUTPUT_MACH % d\n", OPT__OUTPUT_MACH ); -# endif # ifdef MHD fprintf( Note, "OPT__OUTPUT_DIVMAG % d\n", OPT__OUTPUT_DIVMAG ); # endif @@ -1629,6 +1638,12 @@ void Aux_TakeNote() fprintf( Note, "OPT__OUTPUT_LORENTZ % d\n", OPT__OUTPUT_LORENTZ ); fprintf( Note, "OPT__OUTPUT_ENTHALPY % d\n", OPT__OUTPUT_ENTHALPY ); # endif +# ifdef SUPPORT_GRACKLE + fprintf( Note, "OPT__OUTPUT_GRACKLE_TEMP % d\n", OPT__OUTPUT_GRACKLE_TEMP ); + fprintf( Note, "OPT__OUTPUT_GRACKLE_MU % d\n", OPT__OUTPUT_GRACKLE_MU ); + fprintf( Note, "OPT__OUTPUT_GRACKLE_TCOOL % d\n", OPT__OUTPUT_GRACKLE_TCOOL ); +# endif +# endif // user-defined derived fields if ( OPT__OUTPUT_USER_FIELD ) { @@ -1832,6 +1847,18 @@ void Aux_TakeNote() } # endif +# ifdef SUPPORT_GRACKLE + if ( OPT__FLAG_COOLING_LEN ) + { + fprintf( Note, "Flag Criterion (Cooling Length over Cell Size in HYDRO+GRACKLE)\n" ); + fprintf( Note, "***********************************************************************************\n" ); + fprintf( Note, " Level l_cool / dh\n" ); + for (int lv=0; lv declared in Init_MemAllocate_Grackle.cpp +extern int Che_NField; +extern int CheIdx_sEint; + + + + +//------------------------------------------------------------------------------------------------------- +// Function : Grackle_Calculate +// Description : Calculate the fields by calling Grackle's API functions +// +// Note : 1. Ref: https://grackle.readthedocs.io/en/latest/Interaction.html#calling-the-available-functions +// 2. Currently, the fields have to be calculated in units of patch group +// 3. The output field data type is "real" instead of "real_che" +// --> to be consistent with the usage of the output +// 4. This function can be invoked by +// e.g., Output_DumpData_*(), Flag_Real() and Grackle_GetTimeStep_CoolingTime() +// +// Parameter : Out : Output array, array size = NFieldOut*(NPG*PS2*PS2*PS2) +// TFields : Target fields to be calculated: +// _GRACKLE_TEMP, _GRACKLE_MU, _GRACKLE_TCOOL +// --> defined in include/Typedef.h +// lv : Target refinement level +// NPG : Number of patch groups calculated at a time +// PID0_List : List recording the patch indices with LocalID==0 to be calculated +// +// Return : Out[] +//------------------------------------------------------------------------------------------------------- +void Grackle_Calculate( real Out[], const GrackleFieldBIdx_t TFields, + const int lv, const int NPG, const int *PID0_List ) +{ + +// 0. nothing to do if there is no target patch group + if ( NPG == 0 ) return; + + const int Size1v = NPG * CUBE(PS2); // size of one field + + +// 1. check the number of output fields + int NFieldOut = 0; + const int IdxOut_Undefined = -1; + const int IdxOut_temp = ( TFields & _GRACKLE_TEMP ) ? NFieldOut++ : IdxOut_Undefined; + const int IdxOut_mu = ( TFields & _GRACKLE_MU ) ? NFieldOut++ : IdxOut_Undefined; + const int IdxOut_tcool = ( TFields & _GRACKLE_TCOOL ) ? NFieldOut++ : IdxOut_Undefined; + + if ( NFieldOut == 0 ) return; + + +// 2. allocate and prepare the input array for the Grackle solver + real_che *gr_fields_input = new real_che[ (long)Che_NField*(long)Size1v ]; + + Grackle_Prepare( lv, gr_fields_input, NPG, PID0_List ); + + +// 3. allocate the output array for the Grackle solver + real_che *gr_fields_temperature = NULL; + real_che *gr_fields_gamma = NULL; + real_che *gr_fields_cooling_time = NULL; + + if ( IdxOut_temp != IdxOut_Undefined || IdxOut_mu != IdxOut_Undefined ) + gr_fields_temperature = new real_che[Size1v]; + + if ( IdxOut_mu != IdxOut_Undefined ) + gr_fields_gamma = new real_che[Size1v]; + + if ( IdxOut_tcool != IdxOut_Undefined ) + gr_fields_cooling_time = new real_che[Size1v]; + + typedef real (*vla_out)[Size1v]; + vla_out Out1D = ( vla_out )Out; + + +// 4. set grid_dimension, grid_start, and grid_end + const int OptFac = 16; // optimization factor + if ( SQR(PS2)%OptFac != 0 ) Aux_Error( ERROR_INFO, "SQR(PS2) %% OptFac != 0 !!\n" ); + + Che_FieldData->grid_dimension[0] = PS2*OptFac; + Che_FieldData->grid_dimension[1] = 1; + Che_FieldData->grid_dimension[2] = SQR(PS2)*NPG/OptFac; + + for (int d=0; d<3; d++) + { + Che_FieldData->grid_start[d] = 0; + Che_FieldData->grid_end [d] = Che_FieldData->grid_dimension[d] - 1; + } + + +// 5. invoke Grackle +// --> note that we use the OpenMP implementation in Grackle directly, which applies the parallelization to the first two +// dimensiones of the input grid +// --> this approach is found to be much more efficient than parallelizing different patches or patch groups here + if ( IdxOut_temp != IdxOut_Undefined || IdxOut_mu != IdxOut_Undefined ) + { + if ( calculate_temperature( &Che_Units, Che_FieldData, gr_fields_temperature ) == 0 ) + Aux_Error( ERROR_INFO, "Grackle calculate_temperature() failed !!\n" ); + } + + if ( IdxOut_mu != IdxOut_Undefined ) + { + if ( calculate_gamma( &Che_Units, Che_FieldData, gr_fields_gamma ) == 0 ) + Aux_Error( ERROR_INFO, "Grackle calculate_gamma() failed !!\n" ); + } + + if ( IdxOut_tcool != IdxOut_Undefined ) + { + if ( calculate_cooling_time( &Che_Units, Che_FieldData, gr_fields_cooling_time ) == 0 ) + Aux_Error( ERROR_INFO, "Grackle calculate_cooling_time() failed !!\n" ); + } + + +// 6. fill in the output array + const real_che *gr_fields_sEint = gr_fields_input + CheIdx_sEint*Size1v; + const real_che temperature_units = (real_che) get_temperature_units( &Che_Units ); + + for (int i=0; i Physical coordinates : dt = physical time interval +// Comoving coordinates : dt = delta(scale_factor) / ( Hubble_parameter*scale_factor^3 ) +// --> We convert dt back to the physical time interval, which equals "delta(scale_factor)" +// in the comoving coordinates, in Mis_GetTimeStep() +// 2. Time-step is set to restrict the cooling process +// --> dt = DT__GRACKLE_COOLING * Min(CoolingTime) +// 3. This is usually for the purpose of outputting data for analysis; +// Inside the Grackle solver, subcycling time-steps will be adopted for the correctness of evolution +// +// Parameter : lv : Target refinement level +// +// Return : dt +//------------------------------------------------------------------------------------------------------- +double Grackle_GetTimeStep_CoolingTime( const int lv ) +{ + +// get the minimum cooling time + const real MinCoolingTime = GetMinCoolingTime( lv ); + +// get the time-step + const double dt = DT__GRACKLE_COOLING * MinCoolingTime; + + return dt; + +} // FUNCTION : Grackle_GetTimeStep_CoolingTime + + + +//------------------------------------------------------------------------------------------------------- +// Function : GetMinCoolingTime +// Description : Get the minimum Grackle cooling time at the target level among all MPI ranks +// +// Note : 1. Invoked by Grackle_GetTimeStep_CoolingTime() +// +// Parameter : lv : Target refinement level +// +// Return : MinCoolingTime_AllRank +//------------------------------------------------------------------------------------------------------- +real GetMinCoolingTime( const int lv ) +{ + + real MinCoolingTime = INFINITY; + bool AnyCell = false; + +# pragma omp parallel + { + + real *Grackle_TCool = new real [ CUBE(PS2) ]; // array storing ONE patch group of grackle cooling time + +// get the minimum Grckle cooling time in this rank +# pragma omp for reduction( min:MinCoolingTime ) reduction( ||:AnyCell ) schedule( runtime ) + for (int PID0=0; PID0NPatchComma[lv][1]; PID0+=8) + { + +// calculate the Grackle cooling time + Grackle_Calculate( Grackle_TCool, _GRACKLE_TCOOL, lv, 1, &PID0 ); + + for (int LocalID=0; LocalID<8; LocalID++) + { + const int PID = PID0 + LocalID; + +// if OPT__FIXUP_RESTRICT is enabled, skip all non-leaf patches +// becausethey are later overwritten by the refined patches +// note that this leads to the timestep being "inf" when a level is completely refined + if ( OPT__FIXUP_RESTRICT && amr->patch[0][lv][PID]->son != -1 ) continue; + + AnyCell = true; + +// calculate the minimum + for (int k=0; kNPatchComma[lv][1]; PID0+=8) + + delete [] Grackle_TCool; + + } // OpenMP parallel region + + +// get the minimum Grackle cooling time in all ranks + real MinCoolingTime_AllRank; + bool AnyCell_AllRank; + + MPI_Allreduce( &MinCoolingTime, &MinCoolingTime_AllRank, 1, MPI_GAMER_REAL, MPI_MIN, MPI_COMM_WORLD ); + MPI_Reduce( &AnyCell, &AnyCell_AllRank, 1, MPI_C_BOOL, MPI_LOR, 0, MPI_COMM_WORLD ); + + +// check + if ( MinCoolingTime_AllRank == INFINITY && AnyCell_AllRank && MPI_Rank == 0 ) + Aux_Error( ERROR_INFO, "MinCoolingTime == INFINITY at lv %d !!\n", lv ); + + + return MinCoolingTime_AllRank; + +} // FUNCTION : GetMinCoolingTime + + + +#endif // #ifdef SUPPORT_GRACKLE diff --git a/src/Grackle/Grackle_Init.cpp b/src/Grackle/Grackle_Init.cpp index a6843c9fc6..4a4e8b8ec3 100644 --- a/src/Grackle/Grackle_Init.cpp +++ b/src/Grackle/Grackle_Init.cpp @@ -99,6 +99,13 @@ void Grackle_Init() grackle_data->three_body_rate = GRACKLE_THREE_BODY_RATE; grackle_data->cie_cooling = GRACKLE_CIE_COOLING; grackle_data->h2_optical_depth_approximation = GRACKLE_H2_OPA_APPROX; + grackle_data->use_volumetric_heating_rate = GRACKLE_USE_V_HEATING_RATE; + grackle_data->use_specific_heating_rate = GRACKLE_USE_S_HEATING_RATE; +// hydrogen mass fraction is only set when it is in non-equilibrium mode +// because the tables for tabulated mode were created assuming hydrogen mass fraction of about 0.716 +// see https://grackle.readthedocs.io/en/latest/Parameters.html#c.HydrogenFractionByMass + if ( GRACKLE_PRIMORDIAL != GRACKLE_PRI_CHE_CLOUDY ) + grackle_data->HydrogenFractionByMass = GRACKLE_HYDROGEN_MFRAC; # ifdef OPENMP // currently we adopt the OpenMP implementation in Grackle directly, which applies the parallelization to diff --git a/src/Grackle/Grackle_Init_FieldData.cpp b/src/Grackle/Grackle_Init_FieldData.cpp index d8b0d8eafc..7c11268b11 100644 --- a/src/Grackle/Grackle_Init_FieldData.cpp +++ b/src/Grackle/Grackle_Init_FieldData.cpp @@ -64,13 +64,13 @@ void Grackle_Init_FieldData() Che_FieldData->DII_density = NULL; Che_FieldData->HDI_density = NULL; Che_FieldData->metal_density = NULL; + Che_FieldData->volumetric_heating_rate = NULL; + Che_FieldData->specific_heating_rate = NULL; // fields not supported yet Che_FieldData->x_velocity = NULL; Che_FieldData->y_velocity = NULL; Che_FieldData->z_velocity = NULL; - Che_FieldData->volumetric_heating_rate = NULL; - Che_FieldData->specific_heating_rate = NULL; Che_FieldData->RT_HI_ionization_rate = NULL; Che_FieldData->RT_HeI_ionization_rate = NULL; Che_FieldData->RT_HeII_ionization_rate = NULL; diff --git a/src/Grackle/Grackle_Prepare.cpp b/src/Grackle/Grackle_Prepare.cpp index dd71c474ff..9f7a7a241f 100644 --- a/src/Grackle/Grackle_Prepare.cpp +++ b/src/Grackle/Grackle_Prepare.cpp @@ -22,8 +22,19 @@ extern int CheIdx_DI; extern int CheIdx_DII; extern int CheIdx_HDI; extern int CheIdx_Metal; +extern int CheIdx_vHeatingRate; +extern int CheIdx_sHeatingRate; +// declare as static so that other functions cannot invoke it directly and must use the function pointer +static real_che Grackle_vHeatingRate_User_Template( const double x, const double y, const double z, const double Time, const double n_H ); +static real_che Grackle_sHeatingRate_User_Template( const double x, const double y, const double z, const double Time ); + + +// these function pointers must be set by a test problem initializer +real_che (*Grackle_vHeatingRate_User_Ptr)( const double x, const double y, const double z, const double Time, const double n_H ) = NULL; +real_che (*Grackle_sHeatingRate_User_Ptr)( const double x, const double y, const double z, const double Time ) = NULL; + //------------------------------------------------------------------------------------------------------- @@ -89,6 +100,20 @@ void Grackle_Prepare( const int lv, real_che h_Che_Array[], const int NPG, const if ( Idx_Metal == Idx_Undefined || CheIdx_Metal == Idx_Undefined ) Aux_Error( ERROR_INFO, "[Che]Idx_Metal is undefined for \"GRACKLE_METAL\" !!\n" ); } + + if ( GRACKLE_USE_V_HEATING_RATE ) { + if ( Grackle_vHeatingRate_User_Ptr == NULL ) + Aux_Error( ERROR_INFO, "Grackle_vHeatingRate_User_Ptr == NULL !!\n" ); + if ( CheIdx_vHeatingRate == Idx_Undefined ) + Aux_Error( ERROR_INFO, "CheIdx_vHeatingRate is undefined for \"GRACKLE_USE_V_HEATING_RATE\" !!\n" ); + } + + if ( GRACKLE_USE_S_HEATING_RATE ) { + if ( Grackle_sHeatingRate_User_Ptr == NULL ) + Aux_Error( ERROR_INFO, "Grackle_sHeatingRate_User_Ptr == NULL !!\n" ); + if ( CheIdx_sHeatingRate == Idx_Undefined ) + Aux_Error( ERROR_INFO, "CheIdx_sHeatingRate is undefined for \"GRACKLE_USE_S_HEATING_RATE\" !!\n" ); + } # endif // #ifdef GAMER_DEBUG @@ -100,23 +125,26 @@ void Grackle_Prepare( const int lv, real_che h_Che_Array[], const int NPG, const # else const bool CheckMinEint_Yes = true; # endif - - real_che *Ptr_Dens0 = h_Che_Array + CheIdx_Dens *Size1v; - real_che *Ptr_sEint0 = h_Che_Array + CheIdx_sEint*Size1v; - real_che *Ptr_Ent0 = h_Che_Array + CheIdx_Ent *Size1v; - real_che *Ptr_e0 = h_Che_Array + CheIdx_e *Size1v; - real_che *Ptr_HI0 = h_Che_Array + CheIdx_HI *Size1v; - real_che *Ptr_HII0 = h_Che_Array + CheIdx_HII *Size1v; - real_che *Ptr_HeI0 = h_Che_Array + CheIdx_HeI *Size1v; - real_che *Ptr_HeII0 = h_Che_Array + CheIdx_HeII *Size1v; - real_che *Ptr_HeIII0 = h_Che_Array + CheIdx_HeIII*Size1v; - real_che *Ptr_HM0 = h_Che_Array + CheIdx_HM *Size1v; - real_che *Ptr_H2I0 = h_Che_Array + CheIdx_H2I *Size1v; - real_che *Ptr_H2II0 = h_Che_Array + CheIdx_H2II *Size1v; - real_che *Ptr_DI0 = h_Che_Array + CheIdx_DI *Size1v; - real_che *Ptr_DII0 = h_Che_Array + CheIdx_DII *Size1v; - real_che *Ptr_HDI0 = h_Che_Array + CheIdx_HDI *Size1v; - real_che *Ptr_Metal0 = h_Che_Array + CheIdx_Metal*Size1v; + const double dh = amr->dh[lv]; + + real_che *Ptr_Dens0 = h_Che_Array + CheIdx_Dens *Size1v; + real_che *Ptr_sEint0 = h_Che_Array + CheIdx_sEint *Size1v; + real_che *Ptr_Ent0 = h_Che_Array + CheIdx_Ent *Size1v; + real_che *Ptr_e0 = h_Che_Array + CheIdx_e *Size1v; + real_che *Ptr_HI0 = h_Che_Array + CheIdx_HI *Size1v; + real_che *Ptr_HII0 = h_Che_Array + CheIdx_HII *Size1v; + real_che *Ptr_HeI0 = h_Che_Array + CheIdx_HeI *Size1v; + real_che *Ptr_HeII0 = h_Che_Array + CheIdx_HeII *Size1v; + real_che *Ptr_HeIII0 = h_Che_Array + CheIdx_HeIII *Size1v; + real_che *Ptr_HM0 = h_Che_Array + CheIdx_HM *Size1v; + real_che *Ptr_H2I0 = h_Che_Array + CheIdx_H2I *Size1v; + real_che *Ptr_H2II0 = h_Che_Array + CheIdx_H2II *Size1v; + real_che *Ptr_DI0 = h_Che_Array + CheIdx_DI *Size1v; + real_che *Ptr_DII0 = h_Che_Array + CheIdx_DII *Size1v; + real_che *Ptr_HDI0 = h_Che_Array + CheIdx_HDI *Size1v; + real_che *Ptr_Metal0 = h_Che_Array + CheIdx_Metal *Size1v; + real_che *Ptr_vHeatingRate0 = h_Che_Array + CheIdx_vHeatingRate*Size1v; + real_che *Ptr_sHeatingRate0 = h_Che_Array + CheIdx_sHeatingRate*Size1v; # pragma omp parallel @@ -135,30 +163,33 @@ void Grackle_Prepare( const int lv, real_che h_Che_Array[], const int NPG, const real_che *Ptr_Dens=NULL, *Ptr_sEint=NULL, *Ptr_Ent=NULL, *Ptr_e=NULL, *Ptr_HI=NULL, *Ptr_HII=NULL; real_che *Ptr_HeI=NULL, *Ptr_HeII=NULL, *Ptr_HeIII=NULL, *Ptr_HM=NULL, *Ptr_H2I=NULL, *Ptr_H2II=NULL; real_che *Ptr_DI=NULL, *Ptr_DII=NULL, *Ptr_HDI=NULL, *Ptr_Metal=NULL; + real_che *Ptr_vHeatingRate=NULL, *Ptr_sHeatingRate=NULL; # pragma omp for schedule( static ) for (int TID=0; TIDpatch[ amr->FluSg[lv] ][lv][PID]->fluid; + const double x0 = amr->patch[0][lv][PID]->EdgeL[0] + 0.5*dh; + const double y0 = amr->patch[0][lv][PID]->EdgeL[1] + 0.5*dh; + const double z0 = amr->patch[0][lv][PID]->EdgeL[2] + 0.5*dh; + for (int k=0; kmetal_density = Ptr_Metal0; + if ( GRACKLE_USE_V_HEATING_RATE ) + Che_FieldData->volumetric_heating_rate = Ptr_vHeatingRate0; + + if ( GRACKLE_USE_S_HEATING_RATE ) + Che_FieldData->specific_heating_rate = Ptr_sHeatingRate0; + } // FUNCTION : Grackle_Prepare +//------------------------------------------------------------------------------------------------------- +// Function : Grackle_vHeatingRate_User_Template +// Description : Function template to set Grackle's volumetric heating rate +// +// Note : 1. Invoked by Grackle_Prepare() using the function pointer +// "Grackle_vHeatingRate_User_Ptr", which must be set by a test problem initializer +// 2. This function will be invoked by multiple OpenMP threads when OPENMP is enabled +// --> Please ensure that everything here is thread-safe +// 3. Returned rate should be in the unit of erg s^-1 cm^-3 +// +// Parameter : x/y/z : Target physical coordinates +// Time : Target physical time +// n_H : Hydrogen number density, should be in the unit of cm^-3 +// +// Return : volumetric_heating_rate +//------------------------------------------------------------------------------------------------------- +real_che Grackle_vHeatingRate_User_Template( const double x, const double y, const double z, const double Time, const double n_H ) +{ + + const double Center[3] = { amr->BoxCenter[0], amr->BoxCenter[1], amr->BoxCenter[2] }; + const double radius_to_center = sqrt( SQR(x-Center[0]) + SQR(y-Center[1]) ); + const double ScaleLength = 0.125*amr->BoxSize[0]; + const double R_core = 0.125*amr->BoxSize[0]; + const double volumetric_heating_rate_0 = n_H * GRACKLE_PE_HEATING_RATE; // GRACKLE_PE_HEATING_RATE is in units of erg cm^-3 s^-1 n_H^-1 + const real_che volumetric_heating_rate = volumetric_heating_rate_0 * exp( (R_core - MAX(radius_to_center, R_core)) / ScaleLength ); + + return volumetric_heating_rate; + +} // FUNCTION : Grackle_vHeatingRate_User_Template + + + +//------------------------------------------------------------------------------------------------------- +// Function : Grackle_sHeatingRate_User_Template +// Description : Function template to set Grackle's specific heating rate +// +// Note : 1. Invoked by Grackle_Prepare() using the function pointer +// "Grackle_sHeatingRate_User_Ptr", which must be set by a test problem initializer +// 2. This function will be invoked by multiple OpenMP threads when OPENMP is enabled +// --> Please ensure that everything here is thread-safe +// 3. Returned rate should be in the units of erg s^-1 g^-1 +// +// Parameter : x/y/z : Target physical coordinates +// Time : Target physical time +// +// Return : specific_heating_rate +//------------------------------------------------------------------------------------------------------- +real_che Grackle_sHeatingRate_User_Template( const double x, const double y, const double z, const double Time ) +{ + + const double Center[3] = { amr->BoxCenter[0], amr->BoxCenter[1], amr->BoxCenter[2] }; + const double radius_to_center = sqrt( SQR(x-Center[0]) + SQR(y-Center[1]) ); + const double ScaleLength = 0.125*amr->BoxSize[0]; + const double R_core = 0.125*amr->BoxSize[0]; + const double specific_heating_rate_0 = GRACKLE_PE_HEATING_RATE * GRACKLE_HYDROGEN_MFRAC / Const_mH; // GRACKLE_PE_HEATING_RATE is in units of erg cm^-3 s^-1 n_H^-1 + const real_che specific_heating_rate = specific_heating_rate_0 * exp( (R_core - MAX(radius_to_center, R_core)) / ScaleLength ); + + return specific_heating_rate; + +} // FUNCTION : Grackle_sHeatingRate_User_Template + + + #endif // #ifdef SUPPORT_GRACKLE diff --git a/src/Grackle/Init_MemAllocate_Grackle.cpp b/src/Grackle/Init_MemAllocate_Grackle.cpp index 36a64b2164..1045898631 100644 --- a/src/Grackle/Init_MemAllocate_Grackle.cpp +++ b/src/Grackle/Init_MemAllocate_Grackle.cpp @@ -6,23 +6,25 @@ // global variables for accessing h_Che_Array[] // --> also used by Grackle_Prepare.cpp and Grackle_Close.cpp // --> they are not declared in "Global.h" simply because they are only used by a few Grackle routines -int Che_NField = NULL_INT; -int CheIdx_Dens = Idx_Undefined; -int CheIdx_sEint = Idx_Undefined; -int CheIdx_Ent = Idx_Undefined; -int CheIdx_e = Idx_Undefined; -int CheIdx_HI = Idx_Undefined; -int CheIdx_HII = Idx_Undefined; -int CheIdx_HeI = Idx_Undefined; -int CheIdx_HeII = Idx_Undefined; -int CheIdx_HeIII = Idx_Undefined; -int CheIdx_HM = Idx_Undefined; -int CheIdx_H2I = Idx_Undefined; -int CheIdx_H2II = Idx_Undefined; -int CheIdx_DI = Idx_Undefined; -int CheIdx_DII = Idx_Undefined; -int CheIdx_HDI = Idx_Undefined; -int CheIdx_Metal = Idx_Undefined; +int Che_NField = NULL_INT; +int CheIdx_Dens = Idx_Undefined; +int CheIdx_sEint = Idx_Undefined; +int CheIdx_Ent = Idx_Undefined; +int CheIdx_e = Idx_Undefined; +int CheIdx_HI = Idx_Undefined; +int CheIdx_HII = Idx_Undefined; +int CheIdx_HeI = Idx_Undefined; +int CheIdx_HeII = Idx_Undefined; +int CheIdx_HeIII = Idx_Undefined; +int CheIdx_HM = Idx_Undefined; +int CheIdx_H2I = Idx_Undefined; +int CheIdx_H2II = Idx_Undefined; +int CheIdx_DI = Idx_Undefined; +int CheIdx_DII = Idx_Undefined; +int CheIdx_HDI = Idx_Undefined; +int CheIdx_Metal = Idx_Undefined; +int CheIdx_vHeatingRate = Idx_Undefined; +int CheIdx_sHeatingRate = Idx_Undefined; @@ -76,6 +78,12 @@ void Init_MemAllocate_Grackle( const int Che_NPG ) if ( GRACKLE_METAL ) CheIdx_Metal = Che_NField ++; + if ( GRACKLE_USE_V_HEATING_RATE ) + CheIdx_vHeatingRate = Che_NField ++; + + if ( GRACKLE_USE_S_HEATING_RATE ) + CheIdx_sHeatingRate = Che_NField ++; + // allocate the input/output array for the Grackle solver for (int t=0; t<2; t++) diff --git a/src/Init/Init_ByRestart_HDF5.cpp b/src/Init/Init_ByRestart_HDF5.cpp index e08c16a93f..dfbdb4f58d 100644 --- a/src/Init/Init_ByRestart_HDF5.cpp +++ b/src/Init/Init_ByRestart_HDF5.cpp @@ -2015,6 +2015,9 @@ void Check_InputPara( const char *FileName, const int FormatVersion ) # ifdef CR_DIFFUSION LoadField( "Dt__CR_Diffusion", &RS.Dt__CR_Diffusion, SID, TID, NonFatal, &RT.Dt__CR_Diffusion, 1, NonFatal ); # endif +# ifdef SUPPORT_GRACKLE + LoadField( "Dt__GrackleCooling", &RS.Dt__GrackleCooling, SID, TID, NonFatal, &RT.Dt__GrackleCooling, 1, NonFatal ); +# endif # ifdef COMOVING LoadField( "Dt__MaxDeltaA", &RS.Dt__MaxDeltaA, SID, TID, NonFatal, &RT.Dt__MaxDeltaA, 1, NonFatal ); # endif @@ -2055,6 +2058,9 @@ void Check_InputPara( const char *FileName, const int FormatVersion ) # ifdef SRHD LoadField( "Opt__Flag_LrtzGradient", &RS.Opt__Flag_LrtzGradient, SID, TID, NonFatal, &RT.Opt__Flag_LrtzGradient, 1, NonFatal ); # endif +# ifdef SUPPORT_GRACKLE + LoadField( "Opt__Flag_CoolingLen", &RS.Opt__Flag_CoolingLen, SID, TID, NonFatal, &RT.Opt__Flag_CoolingLen, 1, NonFatal ); +# endif # ifdef COSMIC_RAY LoadField( "Opt__Flag_CRay", &RS.Opt__Flag_CRay, SID, TID, NonFatal, &RT.Opt__Flag_CRay, 1, NonFatal ); # endif @@ -2225,6 +2231,10 @@ void Check_InputPara( const char *FileName, const int FormatVersion ) LoadField( "Grackle_ThreeBodyRate", &RS.Grackle_ThreeBodyRate, SID, TID, NonFatal, &RT.Grackle_ThreeBodyRate, 1, NonFatal ); LoadField( "Grackle_CIE_Cooling", &RS.Grackle_CIE_Cooling, SID, TID, NonFatal, &RT.Grackle_CIE_Cooling, 1, NonFatal ); LoadField( "Grackle_H2_OpaApprox", &RS.Grackle_H2_OpaApprox, SID, TID, NonFatal, &RT.Grackle_H2_OpaApprox, 1, NonFatal ); + LoadField( "Grackle_UseVHeatingRate", &RS.Grackle_UseVHeatingRate, SID, TID, NonFatal, &RT.Grackle_UseVHeatingRate, 1, NonFatal ); + LoadField( "Grackle_UseSHeatingRate", &RS.Grackle_UseSHeatingRate, SID, TID, NonFatal, &RT.Grackle_UseSHeatingRate, 1, NonFatal ); + LoadField( "Grackle_HydrogenMFrac", &RS.Grackle_HydrogenMFrac, SID, TID, NonFatal, &RT.Grackle_HydrogenMFrac, 1, NonFatal ); + LoadField( "Opt__UnfreezeGrackle", &RS.Opt__UnfreezeGrackle, SID, TID, NonFatal, &RT.Opt__UnfreezeGrackle, 1, NonFatal ); LoadField( "Che_GPU_NPGroup", &RS.Che_GPU_NPGroup, SID, TID, NonFatal, &RT.Che_GPU_NPGroup, 1, NonFatal ); # endif @@ -2355,6 +2365,11 @@ void Check_InputPara( const char *FileName, const int FormatVersion ) LoadField( "Opt__Output_3Velocity", &RS.Opt__Output_3Velocity, SID, TID, NonFatal, &RT.Opt__Output_3Velocity, 1, NonFatal ); LoadField( "Opt__Output_Enthalpy", &RS.Opt__Output_Enthalpy, SID, TID, NonFatal, &RT.Opt__Output_Enthalpy, 1, NonFatal ); # endif +# ifdef SUPPORT_GRACKLE + LoadField( "Opt__Output_GrackleTemp", &RS.Opt__Output_GrackleTemp, SID, TID, NonFatal, &RT.Opt__Output_GrackleTemp, 1, NonFatal ); + LoadField( "Opt__Output_GrackleMu", &RS.Opt__Output_GrackleMu, SID, TID, NonFatal, &RT.Opt__Output_GrackleMu, 1, NonFatal ); + LoadField( "Opt__Output_GrackleTCool", &RS.Opt__Output_GrackleTCool, SID, TID, NonFatal, &RT.Opt__Output_GrackleTCool, 1, NonFatal ); +# endif # endif // #if ( MODEL == HYDRO ) LoadField( "Opt__Output_UserField", &RS.Opt__Output_UserField, SID, TID, NonFatal, &RT.Opt__Output_UserField, 1, NonFatal ); # ifdef PARTICLE @@ -2474,6 +2489,9 @@ void Check_InputPara( const char *FileName, const int FormatVersion ) # ifdef SRHD RS.FlagTable_LrtzGradient[lv] = -1.0; # endif +# ifdef SRHD + RS.FlagTable_CoolingLen [lv] = -1.0; +# endif # elif ( MODEL == ELBDM ) for (int t=0; t<2; t++) { @@ -2573,6 +2591,11 @@ void Check_InputPara( const char *FileName, const int FormatVersion ) LoadField( "FlagTable_LrtzGradient", RS.FlagTable_LrtzGradient, SID, TID, NonFatal, RT.FlagTable_LrtzGradient, N1, NonFatal ); # endif +# ifdef SUPPORT_GRACKLE + if ( OPT__FLAG_COOLING_LEN ) + LoadField( "FlagTable_CoolingLen", RS.FlagTable_CoolingLen, SID, TID, NonFatal, RT.FlagTable_CoolingLen, N1, NonFatal ); +# endif + # elif ( MODEL == ELBDM ) if ( OPT__FLAG_ENGY_DENSITY ) { LoadField( "FlagTable_EngyDensity", RS.FlagTable_EngyDensity, SID, TID, NonFatal, NullPtr, -1, NonFatal ); diff --git a/src/Init/Init_Load_FlagCriteria.cpp b/src/Init/Init_Load_FlagCriteria.cpp index a856bf55bc..826ca709ef 100644 --- a/src/Init/Init_Load_FlagCriteria.cpp +++ b/src/Init/Init_Load_FlagCriteria.cpp @@ -35,6 +35,12 @@ void Init_Load_FlagCriteria() const bool OPT__FLAG_LRTZ_GRADIENT = false; double *FlagTable_LrtzGradient = NULL; # endif + +# ifndef SUPPORT_GRACKLE + const bool OPT__FLAG_COOLING_LEN = false; + double *FlagTable_CoolingLen = NULL; +# endif + # ifndef COSMIC_RAY const bool OPT__FLAG_LOHNER_CRAY = false; const bool OPT__FLAG_CRAY = false; @@ -74,32 +80,35 @@ void Init_Load_FlagCriteria() # error : unsupported MODEL !! # endif - const int NFlagMode = 18; + const int NFlagMode = 19; const bool Flag[NFlagMode] = { OPT__FLAG_RHO, OPT__FLAG_RHO_GRADIENT, OPT__FLAG_PRES_GRADIENT, OPT__FLAG_ENGY_DENSITY, OPT__FLAG_LOHNER, OPT__FLAG_USER, (bool)OPT__FLAG_NPAR_PATCH, OPT__FLAG_NPAR_CELL, OPT__FLAG_PAR_MASS_CELL, OPT__FLAG_VORTICITY, OPT__FLAG_JEANS, OPT__FLAG_CURRENT, OPT__FLAG_CRAY, OPT__FLAG_LRTZ_GRADIENT, OPT__FLAG_INTERFERENCE, - OPT__FLAG_SPECTRAL, OPT__FLAG_ANGULAR, OPT__FLAG_RADIAL }; + OPT__FLAG_SPECTRAL, OPT__FLAG_ANGULAR, OPT__FLAG_RADIAL, + OPT__FLAG_COOLING_LEN }; const char ModeName[][100] = { "OPT__FLAG_RHO", "OPT__FLAG_RHO_GRADIENT", "OPT__FLAG_PRES_GRADIENT", "OPT__FLAG_ENGY_DENSITY", "OPT__FLAG_LOHNER", "OPT__FLAG_USER", "OPT__FLAG_NPAR_PATCH", "OPT__FLAG_NPAR_CELL", "OPT__FLAG_PAR_MASS_CELL", "OPT__FLAG_VORTICITY", "OPT__FLAG_JEANS", "OPT__FLAG_CURRENT", "OPT__FLAG_CRAY", "OPT__FLAG_LRTZ_GRADIENT", "OPT__FLAG_INTERFERENCE", - "OPT__FLAG_SPECTRAL", "OPT__FLAG_ANGULAR", "OPT__FLAG_RADIAL" }; + "OPT__FLAG_SPECTRAL", "OPT__FLAG_ANGULAR", "OPT__FLAG_RADIAL", + "OPT__FLAG_COOLING_LEN" }; const char FileName[][100] = { "Input__Flag_Rho", "Input__Flag_RhoGradient", "Input__Flag_PresGradient", "Input__Flag_EngyDensity", "Input__Flag_Lohner", "Input__Flag_User", "Input__Flag_NParPatch", "Input__Flag_NParCell", "Input__Flag_ParMassCell", "Input__Flag_Vorticity", "Input__Flag_Jeans", "Input__Flag_Current", "Input__Flag_CRay", "Input__Flag_LrtzGradient", "Input__Flag_Interference", "Input__Flag_Spectral", "Input__Flag_AngularResolution", - "Input__Flag_RadialResolution"}; + "Input__Flag_RadialResolution", "Input__Flag_CoolingLen" }; + double *FlagTable[NFlagMode] = { FlagTable_Rho, FlagTable_RhoGradient, FlagTable_PresGradient, NULL, NULL, NULL, NULL, NULL, FlagTable_ParMassCell, FlagTable_Vorticity, FlagTable_Jeans, FlagTable_Current, FlagTable_CRay, FlagTable_LrtzGradient, NULL, NULL, NULL, - FlagTable_Radial }; + FlagTable_Radial, FlagTable_CoolingLen }; FILE *File; char *input_line = NULL, TargetName[100]; @@ -138,6 +147,9 @@ void Init_Load_FlagCriteria() # ifdef SRHD FlagTable_LrtzGradient[lv] = -1.0; # endif +# ifdef SUPPORT_GRACKLE + FlagTable_CoolingLen [lv] = -1.0; +# endif # elif ( MODEL == ELBDM ) for (int t=0; t<2; t++) { diff --git a/src/Init/Init_Load_Parameter.cpp b/src/Init/Init_Load_Parameter.cpp index 7149d02b3a..9f31d7c863 100644 --- a/src/Init/Init_Load_Parameter.cpp +++ b/src/Init/Init_Load_Parameter.cpp @@ -130,6 +130,9 @@ void Init_Load_Parameter() # ifdef CR_DIFFUSION ReadPara->Add( "DT__CR_DIFFUSION", &DT__CR_DIFFUSION, 3.0e-1, 0.0, NoMax_double ); # endif +# ifdef SUPPORT_GRACKLE + ReadPara->Add( "DT__GRACKLE_COOLING", &DT__GRACKLE_COOLING, -1.0, NoMin_double, NoMax_double ); +# endif # ifdef COMOVING ReadPara->Add( "DT__MAX_DELTA_A", &DT__MAX_DELTA_A, 0.01, 0.0, NoMax_double ); # endif @@ -166,6 +169,9 @@ void Init_Load_Parameter() # ifdef SRHD ReadPara->Add( "OPT__FLAG_LRTZ_GRADIENT", &OPT__FLAG_LRTZ_GRADIENT, false, Useless_bool, Useless_bool ); # endif +# ifdef SUPPORT_GRACKLE + ReadPara->Add( "OPT__FLAG_COOLING_LEN", &OPT__FLAG_COOLING_LEN, false, Useless_bool, Useless_bool ); +# endif # ifdef MHD ReadPara->Add( "OPT__FLAG_CURRENT", &OPT__FLAG_CURRENT, false, Useless_bool, Useless_bool ); # endif @@ -253,6 +259,10 @@ void Init_Load_Parameter() ReadPara->Add( "GRACKLE_THREE_BODY_RATE", &GRACKLE_THREE_BODY_RATE, 0, 0, 5 ); ReadPara->Add( "GRACKLE_CIE_COOLING", &GRACKLE_CIE_COOLING, false, Useless_bool, Useless_bool ); ReadPara->Add( "GRACKLE_H2_OPA_APPROX", &GRACKLE_H2_OPA_APPROX, 0, 0, 1 ); + ReadPara->Add( "GRACKLE_USE_V_HEATING_RATE", &GRACKLE_USE_V_HEATING_RATE, false, Useless_bool, Useless_bool ); + ReadPara->Add( "GRACKLE_USE_S_HEATING_RATE", &GRACKLE_USE_S_HEATING_RATE, false, Useless_bool, Useless_bool ); + ReadPara->Add( "GRACKLE_HYDROGEN_MFRAC", &GRACKLE_HYDROGEN_MFRAC, 0.76, 0.0, 1.0 ); + ReadPara->Add( "OPT__UNFREEZE_GRACKLE", &OPT__UNFREEZE_GRACKLE, false, Useless_bool, Useless_bool ); // do not check CHE_GPU_NPGROUP since it may be reset by either Init_ResetParameter() or CUAPI_SetMemSize() ReadPara->Add( "CHE_GPU_NPGROUP", &CHE_GPU_NPGROUP, -1, NoMin_int, NoMax_int ); # endif @@ -532,7 +542,6 @@ void Init_Load_Parameter() ReadPara->Add( "OPT__OUTPUT_CS", &OPT__OUTPUT_CS, false, Useless_bool, Useless_bool ); ReadPara->Add( "OPT__OUTPUT_DIVVEL", &OPT__OUTPUT_DIVVEL, false, Useless_bool, Useless_bool ); ReadPara->Add( "OPT__OUTPUT_MACH", &OPT__OUTPUT_MACH, false, Useless_bool, Useless_bool ); -# endif # ifdef MHD ReadPara->Add( "OPT__OUTPUT_DIVMAG", &OPT__OUTPUT_DIVMAG, false, Useless_bool, Useless_bool ); # endif @@ -541,6 +550,12 @@ void Init_Load_Parameter() ReadPara->Add( "OPT__OUTPUT_3VELOCITY", &OPT__OUTPUT_3VELOCITY, false, Useless_bool, Useless_bool ); ReadPara->Add( "OPT__OUTPUT_ENTHALPY", &OPT__OUTPUT_ENTHALPY, true, Useless_bool, Useless_bool ); # endif +# ifdef SUPPORT_GRACKLE + ReadPara->Add( "OPT__OUTPUT_GRACKLE_TEMP", &OPT__OUTPUT_GRACKLE_TEMP, false, Useless_bool, Useless_bool ); + ReadPara->Add( "OPT__OUTPUT_GRACKLE_MU", &OPT__OUTPUT_GRACKLE_MU, false, Useless_bool, Useless_bool ); + ReadPara->Add( "OPT__OUTPUT_GRACKLE_TCOOL", &OPT__OUTPUT_GRACKLE_TCOOL, false, Useless_bool, Useless_bool ); +# endif +# endif // #if ( MODEL == HYDRO ) ReadPara->Add( "OPT__OUTPUT_USER_FIELD", &OPT__OUTPUT_USER_FIELD, false, Useless_bool, Useless_bool ); ReadPara->Add( "OPT__OUTPUT_MODE", &OPT__OUTPUT_MODE, -1, 1, 3 ); ReadPara->Add( "OPT__OUTPUT_RESTART", &OPT__OUTPUT_RESTART, false, Useless_bool, Useless_bool ); diff --git a/src/Init/Init_TestProb.cpp b/src/Init/Init_TestProb.cpp index 819bc5cd4a..b108f187ca 100644 --- a/src/Init/Init_TestProb.cpp +++ b/src/Init/Init_TestProb.cpp @@ -30,6 +30,7 @@ void Init_TestProb_Hydro_EnergyPowerSpectrum(); void Init_TestProb_Hydro_CR_SoundWave(); void Init_TestProb_Hydro_CR_ShockTube(); void Init_TestProb_Hydro_CR_Diffusion(); +void Init_TestProb_Hydro_GrackleTest(); void Init_TestProb_ELBDM_ExtPot(); void Init_TestProb_ELBDM_JeansInstabilityComoving(); @@ -96,6 +97,7 @@ void Init_TestProb() case TESTPROB_HYDRO_CR_SOUNDWAVE : Init_TestProb_Hydro_CR_SoundWave(); break; case TESTPROB_HYDRO_CR_SHOCKTUBE : Init_TestProb_Hydro_CR_ShockTube(); break; case TESTPROB_HYDRO_CR_DIFFUSION : Init_TestProb_Hydro_CR_Diffusion(); break; + case TESTPROB_HYDRO_GRACKLE_TEST : Init_TestProb_Hydro_GrackleTest(); break; case TESTPROB_ELBDM_EXTPOT : Init_TestProb_ELBDM_ExtPot(); break; case TESTPROB_ELBDM_JEANS_INSTABILITY_COMOVING : Init_TestProb_ELBDM_JeansInstabilityComoving(); break; diff --git a/src/Main/InvokeSolver.cpp b/src/Main/InvokeSolver.cpp index e256197cc3..3398f8ac0a 100644 --- a/src/Main/InvokeSolver.cpp +++ b/src/Main/InvokeSolver.cpp @@ -102,7 +102,12 @@ void InvokeSolver( const Solver_t TSolver, const int lv, const double TimeNew, c // reset the time-step actually adopted to zero for OPT__FREEZE_FLUID - const double dt = ( OPT__FREEZE_FLUID ) ? 0.0 : dt_in; +# ifdef SUPPORT_GRACKLE + const bool UnFreeze = ( TSolver == GRACKLE_SOLVER && OPT__UNFREEZE_GRACKLE ); +# else + const bool UnFreeze = false; +# endif + const double dt = ( OPT__FREEZE_FLUID && ! UnFreeze ) ? 0.0 : dt_in; // set the maximum number of patch groups to be updated at a time diff --git a/src/Main/Main.cpp b/src/Main/Main.cpp index 70358820de..690ab0b315 100644 --- a/src/Main/Main.cpp +++ b/src/Main/Main.cpp @@ -260,6 +260,16 @@ char GRACKLE_CLOUDY_TABLE[MAX_STRING]; int GRACKLE_THREE_BODY_RATE; bool GRACKLE_CIE_COOLING; int GRACKLE_H2_OPA_APPROX; +bool GRACKLE_USE_V_HEATING_RATE; +bool GRACKLE_USE_S_HEATING_RATE; +double GRACKLE_HYDROGEN_MFRAC; +bool OPT__UNFREEZE_GRACKLE; +bool OPT__OUTPUT_GRACKLE_TEMP; +bool OPT__OUTPUT_GRACKLE_MU; +bool OPT__OUTPUT_GRACKLE_TCOOL; +bool OPT__FLAG_COOLING_LEN; +double FlagTable_CoolingLen[NLEVEL-1]; +double DT__GRACKLE_COOLING; int CHE_GPU_NPGROUP; #endif diff --git a/src/Makefile_base b/src/Makefile_base index 05a5ff17b0..994b2cf366 100644 --- a/src/Makefile_base +++ b/src/Makefile_base @@ -324,7 +324,8 @@ ifeq "$(filter -DSUPPORT_GRACKLE, $(SIMU_OPTION))" "-DSUPPORT_GRACKLE" CPU_FILE += CPU_GrackleSolver.cpp CPU_FILE += Grackle_Init.cpp Grackle_End.cpp Init_MemAllocate_Grackle.cpp End_MemFree_Grackle.cpp \ - Grackle_Prepare.cpp Grackle_Close.cpp Grackle_Init_FieldData.cpp Grackle_AdvanceDt.cpp + Grackle_Prepare.cpp Grackle_Close.cpp Grackle_Init_FieldData.cpp Grackle_AdvanceDt.cpp \ + Grackle_Calculate.cpp Grackle_GetTimeStep_CoolingTime.cpp vpath %.cpp Grackle Grackle/CPU_Grackle endif # SUPPORT_GRACKLE diff --git a/src/Miscellaneous/Mis_GetTimeStep.cpp b/src/Miscellaneous/Mis_GetTimeStep.cpp index 322d9e545e..7e031d54b8 100644 --- a/src/Miscellaneous/Mis_GetTimeStep.cpp +++ b/src/Miscellaneous/Mis_GetTimeStep.cpp @@ -236,6 +236,20 @@ double Mis_GetTimeStep( const int lv, const double dTime_SyncFaLv, const double # endif +// 1.10 CRITERION TEN : Grackle cooling time +// ============================================================================================================= +# ifdef SUPPORT_GRACKLE + if ( DT__GRACKLE_COOLING >= 0.0 ) + { + dTime[NdTime] = dTime_dt * Grackle_GetTimeStep_CoolingTime( lv ); + sprintf( dTime_Name[NdTime++], "%s", "Grackle_TCool" ); + +// when fluid is freezed, disable this criterion by resetting it to a huge value + if ( OPT__FREEZE_FLUID && ! OPT__UNFREEZE_GRACKLE ) dTime[NdTime-1] = HUGE_NUMBER; + } +# endif + + // 2. get the minimum time-step from all criteria // ============================================================================================================= diff --git a/src/Output/Output_DumpData_Part.cpp b/src/Output/Output_DumpData_Part.cpp index 7bed3b7093..2118db4a28 100644 --- a/src/Output/Output_DumpData_Part.cpp +++ b/src/Output/Output_DumpData_Part.cpp @@ -4,9 +4,10 @@ static void WriteFile( FILE *File, const int lv, const int PID, const int i, con const int ii, const int jj, const int kk, const real (*DerField)[ CUBE(PS1) ] ); static void GetDerivedField( real (*Der_FluIn)[NCOMP_TOTAL][ CUBE(DER_NXT) ], real (*Der_Out ) [ CUBE(PS1) ], + real (*Der_Out_1PG) [ CUBE(PS2) ], real (*Der_MagFC)[NCOMP_MAG ][ (DER_NXT+1)*SQR(DER_NXT) ], real (*Der_MagCC) [ CUBE(DER_NXT) ], - const int lv, const int PID, const bool PrepFluIn ); + const int lv, const int PID, const bool PrepFluIn, const bool PrepOutPG ); @@ -111,9 +112,11 @@ void Output_DumpData_Part( const OptOutputPart_t Part, const bool BaseOnly, cons // for the derived fields const int Der_NP = 8; bool Der_PrepFluIn; + bool Der_PrepOutPG; real (*Der_FluIn)[NCOMP_TOTAL][ CUBE(DER_NXT) ] = new real [Der_NP][NCOMP_TOTAL ][ CUBE(DER_NXT) ]; real (*Der_Out ) [ CUBE(PS1) ] = new real [DER_NOUT_MAX][ CUBE(PS1) ]; + real (*Der_Out_1PG ) [ CUBE(PS2) ] = new real [DER_NOUT_MAX][ CUBE(PS2) ]; # ifdef MHD real (*Der_MagFC)[NCOMP_MAG ][ (DER_NXT+1)*SQR(DER_NXT) ] = new real [Der_NP][NCOMP_MAG ][ (DER_NXT+1)*SQR(DER_NXT) ]; real (*Der_MagCC) [ CUBE(DER_NXT) ] = new real [NCOMP_MAG ][ CUBE(DER_NXT) ]; @@ -170,6 +173,14 @@ void Output_DumpData_Part( const OptOutputPart_t Part, const bool BaseOnly, cons } if ( OPT__OUTPUT_ENTHALPY ) fprintf( File, " %*s", StrLen_Flt, "Reduced enthalpy" ); +# endif +# ifdef SUPPORT_GRACKLE + if ( OPT__OUTPUT_GRACKLE_TEMP ) + fprintf( File, " %*s", StrLen_Flt, "Grackle temperature" ); + if ( OPT__OUTPUT_GRACKLE_MU ) + fprintf( File, " %*s", StrLen_Flt, "Grackle mu" ); + if ( OPT__OUTPUT_GRACKLE_TCOOL ) + fprintf( File, " %*s", StrLen_Flt, "Grackle cooling time" ); # endif if ( OPT__OUTPUT_USER_FIELD ) { for (int v=0; vNPatchComma[lv][1]; PID++) { if ( PID % 8 == 0 ) Der_PrepFluIn = true; + if ( PID % 8 == 0 ) Der_PrepOutPG = true; // output the patch data only if it has no son (if the option "BaseOnly" is turned off) if ( amr->patch[0][lv][PID]->son == -1 || BaseOnly ) @@ -203,8 +215,9 @@ void Output_DumpData_Part( const OptOutputPart_t Part, const bool BaseOnly, cons if ( Corner[0] == Corner[1] && Corner[0] == Corner[2] ) { // compute the derived fields - GetDerivedField( Der_FluIn, Der_Out, Der_MagFC, Der_MagCC, lv, PID, Der_PrepFluIn ); + GetDerivedField( Der_FluIn, Der_Out, Der_Out_1PG, Der_MagFC, Der_MagCC, lv, PID, Der_PrepFluIn, Der_PrepOutPG ); Der_PrepFluIn = false; + Der_PrepOutPG = false; // write data for (int k=0; kz ) ) { // compute the derived fields - GetDerivedField( Der_FluIn, Der_Out, Der_MagFC, Der_MagCC, lv, PID, Der_PrepFluIn ); + GetDerivedField( Der_FluIn, Der_Out, Der_Out_1PG, Der_MagFC, Der_MagCC, lv, PID, Der_PrepFluIn, Der_PrepOutPG ); Der_PrepFluIn = false; + Der_PrepOutPG = false; // write data // --> check whether the cell is within the target range @@ -260,6 +274,7 @@ void Output_DumpData_Part( const OptOutputPart_t Part, const bool BaseOnly, cons delete [] Der_FluIn; delete [] Der_Out; + delete [] Der_Out_1PG; # ifdef MHD delete [] Der_MagFC; delete [] Der_MagCC; @@ -414,6 +429,18 @@ void WriteFile( FILE *File, const int lv, const int PID, const int i, const int } # endif +# ifdef SUPPORT_GRACKLE + if ( OPT__OUTPUT_GRACKLE_TEMP ) + fprintf( File, BlankPlusFormat_Flt, DerField[ Der_FieldIdx ++ ][Der_CellIdx] ); + + if ( OPT__OUTPUT_GRACKLE_MU ) + fprintf( File, BlankPlusFormat_Flt, DerField[ Der_FieldIdx ++ ][Der_CellIdx] ); + + if ( OPT__OUTPUT_GRACKLE_TCOOL ) + fprintf( File, BlankPlusFormat_Flt, DerField[ Der_FieldIdx ++ ][Der_CellIdx] ); + +# endif + if ( OPT__OUTPUT_USER_FIELD ) { for (int v=0; v To prepare patches within the same patch group just once +// PrepOutPG : Whether to fill in Out_1PG[] +// --> To prepare patches within the same patch group just once // -// Return : FluIn[], Out[], MagFC[] (MagCC[] is not useful outside this function) +// Return : FluIn[], Out[], Out_1PG[], MagFC[] (MagCC[] is not useful outside this function) //------------------------------------------------------------------------------------------------------- void GetDerivedField( real (*FluIn)[NCOMP_TOTAL][ CUBE(DER_NXT) ], real (*Out ) [ CUBE(PS1) ], + real (*Out_1PG) [ CUBE(PS2) ], real (*MagFC)[NCOMP_MAG ][ (DER_NXT+1)*SQR(DER_NXT) ], real (*MagCC) [ CUBE(DER_NXT) ], - const int lv, const int PID, const bool PrepFluIn ) + const int lv, const int PID, const bool PrepFluIn, const bool PrepOutPG ) { const double dh = amr->dh[lv]; @@ -526,6 +558,65 @@ void GetDerivedField( real (*FluIn)[NCOMP_TOTAL][ CUBE(DER_NXT) ], OutFieldIdx += NFieldOut; } + +# ifdef SUPPORT_GRACKLE + if ( OPT__OUTPUT_GRACKLE_TEMP ) + { + const int NFieldOut = 1; + + if ( OutFieldIdx + NFieldOut > DER_NOUT_MAX ) + Aux_Error( ERROR_INFO, "OutFieldIdx (%d) + NFieldOut (%d) > DER_NOUT_MAX (%d) !!\n", + OutFieldIdx, NFieldOut, DER_NOUT_MAX ); + +// Grackle_Calculate has to prepare the field with one patch group each time + const int PID0 = PID - LocalID; + if ( PrepOutPG ) Grackle_Calculate( Out_1PG[OutFieldIdx], _GRACKLE_TEMP, lv, 1, &PID0 ); + +// copy the corresponding patch from the already calculated patch group + const real *Out_1P = Out_1PG[OutFieldIdx] + LocalID*CUBE(PS1); + memcpy( Out[OutFieldIdx], Out_1P, sizeof(real)*CUBE(PS1) ); + + OutFieldIdx += NFieldOut; + } + + if ( OPT__OUTPUT_GRACKLE_MU ) + { + const int NFieldOut = 1; + + if ( OutFieldIdx + NFieldOut > DER_NOUT_MAX ) + Aux_Error( ERROR_INFO, "OutFieldIdx (%d) + NFieldOut (%d) > DER_NOUT_MAX (%d) !!\n", + OutFieldIdx, NFieldOut, DER_NOUT_MAX ); + +// Grackle_Calculate has to prepare the field with one patch group each time + const int PID0 = PID - LocalID; + if ( PrepOutPG ) Grackle_Calculate( Out_1PG[OutFieldIdx], _GRACKLE_MU, lv, 1, &PID0 ); + +// copy the corresponding one patch from the already calculated patch group + const real *Out_1P = Out_1PG[OutFieldIdx] + LocalID*CUBE(PS1); + memcpy( Out[OutFieldIdx], Out_1P, sizeof(real)*CUBE(PS1) ); + + OutFieldIdx += NFieldOut; + } + + if ( OPT__OUTPUT_GRACKLE_TCOOL ) + { + const int NFieldOut = 1; + + if ( OutFieldIdx + NFieldOut > DER_NOUT_MAX ) + Aux_Error( ERROR_INFO, "OutFieldIdx (%d) + NFieldOut (%d) > DER_NOUT_MAX (%d) !!\n", + OutFieldIdx, NFieldOut, DER_NOUT_MAX ); + +// Grackle_Calculate has to prepare the field with one patch group each time + const int PID0 = PID - LocalID; + if ( PrepOutPG ) Grackle_Calculate( Out_1PG[OutFieldIdx], _GRACKLE_TCOOL, lv, 1, &PID0 ); + +// copy the corresponding one patch from the already calculated patch group + const real *Out_1P = Out_1PG[OutFieldIdx] + LocalID*CUBE(PS1); + memcpy( Out[OutFieldIdx], Out_1P, sizeof(real)*CUBE(PS1) ); + + OutFieldIdx += NFieldOut; + } +# endif // #ifdef SUPPORT_GRACKLE # endif // #if ( MODEL == HYDRO ) if ( OPT__OUTPUT_USER_FIELD ) diff --git a/src/Output/Output_DumpData_Total_HDF5.cpp b/src/Output/Output_DumpData_Total_HDF5.cpp index 75462ea3e7..dc09db964e 100644 --- a/src/Output/Output_DumpData_Total_HDF5.cpp +++ b/src/Output/Output_DumpData_Total_HDF5.cpp @@ -79,7 +79,7 @@ Procedure for outputting new variables: //------------------------------------------------------------------------------------------------------- -// Function : Output_DumpData_Total_HDF5 (FormatVersion = 2505) +// Function : Output_DumpData_Total_HDF5 (FormatVersion = 2506) // Description : Output all simulation data in the HDF5 format, which can be used as a restart file // or loaded by YT // @@ -279,6 +279,10 @@ Procedure for outputting new variables: // Input__TestProb parameters in "Info/InputTest" // 2504 : 2025/04/29 --> output OPT__PAR_INIT_CHECK // 2505 : 2025/05/07 --> output PassiveFloor_Var +// 2506 : 2025/12/07 --> output GRACKLE_USE_V_HEATING_RATE, GRACKLE_USE_S_HEATING_RATE, +// GRACKLE_HYDROGEN_MFRAC, OPT__UNFREEZE_GRACKLE, +// OPT__OUTPUT_GRACKLE_TEMP, OPT__OUTPUT_GRACKLE_MU, OPT__OUTPUT_GRACKLE_TCOOL, +// DT__GRACKLE_COOLING, OPT__FLAG_COOLING_LEN, FlagTable_CoolingLen //------------------------------------------------------------------------------------------------------- void Output_DumpData_Total_HDF5( const char *FileName ) { @@ -381,7 +385,6 @@ void Output_DumpData_Total_HDF5( const char *FileName ) if ( MachDumpIdx >= NFIELD_STORED_MAX ) Aux_Error( ERROR_INFO, "exceed NFIELD_STORED_MAX (%d) !!\n", NFIELD_STORED_MAX ); if ( OPT__OUTPUT_MACH ) sprintf( FieldLabelOut[MachDumpIdx ], "%s", "Mach" ); -# endif # ifdef MHD const int DivMagDumpIdx = ( OPT__OUTPUT_DIVMAG ) ? NFieldStored++ : NoDump; @@ -413,6 +416,24 @@ void Output_DumpData_Total_HDF5( const char *FileName ) if ( OPT__OUTPUT_ENTHALPY ) sprintf( FieldLabelOut[EnthalpyDumpIdx], "%s", "Enth" ); # endif // #ifdef SRHD +# ifdef SUPPORT_GRACKLE + const int GrackleTempDumpIdx = ( OPT__OUTPUT_GRACKLE_TEMP ) ? NFieldStored++ : NoDump; + if ( GrackleTempDumpIdx >= NFIELD_STORED_MAX ) + Aux_Error( ERROR_INFO, "exceed NFIELD_STORED_MAX (%d) !!\n", NFIELD_STORED_MAX ); + if ( OPT__OUTPUT_GRACKLE_TEMP ) sprintf( FieldLabelOut[GrackleTempDumpIdx], "%s", "GrackleTemp" ); + + const int GrackleMuDumpIdx = ( OPT__OUTPUT_GRACKLE_MU ) ? NFieldStored++ : NoDump; + if ( GrackleMuDumpIdx >= NFIELD_STORED_MAX ) + Aux_Error( ERROR_INFO, "exceed NFIELD_STORED_MAX (%d) !!\n", NFIELD_STORED_MAX ); + if ( OPT__OUTPUT_GRACKLE_MU ) sprintf( FieldLabelOut[GrackleMuDumpIdx], "%s", "GrackleMu" ); + + const int GrackleTCoolDumpIdx = ( OPT__OUTPUT_GRACKLE_TCOOL ) ? NFieldStored++ : NoDump; + if ( GrackleTCoolDumpIdx >= NFIELD_STORED_MAX ) + Aux_Error( ERROR_INFO, "exceed NFIELD_STORED_MAX (%d) !!\n", NFIELD_STORED_MAX ); + if ( OPT__OUTPUT_GRACKLE_TCOOL ) sprintf( FieldLabelOut[GrackleTCoolDumpIdx], "%s", "GrackleTCool" ); +# endif // ifdef SUPPORT_GRACKLE +# endif // if ( MODEL == HYDRO ) + const int UserDumpIdx0 = ( OPT__OUTPUT_USER_FIELD ) ? NFieldStored : NoDump; if ( UserDumpIdx0+UserDerField_Num-1 >= NFIELD_STORED_MAX ) Aux_Error( ERROR_INFO, "exceed NFIELD_STORED_MAX (%d) !!\n", NFIELD_STORED_MAX ); @@ -777,6 +798,7 @@ void Output_DumpData_Total_HDF5( const char *FileName ) real (*Der_FluIn)[NCOMP_TOTAL][ CUBE(DER_NXT) ] = new real [Der_NP][NCOMP_TOTAL ][ CUBE(DER_NXT) ]; real (*Der_Out ) [ CUBE(PS1) ] = new real [DER_NOUT_MAX][ CUBE(PS1) ]; + real (*Der_Out_1PG) [ CUBE(PS2) ] = new real [DER_NOUT_MAX][ CUBE(PS2) ]; # ifdef MHD real (*Der_MagFC)[NCOMP_MAG ][ (DER_NXT+1)*SQR(DER_NXT) ] = new real [Der_NP][NCOMP_MAG ][ (DER_NXT+1)*SQR(DER_NXT) ]; real (*Der_MagCC) [ CUBE(DER_NXT) ] = new real [NCOMP_MAG ][ CUBE(DER_NXT) ]; @@ -1133,9 +1155,68 @@ void Output_DumpData_Total_HDF5( const char *FileName ) } } # endif // #ifdef SRHD + +# ifdef SUPPORT_GRACKLE +// d-11. Grackle's temperature + else if ( v == GrackleTempDumpIdx ) + { + for (int PID0=0; PID0NPatchComma[lv][1]; PID0+=8) + { +// compute the target derived field with one patch group each time + Grackle_Calculate( Der_Out_1PG[0], _GRACKLE_TEMP, lv, 1, &PID0 ); + +// store the target derived field patch by patch in a patch group + for (int LocalID=0; LocalID<8; LocalID++) + { + const int PID = PID0 + LocalID; + const real *Der_Out_1P = Der_Out_1PG[0] + LocalID*CUBE(PS1); +// copy data of one patch from Der_Out_1P[] to FieldData[] + memcpy( FieldData[PID], Der_Out_1P, FieldSizeOnePatch ); + } // for (int LocalID=0; LocalID<8; LocalID++) + } // for (int PID0=0; PID0NPatchComma[lv][1]; PID0+=8) + } // if ( v == GrackleTempDumpIdx ) + +// d-12. Grackle's mu (mean molecular weight) + else if ( v == GrackleMuDumpIdx ) + { + for (int PID0=0; PID0NPatchComma[lv][1]; PID0+=8) + { +// compute the target derived field with one patch group each time + Grackle_Calculate( Der_Out_1PG[0], _GRACKLE_MU, lv, 1, &PID0 ); + +// store the target derived field patch by patch in a patch group + for (int LocalID=0; LocalID<8; LocalID++) + { + const int PID = PID0 + LocalID; + const real *Der_Out_1P = Der_Out_1PG[0] + LocalID*CUBE(PS1); +// copy data of one patch from Der_Out_1P[] to FieldData[] + memcpy( FieldData[PID], Der_Out_1P, FieldSizeOnePatch ); + } // for (int LocalID=0; LocalID<8; LocalID++) + } // for (int PID0=0; PID0NPatchComma[lv][1]; PID0+=8) + } // if ( v == GrackleMuDumpIdx ) + +// d-13. Grackle's cooling time + else if ( v == GrackleTCoolDumpIdx ) + { + for (int PID0=0; PID0NPatchComma[lv][1]; PID0+=8) + { +// compute the target derived field with one patch group each time + Grackle_Calculate( Der_Out_1PG[0], _GRACKLE_TCOOL, lv, 1, &PID0 ); + +// store the target derived field patch by patch in a patch group + for (int LocalID=0; LocalID<8; LocalID++) + { + const int PID = PID0 + LocalID; + const real *Der_Out_1P = Der_Out_1PG[0] + LocalID*CUBE(PS1); +// copy data of one patch from Der_Out_1P[] to FieldData[] + memcpy( FieldData[PID], Der_Out_1P, FieldSizeOnePatch ); + } // for (int LocalID=0; LocalID<8; LocalID++) + } // for (int PID0=0; PID0NPatchComma[lv][1]; PID0+=8) + } // if ( v == GrackleTCoolDumpIdx ) +# endif // #ifdef SUPPORT_GRACKLE # endif // #if ( MODEL == HYDRO ) -// d-11. user-defined derived fields +// d-14. user-defined derived fields // the following check also works for OPT__OUTPUT_USER_FIELD==false since UserDerField_Num is initialized as 0 else if ( v >= UserDumpIdx0 && v < UserDumpIdx0 + UserDerField_Num ) { @@ -1324,6 +1405,7 @@ void Output_DumpData_Total_HDF5( const char *FileName ) delete [] Der_FluIn; delete [] Der_Out; + delete [] Der_Out_1PG; # ifdef MHD delete [] Der_MagFC; delete [] Der_MagCC; @@ -1667,7 +1749,7 @@ void FillIn_KeyInfo( KeyInfo_t &KeyInfo, const int NFieldStored ) const time_t CalTime = time( NULL ); // calendar time - KeyInfo.FormatVersion = 2505; + KeyInfo.FormatVersion = 2506; KeyInfo.Model = MODEL; KeyInfo.NLevel = NLEVEL; KeyInfo.NCompFluid = NCOMP_FLUID; @@ -2455,6 +2537,9 @@ void FillIn_InputPara( InputPara_t &InputPara, const int NFieldStored, char Fiel # ifdef CR_DIFFUSION InputPara.Dt__CR_Diffusion = DT__CR_DIFFUSION; # endif +# ifdef SUPPORT_GRACKLE + InputPara.Dt__GrackleCooling = DT__GRACKLE_COOLING; +# endif # ifdef COMOVING InputPara.Dt__MaxDeltaA = DT__MAX_DELTA_A; # endif @@ -2501,6 +2586,9 @@ void FillIn_InputPara( InputPara_t &InputPara, const int NFieldStored, char Fiel InputPara.Dt__SpeedOfLight = DT__SPEED_OF_LIGHT; InputPara.Opt__Flag_LrtzGradient = OPT__FLAG_LRTZ_GRADIENT; # endif +# ifdef SUPPORT_GRACKLE + InputPara.Opt__Flag_CoolingLen = OPT__FLAG_COOLING_LEN; +# endif # ifdef COSMIC_RAY InputPara.Opt__Flag_CRay = OPT__FLAG_CRAY; # endif @@ -2688,6 +2776,10 @@ void FillIn_InputPara( InputPara_t &InputPara, const int NFieldStored, char Fiel InputPara.Grackle_ThreeBodyRate = GRACKLE_THREE_BODY_RATE; InputPara.Grackle_CIE_Cooling = GRACKLE_CIE_COOLING; InputPara.Grackle_H2_OpaApprox = GRACKLE_H2_OPA_APPROX; + InputPara.Grackle_UseVHeatingRate = GRACKLE_USE_V_HEATING_RATE; + InputPara.Grackle_UseSHeatingRate = GRACKLE_USE_S_HEATING_RATE; + InputPara.Grackle_HydrogenMFrac = GRACKLE_HYDROGEN_MFRAC; + InputPara.Opt__UnfreezeGrackle = OPT__UNFREEZE_GRACKLE; InputPara.Che_GPU_NPGroup = CHE_GPU_NPGROUP; # endif @@ -2837,6 +2929,11 @@ void FillIn_InputPara( InputPara_t &InputPara, const int NFieldStored, char Fiel InputPara.Opt__Output_Lorentz = OPT__OUTPUT_LORENTZ; InputPara.Opt__Output_Enthalpy = OPT__OUTPUT_ENTHALPY; # endif +# ifdef SUPPORT_GRACKLE + InputPara.Opt__Output_GrackleTemp = OPT__OUTPUT_GRACKLE_TEMP; + InputPara.Opt__Output_GrackleMu = OPT__OUTPUT_GRACKLE_MU; + InputPara.Opt__Output_GrackleTCool = OPT__OUTPUT_GRACKLE_TCOOL; +# endif # endif // #if ( MODEL == HYDRO ) InputPara.Opt__Output_UserField = OPT__OUTPUT_USER_FIELD; InputPara.Opt__Output_Mode = OPT__OUTPUT_MODE; @@ -2931,6 +3028,9 @@ void FillIn_InputPara( InputPara_t &InputPara, const int NFieldStored, char Fiel # ifdef SRHD InputPara.FlagTable_LrtzGradient[lv] = FlagTable_LrtzGradient[lv]; # endif +# ifdef SUPPORT_GRACKLE + InputPara.FlagTable_CoolingLen [lv] = FlagTable_CoolingLen [lv]; +# endif # ifdef COSMIC_RAY InputPara.FlagTable_CRay [lv] = FlagTable_CRay [lv]; # endif @@ -3514,6 +3614,9 @@ void GetCompound_InputPara( hid_t &H5_TypeID, const int NFieldStored ) # ifdef CR_DIFFUSION H5Tinsert( H5_TypeID, "Dt__CR_Diffusion", HOFFSET(InputPara_t,Dt__CR_Diffusion ), H5T_NATIVE_DOUBLE ); # endif +# ifdef SUPPORT_GRACKLE + H5Tinsert( H5_TypeID, "Dt__GrackleCooling", HOFFSET(InputPara_t,Dt__GrackleCooling ), H5T_NATIVE_DOUBLE ); +# endif # ifdef COMOVING H5Tinsert( H5_TypeID, "Dt__MaxDeltaA", HOFFSET(InputPara_t,Dt__MaxDeltaA ), H5T_NATIVE_DOUBLE ); # endif @@ -3552,6 +3655,9 @@ void GetCompound_InputPara( hid_t &H5_TypeID, const int NFieldStored ) # ifdef SRHD H5Tinsert( H5_TypeID, "Opt__Flag_LrtzGradient", HOFFSET(InputPara_t,Opt__Flag_LrtzGradient ), H5T_NATIVE_INT ); # endif +# ifdef SUPPORT_GRACKLE + H5Tinsert( H5_TypeID, "Opt__Flag_CoolingLen", HOFFSET(InputPara_t,Opt__Flag_CoolingLen ), H5T_NATIVE_INT ); +# endif # ifdef COSMIC_RAY H5Tinsert( H5_TypeID, "Opt__Flag_CRay", HOFFSET(InputPara_t,Opt__Flag_CRay ), H5T_NATIVE_INT ); # endif @@ -3755,6 +3861,10 @@ void GetCompound_InputPara( hid_t &H5_TypeID, const int NFieldStored ) H5Tinsert( H5_TypeID, "Grackle_ThreeBodyRate", HOFFSET(InputPara_t,Grackle_ThreeBodyRate ), H5T_NATIVE_INT ); H5Tinsert( H5_TypeID, "Grackle_CIE_Cooling", HOFFSET(InputPara_t,Grackle_CIE_Cooling ), H5T_NATIVE_INT ); H5Tinsert( H5_TypeID, "Grackle_H2_OpaApprox", HOFFSET(InputPara_t,Grackle_H2_OpaApprox ), H5T_NATIVE_INT ); + H5Tinsert( H5_TypeID, "Grackle_UseVHeatingRate", HOFFSET(InputPara_t,Grackle_UseVHeatingRate), H5T_NATIVE_INT ); + H5Tinsert( H5_TypeID, "Grackle_UseSHeatingRate", HOFFSET(InputPara_t,Grackle_UseSHeatingRate), H5T_NATIVE_INT ); + H5Tinsert( H5_TypeID, "Grackle_HydrogenMFrac", HOFFSET(InputPara_t,Grackle_HydrogenMFrac ), H5T_NATIVE_DOUBLE ); + H5Tinsert( H5_TypeID, "Opt__UnfreezeGrackle", HOFFSET(InputPara_t,Opt__UnfreezeGrackle ), H5T_NATIVE_INT ); H5Tinsert( H5_TypeID, "Che_GPU_NPGroup", HOFFSET(InputPara_t,Che_GPU_NPGroup ), H5T_NATIVE_INT ); # endif @@ -3887,6 +3997,11 @@ void GetCompound_InputPara( hid_t &H5_TypeID, const int NFieldStored ) H5Tinsert( H5_TypeID, "Opt__Output_Lorentz", HOFFSET(InputPara_t,Opt__Output_Lorentz ), H5T_NATIVE_INT ); H5Tinsert( H5_TypeID, "Opt__Output_Enthalpy", HOFFSET(InputPara_t,Opt__Output_Enthalpy ), H5T_NATIVE_INT ); # endif +# ifdef SUPPORT_GRACKLE + H5Tinsert( H5_TypeID, "Opt__Output_GrackleTemp", HOFFSET(InputPara_t,Opt__Output_GrackleTemp ), H5T_NATIVE_INT ); + H5Tinsert( H5_TypeID, "Opt__Output_GrackleMu", HOFFSET(InputPara_t,Opt__Output_GrackleMu ), H5T_NATIVE_INT ); + H5Tinsert( H5_TypeID, "Opt__Output_GrackleTCool", HOFFSET(InputPara_t,Opt__Output_GrackleTCool ), H5T_NATIVE_INT ); +# endif # endif // #if ( MODEL == HYDRO ) H5Tinsert( H5_TypeID, "Opt__Output_UserField", HOFFSET(InputPara_t,Opt__Output_UserField ), H5T_NATIVE_INT ); H5Tinsert( H5_TypeID, "Opt__Output_Mode", HOFFSET(InputPara_t,Opt__Output_Mode ), H5T_NATIVE_INT ); @@ -3980,6 +4095,9 @@ void GetCompound_InputPara( hid_t &H5_TypeID, const int NFieldStored ) # ifdef SRHD H5Tinsert( H5_TypeID, "FlagTable_LrtzGradient", HOFFSET(InputPara_t,FlagTable_LrtzGradient ), H5_TypeID_Arr_NLvM1Double ); # endif +# ifdef SUPPORT_GRACKLE + H5Tinsert( H5_TypeID, "FlagTable_CoolingLen", HOFFSET(InputPara_t,FlagTable_CoolingLen ), H5_TypeID_Arr_NLvM1Double ); +# endif # ifdef COSMIC_RAY H5Tinsert( H5_TypeID, "FlagTable_CRay", HOFFSET(InputPara_t,FlagTable_CRay ), H5_TypeID_Arr_NLvM1Double ); # endif diff --git a/src/Refine/Flag_Check.cpp b/src/Refine/Flag_Check.cpp index ebd6801851..2ab947ae8b 100644 --- a/src/Refine/Flag_Check.cpp +++ b/src/Refine/Flag_Check.cpp @@ -34,6 +34,7 @@ static bool Check_Radial( const int i, const int j, const int k, const int lv, c // Vel : Input velocity array // Pres : Input pressure array // Lrtz : Input Lorentz factor array +// LCool : Input cooling length array // Lohner_Ave : Input array storing the averages for the Lohner error estimator // Lohner_Slope : Input array storing the slopes for the Lohner error estimator // Lohner_NVar : Number of variables stored in Lohner_Ave and Lohner_Slope @@ -52,6 +53,7 @@ static bool Check_Radial( const int i, const int j, const int k, const int lv, c bool Flag_Check( const int lv, const int PID, const int i, const int j, const int k, const real dv, const real Fluid[][PS1][PS1][PS1], const real Pot[][PS1][PS1], const real MagCC[][PS1][PS1][PS1], const real Vel[][PS1][PS1][PS1], const real Pres[][PS1][PS1], const real Lrtz[][PS1][PS1], + const real LCool[][PS1][PS1], const real *Lohner_Var, const real *Lohner_Ave, const real *Lohner_Slope, const int Lohner_NVar, const real ParCount[][PS1][PS1], const real ParDens[][PS1][PS1], const real JeansCoeff, const real *Interf_Var, const real Spectral_Cond ) @@ -181,6 +183,17 @@ bool Flag_Check( const int lv, const int PID, const int i, const int j, const in # endif +// check cooling length +// =========================================================================================== +# if ( MODEL == HYDRO && defined SUPPORT_GRACKLE ) + if ( OPT__FLAG_COOLING_LEN ) + { + Flag |= ( amr->dh[lv]*FlagTable_CoolingLen[lv] > LCool[k][j][i] ); + if ( Flag ) return Flag; + } +# endif + + // check vorticity // =========================================================================================== # if ( MODEL == HYDRO ) diff --git a/src/Refine/Flag_Real.cpp b/src/Refine/Flag_Real.cpp index 2531fdfa0c..2348be9783 100644 --- a/src/Refine/Flag_Real.cpp +++ b/src/Refine/Flag_Real.cpp @@ -192,6 +192,7 @@ void Flag_Real( const int lv, const UseLBFunc_t UseLBFunc ) real (*Pres)[PS1][PS1] = NULL; real (*Cs2)[PS1][PS1] = NULL; real (*Lrtz)[PS1][PS1] = NULL; + real (*LCool)[PS1][PS1] = NULL; real (*ParCount)[PS1][PS1] = NULL; // declare as **real** to be consistent with Par_MassAssignment() real (*ParDens )[PS1][PS1] = NULL; real *Lohner_Var = NULL; // array storing the variables for Lohner @@ -200,6 +201,7 @@ void Flag_Real( const int lv, const UseLBFunc_t UseLBFunc ) real *Interf_Var = NULL; // array storing the density and phase for the interference criterion real *Spectral_Var = NULL; // array storing a patch group of real and imaginary parts for the spectral criterion real Spectral_Cond = 0.0; // variable storing the magnitude of the largest coefficient for the spectral criterion + real *Grackle_TCool = NULL; // array storing a patch group of grackle cooling time int i_start, i_end, j_start, j_end, k_start, k_end, SibID, SibPID, PID; bool ProperNesting, NextPatch; @@ -212,12 +214,19 @@ void Flag_Real( const int lv, const UseLBFunc_t UseLBFunc ) if ( OPT__FLAG_JEANS ) NeedPres = true; if ( OPT__FLAG_JEANS ) NeedCs2 = true; # endif +# ifdef SUPPORT_GRACKLE + if ( OPT__FLAG_COOLING_LEN ) NeedCs2 = true; +# endif + if ( NeedCs2 ) NeedPres = true; # ifdef MHD if ( OPT__FLAG_CURRENT || NeedPres ) MagCC = new real [3][PS1][PS1][PS1]; # endif # ifdef SRHD if ( OPT__FLAG_LRTZ_GRADIENT ) Lrtz = new real [PS1][PS1][PS1]; +# endif +# ifdef SUPPORT_GRACKLE + if ( OPT__FLAG_COOLING_LEN ) LCool = new real [PS1][PS1][PS1]; # endif if ( OPT__FLAG_VORTICITY ) Vel = new real [3][PS1][PS1][PS1]; if ( NeedPres ) Pres = new real [PS1][PS1][PS1]; @@ -246,6 +255,11 @@ void Flag_Real( const int lv, const UseLBFunc_t UseLBFunc ) Lohner_Slope = new real [ 3*Lohner_NVar*CUBE(Lohner_NSlope) ]; // 3: X/Y/Z of 1 patch } +# ifdef SUPPORT_GRACKLE + if ( OPT__FLAG_COOLING_LEN ) + Grackle_TCool = new real [ CUBE(PS2) ]; // prepare one patch group +# endif + // loop over all REAL patches (the buffer patches will be flagged only due to the FlagBuf // extension or the grandson check) @@ -278,6 +292,11 @@ void Flag_Real( const int lv, const UseLBFunc_t UseLBFunc ) MinDens, MinPres, MinTemp, MinEntr, DE_Consistency_No ); # endif +# ifdef SUPPORT_GRACKLE + if ( OPT__FLAG_COOLING_LEN ) + Grackle_Calculate( Grackle_TCool, _GRACKLE_TCOOL, lv, NPG, &PID0 ); +# endif + // loop over all local patches within the same patch group for (int LocalID=0; LocalID<8; LocalID++) { @@ -454,6 +473,22 @@ void Flag_Real( const int lv, const UseLBFunc_t UseLBFunc ) } // i,j,k } // if ( OPT__FLAG_LRTZ_GRADIENT ) # endif // #ifdef SRHD + +# ifdef SUPPORT_GRACKLE +// evaluate cooling length + if ( OPT__FLAG_COOLING_LEN ) + { + for (int k=0; k= 1 only) [0.0] +static double GrackleTest_MFrac_HI; // HI mass fraction (GRACKLE_PRIMORDIAL >= 1 only) [0.750158] +static double GrackleTest_MFrac_HII; // HII mass fraction (GRACKLE_PRIMORDIAL >= 1 only) [0.0] +static double GrackleTest_MFrac_HeI; // HeI mass fraction (GRACKLE_PRIMORDIAL >= 1 only) [0.236892] +static double GrackleTest_MFrac_HeII; // HeII mass fraction (GRACKLE_PRIMORDIAL >= 1 only) [0.0] +static double GrackleTest_MFrac_HeIII; // HeIII mass fraction (GRACKLE_PRIMORDIAL >= 1 only) [0.0] +static double GrackleTest_MFrac_HM; // HM mass fraction (GRACKLE_PRIMORDIAL >= 2 only) [0.0] +static double GrackleTest_MFrac_H2I; // H2I mass fraction (GRACKLE_PRIMORDIAL >= 2 only) [0.0] +static double GrackleTest_MFrac_H2II; // H2II mass fraction (GRACKLE_PRIMORDIAL >= 2 only) [0.0] +static double GrackleTest_MFrac_DI; // DI mass fraction (GRACKLE_PRIMORDIAL >= 3 only) [0.0] +static double GrackleTest_MFrac_DII; // DII mass fraction (GRACKLE_PRIMORDIAL >= 3 only) [0.0] +static double GrackleTest_MFrac_HDI; // HDI mass fraction (GRACKLE_PRIMORDIAL >= 3 only) [0.0] +static double GrackleTest_HeatingRate; // User-provided heating rate (in erg cm^-3 s^-1 n_H^-1) [0.0] +static double GrackleTest_CoolingRate; // User-provided cooling rate (in erg cm^-3 s^-1 n_H^-2) [0.0] + +static double GrackleTest_logDens_Min; // Minimum log( mass density ) in the box +static double GrackleTest_logDens_Max; // Maximum log( mass density ) in the box +static double GrackleTest_logDens_Range; // Range of log ( mass density ) +static double GrackleTest_logTemp_Min; // Minimum log( temperature ) in the box +static double GrackleTest_logTemp_Max; // Maximum log( temperature ) in the box +static double GrackleTest_logTemp_Range; // Range of log ( temperature ) +// ======================================================================================= + + + + +//------------------------------------------------------------------------------------------------------- +// Function : Validate +// Description : Validate the compilation flags and runtime parameters for this test problem +// +// Note : None +// +// Parameter : None +// +// Return : None +//------------------------------------------------------------------------------------------------------- +void Validate() +{ + + if ( MPI_Rank == 0 ) Aux_Message( stdout, " Validating test problem %d ...\n", TESTPROB_ID ); + + +// errors +# if ( MODEL != HYDRO ) + Aux_Error( ERROR_INFO, "MODEL != HYDRO !!\n" ); +# endif + +# ifndef SUPPORT_GRACKLE + Aux_Error( ERROR_INFO, "SUPPORT_GRACKLE must be enabled !!\n" ); +# endif + +# ifdef PARTICLE + Aux_Error( ERROR_INFO, "PARTICLE must be disabled !!\n" ); +# endif + +# ifdef GRAVITY + Aux_Error( ERROR_INFO, "GRAVITY must be disabled !!\n" ); +# endif + +# ifdef COMOVING + Aux_Error( ERROR_INFO, "COMOVING must be disabled !!\n" ); +# endif + + if ( !OPT__UNIT ) + Aux_Error( ERROR_INFO, "OPT__UNIT must be enabled for this test !!\n" ); + + if ( !OPT__FREEZE_FLUID ) + Aux_Error( ERROR_INFO, "OPT__FREEZE_FLUID must be enabled for this test !!\n" ); + +# ifdef SUPPORT_GRACKLE + if ( !OPT__UNFREEZE_GRACKLE ) + Aux_Error( ERROR_INFO, "OPT__UNFREEZE_GRACKLE must be enabled for this test !!\n" ); + + if ( !GRACKLE_ACTIVATE ) + Aux_Error( ERROR_INFO, "GRACKLE_ACTIVATE must be enabled for this test !!\n" ); + + if ( !OPT__OUTPUT_GRACKLE_TEMP ) + Aux_Error( ERROR_INFO, "OPT__OUTPUT_GRACKLE_TEMP must be enabled for this test !!\n" ); + + if ( !OPT__OUTPUT_GRACKLE_MU ) + Aux_Error( ERROR_INFO, "OPT__OUTPUT_GRACKLE_MU must be enabled for this test !!\n" ); + + if ( !OPT__OUTPUT_GRACKLE_TCOOL ) + Aux_Error( ERROR_INFO, "OPT__OUTPUT_GRACKLE_TCOOL must be enabled for this test !!\n" ); + + if ( END_STEP != 0 && END_T != 0.0 && !GRACKLE_COOLING ) + Aux_Error( ERROR_INFO, "GRACKLE_COOLING must be enabled for time evolution in this test !!\n" ); + + + if ( MPI_Rank == 0 ) + { + if ( DT__GRACKLE_COOLING < 0.0 ) + Aux_Message( stderr, "WARNING : it's recommended to set DT__GRACKLE_COOLING for this test !!\n" ); + + if ( !OPT__FLAG_COOLING_LEN ) + Aux_Message( stderr, "WARNING : it's recommended to set OPT__FLAG_COOLING_LEN for this test !!\n" ); + } // if ( MPI_Rank == 0 ) +# endif // #ifdef SUPPORT_GRACKLE + + + if ( MPI_Rank == 0 ) Aux_Message( stdout, " Validating test problem %d ... done\n", TESTPROB_ID ); + +} // FUNCTION : Validate + + + +#if ( MODEL == HYDRO && defined SUPPORT_GRACKLE ) +//------------------------------------------------------------------------------------------------------- +// Function : LoadInputTestProb +// Description : Read problem-specific runtime parameters from Input__TestProb and store them in HDF5 snapshots (Data_*) +// +// Note : 1. Invoked by SetParameter() to read parameters +// 2. Invoked by Output_DumpData_Total_HDF5() using the function pointer Output_HDF5_InputTest_Ptr to store parameters +// 3. If there is no problem-specific runtime parameter to load, add at least one parameter +// to prevent an empty structure in HDF5_Output_t +// --> Example: +// LOAD_PARA( load_mode, "TestProb_ID", &TESTPROB_ID, TESTPROB_ID, TESTPROB_ID, TESTPROB_ID ); +// +// Parameter : load_mode : Mode for loading parameters +// --> LOAD_READPARA : Read parameters from Input__TestProb +// LOAD_HDF5_OUTPUT : Store parameters in HDF5 snapshots +// ReadPara : Data structure for reading parameters (used with LOAD_READPARA) +// HDF5_InputTest : Data structure for storing parameters in HDF5 snapshots (used with LOAD_HDF5_OUTPUT) +// +// Return : None +//------------------------------------------------------------------------------------------------------- +void LoadInputTestProb( const LoadParaMode_t load_mode, ReadPara_t *ReadPara, HDF5_Output_t *HDF5_InputTest ) +{ + +# ifndef SUPPORT_HDF5 + if ( load_mode == LOAD_HDF5_OUTPUT ) Aux_Error( ERROR_INFO, "please turn on SUPPORT_HDF5 in the Makefile for load_mode == LOAD_HDF5_OUTPUT !!\n" ); +# endif + + if ( load_mode == LOAD_READPARA && ReadPara == NULL ) Aux_Error( ERROR_INFO, "load_mode == LOAD_READPARA and ReadPara == NULL !!\n" ); + if ( load_mode == LOAD_HDF5_OUTPUT && HDF5_InputTest == NULL ) Aux_Error( ERROR_INFO, "load_mode == LOAD_HDF5_OUTPUT and HDF5_InputTest == NULL !!\n" ); + +// add parameters in the following format: +// --> note that VARIABLE, DEFAULT, MIN, and MAX must have the same data type +// --> some handy constants (e.g., NoMin_int, Eps_float, ...) are defined in "include/ReadPara.h" +// --> LOAD_PARA() is defined in "include/TestProb.h" +// ******************************************************************************************************************************** +// LOAD_PARA( load_mode, "KEY_IN_THE_FILE", &VARIABLE, DEFAULT, MIN, MAX ); +// ******************************************************************************************************************************** + LOAD_PARA( load_mode, "GrackleTest_DefaultTestMode", &GrackleTest_DefaultTestMode, 0, 0, 3 ); + LOAD_PARA( load_mode, "GrackleTest_MassDensity_Min", &GrackleTest_MassDensity_Min, 1.0e-29, Eps_double, NoMax_double ); + LOAD_PARA( load_mode, "GrackleTest_MassDensity_Max", &GrackleTest_MassDensity_Max, 1.0e-21, Eps_double, NoMax_double ); + LOAD_PARA( load_mode, "GrackleTest_TempOverMMW_Min", &GrackleTest_TempOverMMW_Min, 1.0e+00, Eps_double, NoMax_double ); + LOAD_PARA( load_mode, "GrackleTest_TempOverMMW_Max", &GrackleTest_TempOverMMW_Max, 1.0e+08, Eps_double, NoMax_double ); + LOAD_PARA( load_mode, "GrackleTest_MFrac_Metal", &GrackleTest_MFrac_Metal, 0.01295, 0.0, 1.0 ); + LOAD_PARA( load_mode, "GrackleTest_MFrac_e", &GrackleTest_MFrac_e, 0.0, 0.0, 1.0 ); + LOAD_PARA( load_mode, "GrackleTest_MFrac_HI", &GrackleTest_MFrac_HI, 0.750158, 0.0, 1.0 ); + LOAD_PARA( load_mode, "GrackleTest_MFrac_HII", &GrackleTest_MFrac_HII, 0.0, 0.0, 1.0 ); + LOAD_PARA( load_mode, "GrackleTest_MFrac_HeI", &GrackleTest_MFrac_HeI, 0.236892, 0.0, 1.0 ); + LOAD_PARA( load_mode, "GrackleTest_MFrac_HeII", &GrackleTest_MFrac_HeII, 0.0, 0.0, 1.0 ); + LOAD_PARA( load_mode, "GrackleTest_MFrac_HeIII", &GrackleTest_MFrac_HeIII, 0.0, 0.0, 1.0 ); + LOAD_PARA( load_mode, "GrackleTest_MFrac_HM", &GrackleTest_MFrac_HM, 0.0, 0.0, 1.0 ); + LOAD_PARA( load_mode, "GrackleTest_MFrac_H2I", &GrackleTest_MFrac_H2I, 0.0, 0.0, 1.0 ); + LOAD_PARA( load_mode, "GrackleTest_MFrac_H2II", &GrackleTest_MFrac_H2II, 0.0, 0.0, 1.0 ); + LOAD_PARA( load_mode, "GrackleTest_MFrac_DI", &GrackleTest_MFrac_DI, 0.0, 0.0, 1.0 ); + LOAD_PARA( load_mode, "GrackleTest_MFrac_DII", &GrackleTest_MFrac_DII, 0.0, 0.0, 1.0 ); + LOAD_PARA( load_mode, "GrackleTest_MFrac_HDI", &GrackleTest_MFrac_HDI, 0.0, 0.0, 1.0 ); + LOAD_PARA( load_mode, "GrackleTest_HeatingRate", &GrackleTest_HeatingRate, 0.0, 0.0, NoMax_double ); + LOAD_PARA( load_mode, "GrackleTest_CoolingRate", &GrackleTest_CoolingRate, 0.0, 0.0, NoMax_double ); + +} // FUNCITON : LoadInputTestProb + + + +//------------------------------------------------------------------------------------------------------- +// Function : SetParameter +// Description : Load and set the problem-specific runtime parameters +// +// Note : 1. Filename is set to "Input__TestProb" by default +// 2. Major tasks in this function: +// (1) load the problem-specific runtime parameters +// (2) set the problem-specific derived parameters +// (3) reset other general-purpose parameters if necessary +// (4) make a note of the problem-specific parameters +// 3. Must call EoS_Init() before calling any other EoS routine +// +// Parameter : None +// +// Return : None +//------------------------------------------------------------------------------------------------------- +void SetParameter() +{ + + if ( MPI_Rank == 0 ) Aux_Message( stdout, " Setting runtime parameters ...\n" ); + + +// (1) load the problem-specific runtime parameters +// (1-1) read parameters from Input__TestProb + const char FileName[] = "Input__TestProb"; + ReadPara_t *ReadPara = new ReadPara_t; + + LoadInputTestProb( LOAD_READPARA, ReadPara, NULL ); + + ReadPara->Read( FileName ); + + delete ReadPara; + +// (1-2) set the default values + if ( ! GRACKLE_METAL ) + { + GrackleTest_MFrac_Metal = 0.0; PRINT_RESET_PARA( GrackleTest_MFrac_Metal, FORMAT_REAL, "for GRACKLE_METAL disabled" ); + } + + if ( GRACKLE_PRIMORDIAL < GRACKLE_PRI_CHE_NSPE12 ) + { + GrackleTest_MFrac_DI = 0.0; PRINT_RESET_PARA( GrackleTest_MFrac_DI, FORMAT_REAL, "for GRACKLE_PRIMORDIAL < GRACKLE_PRI_CHE_NSPE12" ); + GrackleTest_MFrac_DII = 0.0; PRINT_RESET_PARA( GrackleTest_MFrac_DII, FORMAT_REAL, "for GRACKLE_PRIMORDIAL < GRACKLE_PRI_CHE_NSPE12" ); + GrackleTest_MFrac_HDI = 0.0; PRINT_RESET_PARA( GrackleTest_MFrac_HDI, FORMAT_REAL, "for GRACKLE_PRIMORDIAL < GRACKLE_PRI_CHE_NSPE12" ); + } + + if ( GRACKLE_PRIMORDIAL < GRACKLE_PRI_CHE_NSPE9 ) + { + GrackleTest_MFrac_HM = 0.0; PRINT_RESET_PARA( GrackleTest_MFrac_HM, FORMAT_REAL, "for GRACKLE_PRIMORDIAL < GRACKLE_PRI_CHE_NSPE9" ); + GrackleTest_MFrac_H2I = 0.0; PRINT_RESET_PARA( GrackleTest_MFrac_H2I, FORMAT_REAL, "for GRACKLE_PRIMORDIAL < GRACKLE_PRI_CHE_NSPE9" ); + GrackleTest_MFrac_H2II = 0.0; PRINT_RESET_PARA( GrackleTest_MFrac_H2II, FORMAT_REAL, "for GRACKLE_PRIMORDIAL < GRACKLE_PRI_CHE_NSPE9" ); + } + + if ( GRACKLE_PRIMORDIAL < GRACKLE_PRI_CHE_NSPE6 ) + { + GrackleTest_MFrac_e = 0.0; PRINT_RESET_PARA( GrackleTest_MFrac_e, FORMAT_REAL, "for GRACKLE_PRIMORDIAL < GRACKLE_PRI_CHE_NSPE6" ); + GrackleTest_MFrac_HI = 0.0; PRINT_RESET_PARA( GrackleTest_MFrac_HI, FORMAT_REAL, "for GRACKLE_PRIMORDIAL < GRACKLE_PRI_CHE_NSPE6" ); + GrackleTest_MFrac_HII = 0.0; PRINT_RESET_PARA( GrackleTest_MFrac_HII, FORMAT_REAL, "for GRACKLE_PRIMORDIAL < GRACKLE_PRI_CHE_NSPE6" ); + GrackleTest_MFrac_HeI = 0.0; PRINT_RESET_PARA( GrackleTest_MFrac_HeI, FORMAT_REAL, "for GRACKLE_PRIMORDIAL < GRACKLE_PRI_CHE_NSPE6" ); + GrackleTest_MFrac_HeII = 0.0; PRINT_RESET_PARA( GrackleTest_MFrac_HeII, FORMAT_REAL, "for GRACKLE_PRIMORDIAL < GRACKLE_PRI_CHE_NSPE6" ); + GrackleTest_MFrac_HeIII = 0.0; PRINT_RESET_PARA( GrackleTest_MFrac_HeIII, FORMAT_REAL, "for GRACKLE_PRIMORDIAL < GRACKLE_PRI_CHE_NSPE6" ); + } + + if ( !GRACKLE_USE_V_HEATING_RATE ) + { + GrackleTest_HeatingRate = 0.0; PRINT_RESET_PARA( GrackleTest_HeatingRate, FORMAT_REAL, "for GRACKLE_USE_V_HEATING_RATE disabled" ); + GrackleTest_CoolingRate = 0.0; PRINT_RESET_PARA( GrackleTest_CoolingRate, FORMAT_REAL, "for GRACKLE_USE_V_HEATING_RATE disabled" ); + } + + if ( GrackleTest_DefaultTestMode == 1 ) + { + GrackleTest_MassDensity_Min = 1.0e-29; PRINT_RESET_PARA( GrackleTest_MassDensity_Min, FORMAT_REAL, "for GrackleTest_DefaultTestMode == 1" ); + GrackleTest_MassDensity_Max = 1.0e-21; PRINT_RESET_PARA( GrackleTest_MassDensity_Max, FORMAT_REAL, "for GrackleTest_DefaultTestMode == 1" ); + GrackleTest_TempOverMMW_Min = 1.0e+00; PRINT_RESET_PARA( GrackleTest_TempOverMMW_Min, FORMAT_REAL, "for GrackleTest_DefaultTestMode == 1" ); + GrackleTest_TempOverMMW_Max = 1.0e+08; PRINT_RESET_PARA( GrackleTest_TempOverMMW_Max, FORMAT_REAL, "for GrackleTest_DefaultTestMode == 1" ); + GrackleTest_HeatingRate = 0.0; PRINT_RESET_PARA( GrackleTest_HeatingRate, FORMAT_REAL, "for GrackleTest_DefaultTestMode == 1" ); + GrackleTest_CoolingRate = 0.0; PRINT_RESET_PARA( GrackleTest_CoolingRate, FORMAT_REAL, "for GrackleTest_DefaultTestMode == 1" ); + } + else if ( GrackleTest_DefaultTestMode == 2 ) + { + GrackleTest_MassDensity_Min = 1.0e-24; PRINT_RESET_PARA( GrackleTest_MassDensity_Min, FORMAT_REAL, "for GrackleTest_DefaultTestMode == 2" ); + GrackleTest_MassDensity_Max = 1.0e-24; PRINT_RESET_PARA( GrackleTest_MassDensity_Max, FORMAT_REAL, "for GrackleTest_DefaultTestMode == 2" ); + GrackleTest_TempOverMMW_Min = 1.0e+04; PRINT_RESET_PARA( GrackleTest_TempOverMMW_Min, FORMAT_REAL, "for GrackleTest_DefaultTestMode == 2" ); + GrackleTest_TempOverMMW_Max = 1.0e+04; PRINT_RESET_PARA( GrackleTest_TempOverMMW_Max, FORMAT_REAL, "for GrackleTest_DefaultTestMode == 2" ); + GrackleTest_HeatingRate = 0.0; PRINT_RESET_PARA( GrackleTest_HeatingRate, FORMAT_REAL, "for GrackleTest_DefaultTestMode == 2" ); + GrackleTest_CoolingRate = 0.0; PRINT_RESET_PARA( GrackleTest_CoolingRate, FORMAT_REAL, "for GrackleTest_DefaultTestMode == 2" ); + } + else if ( GrackleTest_DefaultTestMode == 3 ) + { + if ( GRACKLE_PRIMORDIAL != GRACKLE_PRI_CHE_CLOUDY ) + Aux_Error( ERROR_INFO, "GRACKLE_PRIMORDIAL must be 0 for GrackleTest_DefaultTestMode = %d !!\n", + GrackleTest_DefaultTestMode ); + + if ( GRACKLE_COOLING != 1 ) + Aux_Error( ERROR_INFO, "GRACKLE_COOLING must be 1 for GrackleTest_DefaultTestMode = %d !!\n", + GrackleTest_DefaultTestMode ); + + if ( GRACKLE_USE_V_HEATING_RATE != 1 ) + Aux_Error( ERROR_INFO, "GRACKLE_USE_V_HEATING_RATE must be 1 for GrackleTest_DefaultTestMode = %d !!\n", + GrackleTest_DefaultTestMode ); + + if ( GRACKLE_UV != 0 ) + Aux_Error( ERROR_INFO, "GRACKLE_UV must be 0 for GrackleTest_DefaultTestMode = %d !!\n", + GrackleTest_DefaultTestMode ); + + if ( GRACKLE_CMB_FLOOR != 0 ) + Aux_Error( ERROR_INFO, "GRACKLE_CMB_FLOOR must be 0 for GrackleTest_DefaultTestMode = %d !!\n", + GrackleTest_DefaultTestMode ); + + if ( GRACKLE_PE_HEATING != 0 ) + Aux_Error( ERROR_INFO, "GRACKLE_PE_HEATING must be 0 for GrackleTest_DefaultTestMode = %d !!\n", + GrackleTest_DefaultTestMode ); + + GrackleTest_MassDensity_Min = 1.0e-28; PRINT_RESET_PARA( GrackleTest_MassDensity_Min, FORMAT_REAL, "for GrackleTest_DefaultTestMode == 3" ); + GrackleTest_MassDensity_Max = 1.0e-28; PRINT_RESET_PARA( GrackleTest_MassDensity_Max, FORMAT_REAL, "for GrackleTest_DefaultTestMode == 3" ); + GrackleTest_TempOverMMW_Min = 1.0e+06; PRINT_RESET_PARA( GrackleTest_TempOverMMW_Min, FORMAT_REAL, "for GrackleTest_DefaultTestMode == 3" ); + GrackleTest_TempOverMMW_Max = 1.0e+06; PRINT_RESET_PARA( GrackleTest_TempOverMMW_Max, FORMAT_REAL, "for GrackleTest_DefaultTestMode == 3" ); + GrackleTest_MFrac_Metal = 0.0; PRINT_RESET_PARA( GrackleTest_MFrac_Metal, FORMAT_REAL, "for GrackleTest_DefaultTestMode == 3" ); + GrackleTest_HeatingRate = 1.0e-24; PRINT_RESET_PARA( GrackleTest_HeatingRate, FORMAT_REAL, "for GrackleTest_DefaultTestMode == 3" ); + GrackleTest_CoolingRate = 1.6e-20; PRINT_RESET_PARA( GrackleTest_CoolingRate, FORMAT_REAL, "for GrackleTest_DefaultTestMode == 3" ); + } + else + { + Aux_Error( ERROR_INFO, "Unknown GrackleTest_DefaultTestMode = %d !!\n", GrackleTest_DefaultTestMode ); + } + +// (1-3) check the runtime parameters + if ( GrackleTest_MassDensity_Min > GrackleTest_MassDensity_Max ) + Aux_Error( ERROR_INFO, "MassDensity_Min = %14.7e > MassDensity_Max = %14.7e !!\n", + GrackleTest_MassDensity_Min, GrackleTest_MassDensity_Max ); + + if ( GrackleTest_TempOverMMW_Min > GrackleTest_TempOverMMW_Max ) + Aux_Error( ERROR_INFO, "TempOverMMW_Min = %14.7e > TempOverMMW_Max = %14.7e !!\n", + GrackleTest_TempOverMMW_Min, GrackleTest_TempOverMMW_Max ); + + if ( GRACKLE_PRIMORDIAL >= GRACKLE_PRI_CHE_NSPE6 ) + { + const double MFrac_Total = GrackleTest_MFrac_e + GrackleTest_MFrac_HI + GrackleTest_MFrac_HII + + GrackleTest_MFrac_HeI + GrackleTest_MFrac_HeII + GrackleTest_MFrac_HeIII + + GrackleTest_MFrac_HM + GrackleTest_MFrac_H2I + GrackleTest_MFrac_H2II + + GrackleTest_MFrac_DI + GrackleTest_MFrac_DII + GrackleTest_MFrac_HDI + + GrackleTest_MFrac_Metal; + + if ( ! Mis_CompareRealValue( MFrac_Total, 1.0, NULL, false ) ) + Aux_Error( ERROR_INFO, "Sum of mass fraction = %14.7e != 1.0 !!\n", MFrac_Total ); + } + + + +// (2) set the problem-specific derived parameters +// convert to code units + GrackleTest_MassDensity_Min /= UNIT_D; + GrackleTest_MassDensity_Max /= UNIT_D; + + GrackleTest_logDens_Min = log10( GrackleTest_MassDensity_Min ); + GrackleTest_logDens_Max = log10( GrackleTest_MassDensity_Max ); + GrackleTest_logDens_Range = GrackleTest_logDens_Max - GrackleTest_logDens_Min; + GrackleTest_logTemp_Min = log10( GrackleTest_TempOverMMW_Min * MOLECULAR_WEIGHT ); // from Temp/mu to built-in Temp in GAMER + GrackleTest_logTemp_Max = log10( GrackleTest_TempOverMMW_Max * MOLECULAR_WEIGHT ); + GrackleTest_logTemp_Range = GrackleTest_logTemp_Max - GrackleTest_logTemp_Min; + + +// (3) reset other general-purpose parameters +// --> a helper macro PRINT_RESET_PARA is defined in Macro.h + const long End_Step_Default = 10; // 10 * DT__GRACKLE_COOLING * cooling time + const double End_T_Default = 10.0*Const_Myr/UNIT_T; // 10 Myr + + if ( END_STEP < 0 ) { + END_STEP = End_Step_Default; + PRINT_RESET_PARA( END_STEP, FORMAT_LONG, "" ); + } + + if ( END_T < 0.0 ) { + END_T = End_T_Default; + PRINT_RESET_PARA( END_T, FORMAT_REAL, "" ); + } + + +// (4) make a note + if ( MPI_Rank == 0 ) + { + Aux_Message( stdout, "=============================================================================\n" ); + Aux_Message( stdout, " test problem ID = %d\n", TESTPROB_ID ); + Aux_Message( stdout, " GrackleTest_DefaultTestMode = %d\n", GrackleTest_DefaultTestMode ); + Aux_Message( stdout, " GrackleTest_MassDensity_Min = %13.7e UNIT_D\n", GrackleTest_MassDensity_Min ); + Aux_Message( stdout, " = %13.7e g/cm^3\n", GrackleTest_MassDensity_Min*UNIT_D ); + Aux_Message( stdout, " = %13.7e mH/cm^3\n", GrackleTest_MassDensity_Min*UNIT_D/Const_mH ); + Aux_Message( stdout, " GrackleTest_MassDensity_Max = %13.7e UNIT_D\n", GrackleTest_MassDensity_Max ); + Aux_Message( stdout, " = %13.7e g/cm^3\n", GrackleTest_MassDensity_Max*UNIT_D ); + Aux_Message( stdout, " = %13.7e mH/cm^3\n", GrackleTest_MassDensity_Max*UNIT_D/Const_mH ); + Aux_Message( stdout, " GrackleTest_TempOverMMW_Min = %13.7e K\n", GrackleTest_TempOverMMW_Min ); + Aux_Message( stdout, " GrackleTest_TempOverMMW_Max = %13.7e K\n", GrackleTest_TempOverMMW_Max ); + Aux_Message( stdout, " GrackleTest_MFrac_Metal = %13.7e\n", GrackleTest_MFrac_Metal ); + Aux_Message( stdout, " GrackleTest_MFrac_e = %13.7e\n", GrackleTest_MFrac_e ); + Aux_Message( stdout, " GrackleTest_MFrac_HI = %13.7e\n", GrackleTest_MFrac_HI ); + Aux_Message( stdout, " GrackleTest_MFrac_HII = %13.7e\n", GrackleTest_MFrac_HII ); + Aux_Message( stdout, " GrackleTest_MFrac_HeI = %13.7e\n", GrackleTest_MFrac_HeI ); + Aux_Message( stdout, " GrackleTest_MFrac_HeII = %13.7e\n", GrackleTest_MFrac_HeII ); + Aux_Message( stdout, " GrackleTest_MFrac_HeIII = %13.7e\n", GrackleTest_MFrac_HeIII ); + Aux_Message( stdout, " GrackleTest_MFrac_HM = %13.7e\n", GrackleTest_MFrac_HM ); + Aux_Message( stdout, " GrackleTest_MFrac_H2I = %13.7e\n", GrackleTest_MFrac_H2I ); + Aux_Message( stdout, " GrackleTest_MFrac_H2II = %13.7e\n", GrackleTest_MFrac_H2II ); + Aux_Message( stdout, " GrackleTest_MFrac_DI = %13.7e\n", GrackleTest_MFrac_DI ); + Aux_Message( stdout, " GrackleTest_MFrac_DII = %13.7e\n", GrackleTest_MFrac_DII ); + Aux_Message( stdout, " GrackleTest_MFrac_HDI = %13.7e\n", GrackleTest_MFrac_HDI ); + Aux_Message( stdout, " GrackleTest_HeatingRate = %13.7e erg cm^-3 s^-1 n_H^-1\n", GrackleTest_HeatingRate ); + Aux_Message( stdout, " GrackleTest_CoolingRate = %13.7e erg cm^-3 s^-1 n_H^-2\n", GrackleTest_CoolingRate ); + Aux_Message( stdout, "=============================================================================\n" ); + } + + + if ( MPI_Rank == 0 ) Aux_Message( stdout, " Setting runtime parameters ... done\n" ); + +} // FUNCTION : SetParameter + + + +//------------------------------------------------------------------------------------------------------- +// Function : SetGridIC +// Description : Set the problem-specific initial condition on grids +// +// Note : 1. This function may also be used to estimate the numerical errors when OPT__OUTPUT_USER is enabled +// --> In this case, it should provide the analytical solution at the given "Time" +// 2. This function will be invoked by multiple OpenMP threads when OPENMP is enabled +// (unless OPT__INIT_GRID_WITH_OMP is disabled) +// --> Please ensure that everything here is thread-safe +// 3. Even when DUAL_ENERGY is adopted for HYDRO, one does NOT need to set the dual-energy variable here +// --> It will be calculated automatically +// 4. For MHD, do NOT add magnetic energy (i.e., 0.5*B^2) to fluid[ENGY] here +// --> It will be added automatically later +// +// Parameter : fluid : Fluid field to be initialized +// x/y/z : Physical coordinates +// Time : Physical time +// lv : Target refinement level +// AuxArray : Auxiliary array +// +// Return : fluid +//------------------------------------------------------------------------------------------------------- +void SetGridIC( real fluid[], const double x, const double y, const double z, const double Time, + const int lv, double AuxArray[] ) +{ + + +// check +# ifdef GAMER_DEBUG + if ( GRACKLE_PRIMORDIAL >= GRACKLE_PRI_CHE_NSPE6 && Idx_e == Idx_Undefined ) Aux_Error( ERROR_INFO, "Idx_e is undefined !!\n" ); + if ( GRACKLE_PRIMORDIAL >= GRACKLE_PRI_CHE_NSPE6 && Idx_HI == Idx_Undefined ) Aux_Error( ERROR_INFO, "Idx_HI is undefined !!\n" ); + if ( GRACKLE_PRIMORDIAL >= GRACKLE_PRI_CHE_NSPE6 && Idx_HII == Idx_Undefined ) Aux_Error( ERROR_INFO, "Idx_HII is undefined !!\n" ); + if ( GRACKLE_PRIMORDIAL >= GRACKLE_PRI_CHE_NSPE6 && Idx_HeI == Idx_Undefined ) Aux_Error( ERROR_INFO, "Idx_HeI is undefined !!\n" ); + if ( GRACKLE_PRIMORDIAL >= GRACKLE_PRI_CHE_NSPE6 && Idx_HeII == Idx_Undefined ) Aux_Error( ERROR_INFO, "Idx_HeII is undefined !!\n" ); + if ( GRACKLE_PRIMORDIAL >= GRACKLE_PRI_CHE_NSPE6 && Idx_HeIII == Idx_Undefined ) Aux_Error( ERROR_INFO, "Idx_HeIII is undefined !!\n" ); + if ( GRACKLE_PRIMORDIAL >= GRACKLE_PRI_CHE_NSPE9 && Idx_HM == Idx_Undefined ) Aux_Error( ERROR_INFO, "Idx_HM is undefined !!\n" ); + if ( GRACKLE_PRIMORDIAL >= GRACKLE_PRI_CHE_NSPE9 && Idx_H2I == Idx_Undefined ) Aux_Error( ERROR_INFO, "Idx_H2I is undefined !!\n" ); + if ( GRACKLE_PRIMORDIAL >= GRACKLE_PRI_CHE_NSPE9 && Idx_H2II == Idx_Undefined ) Aux_Error( ERROR_INFO, "Idx_H2II is undefined !!\n" ); + if ( GRACKLE_PRIMORDIAL >= GRACKLE_PRI_CHE_NSPE12 && Idx_DI == Idx_Undefined ) Aux_Error( ERROR_INFO, "Idx_DI is undefined !!\n" ); + if ( GRACKLE_PRIMORDIAL >= GRACKLE_PRI_CHE_NSPE12 && Idx_DII == Idx_Undefined ) Aux_Error( ERROR_INFO, "Idx_DII is undefined !!\n" ); + if ( GRACKLE_PRIMORDIAL >= GRACKLE_PRI_CHE_NSPE12 && Idx_HDI == Idx_Undefined ) Aux_Error( ERROR_INFO, "Idx_HDI is undefined !!\n" ); + if ( GRACKLE_METAL && Idx_Metal == Idx_Undefined ) Aux_Error( ERROR_INFO, "Idx_Metal is undefined !!\n" ); + if ( EoS_DensTemp2Pres_CPUPtr == NULL ) Aux_Error( ERROR_INFO, "EoS_DensTemp2Pres_CPUPtr == NULL !!\n" ); +# endif + +// compute the gas log density by linear interpolation in x-direction + const double logDens = GrackleTest_logDens_Min + + GrackleTest_logDens_Range*( x / amr->BoxSize[0] ); + const double Dens = pow( 10, logDens ); + +// compute the gas log temperature by linear interpolation in y-direction + const double logTemp = GrackleTest_logTemp_Min + + GrackleTest_logTemp_Range*( y / amr->BoxSize[1] ); + const double Temp = pow( 10, logTemp ); + +// compute the gas pressure + const double Pres = EoS_DensTemp2Pres_CPUPtr( Dens, Temp, NULL, EoS_AuxArray_Flt, EoS_AuxArray_Int, + h_EoS_Table ); // assuming EoS requires no passive scalars + +// assume no momentum + const double MomX = 0.0; + const double MomY = 0.0; + const double MomZ = 0.0; + +// compute the total gas energy + const double Eint = EoS_DensPres2Eint_CPUPtr( Dens, Pres, NULL, EoS_AuxArray_Flt, + EoS_AuxArray_Int, h_EoS_Table ); // assuming EoS requires no passive scalars + const double Etot = Hydro_ConEint2Etot( Dens, MomX, MomY, MomZ, Eint, 0.0 ); // do NOT include magnetic energy here + + +// set the output array + fluid[DENS] = Dens; + fluid[MOMX] = MomX; + fluid[MOMY] = MomY; + fluid[MOMZ] = MomZ; + fluid[ENGY] = Etot; + + +// set passive scalars +// 6-species network + if ( GRACKLE_PRIMORDIAL >= GRACKLE_PRI_CHE_NSPE6 ) + { + fluid[Idx_e ] = Dens * GrackleTest_MFrac_e; + fluid[Idx_HI ] = Dens * GrackleTest_MFrac_HI; + fluid[Idx_HII ] = Dens * GrackleTest_MFrac_HII; + fluid[Idx_HeI ] = Dens * GrackleTest_MFrac_HeI; + fluid[Idx_HeII ] = Dens * GrackleTest_MFrac_HeII; + fluid[Idx_HeIII] = Dens * GrackleTest_MFrac_HeIII; + } + +// 9-species network + if ( GRACKLE_PRIMORDIAL >= GRACKLE_PRI_CHE_NSPE9 ) + { + fluid[Idx_HM ] = Dens * GrackleTest_MFrac_HM; + fluid[Idx_H2I ] = Dens * GrackleTest_MFrac_H2I; + fluid[Idx_H2II ] = Dens * GrackleTest_MFrac_H2II; + } + +// 12-species network + if ( GRACKLE_PRIMORDIAL >= GRACKLE_PRI_CHE_NSPE12 ) + { + fluid[Idx_DI ] = Dens * GrackleTest_MFrac_DI; + fluid[Idx_DII ] = Dens * GrackleTest_MFrac_DII; + fluid[Idx_HDI ] = Dens * GrackleTest_MFrac_HDI; + } + +// metallicity for metal cooling + if ( GRACKLE_METAL ) + fluid[Idx_Metal] = Dens * GrackleTest_MFrac_Metal; + +} // FUNCTION : SetGridIC + + + +//------------------------------------------------------------------------------------------------------- +// Function : Grackle_vHeatingRate_GrackleTest +// Description : Function to set Grackle's volumetric heating rate for GrackleTest +// +// Note : 1. Invoked by Grackle_Prepare() using the function pointer +// "Grackle_vHeatingRate_User_Ptr", which must be set by a test problem initializer +// 2. This function will be invoked by multiple OpenMP threads when OPENMP is enabled +// --> Please ensure that everything here is thread-safe +// 3. Returned rate should be in the unit of erg s^-1 cm^-3 +// +// Parameter : x/y/z : Target physical coordinates +// Time : Target physical time +// n_H : Hydrogen number density, should be in the unit of cm^-3 +// +// Return : volumetric_heating_rate +//------------------------------------------------------------------------------------------------------- +real_che Grackle_vHeatingRate_GrackleTest( const double x, const double y, const double z, const double Time, const double n_H ) +{ + const double volumetric_heating_rate_0 = n_H * GrackleTest_HeatingRate; // GrackleTest_HeatingRate is in the unit of erg cm^-3 s^-1 n_H^-1 + const double volumetric_cooling_rate_0 = n_H * n_H * GrackleTest_CoolingRate; // GrackleTest_CoolingRate is in the unit of erg cm^-3 s^-1 n_H^-2 + +// assume uniform distribution if it is not specified + if ( GrackleTest_DefaultTestMode != 3 ) + return volumetric_heating_rate_0 - volumetric_cooling_rate_0; + +// an example of spatial distribution only for GrackleTest_DefaultTestMode == 3 +// two 2D Gaussian distributions: one heating and one cooling + const double Center_H[3] = { amr->BoxCenter[0]+0.25*amr->BoxSize[0], amr->BoxCenter[1], amr->BoxCenter[2] }; // center of heating + const double Center_C[3] = { amr->BoxCenter[0]-0.25*amr->BoxSize[0], amr->BoxCenter[1], amr->BoxCenter[2] }; // center of cooling + const double r_to_center_h = sqrt( SQR(x-Center_H[0]) + SQR(y-Center_H[1]) ); // radius to heating + const double r_to_center_c = sqrt( SQR(x-Center_C[0]) + SQR(y-Center_C[1]) ); // radius to cooling + const double distr_width = 0.0625*amr->BoxSize[0]; // width of Gaussian + const double distr_r_max = 0.1250*amr->BoxSize[0]; // cutoff radius + const real_che volumetric_heating_rate_r = ( r_to_center_h <= distr_r_max ) ? volumetric_heating_rate_0 * exp( -0.5*SQR(r_to_center_h/distr_width) ) + : (real_che)0.0; + const real_che volumetric_cooling_rate_r = ( r_to_center_c <= distr_r_max ) ? volumetric_cooling_rate_0 * exp( -0.5*SQR(r_to_center_c/distr_width) ) + : (real_che)0.0; + + return volumetric_heating_rate_r - volumetric_cooling_rate_r; + +} // FUNCTION : Grackle_vHeatingRate_GrackleTest +#endif // #if ( MODEL == HYDRO && defined SUPPORT_GRACKLE ) + + + +//------------------------------------------------------------------------------------------------------- +// Function : Init_TestProb_Hydro_GrackleTest +// Description : Test problem initializer +// +// Note : None +// +// Parameter : None +// +// Return : None +//------------------------------------------------------------------------------------------------------- +void Init_TestProb_Hydro_GrackleTest() +{ + + if ( MPI_Rank == 0 ) Aux_Message( stdout, "%s ...\n", __FUNCTION__ ); + + +// validate the compilation flags and runtime parameters + Validate(); + + +# if ( MODEL == HYDRO && defined SUPPORT_GRACKLE ) +// set the problem-specific runtime parameters + SetParameter(); + + +// set the function pointers of various problem-specific routines + Init_Function_User_Ptr = SetGridIC; + Grackle_vHeatingRate_User_Ptr = Grackle_vHeatingRate_GrackleTest; +# ifdef SUPPORT_HDF5 + Output_HDF5_InputTest_Ptr = LoadInputTestProb; +# endif +# endif // #if ( MODEL == HYDRO && defined SUPPORT_GRACKLE ) + + + if ( MPI_Rank == 0 ) Aux_Message( stdout, "%s ... done\n", __FUNCTION__ ); + +} // FUNCTION : Init_TestProb_Hydro_GrackleTest