Blitz++ provides an implementation of stencil objects which
is currently experimental. This means that the exact
details of how they are declared and used may change in future
releases. Use at your own risk.
| 4.1: Motivation: a nicer notation for stencils |
Suppose we wanted to implement the 3-D acoustic wave equation using finite differencing. Here is how a single iteration would look using subarray syntax:
Range I(1,N-2), J(1,N-2), K(1,N-2);
P3(I,J,K) = (2-6*c(I,J,K)) * P2(I,J,K)
+ c(I,J,K)*(P2(I-1,J,K) + P2(I+1,J,K) + P2(I,J-1,K) + P2(I,J+1,K)
+ P2(I,J,K-1) + P2(I,J,K+1)) - P1(I,J,K);
This syntax is a bit klunky. With stencil objects, the implementation becomes:
BZ_DECLARE_STENCIL4(acoustic3D_stencil,P1,P2,P3,c) P3 = 2 * P2 + c * Laplacian3D(P2) - P1; BZ_END_STENCIL . . applyStencil(acoustic3D_stencil(), P1, P2, P3, c);
| 4.2: Declaring stencil objects |
| 4.3: Automatic determination of stencil extent |
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_STENCILBlitz++ 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
| 4.4: Stencil operators |
| 4.4.1: Central differences |
| 4.4.2: Forward differences |
| 4.4.3: Backward differences |
| 4.4.4: Laplacian operators |
| 4.4.5: Gradient operators |
| 4.4.6: Jacobian operators |
The Jacobian operators are defined over 3D vector fields only
(e.g. Array<TinyVector<double,3>,3>). They return a
TinyMatrix<T,3,3> where T is the numeric type of the
vector field.
These are also available in normalized
versions Jacobian3Dn and Jacobain3D4n which
have factors h.
| 4.4.7: Grad-squared operators |
| 4.4.8: Curl operators |
| 4.4.9: Divergence operators |
| 4.4.10: Mixed partial derivatives |
| 4.5: Declaring your own stencil operators |
| 4.6: Applying a stencil |