Poster of Linux kernelThe best gift for a Linux geek
BoundaryInfo

BoundaryInfo

Section: C Library Functions (3) Updated: Thu Apr 7 2011
Local index Up
 

NAME

BoundaryInfo -  

SYNOPSIS


#include <boundary_info.h>  

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.

                                            :
  _mesh (m)
{
}
 

BoundaryInfo::~BoundaryInfo ()Destructor. Not much to do.

Definition at line 50 of file boundary_info.C.

References clear().

{
  this->clear();
}
 

Member Function Documentation

 

void BoundaryInfo::add_node (const Node *node, const short intid)Add Node node with boundary id id to the boundary information data structures.

Definition at line 323 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().

{
  if (id == invalid_id)
    {
      std::cerr << 'ERROR: You may not set a boundary ID of '
                << invalid_id << std::endl
                << ' That is reserved for internal use.
                << std::endl;

      libmesh_error();
    }

  // A convenient typedef
  typedef std::multimap<const Node*, short int>::const_iterator Iter;
              
  // Don't add the same ID twice
  std::pair<Iter, Iter> pos = _boundary_node_id.equal_range(node);

  for (;pos.first != pos.second; ++pos.first)
    if (pos.first->second == id)
      return;

  std::pair<const Node*, short int> kv (node, id);
  
  _boundary_node_id.insert(kv);
  _boundary_ids.insert(id);
}
 

void BoundaryInfo::add_node (const unsigned intnode, const short intid)Add node number node with boundary id id to the boundary information data structures.

Definition at line 315 of file boundary_info.C.

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

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

void BoundaryInfo::add_side (const unsigned intelem, const unsigned short intside, const short intid)Add side side of element number elem with boundary id id to the boundary information data structure.

Definition at line 354 of file boundary_info.C.

References _mesh, and MeshBase::elem().

Referenced by XdrIO::read_serialized_bcs().

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

void BoundaryInfo::add_side (const Elem *elem, const unsigned short intside, const short intid)Add side side of element elem with boundary id id to the boundary information data structure.

Definition at line 363 of file boundary_info.C.

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

{
  libmesh_assert (elem != NULL);

  // Only add BCs for level-0 elements.
  libmesh_assert (elem->level() == 0);
  
  if (id == invalid_id)
    {
      std::cerr << 'ERROR: You may not set a boundary ID of '
                << invalid_id << std::endl
                << ' That is reserved for internal use.
                << std::endl;

      libmesh_error();
    }
  
  // A convenient typedef
  typedef std::multimap<const Elem*, std::pair<unsigned short int, short int> >::const_iterator Iter;
              
  // Don't add the same ID twice
  std::pair<Iter, Iter> pos = _boundary_side_id.equal_range(elem);

  for (;pos.first != pos.second; ++pos.first)
    if (pos.first->second.first == side &&
        pos.first->second.second == id)
      return;

  std::pair<unsigned short int, short int> p(side,id);
  std::pair<const Elem*, std::pair<unsigned short int, short int> >
    kv (elem, p);
  
  _boundary_side_id.insert(kv);
  _boundary_ids.insert(id);
}
 

short int BoundaryInfo::boundary_id (const Elem *constelem, const unsigned short intside) constReturns 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 421 of file boundary_info.C.

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

Referenced by XdrIO::write_serialized_bcs().

{
  libmesh_assert (elem != NULL);

  // Only level-0 elements store BCs.  If this is not a level-0
  // element get its level-0 parent and infer the BCs.
  const Elem*  searched_elem = elem;
  if (elem->level() != 0)
    searched_elem = elem->top_parent ();
  
  std::pair<std::multimap<const Elem*,
                          std::pair<unsigned short int, short int> >::const_iterator,
            std::multimap<const Elem*,
                          std::pair<unsigned short int, short int> >::const_iterator > 
    e = _boundary_side_id.equal_range(searched_elem);

  // elem not in the data structure
  if (e.first == e.second)
    return invalid_id;

  // elem is there, maybe multiple occurances
  while (e.first != e.second)
    {
      // if this is true we found the requested side
      // of the element and want to return the id
      if (e.first->second.first == side)
        return e.first->second.second;

      ++e.first;
    }

  // if we get here, we found elem in the data structure but not
  // the requested side, so return the default value
  return invalid_id;  
}
 

std::vector< short int > BoundaryInfo::boundary_ids (const Node *node) constReturns the boundary ids associated with Node node.

Definition at line 403 of file boundary_info.C.

References _boundary_node_id.

{
  std::vector<short int> ids;
  
  // A convenient typedef
  typedef std::multimap<const Node*, short int>::const_iterator Iter;
              
  // Don't add the same ID twice
  std::pair<Iter, Iter> pos = _boundary_node_id.equal_range(node);

  for (;pos.first != pos.second; ++pos.first)
    ids.push_back(pos.first->second);

  return ids;
}
 

void BoundaryInfo::build_node_boundary_ids (std::vector< short int > &b_ids)Builds the list of unique node boundary ids.

Definition at line 558 of file boundary_info.C.

References _boundary_node_id.

{
  b_ids.clear();

  std::multimap<const Node*, short int>::const_iterator pos
    = _boundary_node_id.begin();

  for (; pos != _boundary_node_id.end(); ++pos)
    {
      short int id = pos->second;
      
      if(std::find(b_ids.begin(),b_ids.end(),id) == b_ids.end())
        b_ids.push_back(id);
    }
}
 

void BoundaryInfo::build_node_list (std::vector< unsigned int > &nl, std::vector< short int > &il) constCreates a list of nodes and ids for those nodes.

Definition at line 617 of file boundary_info.C.

References _boundary_node_id.

{
  // Reserve the size, then use push_back
  nl.reserve (_boundary_node_id.size());
  il.reserve (_boundary_node_id.size());
  
  std::multimap<const Node*, short int>::const_iterator pos
    = _boundary_node_id.begin();

  for (; pos != _boundary_node_id.end(); ++pos)
    {
      nl.push_back (pos->first->id());
      il.push_back (pos->second);
    }
}
 

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 636 of file boundary_info.C.

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

{
  std::multimap<const Elem*,
                std::pair<unsigned short int,
                          short int> >::const_iterator pos;
  
  //Loop over the side list
  for (pos=_boundary_side_id.begin(); pos != _boundary_side_id.end(); ++pos)
  {
    //Need to loop over the sides of any possible children
    std::vector< const Elem * > family;
#ifdef LIBMESH_ENABLE_AMR
    pos->first->active_family_tree_by_side (family, pos->second.first);
#else
    family.push_back(pos->first);
#endif

    for(unsigned int elem_it=0; elem_it < family.size(); elem_it++)
    {
      const Elem * cur_elem = family[elem_it];
      
      AutoPtr<Elem> side = cur_elem->build_side(pos->second.first);

      //Add each node node on the side with the side's boundary id
      for(unsigned int i=0; i<side->n_nodes(); i++)
      {
        Node * node = side->get_node(i);
        
        this->add_node(node, pos->second.second);
      }
    }
  }
}
 

void BoundaryInfo::build_side_boundary_ids (std::vector< short int > &b_ids)Builds the list of unique side boundary ids.

Definition at line 574 of file boundary_info.C.

References _boundary_side_id.

{
  b_ids.clear();

  std::multimap<const Elem*, std::pair<unsigned short int, short int> >::const_iterator pos
    = _boundary_side_id.begin();

  for (; pos != _boundary_side_id.end(); ++pos)
    {
      short int id = pos->second.second;
      
      if(std::find(b_ids.begin(),b_ids.end(),id) == b_ids.end())
        b_ids.push_back(id);
    }
}
 

void BoundaryInfo::build_side_list (std::vector< unsigned int > &el, std::vector< unsigned short int > &sl, std::vector< short int > &il) constCreates a list of element numbers, sides, and and ids for those sides.

Definition at line 670 of file boundary_info.C.

References _boundary_side_id.

{
  // Reserve the size, then use push_back
  el.reserve (_boundary_side_id.size());
  sl.reserve (_boundary_side_id.size());
  il.reserve (_boundary_side_id.size());

  std::multimap<const Elem*,
                std::pair<unsigned short int,
                          short int> >::const_iterator pos;

  for (pos=_boundary_side_id.begin(); pos != _boundary_side_id.end();
       ++pos)
    {
      el.push_back (pos->first->id());
      sl.push_back (pos->second.first);
      il.push_back (pos->second.second);
    }
}
 

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

{
  _boundary_node_id.clear();
  _boundary_side_id.clear();
  _boundary_ids.clear();
}
 

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.

  { return _boundary_ids; }
 

unsigned int BoundaryInfo::n_boundary_conds () constReturns:

the number of element-based boundary conditions.

Definition at line 590 of file boundary_info.C.

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

{
  // in serial we know the number of bcs from the
  // size of the container
  if (_mesh.is_serial())
    return _boundary_side_id.size();

  // in parallel we need to sum the number of local bcs
  parallel_only();
  
  unsigned int nbcs=0;

  std::multimap<const Elem*,
                std::pair<unsigned short int,
                          short int> >::const_iterator pos;

  for (pos=_boundary_side_id.begin(); pos != _boundary_side_id.end(); ++pos)
    if (pos->first->processor_id() == libMesh::processor_id())
      nbcs++;
  
  Parallel::sum (nbcs);
  
  return nbcs;
}
 

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.

{ return _boundary_ids.size(); }
 

void BoundaryInfo::print_info () constPrint the boundary information data structure.

Definition at line 694 of file boundary_info.C.

References _boundary_node_id, and _boundary_side_id.

{
  // Print out the nodal BCs
  if (!_boundary_node_id.empty())
    {
      std::cout << 'Nodal Boundary conditions:' << std::endl
                << '--------------------------' << std::endl
                << '  (Node No., ID)               ' << std::endl;

//       std::for_each(_boundary_node_id.begin(),
//                  _boundary_node_id.end(),
//                  PrintNodeInfo());

      std::multimap<const Node*, short int>::const_iterator it        = _boundary_node_id.begin();
      const std::multimap<const Node*, short int>::const_iterator end = _boundary_node_id.end();

      for (; it != end; ++it)
        std::cout << '  (' << (*it).first->id()
                  << ', '  << (*it).second
                  << ')'  << std::endl;
    }
  
  // Print out the element BCs
  if (!_boundary_side_id.empty())
    {
      std::cout << std::endl
                << 'Side Boundary conditions:' << std::endl
                << '-------------------------' << std::endl
                << '  (Elem No., Side No., ID)      ' << std::endl;

//       std::for_each(_boundary_side_id.begin(),
//                  _boundary_side_id.end(),
//                  PrintSideInfo());

      std::multimap<const Elem*,
        std::pair<unsigned short int, short int> >::const_iterator it = _boundary_side_id.begin();
      const std::multimap<const Elem*,
        std::pair<unsigned short int, short int> >::const_iterator end = _boundary_side_id.end();

     for (; it != end; ++it)
       std::cout << '  (' << (*it).first->id()
                 << ', '  << (*it).second.first
                 << ', '  << (*it).second.second 
                 << ')'   << std::endl;
    }
}
 

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.

{
  libmesh_assert (elem != NULL);
  
  // Erase everything associated with elem
  _boundary_side_id.erase (elem);
}
 

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.

{
  libmesh_assert (node != NULL);
  
  // Erase everything associated with node
  _boundary_node_id.erase (node);
}
 

void BoundaryInfo::remove_side (const Elem *elem, const unsigned short intside, const short intid)Removes the boundary id id from side side of element elem, if it exists.

Definition at line 491 of file boundary_info.C.

References _boundary_side_id, and Elem::level().

{
  libmesh_assert (elem != NULL);

  // The user shouldn't be trying to remove only one child's boundary
  // id
  libmesh_assert (elem->level() == 0);
  
  std::pair<std::multimap<const Elem*,
                          std::pair<unsigned short int, short int> >::iterator,
            std::multimap<const Elem*,
                          std::pair<unsigned short int, short int> >::iterator > 
    e = _boundary_side_id.equal_range(elem);

  // elem may be there, maybe multiple occurances
  while (e.first != e.second)
    {
      // if this is true we found the requested side
      // of the element and want to erase the requested id
      if (e.first->second.first == side &&
          e.first->second.second == id)
        {
          // (postfix++ - increment the iterator before it's invalid)
          _boundary_side_id.erase(e.first++);
        }
      else
        ++e.first;
    }
}
 

void BoundaryInfo::remove_side (const Elem *elem, const unsigned short intside)Removes all boundary conditions associated with side side of element elem, if any exist.

Definition at line 459 of file boundary_info.C.

References _boundary_side_id, and Elem::level().

{
  libmesh_assert (elem != NULL);

  // The user shouldn't be trying to remove only one child's boundary
  // id
  libmesh_assert (elem->level() == 0);
  
  std::pair<std::multimap<const Elem*,
                          std::pair<unsigned short int, short int> >::iterator,
            std::multimap<const Elem*,
                          std::pair<unsigned short int, short int> >::iterator > 
    e = _boundary_side_id.equal_range(elem);

  // elem may be there, maybe multiple occurances
  while (e.first != e.second)
    {
      // if this is true we found the requested side
      // of the element and want to erase the id
      if (e.first->second.first == side)
        {
          // (postfix++ - increment the iterator before it's invalid)
          _boundary_side_id.erase(e.first++);
        }
      else
        ++e.first;
    }
}
 

unsigned int BoundaryInfo::side_with_boundary_id (const Elem *constelem, const unsigned short intboundary_id) constReturns 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 525 of file boundary_info.C.

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

{
  const Elem* searched_elem = elem;
  if (elem->level() != 0)
    searched_elem = elem->top_parent();

  std::pair<std::multimap<const Elem*,
                          std::pair<unsigned short int, short int> >::const_iterator,
            std::multimap<const Elem*,
                          std::pair<unsigned short int, short int> >::const_iterator > 
    e = _boundary_side_id.equal_range(searched_elem);

  // elem not in the data structure
  if (e.first == e.second)
    return libMesh::invalid_uint;

  // elem is there, maybe multiple occurances
  while (e.first != e.second)
    {
      // if this is true we found the requested boundary_id
      // of the element and want to return the side
      if (e.first->second.second == boundary_id)
        return e.first->second.first;

      ++e.first;
    }

  // if we get here, we found elem in the data structure but not
  // the requested boundary id, so return the default value
  return libMesh::invalid_uint;  
}
 

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 204 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(), MeshBase::n_subdomains(), 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(), MeshBase::set_n_subdomains(), Elem::set_node(), Partitioner::set_node_processor_ids(), Elem::set_parent(), Elem::subdomain_id(), and Elem::top_parent().

{
  // Re-create the boundary mesh.
  boundary_mesh.clear();
    
  boundary_mesh.set_n_subdomains() = _mesh.n_subdomains();
  boundary_mesh.set_n_partitions() = _mesh.n_partitions();

  // Make individual copies of all the nodes in the current mesh
  // and add them to the boundary mesh.  Yes, this is overkill because
  // all of the current mesh nodes will not end up in the the boundary
  // mesh.  These nodes can be trimmed later via a call to prepare_for_use().
  {
    libmesh_assert (boundary_mesh.n_nodes() == 0);
    boundary_mesh.reserve_nodes(_mesh.n_nodes());
    
    MeshBase::const_node_iterator it  = _mesh.nodes_begin();
    MeshBase::const_node_iterator end = _mesh.nodes_end();
    
    for(; it != end; ++it)
      {
        const Node* node = *it;
        boundary_mesh.add_point(*node); // calls Node::build(Point, id)
      }
  }

  // Add additional sides that aren't flagged with boundary conditions
  MeshBase::const_element_iterator       el     = _mesh.active_elements_begin();
  const MeshBase::const_element_iterator end_el = _mesh.active_elements_end(); 

  for ( ; el != end_el; ++el)
    {
      const Elem* elem = *el;
      
      for (unsigned int s=0; s<elem->n_sides(); s++)
        if (elem->neighbor(s) == NULL) // on the boundary
          {
            // Get the top-level parent for this element
            const Elem* top_parent = elem->top_parent();

            // A convenient typedef
            typedef
              std::multimap<const Elem*, std::pair<unsigned short int, short int> >::const_iterator
              Iter;
              
            // Find all the bcs asociated with top_parent
            std::pair<Iter, Iter> pos = _boundary_side_id.equal_range(top_parent);

            // look for a bcid which is (i) in the user-requested set, and
            // (ii) matches the current side #s
            while (pos.first != pos.second)
              {
                // if this side is flagged with a boundary condition
                // and the user wants this id
                if ((pos.first->second.first == s) &&
                    (requested_boundary_ids.count(pos.first->second.second)))
                  {
                    // Build the side - do not use a 'proxy' element here:
                    // This will be going into the BoundaryMesh and needs to
                    // stand on its own.
                    AutoPtr<Elem> side (elem->build_side(s, false));
                    
                    // inherit processor_id and subdomain_id from parent
                    side->subdomain_id() = elem->subdomain_id();
                    side->processor_id() = elem->processor_id();

                    // Add the side
                    Elem* new_elem = boundary_mesh.add_elem(side.release());

                    // and set the parent
                    new_elem->set_parent (const_cast<Elem*>(elem));

                    // This side's Node pointers still point to the nodes of the  original mesh.
                    // We need to re-point them to the boundary mesh's nodes!  Since we copied *ALL* of
                    // the original mesh's nodes over, we should be guaranteed to have the same ordering.
                    for (unsigned int nn=0; nn<new_elem->n_nodes(); ++nn)
                      {
                        // Get the correct node pointer, based on the id()
                        Node* new_node = boundary_mesh.node_ptr(new_elem->node(nn));
                        
                        // sanity check: be sure that the new Nodes global id really matches
                        libmesh_assert (new_node->id() == new_elem->node(nn));

                        // Assign the new node pointer
                        new_elem->set_node(nn) = new_node;
                      }

                    // go on to the next side
                    break;
                  }
                
                ++pos.first;
              } // end loop over bcs matching top_parent
            
          } // end if neighbor is NULL
    } // end loop over active elements

  // Don't repartition this mesh; but rather inherit the partitioning
  boundary_mesh.partitioner().reset(NULL);
  
  // Trim any un-used nodes from the Mesh
  boundary_mesh.prepare_for_use();

  // and finally distribute element partitioning to the nodes
  Partitioner::set_node_processor_ids(boundary_mesh);
}
 

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(), MeshBase::set_n_subdomains(), Elem::set_node(), and Elem::top_parent().

{
  boundary_mesh.clear();

  // Map boundary ids to side subdomain/partition ids
  std::map<short int, unsigned int> id_map;

  // Original Code
  //     unsigned int cnt = 0;
  //     for (std::set<short int>::iterator pos = boundary_ids.begin();
  //     pos != boundary_ids.end(); ++pos)
  //       id_map[*pos] = cnt++;
  
  //     id_map[invalid_id] = cnt;

    
  // New code
  // Here we need to use iota() once it is in the
  // Utility namespace.
  std::for_each(_boundary_ids.begin(),
                _boundary_ids.end(),
                Fill(id_map));
    
  boundary_mesh.set_n_subdomains() = id_map.size();
  boundary_mesh.set_n_partitions() = id_map.size();


  // Make individual copies of all the nodes in the current mesh
  // and add them to the boundary mesh.  Yes, this is overkill because
  // all of the current mesh nodes will not end up in the the boundary
  // mesh.  These nodes can be trimmed later via a call to prepare_for_use().
  {
    libmesh_assert (boundary_mesh.n_nodes() == 0);
    boundary_mesh.reserve_nodes(_mesh.n_nodes());
    
    MeshBase::const_node_iterator it  = _mesh.nodes_begin();
    MeshBase::const_node_iterator end = _mesh.nodes_end();
    
    for(; it != end; ++it)
      {
        const Node* node = *it;
        boundary_mesh.add_point(*node); // calls Node::build(Point, id)
      }
  }

  // Add additional sides that aren't flagged with boundary conditions
  MeshBase::const_element_iterator       el     = _mesh.active_elements_begin();
  const MeshBase::const_element_iterator end_el = _mesh.active_elements_end(); 

  for ( ; el != end_el; ++el)
    {
      const Elem* elem = *el;
      
      for (unsigned int s=0; s<elem->n_sides(); s++)
        if (elem->neighbor(s) == NULL) // on the boundary
          {

            // Build the side - do not use a 'proxy' element here:
            // This will be going into the BoundaryMesh and needs to
            // stand on its own.
            AutoPtr<Elem> side (elem->build_side(s, false));
            
            // Get the top-level parent for this element
            const Elem* top_parent = elem->top_parent();

            // A convenient typedef
            typedef
              std::multimap<const Elem*, std::pair<unsigned short int, short int> >::const_iterator
              Iter;
              
            // Find the right id number for that side
            std::pair<Iter, Iter> pos = _boundary_side_id.equal_range(top_parent);

            while (pos.first != pos.second)
              {
                if (pos.first->second.first == s) // already flagged with a boundary condition
                  {
                    side->subdomain_id() =
                      id_map[pos.first->second.second];
                    break;
                  }
                
                ++pos.first;
              }

            // either the element wasn't found or side s
            // doesn't have a boundary condition
            if (pos.first == pos.second)
              {
                side->subdomain_id() = id_map[invalid_id];
              }

            side->processor_id() = side->subdomain_id(); //elem->processor_id();
            
            // Add the side
            Elem* new_elem = boundary_mesh.add_elem(side.release());

            // This side's Node pointers still point to the nodes of the  original mesh.
            // We need to re-point them to the boundary mesh's nodes!  Since we copied *ALL* of
            // the original mesh's nodes over, we should be guaranteed to have the same ordering.
            for (unsigned int nn=0; nn<new_elem->n_nodes(); ++nn)
              {
                // Get the correct node pointer, based on the id()
                Node* new_node = boundary_mesh.node_ptr(new_elem->node(nn));
                
                // sanity check: be sure that the new Nodes global id really matches
                libmesh_assert (new_node->id() == new_elem->node(nn));

                // Assign the new node pointer
                new_elem->set_node(nn) = new_node;
              }
          }
    } // end loop over active elements

  
  
  // When desired, copy the MeshData
  // to the boundary_mesh
  if ((boundary_mesh_data != NULL) && (this_mesh_data != NULL))
    boundary_mesh_data->assign(*this_mesh_data);

  // Don't repartition this mesh; we're using the processor_id values
  // as a hack to display bcids for now.
  boundary_mesh.partitioner().reset(NULL);

  // Trim any un-used nodes from the Mesh
  boundary_mesh.prepare_for_use();
}
 

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]Data structure that maps sides of elements to boundary ids.

Definition at line 275 of file boundary_info.h.

Referenced by add_side(), boundary_id(), build_node_list_from_side_list(), build_side_boundary_ids(), build_side_list(), clear(), n_boundary_conds(), print_info(), remove(), remove_side(), side_with_boundary_id(), and sync().  

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

 

Author

Generated automatically by Doxygen for libMesh from the source code.


 

Index

NAME
SYNOPSIS
Classes
Public Member Functions
Static Public Attributes
Protected Member Functions
Private Attributes
Friends
Detailed Description
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.
BoundaryInfo::~BoundaryInfo ()Destructor. Not much to do.
Member Function Documentation
void BoundaryInfo::add_node (const Node *node, const short intid)Add Node node with boundary id id to the boundary information data structures.
void BoundaryInfo::add_node (const unsigned intnode, const short intid)Add node number node with boundary id id to the boundary information data structures.
void BoundaryInfo::add_side (const unsigned intelem, const unsigned short intside, const short intid)Add side side of element number elem with boundary id id to the boundary information data structure.
void BoundaryInfo::add_side (const Elem *elem, const unsigned short intside, const short intid)Add side side of element elem with boundary id id to the boundary information data structure.
short int BoundaryInfo::boundary_id (const Elem *constelem, const unsigned short intside) constReturns 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.
std::vector< short int > BoundaryInfo::boundary_ids (const Node *node) constReturns the boundary ids associated with Node node.
void BoundaryInfo::build_node_boundary_ids (std::vector< short int > &b_ids)Builds the list of unique node boundary ids.
void BoundaryInfo::build_node_list (std::vector< unsigned int > &nl, std::vector< short int > &il) constCreates a list of nodes and ids for those nodes.
void BoundaryInfo::build_node_list_from_side_list ()Adds nodes with boundary ids based on the side's boundary ids they are connected to.
void BoundaryInfo::build_side_boundary_ids (std::vector< short int > &b_ids)Builds the list of unique side boundary ids.
void BoundaryInfo::build_side_list (std::vector< unsigned int > &el, std::vector< unsigned short int > &sl, std::vector< short int > &il) constCreates a list of element numbers, sides, and and ids for those sides.
void BoundaryInfo::clear ()Clears the underlying data structures. Returns the object to a pristine state with no data stored.
const std::set<short int>& BoundaryInfo::get_boundary_ids () const [inline]Returns:
unsigned int BoundaryInfo::n_boundary_conds () constReturns:
unsigned int BoundaryInfo::n_boundary_ids () const [inline]Returns the number of user-specified boundary ids.
void BoundaryInfo::print_info () constPrint the boundary information data structure.
void BoundaryInfo::remove (const Elem *elem) [inline]Removes the boundary conditions associated with element elem, if any exist.
void BoundaryInfo::remove (const Node *node) [inline]Removes the boundary conditions associated with node node, if any exist.
void BoundaryInfo::remove_side (const Elem *elem, const unsigned short intside, const short intid)Removes the boundary id id from side side of element elem, if it exists.
void BoundaryInfo::remove_side (const Elem *elem, const unsigned short intside)Removes all boundary conditions associated with side side of element elem, if any exist.
unsigned int BoundaryInfo::side_with_boundary_id (const Elem *constelem, const unsigned short intboundary_id) constReturns 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.
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.
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.
Friends And Related Function Documentation
friend class MeshBase [friend]
Member Data Documentation
std::set<short int> BoundaryInfo::_boundary_ids [private]A collection of user-specified boundary ids.
std::multimap<const Node*, short int> BoundaryInfo::_boundary_node_id [private]Data structure that maps nodes in the mesh to boundary ids.
std::multimap<const Elem*, std::pair<unsigned short int, short int> > BoundaryInfo::_boundary_side_id [private]Data structure that maps sides of elements to boundary ids.
const MeshBase& BoundaryInfo::_mesh [private]The Mesh this boundary info pertains to.
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.
Author

This document was created by man2html, using the manual pages.
Time: 21:42:46 GMT, April 16, 2011