Auxiliary Variables
Auxiliary variables are variables that need to be computed at every model time step in order to advance the model state. Similar auxiliary variables are grouped together in auxiliary variable groups. An auxiliary variable group is implemented as a C++ class.
Basic class structure
Each auxiliary group class has the same basic structure. It is a light-weight class, since it needs to be copied to the GPU to perform computations. Each class contains:
a constructor
public arrays for the auxiliary variables
public member function(s) that compute the variables
member functions for adding metadata and registering with IO
static strings that contain the names used for metadata and IO
Additionally, there may be enum members that store user-configurable options.
As an example, the class KineticAuxVars
that groups kinetic energy and
velocity divergence has the following structure:
class KineticAuxVars {
public:
Array2DReal KineticEnergyCell;
Array2DReal VelocityDivCell;
KineticAuxVars(const HorzMesh *mesh, int NVertLevels);
void addMetaData() const;
void defineIOFields() const;
KOKKOS_FUNCTION void
computeVarsOnCell(int ICell, int KChunk,
const Array2DReal &NormalVelEdge) const;
private:
Array1DI4 NEdgesOnCell;
Array2DI4 EdgesOnCell;
Array2DR8 EdgeSignOnCell;
Array1DR8 DcEdge;
Array1DR8 DvEdge;
Array1DR8 AreaCell;
// names used in defining MetaData and IOFields
static const std::string KineticEnergyCellName;
static const std::string VelocityDivCellName;
};
Configuration enums
Some auxiliary variables have user-configurable options. In that case, for each option an enum is defined in the auxiliary group header file. For example, the flux thickness choice is represented using
enum FluxThickEdgeOption { Center, Upwind };
Constructor
The constructor takes in a mesh, and does the following:
allocates the auxiliary variable arrays
grabs the neccessary data from the mesh
retrieves configuration options
calls the
addMetaData()
anddefineIOFields()
helper functions
Compute member functions
The compute functions operate on a vertical chunk of mesh elements and take in
the element index, the chunk index, and input arrays, which may contain state
variables or other auxiliary variables. There is no output argument, they write
their results directly to the member arrays. There might be more than one
compute function, if variables located on different mesh elements are grouped
together. For example, the VorticityAuxVars
class provides both
void computeVarsOnVertex(int IVertex, int KChunk, const Array2DReal &LayerThickCell, const Array2DReal &NormalVelEdge);
void computeVarsOnEdge(int IEdge, int KChunk);
because the vorticity variables are first computed on vertices and then averaged to edges. Note that the edge compute function doesn’t take any array arguments, because it operates only on the class member arrays.
Implemented groups
The following auxiliary variable groups are currently implemented:
Group |
Auxiliary Variable |
Available options |
---|---|---|
KineticAuxVars |
KineticEnergyCell |
|
VelocityDiv |
||
LayerThicknessAuxVars |
FluxLayerThickEdge |
Center or Upwind |
MeanLayerThickEdge |
||
VorticityAuxVars |
RelVortVertex |
|
NormRelVortVertex |
||
NormPlanetVortVertex |
||
NormRelVortEdge |
||
NormPlanetVortEdge |
||
VelocityDel2AuxVars |
Del2Edge |
|
Del2DivCell |
||
Del2RelVortVertex |
||
TracerAuxVars |
HTracersEdge |
Center or Upwind |
Del2TracersCell |