.. highlight:: rest Describing the background gas ============================= Criptic is allows essentially arbitrary descriptions of the background gas through which cosmic rays move. Users can rely on some :ref:`ssec-gas-predef`, but for most realistic applications users will want to provide their own descriptions of the background gas (where "gas" here also includes the magnetic and radiation fields). This section first explains the basic data structure criptic uses to describe background gas (:ref:`ssec-gasdata`), and then explains the class used to return these descriptions (:ref:`ssec-gas-class`). It also explains the :ref:`ssec-gas-predef` gas descriptors that are available. .. _ssec-gasdata: The ``GasData`` class --------------------- In criptic, the state of the gas at a single point in space and time is described by a the `criptic::gas::GasData `_ class. This is a very simple class that describes the gas compsition. It has the following fields: * ``dx``: the characteristic length scale over which the gas state changes at a given point, which is used to control time steps for cosmic ray advances * ``den``: total mass density of the gas * ``ionDen``: mass density of the ionised component of the gas * ``v``: gas velocity * ``B``: magnetic field * ``denGrad``: gradient of the mass density * ``ionDenGrad``: gradient of the ionised mass density * ``vGrad``: tensor giving the gradient of the velocity * ``BGrad``: tensor giving the gradient of the magnetic field * ``xH0``: abundance of neutral atomic hydrogen (H\ :sup:`0`) per H nucleon * ``xHp``: abundance of ionized hydrogen (H\ :sup:`+`) per H nucleon * ``xHe0``: abundance of neutral atomic helium (He\ :sup:`0`) per H nucleon * ``xHep``: abundance of singly ionized helium (He\ :sup:`+`) per H nucleon * ``xHep2``: abundance of doubly ionized helium (He\ :sup:`+2`) per H nucleon * ``xe``: abundance of free electrons per H nucleon * ``Z``: mass fraction of elements heavier than He * ``TBB``: a vector giving the temperatures of each component of the radiation field * ``WBB``: a vector giving the dilution factors of each component of the radiation field With regard to the abundance quantities (``xH0``, ``xHp``, etc.): abundances in criptic are measured following the astrochemistry convention of giving an abundance as a number of a given species per H nucleon. Thus for example if there is 1 neutral He atom per 10 H atoms, ``xHe0`` would be 0.1. Note that the abundance of molecular hydrogen (H\ :sub:`2`) is not explicitly specified as part of ``GasData``; criptic assumes that all hydrogen nuclei that are not in the form of H\ :sup:`0` or H\ :sup:`+` are in the form of H\ :sub:`2`, from which it immediately follows that :math:`x(\mathrm{H}_2) = [1 - x(\mathrm{H}^0) - x(\mathrm{H}^+)]/2`. With regard to radiation fields: in criptic radiation fields are assumed to be describable as a sum of dilute blackbodies. ``TBB`` gives the temperature of each component, and ``WBB`` gives the dilution factor. For convenience, the ``GasData`` class defines three methods to set abundances to typical values found in predominantly molecular, atomic, and ionized interstellar regions; these routines are ``setMolecularComposition``, ``setAtomicComposition``, and ``setIonizedComposition``. The abundances these routines enforce are: .. list-table:: :header-rows: 1 * - Quantity - Ionized composition - Atomic composition - Molecular composition * - ``xH0`` - 0 - 0.99 - 0 * - ``xHp`` - 1 - 0.01 - 0 * - ``xHe0`` - 0 - 0.0955 - 0.0955 * - ``xHep`` - 0 - 0 - 0 * - ``xHep2`` - 0.0955 - 0 - 0 * - ``xe`` - 1 + 2 * 0.0955 - 0.01 - 1.0e-6 * - ``Z`` - 0.0199 - 0.0199 - 0.0199 .. _ssec-gas-class: The ``Gas`` class ----------------- The basic object in criptic used to describe the background gas is the `criptic::gas::Gas `_ class. This is a pure virtual class, and user-defined (and pre-defined) gas descriptors are derived from it. The user must instantiate and return a pointer to one of these derived objects in the ``initGas`` routine during problem setup -- see :ref:`ssec-init-gas`. The minimum requirement for a class derived from `Gas `_ is that it implement the method ``gasData``, which is a pure virtual method in `Gas `_. The signature for this method is:: virtual GasData gasData(const RealVec &x, const Real t); Here ``x`` is the position at which the gas state is to be returned (an object of type `RealVec <../html/Doxygen/html/classcriptic_1_1_vec3.html>`_), and ``t`` is the time. The method must return a `GasData `_ object in which all the fields listed above have been set. In addition to this required ``gasData`` method, users may wish to provide implementations of three other methods in `Gas `_, which will override the default implementations. The first of these is:: virtual Real dxGhost() const; This method is required to be defined for any class derived from `Gas `_ for which the gas properties are well-defined only over a finite volume (for example, because the gas data are coming from a simulation with a finite domain size). In this case, the problem geometry will generally be restricted to the range over which the gas data are defined (see :ref:`ssec-geometry-parameters`), but, as in any hydrodynamic simulation, criptic needs there to be a ghost region outside the region of valid data where calls to ``gasData`` will not generate non-sensical results. The routine ``dxGhost`` returns the size of this ghost region. The `CartesianGrid `_ class (see :ref:`ssec-gas-predef`) provides an example of a class derived from `Gas `_ that uses the ``dxGhost`` routine. The second optional method in `Gas `_ is the ``frame`` method, which has the signature:: virtual void frame(const RealVec &x, const Real t, RealVec& v, TNBBasis& tnb) const; This method takes as input the position and time, exactly as ``gasData``, but rather than returning the full gas state it only returns the gas velocity ``v`` and the local TNB basis defined by the magnetic field ``tnb``; the latter is a struct of type `TNBBasis `_, which holds the three unit vectors, ``tnb.eT``, ``tnb.eN``, and ``tnb.eB``, that define the TNB basis at the input position; the three vectors correspond to the tangent, normal, and binormal basis vectors, respectvely. The parent `Gas `_ class provides an implementation of ``frame`` that uses the data returned by ``gasData`` to compute the TNB basis. However, since this requires computing the full gas state and then carrying out some vector algebra to derive the TNB basis vectors from it, depending on how the gas state is calculated it may be more computationally efficient to compute the velocity and basis vectors directly. Overriding this method provides a way to do so. The `UniformGas `_ class (see :ref:`ssec-gas-predef`) provides an example of a class derived from `Gas `_ that does this. The third virtual method in `Gas `_ that derived classes may choose to override is:: virtual void updateState(const Real t, Real& tNext); This method is called at the end of every time step, and can be used to modify the state of the background gas (e.g., to implement a background gas that moves or changes over time). The default implementation of ``updateState`` does nothing. The input argument ``t`` is the time at the end of the current step in which ``updateState`` has been called, and the argument ``tNext`` is the time to which the simulation will be advanced after the next time step. Note that users are free to modify ``tNext`` (for example to reduce the time step in order to resolve some event occuring in the background gas), but that such modifications should generally involve only reductions in ``tNext``, not increases, as the latter can reduce simulation accuracy. See `CartesianTimeInterp `_ for an example of a class that uses ``updateState``. .. _ssec-gas-predef: Pre-defined gas descriptors --------------------------- While most users will want to set up their own background gas states, criptic does include a few simple defaults. These are: * `UniformGas `_, which represents a uniform, infinite medium * `CartesianGrid `_, which represents a gas whose properties are stored on a Cartesian grid * `CartesianTimeInterp `_, representing a gas whose properties are stored as a series of Cartesian grids representing snapshots of the gas state uniformly spaced in time * `CartesianTimeInterpFLASH `_, a specialization of `CartesianTimeInterp `_ in which the snapshots storing the data come from an isotheral turbulence simulation run with the `FLASH code `_ The `UniformGas `_ class reads the parameter file and uses the parameters ``gas.density``, ``gas.ionDensity``, ``gas.magField``, ``gas.velocity``, ``gas.dx``, ``gas.TBB``, and ``gas.WBB`` to set the corresponding fields in the `GasData `_ at all positions. Users can also set the abundances by manually specifying ``gas.xH0``, ``gas.xHp``, etc., or can invoke the ``setIonizedComposition``, ``setAtomicComposition``, or ``setMolecularComposition`` methods to set the abundances by setting the keyword ``gas.comp`` to ``ionized``, ``atomic``, or ``molecular``. The `CartesianGrid `_ class reads the parameter ``gas.n_grid`` from the parameter file, which is a triple of three integers specifying the number of cells in the grid; the edges of the grid are assumed to coincide with the problem domain boundaries (see :ref:`ssec-geometry-parameters`). The class then provides an operator ``CartesianGrid::operator()`` that can be used to access the values of cells. Users can use this operator to initialize the values in grid cells. The ``LossRates`` example problem in ``Src/Prob`` in the criptic repository provides an example of how to do this. The `CartesianTimeInterp `_ class is itself a pure virtual class, which provides a framework for interpolating in a Cartesian grid in space and time. It reads ``gas.n_grid`` from the parameter file exactly as for `CartesianGrid `_, and also reads the parameters ``gas.dt`` and ``gas.n_slice``, which give the time interval between slices and the number of time slices, respectively; the first time slice is assumed to be at time 0. To use this class, users must create a derived class that implements the pure virtual method ``loadData``, which loads in a time slice as a `CartesianGrid `_ and provides a pointer to it. The `CartesianTimeInterpFLASH `_ class provides an example of such a derived class.