Next: Stencil operator, Up: Stencils [Contents][Index]
A stencil declaration may not be inside a function. It can appear inside a class declaration (in which case the stencil object is a nested type).
Stencil objects are declared using the macros BZ_DECLARE_STENCIL1
,
BZ_DECLARE_STENCIL2
, etc. The number suffix is how many arrays are
involved in the stencil (in the above example, 4 arrays– P1, P2, P3, c – are
used, so the macro BZ_DECLARE_STENCIL4
is invoked).
The first argument is a name for the stencil object. Subsequent arguments are names for the arrays on which the stencil operates.
After the stencil declaration, the macro BZ_END_STENCIL
must appear
(or the macro BZ_END_STENCIL_WITH_SHAPE
, described in the next
section).
In between the two macros, you can have multiple assignment statements, if/else/elseif constructs, function calls, loops, etc.
Here are some simple examples:
BZ_DECLARE_STENCIL2(smooth2D,A,B) A = (B(0,0) + B(0,1) + B(0,-1) + B(1,0) + B(-1,0)) / 5.0; BZ_END_STENCIL BZ_DECLARE_STENCIL4(acoustic2D,P1,P2,P3,c) A = 2 * P2 + c * (-4 * P2(0,0) + P2(0,1) + P2(0,-1) + P2(1,0) + P2(-1,0)) - P1; BZ_END_STENCIL BZ_DECLARE_STENCIL8(prop2D,E1,E2,E3,M1,M2,M3,cE,cM) E3 = 2 * E2 + cE * Laplacian2D(E2) - E1; M3 = 2 * M2 + cM * Laplacian2D(M2) - M1; BZ_END_STENCIL BZ_DECLARE_STENCIL3(smooth2Db,A,B,c) if ((c > 0.0) && (c < 1.0)) A = c * (B(0,0) + B(0,1) + B(0,-1) + B(1,0) + B(-1,0)) / 5.0 + (1-c)*B; else A = 0; BZ_END_STENCIL
Currently, a stencil can take up to 11 array parameters.
You can use the notation A(i,j,k)
to read the element at an offset
(i,j,k)
from the current element. If you omit the parentheses
(i.e. as in “A
” then the current element is read.
You can invoke stencil operators which calculate finite differences and laplacians.
In stencil declarations such as
BZ_DECLARE_STENCIL2(smooth2D,A,B) A = (B(0,0) + B(0,1) + B(0,-1) + B(1,0) + B(-1,0)) / 5.0; BZ_END_STENCIL
Blitz++ will try to automatically determine the spatial extent of the stencil. This will usually work for stencils defined on integer or float arrays. However, the mechanism does not work well for complex-valued arrays, or arrays of user-defined types. If you get a peculiar error when you try to use a stencil, you probably need to tell Blitz++ the special extent of the stencil manually.
You do this by ending a stencil declaration with
BZ_END_STENCIL_WITH_SHAPE
:
BZ_DECLARE_STENCIL2(smooth2D,A,B) A = (B(0,0) + B(0,1) + B(0,-1) + B(1,0) + B(-1,0)) / 5.0; BZ_END_STENCIL_WITH_SHAPE(shape(-1,-1),shape(+1,+1))
The parameters of this macro are: a TinyVector
(constructed by the
shape()
function) containing the lower bounds of the stencil offsets,
and a TinyVector
containing the upper bounds. You can determine this
by looking at the the terms in the stencil and finding the minimum and
maximum value of each index:
A = (B(0, 0) + B(0, +1) + B(0, -1) + B(+1, 0) + B(-1, 0)) / 5.0; -------- min indices -1, -1 max indices +1, +1
Next: Stencil operator, Up: Stencils [Contents][Index]