BoundaryInfo Class Reference

#include <boundary_info.h>

List of all members.

Classes

class  Fill

Public Member Functions

 ~BoundaryInfo ()
void clear ()
void sync (BoundaryMesh &boundary_mesh, MeshData *boundary_mesh_data=NULL, MeshData *this_mesh_data=NULL)
void sync (const std::set< short int > &requested_boundary_ids, BoundaryMesh &boundary_mesh)
void add_node (const Node *node, const short int id)
void add_node (const unsigned int node, const short int id)
void add_side (const unsigned int elem, const unsigned short int side, const short int id)
void add_side (const Elem *elem, const unsigned short int side, const short int id)
void remove (const Node *node)
void remove (const Elem *elem)
void remove_side (const Elem *elem, const unsigned short int side)
void remove_side (const Elem *elem, const unsigned short int side, const short int id)
unsigned int n_boundary_ids () const
std::vector< short int > boundary_ids (const Node *node) const
short int boundary_id (const Elem *const elem, const unsigned short int side) const
unsigned int side_with_boundary_id (const Elem *const elem, const unsigned short int boundary_id) const
void build_node_boundary_ids (std::vector< short int > &b_ids)
void build_side_boundary_ids (std::vector< short int > &b_ids)
unsigned int n_boundary_conds () const
void build_node_list (std::vector< unsigned int > &nl, std::vector< short int > &il) const
void build_node_list_from_side_list ()
void build_side_list (std::vector< unsigned int > &el, std::vector< unsigned short int > &sl, std::vector< short int > &il) const
const std::set< short int > & get_boundary_ids () const
void print_info () const

Static Public Attributes

static const short int invalid_id = -1234

Protected Member Functions

 BoundaryInfo (const MeshBase &m)

Private Attributes

const MeshBase_mesh
std::multimap< const Node
*, short int > 
_boundary_node_id
std::multimap< const Elem
*, std::pair< unsigned short
int, short int > > 
_boundary_side_id
std::set< short int > _boundary_ids

Friends

class MeshBase


Detailed Description

The BoundaryInfo class contains information relevant to boundary conditions: it does not hold actual boundary condition data (check MeshData for that), but can mark element faces and nodes with ids useful for identifying the type of boundary condtion. It can also build a mesh that just includes boundary elements/faces.

TODO[JWP]: Generalize this to work with MeshBase again.

Definition at line 55 of file boundary_info.h.


Constructor & Destructor Documentation

BoundaryInfo::BoundaryInfo ( const MeshBase m  )  [protected]

Constructor. Takes a reference to the mesh. The BoundaryInfo class is only used internally by the Mesh class. A user should never instantiate this class. Therefore the constructor is protected.

Definition at line 43 of file boundary_info.C.

00043                                             :
00044   _mesh (m)
00045 {
00046 }

BoundaryInfo::~BoundaryInfo (  ) 

Destructor. Not much to do.

Definition at line 50 of file boundary_info.C.

References clear().

00051 {
00052   this->clear();
00053 }


Member Function Documentation

void BoundaryInfo::add_node ( const unsigned int  node,
const short int  id 
)

Add node number node with boundary id id to the boundary information data structures.

Definition at line 313 of file boundary_info.C.

References _mesh, add_node(), and MeshBase::node_ptr().

00315 {
00316   this->add_node (_mesh.node_ptr(node), id);
00317 }

void BoundaryInfo::add_node ( const Node node,
const short int  id 
)

Add Node node with boundary id id to the boundary information data structures.

Definition at line 321 of file boundary_info.C.

References _boundary_ids, _boundary_node_id, and invalid_id.

Referenced by add_node(), and build_node_list_from_side_list().

00323 {
00324   if (id == invalid_id)
00325     {
00326       std::cerr << "ERROR: You may not set a boundary ID of "
00327                 << invalid_id << std::endl
00328                 << " That is reserved for internal use.\n"
00329                 << std::endl;
00330 
00331       libmesh_error();
00332     }
00333 
00334   // A convenient typedef
00335   typedef std::multimap<const Node*, short int>::const_iterator Iter;
00336               
00337   // Don't add the same ID twice
00338   std::pair<Iter, Iter> pos = _boundary_node_id.equal_range(node);
00339 
00340   for (;pos.first != pos.second; ++pos.first)
00341     if (pos.first->second == id)
00342       return;
00343 
00344   std::pair<const Node*, short int> kv (node, id);
00345   
00346   _boundary_node_id.insert(kv);
00347   _boundary_ids.insert(id);
00348 }

void BoundaryInfo::add_side ( const Elem elem,
const unsigned short int  side,
const short int  id 
)

Add side side of element elem with boundary id id to the boundary information data structure.

Definition at line 361 of file boundary_info.C.

References _boundary_ids, _boundary_side_id, invalid_id, and Elem::level().

00364 {
00365   libmesh_assert (elem != NULL);
00366 
00367   // Only add BCs for level-0 elements.
00368   libmesh_assert (elem->level() == 0);
00369   
00370   if (id == invalid_id)
00371     {
00372       std::cerr << "ERROR: You may not set a boundary ID of "
00373                 << invalid_id << std::endl
00374                 << " That is reserved for internal use.\n"
00375                 << std::endl;
00376 
00377       libmesh_error();
00378     }
00379   
00380   // A convenient typedef
00381   typedef std::multimap<const Elem*, std::pair<unsigned short int, short int> >::const_iterator Iter;
00382               
00383   // Don't add the same ID twice
00384   std::pair<Iter, Iter> pos = _boundary_side_id.equal_range(elem);
00385 
00386   for (;pos.first != pos.second; ++pos.first)
00387     if (pos.first->second.first == side &&
00388         pos.first->second.second == id)
00389       return;
00390 
00391   std::pair<unsigned short int, short int> p(side,id);
00392   std::pair<const Elem*, std::pair<unsigned short int, short int> >
00393     kv (elem, p);
00394   
00395   _boundary_side_id.insert(kv);
00396   _boundary_ids.insert(id);
00397 }

void BoundaryInfo::add_side ( const unsigned int  elem,
const unsigned short int  side,
const short int  id 
)

Add side side of element number elem with boundary id id to the boundary information data structure.

Definition at line 352 of file boundary_info.C.

References _mesh, and MeshBase::elem().

Referenced by XdrIO::read_serialized_bcs().

00355 {
00356   this->add_side (_mesh.elem(e), side, id);
00357 }

short int BoundaryInfo::boundary_id ( const Elem *const   elem,
const unsigned short int  side 
) const

Returns the boundary id associated with the side side of element elem. Note that only one id per side is allowed, however multiple sides per element are allowed. Returns invalid_id if the side does not have an associated boundary id, hence invalid_id can be used as the default boundary id.

Definition at line 419 of file boundary_info.C.

References _boundary_side_id, invalid_id, Elem::level(), and Elem::top_parent().

Referenced by XdrIO::write_serialized_bcs().

00421 {
00422   libmesh_assert (elem != NULL);
00423 
00424   // Only level-0 elements store BCs.  If this is not a level-0
00425   // element get its level-0 parent and infer the BCs.
00426   const Elem*  searched_elem = elem;
00427   if (elem->level() != 0)
00428     searched_elem = elem->top_parent ();
00429   
00430   std::pair<std::multimap<const Elem*,
00431                           std::pair<unsigned short int, short int> >::const_iterator,
00432             std::multimap<const Elem*,
00433                           std::pair<unsigned short int, short int> >::const_iterator > 
00434     e = _boundary_side_id.equal_range(searched_elem);
00435 
00436   // elem not in the data structure
00437   if (e.first == e.second)
00438     return invalid_id;
00439 
00440   // elem is there, maybe multiple occurances
00441   while (e.first != e.second)
00442     {
00443       // if this is true we found the requested side
00444       // of the element and want to return the id
00445       if (e.first->second.first == side)
00446         return e.first->second.second;
00447 
00448       ++e.first;
00449     }
00450 
00451   // if we get here, we found elem in the data structure but not
00452   // the requested side, so return the default value
00453   return invalid_id;  
00454 }

std::vector< short int > BoundaryInfo::boundary_ids ( const Node node  )  const

Returns the boundary ids associated with Node node.

Definition at line 401 of file boundary_info.C.

References _boundary_node_id.

00402 {
00403   std::vector<short int> ids;
00404   
00405   // A convenient typedef
00406   typedef std::multimap<const Node*, short int>::const_iterator Iter;
00407               
00408   // Don't add the same ID twice
00409   std::pair<Iter, Iter> pos = _boundary_node_id.equal_range(node);
00410 
00411   for (;pos.first != pos.second; ++pos.first)
00412     ids.push_back(pos.first->second);
00413 
00414   return ids;
00415 }

void BoundaryInfo::build_node_boundary_ids ( std::vector< short int > &  b_ids  ) 

Builds the list of unique node boundary ids.

Definition at line 556 of file boundary_info.C.

References _boundary_node_id.

00557 {
00558   b_ids.clear();
00559 
00560   std::multimap<const Node*, short int>::const_iterator pos
00561     = _boundary_node_id.begin();
00562 
00563   for (; pos != _boundary_node_id.end(); ++pos)
00564     {
00565       short int id = pos->second;
00566       
00567       if(std::find(b_ids.begin(),b_ids.end(),id) == b_ids.end())
00568         b_ids.push_back(id);
00569     }
00570 }

void BoundaryInfo::build_node_list ( std::vector< unsigned int > &  nl,
std::vector< short int > &  il 
) const

Creates a list of nodes and ids for those nodes.

Definition at line 615 of file boundary_info.C.

References _boundary_node_id.

00617 {
00618   // Reserve the size, then use push_back
00619   nl.reserve (_boundary_node_id.size());
00620   il.reserve (_boundary_node_id.size());
00621   
00622   std::multimap<const Node*, short int>::const_iterator pos
00623     = _boundary_node_id.begin();
00624 
00625   for (; pos != _boundary_node_id.end(); ++pos)
00626     {
00627       nl.push_back (pos->first->id());
00628       il.push_back (pos->second);
00629     }
00630 }

void BoundaryInfo::build_node_list_from_side_list (  ) 

Adds nodes with boundary ids based on the side's boundary ids they are connected to.

Definition at line 634 of file boundary_info.C.

References _boundary_side_id, add_node(), Elem::build_side(), and side.

00635 {
00636   std::multimap<const Elem*,
00637                 std::pair<unsigned short int,
00638                           short int> >::const_iterator pos;
00639   
00640   //Loop over the side list
00641   for (pos=_boundary_side_id.begin(); pos != _boundary_side_id.end(); ++pos)
00642   {
00643     //Need to loop over the sides of any possible children
00644     std::vector< const Elem * > family;
00645 #ifdef LIBMESH_ENABLE_AMR
00646     pos->first->active_family_tree_by_side (family, pos->second.first);
00647 #else
00648     family.push_back(pos->first);
00649 #endif
00650 
00651     for(unsigned int elem_it=0; elem_it < family.size(); elem_it++)
00652     {
00653       const Elem * cur_elem = family[elem_it];
00654       
00655       AutoPtr<Elem> side = cur_elem->build_side(pos->second.first);
00656 
00657       //Add each node node on the side with the side's boundary id
00658       for(unsigned int i=0; i<side->n_nodes(); i++)
00659       {
00660         Node * node = side->get_node(i);
00661         
00662         this->add_node(node, pos->second.second);
00663       }
00664     }
00665   }
00666 }

void BoundaryInfo::build_side_boundary_ids ( std::vector< short int > &  b_ids  ) 

Builds the list of unique side boundary ids.

Definition at line 572 of file boundary_info.C.

References _boundary_side_id.

00573 {
00574   b_ids.clear();
00575 
00576   std::multimap<const Elem*, std::pair<unsigned short int, short int> >::const_iterator pos
00577     = _boundary_side_id.begin();
00578 
00579   for (; pos != _boundary_side_id.end(); ++pos)
00580     {
00581       short int id = pos->second.second;
00582       
00583       if(std::find(b_ids.begin(),b_ids.end(),id) == b_ids.end())
00584         b_ids.push_back(id);
00585     }
00586 }

void BoundaryInfo::build_side_list ( std::vector< unsigned int > &  el,
std::vector< unsigned short int > &  sl,
std::vector< short int > &  il 
) const

Creates a list of element numbers, sides, and and ids for those sides.

Definition at line 668 of file boundary_info.C.

References _boundary_side_id.

00671 {
00672   // Reserve the size, then use push_back
00673   el.reserve (_boundary_side_id.size());
00674   sl.reserve (_boundary_side_id.size());
00675   il.reserve (_boundary_side_id.size());
00676 
00677   std::multimap<const Elem*,
00678                 std::pair<unsigned short int,
00679                           short int> >::const_iterator pos;
00680 
00681   for (pos=_boundary_side_id.begin(); pos != _boundary_side_id.end();
00682        ++pos)
00683     {
00684       el.push_back (pos->first->id());
00685       sl.push_back (pos->second.first);
00686       il.push_back (pos->second.second);
00687     }
00688 }

void BoundaryInfo::clear (  ) 

Clears the underlying data structures. Returns the object to a pristine state with no data stored.

Definition at line 57 of file boundary_info.C.

References _boundary_ids, _boundary_node_id, and _boundary_side_id.

Referenced by ~BoundaryInfo().

00058 {
00059   _boundary_node_id.clear();
00060   _boundary_side_id.clear();
00061   _boundary_ids.clear();
00062 }

const std::set<short int>& BoundaryInfo::get_boundary_ids (  )  const [inline]

Returns:
the user-specified boundary ids.

Definition at line 239 of file boundary_info.h.

References _boundary_ids.

00240   { return _boundary_ids; }

unsigned int BoundaryInfo::n_boundary_conds (  )  const

Returns:
the number of element-based boundary conditions.

Definition at line 588 of file boundary_info.C.

References _boundary_side_id, _mesh, MeshBase::is_serial(), and libMesh::processor_id().

00589 {
00590   // in serial we know the number of bcs from the
00591   // size of the container
00592   if (_mesh.is_serial())
00593     return _boundary_side_id.size();
00594 
00595   // in parallel we need to sum the number of local bcs
00596   parallel_only();
00597   
00598   unsigned int nbcs=0;
00599 
00600   std::multimap<const Elem*,
00601                 std::pair<unsigned short int,
00602                           short int> >::const_iterator pos;
00603 
00604   for (pos=_boundary_side_id.begin(); pos != _boundary_side_id.end(); ++pos)
00605     if (pos->first->processor_id() == libMesh::processor_id())
00606       nbcs++;
00607   
00608   Parallel::sum (nbcs);
00609   
00610   return nbcs;
00611 }

unsigned int BoundaryInfo::n_boundary_ids (  )  const [inline]

Returns the number of user-specified boundary ids.

Definition at line 174 of file boundary_info.h.

References _boundary_ids.

00174 { return _boundary_ids.size(); }

void BoundaryInfo::print_info (  )  const

Print the boundary information data structure.

Definition at line 692 of file boundary_info.C.

References _boundary_node_id, and _boundary_side_id.

00693 {
00694   // Print out the nodal BCs
00695   if (!_boundary_node_id.empty())
00696     {
00697       std::cout << "Nodal Boundary conditions:" << std::endl
00698                 << "--------------------------" << std::endl
00699                 << "  (Node No., ID)               " << std::endl;
00700 
00701 //       std::for_each(_boundary_node_id.begin(),
00702 //                  _boundary_node_id.end(),
00703 //                  PrintNodeInfo());
00704 
00705       std::multimap<const Node*, short int>::const_iterator it        = _boundary_node_id.begin();
00706       const std::multimap<const Node*, short int>::const_iterator end = _boundary_node_id.end();
00707 
00708       for (; it != end; ++it)
00709         std::cout << "  (" << (*it).first->id()
00710                   << ", "  << (*it).second
00711                   << ")"  << std::endl;
00712     }
00713   
00714   // Print out the element BCs
00715   if (!_boundary_side_id.empty())
00716     {
00717       std::cout << std::endl
00718                 << "Side Boundary conditions:" << std::endl
00719                 << "-------------------------" << std::endl
00720                 << "  (Elem No., Side No., ID)      " << std::endl;
00721 
00722 //       std::for_each(_boundary_side_id.begin(),
00723 //                  _boundary_side_id.end(),
00724 //                  PrintSideInfo());
00725 
00726       std::multimap<const Elem*,
00727         std::pair<unsigned short int, short int> >::const_iterator it = _boundary_side_id.begin();
00728       const std::multimap<const Elem*,
00729         std::pair<unsigned short int, short int> >::const_iterator end = _boundary_side_id.end();
00730 
00731      for (; it != end; ++it)
00732        std::cout << "  (" << (*it).first->id()
00733                  << ", "  << (*it).second.first
00734                  << ", "  << (*it).second.second 
00735                  << ")"   << std::endl;
00736     }
00737 }

void BoundaryInfo::remove ( const Elem elem  )  [inline]

Removes the boundary conditions associated with element elem, if any exist.

Definition at line 370 of file boundary_info.h.

References _boundary_side_id.

00371 {
00372   libmesh_assert (elem != NULL);
00373   
00374   // Erase everything associated with elem
00375   _boundary_side_id.erase (elem);
00376 }

void BoundaryInfo::remove ( const Node node  )  [inline]

Removes the boundary conditions associated with node node, if any exist.

Definition at line 359 of file boundary_info.h.

References _boundary_node_id.

00360 {
00361   libmesh_assert (node != NULL);
00362   
00363   // Erase everything associated with node
00364   _boundary_node_id.erase (node);
00365 }

void BoundaryInfo::remove_side ( const Elem elem,
const unsigned short int  side,
const short int  id 
)

Removes the boundary id id from side side of element elem, if it exists.

Definition at line 489 of file boundary_info.C.

References _boundary_side_id, and Elem::level().

00492 {
00493   libmesh_assert (elem != NULL);
00494 
00495   // The user shouldn't be trying to remove only one child's boundary
00496   // id
00497   libmesh_assert (elem->level() == 0);
00498   
00499   std::pair<std::multimap<const Elem*,
00500                           std::pair<unsigned short int, short int> >::iterator,
00501             std::multimap<const Elem*,
00502                           std::pair<unsigned short int, short int> >::iterator > 
00503     e = _boundary_side_id.equal_range(elem);
00504 
00505   // elem may be there, maybe multiple occurances
00506   while (e.first != e.second)
00507     {
00508       // if this is true we found the requested side
00509       // of the element and want to erase the requested id
00510       if (e.first->second.first == side &&
00511           e.first->second.second == id)
00512         {
00513           // (postfix++ - increment the iterator before it's invalid)
00514           _boundary_side_id.erase(e.first++);
00515         }
00516       else
00517         ++e.first;
00518     }
00519 }

void BoundaryInfo::remove_side ( const Elem elem,
const unsigned short int  side 
)

Removes all boundary conditions associated with side side of element elem, if any exist.

Definition at line 457 of file boundary_info.C.

References _boundary_side_id, and Elem::level().

00459 {
00460   libmesh_assert (elem != NULL);
00461 
00462   // The user shouldn't be trying to remove only one child's boundary
00463   // id
00464   libmesh_assert (elem->level() == 0);
00465   
00466   std::pair<std::multimap<const Elem*,
00467                           std::pair<unsigned short int, short int> >::iterator,
00468             std::multimap<const Elem*,
00469                           std::pair<unsigned short int, short int> >::iterator > 
00470     e = _boundary_side_id.equal_range(elem);
00471 
00472   // elem may be there, maybe multiple occurances
00473   while (e.first != e.second)
00474     {
00475       // if this is true we found the requested side
00476       // of the element and want to erase the id
00477       if (e.first->second.first == side)
00478         {
00479           // (postfix++ - increment the iterator before it's invalid)
00480           _boundary_side_id.erase(e.first++);
00481         }
00482       else
00483         ++e.first;
00484     }
00485 }

unsigned int BoundaryInfo::side_with_boundary_id ( const Elem *const   elem,
const unsigned short int  boundary_id 
) const

Returns a side of element elem whose associated boundary id is boundary_id if such a side exists. If multiple sides of elem have the same id, only the lowest numbered such side is returned.

Returns invalid_uint if no side has the requested boundary id.

Definition at line 523 of file boundary_info.C.

References _boundary_side_id, libMesh::invalid_uint, Elem::level(), and Elem::top_parent().

00525 {
00526   const Elem* searched_elem = elem;
00527   if (elem->level() != 0)
00528     searched_elem = elem->top_parent();
00529 
00530   std::pair<std::multimap<const Elem*,
00531                           std::pair<unsigned short int, short int> >::const_iterator,
00532             std::multimap<const Elem*,
00533                           std::pair<unsigned short int, short int> >::const_iterator > 
00534     e = _boundary_side_id.equal_range(searched_elem);
00535 
00536   // elem not in the data structure
00537   if (e.first == e.second)
00538     return libMesh::invalid_uint;
00539 
00540   // elem is there, maybe multiple occurances
00541   while (e.first != e.second)
00542     {
00543       // if this is true we found the requested boundary_id
00544       // of the element and want to return the side
00545       if (e.first->second.second == boundary_id)
00546         return e.first->second.first;
00547 
00548       ++e.first;
00549     }
00550 
00551   // if we get here, we found elem in the data structure but not
00552   // the requested boundary id, so return the default value
00553   return libMesh::invalid_uint;  
00554 }

void BoundaryInfo::sync ( const std::set< short int > &  requested_boundary_ids,
BoundaryMesh boundary_mesh 
)

Close the data structures and prepare for use. Synchronizes the boundary_mesh data structures with the mesh data structures. Allows the boundary_mesh to be used like any other mesh. Before this is called the boundary_mesh data structure is empty. Only boundary elements with the specified ids are extracted.

If you are using a MeshData class with this Mesh, you can pass a pointer to both the boundary_mesh's MeshData object, and the MeshData object used for this mesh.

Definition at line 203 of file boundary_info.C.

References _boundary_side_id, _mesh, MeshBase::active_elements_begin(), MeshBase::active_elements_end(), ParallelMesh::add_elem(), ParallelMesh::add_point(), Elem::build_side(), ParallelMesh::clear(), DofObject::id(), Elem::n_nodes(), MeshBase::n_nodes(), ParallelMesh::n_nodes(), MeshBase::n_partitions(), Elem::n_sides(), Elem::neighbor(), Elem::node(), ParallelMesh::node_ptr(), MeshBase::nodes_begin(), MeshBase::nodes_end(), MeshBase::partitioner(), MeshBase::prepare_for_use(), DofObject::processor_id(), ParallelMesh::reserve_nodes(), AutoPtr< Tp >::reset(), MeshBase::set_n_partitions(), Elem::set_node(), Partitioner::set_node_processor_ids(), Elem::set_parent(), side, Elem::subdomain_id(), and Elem::top_parent().

00205 {
00206   // Re-create the boundary mesh.
00207   boundary_mesh.clear();
00208     
00209   boundary_mesh.set_n_partitions() = _mesh.n_partitions();
00210 
00211   // Make individual copies of all the nodes in the current mesh
00212   // and add them to the boundary mesh.  Yes, this is overkill because
00213   // all of the current mesh nodes will not end up in the the boundary
00214   // mesh.  These nodes can be trimmed later via a call to prepare_for_use().
00215   {
00216     libmesh_assert (boundary_mesh.n_nodes() == 0);
00217     boundary_mesh.reserve_nodes(_mesh.n_nodes());
00218     
00219     MeshBase::const_node_iterator it  = _mesh.nodes_begin();
00220     MeshBase::const_node_iterator end = _mesh.nodes_end();
00221     
00222     for(; it != end; ++it)
00223       {
00224         const Node* node = *it;
00225         boundary_mesh.add_point(*node); // calls Node::build(Point, id)
00226       }
00227   }
00228 
00229   // Add additional sides that aren't flagged with boundary conditions
00230   MeshBase::const_element_iterator       el     = _mesh.active_elements_begin();
00231   const MeshBase::const_element_iterator end_el = _mesh.active_elements_end(); 
00232 
00233   for ( ; el != end_el; ++el)
00234     {
00235       const Elem* elem = *el;
00236       
00237       for (unsigned int s=0; s<elem->n_sides(); s++)
00238         if (elem->neighbor(s) == NULL) // on the boundary
00239           {
00240             // Get the top-level parent for this element
00241             const Elem* top_parent = elem->top_parent();
00242 
00243             // A convenient typedef
00244             typedef
00245               std::multimap<const Elem*, std::pair<unsigned short int, short int> >::const_iterator
00246               Iter;
00247               
00248             // Find all the bcs asociated with top_parent
00249             std::pair<Iter, Iter> pos = _boundary_side_id.equal_range(top_parent);
00250 
00251             // look for a bcid which is (i) in the user-requested set, and
00252             // (ii) matches the current side #s
00253             while (pos.first != pos.second)
00254               {
00255                 // if this side is flagged with a boundary condition
00256                 // and the user wants this id
00257                 if ((pos.first->second.first == s) &&
00258                     (requested_boundary_ids.count(pos.first->second.second)))
00259                   {
00260                     // Build the side - do not use a "proxy" element here:
00261                     // This will be going into the BoundaryMesh and needs to
00262                     // stand on its own.
00263                     AutoPtr<Elem> side (elem->build_side(s, false));
00264                     
00265                     // inherit processor_id and subdomain_id from parent
00266                     side->subdomain_id() = elem->subdomain_id();
00267                     side->processor_id() = elem->processor_id();
00268 
00269                     // Add the side
00270                     Elem* new_elem = boundary_mesh.add_elem(side.release());
00271 
00272                     // and set the parent
00273                     new_elem->set_parent (const_cast<Elem*>(elem));
00274 
00275                     // This side's Node pointers still point to the nodes of the  original mesh.
00276                     // We need to re-point them to the boundary mesh's nodes!  Since we copied *ALL* of
00277                     // the original mesh's nodes over, we should be guaranteed to have the same ordering.
00278                     for (unsigned int nn=0; nn<new_elem->n_nodes(); ++nn)
00279                       {
00280                         // Get the correct node pointer, based on the id()
00281                         Node* new_node = boundary_mesh.node_ptr(new_elem->node(nn));
00282                         
00283                         // sanity check: be sure that the new Nodes global id really matches
00284                         libmesh_assert (new_node->id() == new_elem->node(nn));
00285 
00286                         // Assign the new node pointer
00287                         new_elem->set_node(nn) = new_node;
00288                       }
00289 
00290                     // go on to the next side
00291                     break;
00292                   }
00293                 
00294                 ++pos.first;
00295               } // end loop over bcs matching top_parent
00296             
00297           } // end if neighbor is NULL
00298     } // end loop over active elements
00299 
00300   // Don't repartition this mesh; but rather inherit the partitioning
00301   boundary_mesh.partitioner().reset(NULL);
00302   
00303   // Trim any un-used nodes from the Mesh
00304   boundary_mesh.prepare_for_use();
00305 
00306   // and finally distribute element partitioning to the nodes
00307   Partitioner::set_node_processor_ids(boundary_mesh);
00308 }

void BoundaryInfo::sync ( BoundaryMesh boundary_mesh,
MeshData boundary_mesh_data = NULL,
MeshData this_mesh_data = NULL 
)

Close the data structures and prepare for use. Synchronizes the boundary_mesh data structures with the mesh data structures. Allows the boundary_mesh to be used like any other mesh. Before this is called the boundary_mesh data structure is empty.

If you are using a MeshData class with this Mesh, you can pass a pointer to both the boundary_mesh's MeshData object, and the MeshData object used for this mesh.

Re-create the boundary mesh.

Definition at line 66 of file boundary_info.C.

References _boundary_ids, _boundary_side_id, _mesh, MeshBase::active_elements_begin(), MeshBase::active_elements_end(), ParallelMesh::add_elem(), ParallelMesh::add_point(), MeshData::assign(), Elem::build_side(), ParallelMesh::clear(), DofObject::id(), invalid_id, Elem::n_nodes(), MeshBase::n_nodes(), ParallelMesh::n_nodes(), Elem::n_sides(), Elem::neighbor(), Elem::node(), ParallelMesh::node_ptr(), MeshBase::nodes_begin(), MeshBase::nodes_end(), MeshBase::partitioner(), MeshBase::prepare_for_use(), ParallelMesh::reserve_nodes(), AutoPtr< Tp >::reset(), MeshBase::set_n_partitions(), Elem::set_node(), side, and Elem::top_parent().

00069 {
00070   boundary_mesh.clear();
00071 
00076   // Map boundary ids to side subdomain/partition ids
00077   std::map<short int, unsigned int> id_map;
00078 
00079   // Original Code
00080   //     unsigned int cnt = 0;
00081   //     for (std::set<short int>::iterator pos = boundary_ids.begin();
00082   //     pos != boundary_ids.end(); ++pos)
00083   //       id_map[*pos] = cnt++;
00084   
00085   //     id_map[invalid_id] = cnt;
00086 
00087     
00088   // New code
00089   // Here we need to use iota() once it is in the
00090   // Utility namespace.
00091   std::for_each(_boundary_ids.begin(),
00092                 _boundary_ids.end(),
00093                 Fill(id_map));
00094     
00095   boundary_mesh.set_n_partitions() = id_map.size();
00096 
00097 
00098   // Make individual copies of all the nodes in the current mesh
00099   // and add them to the boundary mesh.  Yes, this is overkill because
00100   // all of the current mesh nodes will not end up in the the boundary
00101   // mesh.  These nodes can be trimmed later via a call to prepare_for_use().
00102   {
00103     libmesh_assert (boundary_mesh.n_nodes() == 0);
00104     boundary_mesh.reserve_nodes(_mesh.n_nodes());
00105     
00106     MeshBase::const_node_iterator it  = _mesh.nodes_begin();
00107     MeshBase::const_node_iterator end = _mesh.nodes_end();
00108     
00109     for(; it != end; ++it)
00110       {
00111         const Node* node = *it;
00112         boundary_mesh.add_point(*node); // calls Node::build(Point, id)
00113       }
00114   }
00115 
00116   // Add additional sides that aren't flagged with boundary conditions
00117   MeshBase::const_element_iterator       el     = _mesh.active_elements_begin();
00118   const MeshBase::const_element_iterator end_el = _mesh.active_elements_end(); 
00119 
00120   for ( ; el != end_el; ++el)
00121     {
00122       const Elem* elem = *el;
00123       
00124       for (unsigned int s=0; s<elem->n_sides(); s++)
00125         if (elem->neighbor(s) == NULL) // on the boundary
00126           {
00127 
00128             // Build the side - do not use a "proxy" element here:
00129             // This will be going into the BoundaryMesh and needs to
00130             // stand on its own.
00131             AutoPtr<Elem> side (elem->build_side(s, false));
00132             
00133             // Get the top-level parent for this element
00134             const Elem* top_parent = elem->top_parent();
00135 
00136             // A convenient typedef
00137             typedef
00138               std::multimap<const Elem*, std::pair<unsigned short int, short int> >::const_iterator
00139               Iter;
00140               
00141             // Find the right id number for that side
00142             std::pair<Iter, Iter> pos = _boundary_side_id.equal_range(top_parent);
00143 
00144             while (pos.first != pos.second)
00145               {
00146                 if (pos.first->second.first == s) // already flagged with a boundary condition
00147                   {
00148                     side->subdomain_id() =
00149                       id_map[pos.first->second.second];
00150                     break;
00151                   }
00152                 
00153                 ++pos.first;
00154               }
00155 
00156             // either the element wasn't found or side s
00157             // doesn't have a boundary condition
00158             if (pos.first == pos.second)
00159               {
00160                 side->subdomain_id() = id_map[invalid_id];
00161               }
00162 
00163             side->processor_id() = side->subdomain_id(); //elem->processor_id();
00164             
00165             // Add the side
00166             Elem* new_elem = boundary_mesh.add_elem(side.release());
00167 
00168             // This side's Node pointers still point to the nodes of the  original mesh.
00169             // We need to re-point them to the boundary mesh's nodes!  Since we copied *ALL* of
00170             // the original mesh's nodes over, we should be guaranteed to have the same ordering.
00171             for (unsigned int nn=0; nn<new_elem->n_nodes(); ++nn)
00172               {
00173                 // Get the correct node pointer, based on the id()
00174                 Node* new_node = boundary_mesh.node_ptr(new_elem->node(nn));
00175                 
00176                 // sanity check: be sure that the new Nodes global id really matches
00177                 libmesh_assert (new_node->id() == new_elem->node(nn));
00178 
00179                 // Assign the new node pointer
00180                 new_elem->set_node(nn) = new_node;
00181               }
00182           }
00183     } // end loop over active elements
00184 
00185   
00186   
00187   // When desired, copy the MeshData
00188   // to the boundary_mesh
00189   if ((boundary_mesh_data != NULL) && (this_mesh_data != NULL))
00190     boundary_mesh_data->assign(*this_mesh_data);
00191 
00192   // Don't repartition this mesh; we're using the processor_id values
00193   // as a hack to display bcids for now.
00194   boundary_mesh.partitioner().reset(NULL);
00195 
00196   // Trim any un-used nodes from the Mesh
00197   boundary_mesh.prepare_for_use();
00198 }


Friends And Related Function Documentation

friend class MeshBase [friend]

Definition at line 58 of file boundary_info.h.


Member Data Documentation

std::set<short int> BoundaryInfo::_boundary_ids [private]

A collection of user-specified boundary ids.

Definition at line 280 of file boundary_info.h.

Referenced by add_node(), add_side(), clear(), get_boundary_ids(), n_boundary_ids(), and sync().

std::multimap<const Node*, short int> BoundaryInfo::_boundary_node_id [private]

Data structure that maps nodes in the mesh to boundary ids.

Definition at line 267 of file boundary_info.h.

Referenced by add_node(), boundary_ids(), build_node_boundary_ids(), build_node_list(), clear(), print_info(), and remove().

std::multimap<const Elem*, std::pair<unsigned short int, short int> > BoundaryInfo::_boundary_side_id [private]

const MeshBase& BoundaryInfo::_mesh [private]

The Mesh this boundary info pertains to.

Definition at line 260 of file boundary_info.h.

Referenced by add_node(), add_side(), n_boundary_conds(), and sync().

const short int BoundaryInfo::invalid_id = -1234 [static]

Number used for internal use. This is the return value if a boundary condition is not specified.

Definition at line 251 of file boundary_info.h.

Referenced by add_node(), add_side(), MeshTools::Modification::all_tri(), boundary_id(), MeshTools::Generation::build_cube(), MeshTools::Modification::flatten(), sync(), XdrIO::write_serialized_bcs(), and BoundaryInfo::Fill::~Fill().


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

Site Created By: libMesh Developers
Last modified: November 25 2009 03:43:55.

Hosted By:
SourceForge.net Logo