Detailed pyFastChem module description¶
PyBind11, FastChem can be called directly
within Python. This requires the compilation of FastChem’s
Python wrapper that is located in the file
python/fastchem_python_wrapper.cpp. pyFastChem currently only
links to the long double C++ version of FastChem.CMake approach, pyFastChem will be automatically compiled when
cmake is configured with the corresponding option. If the
configuration and compilation is successful, a module file should be
present in the python/ folder that contains the Python module
which acts as a wrapper between Python and the C++ version of
FastChem. The file should be named pyfastchem.cpython-xxxx,
where xxxx will be a combination of your Python version and
operating system.pyFastChem has been built using the setup.py script or
installed via PyPI, then the module will be located in your normal
Python module library path. It, thus, can be accessed from everywhere
on your system like any other standard Python package. The location
and additional module information can be obtained viapip show pyfastchem
pip might need to be
replaced by pip3.The pyFastChem module provides access to the FastChem object
class as well as additional constants used within FastChem. They are
essentially identical to their C++ counterparts discussed here.
To include the pyFastChem module in your Python project, just import
it using
import pyfastchem
This provides access to the FastChem object class as well as the
input and output structures and additional pre-defined constants used by
FastChem.
pyFastChem constants¶
pyFastChem module contains a number of pre-defined constants.
This includes the constant pyfastchem.FASTCHEM_UNKNOWN_SPECIES of
type int that is returned by some pyFastChem methods when a
chemical species is not found.int defined as constants in the pyFastChem module:pyfastchem.FASTCHEM_SUCCESSIndicates that the calculation has been successful, i.e. that the chemistry iterations converged.
pyfastchem.FASTCHEM_NO_CONVERGENCEIndicates that the calculation was not successful, i.e. that the chemistry did not converge within the allowed maximum number of iterations steps given in the config file or set manually via the
setParametermethod together with thenbIterationsChemparameter (see here). One way to solve such a problem is to increase the maximum number of iteration steps.pyfastchem.FASTCHEM_INITIALIZATION_FAILEDIndicates that something went wrong during reading one of the input files. To find the source of the problem, one can set the verbose level in the config file or manually via
setVerboseLevel(see here) to a higher value and look at the terminal output.pyfastchem.FASTCHEM_IS_BUSYThe chemistry calculations of
FastChemcan only be called once for each object class instance. Attempting to start a new calculation while another is still running will result inFastChemreturning this flag.pyfastchem.FASTCHEM_WRONG_INPUT_VALUESFastChemreturns this flag if some input values are wrong. Currently, this refers to the temperature and pressure vectors in the input structure not having the same size (see here for details on the input structure).pyfastchem.FASTCHEM_PHASE_RULE_VIOLATIONFastChemreturns this flag if condensation is used and the system violates the phase rule. This happens when the number of elements contained in condensates equals the total number of elements. In this case, the gas phase lacks a degree of freedom to yield the correct gas pressure. Such a system cannot be solved as there has always to be at least one incondensable element in the gas phase (see the section about the phase rule in Paper III).
In addition to these flags, the pyFastChem module also includes a
constant string array pyfastchem.FASTCHEM_MSG that contains string
expressions for each of these flags. Using this array with any of the
aforementioned flags pyfastchen.FASTCHEM_MSG[flag] returns a string
with a description of the corresponding flag’s meaning. For example,
pyfastchem.FASTCHEM_MSG[pyfastchem.FASTCHEM_NO_CONVERGENCE]
will return the string "convergence failed".
pyFastChem constructor¶
FastChem is written as an object class, an instance of that
class (i.e. an object) needs to be created before FastChem can be
used. This is done by calling the constructor of the FastChem
class that is contained within the pyFastChem module. There are
three main ways to call the constructor and create an object.pyfastchem.FastChem(str element_abundance_file,
str gas_species_data_file,
int verbose_level)
This constructor requires three parameters: the locations of the element abundance and gas phase species data files, as well as the verbose level. All other options and parameters within
FastChemwill be set to their default values but can be later changed by using the appropriate methods described here. The default maximum number of chemistry iterations is 3000, the number of Newton, bisection and Nelder-Mead method iterations is 3000, and the default accuracy of the of Newton method and the chemistry iterations is set to \(10^{-4}\). This constructor will not read in any condensate data. Trying to use an object created via this method for a calculation using condensation will result in an error message.
pyfastchem.FastChem(str element_abundance_file,
str gas_species_data_file,
str condensate_species_data_file,
int verbose_level)
This constructor requires four parameters: the locations of the element abundance and gas phase species data files, the condensate data file, as well as the verbose level. All other options and parameters within
FastChemwill be set to their default values but can be later changed by using the appropriate methods described here. The default maximum number of chemistry iterations is 3000, the number of Newton, bisection and Nelder-Mead method iterations is 3000, and the default accuracy of the of Newton method and the chemistry iterations is set to \(10^{-4}\). Note that instead of a location for the condensate data, astrcontaining'none'can be used here as well. In that case, no condensate data will be read in and trying to use the object for a calculation using condensation will result in an error message.
pyfastchem.FastChem(str parameter_file,
int intial_verbose_level)
The constructor requires two different arguments: the location of the parameter file and the initial verbose level. The latter one will be replaced by the corresponding value read in from the parameter file. The structure of this parameter file is discussed here. All of parameter values read in from the file can also be adjusted during runtime by using the methods listed here.
pyFastChem input and output structures¶
Running a FastChem chemistry calculation requires input and output data
structures, resembling those of the C++ version.
In Python they are represented as classes rather than a C++struct.
Input structure¶
The original C++ struct translated by PyBind11 has the following
structure in Python:
class FastChemInput:
temperature: list[float] = []
pressure: list[float] = []
equilibrium_condensation = False
rainout_condensation = False
The input class contains the following variables:
temperatureAn array of
floatnumbers that describe the temperature in K.pressureAn array of
floatnumbers that describe the pressure in bar.equilibrium_condensationA
boolparameter that enables the calculation of equilibrium condensation. Its default value isFalse.rainout_condensationA
boolparameter that enables the calculation of condensation via the rainout approximation. Its default value isFalse. Note that when the flagrainout_condensationis set toTrue, the value of the parameterequilibrium_condensationis ignored.
An input structure, in the example here called input_data, can be
defined from the pyFastChem module in the following way:
input_data = pyfastchem.FastChemInput()
The two input arrays for temperature and pressure need to have the same
length. The PyBind11 library allows normal Python lists or NumPy
arrays to be used here. For example, a NumPy array for the pressure
could be defined using NumPy’s logspace function:
input_data.pressure = np.logspace(-6, 1, num=1000)
Both of these input variables need to be an array-type variable, even if only a single temperature-pressure point is going to be calculated.
Output structure¶
The original C++ output struct translated by PyBind11 has the
following structure in Python:
class FastChemOutput:
number_densities: list[list[float]]
total_element_density: list[float]
mean_molecular_weight: list[float]
number_densities_cond: list[list[float]]
element_cond_degree: list[list[float]]
element_conserved: list[list[int]]
nb_chemistry_iterations: list[int]
nb_cond_iterations: list[int]
nb_iterations: list[int]
fastchem_flag: list[int]
It has the following variables:
number_densitiesThe two-dimensional array contains the number densities in of all gas phase species (elements, molecules, ions) as
floatnumbers. The first dimension refers to the temperature-pressure grid and has the same size as the temperature and pressure arrays of the input structure. The second dimension refers to the number of species and has a length ofgetGasSpeciesNumber()(see here).total_element_densityOne-dimensional array of
floatnumbers that contains the total number density of all atoms \(j\), i.e. \(n_\mathrm{tot} = \sum_j \left( n_j + \sum_i \nu_{ij} n_i + \sum_c \nu_{cj} n_c \right)\), summed over their atomic number densities, as well as the ones contained in all other molecules/ions \(j\) and condensates \(c\). This quantity is usually only a diagnostic output and not relevant for other calculations. The dimension of the array is equal to that of the input temperature and pressure vectors.mean_molecular_weightOne-dimensional array of
floatnumbers. Contains the mean molecular weight of the mixture in units of the unified atomic mass unit. For all practical purposes, this can also be converted into units of g/mol. The dimension of the array is equal to that of the input temperature and pressure vectors.number_densities_condThe two-dimensional array contains the fictitious number densities in of all condensate species as
floatnumbers. The first dimension refers to the temperature-pressure grid and has the same size as the temperature and pressure arrays of the input structure. The second dimension refers to the number of species and has a length ofgetCondSpeciesNumber()(see here).element_cond_degreeThe two-dimensional array contains the degree of condensation for all elements. The first dimension refers to the temperature-pressure grid and has the same size as the temperature and pressure vectors of the input structure. The second dimension refers to the number of elements and has a length of
getElementNumber()(see here).element_conservedThe two-dimensional array of
intnumbers contains information on the state of element conservation. A value of 0 indicates that element conservation is not fulfilled, whereas a value of 1 means that the element has been conserved. The first dimension refers to the temperature-pressure grid and has the same size as the temperature and pressure vectors of the input structure. The second dimension refers to the number of elements and has a length ofgetElementNumber()(see here).nb_chemistry_iterationsOne-dimensional array of
intnumbers. Contains the total number of chemistry iterations that were required to solve the system for each temperature-pressure point. The dimension of the array is equal to that of the input temperature and pressure vectors.nb_cond_iterationsOne-dimensional array of
intnumbers. Contains the total number of condensate calculation iterations that were required for each temperature-pressure point. The dimension of the array is equal to that of the input temperature and pressure vectors.nb_iterationsOne-dimensional array of
intnumbers. Contains the total number of coupled condensation-gas phase chemistry calculation iterations that were required to solve the system for each temperature-pressure point. The dimension of the vector is equal to that of the input temperature and pressure vectors.fastchem_flagOne-dimensional array of
intnumbers. Contains flags that give information on potential issues of the chemistry calculation for each temperature-pressure point. The set of potential values is stated here. A string message for each corresponding flag can also be obtained from the constantpyfastchem.FASTCHEM_MSGvector of strings, viapyfastchem.FASTCHEM_MSG[flag]. The dimension of the array is equal to that of the input temperature and pressure vectors.
The output structure from the pyFastChem module, in the example here
called output_data, can be defined in the following way:
output_data = pyfastchem.FastChemOutput()
The arrays of the output structure don’t need to be pre-allocated. This
will be done internally within FastChem when running the chemistry
calculations. If the arrays already contain data, their contents will be
overwritten. The arrays from the output structure can also be easily
converted to more practical NumPy arrays by using, for example:
number_densities = np.array(output_data.number_densities)
pyFastChem functions¶
pyFastChem object returned from pyfastchem.FastChem() has
several methods that allow to interact with FastChem. These
methods are equivalent to those of the C++ object class discussed
here.unsigned int
parameter variable in their original C++ version. Since this data type doesn’t exist
in Python, PyBind11 will convert the supplied int value to its unsigned integer
version for C++. Even though the parameter is defined as an int value for Python,
only positive numbers, including 0, are accepted as valid input. Using a negative
value will result in an error message from PyBind11.int calcDensities(pyfastchem.FastChemInput() input,
pyfastchem.FastChemOutput() output)
Starts a chemistry calculation with the provided
pyfastchem.FastChemInput()andpyfastchem.FastChemOutput()structures. Returns anintvalue that represents the highest value from the flag vector within thepyfastchem.FastChemOutput()structure.
setParameter(str param_name,
param_type param_value)
Sets an internal
FastChemparameter. Depending on the parameter, the variable typeparam_typecan either be anint, abool, or afloatvalue. A list of parameters and their types can be found here. TheC++doubletypes listed there should be replaced by Pythonfloatvalues, whileunsigned intare used asint.PyBind11often converts the Pythonbooltype to an integer value rather than aC++booltype. Setting a boolean parameter will then result in an error message. In such a case, instead of using a simpleTrueas parameter value, an explicit conversion has to be done instead, for example vianp.bool_(True).
int getGasSpeciesNumber()
Returns the total number of gas phase species (atoms, ions, molecules) as
intvalue.
int getElementNumber()
Returns the total number of elements as
intvalue.
int getMoleculeNumber()
Returns the total number of molecules and ions (anything other than elements) as
intvalue.
int getCondSpeciesNumber()
Returns the total number of condensate species as
intvalue.
str getGasSpeciesName(int species_index)
Returns the name of a gas phase species with
intindexspecies_indexasstr; returns empty string if species does not exist.
str getGasSpeciesSymbol(int species_index)
Returns the symbol of an element or the formula of a molecule/ion with
intindexspecies_indexasstr; returns empty string if species does not exist
int getGasSpeciesIndex(str symbol)
Returns the index of a gas phase species (element/molecule/ion) with
strsymbol/formulasymbolasint; returns the constantpyfastchem.FASTCHEM_UNKOWN_SPECIESif species does not exist.
str getElementName(int species_index)
Returns the name of an element with
intindexspecies_indexasstr; returns empty string if species does not exist.
str getElementSymbol(int species_index)
Returns the symbol of an element with
intindexspecies_indexasstr; returns empty string if species does not exist
int getElementIndex(str symbol)
Returns the index of an element with
strsymbol/formulasymbolasint; returns the constantpyfastchem.FASTCHEM_UNKOWN_SPECIESif species does not exist.
str getCondSpeciesName(int species_index)
Returns the name of a condensate species with
intindexspecies_indexasstr; returns empty string if species does not exist.
str getCondSpeciesSymbol(int species_index)
Returns the formula of a condensate with
intindexspecies_indexasstr; returns empty string if species does not exist
int getCondSpeciesIndex(str symbol)
Returns the index of a condensate species with
strsymbol/formulasymbolasint; returns the constantpyfastchem.FASTCHEM_UNKOWN_SPECIESif species does not exist.
float getElementAbundance(int species_index)
Returns the abundance of an element with int index species_index as float; returns 0 if the element does not exist
float [] getElementAbundance()
Returns the abundances of all elements as an array of
floatvalues; array has a length ofgetElementNumber()
setElementAbundances(float [] abundances)
Sets the abundances of all elements; the abundances are supplied as an array of
floatvalues, where the array has to have a size ofgetElementNumber(); if this is not the case,FastChemwill print an error message and leave the element abundances unchanged
float getGasSpeciesWeight(int species_index)
Returns the weight of a gas phase species with
intindexspecies_indexasfloat; returns 0 if species does not exist; for an element this refers to the atomic weight
float getElementWeight(int species_index)
Returns the atomic weight of an element with
intindexspecies_indexasfloat; returns 0 if species does not exist
float getCondSpeciesWeight(int species_index)
Returns the weight of a condensate species with
intindexspecies_indexasfloat; returns 0 if species does not exist
str convertToHillNotation(str formula)
Converts a chemical formula to the Hill notation that is used for the gas-phase species in
FastChem. For example,H2Owould be returned asH2O1. The conversion can also treat formulas with brackets, for example,Na(OH)2or ions, such asFe+orFe++. The latter two would be returned asFe1+andFe1++, respectively. Higher ionsation stages are supported via^, even though they are currently not included in the standardFastChemdata files. For example,Fe^3+would be returned asFe1^3+.
int [] getGasSpeciesStoichiometry(int species_index)
Returns a vector with the stoichiometric coefficients of a gas-phase species with
intindexspecies_index; array has a length ofgetElementNumber()
int [] getCondSpeciesStoichiometry(int species_index)
Returns a vector with the stoichiometric coefficients of a condensed-phase species with
intindexspecies_index; array has a length ofgetElementNumber()
setVerboseLevel(int level)
Sets the verbose level of
FastChem, i.e. the amount of text output in the terminal. A value of 0 will result inFastChembeing almost silent, whereas a value of 4 would provide a lot of debug output. A value larger than 4 will be interpreted as 4. This value will overwrite the one from theFastChemconfig file.