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