# Multispecies Unit

Flash-X 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 .

## 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$$=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 Flash-X 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 .

# Portion of a Config file for a Simulation SPECIES AIR SPECIES SF6

#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)

In Flash-X, you found the integer index of a species by using find_fluid_index. In Flash-X, 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

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.

Properties available through the Multispecies unit.

Property Name

Description

Data type

A

Number of protons and neutrons in nucleus

real

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 ionization

real

MS_EOSTYPE

EOS type to use for MTMMMT EOS

integer

MS_EOSSUBTYPE

EOS subtype to use for MTMMMT EOS

integer

MS_EOSZFREEFILE

Name of file with ionization data

string

MS_EOSENERFILE

Name of file with internal energy data

string

MS_EOSPRESFILE

Name of file with pressure data

string

MS_NUMELEMS

Number of elements comprising this species

integer

MS_ZELEMS

Atomic number of each species element

array(integer)

MS_AELEMS

Mass number of each species element

array(real)

MS_FRACTIONS

Number fraction of each species element

array(real)

MS_OPLOWTEMP

Temperature at which cold opacities are used

real

## 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.

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

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.

## 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 Flash-X 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.

#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)

## 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 <spec> is replaced by the species name as specified in the species setup argument list. Some of these runtime parameters are arrays, and thus the <N> is a number ranging from 1 to MS_MAXELEMS. The Simulation_initSpecies subroutine can be used to override the runtime parameter settings.

Parameters

Property Name

Runtime Parameter Name

A

ms_<spec>A

Z

ms_<spec>Z

N

ms_<spec>Neutral

E

ms_<spec>Negative

BE

ms_<spec>BindEnergy

GAMMA

ms_<spec>Gamma

MS_ZMIN

ms_<spec>Zmin

MS_EOSTYPE

eos_<spec>EosType

MS_EOSSUBTYPE

eos_<spec>SubType

MS_EOSZFREEFILE

eos_<spec>TableFile

MS_EOSENERFILE

eos_<spec>TableFile

MS_EOSPRESFILE

eos_<spec>TableFile

MS_NUMELEMS

ms_<spec>NumElems

MS_ZELEMS

ms_<spec>ZElems_<N>

MS_AELEMS

ms_<spec>AElems_<N>

MS_FRACTIONS

ms_<spec>Fractions_<N>

MS_OPLOWTEMP

op_<spec>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).

In Flash-X, you could set multiple properties at once in a call to add_fluid_to_db. In Flash-X, 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 $$X_i$$ of each of the fluids at a point in space. In that case, if the selected property (one of $$A_i$$, $$Z_i$$, …, $$\gamma_i$$) is denoted $${\cal{P}}_i$$, the sum calculated is

$\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 $$w_i$$ and the selected property (one of $$A_i$$, $$Z_i$$, …, $$\gamma_i$$) is denoted $${\cal{P}}_i$$, the average calculated is

$\frac{1}{N} \sum_i^N {w_i}{\mathcal{P}_i} \quad,$

where $$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 $$w_i$$ and the selected property (one of $$A_i$$, $$Z_i$$, …, $$\gamma_i$$) is denoted $${\cal{P}}_i$$, the sum calculated is

$\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

$\frac{1}{\bar{A}} = \sum_i \frac{X_i}{A_i}~,$

where $$X_i$$ is the mass fraction of species $$i$$, and $$A_i$$ is the atomic mass of that species. To compute $$\bar{A}$$ using the multifluid database, one would use the following lines

call Multispecies_getSumInv(A, abarinv, xn(:)) abar = 1.e0 / abarinv

where xn(:) is an array of the mass fractions of each species in Flash-X. 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 ($$A_i$$). If the weights give the mass fractions $$X_i$$ of the fluids at a point in space and the selected property (one of $$A_i$$, $$Z_i$$, …, $$\gamma_i$$) is denoted $${\cal{P}}_i$$, the sum calculated is

$\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 $$w_i$$ and the selected property (one of $$A_i$$, $$Z_i$$, …, $$\gamma_i$$) is denoted $${\cal{P}}_i$$, the sum calculated is

$\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.

… #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 …

## 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.