#include <source/hierarchy/dlbg/LayerEdgeSet.h>
Public Types | |
typedef LayerNode< DIM > | Node |
typedef Node::LocalIndex | LocalIndex |
typedef LayerNodeSet< DIM >::NodeContainer | NodeContainer |
Container for nodes. | |
typedef LayerNodeSet< DIM >::NodeContainer | NabrContainer |
Container for neighbors. | |
typedef map< LocalIndex, NabrContainer > | Connectivity |
Connectivity data between two node layers. | |
enum | ParallelState { DISTRIBUTED, GLOBALIZED } |
Names of parallel states. More... | |
Public Member Functions | |
LayerEdgeSet () | |
Constructor. | |
virtual | ~LayerEdgeSet (void) |
Destructor. | |
const NodeContainer & | getNodeContainer (const int rank=-1) const |
const Connectivity & | getConnectivity (const int rank=-1) const |
const hier::IntVector< DIM > & | getBaseRefinementRatio () const |
const hier::IntVector< DIM > & | getHeadRefinementRatio () const |
void | attachPartner (LayerEdgeSet &partner) |
Mutually attach to another layer-edge object to create a bi-directional set of edges. | |
LayerEdgeSet & | createPartner (const LayerNodeSet< DIM > &partner_base, const Connectivity *partner_connectivity=NULL) |
LayerEdgeSet & | getPartner () |
Access the attached partner. | |
const LayerEdgeSet & | getPartner () const |
Access the attached partner. | |
void | initialize (ParallelState parallel_state, const LayerNodeSet< DIM > &base_layer, const hier::IntVector< DIM > &head_refinement_ratio, const hier::IntVector< DIM > &gcw=hier::IntVector< DIM >(1), const Connectivity *connectivity=NULL) |
Set data defining the edge set. | |
LayerEdgeSet & | operator= (const LayerEdgeSet &r) |
Assignment operator duplicates edge data and reference to layer node set and sets up a similar partner relationship and parallel mode. | |
void | findEdges () |
Discover and add edges between self and partner. | |
void | bridge (const LayerEdgeSet &edge_to_head, const LayerEdgeSet &edge_to_base) |
Create the layer edge data by bridging the heads of two layer edges whose base nodes are identical to each other. | |
void | replaceNodes (const LayerEdgeSet &map) |
Replace some nodes with others. | |
void | setParallelState (const ParallelState parallel_state) |
Set the parallel distribution state. | |
ParallelState | getParallelState () const |
void | deallocateData () |
Deallocate internal data on nodes and neighbors. | |
void | setMaxGhostCellWidth (const hier::IntVector< DIM > &gcw) |
Set the max ghost cell width used to check for box intersections. | |
const hier::IntVector< DIM > & | getMaxGhostCellWidth () const |
void | printClassData (ostream &co, int debase_depth=0) const |
void | printEdgeStats (ostream &co) const |
void | checkNodeNabrCorrespondance () const |
Check that the node and neighbor containers have a one-to-one correspondance. | |
void | checkNodeConsistency () const |
Check that the node referenced by connectivity match those in the partner's base LayerNodeSet. | |
void | checkConnectivity (const LayerNodeSet< DIM > &head) const |
Static Public Member Functions | |
static void | findEdges (LayerEdgeSet &a, LayerEdgeSet &b) |
static void | checkNodeConsistency (const NodeContainer &local_nodes, const Connectivity &cnect, const LayerNodeSet< DIM > &head_layer) |
Check that nodes referenced by a given connectivity object match nodes in the given node containers. | |
Classes | |
struct | CommunicationStruct |
Data sorted by a hash. More... |
Distributed Layered Box-graph (DLBG):
A box-graph is a graph where the nodes correspond to boxes and edges connect neighboring nodes. Two nodes are neighbors if their boxes overlap when one is grown by some nominal ghost-cell-width. Each edge is defined by the two nodes it connects. The box-graph is useful in SAMR because it shows which boxes directly interact with each other.
We can organize nodes of a box-graph into groups of boxes defined on the same index space. When sorted from coarsest to finest index spaces, the nodes fall into distinct layers. A "layer" is similar to a level in the hierarchy in that patches in a level share the same index space. We use layer instead of level to differentiate the graph from the hierarchy and because a layer does not necessarily have a one-to-one association with a level.
For convenience, we define
An edge is directional, like an arrow, starting at a base node and ending at a head node. Each pair of neighboring nodes has two edges, pointing in opposite directions. This goes also for LayerNodeSet and LayerEdgeSet objects. A single LayerEdgeSet object represents a set of directed edges incident from one base LayerNodeSet to one head LayerNodeSet. The edges pointing in the oposite direction are stored in a separate LayerEdgeSet object.
An object of this class can be partnered with another object that represents the directed edges in the opposite direction. The head of one partner is the base of the other. The partner does not provide additional information but it does organize the information differently. If the edge data is represented as a matrix, then one partner is the transpose of the other. A partnership allows both objects to be modified simultaneously so that their data is consistent. This avoids having to modify one after the other, which is problematic because the second modification begins with inconsistent data.
Two layers may contain edges in opposite directions and not be attached; but they would not be automatically coordinated in that case.
In parallel, a LayerNodeSet can also be in distributed or globalized (see LayerNodeSet). A locally-owned node is called a local node. Nodes owned by other processors are remote notes. Remote nodes are stilled called remote nodes when the LayerNodeSet is globalized. Local knowledge of a remote node does not make it local.
In parallel, we may partition the layer-edge and store it across many processors. The edge are classified as follows:
The parallel state of a LayerEdgeSet object can be:
The distribution state is changed by setParallelState(). Going to a more distributed state primarily means deallocating data, but going to a more serial state requires sharing of data (communicating). Currently, collected state for LayerEdgeSet objects seems to be unneeded.
The general attributes of a LayerEdgeSet are:
The connectivity depends on the base LayerNodeSet and the ghost-cell-width, so it is discarded when either of these is manually changed.
|
|
|
|
|
Container for nodes. This is a sorted container so that it can be compared without expensive searches. A node can be removed or added without changing the indices of existing nodes. |
|
Container for neighbors.
|
|
Connectivity data between two node layers.
The connectivity Because Connectivity is indexed by the LocalIndex instead of a combined owner and LocalIndex, each Connectivity object is implicitly associated with just one owner process. |
|
Names of parallel states.
|
|
Constructor. The default constructor creates empty object in distributed state. |
|
Destructor. Deallocate internal data. |
|
|
|
|
|
|
|
|
|
Mutually attach to another layer-edge object to create a bi-directional set of edges. Preconditions on the partner and this object:
Both objects must be in the same parallel state. Their parallel states will change together for the the duration of the partnership. Both objects are modified to reference each other as mutual partners. Both objects must be unpartnered. Multiple partners are not allowed. Once two layer edges objects are attached, they are synchronized when either calls a synchronizing method. Synchronizing means making all edges between them seen by both objects. (This does not mean that remote edges are seen in DISTRIBUTED modes though.)
The relationship between two attached objects is symmetric, that is, Since the partner is not created internally, it is NOT explicitly deleted when this object goes out of scope. It will simply be detached. This is in contrast to createPartner(). |
|
|
|
Access the attached partner. Error if no partner is attached. |
|
Access the attached partner. Error if no partner is attached. |
|
Set data defining the edge set. The object must not be attached to a partner. This method resets enough data to make coordination with partners irrelevant. You must detach the partner (if any) before calling this method. There should be no reason to use this method while attached.
A reference is made to the given LayerNodeSet. The ghost cell width is copied. If
The parallel state is initialized to the given
A reference is made to the given LayerNodeSet, replacing the current node reference. When debug is enabled, some checks are made to assert that base_layer and connectivity are consistent with each other. |
|
Assignment operator duplicates edge data and reference to layer node set and sets up a similar partner relationship and parallel mode.
If All other data is directly copied. |
|
Discover and add edges between self and partner. Obviously, a partner must be attached. Neighbor information on both the object and its partner is modified. The effect is the same as if findEdges() were called for the partner. This method simply calls findEdges(LayerEdgeSet &a, LayerEdgeSet &b) with the partner in the argument. See that method for communication implications. If the partner is the same object (finding peer edges), edges between a node and itself will be ignored. |
|
|
|
Create the layer edge data by bridging the heads of two layer edges whose base nodes are identical to each other.
(bridge base) ------------bridge-------------> (bridge head) <-------reverse bridge---------- ^ ^ | | | | | | +--edge to base-- (middle layer) --edge to head--+ The bases of the two given layers are known as the middle layer. For each node in this layer, the two given layers give the sets of neighboring nodes at the head and base layers of the current object. These two sets are checked against each other for node intersections. Conditions:
To find peer edges, use identical layer-edges for the leg to head and leg to base. A partner must be attached. |
|
Replace some nodes with others.
Given the LayerEdgeSet object
map (old head) ---------> (new head) ^ ^ \ / edge before mapping -> \ / <- edge after mapping \ / \ / (base) Representing the map by a LayerEdgeSet implicitly requires that any set of nodes replacing an old node must overlap the old ones they replace. A special algorithm taking advantage of this restriction is used to update this object. If you want to manipulate the edge data generally, DO NOT use this method.
We could do the same with a bridge() operation centered at the tail of the map. but that requires that The partner's base will be replaced by the new head. Conditions:
|
|
Set the parallel distribution state. Before putting a LayerEdgeSet in a GLOBALIZED state, The LayerNodeSet given in initialize() must already be in GLOBALIZED mode. The layer-node set must always be in GLOBALIZED mode as long as the layer-edge set is. In GLOBALIZED state, the entire layer is independently duplicated on every process. (For consistency, it is imperative that the layer is operated on uniformly across all processes.) All edges (not just local and semilocal) are found when operations to find them are executed. This method is not necessarily trivial. More memory is required to store additional parts of the graph. If a partner is attached, the parallel state of the partner is affected the same way. Changing parallel state preserves existing neighbor information used by the new parallel state. Neighbor information not used by the new parallel state gets deallocated. For efficiency reasons, this method NEVER implicitly discovers new neighbor information after going to a GLOBALIZED state. To get this data, call findEdges() explicitly. For serial (one processor) runs, there is no difference between the parallel states (except for the names), and there is no real cost for switching parallel states. |
|
|
|
Deallocate internal data on nodes and neighbors. If a partner exists, its internal data is deallocated also. This method does NOT detach the partner. |
|
Set the max ghost cell width used to check for box intersections. The default max ghost cell width is 1. The max ghost cell width affects the overlap comparison, so the old edge data is no longer valid. The old data is discarded. For efficiency reasons, new edge data is not automatically generated. To get this data, call findEdges() explicitly. For attached LayerEdgeSet objects, the ratio of the ghost-cell-width of the two partners must be equal to the inverse ratio of their base layer refinement ratios. This ensures that the overlap check gives the same result regardless of the layer whose boxes are grown for the overlap check. If a partner is attached, the partner's ghost-cell-width is automatically changed to satisfy this requirement. |
|
|
|
|
|
|
|
Check that the node and neighbor containers have a one-to-one correspondance.
|
|
Check that the node referenced by connectivity match those in the partner's base LayerNodeSet. Obviously, the object must have a partner. If the partner's base is not GLOBALIZED, a temporary copy is made and globalized for checking, triggering communication. |
|
Check that nodes referenced by a given connectivity object match nodes in the given node containers.
|
|
Assert that connectivity data is correct for the base and head (partner's base). This is an expensive operation and should only be used for debugging. It creates a globalized version of the layer-node data (if this data is not already globalized), uses the data to compute the edges and compares the result to the current edges. The object must be partnered and be in hybrid mode for checking to work. Checking is done as follows:
Currently, the rebuilt edges are rebuilt using findEdges(). Thus, it may be pointless to use this method as a check for that method. |