3.7 Expressions

This section discusses particulars related to expressions appearing in Nektar++. Expressions in Nektar++ are used to describe spatially or temporally varying properties, for example

which can be retrieved in the solver code.

Expressions appear as the content of VALUE attribute of

The tags above declare expressions as well as link them to one of the field variables declared in <EXPANSIONS> section. For example, the declaration

1  <D VAR="u" VALUE="sin(PI*x)*cos(PI*y)" />

registers expression sin(πx)cos(πy) as a Dirichlet boundary constraint associated with field variable u.

Enforcing the same velocity profile at multiple boundary regions and/or field variables results in repeated re-declarations of a corresponding expression. Currently one cannot directly link a boundary condition declaration with an expression uniquely specified somewhere else, e.g. in the <FUNCTION> subsection. However this duplication does not affect an overall computational performance.

3.7.1 Variables and coordinate systems

Declarations of expressions are formulated in terms of problem space-time coordinates. The library code makes a number of assumptions to variable names and their order of appearance in the declarations. This section describes these assumptions.

Internally, the library uses 3D global coordinate space regardless of problem dimension. Internal global coordinate system has natural basis (1,0,0),(0,1,0),(0,0,1) with coordinates x, y and z. In other words, variables x, y and z are considered to be first, second and third coordinates of a point (x, y, z).

Declarations of problem spatial variables do not exist in the current XML file format. Even though field variables are declarable as in the following code snippet,

1   <VARIABLES> 
2     <V ID="0"> u </V> 
3     <V ID="1"> v </V> 
4   </VARIABLES>

there are no analogous tags for space variables. However an attribute SPACE of <GEOMETRY> section tag declares the dimension of problem space. For example,

1  <GEOMETRY DIM="1" SPACE="2"> ... 
2  </GEOMETRY>

specifies 1D flow within 2D problem space. The number of spatial variables presented in expression declaration should match space dimension declared via <GEOMETRY> section tag.

The library assumes the problem space also has natural basis and spatial coordinates have names x, y and z.

Problem space is naturally embedded into the global coordinate space: each point of

Currently, there is no way to describe rotations and translations of problem space relative to the global coordinate system.

The list of variables allowed in expressions depends on the problem dimension:

Violation of these constraints yields unpredictable results of expression evaluation. The current implementation assigns magic value -9999 to each dimensionally excessive spacial variable appearing in expressions. For example, the following declaration

1  <GEOMETRY DIM="2" SPACE="2"> ... 
2  </GEOMETRY> ... 
3  <CONDITIONS> ... 
4    <BOUNDARYCONDITIONS> 
5       <REGION REF="0"> 
6         <D VAR="u" VALUE="x+y+z" /> <D VAR="v" VALUE="sin(PI*x)*cos(PI*y)" /> 
7       </REGION> 
8     </BOUNDARYCONDITIONS> 
9  ... 
10  </CONDITIONS>

results in expression x + y + z being evaluated at spatial points (xi,yi,-9999) where xi and yi are the spacial coordinates of boundary degrees of freedom. However, the library behaviour under this constraint violation may change at later stages of development (e.g., magic constant 0 may be chosen) and should be considered unpredictable.

Another example of unpredictable behaviour corresponds to wrong ordering of variables:

1  <GEOMETRY DIM="1" SPACE="1"> ... 
2  </GEOMETRY> ... 
3  <CONDITIONS> ... 
4    <BOUNDARYCONDITIONS> 
5       <REGION REF="0"> 
6         <D VAR="u" VALUE="sin(y)" /> 
7       </REGION> 
8     </BOUNDARYCONDITIONS> 
9  ... 
10  </CONDITIONS>

Here one declares 1D problem, so Nektar++ library assumes spacial variable is x. At the same time, an expression sin(y) is perfectly valid on its own, but since it does not depend on x, it will be evaluated to constant sin(-9999) regardless of degree of freedom under consideration.

3.7.1.1 Time dependence

Variable t represents time dependence within expressions. The boundary condition declarations need to add an additional property USERDEFINEDTYPE="TimeDependent" in order to flag time dependency to the library.

3.7.1.2 Syntax of expressions

Analytic expressions are formed of

3.7.1.3 Examples

Some straightforward examples include

3.7.2 Performance considerations

Processing expressions is split into two stages:

Parsing of expressions with their partial evaluation take place at the time of setting the run up (reading an XML file). Each expression, after being pre-processed, is stored internally and quickly retrieved when it turns to evaluation at given spatial-time point(s). This allows to perform evaluation of expressions at a large number of spacial points with minimal setup costs.

3.7.2.1 Pre-evaluation details

Partial evaluation of all constant sub-expressions makes no sense in using derived constants from table above. This means, either make use of pre-defined constant LN10^2 or straightforward expression log10(2)^2 results in constant 5.3018981104783980105 being stored internally after pre-processing. The rules of pre-evaluation are as follows:

For example, declaration

1     <D VAR="u" VALUE="exp(-x*sin(PI*(sqrt(2)+sqrt(3))/2)*y )" />

results in expression exp(-x*(-0.97372300937516503167)*y ) being stored internally: sub-expression sin(PI*(sqrt(2)+sqrt(3))/2) is evaluated to constant but appearance of x and y variables stops further pre-evaluation.

Grouping predefined constants and numbers together helps. Its useful to put brackets to be sure your constants do not run out and become factors of some variables or parameters.

Expression evaluator does not do any clever simplifications of input expressions, which is clear from example above (there is no point in double negation). The following subsection addresses the simplification strategy.

3.7.2.2 Preparing expression

The total evaluation cost depends on the overall number of operations. Since evaluator is not making simplifications, it worth trying to minimise the total number of operations in input expressions manually.

Some operations are more computationally expensive than others. In an order of increasing complexity:

For example,

If any simplifying identity applies to input expression, it may worth applying it, provided it minimises the complexity of evaluation. Computer algebra systems may help.

3.7.2.3 Vectorized evaluation

Expression evaluator is able to calculate an expression for either given point (its space-time coordinates) or given array of points (arrays of their space-time coordinates, it uses SoA). Vectorized evaluation is faster then sequential due to a better data access pattern. Some expressions give measurable speedup factor 4.6. Therefore, if you are creating your own solver, it worth making vectorized calls.