libMesh::MeshRefinement Class Reference
#include <mesh_refinement.h>
Detailed Description
This is the MeshRefinement class. This class implements adaptive mesh refinement algorithms for a MeshBase.
Definition at line 61 of file mesh_refinement.h.
Constructor & Destructor Documentation
| libMesh::MeshRefinement::MeshRefinement | ( | MeshBase & | mesh | ) | [explicit] |
Constructor.
Definition at line 55 of file mesh_refinement.C.
00055 : 00056 _mesh(m), 00057 _use_member_parameters(false), 00058 _coarsen_by_parents(false), 00059 _refine_fraction(0.3), 00060 _coarsen_fraction(0.0), 00061 _max_h_level(libMesh::invalid_uint), 00062 _coarsen_threshold(10), 00063 _nelem_target(0), 00064 _absolute_global_tolerance(0.0), 00065 _face_level_mismatch_limit(1), 00066 _edge_level_mismatch_limit(0), 00067 _node_level_mismatch_limit(0) 00068 #ifdef LIBMESH_ENABLE_PERIODIC 00069 , _periodic_boundaries(NULL) 00070 #endif 00071 { 00072 }
| libMesh::MeshRefinement::MeshRefinement | ( | const MeshRefinement & | ) | [private] |
| libMesh::MeshRefinement::~MeshRefinement | ( | ) |
Destructor. Deletes all the elements that are currently stored.
Definition at line 85 of file mesh_refinement.C.
References clear().
00086 { 00087 this->clear(); 00088 }
Member Function Documentation
| bool libMesh::MeshRefinement::_coarsen_elements | ( | ) | [private] |
Coarsens user-requested elements. Both coarsen_elements and refine_elements used to be in the public interface for the MeshRefinement object. Unfortunately, without proper preparation (make_refinement_compatible, make_coarsening_compatible) at least coarsen_elements() did not work alone. By making them private, we signal to the user that they are not part of the interface.
It is possible that for a given set of refinement flags there is actually no change upon calling this member function. Consequently, this function returns true if the mesh actually changed (hence data needs to be projected) and false otherwise.
Definition at line 1476 of file mesh_refinement.C.
References _mesh, _new_nodes_map, libMesh::Elem::active(), libMesh::MeshBase::boundary_info, clear(), libMesh::Elem::coarsen(), libMesh::Elem::COARSEN, libMesh::Elem::COARSEN_INACTIVE, libMesh::CommWorld, libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), end, libMesh::MeshBase::is_serial(), libMesh::Elem::JUST_COARSENED, libMesh::Elem::level(), libMesh::MeshTools::libmesh_assert_valid_procids< Node >(), libMesh::Parallel::Communicator::max(), libMesh::Elem::nullify_neighbors(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_level(), libMesh::Elem::set_p_refinement_flag(), update_nodes_map(), and libMesh::MeshBase::update_parallel_id_counts().
Referenced by coarsen_elements(), refine_and_coarsen_elements(), and uniformly_coarsen().
01477 { 01478 // This function must be run on all processors at once 01479 parallel_only(); 01480 01481 START_LOG ("_coarsen_elements()", "MeshRefinement"); 01482 01483 // Flag indicating if this call actually changes the mesh 01484 bool mesh_changed = false; 01485 01486 // Clear the unused_elements data structure. 01487 // The elements have been packed since it was built, 01488 // so there are _no_ unused elements. We cannot trust 01489 // any iterators currently in this data structure. 01490 // _unused_elements.clear(); 01491 01492 MeshBase::element_iterator it = _mesh.elements_begin(); 01493 const MeshBase::element_iterator end = _mesh.elements_end(); 01494 01495 // Loop over the elements. 01496 for ( ; it != end; ++it) 01497 { 01498 Elem* elem = *it; 01499 01500 // Not necessary when using elem_iterator 01501 // libmesh_assert(elem); 01502 01503 // active elements flagged for coarsening will 01504 // no longer be deleted until MeshRefinement::contract() 01505 if (elem->refinement_flag() == Elem::COARSEN) 01506 { 01507 // Huh? no level-0 element should be active 01508 // and flagged for coarsening. 01509 libmesh_assert_not_equal_to (elem->level(), 0); 01510 01511 // Remove this element from any neighbor 01512 // lists that point to it. 01513 elem->nullify_neighbors(); 01514 01515 // Remove any boundary information associated 01516 // with this element 01517 _mesh.boundary_info->remove (elem); 01518 01519 // Add this iterator to the _unused_elements 01520 // data structure so we might fill it. 01521 // The _unused_elements optimization is currently off. 01522 // _unused_elements.push_back (it); 01523 01524 // Don't delete the element until 01525 // MeshRefinement::contract() 01526 // _mesh.delete_elem(elem); 01527 01528 // the mesh has certainly changed 01529 mesh_changed = true; 01530 } 01531 01532 // inactive elements flagged for coarsening 01533 // will become active 01534 else if (elem->refinement_flag() == Elem::COARSEN_INACTIVE) 01535 { 01536 elem->coarsen(); 01537 libmesh_assert (elem->active()); 01538 01539 // the mesh has certainly changed 01540 mesh_changed = true; 01541 } 01542 if (elem->p_refinement_flag() == Elem::COARSEN) 01543 { 01544 if (elem->p_level() > 0) 01545 { 01546 elem->set_p_refinement_flag(Elem::JUST_COARSENED); 01547 elem->set_p_level(elem->p_level() - 1); 01548 mesh_changed = true; 01549 } 01550 else 01551 { 01552 elem->set_p_refinement_flag(Elem::DO_NOTHING); 01553 } 01554 } 01555 } 01556 01557 // If the mesh changed on any processor, it changed globally 01558 CommWorld.max(mesh_changed); 01559 // And we may need to update ParallelMesh values reflecting the changes 01560 if (mesh_changed) 01561 _mesh.update_parallel_id_counts(); 01562 01563 // Node processor ids may need to change if an element of that id 01564 // was coarsened away 01565 if (mesh_changed && !_mesh.is_serial()) 01566 { 01567 // Update the _new_nodes_map so that processors can 01568 // find requested nodes 01569 this->update_nodes_map (); 01570 01571 MeshCommunication().make_nodes_parallel_consistent 01572 (_mesh, _new_nodes_map); 01573 01574 // Clear the _new_nodes_map 01575 this->clear(); 01576 01577 #ifdef DEBUG 01578 MeshTools::libmesh_assert_valid_procids<Node>(_mesh); 01579 #endif 01580 } 01581 01582 STOP_LOG ("_coarsen_elements()", "MeshRefinement"); 01583 01584 return mesh_changed; 01585 }
| bool libMesh::MeshRefinement::_refine_elements | ( | ) | [private] |
Refines user-requested elements.
It is possible that for a given set of refinement flags there is actually no change upon calling this member function. Consequently, this function returns true if the mesh actually changed (hence data needs to be projected) and false otherwise.
Definition at line 1589 of file mesh_refinement.C.
References _mesh, _new_nodes_map, libMesh::Elem::active(), clear(), libMesh::CommWorld, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), end, libMesh::MeshBase::is_serial(), libMesh::Elem::JUST_REFINED, libMesh::MeshBase::libmesh_assert_valid_parallel_ids(), libMesh::Parallel::Communicator::max(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_level(), libMesh::Elem::set_p_refinement_flag(), update_nodes_map(), and libMesh::MeshBase::update_parallel_id_counts().
Referenced by refine_and_coarsen_elements(), refine_elements(), and uniformly_refine().
01590 { 01591 // This function must be run on all processors at once 01592 parallel_only(); 01593 01594 // Update the _new_nodes_map so that elements can 01595 // find nodes to connect to. 01596 this->update_nodes_map (); 01597 01598 START_LOG ("_refine_elements()", "MeshRefinement"); 01599 01600 // Iterate over the elements, counting the elements 01601 // flagged for h refinement. 01602 dof_id_type n_elems_flagged = 0; 01603 01604 MeshBase::element_iterator it = _mesh.elements_begin(); 01605 const MeshBase::element_iterator end = _mesh.elements_end(); 01606 01607 for (; it != end; ++it) 01608 { 01609 Elem* elem = *it; 01610 if (elem->refinement_flag() == Elem::REFINE) 01611 n_elems_flagged++; 01612 } 01613 01614 // Construct a local vector of Elem* which have been 01615 // previously marked for refinement. We reserve enough 01616 // space to allow for every element to be refined. 01617 std::vector<Elem*> local_copy_of_elements; 01618 local_copy_of_elements.reserve(n_elems_flagged); 01619 01620 // Iterate over the elements, looking for elements 01621 // flagged for refinement. 01622 for (it = _mesh.elements_begin(); it != end; ++it) 01623 { 01624 Elem* elem = *it; 01625 if (elem->refinement_flag() == Elem::REFINE) 01626 local_copy_of_elements.push_back(elem); 01627 if (elem->p_refinement_flag() == Elem::REFINE && 01628 elem->active()) 01629 { 01630 elem->set_p_level(elem->p_level()+1); 01631 elem->set_p_refinement_flag(Elem::JUST_REFINED); 01632 } 01633 } 01634 01635 // Now iterate over the local copies and refine each one. 01636 // This may resize the mesh's internal container and invalidate 01637 // any existing iterators. 01638 01639 for (std::size_t e = 0; e != local_copy_of_elements.size(); ++e) 01640 local_copy_of_elements[e]->refine(*this); 01641 01642 // The mesh changed if there were elements h refined 01643 bool mesh_changed = !local_copy_of_elements.empty(); 01644 01645 // If the mesh changed on any processor, it changed globally 01646 CommWorld.max(mesh_changed); 01647 01648 // And we may need to update ParallelMesh values reflecting the changes 01649 if (mesh_changed) 01650 _mesh.update_parallel_id_counts(); 01651 01652 if (mesh_changed && !_mesh.is_serial()) 01653 { 01654 MeshCommunication().make_elems_parallel_consistent (_mesh); 01655 MeshCommunication().make_nodes_parallel_consistent 01656 (_mesh, _new_nodes_map); 01657 #ifdef DEBUG 01658 _mesh.libmesh_assert_valid_parallel_ids(); 01659 #endif 01660 } 01661 01662 // Clear the _new_nodes_map and _unused_elements data structures. 01663 this->clear(); 01664 01665 STOP_LOG ("_refine_elements()", "MeshRefinement"); 01666 01667 return mesh_changed; 01668 }
| Real & libMesh::MeshRefinement::absolute_global_tolerance | ( | ) | [inline] |
If absolute_global_tolerance is set to a nonzero value, methods like flag_elements_by_global_tolerance() will attempt to reduce the global error of the mesh (defined as the square root of the sum of the squares of the errors on active elements) to below this tolerance.
absolute_global_tolerance is 0 by default.
Definition at line 692 of file mesh_refinement.h.
References _absolute_global_tolerance, and _use_member_parameters.
00693 { 00694 _use_member_parameters = true; 00695 return _absolute_global_tolerance; 00696 }
Adds the element elem to the mesh.
Definition at line 129 of file mesh_refinement.C.
References _mesh, and libMesh::MeshBase::add_elem().
Referenced by libMesh::Elem::refine().
00130 { 00131 libmesh_assert(elem); 00132 00133 00134 // // If the unused_elements has any iterators from 00135 // // old elements, take the first one 00136 // if (!_unused_elements.empty()) 00137 // { 00138 // std::vector<Elem*>::iterator it = _unused_elements.front(); 00139 00140 // *it = elem; 00141 00142 // _unused_elements.pop_front(); 00143 // } 00144 00145 // // Otherwise, use the conventional add method 00146 // else 00147 // { 00148 // _mesh.add_elem (elem); 00149 // } 00150 00151 // The _unused_elements optimization has been turned off. 00152 _mesh.add_elem (elem); 00153 00154 return elem; 00155 }
| void libMesh::MeshRefinement::add_p_to_h_refinement | ( | ) |
Takes a mesh whose elements are flagged for h refinement and coarsening, and adds flags to request p refinement and coarsening of the same elements.
Definition at line 677 of file mesh_refinement_flagging.C.
References _mesh, libMesh::MeshBase::elements_begin(), and libMesh::MeshBase::elements_end().
| Node * libMesh::MeshRefinement::add_point | ( | const Point & | p, | |
| const processor_id_type | processor_id, | |||
| const Real | tol | |||
| ) |
Add point p to the mesh. The function returns a pointer to the new node. The processor_id is assigned to the new node (only if no existing node is found. The tolerance tol tells the method how far away from p to search for existing nodes.
Definition at line 99 of file mesh_refinement.C.
References _mesh, _new_nodes_map, libMesh::MeshBase::add_point(), libMesh::LocationMap< T >::find(), libMesh::LocationMap< T >::insert(), and libMesh::DofObject::invalid_id.
Referenced by libMesh::Elem::refine().
00102 { 00103 START_LOG("add_point()", "MeshRefinement"); 00104 00105 // Return the node if it already exists 00106 Node *node = _new_nodes_map.find(p, tol); 00107 if (node) 00108 { 00109 STOP_LOG("add_point()", "MeshRefinement"); 00110 return node; 00111 } 00112 00113 // Add the node, with a default id and the requested 00114 // processor_id 00115 node = _mesh.add_point (p, DofObject::invalid_id, processor_id); 00116 00117 libmesh_assert(node); 00118 00119 // Add the node to the map. 00120 _new_nodes_map.insert(*node); 00121 00122 // Return the address of the new node 00123 STOP_LOG("add_point()", "MeshRefinement"); 00124 return node; 00125 }
| void libMesh::MeshRefinement::clean_refinement_flags | ( | ) |
Sets the refinement flag to Elem::DO_NOTHING for each element in the mesh.
Definition at line 688 of file mesh_refinement_flagging.C.
References _mesh, libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), and libMesh::Elem::INACTIVE.
Referenced by flag_elements_by_elem_fraction(), flag_elements_by_error_fraction(), flag_elements_by_nelem_target(), libMesh::EquationSystems::init(), libMesh::EquationSystems::read(), uniformly_coarsen(), and uniformly_refine().
00689 { 00690 // Possibly clean up the refinement flags from 00691 // a previous step 00692 // elem_iterator elem_it (_mesh.elements_begin()); 00693 // const elem_iterator elem_end(_mesh.elements_end()); 00694 00695 MeshBase::element_iterator elem_it = _mesh.elements_begin(); 00696 const MeshBase::element_iterator elem_end = _mesh.elements_end(); 00697 00698 for ( ; elem_it != elem_end; ++elem_it) 00699 { 00700 if ((*elem_it)->active()) 00701 { 00702 (*elem_it)->set_refinement_flag(Elem::DO_NOTHING); 00703 (*elem_it)->set_p_refinement_flag(Elem::DO_NOTHING); 00704 } 00705 else 00706 { 00707 (*elem_it)->set_refinement_flag(Elem::INACTIVE); 00708 (*elem_it)->set_p_refinement_flag(Elem::INACTIVE); 00709 } 00710 } 00711 }
| void libMesh::MeshRefinement::clear | ( | ) |
Deletes all the data that are currently stored.
Definition at line 92 of file mesh_refinement.C.
References _new_nodes_map, and libMesh::LocationMap< T >::clear().
Referenced by _coarsen_elements(), _refine_elements(), and ~MeshRefinement().
00093 { 00094 _new_nodes_map.clear(); 00095 }
| bool & libMesh::MeshRefinement::coarsen_by_parents | ( | ) | [inline] |
If coarsen_by_parents is true, complete groups of sibling elements (elements with the same parent) will be flagged for coarsening. This should make the coarsening more likely to occur as requested.
coarsen_by_parents is true by default.
Definition at line 656 of file mesh_refinement.h.
References _coarsen_by_parents, and _use_member_parameters.
00657 { 00658 _use_member_parameters = true; 00659 return _coarsen_by_parents; 00660 }
| bool libMesh::MeshRefinement::coarsen_elements | ( | const bool | maintain_level_one = true |
) |
Only coarsens the user-requested elements. Some elements will not be coarsened to satisfy the level one rule. It is possible that for a given set of refinement flags there is actually no change upon calling this member function. Consequently, this function returns true if the mesh actually changed (hence data needs to be projected) and false otherwise.
The argument maintain_level_one is now deprecated; use the option face_level_mismatch_limit() instead.
Definition at line 599 of file mesh_refinement.C.
References _coarsen_elements(), _edge_level_mismatch_limit, _face_level_mismatch_limit, _mesh, _node_level_mismatch_limit, libMesh::Elem::active(), libMesh::CommWorld, libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), eliminate_unrefined_patches(), libMesh::Elem::INACTIVE, libMesh::MeshBase::is_serial(), libMesh::Elem::JUST_REFINED, limit_level_mismatch_at_edge(), limit_level_mismatch_at_node(), make_coarsening_compatible(), make_flags_parallel_consistent(), libMesh::Parallel::Communicator::max(), libMesh::Parallel::Communicator::min(), libMesh::MeshBase::prepare_for_use(), libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), and test_level_one().
Referenced by libMesh::EquationSystems::reinit().
00600 { 00601 // This function must be run on all processors at once 00602 parallel_only(); 00603 00604 bool _maintain_level_one = maintain_level_one; 00605 00606 // If the user used non-default parameters, let's warn that they're 00607 // deprecated 00608 if (!maintain_level_one) 00609 { 00610 libmesh_deprecated(); 00611 } 00612 else 00613 _maintain_level_one = _face_level_mismatch_limit; 00614 00615 // We can't yet turn a non-level-one mesh into a level-one mesh 00616 if (_maintain_level_one) 00617 libmesh_assert(test_level_one(true)); 00618 00619 // Possibly clean up the refinement flags from 00620 // a previous step 00621 MeshBase::element_iterator elem_it = _mesh.elements_begin(); 00622 const MeshBase::element_iterator elem_end = _mesh.elements_end(); 00623 00624 for ( ; elem_it != elem_end; ++elem_it) 00625 { 00626 // Pointer to the element 00627 Elem* elem = *elem_it; 00628 00629 // Set refinement flag to INACTIVE if the 00630 // element isn't active 00631 if ( !elem->active()) 00632 { 00633 elem->set_refinement_flag(Elem::INACTIVE); 00634 elem->set_p_refinement_flag(Elem::INACTIVE); 00635 } 00636 00637 // This might be left over from the last step 00638 if (elem->refinement_flag() == Elem::JUST_REFINED) 00639 elem->set_refinement_flag(Elem::DO_NOTHING); 00640 } 00641 00642 // Parallel consistency has to come first, or coarsening 00643 // along processor boundaries might occasionally be falsely 00644 // prevented 00645 if (!_mesh.is_serial()) 00646 this->make_flags_parallel_consistent(); 00647 00648 // Repeat until flag changes match on every processor 00649 do 00650 { 00651 // Repeat until the flags form a conforming mesh. 00652 bool satisfied = false; 00653 do 00654 { 00655 const bool coarsening_satisfied = 00656 this->make_coarsening_compatible(maintain_level_one); 00657 00658 bool smoothing_satisfied = 00659 !this->eliminate_unrefined_patches();// && 00660 00661 if (_edge_level_mismatch_limit) 00662 smoothing_satisfied = smoothing_satisfied && 00663 !this->limit_level_mismatch_at_edge (_edge_level_mismatch_limit); 00664 00665 if (_node_level_mismatch_limit) 00666 smoothing_satisfied = smoothing_satisfied && 00667 !this->limit_level_mismatch_at_node (_node_level_mismatch_limit); 00668 00669 satisfied = (coarsening_satisfied && 00670 smoothing_satisfied); 00671 #ifdef DEBUG 00672 bool max_satisfied = satisfied, 00673 min_satisfied = satisfied; 00674 CommWorld.max(max_satisfied); 00675 CommWorld.min(min_satisfied); 00676 libmesh_assert_equal_to (satisfied, max_satisfied); 00677 libmesh_assert_equal_to (satisfied, min_satisfied); 00678 #endif 00679 } 00680 while (!satisfied); 00681 } 00682 while (!_mesh.is_serial() && !this->make_flags_parallel_consistent()); 00683 00684 // Coarsen the flagged elements. 00685 const bool mesh_changed = 00686 this->_coarsen_elements (); 00687 00688 if (_maintain_level_one) 00689 libmesh_assert(test_level_one(true)); 00690 libmesh_assert(this->make_coarsening_compatible(maintain_level_one)); 00691 // FIXME: This won't pass unless we add a redundant find_neighbors() 00692 // call or replace find_neighbors() with on-the-fly neighbor updating 00693 // libmesh_assert(!this->eliminate_unrefined_patches()); 00694 00695 // We can't contract the mesh ourselves anymore - a System might 00696 // need to restrict old coefficient vectors first 00697 // _mesh.contract(); 00698 00699 // Finally, the new mesh may need to be prepared for use 00700 if (mesh_changed) 00701 _mesh.prepare_for_use (/*skip_renumber =*/false); 00702 00703 return mesh_changed; 00704 }
| Real & libMesh::MeshRefinement::coarsen_fraction | ( | ) | [inline] |
The coarsen_fraction sets either a desired target or a desired maximum number of elements to flag for coarsening, depending on which flag_elements_by method is called.
coarsen_fraction must be in
, and is 0 by default.
Definition at line 668 of file mesh_refinement.h.
References _coarsen_fraction, and _use_member_parameters.
00669 { 00670 _use_member_parameters = true; 00671 return _coarsen_fraction; 00672 }
| Real & libMesh::MeshRefinement::coarsen_threshold | ( | ) | [inline] |
The coarsen_threshold provides hysteresis in AMR/C strategies. Refinement of elements with error estimate E will be done even at the expense of coarsening elements whose children's accumulated error does not exceed coarsen_threshold * E.
coarsen_threshold must be in
, and is 0.1 by default.
Definition at line 680 of file mesh_refinement.h.
References _coarsen_threshold, and _use_member_parameters.
00681 { 00682 _use_member_parameters = true; 00683 return _coarsen_threshold; 00684 }
| void libMesh::MeshRefinement::create_parent_error_vector | ( | const ErrorVector & | error_per_cell, | |
| ErrorVector & | error_per_parent, | |||
| Real & | parent_error_min, | |||
| Real & | parent_error_max | |||
| ) | [private] |
Calculates the error on all coarsenable parents. error_per_parent[parent_id] stores this error if parent_id corresponds to a coarsenable parent, and stores -1 otherwise.
Definition at line 160 of file mesh_refinement.C.
References libMesh::CommWorld, libMesh::DofObject::id(), std::max(), std::min(), libMesh::Parallel::Communicator::min(), libMesh::Elem::parent(), libMesh::Parallel::Communicator::sum(), and libMesh::Parallel::Communicator::verify().
Referenced by flag_elements_by_elem_fraction(), flag_elements_by_error_fraction(), flag_elements_by_error_tolerance(), and flag_elements_by_nelem_target().
00164 { 00165 // This function must be run on all processors at once 00166 parallel_only(); 00167 00168 // Make sure the input error vector is valid 00169 #ifdef DEBUG 00170 for (std::size_t i=0; i != error_per_cell.size(); ++i) 00171 { 00172 libmesh_assert_greater_equal (error_per_cell[i], 0); 00173 // isnan() isn't standard C++ yet 00174 #ifdef isnan 00175 libmesh_assert(!isnan(error_per_cell[i])); 00176 #endif 00177 } 00178 00179 // Use a reference to std::vector to avoid confusing 00180 // CommWorld.verify 00181 std::vector<ErrorVectorReal> &epc = error_per_parent; 00182 libmesh_assert(CommWorld.verify(epc)); 00183 #endif // #ifdef DEBUG 00184 00185 // error values on uncoarsenable elements will be left at -1 00186 error_per_parent.clear(); 00187 error_per_parent.resize(error_per_cell.size(), 0.0); 00188 00189 { 00190 // Find which elements are uncoarsenable 00191 MeshBase::element_iterator elem_it = _mesh.active_local_elements_begin(); 00192 const MeshBase::element_iterator elem_end = _mesh.active_local_elements_end(); 00193 for (; elem_it != elem_end; ++elem_it) 00194 { 00195 Elem* elem = *elem_it; 00196 Elem* parent = elem->parent(); 00197 00198 // Active elements are uncoarsenable 00199 error_per_parent[elem->id()] = -1.0; 00200 00201 // Grandparents and up are uncoarsenable 00202 while (parent) 00203 { 00204 parent = parent->parent(); 00205 if (parent) 00206 { 00207 const dof_id_type parentid = parent->id(); 00208 libmesh_assert_less (parentid, error_per_parent.size()); 00209 error_per_parent[parentid] = -1.0; 00210 } 00211 } 00212 } 00213 00214 // Sync between processors. 00215 // Use a reference to std::vector to avoid confusing 00216 // CommWorld.min 00217 std::vector<ErrorVectorReal> &epp = error_per_parent; 00218 CommWorld.min(epp); 00219 } 00220 00221 // The parent's error is defined as the square root of the 00222 // sum of the children's errors squared, so errors that are 00223 // Hilbert norms remain Hilbert norms. 00224 // 00225 // Because the children may be on different processors, we 00226 // calculate local contributions to the parents' errors squared 00227 // first, then sum across processors and take the square roots 00228 // second. 00229 { 00230 MeshBase::element_iterator elem_it = _mesh.active_local_elements_begin(); 00231 const MeshBase::element_iterator elem_end = _mesh.active_local_elements_end(); 00232 00233 for (; elem_it != elem_end; ++elem_it) 00234 { 00235 Elem* elem = *elem_it; 00236 Elem* parent = elem->parent(); 00237 00238 // Calculate each contribution to parent cells 00239 if (parent) 00240 { 00241 const dof_id_type parentid = parent->id(); 00242 libmesh_assert_less (parentid, error_per_parent.size()); 00243 00244 // If the parent has grandchildren we won't be able to 00245 // coarsen it, so forget it. Otherwise, add this child's 00246 // contribution to the sum of the squared child errors 00247 if (error_per_parent[parentid] != -1.0) 00248 error_per_parent[parentid] += (error_per_cell[elem->id()] * 00249 error_per_cell[elem->id()]); 00250 } 00251 } 00252 } 00253 00254 // Sum the vector across all processors 00255 CommWorld.sum(static_cast<std::vector<ErrorVectorReal>&>(error_per_parent)); 00256 00257 // Calculate the min and max as we loop 00258 parent_error_min = std::numeric_limits<double>::max(); 00259 parent_error_max = 0.; 00260 00261 for (std::size_t i = 0; i != error_per_parent.size(); ++i) 00262 { 00263 // If this element isn't a coarsenable parent with error, we 00264 // have nothing to do. Just flag it as -1 and move on 00265 // Note that CommWorld.sum might have left uncoarsenable 00266 // elements with error_per_parent=-n_proc, so reset it to 00267 // error_per_parent=-1 00268 if (error_per_parent[i] < 0.) 00269 { 00270 error_per_parent[i] = -1.; 00271 continue; 00272 } 00273 00274 // The error estimator might have already given us an 00275 // estimate on the coarsenable parent elements; if so then 00276 // we want to retain that estimate 00277 if (error_per_cell[i]) 00278 { 00279 error_per_parent[i] = error_per_cell[i]; 00280 continue; 00281 } 00282 // if not, then e_parent = sqrt(sum(e_child^2)) 00283 else 00284 error_per_parent[i] = std::sqrt(error_per_parent[i]); 00285 00286 parent_error_min = std::min (parent_error_min, 00287 error_per_parent[i]); 00288 parent_error_max = std::max (parent_error_max, 00289 error_per_parent[i]); 00290 } 00291 }
| unsigned char & libMesh::MeshRefinement::edge_level_mismatch_limit | ( | ) | [inline] |
If edge_level_mismatch_limit is set to a nonzero value, then refinement and coarsening will produce meshes in which the refinement level of two edge neighbors will not differ by more than that limit. If edge_level_mismatch_limit is 0, then level differences will be unlimited.
edge_level_mismatch_limit is 0 by default.
Definition at line 703 of file mesh_refinement.h.
References _edge_level_mismatch_limit.
00704 { 00705 return _edge_level_mismatch_limit; 00706 }
| bool libMesh::MeshRefinement::eliminate_unrefined_patches | ( | ) | [private] |
This algorithm selects an element for refinement if all of its neighbors are (or will be) refined. This algorithm will transform this mesh:
o---o---o---o---o---o---o | | | | | | | | | | | | | | o---o---o---o---o---o---o | | | | | | | | | | | | | | o---o---o---o---o---o---o | | | | | | | | | | | | o---o---o o---o---o | | | | | | | | | | | | o---o---o---o---o---o---o | | | | | | | | | | | | | | o---o---o---o---o---o---o | | | | | | | | | | | | | | o---o---o---o---o---o---o
into this:
o---o---o---o---o---o---o | | | | | | | | | | | | | | o---o---o---o---o---o---o | | | | | | | | | | | | | | o---o---o---o---o---o---o | | | : | | | | | | : | | | o---o---o...o...o---o---o | | | : | | | | | | : | | | o---o---o---o---o---o---o | | | | | | | | | | | | | | o---o---o---o---o---o---o | | | | | | | | | | | | | | o---o---o---o---o---o---o
by refining the indicated element
Definition at line 266 of file mesh_refinement_smoothing.C.
References _mesh, libMesh::Elem::active(), libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::Elem::ancestor(), libMesh::Elem::child(), libMesh::Elem::COARSEN, libMesh::Elem::COARSEN_INACTIVE, libMesh::CommWorld, libMesh::Elem::DO_NOTHING, libMesh::Elem::INACTIVE, libMesh::Elem::level(), libMesh::Parallel::Communicator::max(), libMesh::Elem::min_new_p_level_by_neighbor(), libMesh::Elem::n_children(), libMesh::Elem::n_neighbors(), libMesh::Elem::neighbor(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::Elem::parent(), libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::remote_elem, libMesh::Elem::set_p_refinement_flag(), and libMesh::Elem::set_refinement_flag().
Referenced by coarsen_elements(), refine_and_coarsen_elements(), and refine_elements().
00267 { 00268 // This function must be run on all processors at once 00269 parallel_only(); 00270 00271 bool flags_changed = false; 00272 00273 MeshBase::element_iterator elem_it = _mesh.active_elements_begin(); 00274 const MeshBase::element_iterator elem_end = _mesh.active_elements_end(); 00275 00276 for (; elem_it != elem_end; ++elem_it) 00277 { 00278 Elem* elem = *elem_it; 00279 // First assume that we'll have to flag this element for both h 00280 // and p refinement, then change our minds if we see any 00281 // neighbors that are as coarse or coarser than us. 00282 bool h_flag_me = true, 00283 p_flag_me = true; 00284 00285 00286 // Skip the element if it is already fully flagged for refinement 00287 if (elem->p_refinement_flag() == Elem::REFINE) 00288 p_flag_me = false; 00289 if (elem->refinement_flag() == Elem::REFINE) 00290 { 00291 h_flag_me = false; 00292 if (!p_flag_me) 00293 continue; 00294 } 00295 // Test the parent if that is already flagged for coarsening 00296 else if (elem->refinement_flag() == Elem::COARSEN) 00297 { 00298 libmesh_assert(elem->parent()); 00299 elem = elem->parent(); 00300 // FIXME - this doesn't seem right - RHS 00301 if (elem->refinement_flag() != Elem::COARSEN_INACTIVE) 00302 continue; 00303 p_flag_me = false; 00304 } 00305 00306 const unsigned int my_level = elem->level(); 00307 int my_p_adjustment = 0; 00308 if (elem->p_refinement_flag() == Elem::REFINE) 00309 my_p_adjustment = 1; 00310 else if (elem->p_refinement_flag() == Elem::COARSEN) 00311 { 00312 libmesh_assert_greater (elem->p_level(), 0); 00313 my_p_adjustment = -1; 00314 } 00315 const unsigned int my_new_p_level = elem->p_level() + 00316 my_p_adjustment; 00317 00318 // Check all the element neighbors 00319 for (unsigned int n=0; n<elem->n_neighbors(); n++) 00320 { 00321 const Elem *neighbor = elem->neighbor(n); 00322 // Quit if the element is on a local boundary 00323 if (neighbor == NULL || neighbor == remote_elem) 00324 { 00325 h_flag_me = false; 00326 p_flag_me = false; 00327 break; 00328 } 00329 // if the neighbor will be equally or less refined than 00330 // we are, then we will not become an unrefined island. 00331 // So if we are still considering h refinement: 00332 if (h_flag_me && 00333 // If our neighbor is already at a lower level, 00334 // it can't end up at a higher level even if it 00335 // is flagged for refinement once 00336 ((neighbor->level() < my_level) || 00337 // If our neighbor is at the same level but isn't 00338 // flagged for refinement, it won't end up at a 00339 // higher level 00340 ((neighbor->active()) && 00341 (neighbor->refinement_flag() != Elem::REFINE)) || 00342 // If our neighbor is currently more refined but is 00343 // a parent flagged for coarsening, it will end up 00344 // at the same level. 00345 (neighbor->refinement_flag() == Elem::COARSEN_INACTIVE))) 00346 { 00347 // We've proven we won't become an unrefined island, 00348 // so don't h refine to avoid that. 00349 h_flag_me = false; 00350 00351 // If we've also proven we don't need to p refine, 00352 // we don't need to check more neighbors 00353 if (!p_flag_me) 00354 break; 00355 } 00356 if (p_flag_me) 00357 { 00358 // if active neighbors will have a p level 00359 // equal to or lower than ours, then we do not need to p 00360 // refine ourselves. 00361 if (neighbor->active()) 00362 { 00363 int p_adjustment = 0; 00364 if (neighbor->p_refinement_flag() == Elem::REFINE) 00365 p_adjustment = 1; 00366 else if (neighbor->p_refinement_flag() == Elem::COARSEN) 00367 { 00368 libmesh_assert_greater (neighbor->p_level(), 0); 00369 p_adjustment = -1; 00370 } 00371 if (my_new_p_level >= neighbor->p_level() + p_adjustment) 00372 { 00373 p_flag_me = false; 00374 if (!h_flag_me) 00375 break; 00376 } 00377 } 00378 // If we have inactive neighbors, we need to 00379 // test all their active descendants which neighbor us 00380 else if (neighbor->ancestor()) 00381 { 00382 if (neighbor->min_new_p_level_by_neighbor(elem, 00383 my_new_p_level + 2) <= my_new_p_level) 00384 { 00385 p_flag_me = false; 00386 if (!h_flag_me) 00387 break; 00388 } 00389 } 00390 } 00391 } 00392 00393 if (h_flag_me) 00394 { 00395 // Parents that would create islands should no longer 00396 // coarsen 00397 if (elem->refinement_flag() == Elem::COARSEN_INACTIVE) 00398 { 00399 for (unsigned int c=0; c<elem->n_children(); c++) 00400 { 00401 libmesh_assert_equal_to (elem->child(c)->refinement_flag(), 00402 Elem::COARSEN); 00403 elem->child(c)->set_refinement_flag(Elem::DO_NOTHING); 00404 } 00405 elem->set_refinement_flag(Elem::INACTIVE); 00406 } 00407 else 00408 elem->set_refinement_flag(Elem::REFINE); 00409 flags_changed = true; 00410 } 00411 if (p_flag_me) 00412 { 00413 if (elem->p_refinement_flag() == Elem::COARSEN) 00414 elem->set_p_refinement_flag(Elem::DO_NOTHING); 00415 else 00416 elem->set_p_refinement_flag(Elem::REFINE); 00417 flags_changed = true; 00418 } 00419 } 00420 00421 // If flags changed on any processor then they changed globally 00422 CommWorld.max(flags_changed); 00423 00424 return flags_changed; 00425 }
| unsigned char & libMesh::MeshRefinement::face_level_mismatch_limit | ( | ) | [inline] |
If face_level_mismatch_limit is set to a nonzero value, then refinement and coarsening will produce meshes in which the refinement level of two face neighbors will not differ by more than that limit. If face_level_mismatch_limit is 0, then level differences will be unlimited.
face_level_mismatch_limit is 1 by default. Currently the only supported options are 0 and 1.
Definition at line 698 of file mesh_refinement.h.
References _face_level_mismatch_limit.
Referenced by libMesh::EquationSystems::reinit().
00699 { 00700 return _face_level_mismatch_limit; 00701 }
| void libMesh::MeshRefinement::flag_elements_by_elem_fraction | ( | const ErrorVector & | error_per_cell, | |
| const Real | refine_fraction = 0.3, |
|||
| const Real | coarsen_fraction = 0.0, |
|||
| const unsigned int | max_level = libMesh::invalid_uint | |||
| ) |
Flags elements for coarsening and refinement based on the computed error passed in error_per_cell. This method picks the top refine_fraction * n_elem elements for refinement and the bottom coarsen_fraction * n_elem elements for coarsening. The two fractions refine_fraction and coarsen_fraction must be in
.
All the function arguments except error_per_cell have been deprecated, and will be removed in future libMesh releases - to control these parameters, set the corresponding member variables.
Definition at line 452 of file mesh_refinement_flagging.C.
References _coarsen_by_parents, _coarsen_fraction, _max_h_level, _mesh, _refine_fraction, _use_member_parameters, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_local_elements_begin(), libMesh::MeshBase::active_local_elements_end(), libMesh::Parallel::Communicator::allgather(), clean_refinement_flags(), libMesh::Elem::COARSEN, libMesh::CommWorld, create_parent_error_vector(), libMesh::ErrorVectorReal, libMesh::DofObject::id(), libMesh::invalid_uint, libMesh::Elem::level(), libMesh::MeshBase::mesh_dimension(), libMesh::MeshBase::n_elem(), libMesh::Elem::parent(), libMesh::Real, libMesh::Elem::REFINE, and libMesh::Elem::set_refinement_flag().
00456 { 00457 parallel_only(); 00458 00459 // The function arguments are currently just there for 00460 // backwards_compatibility 00461 if (!_use_member_parameters) 00462 { 00463 // If the user used non-default parameters, lets warn 00464 // that they're deprecated 00465 if (refine_frac != 0.3 || 00466 coarsen_frac != 0.0 || 00467 max_l != libMesh::invalid_uint) 00468 libmesh_deprecated(); 00469 00470 _refine_fraction = refine_frac; 00471 _coarsen_fraction = coarsen_frac; 00472 _max_h_level = max_l; 00473 } 00474 00475 // Check for valid fractions.. 00476 // The fraction values must be in [0,1] 00477 libmesh_assert_greater_equal (_refine_fraction, 0); 00478 libmesh_assert_less_equal (_refine_fraction, 1); 00479 libmesh_assert_greater_equal (_coarsen_fraction, 0); 00480 libmesh_assert_less_equal (_coarsen_fraction, 1); 00481 00482 // The number of active elements in the mesh 00483 const dof_id_type n_active_elem = _mesh.n_elem(); 00484 00485 // The number of elements to flag for coarsening 00486 const dof_id_type n_elem_coarsen = 00487 static_cast<dof_id_type>(_coarsen_fraction * n_active_elem); 00488 00489 // The number of elements to flag for refinement 00490 const dof_id_type n_elem_refine = 00491 static_cast<dof_id_type>(_refine_fraction * n_active_elem); 00492 00493 00494 00495 // Clean up the refinement flags. These could be left 00496 // over from previous refinement steps. 00497 this->clean_refinement_flags(); 00498 00499 00500 // This vector stores the error and element number for all the 00501 // active elements. It will be sorted and the top & bottom 00502 // elements will then be flagged for coarsening & refinement 00503 std::vector<ErrorVectorReal> sorted_error; 00504 00505 sorted_error.reserve (n_active_elem); 00506 00507 // Loop over the active elements and create the entry 00508 // in the sorted_error vector 00509 MeshBase::element_iterator elem_it = _mesh.active_local_elements_begin(); 00510 const MeshBase::element_iterator elem_end = _mesh.active_local_elements_end(); 00511 00512 for (; elem_it != elem_end; ++elem_it) 00513 sorted_error.push_back (error_per_cell[(*elem_it)->id()]); 00514 00515 CommWorld.allgather(sorted_error); 00516 00517 // Now sort the sorted_error vector 00518 std::sort (sorted_error.begin(), sorted_error.end()); 00519 00520 // If we're coarsening by parents: 00521 // Create a sorted error vector with coarsenable parent elements 00522 // only, sorted by lowest errors first 00523 ErrorVector error_per_parent, sorted_parent_error; 00524 if (_coarsen_by_parents) 00525 { 00526 Real parent_error_min, parent_error_max; 00527 00528 create_parent_error_vector(error_per_cell, 00529 error_per_parent, 00530 parent_error_min, 00531 parent_error_max); 00532 00533 sorted_parent_error = error_per_parent; 00534 std::sort (sorted_parent_error.begin(), sorted_parent_error.end()); 00535 00536 // All the other error values will be 0., so get rid of them. 00537 sorted_parent_error.erase (std::remove(sorted_parent_error.begin(), 00538 sorted_parent_error.end(), 0.), 00539 sorted_parent_error.end()); 00540 } 00541 00542 00543 ErrorVectorReal top_error= 0., bottom_error = 0.; 00544 00545 // Get the maximum error value corresponding to the 00546 // bottom n_elem_coarsen elements 00547 if (_coarsen_by_parents && n_elem_coarsen) 00548 { 00549 const unsigned int dim = _mesh.mesh_dimension(); 00550 unsigned int twotodim = 1; 00551 for (unsigned int i=0; i!=dim; ++i) 00552 twotodim *= 2; 00553 00554 dof_id_type n_parent_coarsen = n_elem_coarsen / (twotodim - 1); 00555 00556 if (n_parent_coarsen) 00557 bottom_error = sorted_parent_error[n_parent_coarsen - 1]; 00558 } 00559 else if (n_elem_coarsen) 00560 { 00561 bottom_error = sorted_error[n_elem_coarsen - 1]; 00562 } 00563 00564 if (n_elem_refine) 00565 top_error = sorted_error[sorted_error.size() - n_elem_refine]; 00566 00567 // Finally, let's do the element flagging 00568 elem_it = _mesh.active_elements_begin(); 00569 for (; elem_it != elem_end; ++elem_it) 00570 { 00571 Elem* elem = *elem_it; 00572 Elem* parent = elem->parent(); 00573 00574 if (_coarsen_by_parents && parent && n_elem_coarsen && 00575 error_per_parent[parent->id()] <= bottom_error) 00576 elem->set_refinement_flag(Elem::COARSEN); 00577 00578 if (!_coarsen_by_parents && n_elem_coarsen && 00579 error_per_cell[elem->id()] <= bottom_error) 00580 elem->set_refinement_flag(Elem::COARSEN); 00581 00582 if (n_elem_refine && 00583 elem->level() < _max_h_level && 00584 error_per_cell[elem->id()] >= top_error) 00585 elem->set_refinement_flag(Elem::REFINE); 00586 } 00587 }
| void libMesh::MeshRefinement::flag_elements_by_error_fraction | ( | const ErrorVector & | error_per_cell, | |
| const Real | refine_fraction = 0.3, |
|||
| const Real | coarsen_fraction = 0.0, |
|||
| const unsigned int | max_level = libMesh::invalid_uint | |||
| ) |
Flags elements for coarsening and refinement based on the computed error passed in error_per_cell. The two fractions refine_fraction and coarsen_fraction must be in
.
All the function arguments except error_per_cell have been deprecated, and will be removed in future libMesh releases - to control these parameters, set the corresponding member variables.
Definition at line 45 of file mesh_refinement_flagging.C.
References _coarsen_by_parents, _coarsen_fraction, _max_h_level, _mesh, _refine_fraction, _use_member_parameters, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::MeshBase::active_local_elements_begin(), libMesh::MeshBase::active_local_elements_end(), clean_refinement_flags(), libMesh::Elem::COARSEN, libMesh::CommWorld, create_parent_error_vector(), libMesh::ErrorVectorReal, libMesh::DofObject::id(), libMesh::invalid_uint, libMesh::Elem::level(), libMesh::Parallel::Communicator::max(), std::max(), libMesh::Parallel::Communicator::min(), std::min(), libMesh::Elem::parent(), libMesh::Real, libMesh::Elem::REFINE, and libMesh::Elem::set_refinement_flag().
00049 { 00050 parallel_only(); 00051 00052 // The function arguments are currently just there for 00053 // backwards_compatibility 00054 if (!_use_member_parameters) 00055 { 00056 // If the user used non-default parameters, lets warn 00057 // that they're deprecated 00058 if (refine_frac != 0.3 || 00059 coarsen_frac != 0.0 || 00060 max_l != libMesh::invalid_uint) 00061 libmesh_deprecated(); 00062 00063 _refine_fraction = refine_frac; 00064 _coarsen_fraction = coarsen_frac; 00065 _max_h_level = max_l; 00066 } 00067 00068 // Check for valid fractions.. 00069 // The fraction values must be in [0,1] 00070 libmesh_assert_greater_equal (_refine_fraction, 0); 00071 libmesh_assert_less_equal (_refine_fraction, 1); 00072 libmesh_assert_greater_equal (_coarsen_fraction, 0); 00073 libmesh_assert_less_equal (_coarsen_fraction, 1); 00074 00075 // Clean up the refinement flags. These could be left 00076 // over from previous refinement steps. 00077 this->clean_refinement_flags(); 00078 00079 // We're getting the minimum and maximum error values 00080 // for the ACTIVE elements 00081 Real error_min = 1.e30; 00082 Real error_max = 0.; 00083 00084 // And, if necessary, for their parents 00085 Real parent_error_min = 1.e30; 00086 Real parent_error_max = 0.; 00087 00088 // Prepare another error vector if we need to sum parent errors 00089 ErrorVector error_per_parent; 00090 if (_coarsen_by_parents) 00091 { 00092 create_parent_error_vector(error_per_cell, 00093 error_per_parent, 00094 parent_error_min, 00095 parent_error_max); 00096 } 00097 00098 // We need to loop over all active elements to find the minimum 00099 MeshBase::element_iterator el_it = 00100 _mesh.active_local_elements_begin(); 00101 const MeshBase::element_iterator el_end = 00102 _mesh.active_local_elements_end(); 00103 00104 for (; el_it != el_end; ++el_it) 00105 { 00106 const dof_id_type id = (*el_it)->id(); 00107 libmesh_assert_less (id, error_per_cell.size()); 00108 00109 error_max = std::max (error_max, error_per_cell[id]); 00110 error_min = std::min (error_min, error_per_cell[id]); 00111 } 00112 CommWorld.max(error_max); 00113 CommWorld.min(error_min); 00114 00115 // Compute the cutoff values for coarsening and refinement 00116 const Real error_delta = (error_max - error_min); 00117 const Real parent_error_delta = parent_error_max - parent_error_min; 00118 00119 const Real refine_cutoff = (1.- _refine_fraction)*error_max; 00120 const Real coarsen_cutoff = _coarsen_fraction*error_delta + error_min; 00121 const Real parent_cutoff = _coarsen_fraction*parent_error_delta + error_min; 00122 00123 // // Print information about the error 00124 // libMesh::out << " Error Information:" << std::endl 00125 // << " ------------------" << std::endl 00126 // << " min: " << error_min << std::endl 00127 // << " max: " << error_max << std::endl 00128 // << " delta: " << error_delta << std::endl 00129 // << " refine_cutoff: " << refine_cutoff << std::endl 00130 // << " coarsen_cutoff: " << coarsen_cutoff << std::endl; 00131 00132 00133 00134 // Loop over the elements and flag them for coarsening or 00135 // refinement based on the element error 00136 00137 MeshBase::element_iterator e_it = 00138 _mesh.active_elements_begin(); 00139 const MeshBase::element_iterator e_end = 00140 _mesh.active_elements_end(); 00141 for (; e_it != e_end; ++e_it) 00142 { 00143 Elem* elem = *e_it; 00144 const dof_id_type id = elem->id(); 00145 00146 libmesh_assert_less (id, error_per_cell.size()); 00147 00148 const ErrorVectorReal elem_error = error_per_cell[id]; 00149 00150 if (_coarsen_by_parents) 00151 { 00152 Elem* parent = elem->parent(); 00153 if (parent) 00154 { 00155 const dof_id_type parentid = parent->id(); 00156 if (error_per_parent[parentid] >= 0. && 00157 error_per_parent[parentid] <= parent_cutoff) 00158 elem->set_refinement_flag(Elem::COARSEN); 00159 } 00160 } 00161 // Flag the element for coarsening if its error 00162 // is <= coarsen_fraction*delta + error_min 00163 else if (elem_error <= coarsen_cutoff) 00164 { 00165 elem->set_refinement_flag(Elem::COARSEN); 00166 } 00167 00168 // Flag the element for refinement if its error 00169 // is >= refinement_cutoff. 00170 if (elem_error >= refine_cutoff) 00171 if (elem->level() < _max_h_level) 00172 elem->set_refinement_flag(Elem::REFINE); 00173 } 00174 }
| void libMesh::MeshRefinement::flag_elements_by_error_tolerance | ( | const ErrorVector & | error_per_cell | ) |
Flags elements for coarsening and refinement based on the computed error passed in error_per_cell. This method refines the worst elements with errors greater than absolute_global_tolerance / n_active_elem, flagging at most refine_fraction * n_active_elem It coarsens elements with errors less than coarsen_threshold * global_tolerance / n_active_elem, flagging at most coarsen_fraction * n_active_elem
The three fractions refine_fraction coarsen_fraction and coarsen_threshold should be in
.
Definition at line 178 of file mesh_refinement_flagging.C.
References _absolute_global_tolerance, _coarsen_by_parents, _coarsen_fraction, _coarsen_threshold, _max_h_level, _mesh, _refine_fraction, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::Elem::COARSEN, create_parent_error_vector(), libMesh::ErrorVectorReal, libMesh::DofObject::id(), libMesh::Elem::level(), libMesh::MeshBase::n_active_elem(), libMesh::Elem::n_children(), libMesh::Elem::parent(), libMesh::Real, libMesh::Elem::REFINE, and libMesh::Elem::set_refinement_flag().
00179 { 00180 parallel_only(); 00181 00182 libmesh_assert_greater (_coarsen_threshold, 0); 00183 00184 // Check for valid fractions.. 00185 // The fraction values must be in [0,1] 00186 libmesh_assert_greater_equal (_refine_fraction, 0); 00187 libmesh_assert_less_equal (_refine_fraction, 1); 00188 libmesh_assert_greater_equal (_coarsen_fraction, 0); 00189 libmesh_assert_less_equal (_coarsen_fraction, 1); 00190 00191 // How much error per cell will we tolerate? 00192 const Real local_refinement_tolerance = 00193 _absolute_global_tolerance / std::sqrt(static_cast<Real>(_mesh.n_active_elem())); 00194 const Real local_coarsening_tolerance = 00195 local_refinement_tolerance * _coarsen_threshold; 00196 00197 // Prepare another error vector if we need to sum parent errors 00198 ErrorVector error_per_parent; 00199 if (_coarsen_by_parents) 00200 { 00201 Real parent_error_min, parent_error_max; 00202 00203 create_parent_error_vector(error_per_cell_in, 00204 error_per_parent, 00205 parent_error_min, 00206 parent_error_max); 00207 } 00208 00209 MeshBase::element_iterator elem_it = _mesh.active_elements_begin(); 00210 const MeshBase::element_iterator elem_end = _mesh.active_elements_end(); 00211 00212 for (; elem_it != elem_end; ++elem_it) 00213 { 00214 Elem* elem = *elem_it; 00215 Elem* parent = elem->parent(); 00216 const dof_id_type elem_number = elem->id(); 00217 const ErrorVectorReal elem_error = error_per_cell_in[elem_number]; 00218 00219 if (elem_error > local_refinement_tolerance && 00220 elem->level() < _max_h_level) 00221 elem->set_refinement_flag(Elem::REFINE); 00222 00223 if (!_coarsen_by_parents && elem_error < 00224 local_coarsening_tolerance) 00225 elem->set_refinement_flag(Elem::COARSEN); 00226 00227 if (_coarsen_by_parents && parent) 00228 { 00229 ErrorVectorReal parent_error = error_per_parent[parent->id()]; 00230 if (parent_error >= 0.) 00231 { 00232 const Real parent_coarsening_tolerance = 00233 std::sqrt(parent->n_children() * 00234 local_coarsening_tolerance * 00235 local_coarsening_tolerance); 00236 if (parent_error < parent_coarsening_tolerance) 00237 elem->set_refinement_flag(Elem::COARSEN); 00238 } 00239 } 00240 } 00241 }
| void libMesh::MeshRefinement::flag_elements_by_mean_stddev | ( | const ErrorVector & | error_per_cell, | |
| const Real | refine_fraction = 1.0, |
|||
| const Real | coarsen_fraction = 0.0, |
|||
| const unsigned int | max_level = libMesh::invalid_uint | |||
| ) |
Flags elements for coarsening and refinement based on the computed error passed in error_per_cell. This method picks the top refine_fraction * stddev + mean elements for refinement and the bottom mean - coarsen_fraction * stddev elements for coarsening. The two fractions refine_fraction and coarsen_fraction must be in
.
All the function arguments except error_per_cell have been deprecated, and will be removed in future libMesh releases - to control these parameters, set the corresponding member variables.
Definition at line 591 of file mesh_refinement_flagging.C.
References _coarsen_fraction, _max_h_level, _mesh, _refine_fraction, _use_member_parameters, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::Elem::COARSEN, libMesh::ErrorVectorReal, libMesh::DofObject::id(), libMesh::invalid_uint, libMesh::Elem::level(), std::max(), libMesh::ErrorVector::mean(), libMesh::Real, libMesh::Elem::REFINE, libMesh::Elem::set_refinement_flag(), and libMesh::ErrorVector::variance().
00595 { 00596 // The function arguments are currently just there for 00597 // backwards_compatibility 00598 if (!_use_member_parameters) 00599 { 00600 // If the user used non-default parameters, lets warn 00601 // that they're deprecated 00602 if (refine_frac != 0.3 || 00603 coarsen_frac != 0.0 || 00604 max_l != libMesh::invalid_uint) 00605 libmesh_deprecated(); 00606 00607 _refine_fraction = refine_frac; 00608 _coarsen_fraction = coarsen_frac; 00609 _max_h_level = max_l; 00610 } 00611 00612 // Get the mean value from the error vector 00613 const Real mean = error_per_cell.mean(); 00614 00615 // Get the standard deviation. This equals the 00616 // square-root of the variance 00617 const Real stddev = std::sqrt (error_per_cell.variance()); 00618 00619 // Check for valid fractions 00620 libmesh_assert_greater_equal (_refine_fraction, 0); 00621 libmesh_assert_less_equal (_refine_fraction, 1); 00622 libmesh_assert_greater_equal (_coarsen_fraction, 0); 00623 libmesh_assert_less_equal (_coarsen_fraction, 1); 00624 00625 // The refine and coarsen cutoff 00626 const Real refine_cutoff = mean + _refine_fraction * stddev; 00627 const Real coarsen_cutoff = std::max(mean - _coarsen_fraction * stddev, 0.); 00628 00629 // Loop over the elements and flag them for coarsening or 00630 // refinement based on the element error 00631 MeshBase::element_iterator elem_it = _mesh.active_elements_begin(); 00632 const MeshBase::element_iterator elem_end = _mesh.active_elements_end(); 00633 00634 for (; elem_it != elem_end; ++elem_it) 00635 { 00636 Elem* elem = *elem_it; 00637 const dof_id_type id = elem->id(); 00638 00639 libmesh_assert_less (id, error_per_cell.size()); 00640 00641 const ErrorVectorReal elem_error = error_per_cell[id]; 00642 00643 // Possibly flag the element for coarsening ... 00644 if (elem_error <= coarsen_cutoff) 00645 elem->set_refinement_flag(Elem::COARSEN); 00646 00647 // ... or refinement 00648 if ((elem_error >= refine_cutoff) && (elem->level() < _max_h_level)) 00649 elem->set_refinement_flag(Elem::REFINE); 00650 } 00651 }
| bool libMesh::MeshRefinement::flag_elements_by_nelem_target | ( | const ErrorVector & | error_per_cell | ) |
Flags elements for coarsening and refinement based on the computed error passed in error_per_cell. This method attempts to produce a mesh with slightly more than nelem_target active elements, trading element refinement for element coarsening when their error ratios exceed coarsen_threshold. It flags no more than refine_fraction * n_elem elements for refinement and flags no more than coarsen_fraction * n_elem elements for coarsening. This method returns true if it has done all the AMR/C it can do in a single step, or false if further adaptive steps may be required to produce a mesh with a narrow error distribution and the right number of elements.
Definition at line 245 of file mesh_refinement_flagging.C.
References _coarsen_by_parents, _coarsen_fraction, _coarsen_threshold, _max_h_level, _mesh, _nelem_target, _refine_fraction, libMesh::Elem::active(), libMesh::MeshBase::active_local_elements_begin(), libMesh::MeshBase::active_local_elements_end(), libMesh::Parallel::Communicator::allgather(), libMesh::Elem::child(), clean_refinement_flags(), libMesh::Elem::COARSEN, libMesh::CommWorld, create_parent_error_vector(), libMesh::Elem::has_children(), libMesh::Elem::level(), libMesh::Parallel::Communicator::max(), libMesh::MeshBase::max_elem_id(), libMesh::MeshBase::mesh_dimension(), std::min(), libMesh::MeshBase::n_active_elem(), libMesh::Elem::n_children(), libMesh::MeshBase::query_elem(), libMesh::Real, libMesh::Elem::REFINE, libMesh::remote_elem, and libMesh::Elem::set_refinement_flag().
00246 { 00247 parallel_only(); 00248 00249 // Check for valid fractions.. 00250 // The fraction values must be in [0,1] 00251 libmesh_assert_greater_equal (_refine_fraction, 0); 00252 libmesh_assert_less_equal (_refine_fraction, 1); 00253 libmesh_assert_greater_equal (_coarsen_fraction, 0); 00254 libmesh_assert_less_equal (_coarsen_fraction, 1); 00255 00256 // This function is currently only coded to work when coarsening by 00257 // parents - it's too hard to guess how many coarsenings will be 00258 // performed otherwise. 00259 libmesh_assert (_coarsen_by_parents); 00260 00261 // The number of active elements in the mesh - hopefully less than 00262 // 2 billion on 32 bit machines 00263 const dof_id_type n_active_elem = _mesh.n_active_elem(); 00264 00265 // The maximum number of active elements to flag for coarsening 00266 const dof_id_type max_elem_coarsen = 00267 static_cast<dof_id_type>(_coarsen_fraction * n_active_elem) + 1; 00268 00269 // The maximum number of elements to flag for refinement 00270 const dof_id_type max_elem_refine = 00271 static_cast<dof_id_type>(_refine_fraction * n_active_elem) + 1; 00272 00273 // Clean up the refinement flags. These could be left 00274 // over from previous refinement steps. 00275 this->clean_refinement_flags(); 00276 00277 // The target number of elements to add or remove 00278 const std::ptrdiff_t n_elem_new = _nelem_target - n_active_elem; 00279 00280 // Create an vector with active element errors and ids, 00281 // sorted by highest errors first 00282 const dof_id_type max_elem_id = _mesh.max_elem_id(); 00283 std::vector<std::pair<ErrorVectorReal, dof_id_type> > sorted_error; 00284 00285 sorted_error.reserve (n_active_elem); 00286 00287 // On a ParallelMesh, we need to communicate to know which remote ids 00288 // correspond to active elements. 00289 { 00290 std::vector<bool> is_active(max_elem_id, false); 00291 00292 MeshBase::element_iterator elem_it = _mesh.active_local_elements_begin(); 00293 const MeshBase::element_iterator elem_end = _mesh.active_local_elements_end(); 00294 for (; elem_it != elem_end; ++elem_it) 00295 { 00296 const dof_id_type eid = (*elem_it)->id(); 00297 is_active[eid] = true; 00298 libmesh_assert_less (eid, error_per_cell.size()); 00299 sorted_error.push_back 00300 (std::make_pair(error_per_cell[eid], eid)); 00301 } 00302 00303 CommWorld.max(is_active); 00304 00305 CommWorld.allgather(sorted_error); 00306 } 00307 00308 // Default sort works since pairs are sorted lexicographically 00309 std::sort (sorted_error.begin(), sorted_error.end()); 00310 std::reverse (sorted_error.begin(), sorted_error.end()); 00311 00312 // Create a sorted error vector with coarsenable parent elements 00313 // only, sorted by lowest errors first 00314 ErrorVector error_per_parent; 00315 std::vector<std::pair<ErrorVectorReal, dof_id_type> > sorted_parent_error; 00316 Real parent_error_min, parent_error_max; 00317 00318 create_parent_error_vector(error_per_cell, 00319 error_per_parent, 00320 parent_error_min, 00321 parent_error_max); 00322 00323 // create_parent_error_vector sets values for non-parents and 00324 // non-coarsenable parents to -1. Get rid of them. 00325 for (dof_id_type i=0; i != error_per_parent.size(); ++i) 00326 if (error_per_parent[i] != -1) 00327 sorted_parent_error.push_back(std::make_pair(error_per_parent[i], i)); 00328 00329 std::sort (sorted_parent_error.begin(), sorted_parent_error.end()); 00330 00331 // Keep track of how many elements we plan to coarsen & refine 00332 dof_id_type coarsen_count = 0; 00333 dof_id_type refine_count = 0; 00334 00335 const unsigned int dim = _mesh.mesh_dimension(); 00336 unsigned int twotodim = 1; 00337 for (unsigned int i=0; i!=dim; ++i) 00338 twotodim *= 2; 00339 00340 // First, let's try to get our element count to target_nelem 00341 if (n_elem_new >= 0) 00342 { 00343 // Every element refinement creates at least 00344 // 2^dim-1 new elements 00345 refine_count = 00346 std::min(libmesh_cast_int<dof_id_type>(n_elem_new / (twotodim-1)), 00347 max_elem_refine); 00348 } 00349 else 00350 { 00351 // Every successful element coarsening is likely to destroy 00352 // 2^dim-1 net elements. 00353 coarsen_count = 00354 std::min(libmesh_cast_int<dof_id_type>(-n_elem_new / (twotodim-1)), 00355 max_elem_coarsen); 00356 } 00357 00358 // Next, let's see if we can trade any refinement for coarsening 00359 while (coarsen_count < max_elem_coarsen && 00360 refine_count < max_elem_refine && 00361 coarsen_count < sorted_parent_error.size() && 00362 refine_count < sorted_error.size() && 00363 sorted_error[refine_count].first > 00364 sorted_parent_error[coarsen_count].first * _coarsen_threshold) 00365 { 00366 coarsen_count++; 00367 refine_count++; 00368 } 00369 00370 // On a ParallelMesh, we need to communicate to know which remote ids 00371 // correspond to refinable elements 00372 dof_id_type successful_refine_count = 0; 00373 { 00374 std::vector<bool> is_refinable(max_elem_id, false); 00375 00376 for (dof_id_type i=0; i != sorted_error.size(); ++i) 00377 { 00378 dof_id_type eid = sorted_error[i].second; 00379 Elem *elem = _mesh.query_elem(eid); 00380 if (elem && elem->level() < _max_h_level) 00381 is_refinable[eid] = true; 00382 } 00383 CommWorld.max(is_refinable); 00384 00385 if (refine_count > max_elem_refine) 00386 refine_count = max_elem_refine; 00387 for (dof_id_type i=0; i != sorted_error.size(); ++i) 00388 { 00389 if (successful_refine_count >= refine_count) 00390 break; 00391 00392 dof_id_type eid = sorted_error[i].second; 00393 Elem *elem = _mesh.query_elem(eid); 00394 if (is_refinable[eid]) 00395 { 00396 if (elem) 00397 elem->set_refinement_flag(Elem::REFINE); 00398 successful_refine_count++; 00399 } 00400 } 00401 } 00402 00403 // If we couldn't refine enough elements, don't coarsen too many 00404 // either 00405 if (coarsen_count < (refine_count - successful_refine_count)) 00406 coarsen_count = 0; 00407 else 00408 coarsen_count -= (refine_count - successful_refine_count); 00409 00410 if (coarsen_count > max_elem_coarsen) 00411 coarsen_count = max_elem_coarsen; 00412 00413 dof_id_type successful_coarsen_count = 0; 00414 if (coarsen_count) 00415 { 00416 for (dof_id_type i=0; i != sorted_parent_error.size(); ++i) 00417 { 00418 if (successful_coarsen_count >= coarsen_count * twotodim) 00419 break; 00420 00421 dof_id_type parent_id = sorted_parent_error[i].second; 00422 Elem *parent = _mesh.query_elem(parent_id); 00423 00424 // On a ParallelMesh we skip remote elements 00425 if (!parent) 00426 continue; 00427 00428 libmesh_assert(parent->has_children()); 00429 for (unsigned int c=0; c != parent->n_children(); ++c) 00430 { 00431 Elem *elem = parent->child(c); 00432 if (elem && elem != remote_elem) 00433 { 00434 libmesh_assert(elem->active()); 00435 elem->set_refinement_flag(Elem::COARSEN); 00436 successful_coarsen_count++; 00437 } 00438 } 00439 } 00440 } 00441 00442 // Return true if we've done all the AMR/C we can 00443 if (!successful_coarsen_count && 00444 !successful_refine_count) 00445 return true; 00446 // And false if there may still be more to do. 00447 return false; 00448 }
| MeshBase& libMesh::MeshRefinement::get_mesh | ( | ) | [inline] |
- Returns:
- a writeable reference to the
MeshBaseobject associated with this object.
Definition at line 294 of file mesh_refinement.h.
References _mesh.
00294 { return _mesh; }
| const MeshBase& libMesh::MeshRefinement::get_mesh | ( | ) | const [inline] |
- Returns:
- a constant reference to the
MeshBaseobject associated with this object.
Definition at line 288 of file mesh_refinement.h.
References _mesh.
00288 { return _mesh; }
| bool libMesh::MeshRefinement::has_topological_neighbor | ( | Elem * | elem, | |
| const PointLocatorBase * | point_locator, | |||
| Elem * | neighbor | |||
| ) | [private] |
Local dispatch function for checking the correct has_neighbor function from the Elem class
Definition at line 1788 of file mesh_refinement.C.
References _mesh, _periodic_boundaries, libMesh::Elem::has_neighbor(), and libMesh::Elem::has_topological_neighbor().
Referenced by make_coarsening_compatible(), and make_refinement_compatible().
01791 { 01792 #ifdef LIBMESH_ENABLE_PERIODIC 01793 if (_periodic_boundaries && !_periodic_boundaries->empty()) 01794 { 01795 libmesh_assert(point_locator); 01796 return elem->has_topological_neighbor(neighbor, _mesh, *point_locator, _periodic_boundaries); 01797 } 01798 #endif 01799 return elem->has_neighbor(neighbor); 01800 }
| bool libMesh::MeshRefinement::limit_level_mismatch_at_edge | ( | const unsigned int | max_mismatch | ) | [private] |
Definition at line 131 of file mesh_refinement_smoothing.C.
References _mesh, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::Elem::build_edge(), libMesh::CommWorld, libMesh::Elem::level(), libMesh::Parallel::Communicator::max(), std::max(), libMesh::Elem::n_edges(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::Elem::parent(), libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), and swap().
Referenced by coarsen_elements(), refine_and_coarsen_elements(), and refine_elements().
00132 { 00133 // This function must be run on all processors at once 00134 parallel_only(); 00135 00136 bool flags_changed = false; 00137 00138 00139 // Maps holding the maximum element level that touches an edge 00140 std::map<std::pair<unsigned int, unsigned int>, unsigned char> 00141 max_level_at_edge; 00142 std::map<std::pair<unsigned int, unsigned int>, unsigned char> 00143 max_p_level_at_edge; 00144 00145 // Loop over all the active elements & fill the maps 00146 { 00147 MeshBase::element_iterator elem_it = _mesh.active_elements_begin(); 00148 const MeshBase::element_iterator elem_end = _mesh.active_elements_end(); 00149 00150 for (; elem_it != elem_end; ++elem_it) 00151 { 00152 const Elem* elem = *elem_it; 00153 const unsigned char elem_level = 00154 elem->level() + ((elem->refinement_flag() == Elem::REFINE) ? 1 : 0); 00155 const unsigned char elem_p_level = 00156 elem->p_level() + ((elem->p_refinement_flag() == Elem::REFINE) ? 1 : 0); 00157 00158 // Set the max_level at each edge 00159 for (unsigned int n=0; n<elem->n_edges(); n++) 00160 { 00161 AutoPtr<Elem> edge = elem->build_edge(n); 00162 dof_id_type childnode0 = edge->node(0); 00163 dof_id_type childnode1 = edge->node(1); 00164 if (childnode1 < childnode0) 00165 std::swap(childnode0, childnode1); 00166 00167 for (const Elem *p = elem; p != NULL; p = p->parent()) 00168 { 00169 AutoPtr<Elem> pedge = p->build_edge(n); 00170 dof_id_type node0 = pedge->node(0); 00171 dof_id_type node1 = pedge->node(1); 00172 00173 if (node1 < node0) 00174 std::swap(node0, node1); 00175 00176 // If elem does not share this edge with its ancestor 00177 // p, refinement levels of elements sharing p's edge 00178 // are not restricted by refinement levels of elem. 00179 // Furthermore, elem will not share this edge with any 00180 // of p's ancestors, so we can safely break out of the 00181 // for loop early. 00182 if (node0 != childnode0 && node1 != childnode1) 00183 break; 00184 00185 childnode0 = node0; 00186 childnode1 = node1; 00187 00188 std::pair<unsigned int, unsigned int> edge_key = 00189 std::make_pair(node0, node1); 00190 00191 if (max_level_at_edge.find(edge_key) == 00192 max_level_at_edge.end()) 00193 { 00194 max_level_at_edge[edge_key] = elem_level; 00195 max_p_level_at_edge[edge_key] = elem_p_level; 00196 } 00197 else 00198 { 00199 max_level_at_edge[edge_key] = 00200 std::max (max_level_at_edge[edge_key], elem_level); 00201 max_p_level_at_edge[edge_key] = 00202 std::max (max_p_level_at_edge[edge_key], elem_p_level); 00203 } 00204 } 00205 } 00206 } 00207 } 00208 00209 00210 // Now loop over the active elements and flag the elements 00211 // who violate the requested level mismatch 00212 { 00213 MeshBase::element_iterator elem_it = _mesh.active_elements_begin(); 00214 const MeshBase::element_iterator elem_end = _mesh.active_elements_end(); 00215 00216 for (; elem_it != elem_end; ++elem_it) 00217 { 00218 Elem* elem = *elem_it; 00219 const unsigned int elem_level = elem->level(); 00220 const unsigned int elem_p_level = elem->p_level(); 00221 00222 // Skip the element if it is already fully flagged 00223 if (elem->refinement_flag() == Elem::REFINE && 00224 elem->p_refinement_flag() == Elem::REFINE) 00225 continue; 00226 00227 // Loop over the nodes, check for possible mismatch 00228 for (unsigned int n=0; n<elem->n_edges(); n++) 00229 { 00230 AutoPtr<Elem> edge = elem->build_edge(n); 00231 dof_id_type node0 = edge->node(0); 00232 dof_id_type node1 = edge->node(1); 00233 if (node1 < node0) 00234 std::swap(node0, node1); 00235 00236 std::pair<dof_id_type, dof_id_type> edge_key = 00237 std::make_pair(node0, node1); 00238 00239 // Flag the element for refinement if it violates 00240 // the requested level mismatch 00241 if ( (elem_level + max_mismatch) < max_level_at_edge[edge_key] 00242 && elem->refinement_flag() != Elem::REFINE) 00243 { 00244 elem->set_refinement_flag (Elem::REFINE); 00245 flags_changed = true; 00246 } 00247 if ( (elem_p_level + max_mismatch) < max_p_level_at_edge[edge_key] 00248 && elem->p_refinement_flag() != Elem::REFINE) 00249 { 00250 elem->set_p_refinement_flag (Elem::REFINE); 00251 flags_changed = true; 00252 } 00253 } 00254 } 00255 } 00256 00257 // If flags changed on any processor then they changed globally 00258 CommWorld.max(flags_changed); 00259 00260 return flags_changed; 00261 }
| bool libMesh::MeshRefinement::limit_level_mismatch_at_node | ( | const unsigned int | max_mismatch | ) | [private] |
This algorithm restricts the maximum level mismatch at any node in the mesh. Calling this with max_mismatch equal to 1 would transform this mesh:
o---o---o---o---o-------o-------o | | | | | | | | | | | | | | o---o---o---o---o | | | | | | | | | | | | | | | | o---o---o---o---o-------o-------o | | | | | | | | | | | | | | o---o---o---o---o | | | | | | | | | | | | | | | | o---o---o---o---o-------o-------o | | | | | | | | | | | | | | | | | | | | o-------o-------o | | | | | | | | | | | | | | | | | | | | | o-------o-------o---------------o
into this:
o---o---o---o---o-------o-------o | | | | | | | | | | | | | | o---o---o---o---o | | | | | | | | | | | | | | | | o---o---o---o---o-------o-------o | | | | | | | | | | | | | | o---o---o---o---o | | | | | | | | | | | | | | | | o---o---o---o---o-------o-------o | | | : | | | | : | | | | : | | | | : | | | | : | o-------o-------o.......o.......o | | | : | | | | : | | | | : | | | | : | | | | : | o-------o-------o-------o-------o
by refining the indicated element
Definition at line 39 of file mesh_refinement_smoothing.C.
References _mesh, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::CommWorld, libMesh::Elem::level(), libMesh::Parallel::Communicator::max(), std::max(), libMesh::Elem::n_nodes(), libMesh::MeshBase::n_nodes(), libMesh::Elem::node(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), and libMesh::Elem::set_refinement_flag().
Referenced by coarsen_elements(), refine_and_coarsen_elements(), and refine_elements().
00040 { 00041 // This function must be run on all processors at once 00042 parallel_only(); 00043 00044 bool flags_changed = false; 00045 00046 00047 // Vector holding the maximum element level that touches a node. 00048 std::vector<unsigned char> max_level_at_node (_mesh.n_nodes(), 0); 00049 std::vector<unsigned char> max_p_level_at_node (_mesh.n_nodes(), 0); 00050 00051 00052 // Loop over all the active elements & fill the vector 00053 { 00054 MeshBase::element_iterator elem_it = _mesh.active_elements_begin(); 00055 const MeshBase::element_iterator elem_end = _mesh.active_elements_end(); 00056 00057 for (; elem_it != elem_end; ++elem_it) 00058 { 00059 const Elem* elem = *elem_it; 00060 const unsigned char elem_level = 00061 elem->level() + ((elem->refinement_flag() == Elem::REFINE) ? 1 : 0); 00062 const unsigned char elem_p_level = 00063 elem->p_level() + ((elem->p_refinement_flag() == Elem::REFINE) ? 1 : 0); 00064 00065 // Set the max_level at each node 00066 for (unsigned int n=0; n<elem->n_nodes(); n++) 00067 { 00068 const dof_id_type node_number = elem->node(n); 00069 00070 libmesh_assert_less (node_number, max_level_at_node.size()); 00071 00072 max_level_at_node[node_number] = 00073 std::max (max_level_at_node[node_number], elem_level); 00074 max_p_level_at_node[node_number] = 00075 std::max (max_p_level_at_node[node_number], elem_p_level); 00076 } 00077 } 00078 } 00079 00080 00081 // Now loop over the active elements and flag the elements 00082 // who violate the requested level mismatch 00083 { 00084 MeshBase::element_iterator elem_it = _mesh.active_elements_begin(); 00085 const MeshBase::element_iterator elem_end = _mesh.active_elements_end(); 00086 00087 for (; elem_it != elem_end; ++elem_it) 00088 { 00089 Elem* elem = *elem_it; 00090 const unsigned int elem_level = elem->level(); 00091 const unsigned int elem_p_level = elem->p_level(); 00092 00093 // Skip the element if it is already fully flagged 00094 if (elem->refinement_flag() == Elem::REFINE && 00095 elem->p_refinement_flag() == Elem::REFINE) 00096 continue; 00097 00098 // Loop over the nodes, check for possible mismatch 00099 for (unsigned int n=0; n<elem->n_nodes(); n++) 00100 { 00101 const dof_id_type node_number = elem->node(n); 00102 00103 // Flag the element for refinement if it violates 00104 // the requested level mismatch 00105 if ( (elem_level + max_mismatch) < max_level_at_node[node_number] 00106 && elem->refinement_flag() != Elem::REFINE) 00107 { 00108 elem->set_refinement_flag (Elem::REFINE); 00109 flags_changed = true; 00110 } 00111 if ( (elem_p_level + max_mismatch) < max_p_level_at_node[node_number] 00112 && elem->p_refinement_flag() != Elem::REFINE) 00113 { 00114 elem->set_p_refinement_flag (Elem::REFINE); 00115 flags_changed = true; 00116 } 00117 } 00118 } 00119 } 00120 00121 // If flags changed on any processor then they changed globally 00122 CommWorld.max(flags_changed); 00123 00124 return flags_changed; 00125 }
| bool libMesh::MeshRefinement::make_coarsening_compatible | ( | const bool | maintain_level_one | ) | [private] |
Take user-specified coarsening flags and augment them so that level-one dependency is satisfied.
Definition at line 920 of file mesh_refinement.C.
References _face_level_mismatch_limit, _mesh, _periodic_boundaries, libMesh::Elem::active(), libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::Elem::ancestor(), libMesh::Elem::child(), libMesh::Elem::COARSEN, libMesh::Elem::COARSEN_INACTIVE, libMesh::CommWorld, libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), libMesh::AutoPtr< Tp >::get(), libMesh::Elem::has_children(), has_topological_neighbor(), libMesh::Elem::INACTIVE, libMesh::MeshBase::is_serial(), libMesh::Elem::level(), libMesh::MeshBase::level_elements_begin(), libMesh::MeshBase::level_elements_end(), std::max(), libMesh::MeshTools::max_level(), libMesh::Parallel::Communicator::min(), libMesh::Elem::n_children(), libMesh::Elem::n_neighbors(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::processor_id(), libMesh::DofObject::processor_id(), libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::remote_elem, libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), libMesh::MeshBase::sub_point_locator(), topological_neighbor(), and libMesh::Parallel::Communicator::verify().
Referenced by coarsen_elements(), and refine_and_coarsen_elements().
00921 { 00922 // This function must be run on all processors at once 00923 parallel_only(); 00924 00925 // We may need a PointLocator for topological_neighbor() tests 00926 // later, which we need to make sure gets constructed on all 00927 // processors at once. 00928 AutoPtr<PointLocatorBase> point_locator; 00929 00930 #ifdef LIBMESH_ENABLE_PERIODIC 00931 bool has_periodic_boundaries = 00932 _periodic_boundaries && !_periodic_boundaries->empty(); 00933 libmesh_assert(CommWorld.verify(has_periodic_boundaries)); 00934 00935 if (has_periodic_boundaries) 00936 point_locator = _mesh.sub_point_locator(); 00937 #endif 00938 00939 START_LOG ("make_coarsening_compatible()", "MeshRefinement"); 00940 00941 bool _maintain_level_one = maintain_level_one; 00942 00943 // If the user used non-default parameters, let's warn that they're 00944 // deprecated 00945 if (!maintain_level_one) 00946 { 00947 libmesh_deprecated(); 00948 } 00949 else 00950 _maintain_level_one = _face_level_mismatch_limit; 00951 00952 00953 // Unless we encounter a specific situation level-one 00954 // will be satisfied after executing this loop just once 00955 bool level_one_satisfied = true; 00956 00957 00958 // Unless we encounter a specific situation we will be compatible 00959 // with any selected refinement flags 00960 bool compatible_with_refinement = true; 00961 00962 00963 // find the maximum h and p levels in the mesh 00964 unsigned int max_level = 0; 00965 unsigned int max_p_level = 0; 00966 00967 { 00968 // First we look at all the active level-0 elements. Since it doesn't make 00969 // sense to coarsen them we must un-set their coarsen flags if 00970 // they are set. 00971 MeshBase::element_iterator el = _mesh.active_elements_begin(); 00972 const MeshBase::element_iterator end_el = _mesh.active_elements_end(); 00973 00974 for (; el != end_el; ++el) 00975 { 00976 Elem *elem = *el; 00977 max_level = std::max(max_level, elem->level()); 00978 max_p_level = 00979 std::max(max_p_level, 00980 static_cast<unsigned int>(elem->p_level())); 00981 00982 if ((elem->level() == 0) && 00983 (elem->refinement_flag() == Elem::COARSEN)) 00984 elem->set_refinement_flag(Elem::DO_NOTHING); 00985 00986 if ((elem->p_level() == 0) && 00987 (elem->p_refinement_flag() == Elem::COARSEN)) 00988 elem->set_p_refinement_flag(Elem::DO_NOTHING); 00989 } 00990 } 00991 00992 // if there are no refined elements on this processor then 00993 // there is no work for us to do 00994 if (max_level == 0 && max_p_level == 0) 00995 { 00996 STOP_LOG ("make_coarsening_compatible()", "MeshRefinement"); 00997 00998 // But we still have to check with other processors 00999 CommWorld.min(compatible_with_refinement); 01000 01001 return compatible_with_refinement; 01002 } 01003 01004 01005 01006 // Loop over all the active elements. If an element is marked 01007 // for coarsening we better check its neighbors. If ANY of these neighbors 01008 // are marked for refinement AND are at the same level then there is a 01009 // conflict. By convention refinement wins, so we un-mark the element for 01010 // coarsening. Level-one would be violated in this case so we need to re-run 01011 // the loop. 01012 if (_maintain_level_one) 01013 { 01014 01015 repeat: 01016 level_one_satisfied = true; 01017 01018 do 01019 { 01020 level_one_satisfied = true; 01021 01022 MeshBase::element_iterator el = _mesh.active_elements_begin(); 01023 const MeshBase::element_iterator end_el = _mesh.active_elements_end(); 01024 01025 for (; el != end_el; ++el) 01026 { 01027 Elem* elem = *el; 01028 bool my_flag_changed = false; 01029 01030 if (elem->refinement_flag() == Elem::COARSEN) // If the element is active and 01031 // the coarsen flag is set 01032 { 01033 const unsigned int my_level = elem->level(); 01034 01035 for (unsigned int n=0; n<elem->n_neighbors(); n++) 01036 { 01037 const Elem* neighbor = 01038 topological_neighbor(elem, point_locator.get(), n); 01039 01040 if (neighbor != NULL && // I have a 01041 neighbor != remote_elem) // neighbor here 01042 { 01043 if (neighbor->active()) // and it is active 01044 { 01045 if ((neighbor->level() == my_level) && 01046 (neighbor->refinement_flag() == Elem::REFINE)) // the neighbor is at my level 01047 // and wants to be refined 01048 { 01049 elem->set_refinement_flag(Elem::DO_NOTHING); 01050 my_flag_changed = true; 01051 break; 01052 } 01053 } 01054 else // I have a neighbor and it is not active. That means it has children. 01055 { // While it _may_ be possible to coarsen us if all the children of 01056 // that element want to be coarsened, it is impossible to know at this 01057 // stage. Forget about it for the moment... This can be handled in 01058 // two steps. 01059 elem->set_refinement_flag(Elem::DO_NOTHING); 01060 my_flag_changed = true; 01061 break; 01062 } 01063 } 01064 } 01065 } 01066 if (elem->p_refinement_flag() == Elem::COARSEN) // If 01067 // the element is active and the order reduction flag is set 01068 { 01069 const unsigned int my_p_level = elem->p_level(); 01070 01071 for (unsigned int n=0; n<elem->n_neighbors(); n++) 01072 { 01073 const Elem* neighbor = 01074 topological_neighbor(elem, point_locator.get(), n); 01075 01076 if (neighbor != NULL && // I have a 01077 neighbor != remote_elem) // neighbor here 01078 { 01079 if (neighbor->active()) // and it is active 01080 { 01081 if ((neighbor->p_level() > my_p_level && 01082 neighbor->p_refinement_flag() != Elem::COARSEN) 01083 || (neighbor->p_level() == my_p_level && 01084 neighbor->p_refinement_flag() == Elem::REFINE)) 01085 { 01086 elem->set_p_refinement_flag(Elem::DO_NOTHING); 01087 my_flag_changed = true; 01088 break; 01089 } 01090 } 01091 else // I have a neighbor and it is not active. 01092 { // We need to find which of its children 01093 // have me as a neighbor, and maintain 01094 // level one p compatibility with them. 01095 // Because we currently have level one h 01096 // compatibility, we don't need to check 01097 // grandchildren 01098 01099 libmesh_assert(neighbor->has_children()); 01100 for (unsigned int c=0; c!=neighbor->n_children(); c++) 01101 { 01102 Elem *subneighbor = neighbor->child(c); 01103 if (subneighbor != remote_elem && 01104 subneighbor->active() && 01105 has_topological_neighbor(subneighbor, point_locator.get(), elem)) 01106 if ((subneighbor->p_level() > my_p_level && 01107 subneighbor->p_refinement_flag() != Elem::COARSEN) 01108 || (subneighbor->p_level() == my_p_level && 01109 subneighbor->p_refinement_flag() == Elem::REFINE)) 01110 { 01111 elem->set_p_refinement_flag(Elem::DO_NOTHING); 01112 my_flag_changed = true; 01113 break; 01114 } 01115 } 01116 if (my_flag_changed) 01117 break; 01118 } 01119 } 01120 } 01121 } 01122 01123 // If the current element's flag changed, we hadn't 01124 // satisfied the level one rule. 01125 if (my_flag_changed) 01126 level_one_satisfied = false; 01127 01128 // Additionally, if it has non-local neighbors, and 01129 // we're not in serial, then we'll eventually have to 01130 // return compatible_with_refinement = false, because 01131 // our change has to propagate to neighboring 01132 // processors. 01133 if (my_flag_changed && !_mesh.is_serial()) 01134 for (unsigned int n=0; n != elem->n_neighbors(); ++n) 01135 { 01136 Elem* neigh = 01137 topological_neighbor(elem, point_locator.get(), n); 01138 01139 if (!neigh) 01140 continue; 01141 if (neigh == remote_elem || 01142 neigh->processor_id() != 01143 libMesh::processor_id()) 01144 { 01145 compatible_with_refinement = false; 01146 break; 01147 } 01148 // FIXME - for non-level one meshes we should 01149 // test all descendants 01150 if (neigh->has_children()) 01151 for (unsigned int c=0; c != neigh->n_children(); ++c) 01152 if (neigh->child(c) == remote_elem || 01153 neigh->child(c)->processor_id() != 01154 libMesh::processor_id()) 01155 { 01156 compatible_with_refinement = false; 01157 break; 01158 } 01159 } 01160 } 01161 } 01162 while (!level_one_satisfied); 01163 01164 } // end if (_maintain_level_one) 01165 01166 01167 // Next we look at all of the ancestor cells. 01168 // If there is a parent cell with all of its children 01169 // wanting to be unrefined then the element is a candidate 01170 // for unrefinement. If all the children don't 01171 // all want to be unrefined then ALL of them need to have their 01172 // unrefinement flags cleared. 01173 for (int level=(max_level); level >= 0; level--) 01174 { 01175 MeshBase::element_iterator el = _mesh.level_elements_begin(level); 01176 const MeshBase::element_iterator end_el = _mesh.level_elements_end(level); 01177 for (; el != end_el; ++el) 01178 { 01179 Elem *elem = *el; 01180 if (elem->ancestor()) 01181 { 01182 01183 // right now the element hasn't been disqualified 01184 // as a candidate for unrefinement 01185 bool is_a_candidate = true; 01186 bool found_remote_child = false; 01187 01188 for (unsigned int c=0; c<elem->n_children(); c++) 01189 { 01190 Elem *child = elem->child(c); 01191 if (child == remote_elem) 01192 found_remote_child = true; 01193 else if ((child->refinement_flag() != Elem::COARSEN) || 01194 !child->active() ) 01195 is_a_candidate = false; 01196 } 01197 01198 if (!is_a_candidate && !found_remote_child) 01199 { 01200 elem->set_refinement_flag(Elem::INACTIVE); 01201 01202 for (unsigned int c=0; c<elem->n_children(); c++) 01203 { 01204 Elem *child = elem->child(c); 01205 if (child == remote_elem) 01206 continue; 01207 if (child->refinement_flag() == Elem::COARSEN) 01208 { 01209 level_one_satisfied = false; 01210 child->set_refinement_flag(Elem::DO_NOTHING); 01211 } 01212 } 01213 } 01214 } 01215 } 01216 } 01217 01218 if (!level_one_satisfied && _maintain_level_one) goto repeat; 01219 01220 01221 // If all the children of a parent are set to be coarsened 01222 // then flag the parent so that they can kill thier kids... 01223 MeshBase::element_iterator all_el = _mesh.elements_begin(); 01224 const MeshBase::element_iterator all_el_end = _mesh.elements_end(); 01225 for (; all_el != all_el_end; ++all_el) 01226 { 01227 Elem *elem = *all_el; 01228 if (elem->ancestor()) 01229 { 01230 01231 // Presume all the children are local and flagged for 01232 // coarsening and then look for a contradiction 01233 bool all_children_flagged_for_coarsening = true; 01234 bool found_remote_child = false; 01235 01236 for (unsigned int c=0; c<elem->n_children(); c++) 01237 { 01238 Elem *child = elem->child(c); 01239 if (child == remote_elem) 01240 found_remote_child = true; 01241 else if (child->refinement_flag() != Elem::COARSEN) 01242 all_children_flagged_for_coarsening = false; 01243 } 01244 01245 if (!found_remote_child && 01246 all_children_flagged_for_coarsening) 01247 elem->set_refinement_flag(Elem::COARSEN_INACTIVE); 01248 else if (!found_remote_child) 01249 elem->set_refinement_flag(Elem::INACTIVE); 01250 } 01251 } 01252 01253 STOP_LOG ("make_coarsening_compatible()", "MeshRefinement"); 01254 01255 // If one processor finds an incompatibility, we're globally 01256 // incompatible 01257 CommWorld.min(compatible_with_refinement); 01258 01259 return compatible_with_refinement; 01260 }
| bool libMesh::MeshRefinement::make_flags_parallel_consistent | ( | ) | [private] |
Copy refinement flags on ghost elements from their local processors. Return true if any flags changed.
Definition at line 890 of file mesh_refinement.C.
References _mesh, libMesh::CommWorld, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), libMesh::Parallel::Communicator::min(), libMesh::Elem::p_refinement_flag(), parallel_consistent, libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), and libMesh::Parallel::sync_dofobject_data_by_id().
Referenced by coarsen_elements(), refine_and_coarsen_elements(), and refine_elements().
00891 { 00892 // This function must be run on all processors at once 00893 parallel_only(); 00894 00895 START_LOG ("make_flags_parallel_consistent()", "MeshRefinement"); 00896 00897 SyncRefinementFlags hsync(_mesh, &Elem::refinement_flag, 00898 &Elem::set_refinement_flag); 00899 Parallel::sync_dofobject_data_by_id 00900 (_mesh.elements_begin(), _mesh.elements_end(), hsync); 00901 00902 SyncRefinementFlags psync(_mesh, &Elem::p_refinement_flag, 00903 &Elem::set_p_refinement_flag); 00904 Parallel::sync_dofobject_data_by_id 00905 (_mesh.elements_begin(), _mesh.elements_end(), psync); 00906 00907 // If we weren't consistent in both h and p on every processor then 00908 // we weren't globally consistent 00909 bool parallel_consistent = hsync.parallel_consistent && 00910 psync.parallel_consistent; 00911 CommWorld.min(parallel_consistent); 00912 00913 STOP_LOG ("make_flags_parallel_consistent()", "MeshRefinement"); 00914 00915 return parallel_consistent; 00916 }
| bool libMesh::MeshRefinement::make_refinement_compatible | ( | const bool | maintain_level_one | ) | [private] |
Take user-specified refinement flags and augment them so that level-one dependency is satisfied.
Definition at line 1269 of file mesh_refinement.C.
References _face_level_mismatch_limit, _mesh, _periodic_boundaries, libMesh::Elem::active(), libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::Elem::child(), libMesh::Elem::COARSEN, libMesh::CommWorld, libMesh::Elem::DO_NOTHING, libMesh::AutoPtr< Tp >::get(), libMesh::Elem::has_children(), has_topological_neighbor(), libMesh::Elem::INACTIVE, libMesh::Elem::level(), libMesh::Parallel::Communicator::min(), libMesh::Elem::n_children(), libMesh::Elem::n_sides(), libMesh::Elem::p_level(), libMesh::Elem::p_refinement_flag(), libMesh::Elem::parent(), libMesh::Elem::REFINE, libMesh::Elem::refinement_flag(), libMesh::remote_elem, libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), side, libMesh::MeshBase::sub_point_locator(), topological_neighbor(), and libMesh::Parallel::Communicator::verify().
Referenced by refine_and_coarsen_elements(), and refine_elements().
01270 { 01271 // This function must be run on all processors at once 01272 parallel_only(); 01273 01274 // We may need a PointLocator for topological_neighbor() tests 01275 // later, which we need to make sure gets constructed on all 01276 // processors at once. 01277 AutoPtr<PointLocatorBase> point_locator; 01278 01279 #ifdef LIBMESH_ENABLE_PERIODIC 01280 bool has_periodic_boundaries = 01281 _periodic_boundaries && !_periodic_boundaries->empty(); 01282 libmesh_assert(CommWorld.verify(has_periodic_boundaries)); 01283 01284 if (has_periodic_boundaries) 01285 point_locator = _mesh.sub_point_locator(); 01286 #endif 01287 01288 START_LOG ("make_refinement_compatible()", "MeshRefinement"); 01289 01290 bool _maintain_level_one = maintain_level_one; 01291 01292 // If the user used non-default parameters, let's warn that they're 01293 // deprecated 01294 if (!maintain_level_one) 01295 { 01296 libmesh_deprecated(); 01297 } 01298 else 01299 _maintain_level_one = _face_level_mismatch_limit; 01300 01301 // Unless we encounter a specific situation level-one 01302 // will be satisfied after executing this loop just once 01303 bool level_one_satisfied = true; 01304 01305 // Unless we encounter a specific situation we will be compatible 01306 // with any selected coarsening flags 01307 bool compatible_with_coarsening = true; 01308 01309 // This loop enforces the level-1 rule. We should only 01310 // execute it if the user indeed wants level-1 satisfied! 01311 if (_maintain_level_one) 01312 { 01313 do 01314 { 01315 level_one_satisfied = true; 01316 01317 MeshBase::element_iterator el = _mesh.active_elements_begin(); 01318 const MeshBase::element_iterator end_el = _mesh.active_elements_end(); 01319 01320 for (; el != end_el; ++el) 01321 { 01322 Elem *elem = *el; 01323 if (elem->refinement_flag() == Elem::REFINE) // If the element is active and the 01324 // h refinement flag is set 01325 { 01326 const unsigned int my_level = elem->level(); 01327 01328 for (unsigned int side=0; side != elem->n_sides(); side++) 01329 { 01330 Elem* neighbor = 01331 topological_neighbor(elem, point_locator.get(), side); 01332 01333 if (neighbor != NULL && // I have a 01334 neighbor != remote_elem && // neighbor here 01335 neighbor->active()) // and it is active 01336 { 01337 // Case 1: The neighbor is at the same level I am. 01338 // 1a: The neighbor will be refined -> NO PROBLEM 01339 // 1b: The neighbor won't be refined -> NO PROBLEM 01340 // 1c: The neighbor wants to be coarsened -> PROBLEM 01341 if (neighbor->level() == my_level) 01342 { 01343 if (neighbor->refinement_flag() == Elem::COARSEN) 01344 { 01345 neighbor->set_refinement_flag(Elem::DO_NOTHING); 01346 if (neighbor->parent()) 01347 neighbor->parent()->set_refinement_flag(Elem::INACTIVE); 01348 compatible_with_coarsening = false; 01349 level_one_satisfied = false; 01350 } 01351 } 01352 01353 01354 // Case 2: The neighbor is one level lower than I am. 01355 // The neighbor thus MUST be refined to satisfy 01356 // the level-one rule, regardless of whether it 01357 // was originally flagged for refinement. If it 01358 // wasn't flagged already we need to repeat 01359 // this process. 01360 else if ((neighbor->level()+1) == my_level) 01361 { 01362 if (neighbor->refinement_flag() != Elem::REFINE) 01363 { 01364 neighbor->set_refinement_flag(Elem::REFINE); 01365 if (neighbor->parent()) 01366 neighbor->parent()->set_refinement_flag(Elem::INACTIVE); 01367 compatible_with_coarsening = false; 01368 level_one_satisfied = false; 01369 } 01370 } 01371 #ifdef DEBUG 01372 01373 // Sanity check. We should never get into a 01374 // case when our neighbot is more than one 01375 // level away. 01376 else if ((neighbor->level()+1) < my_level) 01377 { 01378 libmesh_error(); 01379 } 01380 01381 01382 // Note that the only other possibility is that the 01383 // neighbor is already refined, in which case it isn't 01384 // active and we should never get here. 01385 else 01386 { 01387 libmesh_error(); 01388 } 01389 #endif 01390 } 01391 } 01392 } 01393 if (elem->p_refinement_flag() == Elem::REFINE) // If the element is active and the 01394 // p refinement flag is set 01395 { 01396 const unsigned int my_p_level = elem->p_level(); 01397 01398 for (unsigned int side=0; side != elem->n_sides(); side++) 01399 { 01400 Elem* neighbor = 01401 topological_neighbor(elem, point_locator.get(), side); 01402 01403 if (neighbor != NULL && // I have a 01404 neighbor != remote_elem) // neighbor here 01405 { 01406 if (neighbor->active()) // and it is active 01407 { 01408 if (neighbor->p_level() < my_p_level && 01409 neighbor->p_refinement_flag() != Elem::REFINE) 01410 { 01411 neighbor->set_p_refinement_flag(Elem::REFINE); 01412 level_one_satisfied = false; 01413 compatible_with_coarsening = false; 01414 } 01415 if (neighbor->p_level() == my_p_level && 01416 neighbor->p_refinement_flag() == Elem::COARSEN) 01417 { 01418 neighbor->set_p_refinement_flag(Elem::DO_NOTHING); 01419 level_one_satisfied = false; 01420 compatible_with_coarsening = false; 01421 } 01422 } 01423 else // I have an inactive neighbor 01424 { 01425 libmesh_assert(neighbor->has_children()); 01426 for (unsigned int c=0; c!=neighbor->n_children(); c++) 01427 { 01428 Elem *subneighbor = neighbor->child(c); 01429 if (subneighbor == remote_elem) 01430 continue; 01431 if (subneighbor->active() && 01432 has_topological_neighbor(subneighbor, point_locator.get(), elem)) 01433 { 01434 if (subneighbor->p_level() < my_p_level && 01435 subneighbor->p_refinement_flag() != Elem::REFINE) 01436 { 01437 // We should already be level one 01438 // compatible 01439 libmesh_assert_greater (subneighbor->p_level() + 2u, 01440 my_p_level); 01441 subneighbor->set_p_refinement_flag(Elem::REFINE); 01442 level_one_satisfied = false; 01443 compatible_with_coarsening = false; 01444 } 01445 if (subneighbor->p_level() == my_p_level && 01446 subneighbor->p_refinement_flag() == Elem::COARSEN) 01447 { 01448 subneighbor->set_p_refinement_flag(Elem::DO_NOTHING); 01449 level_one_satisfied = false; 01450 compatible_with_coarsening = false; 01451 } 01452 } 01453 } 01454 } 01455 } 01456 } 01457 } 01458 } 01459 } 01460 01461 while (!level_one_satisfied); 01462 } // end if (_maintain_level_one) 01463 01464 // If we're not compatible on one processor, we're globally not 01465 // compatible 01466 CommWorld.min(compatible_with_coarsening); 01467 01468 STOP_LOG ("make_refinement_compatible()", "MeshRefinement"); 01469 01470 return compatible_with_coarsening; 01471 }
| unsigned int & libMesh::MeshRefinement::max_h_level | ( | ) | [inline] |
The max_h_level is the greatest refinement level an element should reach.
max_h_level is unlimited (libMesh::invalid_uint) by default
Definition at line 674 of file mesh_refinement.h.
References _max_h_level, and _use_member_parameters.
00675 { 00676 _use_member_parameters = true; 00677 return _max_h_level; 00678 }
| dof_id_type & libMesh::MeshRefinement::nelem_target | ( | ) | [inline] |
If nelem_target is set to a nonzero value, methods like flag_elements_by_nelem_target() will attempt to keep the number of active elements in the mesh close to nelem_target.
nelem_target is 0 by default.
Definition at line 686 of file mesh_refinement.h.
References _nelem_target, and _use_member_parameters.
00687 { 00688 _use_member_parameters = true; 00689 return _nelem_target; 00690 }
| unsigned char & libMesh::MeshRefinement::node_level_mismatch_limit | ( | ) | [inline] |
If node_level_mismatch_limit is set to a nonzero value, then refinement and coarsening will produce meshes in which the refinement level of two nodal neighbors will not differ by more than that limit. If node_level_mismatch_limit is 0, then level differences will be unlimited.
node_level_mismatch_limit is 0 by default.
Definition at line 708 of file mesh_refinement.h.
References _node_level_mismatch_limit.
00709 { 00710 return _node_level_mismatch_limit; 00711 }
| MeshRefinement& libMesh::MeshRefinement::operator= | ( | const MeshRefinement & | ) | [private] |
| bool libMesh::MeshRefinement::refine_and_coarsen_elements | ( | const bool | maintain_level_one = true |
) |
Refines and coarsens user-requested elements. Will also refine/coarsen additional elements to satisy level-one rule. It is possible that for a given set of refinement flags there is actually no change upon calling this member function. Consequently, this function returns true if the mesh actually changed (hence data needs to be projected) and false otherwise.
The argument maintain_level_one is now deprecated; use the option face_level_mismatch_limit() instead.
Definition at line 441 of file mesh_refinement.C.
References _coarsen_elements(), _edge_level_mismatch_limit, _face_level_mismatch_limit, _mesh, _node_level_mismatch_limit, _refine_elements(), libMesh::Elem::active(), libMesh::CommWorld, libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), eliminate_unrefined_patches(), libMesh::Elem::INACTIVE, libMesh::MeshBase::is_serial(), libMesh::Elem::JUST_REFINED, libMesh::MeshBase::libmesh_assert_valid_parallel_ids(), limit_level_mismatch_at_edge(), limit_level_mismatch_at_node(), make_coarsening_compatible(), make_flags_parallel_consistent(), make_refinement_compatible(), libMesh::Parallel::Communicator::max(), libMesh::Parallel::Communicator::min(), libMesh::MeshBase::prepare_for_use(), libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), test_level_one(), and test_unflagged().
00442 { 00443 // This function must be run on all processors at once 00444 parallel_only(); 00445 00446 bool _maintain_level_one = maintain_level_one; 00447 00448 // If the user used non-default parameters, let's warn that they're 00449 // deprecated 00450 if (!maintain_level_one) 00451 { 00452 libmesh_deprecated(); 00453 } 00454 else 00455 _maintain_level_one = _face_level_mismatch_limit; 00456 00457 // We can't yet turn a non-level-one mesh into a level-one mesh 00458 if (_maintain_level_one) 00459 libmesh_assert(test_level_one(true)); 00460 00461 // Possibly clean up the refinement flags from 00462 // a previous step 00463 MeshBase::element_iterator elem_it = _mesh.elements_begin(); 00464 const MeshBase::element_iterator elem_end = _mesh.elements_end(); 00465 00466 for ( ; elem_it != elem_end; ++elem_it) 00467 { 00468 // Pointer to the element 00469 Elem *elem = *elem_it; 00470 00471 // Set refinement flag to INACTIVE if the 00472 // element isn't active 00473 if ( !elem->active()) 00474 { 00475 elem->set_refinement_flag(Elem::INACTIVE); 00476 elem->set_p_refinement_flag(Elem::INACTIVE); 00477 } 00478 00479 // This might be left over from the last step 00480 if (elem->refinement_flag() == Elem::JUST_REFINED) 00481 elem->set_refinement_flag(Elem::DO_NOTHING); 00482 } 00483 00484 // Parallel consistency has to come first, or coarsening 00485 // along processor boundaries might occasionally be falsely 00486 // prevented 00487 if (!_mesh.is_serial()) 00488 this->make_flags_parallel_consistent(); 00489 00490 // Repeat until flag changes match on every processor 00491 do 00492 { 00493 // Repeat until coarsening & refinement flags jive 00494 bool satisfied = false; 00495 do 00496 { 00497 const bool coarsening_satisfied = 00498 this->make_coarsening_compatible(maintain_level_one); 00499 00500 const bool refinement_satisfied = 00501 this->make_refinement_compatible(maintain_level_one); 00502 00503 bool smoothing_satisfied = 00504 !this->eliminate_unrefined_patches(); 00505 00506 if (_edge_level_mismatch_limit) 00507 smoothing_satisfied = smoothing_satisfied && 00508 !this->limit_level_mismatch_at_edge (_edge_level_mismatch_limit); 00509 00510 if (_node_level_mismatch_limit) 00511 smoothing_satisfied = smoothing_satisfied && 00512 !this->limit_level_mismatch_at_node (_node_level_mismatch_limit); 00513 00514 satisfied = (coarsening_satisfied && 00515 refinement_satisfied && 00516 smoothing_satisfied); 00517 #ifdef DEBUG 00518 bool max_satisfied = satisfied, 00519 min_satisfied = satisfied; 00520 CommWorld.max(max_satisfied); 00521 CommWorld.min(min_satisfied); 00522 libmesh_assert_equal_to (satisfied, max_satisfied); 00523 libmesh_assert_equal_to (satisfied, min_satisfied); 00524 #endif 00525 } 00526 while (!satisfied); 00527 } 00528 while (!_mesh.is_serial() && !this->make_flags_parallel_consistent()); 00529 00530 // First coarsen the flagged elements. 00531 const bool coarsening_changed_mesh = 00532 this->_coarsen_elements (); 00533 00534 // FIXME: test_level_one now tests consistency across periodic 00535 // boundaries, which requires a point_locator, which just got 00536 // invalidated by _coarsen_elements() and hasn't yet been cleared by 00537 // prepare_for_use(). 00538 00539 // if (_maintain_level_one) 00540 // libmesh_assert(test_level_one(true)); 00541 // libmesh_assert(this->make_coarsening_compatible(maintain_level_one)); 00542 // libmesh_assert(this->make_refinement_compatible(maintain_level_one)); 00543 00544 // FIXME: This won't pass unless we add a redundant find_neighbors() 00545 // call or replace find_neighbors() with on-the-fly neighbor updating 00546 // libmesh_assert(!this->eliminate_unrefined_patches()); 00547 00548 // We can't contract the mesh ourselves anymore - a System might 00549 // need to restrict old coefficient vectors first 00550 // _mesh.contract(); 00551 00552 // Now refine the flagged elements. This will 00553 // take up some space, maybe more than what was freed. 00554 const bool refining_changed_mesh = 00555 this->_refine_elements(); 00556 00557 // Finally, the new mesh needs to be prepared for use 00558 if (coarsening_changed_mesh || refining_changed_mesh) 00559 { 00560 #ifdef DEBUG 00561 _mesh.libmesh_assert_valid_parallel_ids(); 00562 #endif 00563 00564 _mesh.prepare_for_use (/*skip_renumber =*/false); 00565 00566 if (_maintain_level_one) 00567 libmesh_assert(test_level_one(true)); 00568 libmesh_assert(test_unflagged(true)); 00569 libmesh_assert(this->make_coarsening_compatible(maintain_level_one)); 00570 libmesh_assert(this->make_refinement_compatible(maintain_level_one)); 00571 // FIXME: This won't pass unless we add a redundant find_neighbors() 00572 // call or replace find_neighbors() with on-the-fly neighbor updating 00573 // libmesh_assert(!this->eliminate_unrefined_patches()); 00574 00575 return true; 00576 } 00577 else 00578 { 00579 if (_maintain_level_one) 00580 libmesh_assert(test_level_one(true)); 00581 libmesh_assert(test_unflagged(true)); 00582 libmesh_assert(this->make_coarsening_compatible(maintain_level_one)); 00583 libmesh_assert(this->make_refinement_compatible(maintain_level_one)); 00584 } 00585 00586 // Otherwise there was no change in the mesh, 00587 // let the user know. Also, there is no need 00588 // to prepare the mesh for use since it did not change. 00589 return false; 00590 00591 }
| bool libMesh::MeshRefinement::refine_elements | ( | const bool | maintain_level_one = true |
) |
Only refines the user-requested elements. It is possible that for a given set of refinement flags there is actually no change upon calling this member function. Consequently, this function returns true if the mesh actually changed (hence data needs to be projected) and false otherwise.
The argument maintain_level_one is now deprecated; use the option face_level_mismatch_limit() instead.
Definition at line 712 of file mesh_refinement.C.
References _edge_level_mismatch_limit, _face_level_mismatch_limit, _mesh, _node_level_mismatch_limit, _refine_elements(), libMesh::Elem::active(), libMesh::CommWorld, libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), eliminate_unrefined_patches(), libMesh::Elem::INACTIVE, libMesh::MeshBase::is_serial(), libMesh::Elem::JUST_REFINED, limit_level_mismatch_at_edge(), limit_level_mismatch_at_node(), make_flags_parallel_consistent(), make_refinement_compatible(), libMesh::Parallel::Communicator::max(), libMesh::Parallel::Communicator::min(), libMesh::MeshBase::prepare_for_use(), libMesh::Elem::refinement_flag(), libMesh::Elem::set_p_refinement_flag(), libMesh::Elem::set_refinement_flag(), and test_level_one().
Referenced by libMesh::EquationSystems::reinit().
00713 { 00714 // This function must be run on all processors at once 00715 parallel_only(); 00716 00717 bool _maintain_level_one = maintain_level_one; 00718 00719 // If the user used non-default parameters, let's warn that they're 00720 // deprecated 00721 if (!maintain_level_one) 00722 { 00723 libmesh_deprecated(); 00724 } 00725 else 00726 _maintain_level_one = _face_level_mismatch_limit; 00727 00728 if (_maintain_level_one) 00729 libmesh_assert(test_level_one(true)); 00730 00731 // Possibly clean up the refinement flags from 00732 // a previous step 00733 MeshBase::element_iterator elem_it = _mesh.elements_begin(); 00734 const MeshBase::element_iterator elem_end = _mesh.elements_end(); 00735 00736 for ( ; elem_it != elem_end; ++elem_it) 00737 { 00738 // Pointer to the element 00739 Elem *elem = *elem_it; 00740 00741 // Set refinement flag to INACTIVE if the 00742 // element isn't active 00743 if ( !elem->active()) 00744 { 00745 elem->set_refinement_flag(Elem::INACTIVE); 00746 elem->set_p_refinement_flag(Elem::INACTIVE); 00747 } 00748 00749 // This might be left over from the last step 00750 if (elem->refinement_flag() == Elem::JUST_REFINED) 00751 elem->set_refinement_flag(Elem::DO_NOTHING); 00752 } 00753 00754 00755 00756 // Parallel consistency has to come first, or coarsening 00757 // along processor boundaries might occasionally be falsely 00758 // prevented 00759 if (!_mesh.is_serial()) 00760 this->make_flags_parallel_consistent(); 00761 00762 // Repeat until flag changes match on every processor 00763 do 00764 { 00765 // Repeat until coarsening & refinement flags jive 00766 bool satisfied = false; 00767 do 00768 { 00769 const bool refinement_satisfied = 00770 this->make_refinement_compatible(maintain_level_one); 00771 00772 bool smoothing_satisfied = 00773 !this->eliminate_unrefined_patches();// && 00774 00775 if (_edge_level_mismatch_limit) 00776 smoothing_satisfied = smoothing_satisfied && 00777 !this->limit_level_mismatch_at_edge (_edge_level_mismatch_limit); 00778 00779 if (_node_level_mismatch_limit) 00780 smoothing_satisfied = smoothing_satisfied && 00781 !this->limit_level_mismatch_at_node (_node_level_mismatch_limit); 00782 00783 satisfied = (refinement_satisfied && 00784 smoothing_satisfied); 00785 #ifdef DEBUG 00786 bool max_satisfied = satisfied, 00787 min_satisfied = satisfied; 00788 CommWorld.max(max_satisfied); 00789 CommWorld.min(min_satisfied); 00790 libmesh_assert_equal_to (satisfied, max_satisfied); 00791 libmesh_assert_equal_to (satisfied, min_satisfied); 00792 #endif 00793 } 00794 while (!satisfied); 00795 } 00796 while (!_mesh.is_serial() && !this->make_flags_parallel_consistent()); 00797 00798 // Now refine the flagged elements. This will 00799 // take up some space, maybe more than what was freed. 00800 const bool mesh_changed = 00801 this->_refine_elements(); 00802 00803 if (_maintain_level_one) 00804 libmesh_assert(test_level_one(true)); 00805 libmesh_assert(this->make_refinement_compatible(maintain_level_one)); 00806 // FIXME: This won't pass unless we add a redundant find_neighbors() 00807 // call or replace find_neighbors() with on-the-fly neighbor updating 00808 // libmesh_assert(!this->eliminate_unrefined_patches()); 00809 00810 // Finally, the new mesh needs to be prepared for use 00811 if (mesh_changed) 00812 _mesh.prepare_for_use (/*skip_renumber =*/false); 00813 00814 return mesh_changed; 00815 }
| Real & libMesh::MeshRefinement::refine_fraction | ( | ) | [inline] |
The refine_fraction sets either a desired target or a desired maximum number of elements to flag for refinement, depending on which flag_elements_by method is called.
refine_fraction must be in
, and is 0.3 by default.
Definition at line 662 of file mesh_refinement.h.
References _refine_fraction, and _use_member_parameters.
00663 { 00664 _use_member_parameters = true; 00665 return _refine_fraction; 00666 }
| void libMesh::MeshRefinement::set_periodic_boundaries_ptr | ( | PeriodicBoundaries * | pb_ptr | ) |
Definition at line 77 of file mesh_refinement.C.
References _periodic_boundaries.
00078 { 00079 _periodic_boundaries = pb_ptr; 00080 }
| void libMesh::MeshRefinement::switch_h_to_p_refinement | ( | ) |
Takes a mesh whose elements are flagged for h refinement and coarsening, and switches those flags to request p refinement and coarsening instead.
Definition at line 655 of file mesh_refinement_flagging.C.
References _mesh, libMesh::Elem::DO_NOTHING, libMesh::MeshBase::elements_begin(), libMesh::MeshBase::elements_end(), and libMesh::Elem::INACTIVE.
00656 { 00657 MeshBase::element_iterator elem_it = _mesh.elements_begin(); 00658 const MeshBase::element_iterator elem_end = _mesh.elements_end(); 00659 00660 for ( ; elem_it != elem_end; ++elem_it) 00661 { 00662 if ((*elem_it)->active()) 00663 { 00664 (*elem_it)->set_p_refinement_flag((*elem_it)->refinement_flag()); 00665 (*elem_it)->set_refinement_flag(Elem::DO_NOTHING); 00666 } 00667 else 00668 { 00669 (*elem_it)->set_p_refinement_flag((*elem_it)->refinement_flag()); 00670 (*elem_it)->set_refinement_flag(Elem::INACTIVE); 00671 } 00672 } 00673 }
| bool libMesh::MeshRefinement::test_level_one | ( | bool | libmesh_assert_yes = false |
) |
Returns true if and only if the mesh is level one smooth Returns false otherwise Aborts the program if libmesh_assert_yes is true and the mesh is not level one smooth
Referenced by coarsen_elements(), refine_and_coarsen_elements(), and refine_elements().
| bool libMesh::MeshRefinement::test_unflagged | ( | bool | libmesh_assert_yes = false |
) |
Returns true if and only if the mesh has no elements flagged to be coarsened or refined Returns false otherwise Aborts the program if libmesh_assert_yes is true and the mesh has flagged elements
Referenced by refine_and_coarsen_elements().
| Elem * libMesh::MeshRefinement::topological_neighbor | ( | Elem * | elem, | |
| const PointLocatorBase * | point_locator, | |||
| const unsigned int | side | |||
| ) | [private] |
Local dispatch function for getting the correct topological neighbor from the Elem class
Definition at line 1772 of file mesh_refinement.C.
References _mesh, _periodic_boundaries, libMesh::Elem::neighbor(), and libMesh::Elem::topological_neighbor().
Referenced by make_coarsening_compatible(), and make_refinement_compatible().
01775 { 01776 #ifdef LIBMESH_ENABLE_PERIODIC 01777 if (_periodic_boundaries && !_periodic_boundaries->empty()) 01778 { 01779 libmesh_assert(point_locator); 01780 return elem->topological_neighbor(side, _mesh, *point_locator, _periodic_boundaries); 01781 } 01782 #endif 01783 return elem->neighbor(side); 01784 }
| void libMesh::MeshRefinement::uniformly_coarsen | ( | unsigned int | n = 1 |
) |
Attempts to uniformly coarsen the mesh n times.
Definition at line 1741 of file mesh_refinement.C.
References _coarsen_elements(), _mesh, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), clean_refinement_flags(), libMesh::Elem::COARSEN, libMesh::Elem::COARSEN_INACTIVE, and libMesh::MeshBase::prepare_for_use().
Referenced by libMesh::AdjointRefinementEstimator::estimate_error().
01742 { 01743 // Coarsen n times 01744 for (unsigned int rstep=0; rstep<n; rstep++) 01745 { 01746 // Clean up the refinement flags 01747 this->clean_refinement_flags(); 01748 01749 // Flag all the active elements for coarsening 01750 MeshBase::element_iterator elem_it = _mesh.active_elements_begin(); 01751 const MeshBase::element_iterator elem_end = _mesh.active_elements_end(); 01752 01753 for ( ; elem_it != elem_end; ++elem_it) 01754 { 01755 (*elem_it)->set_refinement_flag(Elem::COARSEN); 01756 if ((*elem_it)->parent()) 01757 (*elem_it)->parent()->set_refinement_flag(Elem::COARSEN_INACTIVE); 01758 } 01759 01760 // Coarsen all the elements we just flagged. 01761 this->_coarsen_elements(); 01762 } 01763 01764 01765 // Finally, the new mesh probably needs to be prepared for use 01766 if (n > 0) 01767 _mesh.prepare_for_use (/*skip_renumber =*/false); 01768 }
| void libMesh::MeshRefinement::uniformly_p_coarsen | ( | unsigned int | n = 1 |
) |
Attempts to uniformly p coarsen the mesh n times.
Definition at line 1691 of file mesh_refinement.C.
References _mesh, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), and libMesh::Elem::JUST_COARSENED.
Referenced by libMesh::AdjointRefinementEstimator::estimate_error().
01692 { 01693 // Coarsen p times 01694 for (unsigned int rstep=0; rstep<n; rstep++) 01695 { 01696 // P coarsen all the active elements 01697 MeshBase::element_iterator elem_it = _mesh.active_elements_begin(); 01698 const MeshBase::element_iterator elem_end = _mesh.active_elements_end(); 01699 01700 for ( ; elem_it != elem_end; ++elem_it) 01701 { 01702 if ((*elem_it)->p_level() > 0) 01703 { 01704 (*elem_it)->set_p_level((*elem_it)->p_level()-1); 01705 (*elem_it)->set_p_refinement_flag(Elem::JUST_COARSENED); 01706 } 01707 } 01708 } 01709 }
| void libMesh::MeshRefinement::uniformly_p_refine | ( | unsigned int | n = 1 |
) |
Uniformly p refines the mesh n times.
Definition at line 1672 of file mesh_refinement.C.
References _mesh, libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), and libMesh::Elem::JUST_REFINED.
Referenced by libMesh::AdjointRefinementEstimator::estimate_error().
01673 { 01674 // Refine n times 01675 for (unsigned int rstep=0; rstep<n; rstep++) 01676 { 01677 // P refine all the active elements 01678 MeshBase::element_iterator elem_it = _mesh.active_elements_begin(); 01679 const MeshBase::element_iterator elem_end = _mesh.active_elements_end(); 01680 01681 for ( ; elem_it != elem_end; ++elem_it) 01682 { 01683 (*elem_it)->set_p_level((*elem_it)->p_level()+1); 01684 (*elem_it)->set_p_refinement_flag(Elem::JUST_REFINED); 01685 } 01686 } 01687 }
| void libMesh::MeshRefinement::uniformly_refine | ( | unsigned int | n = 1 |
) |
Uniformly refines the mesh n times.
Definition at line 1713 of file mesh_refinement.C.
References _mesh, _refine_elements(), libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), clean_refinement_flags(), libMesh::MeshBase::prepare_for_use(), and libMesh::Elem::REFINE.
Referenced by libMesh::AdjointRefinementEstimator::estimate_error().
01714 { 01715 // Refine n times 01716 // FIXME - this won't work if n>1 and the mesh 01717 // has already been attached to an equation system 01718 for (unsigned int rstep=0; rstep<n; rstep++) 01719 { 01720 // Clean up the refinement flags 01721 this->clean_refinement_flags(); 01722 01723 // Flag all the active elements for refinement. 01724 MeshBase::element_iterator elem_it = _mesh.active_elements_begin(); 01725 const MeshBase::element_iterator elem_end = _mesh.active_elements_end(); 01726 01727 for ( ; elem_it != elem_end; ++elem_it) 01728 (*elem_it)->set_refinement_flag(Elem::REFINE); 01729 01730 // Refine all the elements we just flagged. 01731 this->_refine_elements(); 01732 } 01733 01734 // Finally, the new mesh probably needs to be prepared for use 01735 if (n > 0) 01736 _mesh.prepare_for_use (/*skip_renumber =*/false); 01737 }
| void libMesh::MeshRefinement::update_nodes_map | ( | ) | [private] |
Updates the _new_nodes_map
Definition at line 295 of file mesh_refinement.C.
References _mesh, _new_nodes_map, and libMesh::LocationMap< T >::init().
Referenced by _coarsen_elements(), and _refine_elements().
00296 { 00297 this->_new_nodes_map.init(_mesh); 00298 }
Member Data Documentation
Definition at line 641 of file mesh_refinement.h.
Referenced by absolute_global_tolerance(), and flag_elements_by_error_tolerance().
bool libMesh::MeshRefinement::_coarsen_by_parents [private] |
Refinement parameter values
Definition at line 629 of file mesh_refinement.h.
Referenced by coarsen_by_parents(), flag_elements_by_elem_fraction(), flag_elements_by_error_fraction(), flag_elements_by_error_tolerance(), and flag_elements_by_nelem_target().
Definition at line 633 of file mesh_refinement.h.
Referenced by coarsen_fraction(), flag_elements_by_elem_fraction(), flag_elements_by_error_fraction(), flag_elements_by_error_tolerance(), flag_elements_by_mean_stddev(), and flag_elements_by_nelem_target().
Definition at line 637 of file mesh_refinement.h.
Referenced by coarsen_threshold(), flag_elements_by_error_tolerance(), and flag_elements_by_nelem_target().
unsigned char libMesh::MeshRefinement::_edge_level_mismatch_limit [private] |
Definition at line 643 of file mesh_refinement.h.
Referenced by coarsen_elements(), edge_level_mismatch_limit(), refine_and_coarsen_elements(), and refine_elements().
unsigned char libMesh::MeshRefinement::_face_level_mismatch_limit [private] |
Definition at line 643 of file mesh_refinement.h.
Referenced by coarsen_elements(), face_level_mismatch_limit(), make_coarsening_compatible(), make_refinement_compatible(), refine_and_coarsen_elements(), and refine_elements().
unsigned int libMesh::MeshRefinement::_max_h_level [private] |
Definition at line 635 of file mesh_refinement.h.
Referenced by flag_elements_by_elem_fraction(), flag_elements_by_error_fraction(), flag_elements_by_error_tolerance(), flag_elements_by_mean_stddev(), flag_elements_by_nelem_target(), and max_h_level().
MeshBase& libMesh::MeshRefinement::_mesh [private] |
Reference to the mesh.
Definition at line 616 of file mesh_refinement.h.
Referenced by _coarsen_elements(), _refine_elements(), add_elem(), add_p_to_h_refinement(), add_point(), clean_refinement_flags(), coarsen_elements(), eliminate_unrefined_patches(), flag_elements_by_elem_fraction(), flag_elements_by_error_fraction(), flag_elements_by_error_tolerance(), flag_elements_by_mean_stddev(), flag_elements_by_nelem_target(), get_mesh(), has_topological_neighbor(), limit_level_mismatch_at_edge(), limit_level_mismatch_at_node(), make_coarsening_compatible(), make_flags_parallel_consistent(), make_refinement_compatible(), refine_and_coarsen_elements(), refine_elements(), switch_h_to_p_refinement(), topological_neighbor(), uniformly_coarsen(), uniformly_p_coarsen(), uniformly_p_refine(), uniformly_refine(), and update_nodes_map().
Definition at line 639 of file mesh_refinement.h.
Referenced by flag_elements_by_nelem_target(), and nelem_target().
Data structure that holds the new nodes information.
Definition at line 611 of file mesh_refinement.h.
Referenced by _coarsen_elements(), _refine_elements(), add_point(), clear(), and update_nodes_map().
unsigned char libMesh::MeshRefinement::_node_level_mismatch_limit [private] |
Definition at line 643 of file mesh_refinement.h.
Referenced by coarsen_elements(), node_level_mismatch_limit(), refine_and_coarsen_elements(), and refine_elements().
Definition at line 647 of file mesh_refinement.h.
Referenced by has_topological_neighbor(), make_coarsening_compatible(), make_refinement_compatible(), set_periodic_boundaries_ptr(), and topological_neighbor().
Definition at line 631 of file mesh_refinement.h.
Referenced by flag_elements_by_elem_fraction(), flag_elements_by_error_fraction(), flag_elements_by_error_tolerance(), flag_elements_by_mean_stddev(), flag_elements_by_nelem_target(), and refine_fraction().
bool libMesh::MeshRefinement::_use_member_parameters [private] |
For backwards compatibility, we initialize this as false and then set it to true if the user uses any of the refinement parameter accessor functions
Definition at line 623 of file mesh_refinement.h.
Referenced by absolute_global_tolerance(), coarsen_by_parents(), coarsen_fraction(), coarsen_threshold(), flag_elements_by_elem_fraction(), flag_elements_by_error_fraction(), flag_elements_by_mean_stddev(), max_h_level(), nelem_target(), and refine_fraction().
The documentation for this class was generated from the following files:
Site Created By: libMesh Developers
Last modified: February 05 2013 19:55:29 UTC
Hosted By: