SpatialOps
Inferring operator types

Goal

Illustrate how to obtain stencil operator types.

Key Concepts

  1. There are a number of predefined operators/stencils in SpatialOps. They can be obtained via two simple ways:

    • The simplest way to obtain these is via the BasicOpTypes struct. This requires the volume field type and provides the types of all operators associated with that field.
    • Alternatively, one can use the OperatorTypeBuilder struct, which provides a bit more flexibility but requires more type knowledge.

    These approaches are both illustrated in the example below.

  2. Each stencil defines the type of field that it consumes (the source field) as well as the type of field it produces (the destination field) as follows:
    typedef OpType::SrcFieldType SrcType;
    typedef OpType::DestFieldType DestType;
  3. Because of this strong typing and type inference, SpatialOps can guarantee, at compile time, compatibility between fields and operators.
See also
The 3D Laplacian in action, which uses the concepts shown here to create a very generic 3D Laplacian function.
The Operator Types module, which provides additional documentation on operator type inference.

Example Code

examples/stencil_type_inference.cpp

#include <spatialops/structured/FVStaggered.h> // defines field and operator types for structured meshes
#include <spatialops/SpatialOpsTools.h> // for is_same_type
#include <cassert>
using namespace SpatialOps;
int main()
{
//----------------------------------------------------------------------------
// Illustrate type inference to obtain various operator types from a given
// volume field type. If an invalid "volume" field is provided, a compiler
// error will result.
typedef BasicOpTypes<SVolField>::GradX GradX; // x-derivative operator type
typedef BasicOpTypes<SVolField>::GradY GradY; // y-derivative operator type
typedef BasicOpTypes<SVolField>::GradZ GradZ; // z-derivative operator type
typedef BasicOpTypes<SVolField>::InterpC2FX InterpX; // x-interpolant operator type
typedef BasicOpTypes<SVolField>::InterpC2FY InterpY; // y-interpolant operator type
typedef BasicOpTypes<SVolField>::InterpC2FZ InterpZ; // z-interpolant operator type
typedef BasicOpTypes<SVolField>::DivX DivX; // x-divergence operator
typedef BasicOpTypes<SVolField>::DivY DivY; // y-divergence operator
typedef BasicOpTypes<SVolField>::DivZ DivZ; // z-divergence operator
//----------------------------------------------------------------------------
// Illustrate more general way to obtain operator types using OperatorTypeBuilder
// Here, we use the operation we want to accomplish (e.g., Interpolant) as
// well as the source and destination field types to obtain the operator type
// of interest. If no such operator has been defined, a compiler error will result.
assert(( is_same_type< InterpX,InterpX2 >() ));
assert(( is_same_type< GradX, GradX2 >() ));
assert(( is_same_type< DivX, DivX2 >() ));
//----------------------------------------------------------------------------
// Operators define the types of fields that they operate on (source field types)
// as well as the type of field that they produce (destination field type)
assert(( is_same_type< InterpX::SrcFieldType, SVolField >() ));
assert(( is_same_type< InterpX::DestFieldType, SSurfXField>() ));
assert(( is_same_type< DivY::SrcFieldType, SSurfYField>() ));
assert(( is_same_type< DivY::DestFieldType, SVolField >() ));
//----------------------------------------------------------------------------
// The examples above were dealing with the cell-centered mesh (with field types
// SVolField, SSurfXField, etc.) but we can also apply type inference for the
// staggered meshes.
typedef BasicOpTypes<XVolField>::GradX XVolGradX;
assert(( is_same_type< XVolGradX::DestFieldType, XVolDivX::SrcFieldType>() ));
return 0;
}