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() and defineIOFields() 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