$extrastylesheet
mesh_tools.C
Go to the documentation of this file.
00001 // The libMesh Finite Element Library.
00002 // Copyright (C) 2002-2014 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
00003 
00004 // This library is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU Lesser General Public
00006 // License as published by the Free Software Foundation; either
00007 // version 2.1 of the License, or (at your option) any later version.
00008 
00009 // This library is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012 // Lesser General Public License for more details.
00013 
00014 // You should have received a copy of the GNU Lesser General Public
00015 // License along with this library; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 
00018 
00019 
00020 // C++ includes
00021 #include <limits>
00022 #include <numeric> // for std::accumulate
00023 #include <set>
00024 
00025 // Local includes
00026 #include "libmesh/elem.h"
00027 #include "libmesh/elem_range.h"
00028 #include "libmesh/mesh_base.h"
00029 #include "libmesh/mesh_communication.h"
00030 #include "libmesh/mesh_tools.h"
00031 #include "libmesh/node_range.h"
00032 #include "libmesh/parallel.h"
00033 #include "libmesh/parallel_mesh.h"
00034 #include "libmesh/serial_mesh.h"
00035 #include "libmesh/sphere.h"
00036 #include "libmesh/threads.h"
00037 
00038 #ifdef DEBUG
00039 #  include "libmesh/remote_elem.h"
00040 #endif
00041 
00042 
00043 
00044 // ------------------------------------------------------------
00045 // anonymous namespace for helper classes
00046 namespace {
00047 
00048 using namespace libMesh;
00049 
00057 class SumElemWeight
00058 {
00059 public:
00060   SumElemWeight () :
00061     _weight(0)
00062   {}
00063 
00064   SumElemWeight (SumElemWeight &, Threads::split) :
00065     _weight(0)
00066   {}
00067 
00068   void operator()(const ConstElemRange &range)
00069   {
00070     for (ConstElemRange::const_iterator it = range.begin(); it !=range.end(); ++it)
00071       _weight += (*it)->n_nodes();
00072   }
00073 
00074   dof_id_type weight() const
00075   { return _weight; }
00076 
00077   // If we don't have threads we never need a join, and icpc yells a
00078   // warning if it sees an anonymous function that's never used
00079 #if LIBMESH_USING_THREADS
00080   void join (const SumElemWeight &other)
00081   { _weight += other.weight(); }
00082 #endif
00083 
00084 private:
00085   dof_id_type _weight;
00086 };
00087 
00088 
00095 class FindBBox
00096 {
00097 public:
00098   FindBBox () :
00099     _vmin(LIBMESH_DIM,  std::numeric_limits<Real>::max()),
00100     _vmax(LIBMESH_DIM, -std::numeric_limits<Real>::max())
00101   {}
00102 
00103   FindBBox (FindBBox &other, Threads::split) :
00104     _vmin(other._vmin),
00105     _vmax(other._vmax)
00106   {}
00107 
00108   std::vector<Real> & min() { return _vmin; }
00109   std::vector<Real> & max() { return _vmax; }
00110 
00111   void operator()(const ConstNodeRange &range)
00112   {
00113     for (ConstNodeRange::const_iterator it = range.begin(); it != range.end(); ++it)
00114       {
00115         const Node *node = *it;
00116         libmesh_assert(node);
00117 
00118         for (unsigned int i=0; i<LIBMESH_DIM; i++)
00119           {
00120             _vmin[i] = std::min(_vmin[i], (*node)(i));
00121             _vmax[i] = std::max(_vmax[i], (*node)(i));
00122           }
00123       }
00124   }
00125 
00126   void operator()(const ConstElemRange &range)
00127   {
00128     for (ConstElemRange::const_iterator it = range.begin(); it != range.end(); ++it)
00129       {
00130         const Elem *elem = *it;
00131         libmesh_assert(elem);
00132 
00133         for (unsigned int n=0; n<elem->n_nodes(); n++)
00134           {
00135             const Point &point = elem->point(n);
00136 
00137             for (unsigned int i=0; i<LIBMESH_DIM; i++)
00138               {
00139                 _vmin[i] = std::min(_vmin[i], point(i));
00140                 _vmax[i] = std::max(_vmax[i], point(i));
00141               }
00142           }
00143       }
00144   }
00145 
00146   // If we don't have threads we never need a join, and icpc yells a
00147   // warning if it sees an anonymous function that's never used
00148 #if LIBMESH_USING_THREADS
00149   void join (const FindBBox &other)
00150   {
00151     for (unsigned int i=0; i<LIBMESH_DIM; i++)
00152       {
00153         _vmin[i] = std::min(_vmin[i], other._vmin[i]);
00154         _vmax[i] = std::max(_vmax[i], other._vmax[i]);
00155       }
00156   }
00157 #endif
00158 
00159   MeshTools::BoundingBox bbox () const
00160   {
00161     Point pmin(_vmin[0]
00162 #if LIBMESH_DIM > 1
00163                , _vmin[1]
00164 #endif
00165 #if LIBMESH_DIM > 2
00166                , _vmin[2]
00167 #endif
00168                );
00169     Point pmax(_vmax[0]
00170 #if LIBMESH_DIM > 1
00171                , _vmax[1]
00172 #endif
00173 #if LIBMESH_DIM > 2
00174                , _vmax[2]
00175 #endif
00176                );
00177 
00178     const MeshTools::BoundingBox ret_val(pmin, pmax);
00179 
00180     return ret_val;
00181   }
00182 
00183 private:
00184   std::vector<Real> _vmin;
00185   std::vector<Real> _vmax;
00186 };
00187 
00188 #ifdef DEBUG
00189 void assert_semiverify_dofobj(const Parallel::Communicator &communicator,
00190                               const DofObject *d)
00191 {
00192   if (d)
00193     {
00194       const unsigned int n_sys = d->n_systems();
00195 
00196       std::vector<unsigned int> n_vars (n_sys, 0);
00197       for (unsigned int s = 0; s != n_sys; ++s)
00198         n_vars[s] = d->n_vars(s);
00199 
00200       const unsigned int tot_n_vars =
00201         std::accumulate(n_vars.begin(), n_vars.end(), 0);
00202 
00203       std::vector<unsigned int> n_comp (tot_n_vars, 0);
00204       std::vector<dof_id_type> first_dof (tot_n_vars, 0);
00205 
00206       for (unsigned int s = 0, i=0; s != n_sys; ++s)
00207         for (unsigned int v = 0; v != n_vars[s]; ++v, ++i)
00208           {
00209             n_comp[i] = d->n_comp(s,v);
00210             first_dof[i] = n_comp[i] ? d->dof_number(s,v,0) : DofObject::invalid_id;
00211           }
00212 
00213       libmesh_assert(communicator.semiverify(&n_sys));
00214       libmesh_assert(communicator.semiverify(&n_vars));
00215       libmesh_assert(communicator.semiverify(&n_comp));
00216       libmesh_assert(communicator.semiverify(&first_dof));
00217     }
00218   else
00219     {
00220       const unsigned int* p_ui = NULL;
00221       const std::vector<unsigned int>* p_vui = NULL;
00222       const std::vector<dof_id_type>* p_vdid = NULL;
00223 
00224       libmesh_assert(communicator.semiverify(p_ui));
00225       libmesh_assert(communicator.semiverify(p_vui));
00226       libmesh_assert(communicator.semiverify(p_vui));
00227       libmesh_assert(communicator.semiverify(p_vdid));
00228     }
00229 }
00230 #endif // DEBUG
00231 
00232 }
00233 
00234 
00235 namespace libMesh
00236 {
00237 // Small helper function to make intersect more readable.
00238 bool is_between(Real min, Real check, Real max)
00239 {
00240   return min <= check && check <= max;
00241 }
00242 
00243 bool MeshTools::BoundingBox::intersect (const BoundingBox & other_box) const
00244 {
00245   // Make local variables first to make thiings more clear in a moment
00246   const Real& my_min_x = this->first(0);
00247   const Real& my_max_x = this->second(0);
00248   const Real& other_min_x = other_box.first(0);
00249   const Real& other_max_x = other_box.second(0);
00250 
00251   const bool x_int = is_between(my_min_x, other_min_x, my_max_x) || is_between(my_min_x, other_max_x, my_max_x) ||
00252     is_between(other_min_x, my_min_x, other_max_x) || is_between(other_min_x, my_max_x, other_max_x);
00253 
00254   bool intersection_true = x_int;
00255 
00256 #if LIBMESH_DIM > 1
00257   const Real& my_min_y = this->first(1);
00258   const Real& my_max_y = this->second(1);
00259   const Real& other_min_y = other_box.first(1);
00260   const Real& other_max_y = other_box.second(1);
00261 
00262   const bool y_int = is_between(my_min_y, other_min_y, my_max_y) || is_between(my_min_y, other_max_y, my_max_y) ||
00263     is_between(other_min_y, my_min_y, other_max_y) || is_between(other_min_y, my_max_y, other_max_y);
00264 
00265   intersection_true = intersection_true && y_int;
00266 #endif
00267 
00268 #if LIBMESH_DIM > 2
00269   const Real& my_min_z = this->first(2);
00270   const Real& my_max_z = this->second(2);
00271   const Real& other_min_z = other_box.first(2);
00272   const Real& other_max_z = other_box.second(2);
00273 
00274   const bool z_int = is_between(my_min_z, other_min_z, my_max_z) || is_between(my_min_z, other_max_z, my_max_z) ||
00275     is_between(other_min_z, my_min_z, other_max_z) || is_between(other_min_z, my_max_z, other_max_z);
00276 
00277   intersection_true = intersection_true && z_int;
00278 #endif
00279 
00280   return intersection_true;
00281 }
00282 
00283 bool MeshTools::BoundingBox::contains_point (const Point & p) const
00284 {
00285   // Make local variables first to make thiings more clear in a moment
00286   Real my_min_x = this->first(0);
00287   Real my_max_x = this->second(0);
00288   bool x_int = is_between(my_min_x, p(0), my_max_x);
00289 
00290   bool intersection_true = x_int;
00291 
00292 #if LIBMESH_DIM > 1
00293   Real my_min_y = this->first(1);
00294   Real my_max_y = this->second(1);
00295   bool y_int = is_between(my_min_y, p(1), my_max_y);
00296 
00297   intersection_true = intersection_true && y_int;
00298 #endif
00299 
00300 
00301 #if LIBMESH_DIM > 2
00302   Real my_min_z = this->first(2);
00303   Real my_max_z = this->second(2);
00304   bool z_int = is_between(my_min_z, p(2), my_max_z);
00305 
00306   intersection_true = intersection_true && z_int;
00307 #endif
00308 
00309   return intersection_true;
00310 }
00311 
00312 // ------------------------------------------------------------
00313 // MeshTools functions
00314 dof_id_type MeshTools::total_weight(const MeshBase& mesh)
00315 {
00316   if (!mesh.is_serial())
00317     {
00318       libmesh_parallel_only(mesh.comm());
00319       dof_id_type weight = MeshTools::weight (mesh, mesh.processor_id());
00320       mesh.comm().sum(weight);
00321       dof_id_type unpartitioned_weight =
00322         MeshTools::weight (mesh, DofObject::invalid_processor_id);
00323       return weight + unpartitioned_weight;
00324     }
00325 
00326   SumElemWeight sew;
00327 
00328   Threads::parallel_reduce (ConstElemRange (mesh.elements_begin(),
00329                                             mesh.elements_end()),
00330                             sew);
00331   return sew.weight();
00332 
00333 }
00334 
00335 
00336 
00337 dof_id_type MeshTools::weight(const MeshBase& mesh, const processor_id_type pid)
00338 {
00339   SumElemWeight sew;
00340 
00341   Threads::parallel_reduce (ConstElemRange (mesh.pid_elements_begin(pid),
00342                                             mesh.pid_elements_end(pid)),
00343                             sew);
00344   return sew.weight();
00345 }
00346 
00347 
00348 
00349 void MeshTools::build_nodes_to_elem_map (const MeshBase& mesh,
00350                                          std::vector<std::vector<dof_id_type> >& nodes_to_elem_map)
00351 {
00352   nodes_to_elem_map.resize (mesh.n_nodes());
00353 
00354   MeshBase::const_element_iterator       el  = mesh.elements_begin();
00355   const MeshBase::const_element_iterator end = mesh.elements_end();
00356 
00357   for (; el != end; ++el)
00358     for (unsigned int n=0; n<(*el)->n_nodes(); n++)
00359       {
00360         libmesh_assert_less ((*el)->node(n), nodes_to_elem_map.size());
00361         libmesh_assert_less ((*el)->id(), mesh.n_elem());
00362 
00363         nodes_to_elem_map[(*el)->node(n)].push_back((*el)->id());
00364       }
00365 }
00366 
00367 
00368 
00369 void MeshTools::build_nodes_to_elem_map (const MeshBase& mesh,
00370                                          std::vector<std::vector<const Elem*> >& nodes_to_elem_map)
00371 {
00372   nodes_to_elem_map.resize (mesh.n_nodes());
00373 
00374   MeshBase::const_element_iterator       el  = mesh.elements_begin();
00375   const MeshBase::const_element_iterator end = mesh.elements_end();
00376 
00377   for (; el != end; ++el)
00378     for (unsigned int n=0; n<(*el)->n_nodes(); n++)
00379       {
00380         libmesh_assert_less ((*el)->node(n), nodes_to_elem_map.size());
00381 
00382         nodes_to_elem_map[(*el)->node(n)].push_back(*el);
00383       }
00384 }
00385 
00386 
00387 
00388 void MeshTools::find_boundary_nodes (const MeshBase& mesh,
00389                                      std::vector<bool>& on_boundary)
00390 {
00391   // Resize the vector which holds boundary nodes and fill with false.
00392   on_boundary.resize(mesh.n_nodes());
00393   std::fill(on_boundary.begin(),
00394             on_boundary.end(),
00395             false);
00396 
00397   // Loop over elements, find those on boundary, and
00398   // mark them as true in on_boundary.
00399   MeshBase::const_element_iterator       el  = mesh.active_elements_begin();
00400   const MeshBase::const_element_iterator end = mesh.active_elements_end();
00401 
00402   for (; el != end; ++el)
00403     for (unsigned int s=0; s<(*el)->n_neighbors(); s++)
00404       if ((*el)->neighbor(s) == NULL) // on the boundary
00405         {
00406           const UniquePtr<Elem> side((*el)->build_side(s));
00407 
00408           for (unsigned int n=0; n<side->n_nodes(); n++)
00409             on_boundary[side->node(n)] = true;
00410         }
00411 }
00412 
00413 
00414 
00415 MeshTools::BoundingBox
00416 MeshTools::bounding_box(const MeshBase& mesh)
00417 {
00418   // This function must be run on all processors at once
00419   libmesh_parallel_only(mesh.comm());
00420 
00421   FindBBox find_bbox;
00422 
00423   Threads::parallel_reduce (ConstNodeRange (mesh.local_nodes_begin(),
00424                                             mesh.local_nodes_end()),
00425                             find_bbox);
00426 
00427   // and the unpartitioned nodes
00428   Threads::parallel_reduce (ConstNodeRange (mesh.pid_nodes_begin(DofObject::invalid_processor_id),
00429                                             mesh.pid_nodes_end(DofObject::invalid_processor_id)),
00430                             find_bbox);
00431 
00432   // Compare the bounding boxes across processors
00433   mesh.comm().min(find_bbox.min());
00434   mesh.comm().max(find_bbox.max());
00435 
00436   return find_bbox.bbox();
00437 }
00438 
00439 
00440 
00441 Sphere
00442 MeshTools::bounding_sphere(const MeshBase& mesh)
00443 {
00444   BoundingBox bbox = bounding_box(mesh);
00445 
00446   const Real  diag = (bbox.second - bbox.first).size();
00447   const Point cent = (bbox.second + bbox.first)/2;
00448 
00449   return Sphere (cent, .5*diag);
00450 }
00451 
00452 
00453 
00454 MeshTools::BoundingBox
00455 MeshTools::processor_bounding_box (const MeshBase& mesh,
00456                                    const processor_id_type pid)
00457 {
00458   libmesh_assert_less (pid, mesh.n_processors());
00459 
00460   FindBBox find_bbox;
00461 
00462   Threads::parallel_reduce (ConstElemRange (mesh.pid_elements_begin(pid),
00463                                             mesh.pid_elements_end(pid)),
00464                             find_bbox);
00465 
00466   return find_bbox.bbox();
00467 }
00468 
00469 
00470 
00471 Sphere
00472 MeshTools::processor_bounding_sphere (const MeshBase& mesh,
00473                                       const processor_id_type pid)
00474 {
00475   BoundingBox bbox = processor_bounding_box(mesh,pid);
00476 
00477   const Real  diag = (bbox.second - bbox.first).size();
00478   const Point cent = (bbox.second + bbox.first)/2;
00479 
00480   return Sphere (cent, .5*diag);
00481 }
00482 
00483 
00484 
00485 MeshTools::BoundingBox
00486 MeshTools::subdomain_bounding_box (const MeshBase& mesh,
00487                                    const subdomain_id_type sid)
00488 {
00489   libmesh_assert_not_equal_to (mesh.n_nodes(), 0);
00490 
00491   Point min( 1.e30,  1.e30,  1.e30);
00492   Point max(-1.e30, -1.e30, -1.e30);
00493 
00494   for (unsigned int e=0; e<mesh.n_elem(); e++)
00495     if (mesh.elem(e)->subdomain_id() == sid)
00496       for (unsigned int n=0; n<mesh.elem(e)->n_nodes(); n++)
00497         for (unsigned int i=0; i<mesh.spatial_dimension(); i++)
00498           {
00499             min(i) = std::min(min(i), mesh.point(mesh.elem(e)->node(n))(i));
00500             max(i) = std::max(max(i), mesh.point(mesh.elem(e)->node(n))(i));
00501           }
00502 
00503   return BoundingBox (min, max);
00504 }
00505 
00506 
00507 
00508 Sphere
00509 MeshTools::subdomain_bounding_sphere (const MeshBase& mesh,
00510                                       const subdomain_id_type sid)
00511 {
00512   BoundingBox bbox = subdomain_bounding_box(mesh,sid);
00513 
00514   const Real  diag = (bbox.second - bbox.first).size();
00515   const Point cent = (bbox.second + bbox.first)/2;
00516 
00517   return Sphere (cent, .5*diag);
00518 }
00519 
00520 
00521 
00522 void MeshTools::elem_types (const MeshBase& mesh,
00523                             std::vector<ElemType>& et)
00524 {
00525   MeshBase::const_element_iterator       el  = mesh.elements_begin();
00526   const MeshBase::const_element_iterator end = mesh.elements_end();
00527 
00528   // Automatically get the first type
00529   et.push_back((*el)->type());  ++el;
00530 
00531   // Loop over the rest of the elements.
00532   // If the current element type isn't in the
00533   // vector, insert it.
00534   for (; el != end; ++el)
00535     if (!std::count(et.begin(), et.end(), (*el)->type()))
00536       et.push_back((*el)->type());
00537 }
00538 
00539 
00540 
00541 dof_id_type MeshTools::n_elem_of_type (const MeshBase& mesh,
00542                                        const ElemType type)
00543 {
00544   return static_cast<dof_id_type>(std::distance(mesh.type_elements_begin(type),
00545                                                 mesh.type_elements_end  (type)));
00546 }
00547 
00548 
00549 
00550 dof_id_type MeshTools::n_active_elem_of_type (const MeshBase& mesh,
00551                                               const ElemType type)
00552 {
00553   return static_cast<dof_id_type>(std::distance(mesh.active_type_elements_begin(type),
00554                                                 mesh.active_type_elements_end  (type)));
00555 }
00556 
00557 dof_id_type MeshTools::n_non_subactive_elem_of_type_at_level(const MeshBase& mesh,
00558                                                              const ElemType type,
00559                                                              const unsigned int level)
00560 {
00561   dof_id_type cnt = 0;
00562   // iterate over the elements of the specified type
00563   MeshBase::const_element_iterator el = mesh.type_elements_begin(type);
00564   const MeshBase::const_element_iterator end = mesh.type_elements_end(type);
00565 
00566   for(; el!=end; ++el)
00567     if( ((*el)->level() == level) && !(*el)->subactive())
00568       cnt++;
00569 
00570   return cnt;
00571 }
00572 
00573 
00574 unsigned int MeshTools::n_active_local_levels(const MeshBase& mesh)
00575 {
00576   unsigned int max_level = 0;
00577 
00578   MeshBase::const_element_iterator el = mesh.active_local_elements_begin();
00579   const MeshBase::const_element_iterator end_el = mesh.active_local_elements_end();
00580 
00581   for( ; el != end_el; ++el)
00582     max_level = std::max((*el)->level(), max_level);
00583 
00584   return max_level + 1;
00585 }
00586 
00587 
00588 
00589 unsigned int MeshTools::n_active_levels(const MeshBase& mesh)
00590 {
00591   libmesh_parallel_only(mesh.comm());
00592 
00593   unsigned int nl = MeshTools::n_active_local_levels(mesh);
00594 
00595   MeshBase::const_element_iterator el =
00596     mesh.unpartitioned_elements_begin();
00597   const MeshBase::const_element_iterator end_el =
00598     mesh.unpartitioned_elements_end();
00599 
00600   for( ; el != end_el; ++el)
00601     if ((*el)->active())
00602       nl = std::max((*el)->level() + 1, nl);
00603 
00604   mesh.comm().max(nl);
00605   return nl;
00606 }
00607 
00608 
00609 
00610 unsigned int MeshTools::n_local_levels(const MeshBase& mesh)
00611 {
00612   unsigned int max_level = 0;
00613 
00614   MeshBase::const_element_iterator el = mesh.local_elements_begin();
00615   const MeshBase::const_element_iterator end_el = mesh.local_elements_end();
00616 
00617   for( ; el != end_el; ++el)
00618     max_level = std::max((*el)->level(), max_level);
00619 
00620   return max_level + 1;
00621 }
00622 
00623 
00624 
00625 unsigned int MeshTools::n_levels(const MeshBase& mesh)
00626 {
00627   libmesh_parallel_only(mesh.comm());
00628 
00629   unsigned int nl = MeshTools::n_local_levels(mesh);
00630 
00631   MeshBase::const_element_iterator el =
00632     mesh.unpartitioned_elements_begin();
00633   const MeshBase::const_element_iterator end_el =
00634     mesh.unpartitioned_elements_end();
00635 
00636   for( ; el != end_el; ++el)
00637     nl = std::max((*el)->level() + 1, nl);
00638 
00639   mesh.comm().max(nl);
00640   return nl;
00641 }
00642 
00643 
00644 
00645 void MeshTools::get_not_subactive_node_ids(const MeshBase& mesh,
00646                                            std::set<dof_id_type>& not_subactive_node_ids)
00647 {
00648   MeshBase::const_element_iterator el           = mesh.elements_begin();
00649   const MeshBase::const_element_iterator end_el = mesh.elements_end();
00650   for( ; el != end_el; ++el)
00651     {
00652       const Elem* elem = (*el);
00653       if(!elem->subactive())
00654         for (unsigned int n=0; n<elem->n_nodes(); ++n)
00655           not_subactive_node_ids.insert(elem->node(n));
00656     }
00657 }
00658 
00659 
00660 
00661 dof_id_type MeshTools::n_elem (const MeshBase::const_element_iterator &begin,
00662                                const MeshBase::const_element_iterator &end)
00663 {
00664   return cast_int<dof_id_type>(std::distance(begin, end));
00665 }
00666 
00667 
00668 
00669 dof_id_type MeshTools::n_nodes (const MeshBase::const_node_iterator &begin,
00670                                 const MeshBase::const_node_iterator &end)
00671 {
00672   return cast_int<dof_id_type>(std::distance(begin, end));
00673 }
00674 
00675 
00676 
00677 unsigned int MeshTools::n_p_levels (const MeshBase& mesh)
00678 {
00679   libmesh_parallel_only(mesh.comm());
00680 
00681   unsigned int max_p_level = 0;
00682 
00683   // first my local elements
00684   MeshBase::const_element_iterator
00685     el     = mesh.local_elements_begin(),
00686     end_el = mesh.local_elements_end();
00687 
00688   for( ; el != end_el; ++el)
00689     max_p_level = std::max((*el)->p_level(), max_p_level);
00690 
00691   // then any unpartitioned objects
00692   el     = mesh.unpartitioned_elements_begin();
00693   end_el = mesh.unpartitioned_elements_end();
00694 
00695   for( ; el != end_el; ++el)
00696     max_p_level = std::max((*el)->p_level(), max_p_level);
00697 
00698   mesh.comm().max(max_p_level);
00699   return max_p_level + 1;
00700 }
00701 
00702 
00703 
00704 void MeshTools::find_nodal_neighbors(const MeshBase&,
00705                                      const Node& node,
00706                                      std::vector<std::vector<const Elem*> >& nodes_to_elem_map,
00707                                      std::vector<const Node*>& neighbors)
00708 {
00709   // We'll refer back to the Node ID several times
00710   dof_id_type global_id = node.id();
00711 
00712   // Iterators to iterate through the elements that include this node
00713   std::vector<const Elem*>::const_iterator el     = nodes_to_elem_map[global_id].begin();
00714   std::vector<const Elem*>::const_iterator end_el = nodes_to_elem_map[global_id].end();
00715 
00716   // Look through the elements that contain this node
00717   // find the local node id... then find the side that
00718   // node lives on in the element
00719   // next, look for the _other_ node on that side
00720   // That other node is a "nodal_neighbor"... save it
00721   for (; el != end_el; ++el)
00722     {
00723       // Grab an Elem pointer to use in the subsequent loop
00724       const Elem* elem = *el;
00725 
00726       // We only care about active elements...
00727       if (elem->active())
00728         {
00729           // Which local node number is global_id?
00730           unsigned local_node_number = elem->local_node(global_id);
00731 
00732           // Make sure it was found
00733           libmesh_assert_not_equal_to(local_node_number, libMesh::invalid_uint);
00734 
00735           // Index of the current edge
00736           unsigned current_edge = 0;
00737 
00738           while (current_edge < elem->n_edges())
00739             {
00740               // Find the edge the node is on
00741               bool found_edge = false;
00742               for (; current_edge<elem->n_edges(); ++current_edge)
00743                 if ( elem->is_node_on_edge(local_node_number, current_edge) )
00744                   {
00745                     found_edge = true;
00746                     break;
00747                   }
00748 
00749               // Did we find one?
00750               if (found_edge)
00751                 {
00752                   Node* node_to_save = NULL;
00753 
00754                   // Find another node in this element on this edge
00755                   for (unsigned other_node_this_edge = 0; other_node_this_edge<elem->n_nodes(); other_node_this_edge++)
00756                     if ( (elem->is_node_on_edge(other_node_this_edge, current_edge)) && // On the current edge
00757                          (elem->node(other_node_this_edge) != global_id))               // But not the original node
00758                       {
00759                         // We've found a nodal neighbor!  Save a pointer to it..
00760                         node_to_save = elem->get_node(other_node_this_edge);
00761                         break;
00762                       }
00763 
00764                   // Make sure we found something
00765                   libmesh_assert(node_to_save != NULL);
00766 
00767                   // Search to see if we've already found this one
00768                   std::vector<const Node*>::const_iterator result = std::find(neighbors.begin(),
00769                                                                               neighbors.end(),
00770                                                                               node_to_save);
00771 
00772                   // If we didn't already have it, add it to the vector
00773                   if (result == neighbors.end())
00774                     neighbors.push_back(node_to_save);
00775                 }
00776 
00777               // Keep looking for edges, node may be on more than one edge
00778               current_edge++;
00779             }
00780         }
00781     }
00782 }
00783 
00784 
00785 
00786 void MeshTools::find_hanging_nodes_and_parents(const MeshBase& mesh, std::map<dof_id_type, std::vector<dof_id_type> >& hanging_nodes)
00787 {
00788   MeshBase::const_element_iterator it  = mesh.active_local_elements_begin();
00789   const MeshBase::const_element_iterator end = mesh.active_local_elements_end();
00790 
00791   //Loop through all the elements
00792   for (; it != end; ++it)
00793     {
00794       //Save it off for easier access
00795       const Elem* elem = (*it);
00796 
00797       //Right now this only works for quad4's
00798       //libmesh_assert_equal_to (elem->type(), QUAD4);
00799       if(elem->type() == QUAD4)
00800         {
00801           //Loop over the sides looking for sides that have hanging nodes
00802           //This code is inspired by compute_proj_constraints()
00803           for (unsigned int s=0; s<elem->n_sides(); s++)
00804             {
00805               //If not a boundary node
00806               if (elem->neighbor(s) != NULL)
00807                 {
00808                   // Get pointers to the element's neighbor.
00809                   const Elem* neigh = elem->neighbor(s);
00810 
00811                   //Is there a coarser element next to this one?
00812                   if (neigh->level() < elem->level())
00813                     {
00814                       const Elem *ancestor = elem;
00815                       while (neigh->level() < ancestor->level())
00816                         ancestor = ancestor->parent();
00817                       unsigned int s_neigh = neigh->which_neighbor_am_i(ancestor);
00818                       libmesh_assert_less (s_neigh, neigh->n_neighbors());
00819 
00820                       //Couple of helper uints...
00821                       unsigned int local_node1=0;
00822                       unsigned int local_node2=0;
00823 
00824                       bool found_in_neighbor = false;
00825 
00826                       //Find the two vertices that make up this side
00827                       while(!elem->is_node_on_side(local_node1++,s)) { }
00828                       local_node1--;
00829 
00830                       //Start looking for the second one with the next node
00831                       local_node2=local_node1+1;
00832 
00833                       //Find the other one
00834                       while(!elem->is_node_on_side(local_node2++,s)) { }
00835                       local_node2--;
00836 
00837                       //Pull out their global ids:
00838                       dof_id_type node1 = elem->node(local_node1);
00839                       dof_id_type node2 = elem->node(local_node2);
00840 
00841                       //Now find which node is present in the neighbor
00842                       //FIXME This assumes a level one rule!
00843                       //The _other_ one is the hanging node
00844 
00845                       //First look for the first one
00846                       //FIXME could be streamlined a bit
00847                       for(unsigned int n=0;n<neigh->n_sides();n++)
00848                         {
00849                           if(neigh->node(n) == node1)
00850                             found_in_neighbor=true;
00851                         }
00852 
00853                       dof_id_type hanging_node=0;
00854 
00855                       if(!found_in_neighbor)
00856                         hanging_node=node1;
00857                       else //If it wasn't node1 then it must be node2!
00858                         hanging_node=node2;
00859 
00860                       //Reset these for reuse
00861                       local_node1=0;
00862                       local_node2=0;
00863 
00864                       //Find the first node that makes up the side in the neighbor (these should be the parent nodes)
00865                       while(!neigh->is_node_on_side(local_node1++,s_neigh)) { }
00866                       local_node1--;
00867 
00868                       local_node2=local_node1+1;
00869 
00870                       //Find the second node...
00871                       while(!neigh->is_node_on_side(local_node2++,s_neigh)) { }
00872                       local_node2--;
00873 
00874                       //Save them if we haven't already found the parents for this one
00875                       if(hanging_nodes[hanging_node].size()<2)
00876                         {
00877                           hanging_nodes[hanging_node].push_back(neigh->node(local_node1));
00878                           hanging_nodes[hanging_node].push_back(neigh->node(local_node2));
00879                         }
00880                     }
00881                 }
00882             }
00883         }
00884     }
00885 }
00886 
00887 
00888 
00889 void MeshTools::correct_node_proc_ids (MeshBase &mesh)
00890 {
00891   // This function must be run on all processors at once
00892   libmesh_parallel_only(mesh.comm());
00893 
00894   // Fix all nodes' processor ids.  Coarsening may have left us with
00895   // nodes which are no longer touched by any elements of the same
00896   // processor id, and for DofMap to work we need to fix that.
00897 
00898   // In the first pass, invalidate processor ids for nodes on active
00899   // elements.  We avoid touching subactive-only nodes.
00900   MeshBase::element_iterator       e_it  = mesh.active_elements_begin();
00901   const MeshBase::element_iterator e_end = mesh.active_elements_end();
00902   for (; e_it != e_end; ++e_it)
00903     {
00904       Elem *elem = *e_it;
00905       for (unsigned int n=0; n != elem->n_nodes(); ++n)
00906         {
00907           Node *node = elem->get_node(n);
00908           node->invalidate_processor_id();
00909         }
00910     }
00911 
00912   // In the second pass, find the lowest processor ids on active
00913   // elements touching each node, and set the node processor id.
00914   for (e_it = mesh.active_elements_begin(); e_it != e_end; ++e_it)
00915     {
00916       Elem *elem = *e_it;
00917       processor_id_type proc_id = elem->processor_id();
00918       for (unsigned int n=0; n != elem->n_nodes(); ++n)
00919         {
00920           Node *node = elem->get_node(n);
00921           if (node->processor_id() == DofObject::invalid_processor_id ||
00922               node->processor_id() > proc_id)
00923             node->processor_id() = proc_id;
00924         }
00925     }
00926 
00927   // Those two passes will correct every node that touches a local
00928   // element, but we can't be sure about nodes touching remote
00929   // elements.  Fix those now.
00930   MeshCommunication().make_node_proc_ids_parallel_consistent (mesh);
00931 }
00932 
00933 
00934 
00935 #ifdef DEBUG
00936 void MeshTools::libmesh_assert_equal_n_systems (const MeshBase &mesh)
00937 {
00938   MeshBase::const_element_iterator el =
00939     mesh.elements_begin();
00940   const MeshBase::const_element_iterator el_end =
00941     mesh.elements_end();
00942   if (el == el_end)
00943     return;
00944 
00945   const unsigned int n_sys = (*el)->n_systems();
00946 
00947   for (; el != el_end; ++el)
00948     {
00949       const Elem *elem = *el;
00950       libmesh_assert_equal_to (elem->n_systems(), n_sys);
00951     }
00952 
00953   MeshBase::const_node_iterator node_it =
00954     mesh.nodes_begin();
00955   const MeshBase::const_node_iterator node_end =
00956     mesh.nodes_end();
00957 
00958   if (node_it == node_end)
00959     return;
00960 
00961   for (; node_it != node_end; ++node_it)
00962     {
00963       const Node *node = *node_it;
00964       libmesh_assert_equal_to (node->n_systems(), n_sys);
00965     }
00966 }
00967 
00968 
00969 
00970 #ifdef LIBMESH_ENABLE_AMR
00971 void MeshTools::libmesh_assert_old_dof_objects (const MeshBase &mesh)
00972 {
00973   MeshBase::const_element_iterator el =
00974     mesh.elements_begin();
00975   const MeshBase::const_element_iterator el_end =
00976     mesh.elements_end();
00977 
00978   for (; el != el_end; ++el)
00979     {
00980       const Elem *elem = *el;
00981 
00982       if (elem->refinement_flag() == Elem::JUST_REFINED ||
00983           elem->refinement_flag() == Elem::INACTIVE)
00984         continue;
00985 
00986       if (elem->has_dofs())
00987         libmesh_assert(elem->old_dof_object);
00988 
00989       for (unsigned int n=0; n != elem->n_nodes(); ++n)
00990         {
00991           const Node *node = elem->get_node(n);
00992           if (node->has_dofs())
00993             libmesh_assert(elem->get_node(n)->old_dof_object);
00994         }
00995     }
00996 }
00997 #else
00998 void MeshTools::libmesh_assert_old_dof_objects (const MeshBase &) {}
00999 #endif // LIBMESH_ENABLE_AMR
01000 
01001 
01002 
01003 void MeshTools::libmesh_assert_valid_node_pointers(const MeshBase &mesh)
01004 {
01005   const MeshBase::const_element_iterator el_end =
01006     mesh.elements_end();
01007   for (MeshBase::const_element_iterator el =
01008          mesh.elements_begin(); el != el_end; ++el)
01009     {
01010       const Elem* elem = *el;
01011       libmesh_assert (elem);
01012       while (elem)
01013         {
01014           elem->libmesh_assert_valid_node_pointers();
01015           for (unsigned int n=0; n != elem->n_neighbors(); ++n)
01016             if (elem->neighbor(n) &&
01017                 elem->neighbor(n) != remote_elem)
01018               elem->neighbor(n)->libmesh_assert_valid_node_pointers();
01019 
01020           libmesh_assert_not_equal_to (elem->parent(), remote_elem);
01021           elem = elem->parent();
01022         }
01023     }
01024 }
01025 
01026 
01027 void MeshTools::libmesh_assert_valid_remote_elems(const MeshBase &mesh)
01028 {
01029   const MeshBase::const_element_iterator el_end =
01030     mesh.local_elements_end();
01031   for (MeshBase::const_element_iterator el =
01032          mesh.local_elements_begin(); el != el_end; ++el)
01033     {
01034       const Elem* elem = *el;
01035       libmesh_assert (elem);
01036       for (unsigned int n=0; n != elem->n_neighbors(); ++n)
01037         libmesh_assert_not_equal_to (elem->neighbor(n), remote_elem);
01038 #ifdef LIBMESH_ENABLE_AMR
01039       const Elem* parent = elem->parent();
01040       if (parent)
01041         {
01042           libmesh_assert_not_equal_to (parent, remote_elem);
01043           for (unsigned int c=0; c != elem->n_children(); ++c)
01044             libmesh_assert_not_equal_to (parent->child(c), remote_elem);
01045         }
01046 #endif
01047     }
01048 }
01049 
01050 
01051 void MeshTools::libmesh_assert_no_links_to_elem(const MeshBase &mesh,
01052                                                 const Elem *bad_elem)
01053 {
01054   const MeshBase::const_element_iterator el_end =
01055     mesh.elements_end();
01056   for (MeshBase::const_element_iterator el =
01057          mesh.elements_begin(); el != el_end; ++el)
01058     {
01059       const Elem* elem = *el;
01060       libmesh_assert (elem);
01061       libmesh_assert_not_equal_to (elem->parent(), bad_elem);
01062       for (unsigned int n=0; n != elem->n_neighbors(); ++n)
01063         libmesh_assert_not_equal_to (elem->neighbor(n), bad_elem);
01064 #ifdef LIBMESH_ENABLE_AMR
01065       if (elem->has_children())
01066         for (unsigned int c=0; c != elem->n_children(); ++c)
01067           libmesh_assert_not_equal_to (elem->child(c), bad_elem);
01068 #endif
01069     }
01070 }
01071 
01072 
01073 
01074 void MeshTools::libmesh_assert_valid_elem_ids(const MeshBase &mesh)
01075 {
01076   processor_id_type lastprocid = 0;
01077   dof_id_type lastelemid = 0;
01078 
01079   const MeshBase::const_element_iterator el_end =
01080     mesh.active_elements_end();
01081   for (MeshBase::const_element_iterator el =
01082          mesh.active_elements_begin(); el != el_end; ++el)
01083     {
01084       const Elem* elem = *el;
01085       libmesh_assert (elem);
01086       processor_id_type elemprocid = elem->processor_id();
01087       dof_id_type elemid = elem->id();
01088 
01089       libmesh_assert_greater_equal (elemid, lastelemid);
01090       libmesh_assert_greater_equal (elemprocid, lastprocid);
01091 
01092       lastelemid = elemid;
01093       lastprocid = elemprocid;
01094     }
01095 }
01096 
01097 
01098 
01099 void MeshTools::libmesh_assert_valid_amr_elem_ids(const MeshBase &mesh)
01100 {
01101   const MeshBase::const_element_iterator el_end =
01102     mesh.elements_end();
01103   for (MeshBase::const_element_iterator el =
01104          mesh.elements_begin(); el != el_end; ++el)
01105     {
01106       const Elem* elem = *el;
01107       libmesh_assert (elem);
01108 
01109       const Elem* parent = elem->parent();
01110 
01111       if (parent)
01112         {
01113           libmesh_assert_greater_equal (elem->id(), parent->id());
01114           libmesh_assert_greater_equal (elem->processor_id(), parent->processor_id());
01115         }
01116     }
01117 }
01118 
01119 
01120 
01121 void MeshTools::libmesh_assert_connected_nodes (const MeshBase &mesh)
01122 {
01123   std::set<const Node*> used_nodes;
01124 
01125   const MeshBase::const_element_iterator el_end =
01126     mesh.elements_end();
01127   for (MeshBase::const_element_iterator el =
01128          mesh.elements_begin(); el != el_end; ++el)
01129     {
01130       const Elem* elem = *el;
01131       libmesh_assert (elem);
01132 
01133       for (unsigned int n=0; n<elem->n_nodes(); ++n)
01134         used_nodes.insert(elem->get_node(n));
01135     }
01136 
01137   const MeshBase::const_node_iterator node_end = mesh.nodes_end();
01138 
01139   for (MeshBase::const_node_iterator node_it = mesh.nodes_begin();
01140        node_it != node_end; ++node_it)
01141     {
01142       Node *node = *node_it;
01143       libmesh_assert(node);
01144       libmesh_assert(used_nodes.count(node));
01145     }
01146 }
01147 
01148 
01149 
01150 namespace MeshTools {
01151 
01152 void libmesh_assert_valid_dof_ids(const MeshBase &mesh)
01153 {
01154   if (mesh.n_processors() == 1)
01155     return;
01156 
01157   libmesh_parallel_only(mesh.comm());
01158 
01159   dof_id_type pmax_elem_id = mesh.max_elem_id();
01160   mesh.comm().max(pmax_elem_id);
01161 
01162   for (dof_id_type i=0; i != pmax_elem_id; ++i)
01163     assert_semiverify_dofobj(mesh.comm(),
01164                              mesh.query_elem(i));
01165 
01166   dof_id_type pmax_node_id = mesh.max_node_id();
01167   mesh.comm().max(pmax_node_id);
01168 
01169   for (dof_id_type i=0; i != pmax_node_id; ++i)
01170     assert_semiverify_dofobj(mesh.comm(),
01171                              mesh.query_node_ptr(i));
01172 }
01173 
01174 template <>
01175 void libmesh_assert_valid_procids<Elem>(const MeshBase& mesh)
01176 {
01177   if (mesh.n_processors() == 1)
01178     return;
01179 
01180   libmesh_parallel_only(mesh.comm());
01181 
01182   // We want this test to be valid even when called even after nodes
01183   // have been added asynchonously but before they're renumbered
01184   dof_id_type parallel_max_elem_id = mesh.max_elem_id();
01185   mesh.comm().max(parallel_max_elem_id);
01186 
01187   // Check processor ids for consistency between processors
01188 
01189   for (dof_id_type i=0; i != parallel_max_elem_id; ++i)
01190     {
01191       const Elem *elem = mesh.query_elem(i);
01192 
01193       processor_id_type min_id =
01194         elem ? elem->processor_id() :
01195         std::numeric_limits<processor_id_type>::max();
01196       mesh.comm().min(min_id);
01197 
01198       processor_id_type max_id =
01199         elem ? elem->processor_id() :
01200         std::numeric_limits<processor_id_type>::min();
01201       mesh.comm().max(max_id);
01202 
01203       if (elem)
01204         {
01205           libmesh_assert_equal_to (min_id, elem->processor_id());
01206           libmesh_assert_equal_to (max_id, elem->processor_id());
01207         }
01208 
01209       if (min_id == mesh.processor_id())
01210         libmesh_assert(elem);
01211     }
01212 
01213   // If we're adaptively refining, check processor ids for consistency
01214   // between parents and children.
01215 #ifdef LIBMESH_ENABLE_AMR
01216 
01217   // Ancestor elements we won't worry about, but subactive and active
01218   // elements ought to have parents with consistent processor ids
01219 
01220   const MeshBase::const_element_iterator el_end =
01221     mesh.elements_end();
01222   for (MeshBase::const_element_iterator el =
01223          mesh.elements_begin(); el != el_end; ++el)
01224     {
01225       const Elem *elem = *el;
01226       libmesh_assert(elem);
01227 
01228       if (!elem->active() && !elem->subactive())
01229         continue;
01230 
01231       const Elem *parent = elem->parent();
01232 
01233       if (parent)
01234         {
01235           libmesh_assert(parent->has_children());
01236           processor_id_type parent_procid = parent->processor_id();
01237           bool matching_child_id = false;
01238           for (unsigned int c = 0; c != parent->n_children(); ++c)
01239             {
01240               const Elem* child = parent->child(c);
01241               libmesh_assert(child);
01242 
01243               // If we've got a remote_elem then we don't know whether
01244               // it's responsible for the parent's processor id; all
01245               // we can do is assume it is and let its processor fail
01246               // an assert if there's something wrong.
01247               if (child == remote_elem ||
01248                   child->processor_id() == parent_procid)
01249                 matching_child_id = true;
01250             }
01251           libmesh_assert(matching_child_id);
01252         }
01253     }
01254 #endif
01255 }
01256 
01257 
01258 
01259 template <>
01260 void libmesh_assert_valid_procids<Node>(const MeshBase& mesh)
01261 {
01262   if (mesh.n_processors() == 1)
01263     return;
01264 
01265   libmesh_parallel_only(mesh.comm());
01266 
01267   // We want this test to be valid even when called even after nodes
01268   // have been added asynchonously but before they're renumbered
01269   dof_id_type parallel_max_node_id = mesh.max_node_id();
01270   mesh.comm().max(parallel_max_node_id);
01271 
01272   // Check processor ids for consistency between processors
01273 
01274   for (dof_id_type i=0; i != parallel_max_node_id; ++i)
01275     {
01276       const Node *node = mesh.query_node_ptr(i);
01277 
01278       processor_id_type min_id =
01279         node ? node->processor_id() :
01280         std::numeric_limits<processor_id_type>::max();
01281       mesh.comm().min(min_id);
01282 
01283       processor_id_type max_id =
01284         node ? node->processor_id() :
01285         std::numeric_limits<processor_id_type>::min();
01286       mesh.comm().max(max_id);
01287 
01288       if (node)
01289         {
01290           libmesh_assert_equal_to (min_id, node->processor_id());
01291           libmesh_assert_equal_to (max_id, node->processor_id());
01292         }
01293 
01294       if (min_id == mesh.processor_id())
01295         libmesh_assert(node);
01296     }
01297 
01298   std::vector<bool> node_touched_by_me(parallel_max_node_id, false);
01299 
01300   const MeshBase::const_element_iterator el_end =
01301     mesh.active_local_elements_end();
01302   for (MeshBase::const_element_iterator el =
01303          mesh.active_local_elements_begin(); el != el_end; ++el)
01304     {
01305       const Elem* elem = *el;
01306       libmesh_assert (elem);
01307 
01308       for (unsigned int i=0; i != elem->n_nodes(); ++i)
01309         {
01310           const Node *node = elem->get_node(i);
01311           dof_id_type nodeid = node->id();
01312           node_touched_by_me[nodeid] = true;
01313         }
01314     }
01315   std::vector<bool> node_touched_by_anyone(node_touched_by_me);
01316   mesh.comm().max(node_touched_by_anyone);
01317 
01318   const MeshBase::const_node_iterator nd_end = mesh.local_nodes_end();
01319   for (MeshBase::const_node_iterator nd = mesh.local_nodes_begin();
01320        nd != nd_end; ++nd)
01321     {
01322       const Node *node = *nd;
01323       libmesh_assert(node);
01324 
01325       dof_id_type nodeid = node->id();
01326       libmesh_assert(!node_touched_by_anyone[nodeid] ||
01327                      node_touched_by_me[nodeid]);
01328     }
01329 }
01330 
01331 } // namespace MeshTools
01332 
01333 
01334 
01335 #ifdef LIBMESH_ENABLE_AMR
01336 void MeshTools::libmesh_assert_valid_refinement_flags(const MeshBase &mesh)
01337 {
01338   libmesh_parallel_only(mesh.comm());
01339   if (mesh.n_processors() == 1)
01340     return;
01341 
01342   std::vector<unsigned char> my_elem_h_state(mesh.max_elem_id(), 255);
01343   std::vector<unsigned char> my_elem_p_state(mesh.max_elem_id(), 255);
01344 
01345   const MeshBase::const_element_iterator el_end =
01346     mesh.elements_end();
01347   for (MeshBase::const_element_iterator el =
01348          mesh.elements_begin(); el != el_end; ++el)
01349     {
01350       const Elem* elem = *el;
01351       libmesh_assert (elem);
01352       dof_id_type elemid = elem->id();
01353 
01354       my_elem_h_state[elemid] =
01355         static_cast<unsigned char>(elem->refinement_flag());
01356 
01357       my_elem_p_state[elemid] =
01358         static_cast<unsigned char>(elem->p_refinement_flag());
01359     }
01360   std::vector<unsigned char> min_elem_h_state(my_elem_h_state);
01361   mesh.comm().min(min_elem_h_state);
01362 
01363   std::vector<unsigned char> min_elem_p_state(my_elem_p_state);
01364   mesh.comm().min(min_elem_p_state);
01365 
01366   for (dof_id_type i=0; i!= mesh.max_elem_id(); ++i)
01367     {
01368       libmesh_assert(my_elem_h_state[i] == 255 ||
01369                      my_elem_h_state[i] == min_elem_h_state[i]);
01370       libmesh_assert(my_elem_p_state[i] == 255 ||
01371                      my_elem_p_state[i] == min_elem_p_state[i]);
01372     }
01373 }
01374 #else
01375 void MeshTools::libmesh_assert_valid_refinement_flags(const MeshBase &)
01376 {
01377 }
01378 #endif // LIBMESH_ENABLE_AMR
01379 
01380 
01381 
01382 #ifdef LIBMESH_ENABLE_AMR
01383 void MeshTools::libmesh_assert_valid_refinement_tree(const MeshBase &mesh)
01384 {
01385   const MeshBase::const_element_iterator el_end =
01386     mesh.elements_end();
01387   for (MeshBase::const_element_iterator el =
01388          mesh.elements_begin(); el != el_end; ++el)
01389     {
01390       const Elem *elem = *el;
01391       libmesh_assert(elem);
01392       if (elem->has_children())
01393         for (unsigned int n=0; n != elem->n_children(); ++n)
01394           {
01395             libmesh_assert(elem->child(n));
01396             if (elem->child(n) != remote_elem)
01397               libmesh_assert_equal_to (elem->child(n)->parent(), elem);
01398           }
01399       if (elem->active())
01400         {
01401           libmesh_assert(!elem->ancestor());
01402           libmesh_assert(!elem->subactive());
01403         }
01404       else if (elem->ancestor())
01405         {
01406           libmesh_assert(!elem->subactive());
01407         }
01408       else
01409         libmesh_assert(elem->subactive());
01410     }
01411 }
01412 #else
01413 void MeshTools::libmesh_assert_valid_refinement_tree(const MeshBase &)
01414 {
01415 }
01416 #endif // LIBMESH_ENABLE_AMR
01417 
01418 
01419 
01420 void MeshTools::libmesh_assert_valid_neighbors(const MeshBase &mesh)
01421 {
01422   const MeshBase::const_element_iterator el_end = mesh.elements_end();
01423   for (MeshBase::const_element_iterator el = mesh.elements_begin();
01424        el != el_end; ++el)
01425     {
01426       const Elem* elem = *el;
01427       libmesh_assert (elem);
01428       elem->libmesh_assert_valid_neighbors();
01429     }
01430 }
01431 
01432 
01433 
01434 #endif
01435 
01436 
01437 
01438 void MeshTools::Private::globally_renumber_nodes_and_elements (MeshBase& mesh)
01439 {
01440   MeshCommunication().assign_global_indices(mesh);
01441 }
01442 
01443 } // namespace libMesh