The following is a code fragment illustrating the creation of a POOMA Array using a GridLayout.
IndirectionList<int> g1(5);
g1(0) = 0; g1(1) = 5; g1(2) = 11; g1(3) = 17; g1(4) = 25;
Interval<1> dom(g1(0),g1(4)-1);
GridPartition<1> martition(Grid<1>(g1),igl,egl);
GuardLayers<1> igl(1), egl(0,2);
GridLayout<1> mayout2(dom, martition, ReplicatedTag() );
Array<1, double, MultiPatch<GridTag, Brick> > aa(mayout2);
The GuardLayers<Dim> class is used to specify both internal and external guard layers. Each dimension has a pair of integers to allow for asymmetric guard layer thicknesses. External guard layer specifications override those specified by the internal guard layer for those patches that make up the edges of the data object.
There are two types of GuardLayers used by a MultiPatchEngine based Pooma data object. These are internal guard layers and external guard layers. Each data patch of a POOMA data object has its domain extended by the number of data elements specified by the GuardLayers object.
Internal guard layers are layers of elements or cells added to the upper and/or lower end of the sub-domain of the PatchEngine. These cells are to be filled with the data values of the adjacent patches, in order to minimize cross context data dependency of execution of expressions for each PatchEngine. In general it is an error to specify a internal guard layer that is larger than the patch dimension. This is especially important to remember when dealing with SparseTileLayout and GridLayout.
External guard layers are on the edge of the entire data object and are used for external boundary conditions. In this diagram, the external guard layers are indicated by 'egl'. External guard layers data allocation exists only for those PatchEngines that are on the edges of the full domain of the Pooma data object. The data elements that make up the external guard layers are generally used for external boundary conditions.
In this example, the GuardLayers specification is symmetric, and the size of the internal and external guard layers are both 2. In general, GuardLayers may be specified asymmetrically, for instance:
GuardLayers<2> egl(0,5,3,1);
The first axis has an (external) GuardLayers specification that is 0 on the lower edge of the domain, and has a width of 5 on the upper edge of the domain, while in the second axis, the lower edge of the domain is extended by 3, and extended by 1 on the upper edge of the domain.
When the external guard layers and internal guard layers are specified
separately, the thickness of the external guard layer region in the patches
that form the edges of the domain will be that which was specified by the
external guard layer. Where those patches don't have an edge on the border
of the domain, the internal guard layer specification will determine the
size of the patches.
The following graphic illustrates the internal and external guard cell
regions for a UniformGridLayout with asymmetric guard cell specifications:
GuardLayers egl(1,3,2,3);
GuardLayers igl(2,1,1,3);
Interval<2> dom(Interval<1>(0,14),Interval<1>(0,9));
UniformGridPartition<2> asypart(Loc<2>(3,2),igl,egl);
Array<2,double,MultiPatchEngine<UniformTag,CompressibleBrick> > Array(UniformGridLayout<2>(dom,asypart,ReplicatedTag());
UniformGridLayout<Dim>
Divides the data space into regions defined by dividing each axis into
an integral number of equally size segments.
GridLayout<Dim>
Divides the data space into regions by segmenting each axis arbitrarily.
SparseTileLayout<Dim>
Tiles the domain (called the BoundingBox for this Layout) with non-overlapping
patches. The patches do not have to completely tile the BoundingBox. The
SparseTileLayout was designed in anticipation of Adaptive Mesh Refinement
codes development within Pooma. In SparseTileLayout, there are class member
functions that support accessing both the list of conventional internal
and external guard layer regions, as well as guard layers that do not intersect
or overlap onto the data space of patches defined within the layout.
DynamicLayout
An inherently 1-dimensional Layout, that allows the patches to be resized.
DomainLayout<Dim>
A single patch domain defined by a single Interval.
Layouts have Partitioners that are invoked to generate the
patch-subdomains, taking into account internal and external GuardLayers.
The currently available Partitioners are
UniformGridPartitioner<Dim>
Used to generate patches for a UniformGridLayout.
GridPartitioner<Dim>
Used to generate patches for a GridLayout.
TilePartition<Dim>
Generates patches from a provided list of domains.
SpatialPartition<ReferenceLayout>
Generates a list of empty patches that correspond in context and affinity
to the patch list of a provided reference Layout. Generally used with DynamicLayout.
LocalMapper<Dim>
Assigns all patches to a Context == -1. The value -1 is a special value
used by other parts of POOMA to indicate that the entire data object should
be replicated on each context.
DistributedMapper<Dim>
The DistributedMapper is a wrapper for other ContextMappers that
tries to pick an optimal mapper for the case where the data is distributed
over multiple contexts.
UniformMapper
This is a mapper specialized to Dim == 1, and evenly divides the patch
list sequence into the number of contexts.
BisectionMapper<Dim>
Uses Recursive bisection of the largest group of patches to produce
contexts with an approximately minimum surface to volume ratio. See figure.
ContiguousMapper
Assigns patches to a context in a modified Fortran storage order: As
the index gets to an boundary, the lowest axis index decrements, rather
than going from LowIndex = IndexMax to LowIndex = 0; see the figure for
an illustration of this mapper.
Only some combinations of Layouts, Partitioners and ContextMappers
are valid.
It is a logical error to use a GridPartitioner or SpatialPartitioner with a UniformGridLayout, as one of the optimizations within UniformGridLayout is that all domains are the same size. However, you can use a UniformGridPartitioner with a GridLayout, as the partitioning performed is within the restrictions imposed by GridLayout. SparseTileLayout is only compatible with TilePartition.
It is an error to try to use a MultiPatch engine of Brick or CompressibleBrick with any other mapper other than LocalMapper, and/or any layout that is not constructed with a ReplicatedTag argument. Since Bricks are single context only data engines, any MultiPatch engine constructed using Brick patch engines must not be distributed.
Similarly, MultiPatchEngine may not be constructed with the PatchEngine tag specified as Remote<PatchEngine> if LocalMapper is specified in the Layout used to construct the MultiPatchEngine. Either of the aforementioned combinations will generate a PInsist error inside MultiPatchEngine.