SpatialOps
Supported Nebo Field Operations

All Nebo field operations are within the SpatialOps namespace and are defined/implemented in the file NeboOperators.h. For the most part, users should not need to look at implementations, which use template metaprogramming extensively.

To access any of these operators, please use:

#include <spatialops/Nebo.h>

Nebo Expressions

A Nebo Expression can be:

  • A scalar: examples include 1.3, 2 etc.
  • A SpatialField
  • Any valid use of supported operators and functions, whose arguments themselves are Nebo Expressions;
  • A stencil operator applied to a Nebo Expression.

Type matching in Nebo Expressions

Each Nebo Expression has a field type. Each subexpression of an expression must have the same field type. If two incompatible field types are used in the same expression, the code will NOT compile, and it will result in a lengthy compiler error.


Basic Algebraic Operations

In the following table, result refers to a SpatialField whereas arg1 and arg2 can be a scalar, SpatialField or Nebo expression. All operations are applied point-wise on the arguments.

Operation Operator Basic Syntax Reference
Addition + result <<= arg1 + arg2 SpatialOps::SumOp
Subtraction - result <<= arg1 - arg2 SpatialOps::DiffOp
Multiplication * result <<= arg1 * arg2 SpatialOps::ProdOp
Division / result <<= arg1 / arg2 SpatialOps::DivOp
Negation - result <<= -arg SpatialOps::NegFcn

Functions

In the following table, result refers to a SpatialField whereas arg can be a scalar, SpatialField or Nebo expression. All operations are applied point-wise on the arguments.

Operation Operator Basic Syntax Reference
cosine cos result <<= cos(arg) SpatialOps::CosFcn
sine sin result <<= sin(arg) SpatialOps::SinFcn
tangent tan result <<= tan(arg) SpatialOps::TanFcn
exponential (with base 'e') exp result <<= exp(arg) SpatialOps::ExpFcn
error function erf result <<= erf(arg) SpatialOps::ErfFcn
inverse error function inv_erf result <<= inv_erf(arg) SpatialOps::InvErfFcn
complimentary error function erfc result <<= erfc(arg) SpatialOps::ErfcFcn
inverse complimentary error function inv_erfc result <<= inv_erfc(arg) SpatialOps::InvErfcFcn
hyperbolic tan tanh result <<= tanh(arg) SpatialOps::TanhFcn
gamma function gamma result <<= gamma(arg) SpatialOps::GammaFcn
natural logarithm log result <<= log(arg) SpatialOps::LogFcn
base 10 logarithm log10 result <<= log10(arg) SpatialOps::Log10Fcn
exponentiation (with given base 'arg')pow result <<= pow(arg,val) SpatialOps::PowFcn
square root sqrt result <<= sqrt(arg) SpatialOps::SqrtFcn
square square result <<= square(arg) SpatialOps::SquareFcn
cube cube result <<= cube(arg) SpatialOps::CubeFcn
absolute value abs result <<= abs(arg) SpatialOps::AbsFcn

Comparison Operations

Comparison operators perform point-wise comparisons. In the following table, arg1 and arg2 can be scalars, SpatialFields, or Nebo expressions. These comparison operations are typically used with cond.

Operation Operator Basic Syntax Reference
Greater than > arg1 > arg2 SpatialOps::GreaterThanCmp
Less than < arg1 < arg2 SpatialOps::LessThanCmp
Equal to == arg1 == arg2 SpatialOps::EqualCmp
Greater or equal to >= arg1 >= arg2 SpatialOps::GreaterThanEqualCmp
Less or equal to <= arg1 <= arg2 SpatialOps::LessThanEqualCmp
Not equal to != arg1 != arg2 SpatialOps::InequalCmp

Below, result is a field containing the pointwise result of the associated operation on arg1 and arg2 which can be scalars, SpatialFields or Nebo expressions:

Operation Operator Basic Syntax Reference
Maximum max result <<= max(arg1,arg2) SpatialOps::MaxFcn
Minimum min result <<= min(arg1,arg2) SpatialOps::MinFcn

Logical Operations

Nebo logical operators perform pointwise combinations of the results of comparison operations and / or masks.

Operation Operator Basic Syntax Reference
And && result <<= expr1 && expr2 SpatialOps::AndOp
Or || result <<= expr1 || expr2 SpatialOps::OrOp
Not ! result <<= !expr SpatialOps::NotOp

Reduction Operations

Operation Operator Basic Syntax
max nebo_max result <<= nebo_max( expr )
min nebo_min result <<= nebo_min( expr )
sum nebo_sum result <<= nebo_sum( expr )
L2 norm nebo_normresult <<= nebo_norm( expr )

There are also variants of these operations that exclude ghost cells:

Operation Operator Basic Syntax
max nebo_max_interior result <<= nebo_max_interior( expr )
min nebo_min_interior result <<= nebo_min_interior( expr )
sum nebo_sum_interior result <<= nebo_sum_interior( expr )
L2 norm nebo_norm_interiorresult <<= nebo_norm_interior( expr )

Conditional Operations using Nebo

Frequently one wishes to perform calculations of the form:

for i
  if     ( condition1 ) f[i] = something;
  else if( condition2 ) f[i] = something else;
  ...
  else                  f[i] = some default;
end

In Nebo, this is accomplished via cond which has the basic syntax:

f <<= cond( condition1, result1 )
          ( condition2, result2 )
          ...
          ( defaultResult );

Guidelines for using cond

There are a few guidelines/rules when using cond

  • Every cond expression must end with exactly one final clause. The final clause must contain exactly one argument, which must be a valid Nebo Expression.
  • There can be an arbitrary number of conditionals provided, and they are evaluated in order just as the for loop example above.
  • There are constraints on the arguments to cond as summarized in the following table:
    Item Valid inputs
    condition Nebo comparison operators or logical operators or masks
    result Scalar, SpatialField, or Nebo expression
    A cond expression must have at least one clause, and the requirements for each clause are as follows:

Non-final Clauses

  • Every non-final clause must contain exactly two arguments.
  • The first argument of each non-final clause must be a Nebo Boolean Expression.
  • The second argument of each non-final clause must be a valid Nebo Expression.

Final Clauses

  • Every cond expression must end with exactly one final clause.
  • The final clause must contain exactly one argument.
  • The argument of the final clause must be a valid Nebo Expression.

Examples of using cond

A few examples of cond:

// here assume that f, a and b are all SpatialField objects
f <<= cond( a > b, a ) // assign f=a where a>b
( b ); // f=b otherwise
f <<= cond( sin(a) > 0, exp(b) ) // assign f = exp(b) where sin(a) is positive
( a < 5, 1.0 ) // for cases not covered above, and where a<5, set f=1.0
( b ); // all other cases, set f=b
f <<= cond( f > a, 0.0 ) // when f exceeds a (pointwise), clip it to 0.0
( f ); // otherwise, leave it unchanged
See also
Operations using fields for a more complete example.

Design Background for cond

The conditional statement if and the ternary operator ( ? : ) cannot be overloaded in C++. Thus, to have pointwise conditional evaluation over fields, Nebo introduces cond, as used in many functional languages (introduced by LISP). Fortunately, cond fits into Nebo's syntax through C++ operator overloading and template meta-programming, which Nebo exploits. Additionally, through the use of inlined templated functions, cond compiles down to nested ternary operators ( ? : ). Thus, while the templates for cond are not simple, the executed code is simple and efficient.