The boundary specify in libmesh is limited. I added more routines to support 
boundary process during my work.

I hope these routines can be accepted by libmesh developers.



The two member functions for elem.C



/**

   * Same as the \p family_tree() member, but only adds elements

   * which are next to \p side.

   */

  void family_tree_by_side (std::vector<const Elem*>& family,

                          const unsigned int s,

                          const bool reset=true) const;





void Elem::family_tree_by_side (std::vector<const Elem*>& family,

                           const unsigned int s,

                                 const bool reset)  const

{

  // Clear the vector if the flag reset tells us to.

  if (reset)

    family.clear();



  assert( s<this->n_sides() );



  // Add this element to the family tree.

  family.push_back(this);



  // Recurse into the elements children, if it has them.

  // Do not clear the vector any more.

  if (!this->active())

    for (unsigned int c=0; c<this->n_children(); c++)

      if (this->child(c)->is_child_on_side(c, s))

        this->child(c)->family_tree_by_side (family, s, false);



}



//------------------------------------------------------------------------------



 /**

   * Same as the \p active_family_tree() member, but only adds elements

   * which are next to \p side.

   */

  void active_family_tree_by_side (std::vector<const Elem*>& family,

                                 const unsigned int s,

                                 const bool reset=true) const;



void Elem::active_family_tree_by_side (std::vector<const Elem*>& family,

                                     const unsigned int s,

                                     const bool reset) const

{



  // Clear the vector if the flag reset tells us to.

  if (reset)

    family.clear();



  assert( s<this->n_sides() );



  // Add an active element to the family tree.

  if (this->active())

    family.push_back(this);



  // Or recurse into an ancestor element's children.

  // Do not clear the vector any more.

  else

    for (unsigned int c=0; c<this->n_children(); c++)

      if (this->child(c)->is_child_on_side(c, s))

        this->child(c)->active_family_tree_by_side (family, s, false);

}





And the build_active_side_list function in boundary_info.C. with this 
function, One can access boundary side of active element.



  /**

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

   */

  void build_active_side_list (std::vector<unsigned int>&       el,

                            std::vector<unsigned short int>& sl,

                            std::vector<short int>&          il) const;



void BoundaryInfo::build_active_side_list (std::vector<unsigned int>& 
el,

    std::vector<unsigned short int>& sl,

    std::vector<short int>&          il) const

{

  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)

  {

    const Elem * elem = pos->first;

    if (elem->active() )

    {

      el.push_back (pos->first->id());

      sl.push_back (pos->second.first);

      il.push_back (pos->second.second);

    }

    // this element has child

    else

    {

      unsigned short int side = pos->second.first;

      std::vector<const Elem*> family;



      elem->active_family_tree_by_side(family, side);



      for(unsigned int n=0; n<family.size(); ++n)

      {

        el.push_back (family[n]->id());

        sl.push_back (side);

        il.push_back (pos->second.second);

      }



    }

  }



}





At last, an interesting function for set the boundary id to boundary node. 
Since some nodes are shared by side with different boundary id, a priority 
order should be provide for determine which boundary id these nodes have.

/**

   * build _boundary_node_id map with a priority order of boundary id

   * from boundary side. i.e. one node lies on the interface of two sides 
with

   * different boundary id, the id of this node will be determined by an 
priority order.

   */

  void build_node_ids_from_priority_order(const std::map<short int, unsigned 
int> & order);



void BoundaryInfo::build_node_ids_from_priority_order(const std::map<short 
int, unsigned int> & order)

{

  _boundary_node_id.clear();



  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)

  {

    const Elem* elem = (*pos).first;

    unsigned short int side = (*pos).second.first;

    short int bd_id = (*pos).second.second;



    std::vector<const Elem*> family;

    elem->active_family_tree_by_side(family, side);



    for(unsigned int f=0; f<family.size(); ++f)

    {

      const Elem* family_elem = family[f];

      AutoPtr<Elem> side_elem = family_elem->build_side(side);



      for (unsigned int n=0; n<side_elem->n_nodes(); ++n)

      {



        const Node * node = side_elem->get_node(n);



        std::map<const Node*, short int>::iterator it = 
_boundary_node_id.find(node);



        // the node is already exist

        if( it != _boundary_node_id.end()  )

        {

          // the bd id of existing node

          short int node_bd_id = (*it).second;



          //if current bd_id has a higher priority order, replace existing 
bd_id

          unsigned int o1 = (*order.find(bd_id)).second;

          unsigned int o2 = (*order.find(node_bd_id)).second;



          if(  o1 > o2  )

            _boundary_node_id[node] = bd_id;

        }

        // not exist yet? insert it

        else

          _boundary_node_id[node] = bd_id;



      }

    }

  }



}









-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
_______________________________________________
Libmesh-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/libmesh-users

Reply via email to