libMesh::Patch Class Reference

#include <patch.h>

List of all members.

Public Types

typedef void(Patch::* PMF )()

Public Member Functions

 Patch ()
 ~Patch ()
void add_face_neighbors ()
void add_local_face_neighbors ()
void add_semilocal_face_neighbors ()
void add_point_neighbors ()
void add_local_point_neighbors ()
void add_semilocal_point_neighbors ()
void build_around_element (const Elem *elem, const unsigned int target_patch_size=10, PMF patchtype=&Patch::add_local_face_neighbors)

Protected Member Functions

void find_face_neighbors (std::set< const Elem * > &neighbor_set)
void find_point_neighbors (std::set< const Elem * > &neighbor_set)

Detailed Description

This class implements useful utility functions for a patch of elements

Author:
Roy H. Stogner, 2007. based on code by Varis Carey, Benjamin S. Kirk, 2004.

Definition at line 46 of file patch.h.


Member Typedef Documentation

typedef void(Patch::* libMesh::Patch::PMF)()

Pointer to Member Function typedef

Definition at line 101 of file patch.h.


Constructor & Destructor Documentation

libMesh::Patch::Patch (  )  [inline]

Constructor.

Definition at line 53 of file patch.h.

00053 {}

libMesh::Patch::~Patch (  )  [inline]

Destructor.

Definition at line 58 of file patch.h.

00058 {}


Member Function Documentation

void libMesh::Patch::add_face_neighbors (  ) 

This function finds all elements which touch the current patch at a face, and adds them to the patch.

Definition at line 77 of file patch.C.

References find_face_neighbors().

00078 {
00079   std::set<const Elem *> new_neighbors;
00080 
00081   this->find_face_neighbors(new_neighbors);
00082 
00083   this->insert(new_neighbors.begin(), new_neighbors.end());
00084 }

void libMesh::Patch::add_local_face_neighbors (  ) 

This function finds all elements on the current processor which touch the current patch at a face, and adds them to the patch.

Definition at line 88 of file patch.C.

References find_face_neighbors(), libMesh::processor_id(), and libMesh::DofObject::processor_id().

Referenced by build_around_element().

00089 {
00090   std::set<const Elem *> new_neighbors;
00091 
00092   this->find_face_neighbors(new_neighbors);
00093 
00094   std::set<const Elem*>::const_iterator       it  = new_neighbors.begin();
00095   const std::set<const Elem*>::const_iterator end_it = new_neighbors.end();
00096 
00097   for (; it != end_it; ++it)
00098     {
00099       const Elem* neighbor = *it;
00100       if (neighbor->processor_id() ==
00101           libMesh::processor_id()) // ... if the neighbor belongs to this processor
00102         this->insert (neighbor);   // ... then add it to the patch
00103     }
00104 }

void libMesh::Patch::add_local_point_neighbors (  ) 

This function finds all elements on the current processor which touch the current patch at any point, and adds them to the patch.

Definition at line 158 of file patch.C.

References find_point_neighbors(), libMesh::processor_id(), and libMesh::DofObject::processor_id().

Referenced by build_around_element().

00159 {
00160   std::set<const Elem *> new_neighbors;
00161 
00162   this->find_point_neighbors(new_neighbors);
00163 
00164   std::set<const Elem*>::const_iterator       it  = new_neighbors.begin();
00165   const std::set<const Elem*>::const_iterator end_it = new_neighbors.end();
00166 
00167   for (; it != end_it; ++it)
00168     {
00169       const Elem* neighbor = *it;
00170       if (neighbor->processor_id() ==
00171           libMesh::processor_id()) // ... if the neighbor belongs to this processor
00172         this->insert (neighbor);   // ... then add it to the patch
00173     }
00174 }

void libMesh::Patch::add_point_neighbors (  ) 

This function finds all elements which touch the current patch at any point, and adds them to the patch.

Definition at line 147 of file patch.C.

References find_point_neighbors().

00148 {
00149   std::set<const Elem *> new_neighbors;
00150 
00151   this->find_point_neighbors(new_neighbors);
00152 
00153   this->insert(new_neighbors.begin(), new_neighbors.end());
00154 }

void libMesh::Patch::add_semilocal_face_neighbors (  ) 

This function finds all elements which touch the current patch at a face and which touch one of our processor's elements at any point, and it adds them to the patch.

Definition at line 108 of file patch.C.

References find_face_neighbors(), and libMesh::Elem::is_semilocal().

00109 {
00110   std::set<const Elem *> new_neighbors;
00111 
00112   this->find_face_neighbors(new_neighbors);
00113 
00114   std::set<const Elem*>::const_iterator       it  = new_neighbors.begin();
00115   const std::set<const Elem*>::const_iterator end_it = new_neighbors.end();
00116 
00117   for (; it != end_it; ++it)
00118     {
00119       const Elem* neighbor = *it;
00120       if (neighbor->is_semilocal())
00121         this->insert (neighbor);
00122     }
00123 }

void libMesh::Patch::add_semilocal_point_neighbors (  ) 

This function finds all elements which touch the current patch at any point and which touch one of our processor's elements at any point, and it adds them to the patch.

Definition at line 178 of file patch.C.

References find_point_neighbors(), and libMesh::Elem::is_semilocal().

00179 {
00180   std::set<const Elem *> new_neighbors;
00181 
00182   this->find_point_neighbors(new_neighbors);
00183 
00184   std::set<const Elem*>::const_iterator       it  = new_neighbors.begin();
00185   const std::set<const Elem*>::const_iterator end_it = new_neighbors.end();
00186 
00187   for (; it != end_it; ++it)
00188     {
00189       const Elem* neighbor = *it;
00190       if (neighbor->is_semilocal())
00191         this->insert (neighbor);
00192     }
00193 }

void libMesh::Patch::build_around_element ( const Elem elem,
const unsigned int  target_patch_size = 10,
PMF  patchtype = &Patch::add_local_face_neighbors 
)

Erases any elements in the current patch, then builds a new patch containing element elem by repeated addition of neighbors on the current processor. This procedure is repeated until the number of elements meets or exceeds target_patch_size, or until the patch has no more local neighbors.

Definition at line 197 of file patch.C.

References libMesh::Elem::active(), add_local_face_neighbors(), add_local_point_neighbors(), end, libMesh::err, libMesh::processor_id(), and libMesh::DofObject::processor_id().

Referenced by libMesh::WeightedPatchRecoveryErrorEstimator::EstimateError::operator()(), and libMesh::PatchRecoveryErrorEstimator::EstimateError::operator()().

00200 {
00201 
00202   // Make sure we are building a patch for an active element.
00203   libmesh_assert(e0);
00204   libmesh_assert (e0->active());
00205   // Make sure we are either starting with a local element or
00206   // requesting a nonlocal patch
00207   libmesh_assert ((patchtype != &Patch::add_local_face_neighbors &&
00208            patchtype != &Patch::add_local_point_neighbors) ||
00209            e0->processor_id() == libMesh::processor_id());
00210 
00211   // First clear the current set, then add the element of interest.
00212   this->clear();
00213   this->insert (e0);
00214 
00215   // Repeatedly add the neighbors of the elements in the patch until
00216   // the target patch size is met
00217   while (this->size() < target_patch_size)
00218     {
00219       // It is possible that the target patch size is larger than the number
00220       // of elements that can be added to the patch.  Since we don't
00221       // have access to the Mesh object here, the only way we can
00222       // detect this case is by detecting a "stagnant patch," i.e. a
00223       // patch whose size does not increase after adding face neighbors
00224       const std::size_t old_patch_size = this->size();
00225 
00226       // We profile the patch-extending functions separately
00227       (this->*patchtype)();
00228 
00229       // Check for a "stagnant" patch
00230       if (this->size() == old_patch_size)
00231         {
00232           libmesh_do_once(libMesh::err <<
00233             "WARNING: stagnant patch of " << this->size() << " elements."
00234             << std::endl <<
00235             "Does the target patch size exceed the number of local elements?"
00236             << std::endl;
00237           libmesh_here(););
00238           break;
00239         }
00240     } // end while loop
00241 
00242 
00243   // make sure all the elements in the patch are active and local
00244   // if we are in debug mode
00245 #ifdef DEBUG
00246   {
00247     std::set<const Elem*>::const_iterator       it  = this->begin();
00248     const std::set<const Elem*>::const_iterator end_it = this->end();
00249 
00250     for (; it != end_it; ++it)
00251       {
00252         // Convenience.  Keep the syntax simple.
00253         const Elem* elem = *it;
00254 
00255         libmesh_assert (elem->active());
00256         if ((patchtype == &Patch::add_local_face_neighbors ||
00257              patchtype == &Patch::add_local_point_neighbors))
00258           libmesh_assert_equal_to (elem->processor_id(), libMesh::processor_id());
00259       }
00260   }
00261 #endif
00262 
00263 }

void libMesh::Patch::find_face_neighbors ( std::set< const Elem * > &  neighbor_set  )  [protected]

This function finds all elements which touch the current patch at a face

Definition at line 38 of file patch.C.

References libMesh::Elem::active(), libMesh::Elem::active_family_tree_by_neighbor(), end, libMesh::Elem::n_sides(), and libMesh::Elem::neighbor().

Referenced by add_face_neighbors(), add_local_face_neighbors(), and add_semilocal_face_neighbors().

00039 {
00040   // Loop over all the elements in the patch
00041   std::set<const Elem*>::const_iterator       it  = this->begin();
00042   const std::set<const Elem*>::const_iterator end_it = this->end();
00043 
00044   for (; it != end_it; ++it)
00045     {
00046       const Elem* elem = *it;
00047       for (unsigned int s=0; s<elem->n_sides(); s++)
00048         if (elem->neighbor(s) != NULL)        // we have a neighbor on this side
00049           {
00050             const Elem* neighbor = elem->neighbor(s);
00051 
00052 #ifdef LIBMESH_ENABLE_AMR
00053             if (!neighbor->active())          // the neighbor is *not* active,
00054               {                               // so add *all* neighboring
00055                                               // active children to the patch
00056                 std::vector<const Elem*> active_neighbor_children;
00057 
00058                 neighbor->active_family_tree_by_neighbor
00059                   (active_neighbor_children, elem);
00060 
00061                 std::vector<const Elem*>::const_iterator
00062                   child_it  = active_neighbor_children.begin();
00063                 const std::vector<const Elem*>::const_iterator
00064                   child_end = active_neighbor_children.end();
00065                 for (; child_it != child_end; ++child_it)
00066                   new_neighbors.insert(*child_it);
00067               }
00068             else
00069 #endif // #ifdef LIBMESH_ENABLE_AMR
00070               new_neighbors.insert (neighbor); // add active neighbors
00071           }
00072     }
00073 }

void libMesh::Patch::find_point_neighbors ( std::set< const Elem * > &  neighbor_set  )  [protected]

This function finds all elements which touch the current patch at any point

Definition at line 127 of file patch.C.

References end, and libMesh::Elem::find_point_neighbors().

Referenced by add_local_point_neighbors(), add_point_neighbors(), and add_semilocal_point_neighbors().

00128 {
00129   // Loop over all the elements in the patch
00130   std::set<const Elem*>::const_iterator       it  = this->begin();
00131   const std::set<const Elem*>::const_iterator end_it = this->end();
00132 
00133   for (; it != end_it; ++it)
00134     {
00135       std::set<const Elem*> elem_point_neighbors;
00136 
00137       const Elem* elem = *it;
00138       elem->find_point_neighbors(elem_point_neighbors);
00139 
00140       new_neighbors.insert(elem_point_neighbors.begin(),
00141                            elem_point_neighbors.end());
00142     }
00143 }


The documentation for this class was generated from the following files:

Site Created By: libMesh Developers
Last modified: February 05 2013 19:55:32 UTC

Hosted By:
SourceForge.net Logo