.. include:: defs.h .. _`Chp:Multispecies Unit`: Multispecies Unit ================= |flashx| has the ability to track multiple fluids, each of which can have its own properties. The ``Multispecies`` unit handles setting and querying on the properties of fluids, as well as some common operations on properties. The advection and normalization of species is described in the context of the Hydro unit in . .. _`Sec:defining_species`: Defining Species ---------------- The names and properties of fluids are accessed by using their constant integer values defined in the ``Simulation.h`` header file. The species names are defined in a ``Config`` file. The names of the species, for example ``AIR``, ``NI56``, are given in the ``Config`` file with keyword ``SPECIES``. In the traditional method for defining species, this ``Config`` would typically be the application’s ``Config`` file in the ``Simulation`` unit. In the alternative method described below in , ``SPECIES`` are normally not listed explicitly in the ``Simulation`` unit ``Config``, but instead are automatically generated by ``Multispecies/MultispeciesMain/Config`` based on the contents of the ``species`` setup variable. Either way, the ``setup`` procedure transforms those names into accessor integers with the appended description ``_SPEC``. These names are stored in the ``Simulation.h`` file. The total number of species defined is also defined within ``Simulation.h`` as ``NSPECIES``, and the integer range of their definition is given by ``SPECIES_BEGIN`` and ``SPECIES_END``. To access the species in your code, use the index listed in ``Simulation.h``, for example ``AIR_SPEC``, ``NI56_SPEC``. Note that ``NSPECIES``, ``SPECIES_BEGIN``, and ``SPECIES_END`` are always defined, whether a simulation uses multiple species or not (and whehter the simulation includes the ``Multispecies`` unit or not). However, if ``NSPECIES``\ :math:`=0`, ``SPECIES_END`` will be less than ``SPECIES_BEGIN``, and then neither of them should be used as an index into solution vectors. As an illustration, Figures  and are snippets from a configuration file and the corresponding section of the |flashx| header file, respectively. For more information on ``Config`` files, see ; for more information on the ``setup`` procedure, see ; for more information on the structure of the main header file ``Simulation.h``, see . .. container:: shrink .. container:: fcodeseg # Portion of a Config file for a Simulation SPECIES AIR SPECIES SF6 .. container:: shrink .. container:: fcodeseg #define SPECIES_BEGIN (NPROP_VARS + CONSTANT_ONE) #define AIR_SPEC 11 #define SF6_SPEC 12 #define NSPECIES 2 #define SPECIES_END (SPECIES_BEGIN + NSPECIES - CONSTANT_ONE) .. container:: flashtip In |flashx|, you found the integer index of a species by using ``find_fluid_index``. In |flashx|, the species index is always available because it is defined in ``Simulation.h``. Use the index directory, as in ``xIn(NAME_SPEC - SPECIES_BEGIN + 1) = solnData(NAME_SPEC,i,j,k)``. But be careful that the species name is really defined in your simulation! You can test with .. container:: codeseg if (NAME_SPEC /= NONEXISTENT) then okVariable = solnData(NAME_SPEC,i,j,k) endif The available properties of an individual fluid are listed in and are defined in file ``Multispecies.h``. In order to reference the properties in code, you must ``#include`` the file ``Multispecies.h``. The initialization of properties is described in the following section. .. container:: center .. container:: :name: Tbl:MultispeciesProperties .. table:: Properties available through the ``Multispecies`` unit. +---------------------+-----------------------------+----------------+ | **Property Name** | **Description** | **Data type** | +=====================+=============================+================+ | ``A`` | Number of protons and | real | | | neutrons in nucleus | | +---------------------+-----------------------------+----------------+ | ``Z`` | Atomic number | real | +---------------------+-----------------------------+----------------+ | ``N`` | Number of neutrons | real | +---------------------+-----------------------------+----------------+ | ``E`` | Number of electrons | real | +---------------------+-----------------------------+----------------+ | ``BE`` | Binding Energy | real | +---------------------+-----------------------------+----------------+ | ``GAMMA`` | Ratio of heat capacities | real | +---------------------+-----------------------------+----------------+ | ``MS_ZMIN`` | Minimum allowed average | real | | | ionization | | +---------------------+-----------------------------+----------------+ | ``MS_EOSTYPE`` | EOS type to use for MTMMMT | integer | | | EOS | | +---------------------+-----------------------------+----------------+ | ``MS_EOSSUBTYPE`` | EOS subtype to use for | integer | | | MTMMMT EOS | | +---------------------+-----------------------------+----------------+ | ``MS_EOSZFREEFILE`` | Name of file with | string | | | ionization data | | +---------------------+-----------------------------+----------------+ | ``MS_EOSENERFILE`` | Name of file with internal | string | | | energy data | | +---------------------+-----------------------------+----------------+ | ``MS_EOSPRESFILE`` | Name of file with pressure | string | | | data | | +---------------------+-----------------------------+----------------+ | ``MS_NUMELEMS`` | Number of elements | integer | | | comprising this species | | +---------------------+-----------------------------+----------------+ | ``MS_ZELEMS`` | Atomic number of each | array(integer) | | | species element | | +---------------------+-----------------------------+----------------+ | ``MS_AELEMS`` | Mass number of each species | array(real) | | | element | | +---------------------+-----------------------------+----------------+ | ``MS_FRACTIONS`` | Number fraction of each | array(real) | | | species element | | +---------------------+-----------------------------+----------------+ | ``MS_OPLOWTEMP`` | Temperature at which cold | real | | | opacities are used | | +---------------------+-----------------------------+----------------+ .. _`Sec:init_species`: Initializing Species Information in ``Simulation_initSpecies`` -------------------------------------------------------------- Before you can work with the properties of a fluid, you must initialize the data in the ``Multispecies`` unit. Normally, initialization is done in the routine ``Simulation/Simulation_initSpecies``. An example procedure is shown below and consists of setting relevant properties for all fluids/``SPECIES`` defined in the ``Config`` file. Fluids do not have to be isotopes; any molecular substance which can be defined by the properties shown in is a valid input to the Multispecies unit. .. container:: shrink .. container:: codeseg subroutine Simulation_initSpecies() implicit none #include "Multispecies.h" #include "Simulation.h" ! These two variables are defined in the Config file as ! SPECIES SF6 and SPECIES AIR call Multispecies_setProperty(SF6_SPEC, A, 146.) call Multispecies_setProperty(SF6_SPEC, Z, 70.) call Multispecies_setProperty(SF6_SPEC, GAMMA, 1.09) call Multispecies_setProperty(AIR_SPEC, A, 28.66) call Multispecies_setProperty(AIR_SPEC, Z, 14.) call Multispecies_setProperty(AIR_SPEC, GAMMA, 1.4) end subroutine Simulation_initSpecies .. container:: flashtip For nuclear burning networks, a ``Simulation_initSpecies`` routine is already predefined. It automatically initializes all isotopes found in the ``Config`` file. To use this shortcut, ``REQUIRE`` the module ``Simulation/SimulationComposition`` in the ``Config`` file. .. _`Sec:constelems`: Specifying Constituent Elements of a Species -------------------------------------------- A species can represent a specific isotope or a single element or a more complex material. Some units in |flashx| require information about the elements that constitute a single species. For example, water is comprised of two elements: Hydrogen and Oxygen. The ``Multispecies`` database can store a list of the atomic numbers, mass numbers, and relative number fractions of each of the elements within a given species. This information is stored in the array properties ``MS_ZELEMS``, ``MS_AELEMS``, and ``MS_FRACTIONS`` respectively. The property ``MS_NUMELEMS`` contains the total number of elements for a species (``MS_NUMELEMS`` would be two for water since water is made of Hydrogen and Oxygen). There is an upper bound on the number of elements for a single species which is defined using the preprocessor symbol ``MS_MAXELEMS`` in the “Simulation.h” header file and defaults to six. The value of ``MS_MAXELEMS`` can be changed using the ``ms_maxelems`` setup variable. shows an example of how the constituent elements for water can be set using the ``Simulation_initSpecies`` subroutine. The constituent element information is optional and is only needed if a particular unit of interest requires it. At present, only the analytic cold opacities used in the ``Opacity`` unit make use of the constituent element information. .. container:: shrink .. container:: codeseg #include "Simulation.h" #include "Multispecies.h" ! Create arrays to store constituent element data. Note that these ! arrays are always of length MS_MAXELEMS. real :: aelems(MS_MAXELEMS) real :: fractions(MS_MAXELEMS) integer :: zelems(MS_MAXELEMS) call Multispecies_setProperty(H2O_SPEC, A, 18.0/3.0) ! Set average mass number call Multispecies_setProperty(H2O_SPEC, Z, 10.0/3.0) ! Set average atomic number call Multispecies_setProperty(H2O_SPEC, GAMMA, 5.0/3.0) call Multispecies_setProperty(H2O_SPEC, MS_NUMELEMS, 2) aelems(1) = 1.0 ! Hydrogen aelems(2) = 16.0 ! Oxygen call Multispecies_setProperty(H2O_SPEC, MS_AELEMS, aelems) zelems(1) = 1 ! Hydrogen zelems(2) = 8 ! Oxygen call Multispecies_setProperty(H2O_SPEC, MS_ZELEMS, zelems) fractions(1) = 2.0/3.0 ! Two parts Hydrogen fractions(2) = 1.0/3.0 ! One part Oxygen call Multispecies_setProperty(H2O_SPEC, MS_FRACTIONS, fractions) .. _`Sec:DefineSpecies2`: Alternative Method for Defining Species --------------------------------------- described how species can be defined by using the ``SPECIES`` keyword in the ``Config`` file. then described how the properties of the species can be set using various subroutines defined in the ``Multispecies`` unit. There is an alternative to these approaches which uses setup variables to define the species, then uses runtime parameters to set the properties of each species. This allows users to change the number and names of species without modifying the ``Config`` file and also allows users to change properties without recompiling the code. Species can be defined using the ``species`` setup variable. For example, to create two species called ``AIR`` and ``SF6`` one would specify ``species=air,sf6`` in the simulation setup command. Using this setup variable and using the ``SPECIES`` keyword in the ``Config`` file are mutually exclusive. Thus, the user must choose which method they wish to use for a given simulation. Certain units, such as the ``Opacity`` unit, requires the use of the setup variable. When species are defined using the setup variable approach, the ``Multispecies`` unit will automatically define several runtime parameters for each species. These runtime parameters can be used set the properties shown in . The runtime parameter names contain the species name. shows an example of the mapping between runtime parameters and ``Multispecies`` properties, where ```` is replaced by the species name as specified in the species setup argument list. Some of these runtime parameters are arrays, and thus the ```` is a number ranging from 1 to ``MS_MAXELEMS``. The ``Simulation_initSpecies`` subroutine can be used to override the runtime parameter settings. .. container:: center .. container:: :name: Tbl:MultispeciesRtp .. table:: Automatically Generated ``Multispecies`` Runtime Parameters =================== ========================== **Property Name** **Runtime Parameter Name** =================== ========================== ``A`` ``ms_A`` ``Z`` ``ms_Z`` ``N`` ``ms_Neutral`` ``E`` ``ms_Negative`` ``BE`` ``ms_BindEnergy`` ``GAMMA`` ``ms_Gamma`` ``MS_ZMIN`` ``ms_Zmin`` ``MS_EOSTYPE`` ``eos_EosType`` ``MS_EOSSUBTYPE`` ``eos_SubType`` ``MS_EOSZFREEFILE`` ``eos_TableFile`` ``MS_EOSENERFILE`` ``eos_TableFile`` ``MS_EOSPRESFILE`` ``eos_TableFile`` ``MS_NUMELEMS`` ``ms_NumElems`` ``MS_ZELEMS`` ``ms_ZElems_`` ``MS_AELEMS`` ``ms_AElems_`` ``MS_FRACTIONS`` ``ms_Fractions_`` ``MS_OPLOWTEMP`` ``op_LowTemp`` =================== ========================== Routine Descriptions -------------------- We now briefly discuss some interfaces to the multifluid database that are likely of interest to the user. Many of these routines include optional arguments. - ``Multispecies/Multispecies_setProperty`` This routine sets the value species property. It should be called within the subroutine ``Simulation/Simulation_initSpecies`` for all the species of interest in the simulation problem, and for all the required properties (any of A, Z, N, E, EB, GAMMA). .. container:: flashtip In |flashx|, you could set multiple properties at once in a call to ``add_fluid_to_db``. In |flashx|, individual calls are required. If you are setting up a nuclear network, there is a precoded ``Simulation/Simulation_initSpecies`` to easily initialize all necessary species. It is located in the unit ``Simulation/SimulationComposition``, which must be listed in your simulation ``Config`` file. - ``Multispecies/Multispecies_getProperty`` Returns the value of a requested property. - ``Multispecies/Multispecies_getSum`` Returns a weighted sum of a chosen property of species. The total number of species can be subset. The weights are optional, but are typically the mass fractions :math:`X_i` of each of the fluids at a point in space. In that case, if the selected property (one of :math:`A_i`, :math:`Z_i`, …, :math:`\gamma_i`) is denoted :math:`{\cal{P}}_i`, the sum calculated is .. math:: \sum_i {X_i}{\mathcal{P}_i} \quad. - Returns the weighted average of the chosen property. As in ``Multispecies_getSum``, weights are optional and a subset of species can be chosen. If the weights are denoted :math:`w_i` and the selected property (one of :math:`A_i`, :math:`Z_i`, …, :math:`\gamma_i`) is denoted :math:`{\cal{P}}_i`, the average calculated is .. math:: \frac{1}{N} \sum_i^N {w_i}{\mathcal{P}_i} \quad, where :math:`N` is the number of species included in the sum; it may be less than the number of all defined species if an average over a subset is requested. - ``Multispecies/Multispecies_getSumInv`` Same as ``Multispecies_getSum``, but compute the weighted sum of the inverse of the chosen property. If the weights are denoted :math:`w_i` and the selected property (one of :math:`A_i`, :math:`Z_i`, …, :math:`\gamma_i`) is denoted :math:`{\cal{P}}_i`, the sum calculated is .. math:: \sum_i^N \frac{w_i}{\mathcal{P}_i} \quad. For example, the average atomic mass of a collection of fluids is typically defined by .. math:: \frac{1}{\bar{A}} = \sum_i \frac{X_i}{A_i}~, where :math:`X_i` is the mass fraction of species :math:`i`, and :math:`A_i` is the atomic mass of that species. To compute :math:`\bar{A}` using the multifluid database, one would use the following lines .. container:: codeseg call Multispecies_getSumInv(A, abarinv, xn(:)) abar = 1.e0 / abarinv where ``xn(:)`` is an array of the mass fractions of each species in |flashx|. This method allows some of the mass fractions to be zero. - ``Multispecies/Multispecies_getSumFrac`` Same as ``Multispecies_getSum``, but compute the weighted sum of the chosen property divided by the total number of particles (:math:`A_i`). If the weights give the mass fractions :math:`X_i` of the fluids at a point in space and the selected property (one of :math:`A_i`, :math:`Z_i`, …, :math:`\gamma_i`) is denoted :math:`{\cal{P}}_i`, the sum calculated is .. math:: \sum_i \frac{X_i}{A_i}{\mathcal{P}_i} \quad. - ``Multispecies/Multispecies_getSumSqr`` Same as ``Multispecies_getSum``, but compute the weighted sum of the squares of the chosen property values. If the weights are denoted :math:`w_i` and the selected property (one of :math:`A_i`, :math:`Z_i`, …, :math:`\gamma_i`) is denoted :math:`{\cal{P}}_i`, the sum calculated is .. math:: \sum_i^N {w_i}{\mathcal{P}_i}^2 \quad. - ``Multispecies/Multispecies_list`` List the contents of the multifluid database in a snappy table format. Example Usage ------------- In general, to use Multispecies properties in a simulation, the user must only properly initialize the species as described above in the ``Simulation_init`` routine. But to program with the Multispecies properties, you must do three things: - ``#include`` the ``Simulation.h`` file to identify the defined species - ``#include`` the ``Multispecies.h`` file to identify the desired property - use the Fortran interface to the Multispecies unit because the majority of the routines are overloaded. The example below shows a snippet of code to calculate the electron density. .. container:: codeseg ... #include Simulation.h #include Multispecies.h USE Multispecies_interface, ONLY: Multispecies_getSumInv, Multispecies_getSumFrac ... do k=blkLimitsGC(LOW,KAXIS),blkLimitsGC(HIGH,KAXIS) do j=blkLimitsGC(LOW,JAXIS),blkLimitsGC(HIGH,JAXIS) do i=blkLimitsGC(LOW,IAXIS),blkLimitsGC(HIGH,IAXIS) call Multispecies_getSumInv(A,abar_inv) abar = 1.e0 / abar_inv call Multispecies_getSumFrac(Z,zbar) zbar = abar \* zbar ye(i,j,k) = abar_inv*zbar enddo enddo enddo ... .. _`Sec:MultispeciesUnitTest`: Unit Test --------- The unit test for ``Multispecies`` provides a complete example of how to call the various API routines in the unit with all variations of arguments. Within ``Multispecies/Multispecies_unitTest``, incorrect usage is also indicated within commented-out statements.