Installation
The compilation process for grackle is very similar to that for
Enzo. For more details on the Enzo build
system, see the Enzo build documentation.
Dependencies
In addition to C/C++ and Fortran compilers, the following dependency must
also be installed:
- HDF5, the hierarchical data format.
HDF5 also may require the szip and zlib libraries, which can be
found at the HDF5 website. Compiling with HDF5 1.8 or greater
requires that the compiler directive
H5_USE_16_API
be specified.
This can be done with -DH5_USE_16_API
, which is in the machine
specific make files.
Downloading
Grackle is available in a mercurial repository
here. The mercurial site
is here and an excellent tutorial can be
found here. With mercurial
installed, grackle can be obtained with the following command:
~ $ hg clone https://bitbucket.org/grackle/grackle
Building
- Initialize the build system.
~ $ cd grackle
~/grackle $ ./configure
- Proceed to the source directory.
- Configure the build system.
Note
As of version 2.1, Grackle uses libtool
for building and installation.
As such, both shared and static libraries will be built automatically and
it is not necessary to add the -fPIC compiler flag.
Compile settings for different systems are stored in files starting with
“Make.mach” in the source directory. Grackle comes with three sample make
macros: Make.mach.darwin
for Mac OSX, Make.mach.linux-gnu
for
Linux systems, and an unformatted Make.mach.unknown
. If you have a make
file prepared for an Enzo install, it cannot be used straight away, but is a
very good place to start.
Once you have chosen the make file to be used, a few variables should be set:
MACH_LIBTOOL
- path to libtool
executable. Note, on a Mac,
this should point to glibtool
, which can be installed with macports
or homebrew.
LOCAL_HDF5_INSTALL
- path to your hdf5 installation.
LOCAL_FC_INSTALL
- path to Fortran compilers (not including the bin
subdirectory).
MACH_INSTALL_PREFIX
- path where grackle header and library files
will be installed.
MACH_INSTALL_LIB_DIR
- path where libgrackle will be installed (only
set if different from MACH_INSTALL_PREFIX/lib).
MACH_INSTALL_INCLUDE_DIR
- path where grackle header files will be
installed (only set if different from MACH_INSTALL_PREFIX/include).
Once the proper variables are set, they are loaded into the build system by
doing the following:
~/grackle/src/clib $ make machine-<system>
Where system refers to the make file you have chosen. For example, if you
chose Make.mach.darwin
, type:
~/grackle/src/clib $ make machine-darwin
Custom make files can be saved and loaded from a .grackle directory in the
home directory.
Compiler Settings
There are three compile options available for setting the precision of
baryon fields, compiler optimization, and enabling OpenMP. To see them,
type:
~/grackle/src/clib $ make show-config
MACHINE: Darwin (OSX)
MACHINE-NAME: darwin
CONFIG_PRECISION [precision-{32,64}] : 64
CONFIG_OPT [opt-{warn,debug,high,aggressive}] : high
CONFIG_OMP [omp-{on,off}] : off
For example, to change the optimization to high, type:
~/grackle/src/clib $ make opt-high
Custom settings can be saved for later use by typing:
~/grackle/src/clib $ make save-config-<keyword>
They will be saved in the .grackle directory in your home directory. To
reload them, type:
~/grackle/src/clib $ make load-config-<keyword>
For a list of all available make commands, type:
~/grackle/src/clib $ make help
========================================================================
Grackle Makefile Help
========================================================================
make Compile and generate librackle
make install Copy the library somewhere
make help Display this help information
make clean Remove object files, executable, etc.
make dep Create make dependencies in DEPEND file
make show-version Display revision control system branch and revision
make show-diff Display local file modifications
make help-config Display detailed help on configuration make targets
make show-config Display the configuration settings
make show-flags Display specific compilation flags
make default Reset the configuration to the default values
- Compile and Install
To build the code, type:
~/grackle/src/clib $ make
Updating DEPEND
Compiling calc_rates.F
Compiling cool1d_multi.F
....
Linking
Success!
Then, to install:
~/grackle/src/clib $ make install
- Test your Installation
Once installed, you can test your installation with the provided example to
assure it is functioning correctly. If something goes wrong in this process,
check the out.compile
file to see what went wrong during compilation,
or use ldd
(otool -L
on Mac) on your executable to determine what went
wrong during linking.
~/grackle/src/clib $ cd ../example
~/grackle/src/example $ make clean
~/grackle/src/example $ make
Compiling cxx_example.C
Linking
Success!
~/grackle/src/example $ ./cxx_example
The Grackle Version 2.2
Mercurial Branch default
Mercurial Revision b4650914153d
Initializing grackle data.
with_radiative_cooling: 1.
primordial_chemistry: 3.
metal_cooling: 1.
UVbackground: 1.
Initializing Cloudy cooling: Metals.
cloudy_table_file: ../../input/CloudyData_UVB=HM2012.h5.
Cloudy cooling grid rank: 3.
Cloudy cooling grid dimensions: 29 26 161.
Parameter1: -10 to 4 (29 steps).
Parameter2: 0 to 14.849 (26 steps).
Temperature: 1 to 9 (161 steps).
Reading Cloudy Cooling dataset.
Reading Cloudy Heating dataset.
Initializing UV background.
Reading UV background data from ../../input/CloudyData_UVB=HM2012.h5.
UV background information:
Haardt & Madau (2012, ApJ, 746, 125) [Galaxies & Quasars]
z_min = 0.000
z_max = 15.130
Setting UVbackground_redshift_on to 15.130000.
Setting UVbackground_redshift_off to 0.000000.
Cooling time = -1.434987e+13 s.
Temperature = 4.637034e+02 K.
Pressure = 3.345738e+34.
gamma = 1.666645e+00.
In order to verify that Grackle is fully functional, try running the
test suite.
Running the Test Suite
Grackle contains a number of unit and answer tests to verify that everything is
working properly. These will verify that:
- proper and comoving unit systems are consistent
- atomic, primordial collisional ionization equilibrium agrees with
the analytical solution
- all code examples build and run
- all python examples run and give correct results
- all Python code conforms to PEP 8
Once you have installed pygrackle, the tests can be run from the
src directory by typing make test
:
~ $ cd grackle/src
~/grackle/src $ make test
or from the src/python directory by typing py.test
:
~ $ cd grackle/src/python
~/grackle/src $ py.test
===================================== test session starts ======================================
platform darwin -- Python 2.7.11, pytest-2.8.1, py-1.4.30, pluggy-0.3.1
rootdir: /Users/britton/Documents/work/simulation/grackle/grackle/src/python, inifile:
collected 13 items
tests/test_chemistry.py ...
tests/test_code_examples.py ....
tests/test_examples.py ........
tests/test_flake8.py .
tests/test_primordial.py .
================================== 17 passed in 68.83 seconds ==================================
Now it’s time to integrate grackle into your simulation code.
Adding Grackle to Your Simulation Code
The majority of this document follows the implementation of Grackle in
a C++ simulation code. Full implementation examples for
C, C++, and Fortran are also available in the Grackle source. See
Example Executables for more information. For a list of all available
functions, see the API Reference.
Example Executables
The grackle source code contains examples for C, C++, and Fortran codes.
They are located in the src/example directory and provide examples
of calling all of grackle’s functions.
- c_example.c - C example
- cxx_example.C - C++ example
- cxx_omp_example.C - C++ example using OpenMP
- fortran_example.F - Fortran example
Once you have already installed the grackle library, you can build the examples
by typing make and the name of the file without extension. For example, to
build the C++ example, type:
To run the example, make sure to add the path to the directory containing
the installed libgrackle.so to your LD_LIBRARY_PATH (or
DYLD_LIBRARY_PATH on Mac).
Data Types
The grackle library provides a configurable variable type to control the
precision of the baryon fields passed to the grackle functions. For C and
C++ codes, this is gr_float
. For Fortran codes, this is
R_PREC
. The precision of these types can be configured with the
precision compile option. Compile with precision-32 to make
gr_float
and R_PREC
a 4 byte float (float for C/C++
and real*4 for Fortran). Compile with precision-64 to make
gr_float
and R_PREC
an 8 byte float (double for C/C++
and real*8 for Fortran).
-
gr_float
Floating point type used for the baryon fields. This is of type float
if compiled with precision-32 and type double if compiled with
precision-64.
-
R_PREC
The Fortran analog of gr_float
. This is of type real*4 if
compiled with precision-32 and type real*8 if compiled with
precision-64.
Enabling Output
By default, grackle will not print anything but error messages. However,
a short summary of the running configuration can be printed by setting
grackle_verbose
to 1. In a parallel code, it is recommended that
output only be enabled for the root process.
// Enable output
grackle_verbose = 1;
Code Units
It is strongly recommended to use comoving coordinates with any
cosmological simulation. The code_units
structure contains
conversions from code units to CGS. If comoving_coordinates
is set to
0, it is assumed that the fields passed into the solver are in the
proper frame. All of the units (density, length, time, velocity, and
expansion factor) must be set. When using the proper frame, a_units
(units for the expansion factor) must be set to 1.0.
-
code_units
This structure contains the following members.
-
int
comoving_coordinates
If set to 1, the incoming field data is assumed to be in the comoving
frame. If set to 0, the incoming field data is assumed to be in the
proper frame.
-
double
density_units
Conversion factor to be multiplied by density fields to return
densities in proper g/cm3.
-
double
length_units
Conversion factor to be multiplied by length variables to return
lengths in proper cm.
-
double
time_units
Conversion factor to be multiplied by time variables to return
times in s.
-
double
velocity_units
Conversion factor to be multiplied by velocities to return proper cm/s.
-
double
a_units
Conversion factor to be multiplied by the expansion factor such that
atrue = acode* a_units
.
-
double
a_value
The current value of the expansion factor in units of a_units
.
The conversion from redshift to expansion factor in code units is given
by a_value
= 1 / (1 + z) / a_units
. If the
simulation is not cosmological, a_value
should be set to 1.
Note, if a_value
is set to something other than 1 in a
non-cosmological simulation, all redshift dependent chemistry and
cooling terms will be set corresponding to the redshift given.
code_units my_units;
my_units.comoving_coordinates = 0; // 1 if cosmological sim, 0 if not
my_units.density_units = 1.67e-24; // 1 m_H/cc
my_units.length_units = 3.086e21; // 1 kpc
my_units.time_units = 3.15569e13; // 1 Myr
my_units.velocity_units = my_units.length_units / my_units.time_units;
my_units.a_units = 1.0; // units for the expansion factor
my_units.a_value = 1. / (1. + current_redshift) / my_units.a_units;
If comoving_coordinates
is set to 1, it is assumed that the fields being
passed to the solver are in the comoving frame. Hence, the units must
convert from code units in the comoving frame to CGS in the proper
frame.
Note
With comoving_coordinate
set to 1, velocity units need to be
defined in the following way.
my_units.velocity_units = my_units.a_units *
(my_units.length_units / a_value) / my_units.time_units; // since u = a * dx/dt
For an example of using comoving units, see the units system in the
Enzo code. For cosmological simualations, a
comoving unit system is preferred, though not required, since it allows the
densities to stay close to 1.0.
Chemistry Data
The main Grackle header file contains a structure of type
chemistry_data
called grackle_data
, which contains all of the
parameters that control the behavior of the solver. The routine,
set_default_chemistry_parameters()
is responsible for the initial setup
of this structure and for setting of all the default parameter values. This
function must be handed a pointer to an instance of chemistry_data
,
which will then be attached to grackle_data
. The function will return an
integer indicating success (1) or failure (0). After this, parameters can then
be set to their desired values by accessing grackle_data
. See
Parameters and Data Files for a full list of the available parameters.
-
chemistry_data
This structure holds all grackle run-time parameters, which are listed in
Parameters and Data Files.
-
chemistry_data_storage
This structure holds all chemistry and cooling rate arrays. All functions
described here make use of an internally stored instance of this type.
The user will not normally encounter this data type, except when using the
Internal Functions.
chemistry_data *my_grackle_data;
my_grackle_data = new chemistry_data;
if (set_default_chemistry_parameters(my_grackle_data) == 0) {
fprintf(stderr, "Error in set_default_chemistry_parameters.\n");
}
// Set parameter values for chemistry.
// Now access the global copy of the chemistry_data struct (grackle_data).
grackle_data->use_grackle = 1; // chemistry on
grackle_data->with_radiative_cooling = 1; // cooling on
grackle_data->primordial_chemistry = 3; // molecular network with H, He, D
grackle_data->metal_cooling = 1; // metal cooling on
grackle_data->UVbackground = 1; // UV background on
grackle_data->grackle_data_file = "CloudyData_UVB=HM2012.h5"; // data file
Once the desired parameters have been set, the chemistry and cooling rates
must be initialized by calling initialize_chemistry_data()
with a
pointer to the code_units
struct created earlier. This function
will return an integer indicating success (1) or failure (0).
// Set initial expansion factor (for internal units).
// Set expansion factor to 1 for non-cosmological simulation.
double initial_redshift = 100.;
double a_value = 1. / (1. + initial_redshift) / my_units.a_units;
// Finally, initialize the chemistry object.
if (initialize_chemistry_data(&my_units) == 0) {
fprintf(stderr, "Error in initialize_chemistry_data.\n");
return 0;
}
The Grackle is now ready to be used.
Running with OpenMP
As of version 2.2, Grackle can be run with OpenMP parallelism. To do this,
the library must first be compiled with OpenMP support enabled by issuing the
command, “make omp-on”, before compiling. See Compiler Settings for
more information on how to change settings.
For an example of how to compile your code with OpenMP, see the
cxx_omp_example.C code example (Example Executables). Once your code has
been compiled with OpenMP enabled, the number of threads used can be controlled
by setting the omp_nthreads
parameter, stored in the grackle_data
struct.
// 8 threads per process
grackle_data->omp_nthreads = 8;
If not set, this parameter will be set to the maximum number of threads
possible, as determined by the system or as configured by setting the
OMP_NUM_THREADS
environment variable.
Creating the Necessary Fields
As of version 3.0, the various density and energy fields are passed to
Grackle’s functions using a struct of type grackle_field_data
.
The struct contains information about the size and shape of the field arrays
and pointers to all field arrays.
-
grackle_field_data
This structure is used to pass field data to Grackle’s functions. It
contains the following members:
-
int
grid_rank
The active dimensions (not including ignored boundary zones) of the field
arrays.
-
int*
grid_dimension
This should point to an array of size grid_rank
. This stores
the size of the field arrays in each dimension.
-
int*
grid_start
This should point to an array of size grid_rank
. This stores
the starting value in each dimension for the field data. This can be
used to ignore boundary cells in grid data.
-
int*
grid_end
This should point to an array of size grid_rank
. This stores
the end value in each dimension for the field data. This can be used
to ignore boundary cells in grid data.
-
gr_float*
density
Pointer to the density field array.
-
gr_float*
HI_density
Pointer to the HI density field array. Used when
primordial_chemistry
is set to 1, 2, or 3.
-
gr_float*
HII_density
Pointer to the HII density field array. Used when
primordial_chemistry
is set to 1, 2, or 3.
-
gr_float*
HM_density
Pointer to the H- density field array. Used when
primordial_chemistry
is set to 2 or 3.
-
gr_float*
HeI_density
Pointer to the HeI density field array. Used when
primordial_chemistry
is set to 1, 2, or 3.
-
gr_float*
HeII_density
Pointer to the HeII density field array. Used when
primordial_chemistry
is set to 1, 2, or 3.
-
gr_float*
HeIII_density
Pointer to the HeIII density field array. Used when
primordial_chemistry
is set to 1, 2, or 3.
-
gr_float*
H2I_density
Pointer to the H2 density field array. Used when
primordial_chemistry
is set to 2 or 3.
-
gr_float*
H2II_density
Pointer to the H2+ density field
array. Used when primordial_chemistry
is set to
2 or 3.
-
gr_float*
DI_density
Pointer to the DI density field array. Used when
primordial_chemistry
is set to 3.
-
gr_float*
DII_density
Pointer to the DII density field array. Used when
primordial_chemistry
is set to 3.
-
gr_float*
HDI_density
Pointer to the HD density field array. Used when
primordial_chemistry
is set to 3.
-
gr_float*
e_density
Pointer to the electron density field array. Used when
primordial_chemistry
is set to 1, 2, or 3. Note,
the electron mass density should be scaled by the ratio of the
proton mass to the electron mass such that the electron density
in the code is the electron number density times the proton
mass.
-
gr_float*
metal_density
Pointer to the metal density field array. Used when
metal_cooling
is set to 1.
-
gr_float*
internal_energy
Pointer to the internal energy field array.
-
gr_float*
x_velocity
Pointer to the x-velocity field array. Currently not used.
-
gr_float*
y_velocity
Pointer to the y-velocity field array. Currently not used.
-
gr_float*
z_velocity
Pointer to the z-velocity field array. Currently not used.
-
gr_float*
volumetric_heating_rate
Pointer to values containing volumetric heating rates. Rates
should be in units of erg/s/cm3. Used when
use_volumetric_heating_rate
is set to 1.
-
gr_float*
specific_heating_rate
Pointer to values containing specific heating rates. Rates
should be in units of erg/s/g. Used when
use_specific_heating_rate
is set to 1.
-
gr_float *
RT_heating_rate
Pointer to the radiation transfer heating rate field. Rates
should be in units of erg/s/cm3. Used when
use_radiative_transfer
is set to 1.
-
gr_float *
RT_HI_ionization_rate
Pointer to the HI photo-ionization rate field used with
radiative transfer. Rates should be in units of
1/time_units
. Used when
use_radiative_transfer
is set to 1.
-
gr_float *
RT_HeI_ionization_rate
Pointer to the HeI photo-ionization rate field used with
radiative transfer. Rates should be in units of
1/time_units
. Used when
use_radiative_transfer
is set to 1.
-
gr_float *
RT_HeII_ionization_rate
Pointer to the HeII photo-ionization rate field used with
radiative transfer. Rates should be in units of
1/time_units
. Used when
use_radiative_transfer
is set to 1.
-
gr_float *
RT_H2_dissociation_rate
Pointer to the H2 photo-dissociation rate field
used with radiative transfer. Rates should be in units of
1/time_units
. Used when
use_radiative_transfer
is set to 1 and
primordial_chemistry
is either 2 or 3.
It is not necessary to attach a pointer to any field that you do
not intend to use.
// Create struct for storing grackle field data
grackle_field_data my_fields;
// Set grid dimension and size.
// grid_start and grid_end are used to ignore ghost zones.
int field_size = 1;
my_fields.grid_rank = 3;
my_fields.grid_dimension = new int[3];
my_fields.grid_start = new int[3];
my_fields.grid_end = new int[3];
for (int i = 0;i < 3;i++) {
my_fields.grid_dimension[i] = 1;
my_fields.grid_start[i] = 0;
my_fields.grid_end[i] = 0;
}
my_fields.grid_dimension[0] = field_size;
my_fields.grid_end[0] = field_size - 1;
// Set field arrays.
my_fields.density = new gr_float[field_size];
my_fields.internal_energy = new gr_float[field_size];
my_fields.x_velocity = new gr_float[field_size];
my_fields.y_velocity = new gr_float[field_size];
my_fields.z_velocity = new gr_float[field_size];
// for primordial_chemistry >= 1
my_fields.HI_density = new gr_float[field_size];
my_fields.HII_density = new gr_float[field_size];
my_fields.HeI_density = new gr_float[field_size];
my_fields.HeII_density = new gr_float[field_size];
my_fields.HeIII_density = new gr_float[field_size];
my_fields.e_density = new gr_float[field_size];
// for primordial_chemistry >= 2
my_fields.HM_density = new gr_float[field_size];
my_fields.H2I_density = new gr_float[field_size];
my_fields.H2II_density = new gr_float[field_size];
// for primordial_chemistry >= 3
my_fields.DI_density = new gr_float[field_size];
my_fields.DII_density = new gr_float[field_size];
my_fields.HDI_density = new gr_float[field_size];
// for metal_cooling = 1
my_fields.metal_density = new gr_float[field_size];
// volumetric heating rate (provide in units [erg s^-1 cm^-3])
my_fields.volumetric_heating_rate = new gr_float[field_size];
// specific heating rate (provide in units [egs s^-1 g^-1]
my_fields.specific_heating_rate = new gr_float[field_size];
Note
The electron mass density should be scaled by the ratio of the
proton mass to the electron mass such that the electron density in the
code is the electron number density times the proton mass.
Calling the Available Functions
There are five functions available, one to solve the chemistry and cooling
and four others to calculate the cooling time, temperature, pressure, and the
ratio of the specific heats (gamma). The arguments required are the
code_units
structure and the grackle_field_data
struct.
For the chemistry solving routine, a timestep must also be given. For the
four field calculator routines, the array to be filled with the field values
must be created and passed as an argument as well.
Solve the Chemistry and Cooling
// some timestep (one million years)
double dt = 3.15e7 * 1e6 / my_units.time_units;
if (solve_chemistry(&my_units, &my_fields, dt) == 0) {
fprintf(stderr, "Error in solve_chemistry.\n");
return 0;
}
Calculating the Cooling Time
gr_float *cooling_time;
cooling_time = new gr_float[field_size];
if (calculate_cooling_time(&my_units, &my_fields,
cooling_time) == 0) {
fprintf(stderr, "Error in calculate_cooling_time.\n");
return 0;
}
Calculating the Temperature Field
gr_float *temperature;
temperature = new gr_float[field_size];
if (calculate_temperature(&my_units, &my_fields,
temperature) == 0) {
fprintf(stderr, "Error in calculate_temperature.\n");
return EXIT_FAILURE;
}
Calculating the Pressure Field
gr_float *pressure;
pressure = new gr_float[field_size];
if (calculate_pressure(&my_units, &my_fields,
pressure) == 0) {
fprintf(stderr, "Error in calculate_pressure.\n");
return EXIT_FAILURE;
}
Calculating the Gamma Field
gr_float *gamma;
gamma = new gr_float[field_size];
if (calculate_gamma(&my_units, &my_fields,
gamma) == 0) {
fprintf(stderr, "Error in calculate_gamma.\n");
return EXIT_FAILURE;
}
Parameters and Data Files
Parameters
For all on/off integer flags, 0 is off and 1 is on.
-
int
use_grackle
Flag to activate the grackle machinery. Default: 0.
-
int
with_radiative_cooling
Flag to include radiative cooling and actually update the thermal
energy during the chemistry solver. If off, the chemistry species
will still be updated. The most common reason to set this to off
is to iterate the chemistry network to an equilibrium state.
Default: 1.
-
int
primordial_chemistry
Flag to control which primordial chemistry network is used.
Default: 0.
- 0: no chemistry network. Radiative cooling for primordial
species is solved by interpolating from lookup tables
calculated with Cloudy.
- 1: 6-species atomic H and He. Active species: H, H+,
He, He+, ++, e-.
- 2: 9-species network including atomic species above and species
for molecular hydrogen formation. This network includes
formation from the H- and H2+
channels, three-body formation (H+H+H and H+H+H2),
H2 rotational transitions, chemical heating, and
collision-induced emission (optional). Active species: above +
H-, H2, H2+.
- 3: 12-species network include all above plus HD rotation cooling.
Active species: above + D, D+, HD.
Note
In order to make use of the non-equilibrium chemistry
network (primordial_chemistry
options 1-3), you must add
and advect baryon fields for each of the species used by that
particular option.
-
int
h2_on_dust
Flag to enable H2 formation on dust grains, dust cooling, and
dust-gas heat transfer follow Omukai (2000). This assumes
that the dust to gas ratio scales with the metallicity. Default: 0.
-
int
metal_cooling
Flag to enable metal cooling using the Cloudy tables. If enabled, the
cooling table to be used must be specified with the
grackle_data_file
parameter. Default: 0.
Note
In order to use the metal cooling, you must add and advect a
metal density field.
-
int
cmb_temperature_floor
Flag to enable an effective CMB temperature floor. This is implemented
by subtracting the value of the cooling rate at TCMB from the
total cooling rate. Default: 1.
-
int
UVbackground
Flag to enable a UV background. If enabled, the cooling table to be
used must be specified with the grackle_data_file
parameter.
Default: 0.
-
char*
grackle_data_file
Path to the data file containing the metal cooling and UV background
tables. Default: “”.
-
float
Gamma
The ratio of specific heats for an ideal gas. A direct calculation
for the molecular component is used if primordial_chemistry
> 1. Default: 5/3.
-
int
three_body_rate
Flag to control which three-body H2 formation rate is used.
The first five options are discussed in Turk et. al. (2011). Default: 0.
-
int
cie_cooling
Flag to enable H2 collision-induced emission cooling from
Ripamonti & Abel (2004). Default: 0.
-
int
h2_optical_depth_approximation
Flag to enable H2 cooling attenuation from Ripamonti &
Abel (2004).
Default: 0.
-
int
photoelectric_heating
Flag to enable a spatially uniform heating term approximating
photo-electric heating from dust from Tasker & Bryan (2008). Default: 0.
-
int
photoelectric_heating_rate
If photoelectric_heating
enabled, the heating rate in
units of erg cm-3 s-1. Default: 8.5e-26.
-
int
Compton_xray_heating
Flag to enable Compton heating from an X-ray background following
Madau & Efstathiou (1999). Default: 0.
-
float
LWbackground_intensity
Intensity of a constant Lyman-Werner H2 photo-dissociating
radiation field in units of 10-21 erg s-1 cm-2 Hz-1 sr-1. Default: 0.
-
int
LWbackground_sawtooth_suppression
Flag to enable suppression of Lyman-Werner flux due to Lyman-series
absorption (giving a sawtooth pattern), taken from Haiman & Abel,
& Rees (2000).
Default: 0.
-
int
use_volumetric_heating_rate
Flag to signal that an array of volumetric heating rates is being
provided in the volumetric_heating_rate
field of the
grackle_field_data
struct. Default: 0.
-
int
use_specific_heating_rate
Flag to signal that an array of specific heating rates is being
provided in the specific_heating_rate
field of the
grackle_field_data
struct. Default: 0.
-
use_radiative_transfer
Flag to signal that arrays of ionization and heating rates from
radiative transfer solutions are being provided. Only
available if primordial_chemistry
is greater than 0. HI, HeI,
and HeII ionization arrays are provided in RT_HI_ionization_rate
,
RT_HeI_ionization_rate
, and RT_HeII_ionization_rate
fields, respectively, of the grackle_field_data
struct.
Associated heating rate is provided in the RT_heating_rate
field, and H2 photodissociation rate can also be provided in the
RT_H2_dissociation_rate
field when
primordial_chemistry
is set to either 2 or 3. Default: 0.
-
radiative_transfer_coupled_rate_solver
Flag that must be enabled to couple the passed radiative transfer
fields to the chemistry solver. Default: 0.
-
radiative_transfer_intermediate_step
Flag to enable intermediate stepping in applying radiative transfer
fields to chemistry solver. Default: 0.
-
radiative_transfer_hydrogen_only
Flag to only use hydrogen ionization and heating rates from the
radiative transfer solutions. Default: 0.
-
self_shielding_method
Switch to enable approximate self-shielding from the UV background.
All three of the below methods incorporate Eq. 13 and 14 from
Rahmati et. al. 2013.
These equations involve using the spectrum averaged photoabsorption cross
for the given species (HI or HeI). These redshift dependent values are
pre-computed for the HM2012 and FG2011 UV backgrounds and included in
their respective cooling data tables. Care is advised in using any of
these methods. Default: 0.
-
int
omp_nthreads
Sets the number of OpenMP threads. If not set, this will be set to
the maximum number of threads possible, as determined by the system
or as configured by setting the OMP_NUM_THREADS
environment
variable. Note, Grackle must be compiled with OpenMP support
enabled. See Running with OpenMP.
Data Files
All data files are located in the input directory in the source.
The first three files contain the heating and cooling rates for both
primordial and metal species as well as the UV background photo-heating
and photo-ionization rates. For all three files, the valid density and
temperature range is given below. Extrapolation is performed when
outside of the data range. The metal cooling rates are stored for
solar metallicity and scaled linearly with the metallicity of the gas.
Valid range:
- number density: -10 < log10 (nH / cm-3) < 4
- temperature: the temperature range is 1 < log10 (T / K) < 9.
Data files:
- CloudyData_noUVB.h5 - cooling rates for collisional ionization
equilibrium.
- CloudyData_UVB=FG2011.h5 - heating and cooling rates and UV
background rates from the work of Faucher-Giguere et. al. (2009), updated in 2011.
The maxmimum redshift is 10.6. Above that, collisional ionization
equilibrium is assumed.
- CloudyData_UVB=HM2012.h5 - heating and cooling rates and UV
background rates from the work of Haardt & Madau (2012). The maximum
redshift is 15.13. Above that, collisional ionization equilibrium is
assumed.
The final file includes only metal cooling rates under collisional
ionization equilibrium, i.e., no incident radiation field. This table
extends to higher densities and also varies in metallicity rather than
scaling proportional to the solar value. This captures the
thermalization of metal coolants occuring at high densities, making this
table more appropriate for simulations of collapsing gas-clouds.
Valid range:
- number density: -6 < log10 (nH / cm-3) < 12
- metallicity: -6 < log10 (Z / Zsun) < 1
- temperature: the temperature range is 1 < log10 (T / K) < 8.
Data file:
- cloudy_metals_2008_3D.h5 - collisional ionization equilibrium,
metal cooling rates only.
Pygrackle: Running Grackle in Python
Grackle comes with a Python interface, called Pygrackle, which provides
access to all of Grackle’s functionality. Pygrackle requires the following
Python packages:
The easiest thing to do is follow the instructions for installing yt,
which will provide you with Cython, matplotlib, and NumPy. Flake8 and
py.test can then be installed via pip.
Installing Pygrackle
Once the Grackle library has been built and the above dependencies have been
installed, Pygrackle can be installed by moving into the src/python
directory and running python setup.py install
.
~/grackle $ cd src/python
~/grackle/src/python $ python setup.py install
Note
Pygrackle can only be run when Grackle is compiled without OpenMP.
See Running with OpenMP.
Running the Example Scripts
A number of example scripts are available in the src/python/examples
directory. These scripts provide examples of ways that Grackle can be
used in simplified models, such as solving the temperature evolution of
a parcel of gas at constant density or in a free-fall model. Each example
will produce a figure as well as a dataset that can be loaded and analyzed
with yt.
Cooling Cell Example
This sets up a single grid cell with an initial density and temperature and solves
the chemistry and cooling for a given amount of time. The resulting dataset gives
the values of the densities, temperatures, and mean molecular weights for all times.
>>> import yt
>>> ds = yt.load("cooling_cell.h5")
>>> print ds.data["time"].to("Myr")
YTArray([ 0.00000000e+00, 6.74660169e-02, 1.34932034e-01, ...,
9.98497051e+01, 9.99171711e+01, 9.99846371e+01]) Myr
>>> print ds.data["temperature"]
YTArray([ 990014.56406726, 980007.32720091, 969992.99066987, ...,
9263.81515866, 9263.81515824, 9263.81515865]) K
Free-Fall Collapse Example
This sets up a single grid cell with an initial number density of 1 cm-3.
The density increases with time following a free-fall collapse model. As the density
increases, thermal energy is added to model heating via adiabatic compression.
This can be useful for testing chemistry networks over a large range in density.
The resulting dataset can be analyzed similarly as above.
>>> import yt
>>> ds = yt.load("freefall.h5")
>>> print ds.data["time"].to("Myr")
[ 0. 0.45900816 0.91572127 ..., 219.90360841 219.90360855
219.9036087 ] Myr
>>> print ds.data["density"]
[ 1.67373522e-25 1.69059895e-25 1.70763258e-25 ..., 1.65068531e-12
1.66121253e-12 1.67178981e-12] g/cm**3
>>> print ds.data["temperature"]
[ 99.94958248 100.61345564 101.28160228 ..., 1728.89321898
1729.32604568 1729.75744287] K
Simulation Dataset Example
This provides an example of using the grackle library for calculating chemistry and
cooling quantities for a pre-existing simulation dataset. To run this example, you
must also download the IsolatedGalaxy dataset from the yt sample data page.
How to Develop Grackle
Grackle is a community project!
We are very happy to accept patches, features, and bugfixes from any member of
the community! Grackle is developed using mercurial, primarily because it
enables very easy and straightforward submission of changesets. We’re eager to
hear from you.
Note
If you already know how to use the mercurial version control system and are comfortable with handling it yourself,
the quickest way to contribute to Grackle is to fork us on BitBucket, make your changes, push the
changes to your fork and issue a pull request. The rest of this
document is just an explanation of how to do that.
Keep in touch, and happy hacking!
Open Issues
If you’re interested in participating in Grackle development, take a look at the
issue tracker on bitbucket. If you are
encountering a bug that is not already tracked there, please open a new issue.
Submitting Changes
We provide a brief introduction to submitting changes here. We encourage
contributions from any user. While we do not discuss version control, mercurial
or the advanced usage of BitBucket in detail here, we do provide an outline of
how to submit changes and we are happy to provide further assistance or
guidance on the mailing list.
Licensing
Grackle is under the Enzo public license, a BSD-like license.
All contributed code must be BSD-compatible. If you’d rather not license in
this manner, but still want to contribute, please consider creating an external
package, which we’ll happily link to in the Grackle documentation.
How To Get The Source Code For Editing
Grackle is hosted on BitBucket, and you can see all of the Grackle repositories at
http://bitbucket.org/grackle/. In order to modify the source code for Grackle,
we ask that you make a “fork” of the main Grackle repository on bitbucket. A
fork is simply an exact copy of the main repository (along with its history)
that you will now own and can make modifications as you please. You can create
a personal fork by visiting the Grackle bitbucket webpage at
https://bitbucket.org/grackle/grackle/ . After logging in, you should see an
option near the top right labeled “fork”. Click this option, and then click the
fork repository button on the subsequent page. You now have a forked copy of
the Grackle repository for your own personal modification.
This forked copy exists on the bitbucket repository, so in order to access
it locally, follow the instructions at the top of that webpage for that
forked repository, namely run at a local command line:
$ hg clone http://bitbucket.org/<USER>/<REPOSITORY_NAME>
This downloads that new forked repository to your local machine, so that you can
access it, read it, make modifications, etc. It will put the repository in a
local directory of the same name as the repository in the current working
directory. You should also run the following command, to make sure you have the
most up-to-date version of Grackle checked out in your working directory.
You can see any past state of the code by using the hg log command.
For example, the following command would show you the last 5 changesets
(modifications to the code) that were submitted to that repository.
$ cd <REPOSITORY_NAME>
$ hg log -l 5
Using the revision specifier (the number or hash identifier next to each
changeset), you can update the local repository to any past state of the
code (a previous changeset or version) by executing the command:
$ hg update revision_specifier
How to Use Mercurial with Grackle
If you’re new to Mercurial, these three resources are pretty great for learning
the ins and outs:
The commands that are essential for using mercurial include:
hg help
which provides help for any mercurial command. For example, you
can learn more about the log
command by doing hg help log
. Other useful
topics to use with hg help
are hg help glossary
, hg help config
,
hg help extensions
, and hg help revsets
.
hg commit
which commits changes in the working directory to the
repository, creating a new “changeset object.”
hg add
which adds a new file to be tracked by mercurial. This does
not change the working directory.
hg pull
which pulls (from an optional path specifier) changeset
objects from a remote source. The working directory is not modified.
hg push
which sends (to an optional path specifier) changeset objects
to a remote source. The working directory is not modified.
hg log
which shows a log of all changeset objects in the current
repository. Use -G
to show a graph of changeset objects and their
relationship.
hg update
which (with an optional “revision” specifier) updates the
state of the working directory to match a changeset object in the
repository.
hg merge
which combines two changesets to make a union of their lines
of development. This updates the working directory.
We are happy to asnswers questions about mercurial use on on the mailing list to
walk you through any troubles you might have. Here are some general suggestions
for using mercurial:
- Named branches are to be avoided. Try using bookmarks (
see hg help
bookmark
) to track work. (More info about bookmarks is available on the
mercurial wiki)
- Make sure you set a username in your
~/.hgrc
before you commit any
changes! All of the tutorials above will describe how to do this as one of
the very first steps.
- Please avoid deleting your Grackle forks, as that deletes the pull request
discussion from process from BitBucket’s website, even if your pull request
is merged.
- You should only need one fork. See Making and Sharing Changes for a description of
the basic workflow.
Making and Sharing Changes
The simplest way to submit changes to Grackle is to do the following:
- Build Grackle from the mercurial repository
- Navigate to the root of the Grackle repository
- Make some changes and commit them
- Fork the Grackle repository on BitBucket
- Push the changesets to your fork
- Issue a pull request.
Here’s a more detailed flowchart of how to submit changes.
Edit the source file you are interested in and test your changes.
Fork Grackle on BitBucket. (This step only has to be done once.) You can do
this at: https://bitbucket.org/grackle/grackle/fork. Call this repository
grackle.
Create a bookmark to track your work. For example: hg bookmark
my-first-pull-request
Commit these changes, using hg commit
. This can take an argument
which is a series of filenames, if you have some changes you do not want
to commit.
Remember that this is a large development effort and to keep the code
accessible to everyone, good documentation is a must. Add in source code
comments for what you are doing. Add in docstrings
if you are adding a new function or class or keyword to a function.
Add documentation to the appropriate section of the online docs so that
people other than yourself know how to use your new code.
If your changes include new functionality or cover an untested area of the
code, add a test. Commit these changes as well.
Push your changes to your new fork using the command:
hg push -B my-first-pull-request https://bitbucket.org/YourUsername/grackle/
Where you should substitute the name of the bookmark you are working on for
my-first-pull-request
. If you end up doing considerable development, you
can set an alias in the file .hg/hgrc
to point to this path.
Note
Note that the above approach uses HTTPS as the transfer protocol
between your machine and BitBucket. If you prefer to use SSH - or
perhaps you’re behind a proxy that doesn’t play well with SSL via
HTTPS - you may want to set up an SSH key on BitBucket. Then, you use
the syntax ssh://hg@bitbucket.org/YourUsername/grackle
, or equivalent,
in place of https://bitbucket.org/YourUsername/grackle
in Mercurial
commands. For consistency, all commands we list in this document use the
HTTPS protocol.
Issue a pull request at
https://bitbucket.org/YourUsername/grackle/pull-request/new
A pull request is an automated way of asking people to review and accept the
modifications you have made to your personal version of the code.
During the course of your pull request you may be asked to make changes. These
changes may be related to style issues, correctness issues, or requesting
tests. The process for responding to pull request code review is relatively
straightforward.
Make requested changes, or leave a comment on the pull request page on
Bitbucket indicating why you don’t think they should be made.
Commit those changes to your local repository.
Push the changes to your fork:
Your pull request will be automatically updated.