SAMRAI::hier::LayerEdgeSet< DIM > Class Template Reference

Encapsulates a set of DLBG edges that connect two LayerNodeSet objects. More...

#include <source/hierarchy/dlbg/LayerEdgeSet.h>

List of all members.

Algorithms for computing edge data

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.
static void findEdges (LayerEdgeSet &a, LayerEdgeSet &b)

For outputs, error checking and debugging.

virtual void printClassData (std::ostream &co, int debase_depth=0) const
void printEdgeStats (std::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 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.

Public Types

enum  ParallelState { DISTRIBUTED, GLOBALIZED }
 Names of parallel states. More...
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 std::map< LocalIndex,
NabrContainer
Connectivity
 Connectivity data between two node layers.

Public Member Functions

 LayerEdgeSet ()
 Constructor.
virtual ~LayerEdgeSet (void)
 Destructor.
const NodeContainergetNodeContainer (const int rank=-1) const
const ConnectivitygetConnectivity (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.
LayerEdgeSetcreatePartner (const LayerNodeSet< DIM > &partner_base, const Connectivity *partner_connectivity=NULL)
LayerEdgeSetgetPartner ()
 Access the attached partner.
const LayerEdgeSetgetPartner () 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.
LayerEdgeSetoperator= (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 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

Classes

struct  CommunicationStruct
 Data sorted by a hash. More...


Detailed Description

template<int DIM>
class SAMRAI::hier::LayerEdgeSet< DIM >

Encapsulates a set of DLBG edges that connect two LayerNodeSet objects.

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:

  1. DISTRIBUTED: An object in this state stores only edges incident from local nodes.
  2. GLOBALIZED: In this state, the edges are globally duplicated on all processors.

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.


Member Typedef Documentation

template<int DIM>
typedef LayerNode<DIM> SAMRAI::hier::LayerEdgeSet< DIM >::Node

template<int DIM>
typedef Node::LocalIndex SAMRAI::hier::LayerEdgeSet< DIM >::LocalIndex

template<int DIM>
typedef LayerNodeSet<DIM>::NodeContainer SAMRAI::hier::LayerEdgeSet< DIM >::NodeContainer

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.

template<int DIM>
typedef LayerNodeSet<DIM>::NodeContainer SAMRAI::hier::LayerEdgeSet< DIM >::NabrContainer

Container for neighbors.

template<int DIM>
typedef std::map<LocalIndex,NabrContainer> SAMRAI::hier::LayerEdgeSet< DIM >::Connectivity

Connectivity data between two node layers.

The connectivity m maps a node with index i to a set of nodes m[i], usually its neighbors. (The neighbors data is a container of nodes.)

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.


Member Enumeration Documentation

template<int DIM>
enum SAMRAI::hier::LayerEdgeSet::ParallelState

Names of parallel states.

Enumerator:
DISTRIBUTED 
GLOBALIZED 


Constructor & Destructor Documentation

template<int DIM>
SAMRAI::hier::LayerEdgeSet< DIM >::LayerEdgeSet (  ) 

Constructor.

The default constructor creates empty object in distributed state.

template<int DIM>
SAMRAI::hier::LayerEdgeSet< DIM >::~LayerEdgeSet ( void   )  [virtual]

Destructor.

Deallocate internal data.


Member Function Documentation

template<int DIM>
const LayerEdgeSet< DIM >::NodeContainer & SAMRAI::hier::LayerEdgeSet< DIM >::getNodeContainer ( const int  rank = -1  )  const [inline]

template<int DIM>
const LayerEdgeSet< DIM >::Connectivity & SAMRAI::hier::LayerEdgeSet< DIM >::getConnectivity ( const int  rank = -1  )  const

template<int DIM>
const hier::IntVector< DIM > & SAMRAI::hier::LayerEdgeSet< DIM >::getBaseRefinementRatio (  )  const [inline]

template<int DIM>
const hier::IntVector< DIM > & SAMRAI::hier::LayerEdgeSet< DIM >::getHeadRefinementRatio (  )  const [inline]

template<int DIM>
void SAMRAI::hier::LayerEdgeSet< DIM >::attachPartner ( LayerEdgeSet< DIM > &  partner  ) 

Mutually attach to another layer-edge object to create a bi-directional set of edges.

Preconditions on the partner and this object:

  1. The base refinement ratio of one partner and the head ratio of the other must be equal, and vice versa.
  2. The product of the base refinement ratio and the ghost-cell-width musb be the same for the partners. This ensures that the overlap check gives the same result regardless of the layer whose boxes are grown for the overlap check. For the extent of the partnership, this requirement must be met. Resetting the ghost-cell-width of one partner forces the ghost-cell-width of the partner to change to meet this requirement.

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, a.attach(b) has the same effect as b.attach(a). It is permissible to pass *this in for partner, which is how peer edges are set up.

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().

template<int DIM>
LayerEdgeSet< DIM > & SAMRAI::hier::LayerEdgeSet< DIM >::createPartner ( const LayerNodeSet< DIM > &  partner_base,
const Connectivity partner_connectivity = NULL 
)

template<int DIM>
LayerEdgeSet< DIM > & SAMRAI::hier::LayerEdgeSet< DIM >::getPartner (  ) 

Access the attached partner.

Error if no partner is attached.

template<int DIM>
const LayerEdgeSet< DIM > & SAMRAI::hier::LayerEdgeSet< DIM >::getPartner (  )  const

Access the attached partner.

Error if no partner is attached.

template<int DIM>
void SAMRAI::hier::LayerEdgeSet< DIM >::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.

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 connectivity is given, a copy is made from it. This is meant for use when you have an external means for computing the connectivity data. (The accuracy and consistency of the connectivity is not checked!) If connectivity is not given, it should be created using findEdges() before calling a method that uses it.

The parallel state is initialized to the given parallel_state. If state is GLOBALIZED:

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.

template<int DIM>
LayerEdgeSet< DIM > & SAMRAI::hier::LayerEdgeSet< DIM >::operator= ( const LayerEdgeSet< DIM > &  r  ) 

Assignment operator duplicates edge data and reference to layer node set and sets up a similar partner relationship and parallel mode.

If r is attached to itself, self-attach. If r is attached but not to itself, create a duplicate partner and attach to it.

All other data is directly copied.

template<int DIM>
void SAMRAI::hier::LayerEdgeSet< DIM >::findEdges (  ) 

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.

template<int DIM>
void SAMRAI::hier::LayerEdgeSet< DIM >::findEdges ( LayerEdgeSet< DIM > &  a,
LayerEdgeSet< DIM > &  b 
) [static]

template<int DIM>
void SAMRAI::hier::LayerEdgeSet< DIM >::bridge ( const LayerEdgeSet< DIM > &  edge_to_head,
const LayerEdgeSet< DIM > &  edge_to_base 
)

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:

  1. edge_to_head and edge_to_base must be incident from identical sets of nodes.
  2. edge_to_head and edge_to_base must have attached partners.
  3. Any parallel state is allowed, but states must be consistent between all LayerEdgeSet objects.
  4. At least one of the head or base layers must be completely nested in the middle layer. If neither is nested, some edges may be missed.

To find peer edges, use identical layer-edges for the leg to head and leg to base.

A partner must be attached.

template<int DIM>
void SAMRAI::hier::LayerEdgeSet< DIM >::replaceNodes ( const LayerEdgeSet< DIM > &  map  ) 

Replace some nodes with others.

Given the LayerEdgeSet object map, which maps some nodes in the head of the current LayerEdgeSet to new nodes (also in the head), replace each given node in the head layer by its neighbors in the tail of map.

                               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.

map is a layer edge from nodes to be removed to nodes to be in its place. If any edges in map references nodes not locally owned, communication with the owner is triggered. In these cases, it is CRITICAL that the same mapping is introduced on the owner processes.

We could do the same with a bridge() operation centered at the tail of the map. but that requires that map maps the unchanged nodes in the tail to itself, and it also requires doing work to map unchanged nodes to themselves. This is a lot of extra overhead when map is very small. If map maps each unchanged node to itself, a.replaceNodes(map) is equivalent to a.bridge(map,a.getPartner()).

The partner's base will be replaced by the new head.

Conditions:

  1. map must be based at the head of the current object.
  2. map and the current object must have attached partners.
  3. Any parallel state is allowed, but states must be consistent between all LayerEdgeSet objects.
  4. map must not map any node outside the range of the node's current box.

Parameters:
map Mapping between old head and new head. A partner must be attached.

template<int DIM>
void SAMRAI::hier::LayerEdgeSet< DIM >::setParallelState ( const ParallelState  parallel_state  ) 

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.

template<int DIM>
LayerEdgeSet< DIM >::ParallelState SAMRAI::hier::LayerEdgeSet< DIM >::getParallelState (  )  const [inline]

template<int DIM>
void SAMRAI::hier::LayerEdgeSet< DIM >::deallocateData (  ) 

Deallocate internal data on nodes and neighbors.

If a partner exists, its internal data is deallocated also. This method does NOT detach the partner.

template<int DIM>
void SAMRAI::hier::LayerEdgeSet< DIM >::setMaxGhostCellWidth ( const hier::IntVector< DIM > &  gcw  ) 

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.

template<int DIM>
const hier::IntVector< DIM > & SAMRAI::hier::LayerEdgeSet< DIM >::getMaxGhostCellWidth (  )  const [inline]

template<int DIM>
void SAMRAI::hier::LayerEdgeSet< DIM >::printClassData ( std::ostream &  co,
int  debase_depth = 0 
) const [virtual]

template<int DIM>
void SAMRAI::hier::LayerEdgeSet< DIM >::printEdgeStats ( std::ostream &  co  )  const

template<int DIM>
void SAMRAI::hier::LayerEdgeSet< DIM >::checkNodeNabrCorrespondance (  )  const

Check that the node and neighbor containers have a one-to-one correspondance.

template<int DIM>
void SAMRAI::hier::LayerEdgeSet< DIM >::checkNodeConsistency (  )  const

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.

template<int DIM>
void SAMRAI::hier::LayerEdgeSet< DIM >::checkNodeConsistency ( const NodeContainer local_nodes,
const Connectivity cnect,
const LayerNodeSet< DIM > &  head_layer 
) [static]

Check that nodes referenced by a given connectivity object match nodes in the given node containers.

Parameters:
local_nodes A node container.
cnect Connectivity data for nodes.
head_layer LayerNodeSet describing the head with respect to the given connectivity. This object must be in GLOBALIZED state.

template<int DIM>
void SAMRAI::hier::LayerEdgeSet< DIM >::checkConnectivity ( const LayerNodeSet< DIM > &  head  )  const

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.


The documentation for this class was generated from the following files:
Generated on Thu Jun 18 11:28:28 2009 for SAMRAI by  doxygen 1.5.1