BoundaryInfo Class Reference
#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
TheBoundaryInfo 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().
| 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().
| 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] |
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().
The documentation for this class was generated from the following files: