$extrastylesheet
elem.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 <algorithm> // for std::sort
00022 #include <iterator>  // for std::ostream_iterator
00023 #include <sstream>
00024 #include <limits>    // for std::numeric_limits<>
00025 #include <cmath>     // for std::sqrt()
00026 
00027 // Local includes
00028 #include "libmesh/elem.h"
00029 #include "libmesh/fe_type.h"
00030 #include "libmesh/fe_interface.h"
00031 #include "libmesh/node_elem.h"
00032 #include "libmesh/edge_edge2.h"
00033 #include "libmesh/edge_edge3.h"
00034 #include "libmesh/edge_edge4.h"
00035 #include "libmesh/edge_inf_edge2.h"
00036 #include "libmesh/face_tri3.h"
00037 #include "libmesh/face_tri3_subdivision.h"
00038 #include "libmesh/face_tri6.h"
00039 #include "libmesh/face_quad4.h"
00040 #include "libmesh/face_quad8.h"
00041 #include "libmesh/face_quad9.h"
00042 #include "libmesh/face_inf_quad4.h"
00043 #include "libmesh/face_inf_quad6.h"
00044 #include "libmesh/cell_tet4.h"
00045 #include "libmesh/cell_tet10.h"
00046 #include "libmesh/cell_hex8.h"
00047 #include "libmesh/cell_hex20.h"
00048 #include "libmesh/cell_hex27.h"
00049 #include "libmesh/cell_inf_hex8.h"
00050 #include "libmesh/cell_inf_hex16.h"
00051 #include "libmesh/cell_inf_hex18.h"
00052 #include "libmesh/cell_prism6.h"
00053 #include "libmesh/cell_prism15.h"
00054 #include "libmesh/cell_prism18.h"
00055 #include "libmesh/cell_inf_prism6.h"
00056 #include "libmesh/cell_inf_prism12.h"
00057 #include "libmesh/cell_pyramid5.h"
00058 #include "libmesh/cell_pyramid13.h"
00059 #include "libmesh/cell_pyramid14.h"
00060 #include "libmesh/fe_base.h"
00061 #include "libmesh/mesh_base.h"
00062 #include "libmesh/quadrature_gauss.h"
00063 #include "libmesh/remote_elem.h"
00064 #include "libmesh/reference_elem.h"
00065 #include "libmesh/string_to_enum.h"
00066 
00067 #ifdef LIBMESH_ENABLE_PERIODIC
00068 #include "libmesh/mesh.h"
00069 #include "libmesh/periodic_boundaries.h"
00070 #include "libmesh/boundary_info.h"
00071 #endif
00072 
00073 namespace libMesh
00074 {
00075 
00076 const subdomain_id_type Elem::invalid_subdomain_id = std::numeric_limits<subdomain_id_type>::max();
00077 
00078 // Initialize static member variables
00079 const unsigned int Elem::type_to_n_nodes_map [] =
00080   {
00081     2,  // EDGE2
00082     3,  // EDGE3
00083     4,  // EDGE4
00084 
00085     3,  // TRI3
00086     6,  // TRI6
00087 
00088     4,  // QUAD4
00089     8,  // QUAD8
00090     9,  // QUAD9
00091 
00092     4,  // TET4
00093     10, // TET10
00094 
00095     8,  // HEX8
00096     20, // HEX20
00097     27, // HEX27
00098 
00099     6,  // PRISM6
00100     15, // PRISM15
00101     18, // PRISM18
00102 
00103     5,  // PYRAMID5
00104     13, // PYRAMID13
00105     14, // PYRAMID14
00106 
00107     2,  // INFEDGE2
00108 
00109     4,  // INFQUAD4
00110     6,  // INFQUAD6
00111 
00112     8,  // INFHEX8
00113     16, // INFHEX16
00114     18, // INFHEX18
00115 
00116     6,  // INFPRISM6
00117     16, // INFPRISM12
00118 
00119     1,  // NODEELEM
00120 
00121     3,  // TRI3SUBDIVISION
00122   };
00123 
00124 const unsigned int Elem::type_to_n_sides_map [] =
00125   {
00126     2,  // EDGE2
00127     2,  // EDGE3
00128     2,  // EDGE4
00129 
00130     3,  // TRI3
00131     3,  // TRI6
00132 
00133     4,  // QUAD4
00134     4,  // QUAD8
00135     4,  // QUAD9
00136 
00137     4,  // TET4
00138     4,  // TET10
00139 
00140     6,  // HEX8
00141     6,  // HEX20
00142     6,  // HEX27
00143 
00144     5,  // PRISM6
00145     5,  // PRISM15
00146     5,  // PRISM18
00147 
00148     5,  // PYRAMID5
00149     5,  // PYRAMID13
00150     5,  // PYRAMID14
00151 
00152     2,  // INFEDGE2
00153 
00154     3,  // INFQUAD4
00155     3,  // INFQUAD6
00156 
00157     5,  // INFHEX8
00158     5,  // INFHEX16
00159     5,  // INFHEX18
00160 
00161     4,  // INFPRISM6
00162     4,  // INFPRISM12
00163 
00164     0,  // NODEELEM
00165   };
00166 
00167 const unsigned int Elem::type_to_n_edges_map [] =
00168   {
00169     0,  // EDGE2
00170     0,  // EDGE3
00171     0,  // EDGE4
00172 
00173     3,  // TRI3
00174     3,  // TRI6
00175 
00176     4,  // QUAD4
00177     4,  // QUAD8
00178     4,  // QUAD9
00179 
00180     6,  // TET4
00181     6,  // TET10
00182 
00183     12, // HEX8
00184     12, // HEX20
00185     12, // HEX27
00186 
00187     9,  // PRISM6
00188     9,  // PRISM15
00189     9,  // PRISM18
00190 
00191     8,  // PYRAMID5
00192     8,  // PYRAMID13
00193     8,  // PYRAMID14
00194 
00195     0,  // INFEDGE2
00196 
00197     4,  // INFQUAD4
00198     4,  // INFQUAD6
00199 
00200     8,  // INFHEX8
00201     8,  // INFHEX16
00202     8,  // INFHEX18
00203 
00204     6,  // INFPRISM6
00205     6,  // INFPRISM12
00206 
00207     0,  // NODEELEM
00208   };
00209 
00210 // ------------------------------------------------------------
00211 // Elem class member funcions
00212 UniquePtr<Elem> Elem::build(const ElemType type,
00213                             Elem* p)
00214 {
00215   Elem* elem = NULL;
00216 
00217   switch (type)
00218     {
00219       // 0D elements
00220     case NODEELEM:
00221       {
00222         elem = new NodeElem(p);
00223         break;
00224       }
00225 
00226       // 1D elements
00227     case EDGE2:
00228       {
00229         elem = new Edge2(p);
00230         break;
00231       }
00232     case EDGE3:
00233       {
00234         elem = new Edge3(p);
00235         break;
00236       }
00237     case EDGE4:
00238       {
00239         elem = new Edge4(p);
00240         break;
00241       }
00242 
00243 
00244 
00245       // 2D elements
00246     case TRI3:
00247       {
00248         elem = new Tri3(p);
00249         break;
00250       }
00251     case TRI3SUBDIVISION:
00252       {
00253         elem = new Tri3Subdivision(p);
00254         break;
00255       }
00256     case TRI6:
00257       {
00258         elem = new Tri6(p);
00259         break;
00260       }
00261     case QUAD4:
00262       {
00263         elem = new Quad4(p);
00264         break;
00265       }
00266     case QUAD8:
00267       {
00268         elem = new Quad8(p);
00269         break;
00270       }
00271     case QUAD9:
00272       {
00273         elem = new Quad9(p);
00274         break;
00275       }
00276 
00277 
00278       // 3D elements
00279     case TET4:
00280       {
00281         elem = new Tet4(p);
00282         break;
00283       }
00284     case TET10:
00285       {
00286         elem = new Tet10(p);
00287         break;
00288       }
00289     case HEX8:
00290       {
00291         elem = new Hex8(p);
00292         break;
00293       }
00294     case HEX20:
00295       {
00296         elem = new Hex20(p);
00297         break;
00298       }
00299     case HEX27:
00300       {
00301         elem = new Hex27(p);
00302         break;
00303       }
00304     case PRISM6:
00305       {
00306         elem = new Prism6(p);
00307         break;
00308       }
00309     case PRISM15:
00310       {
00311         elem = new Prism15(p);
00312         break;
00313       }
00314     case PRISM18:
00315       {
00316         elem = new Prism18(p);
00317         break;
00318       }
00319     case PYRAMID5:
00320       {
00321         elem = new Pyramid5(p);
00322         break;
00323       }
00324     case PYRAMID13:
00325       {
00326         elem = new Pyramid13(p);
00327         break;
00328       }
00329     case PYRAMID14:
00330       {
00331         elem = new Pyramid14(p);
00332         break;
00333       }
00334 
00335 
00336 
00337 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
00338 
00339       // 1D infinite elements
00340     case INFEDGE2:
00341       {
00342         elem = new InfEdge2(p);
00343         break;
00344       }
00345 
00346 
00347       // 2D infinite elements
00348     case INFQUAD4:
00349       {
00350         elem = new InfQuad4(p);
00351         break;
00352       }
00353     case INFQUAD6:
00354       {
00355         elem = new InfQuad6(p);
00356         break;
00357       }
00358 
00359 
00360       // 3D infinite elements
00361     case INFHEX8:
00362       {
00363         elem = new InfHex8(p);
00364         break;
00365       }
00366     case INFHEX16:
00367       {
00368         elem = new InfHex16(p);
00369         break;
00370       }
00371     case INFHEX18:
00372       {
00373         elem = new InfHex18(p);
00374         break;
00375       }
00376     case INFPRISM6:
00377       {
00378         elem = new InfPrism6(p);
00379         break;
00380       }
00381     case INFPRISM12:
00382       {
00383         elem = new InfPrism12(p);
00384         break;
00385       }
00386 
00387 #endif
00388 
00389     default:
00390       libmesh_error_msg("ERROR: Undefined element type!");
00391     }
00392 
00393   return UniquePtr<Elem>(elem);
00394 }
00395 
00396 
00397 
00398 const Elem* Elem::reference_elem () const
00399 {
00400   return &(ReferenceElem::get(this->type()));
00401 }
00402 
00403 
00404 
00405 Point Elem::centroid() const
00406 {
00407   Point cp;
00408 
00409   for (unsigned int n=0; n<this->n_vertices(); n++)
00410     cp.add (this->point(n));
00411 
00412   return (cp /= static_cast<Real>(this->n_vertices()));
00413 }
00414 
00415 
00416 
00417 Real Elem::hmin() const
00418 {
00419   Real h_min=std::numeric_limits<Real>::max();
00420 
00421   for (unsigned int n_outer=0; n_outer<this->n_vertices(); n_outer++)
00422     for (unsigned int n_inner=n_outer+1; n_inner<this->n_vertices(); n_inner++)
00423       {
00424         const Point diff = (this->point(n_outer) - this->point(n_inner));
00425 
00426         h_min = std::min(h_min,diff.size_sq());
00427       }
00428 
00429   return std::sqrt(h_min);
00430 }
00431 
00432 
00433 
00434 Real Elem::hmax() const
00435 {
00436   Real h_max=0;
00437 
00438   for (unsigned int n_outer=0; n_outer<this->n_vertices(); n_outer++)
00439     for (unsigned int n_inner=n_outer+1; n_inner<this->n_vertices(); n_inner++)
00440       {
00441         const Point diff = (this->point(n_outer) - this->point(n_inner));
00442 
00443         h_max = std::max(h_max,diff.size_sq());
00444       }
00445 
00446   return std::sqrt(h_max);
00447 }
00448 
00449 
00450 
00451 Real Elem::length(const unsigned int n1,
00452                   const unsigned int n2) const
00453 {
00454   libmesh_assert_less ( n1, this->n_vertices() );
00455   libmesh_assert_less ( n2, this->n_vertices() );
00456 
00457   return (this->point(n1) - this->point(n2)).size();
00458 }
00459 
00460 
00461 
00462 bool Elem::operator == (const Elem& rhs) const
00463 {
00464 
00465   // Cast rhs to an Elem*
00466   //    const Elem* rhs_elem = dynamic_cast<const Elem*>(&rhs);
00467   const Elem* rhs_elem = &rhs;
00468 
00469   // If we cannot cast to an Elem*, rhs must be a Node
00470   //    if(rhs_elem == static_cast<const Elem*>(NULL))
00471   //        return false;
00472 
00473   //   libmesh_assert (n_nodes());
00474   //   libmesh_assert (rhs.n_nodes());
00475 
00476   //   // Elements can only be equal if they
00477   //   // contain the same number of nodes.
00478   //   if (this->n_nodes() == rhs.n_nodes())
00479   //     {
00480   //       // Create a set that contains our global
00481   //       // node numbers and those of our neighbor.
00482   //       // If the set is the same size as the number
00483   //       // of nodes in both elements then they must
00484   //       // be connected to the same nodes.
00485   //       std::set<unsigned int> nodes_set;
00486 
00487   //       for (unsigned int n=0; n<this->n_nodes(); n++)
00488   //         {
00489   //           nodes_set.insert(this->node(n));
00490   //           nodes_set.insert(rhs.node(n));
00491   //         }
00492 
00493   //       // If this passes the elements are connected
00494   //       // to the same global nodes
00495   //       if (nodes_set.size() == this->n_nodes())
00496   //         return true;
00497   //     }
00498 
00499   //   // If we get here it is because the elements either
00500   //   // do not have the same number of nodes or they are
00501   //   // connected to different nodes.  Either way they
00502   //   // are not the same element
00503   //   return false;
00504 
00505   // Useful typedefs
00506   typedef std::vector<dof_id_type>::iterator iterator;
00507 
00508 
00509   // Elements can only be equal if they
00510   // contain the same number of nodes.
00511   // However, we will only test the vertices,
00512   // which is sufficient & cheaper
00513   if (this->n_nodes() == rhs_elem->n_nodes())
00514     {
00515       // The number of nodes in the element
00516       const unsigned int nn = this->n_nodes();
00517 
00518       // Create a vector that contains our global
00519       // node numbers and those of our neighbor.
00520       // If the sorted, unique vector is the same size
00521       // as the number of nodes in both elements then
00522       // they must be connected to the same nodes.
00523       //
00524       // The vector will be no larger than 2*n_nodes(),
00525       // so we might as well reserve the space.
00526       std::vector<dof_id_type> common_nodes;
00527       common_nodes.reserve (2*nn);
00528 
00529       // Add the global indices of the nodes
00530       for (unsigned int n=0; n<nn; n++)
00531         {
00532           common_nodes.push_back (this->node(n));
00533           common_nodes.push_back (rhs_elem->node(n));
00534         }
00535 
00536       // Sort the vector and find out how long
00537       // the sorted vector is.
00538       std::sort (common_nodes.begin(), common_nodes.end());
00539 
00540       iterator new_end = std::unique (common_nodes.begin(),
00541                                       common_nodes.end());
00542 
00543       const int new_size = cast_int<int>
00544         (std::distance (common_nodes.begin(), new_end));
00545 
00546       // If this passes the elements are connected
00547       // to the same global vertex nodes
00548       if (new_size == static_cast<int>(nn))
00549         return true;
00550     }
00551 
00552   // If we get here it is because the elements either
00553   // do not have the same number of nodes or they are
00554   // connected to different nodes.  Either way they
00555   // are not the same element
00556   return false;
00557 }
00558 
00559 
00560 
00561 bool Elem::is_semilocal(const processor_id_type my_pid) const
00562 {
00563   std::set<const Elem *> point_neighbors;
00564 
00565   this->find_point_neighbors(point_neighbors);
00566 
00567   std::set<const Elem*>::const_iterator       it  = point_neighbors.begin();
00568   const std::set<const Elem*>::const_iterator end = point_neighbors.end();
00569 
00570   for (; it != end; ++it)
00571     {
00572       const Elem* elem = *it;
00573       if (elem->processor_id() == my_pid)
00574         return true;
00575     }
00576 
00577   return false;
00578 }
00579 
00580 
00581 
00582 bool Elem::contains_vertex_of(const Elem *e) const
00583 {
00584   // Our vertices are the first numbered nodes
00585   for (unsigned int n = 0; n != e->n_vertices(); ++n)
00586     if (this->contains_point(e->point(n)))
00587       return true;
00588   return false;
00589 }
00590 
00591 
00592 
00593 bool Elem::contains_edge_of(const Elem *e) const
00594 {
00595   unsigned int num_contained_edges = 0;
00596 
00597   // Our vertices are the first numbered nodes
00598   for (unsigned int n = 0; n != e->n_vertices(); ++n)
00599     {
00600       if (this->contains_point(e->point(n)))
00601         {
00602           num_contained_edges++;
00603           if(num_contained_edges>=2)
00604             {
00605               return true;
00606             }
00607         }
00608     }
00609   return false;
00610 }
00611 
00612 
00613 
00614 void Elem::find_point_neighbors(const Point &p,
00615                                 std::set<const Elem *> &neighbor_set) const
00616 {
00617   libmesh_assert(this->contains_point(p));
00618 
00619   neighbor_set.clear();
00620   neighbor_set.insert(this);
00621 
00622   std::set<const Elem *> untested_set, next_untested_set;
00623   untested_set.insert(this);
00624 
00625   while (!untested_set.empty())
00626     {
00627       // Loop over all the elements in the patch that haven't already
00628       // been tested
00629       std::set<const Elem*>::const_iterator       it  = untested_set.begin();
00630       const std::set<const Elem*>::const_iterator end = untested_set.end();
00631 
00632       for (; it != end; ++it)
00633         {
00634           const Elem* elem = *it;
00635 
00636           for (unsigned int s=0; s<elem->n_sides(); s++)
00637             {
00638               const Elem* current_neighbor = elem->neighbor(s);
00639               if (current_neighbor &&
00640                   current_neighbor != remote_elem)    // we have a real neighbor on this side
00641                 {
00642                   if (current_neighbor->active())                // ... if it is active
00643                     {
00644                       if (current_neighbor->contains_point(p))   // ... and touches p
00645                         {
00646                           // Make sure we'll test it
00647                           if (!neighbor_set.count(current_neighbor))
00648                             next_untested_set.insert (current_neighbor);
00649 
00650                           // And add it
00651                           neighbor_set.insert (current_neighbor);
00652                         }
00653                     }
00654 #ifdef LIBMESH_ENABLE_AMR
00655                   else                                 // ... the neighbor is *not* active,
00656                     {                                  // ... so add *all* neighboring
00657                                                        // active children that touch p
00658                       std::vector<const Elem*> active_neighbor_children;
00659 
00660                       current_neighbor->active_family_tree_by_neighbor
00661                         (active_neighbor_children, elem);
00662 
00663                       std::vector<const Elem*>::const_iterator
00664                         child_it = active_neighbor_children.begin();
00665                       const std::vector<const Elem*>::const_iterator
00666                         child_end = active_neighbor_children.end();
00667                       for (; child_it != child_end; ++child_it)
00668                         {
00669                           const Elem *current_child = *child_it;
00670                           if (current_child->contains_point(p))
00671                             {
00672                               // Make sure we'll test it
00673                               if (!neighbor_set.count(current_child))
00674                                 next_untested_set.insert (current_child);
00675 
00676                               neighbor_set.insert (current_child);
00677                             }
00678                         }
00679                     }
00680 #endif // #ifdef LIBMESH_ENABLE_AMR
00681                 }
00682             }
00683         }
00684       untested_set.swap(next_untested_set);
00685       next_untested_set.clear();
00686     }
00687 }
00688 
00689 
00690 
00691 void Elem::find_point_neighbors(std::set<const Elem *> &neighbor_set) const
00692 {
00693   neighbor_set.clear();
00694   neighbor_set.insert(this);
00695 
00696   std::set<const Elem *> untested_set, next_untested_set;
00697   untested_set.insert(this);
00698 
00699   while (!untested_set.empty())
00700     {
00701       // Loop over all the elements in the patch that haven't already
00702       // been tested
00703       std::set<const Elem*>::const_iterator       it  = untested_set.begin();
00704       const std::set<const Elem*>::const_iterator end = untested_set.end();
00705 
00706       for (; it != end; ++it)
00707         {
00708           const Elem* elem = *it;
00709 
00710           for (unsigned int s=0; s<elem->n_sides(); s++)
00711             {
00712               const Elem* current_neighbor = elem->neighbor(s);
00713               if (current_neighbor &&
00714                   current_neighbor != remote_elem)    // we have a real neighbor on this side
00715                 {
00716                   if (current_neighbor->active())                // ... if it is active
00717                     {
00718                       if (this->contains_vertex_of(current_neighbor) // ... and touches us
00719                           || current_neighbor->contains_vertex_of(this))
00720                         {
00721                           // Make sure we'll test it
00722                           if (!neighbor_set.count(current_neighbor))
00723                             next_untested_set.insert (current_neighbor);
00724 
00725                           // And add it
00726                           neighbor_set.insert (current_neighbor);
00727                         }
00728                     }
00729 #ifdef LIBMESH_ENABLE_AMR
00730                   else                                 // ... the neighbor is *not* active,
00731                     {                                  // ... so add *all* neighboring
00732                                                        // active children
00733                       std::vector<const Elem*> active_neighbor_children;
00734 
00735                       current_neighbor->active_family_tree_by_neighbor
00736                         (active_neighbor_children, elem);
00737 
00738                       std::vector<const Elem*>::const_iterator
00739                         child_it = active_neighbor_children.begin();
00740                       const std::vector<const Elem*>::const_iterator
00741                         child_end = active_neighbor_children.end();
00742                       for (; child_it != child_end; ++child_it)
00743                         {
00744                           const Elem *current_child = *child_it;
00745                           if (this->contains_vertex_of(current_child) ||
00746                               (current_child)->contains_vertex_of(this))
00747                             {
00748                               // Make sure we'll test it
00749                               if (!neighbor_set.count(current_child))
00750                                 next_untested_set.insert (current_child);
00751 
00752                               neighbor_set.insert (current_child);
00753                             }
00754                         }
00755                     }
00756 #endif // #ifdef LIBMESH_ENABLE_AMR
00757                 }
00758             }
00759         }
00760       untested_set.swap(next_untested_set);
00761       next_untested_set.clear();
00762     }
00763 }
00764 
00765 
00766 
00767 void Elem::find_edge_neighbors(const Point& p1,
00768                                const Point& p2,
00769                                std::set<const Elem *> &neighbor_set) const
00770 {
00771   // Simple but perhaps suboptimal code: find elements containing the
00772   // first point, then winnow this set down by removing elements which
00773   // don't also contain the second point
00774 
00775   libmesh_assert(this->contains_point(p2));
00776   this->find_point_neighbors(p1, neighbor_set);
00777 
00778   std::set<const Elem*>::iterator        it = neighbor_set.begin();
00779   const std::set<const Elem*>::iterator end = neighbor_set.end();
00780 
00781   while(it != end) {
00782     std::set<const Elem*>::iterator current = it++;
00783 
00784     const Elem* elem = *current;
00785     // This won't invalidate iterator it, because it is already
00786     // pointing to the next element
00787     if (!elem->contains_point(p2))
00788       neighbor_set.erase(current);
00789   }
00790 }
00791 
00792 
00793 
00794 void Elem::find_edge_neighbors(std::set<const Elem *> &neighbor_set) const
00795 {
00796   neighbor_set.clear();
00797   neighbor_set.insert(this);
00798 
00799   std::set<const Elem *> untested_set, next_untested_set;
00800   untested_set.insert(this);
00801 
00802   while (!untested_set.empty())
00803     {
00804       // Loop over all the elements in the patch that haven't already
00805       // been tested
00806       std::set<const Elem*>::const_iterator       it  = untested_set.begin();
00807       const std::set<const Elem*>::const_iterator end = untested_set.end();
00808 
00809       for (; it != end; ++it)
00810         {
00811           const Elem* elem = *it;
00812 
00813           for (unsigned int s=0; s<elem->n_sides(); s++)
00814             {
00815               const Elem* current_neighbor = elem->neighbor(s);
00816               if (current_neighbor &&
00817                   current_neighbor != remote_elem)    // we have a real neighbor on this side
00818                 {
00819                   if (current_neighbor->active())                // ... if it is active
00820                     {
00821                       if (this->contains_edge_of(current_neighbor) // ... and touches us
00822                           || current_neighbor->contains_edge_of(this))
00823                         {
00824                           // Make sure we'll test it
00825                           if (!neighbor_set.count(current_neighbor))
00826                             next_untested_set.insert (current_neighbor);
00827 
00828                           // And add it
00829                           neighbor_set.insert (current_neighbor);
00830                         }
00831                     }
00832 #ifdef LIBMESH_ENABLE_AMR
00833                   else                                 // ... the neighbor is *not* active,
00834                     {                                  // ... so add *all* neighboring
00835                                                        // active children
00836                       std::vector<const Elem*> active_neighbor_children;
00837 
00838                       current_neighbor->active_family_tree_by_neighbor
00839                         (active_neighbor_children, elem);
00840 
00841                       std::vector<const Elem*>::const_iterator
00842                         child_it = active_neighbor_children.begin();
00843                       const std::vector<const Elem*>::const_iterator
00844                         child_end = active_neighbor_children.end();
00845                       for (; child_it != child_end; ++child_it)
00846                         {
00847                           const Elem *current_child = *child_it;
00848                           if (this->contains_edge_of(*child_it) ||
00849                               (*child_it)->contains_edge_of(this))
00850                             {
00851                               // Make sure we'll test it
00852                               if (!neighbor_set.count(current_child))
00853                                 next_untested_set.insert (current_child);
00854 
00855                               neighbor_set.insert (current_child);
00856                             }
00857                         }
00858                     }
00859 #endif // #ifdef LIBMESH_ENABLE_AMR
00860                 }
00861             }
00862         }
00863       untested_set.swap(next_untested_set);
00864       next_untested_set.clear();
00865     }
00866 }
00867 
00868 #ifdef LIBMESH_ENABLE_PERIODIC
00869 
00870 Elem* Elem::topological_neighbor (const unsigned int i,
00871                                   MeshBase & mesh,
00872                                   const PointLocatorBase& point_locator,
00873                                   const PeriodicBoundaries * pb)
00874 {
00875   libmesh_assert_less (i, this->n_neighbors());
00876 
00877   Elem * neighbor_i = this->neighbor(i);
00878   if (neighbor_i != NULL)
00879     return neighbor_i;
00880 
00881   if (pb)
00882     {
00883       // Since the neighbor is NULL it must be on a boundary. We need
00884       // see if this is a periodic boundary in which case it will have a
00885       // topological neighbor
00886 
00887       std::vector<boundary_id_type> boundary_ids =
00888         mesh.get_boundary_info().boundary_ids(this, cast_int<unsigned short>(i));
00889       for (std::vector<boundary_id_type>::iterator j = boundary_ids.begin(); j != boundary_ids.end(); ++j)
00890         if (pb->boundary(*j))
00891           {
00892             // Since the point locator inside of periodic boundaries
00893             // returns a const pointer we will retrieve the proper
00894             // pointer directly from the mesh object.  Also since coarse
00895             // elements do not have more refined neighbors we need to make
00896             // sure that we don't return one of these types of neighbors.
00897             neighbor_i = mesh.elem(pb->neighbor(*j, point_locator, this, i)->id());
00898             if (level() < neighbor_i->level())
00899               neighbor_i = neighbor_i->parent();
00900             return neighbor_i;
00901           }
00902     }
00903 
00904   return NULL;
00905 }
00906 
00907 
00908 
00909 const Elem* Elem::topological_neighbor (const unsigned int i,
00910                                         const MeshBase & mesh,
00911                                         const PointLocatorBase& point_locator,
00912                                         const PeriodicBoundaries * pb) const
00913 {
00914   libmesh_assert_less (i, this->n_neighbors());
00915 
00916   const Elem * neighbor_i = this->neighbor(i);
00917   if (neighbor_i != NULL)
00918     return neighbor_i;
00919 
00920   if (pb)
00921     {
00922       // Since the neighbor is NULL it must be on a boundary. We need
00923       // see if this is a periodic boundary in which case it will have a
00924       // topological neighbor
00925 
00926       std::vector<boundary_id_type> boundary_ids =
00927         mesh.get_boundary_info().boundary_ids(this, cast_int<unsigned short>(i));
00928       for (std::vector<boundary_id_type>::iterator j = boundary_ids.begin(); j != boundary_ids.end(); ++j)
00929         if (pb->boundary(*j))
00930           {
00931             // Since the point locator inside of periodic boundaries
00932             // returns a const pointer we will retrieve the proper
00933             // pointer directly from the mesh object.  Also since coarse
00934             // elements do not have more refined neighbors we need to make
00935             // sure that we don't return one of these types of neighbors.
00936             neighbor_i = mesh.elem(pb->neighbor(*j, point_locator, this, i)->id());
00937             if (level() < neighbor_i->level())
00938               neighbor_i = neighbor_i->parent();
00939             return neighbor_i;
00940           }
00941     }
00942 
00943   return NULL;
00944 }
00945 
00946 
00947 bool Elem::has_topological_neighbor (const Elem* elem,
00948                                      const MeshBase & mesh,
00949                                      const PointLocatorBase& point_locator,
00950                                      PeriodicBoundaries * pb) const
00951 {
00952   // First see if this is a normal "interior" neighbor
00953   if (has_neighbor(elem))
00954     return true;
00955 
00956   for (unsigned int n=0; n<this->n_neighbors(); n++)
00957     if (this->topological_neighbor(n, mesh, point_locator, pb))
00958       return true;
00959 
00960   return false;
00961 }
00962 
00963 
00964 #endif
00965 
00966 #ifdef DEBUG
00967 
00968 void Elem::libmesh_assert_valid_node_pointers() const
00969 {
00970   libmesh_assert(this->valid_id());
00971   for (unsigned int n=0; n != this->n_nodes(); ++n)
00972     {
00973       libmesh_assert(this->get_node(n));
00974       libmesh_assert(this->get_node(n)->valid_id());
00975     }
00976 }
00977 
00978 
00979 
00980 void Elem::libmesh_assert_valid_neighbors() const
00981 {
00982   for (unsigned int s=0; s<this->n_neighbors(); s++)
00983     {
00984       const Elem *neigh = this->neighbor(s);
00985 
00986       // Any element might have a remote neighbor; checking
00987       // to make sure that's not inaccurate is tough.
00988       if (neigh == remote_elem)
00989         continue;
00990 
00991       if (neigh)
00992         {
00993           // Only subactive elements have subactive neighbors
00994           libmesh_assert (this->subactive() || !neigh->subactive());
00995 
00996           const Elem *elem = this;
00997 
00998           // If we're subactive but our neighbor isn't, its
00999           // return neighbor link will be to our first active
01000           // ancestor OR to our inactive ancestor of the same
01001           // level as neigh,
01002           if (this->subactive() && !neigh->subactive())
01003             {
01004               for (elem = this; !elem->active();
01005                    elem = elem->parent())
01006                 libmesh_assert(elem);
01007             }
01008           else
01009             {
01010               unsigned int rev = neigh->which_neighbor_am_i(elem);
01011               libmesh_assert_less (rev, neigh->n_neighbors());
01012 
01013               if (this->subactive() && !neigh->subactive())
01014                 {
01015                   while (neigh->neighbor(rev) != elem)
01016                     {
01017                       libmesh_assert(elem->parent());
01018                       elem = elem->parent();
01019                     }
01020                 }
01021               else
01022                 {
01023                   Elem *nn = neigh->neighbor(rev);
01024                   libmesh_assert(nn);
01025 
01026                   for (; elem != nn; elem = elem->parent())
01027                     libmesh_assert(elem);
01028                 }
01029             }
01030         }
01031       // If we don't have a neighbor and we're not subactive, our
01032       // ancestors shouldn't have any neighbors in this same
01033       // direction.
01034       else if (!this->subactive())
01035         {
01036           const Elem *my_parent = this->parent();
01037           if (my_parent &&
01038               // A parent with a different dimension isn't really one of
01039               // our ancestors, it means we're on a boundary mesh and this
01040               // is an interior mesh element for which we're on a side.
01041               // Nothing to test for in that case.
01042               (my_parent->dim() == this->dim()))
01043             libmesh_assert (!my_parent->neighbor(s));
01044         }
01045     }
01046 }
01047 
01048 #endif // DEBUG
01049 
01050 
01051 
01052 void Elem::make_links_to_me_local(unsigned int n)
01053 {
01054   Elem *neigh = this->neighbor(n);
01055 
01056   // Don't bother calling this function unless it's necessary
01057   libmesh_assert(neigh);
01058   libmesh_assert(!neigh->is_remote());
01059 
01060   // We never have neighbors more refined than us
01061   libmesh_assert_less_equal (neigh->level(), this->level());
01062 
01063   // We never have subactive neighbors of non subactive elements
01064   libmesh_assert(!neigh->subactive() || this->subactive());
01065 
01066   // If we have a neighbor less refined than us then it must not
01067   // have any more refined active descendants we could have
01068   // pointed to instead.
01069   libmesh_assert(neigh->level() == this->level() ||
01070                  neigh->active());
01071 
01072   // If neigh is at our level, then its family might have
01073   // remote_elem neighbor links which need to point to us
01074   // instead, but if not, then we're done.
01075   if (neigh->level() != this->level())
01076     return;
01077 
01078   // If neigh is subactive then we're not updating its neighbor links
01079   // FIXME - this needs to change when we start using subactive
01080   // elements for more than just the two-phase
01081   // restriction/prolongation projections.
01082   if (neigh->subactive())
01083     return;
01084 
01085   // What side of neigh are we on?  We can't use the usual Elem
01086   // method because we're in the middle of restoring topology
01087   const UniquePtr<Elem> my_side = this->side(n);
01088   unsigned int nn = 0;
01089   for (; nn != neigh->n_sides(); ++nn)
01090     {
01091       const UniquePtr<Elem> neigh_side = neigh->side(nn);
01092       if (*my_side == *neigh_side)
01093         break;
01094     }
01095 
01096   // we had better be on *some* side of neigh
01097   libmesh_assert_less (nn, neigh->n_sides());
01098 
01099   // Find any elements that ought to point to elem
01100   std::vector<const Elem*> neigh_family;
01101 #ifdef LIBMESH_ENABLE_AMR
01102   if (this->active())
01103     neigh->family_tree_by_side(neigh_family, nn);
01104   else
01105 #endif
01106     neigh_family.push_back(neigh);
01107 
01108   // And point them to elem
01109   for (unsigned int i = 0; i != neigh_family.size(); ++i)
01110     {
01111       Elem* neigh_family_member = const_cast<Elem*>(neigh_family[i]);
01112 
01113       // Ideally, the neighbor link ought to either be correct
01114       // already or ought to be to remote_elem.
01115       //
01116       // However, if we're redistributing a newly created elem,
01117       // after an AMR step but before find_neighbors has fixed up
01118       // neighbor links, we might have an out of date neighbor
01119       // link to elem's parent instead.
01120 #ifdef LIBMESH_ENABLE_AMR
01121       libmesh_assert((neigh_family_member->neighbor(nn) == this) ||
01122                      (neigh_family_member->neighbor(nn) == remote_elem)
01123                      || ((this->refinement_flag() == JUST_REFINED) &&
01124                          (this->parent() != NULL) &&
01125                          (neigh_family_member->neighbor(nn) == this->parent())));
01126 #else
01127       libmesh_assert((neigh_family_member->neighbor(nn) == this) ||
01128                      (neigh_family_member->neighbor(nn) == remote_elem));
01129 #endif
01130 
01131       neigh_family_member->set_neighbor(nn, this);
01132     }
01133 }
01134 
01135 
01136 void Elem::make_links_to_me_remote()
01137 {
01138   libmesh_assert_not_equal_to (this, remote_elem);
01139 
01140   // We need to have handled any children first
01141 #if defined(LIBMESH_ENABLE_AMR) && defined(DEBUG)
01142   if (this->has_children())
01143     for (unsigned int c = 0; c != this->n_children(); ++c)
01144       {
01145         Elem *current_child = this->child(c);
01146         libmesh_assert_equal_to (current_child, remote_elem);
01147       }
01148 #endif
01149 
01150   // Remotify any neighbor links to non-subactive elements
01151   if (!this->subactive())
01152     {
01153       for (unsigned int s = 0; s != this->n_sides(); ++s)
01154         {
01155           Elem *neigh = this->neighbor(s);
01156           if (neigh && neigh != remote_elem && !neigh->subactive())
01157             {
01158               // My neighbor should never be more refined than me; my real
01159               // neighbor would have been its parent in that case.
01160               libmesh_assert_greater_equal (this->level(), neigh->level());
01161 
01162               if (this->level() == neigh->level() &&
01163                   neigh->has_neighbor(this))
01164                 {
01165 #ifdef LIBMESH_ENABLE_AMR
01166                   // My neighbor may have descendants which also consider me a
01167                   // neighbor
01168                   std::vector<const Elem*> family;
01169                   neigh->family_tree_by_neighbor (family, this);
01170 
01171                   // FIXME - There's a lot of ugly const_casts here; we
01172                   // may want to make remote_elem non-const and create
01173                   // non-const versions of the family_tree methods
01174                   for (unsigned int i=0; i != family.size(); ++i)
01175                     {
01176                       Elem *n = const_cast<Elem*>(family[i]);
01177                       libmesh_assert (n);
01178                       if (n == remote_elem)
01179                         continue;
01180                       unsigned int my_s = n->which_neighbor_am_i(this);
01181                       libmesh_assert_less (my_s, n->n_neighbors());
01182                       libmesh_assert_equal_to (n->neighbor(my_s), this);
01183                       n->set_neighbor(my_s, const_cast<RemoteElem*>(remote_elem));
01184                     }
01185 #else
01186                   unsigned int my_s = neigh->which_neighbor_am_i(this);
01187                   libmesh_assert_less (my_s, neigh->n_neighbors());
01188                   libmesh_assert_equal_to (neigh->neighbor(my_s), this);
01189                   neigh->set_neighbor(my_s, const_cast<RemoteElem*>(remote_elem));
01190 #endif
01191                 }
01192 #ifdef LIBMESH_ENABLE_AMR
01193               // Even if my neighbor doesn't link back to me, it might
01194               // have subactive descendants which do
01195               else if (neigh->has_children())
01196                 {
01197                   // If my neighbor at the same level doesn't have me as a
01198                   // neighbor, I must be subactive
01199                   libmesh_assert(this->level() > neigh->level() ||
01200                                  this->subactive());
01201 
01202                   // My neighbor must have some ancestor of mine as a
01203                   // neighbor
01204                   Elem *my_ancestor = this->parent();
01205                   libmesh_assert(my_ancestor);
01206                   while (!neigh->has_neighbor(my_ancestor))
01207                     {
01208                       my_ancestor = my_ancestor->parent();
01209                       libmesh_assert(my_ancestor);
01210                     }
01211 
01212                   // My neighbor may have descendants which consider me a
01213                   // neighbor
01214                   std::vector<const Elem*> family;
01215                   neigh->family_tree_by_subneighbor (family, my_ancestor, this);
01216 
01217                   // FIXME - There's a lot of ugly const_casts here; we
01218                   // may want to make remote_elem non-const and create
01219                   // non-const versions of the family_tree methods
01220                   for (unsigned int i=0; i != family.size(); ++i)
01221                     {
01222                       Elem *n = const_cast<Elem*>(family[i]);
01223                       libmesh_assert (n);
01224                       if (n == remote_elem)
01225                         continue;
01226                       unsigned int my_s = n->which_neighbor_am_i(this);
01227                       libmesh_assert_less (my_s, n->n_neighbors());
01228                       libmesh_assert_equal_to (n->neighbor(my_s), this);
01229                       n->set_neighbor(my_s, const_cast<RemoteElem*>(remote_elem));
01230                     }
01231                 }
01232 #endif
01233             }
01234         }
01235     }
01236 
01237 #ifdef LIBMESH_ENABLE_AMR
01238   // Remotify parent's child link
01239   Elem *my_parent = this->parent();
01240   if (my_parent &&
01241       // As long as it's not already remote
01242       my_parent != remote_elem &&
01243       // And it's a real parent, not an interior parent
01244       this->dim() == my_parent->dim())
01245     {
01246       unsigned int me = my_parent->which_child_am_i(this);
01247       libmesh_assert_equal_to (my_parent->child(me), this);
01248       my_parent->set_child(me, const_cast<RemoteElem*>(remote_elem));
01249     }
01250 #endif
01251 }
01252 
01253 
01254 
01255 void Elem::write_connectivity (std::ostream& out_stream,
01256                                const IOPackage iop) const
01257 {
01258   libmesh_assert (out_stream.good());
01259   libmesh_assert(_nodes);
01260   libmesh_assert_not_equal_to (iop, INVALID_IO_PACKAGE);
01261 
01262   switch (iop)
01263     {
01264     case TECPLOT:
01265       {
01266         // This connectivity vector will be used repeatedly instead
01267         // of being reconstructed inside the loop.
01268         std::vector<dof_id_type> conn;
01269         for (unsigned int sc=0; sc <this->n_sub_elem(); sc++)
01270           {
01271             this->connectivity(sc, TECPLOT, conn);
01272 
01273             std::copy(conn.begin(),
01274                       conn.end(),
01275                       std::ostream_iterator<dof_id_type>(out_stream, " "));
01276 
01277             out_stream << '\n';
01278           }
01279         return;
01280       }
01281 
01282     case UCD:
01283       {
01284         for (unsigned int i=0; i<this->n_nodes(); i++)
01285           out_stream << this->node(i)+1 << "\t";
01286 
01287         out_stream << '\n';
01288         return;
01289       }
01290 
01291     default:
01292       libmesh_error_msg("Unsupported IO package " << iop);
01293     }
01294 }
01295 
01296 
01297 
01298 Real Elem::quality (const ElemQuality q) const
01299 {
01300   switch (q)
01301     {
01305     default:
01306       {
01307         libmesh_do_once( libmesh_here();
01308 
01309                          libMesh::err << "ERROR:  unknown quality metric: "
01310                          << Utility::enum_to_string(q)
01311                          << std::endl
01312                          << "Cowardly returning 1."
01313                          << std::endl; );
01314 
01315         return 1.;
01316       }
01317     }
01318 
01319   libmesh_error_msg("We'll never get here!");
01320   return 0.;
01321 }
01322 
01323 
01324 
01325 bool Elem::ancestor() const
01326 {
01327 #ifdef LIBMESH_ENABLE_AMR
01328 
01329   if (this->active())
01330     return false;
01331 
01332   if (!this->has_children())
01333     return false;
01334   if (this->child(0)->active())
01335     return true;
01336 
01337   return this->child(0)->ancestor();
01338 #else
01339   return false;
01340 #endif
01341 }
01342 
01343 
01344 
01345 #ifdef LIBMESH_ENABLE_AMR
01346 
01347 void Elem::add_child (Elem* elem)
01348 {
01349   if(_children == NULL)
01350     {
01351       _children = new Elem*[this->n_children()];
01352 
01353       for (unsigned int c=0; c<this->n_children(); c++)
01354         this->set_child(c, NULL);
01355     }
01356 
01357   for (unsigned int c=0; c<this->n_children(); c++)
01358     {
01359       if(this->_children[c] == NULL || this->_children[c] == remote_elem)
01360         {
01361           libmesh_assert_equal_to (this, elem->parent());
01362           this->set_child(c, elem);
01363           return;
01364         }
01365     }
01366 
01367   libmesh_error_msg("Error: Tried to add a child to an element with full children array");
01368 }
01369 
01370 
01371 
01372 void Elem::add_child (Elem* elem, unsigned int c)
01373 {
01374   if(!this->has_children())
01375     {
01376       _children = new Elem*[this->n_children()];
01377 
01378       for (unsigned int i=0; i<this->n_children(); i++)
01379         this->set_child(i, NULL);
01380     }
01381 
01382   libmesh_assert (this->_children[c] == NULL || this->child(c) == remote_elem);
01383   libmesh_assert (elem == remote_elem || this == elem->parent());
01384 
01385   this->set_child(c, elem);
01386 }
01387 
01388 
01389 
01390 void Elem::replace_child (Elem* elem, unsigned int c)
01391 {
01392   libmesh_assert(this->has_children());
01393 
01394   libmesh_assert(this->child(c));
01395 
01396   this->set_child(c, elem);
01397 }
01398 
01399 
01400 
01401 bool Elem::is_child_on_edge(const unsigned int libmesh_dbg_var(c),
01402                             const unsigned int e) const
01403 {
01404   libmesh_assert_less (c, this->n_children());
01405   libmesh_assert_less (e, this->n_edges());
01406 
01407   UniquePtr<Elem> my_edge = this->build_edge(e);
01408   UniquePtr<Elem> child_edge = this->build_edge(e);
01409 
01410   // We're assuming that an overlapping child edge has the same
01411   // number and orientation as its parent
01412   return (child_edge->node(0) == my_edge->node(0) ||
01413           child_edge->node(1) == my_edge->node(1));
01414 }
01415 
01416 
01417 void Elem::family_tree (std::vector<const Elem*>& family,
01418                         const bool reset) const
01419 {
01420   // The "family tree" doesn't include subactive elements
01421   libmesh_assert(!this->subactive());
01422 
01423   // Clear the vector if the flag reset tells us to.
01424   if (reset)
01425     family.clear();
01426 
01427   // Add this element to the family tree.
01428   family.push_back(this);
01429 
01430   // Recurse into the elements children, if it has them.
01431   // Do not clear the vector any more.
01432   if (!this->active())
01433     for (unsigned int c=0; c<this->n_children(); c++)
01434       if (!this->child(c)->is_remote())
01435         this->child(c)->family_tree (family, false);
01436 }
01437 
01438 
01439 
01440 void Elem::total_family_tree (std::vector<const Elem*>& family,
01441                               const bool reset) const
01442 {
01443   // Clear the vector if the flag reset tells us to.
01444   if (reset)
01445     family.clear();
01446 
01447   // Add this element to the family tree.
01448   family.push_back(this);
01449 
01450   // Recurse into the elements children, if it has them.
01451   // Do not clear the vector any more.
01452   if (this->has_children())
01453     for (unsigned int c=0; c<this->n_children(); c++)
01454       if (!this->child(c)->is_remote())
01455         this->child(c)->total_family_tree (family, false);
01456 }
01457 
01458 
01459 
01460 void Elem::active_family_tree (std::vector<const Elem*>& active_family,
01461                                const bool reset) const
01462 {
01463   // The "family tree" doesn't include subactive elements
01464   libmesh_assert(!this->subactive());
01465 
01466   // Clear the vector if the flag reset tells us to.
01467   if (reset)
01468     active_family.clear();
01469 
01470   // Add this element to the family tree if it is active
01471   if (this->active())
01472     active_family.push_back(this);
01473 
01474   // Otherwise recurse into the element's children.
01475   // Do not clear the vector any more.
01476   else
01477     for (unsigned int c=0; c<this->n_children(); c++)
01478       if (!this->child(c)->is_remote())
01479         this->child(c)->active_family_tree (active_family, false);
01480 }
01481 
01482 
01483 
01484 void Elem::family_tree_by_side (std::vector<const Elem*>& family,
01485                                 const unsigned int s,
01486                                 const bool reset)  const
01487 {
01488   // The "family tree" doesn't include subactive elements
01489   libmesh_assert(!this->subactive());
01490 
01491   // Clear the vector if the flag reset tells us to.
01492   if (reset)
01493     family.clear();
01494 
01495   libmesh_assert_less (s, this->n_sides());
01496 
01497   // Add this element to the family tree.
01498   family.push_back(this);
01499 
01500   // Recurse into the elements children, if it has them.
01501   // Do not clear the vector any more.
01502   if (!this->active())
01503     for (unsigned int c=0; c<this->n_children(); c++)
01504       if (!this->child(c)->is_remote() && this->is_child_on_side(c, s))
01505         this->child(c)->family_tree_by_side (family, s, false);
01506 }
01507 
01508 
01509 
01510 void Elem::active_family_tree_by_side (std::vector<const Elem*>& family,
01511                                        const unsigned int s,
01512                                        const bool reset) const
01513 {
01514   // The "family tree" doesn't include subactive elements
01515   libmesh_assert(!this->subactive());
01516 
01517   // Clear the vector if the flag reset tells us to.
01518   if (reset)
01519     family.clear();
01520 
01521   libmesh_assert_less (s, this->n_sides());
01522 
01523   // Add an active element to the family tree.
01524   if (this->active())
01525     family.push_back(this);
01526 
01527   // Or recurse into an ancestor element's children.
01528   // Do not clear the vector any more.
01529   else
01530     for (unsigned int c=0; c<this->n_children(); c++)
01531       if (!this->child(c)->is_remote() && this->is_child_on_side(c, s))
01532         this->child(c)->active_family_tree_by_side (family, s, false);
01533 }
01534 
01535 
01536 
01537 void Elem::family_tree_by_neighbor (std::vector<const Elem*>& family,
01538                                     const Elem* neighbor_in,
01539                                     const bool reset) const
01540 {
01541   // The "family tree" doesn't include subactive elements
01542   libmesh_assert(!this->subactive());
01543 
01544   // Clear the vector if the flag reset tells us to.
01545   if (reset)
01546     family.clear();
01547 
01548   // This only makes sense if we're already a neighbor
01549   libmesh_assert (this->has_neighbor(neighbor_in));
01550 
01551   // Add this element to the family tree.
01552   family.push_back(this);
01553 
01554   // Recurse into the elements children, if it's not active.
01555   // Do not clear the vector any more.
01556   if (!this->active())
01557     for (unsigned int c=0; c<this->n_children(); c++)
01558       {
01559         Elem *current_child = this->child(c);
01560         if (current_child != remote_elem && current_child->has_neighbor(neighbor_in))
01561           current_child->family_tree_by_neighbor (family, neighbor_in, false);
01562       }
01563 }
01564 
01565 
01566 
01567 void Elem::family_tree_by_subneighbor (std::vector<const Elem*>& family,
01568                                        const Elem* neighbor_in,
01569                                        const Elem* subneighbor,
01570                                        const bool reset) const
01571 {
01572   // The "family tree" doesn't include subactive elements
01573   libmesh_assert(!this->subactive());
01574 
01575   // Clear the vector if the flag reset tells us to.
01576   if (reset)
01577     family.clear();
01578 
01579   // To simplifly this function we need an existing neighbor
01580   libmesh_assert (neighbor_in);
01581   libmesh_assert_not_equal_to (neighbor_in, remote_elem);
01582   libmesh_assert (this->has_neighbor(neighbor_in));
01583 
01584   // This only makes sense if subneighbor descends from neighbor
01585   libmesh_assert (subneighbor);
01586   libmesh_assert_not_equal_to (subneighbor, remote_elem);
01587   libmesh_assert (neighbor_in->is_ancestor_of(subneighbor));
01588 
01589   // Add this element to the family tree if applicable.
01590   if (neighbor_in == subneighbor)
01591     family.push_back(this);
01592 
01593   // Recurse into the elements children, if it's not active.
01594   // Do not clear the vector any more.
01595   if (!this->active())
01596     for (unsigned int c=0; c != this->n_children(); ++c)
01597       {
01598         Elem *current_child = this->child(c);
01599         if (current_child != remote_elem)
01600           for (unsigned int s=0; s != current_child->n_sides(); ++s)
01601             {
01602               Elem *child_neigh = current_child->neighbor(s);
01603               if (child_neigh &&
01604                   (child_neigh == neighbor_in ||
01605                    (child_neigh->parent() == neighbor_in &&
01606                     child_neigh->is_ancestor_of(subneighbor))))
01607                 current_child->family_tree_by_subneighbor (family, child_neigh,
01608                                                            subneighbor, false);
01609             }
01610       }
01611 }
01612 
01613 
01614 
01615 void Elem::active_family_tree_by_neighbor (std::vector<const Elem*>& family,
01616                                            const Elem* neighbor_in,
01617                                            const bool reset) const
01618 {
01619   // The "family tree" doesn't include subactive elements
01620   libmesh_assert(!this->subactive());
01621 
01622   // Clear the vector if the flag reset tells us to.
01623   if (reset)
01624     family.clear();
01625 
01626   // This only makes sense if we're already a neighbor
01627   if (this->level() >= neighbor_in->level())
01628     libmesh_assert (this->has_neighbor(neighbor_in));
01629 
01630   // Add an active element to the family tree.
01631   if (this->active())
01632     family.push_back(this);
01633 
01634   // Or recurse into an ancestor element's children.
01635   // Do not clear the vector any more.
01636   else if (!this->active())
01637     for (unsigned int c=0; c<this->n_children(); c++)
01638       {
01639         Elem *current_child = this->child(c);
01640         if (current_child != remote_elem && current_child->has_neighbor(neighbor_in))
01641           current_child->active_family_tree_by_neighbor (family, neighbor_in, false);
01642       }
01643 }
01644 
01645 
01646 
01647 unsigned int Elem::min_p_level_by_neighbor(const Elem* neighbor_in,
01648                                            unsigned int current_min) const
01649 {
01650   libmesh_assert(!this->subactive());
01651   libmesh_assert(neighbor_in->active());
01652 
01653   // If we're an active element this is simple
01654   if (this->active())
01655     return std::min(current_min, this->p_level());
01656 
01657   libmesh_assert(has_neighbor(neighbor_in));
01658 
01659   // The p_level() of an ancestor element is already the minimum
01660   // p_level() of its children - so if that's high enough, we don't
01661   // need to examine any children.
01662   if (current_min <= this->p_level())
01663     return current_min;
01664 
01665   unsigned int min_p_level = current_min;
01666 
01667   for (unsigned int c=0; c<this->n_children(); c++)
01668     {
01669       const Elem* const current_child = this->child(c);
01670       if (current_child != remote_elem && current_child->has_neighbor(neighbor_in))
01671         min_p_level =
01672           current_child->min_p_level_by_neighbor(neighbor_in,
01673                                                  min_p_level);
01674     }
01675 
01676   return min_p_level;
01677 }
01678 
01679 
01680 unsigned int Elem::min_new_p_level_by_neighbor(const Elem* neighbor_in,
01681                                                unsigned int current_min) const
01682 {
01683   libmesh_assert(!this->subactive());
01684   libmesh_assert(neighbor_in->active());
01685 
01686   // If we're an active element this is simple
01687   if (this->active())
01688     {
01689       unsigned int new_p_level = this->p_level();
01690       if (this->p_refinement_flag() == Elem::REFINE)
01691         new_p_level += 1;
01692       if (this->p_refinement_flag() == Elem::COARSEN)
01693         {
01694           libmesh_assert_greater (new_p_level, 0);
01695           new_p_level -= 1;
01696         }
01697       return std::min(current_min, new_p_level);
01698     }
01699 
01700   libmesh_assert(has_neighbor(neighbor_in));
01701 
01702   unsigned int min_p_level = current_min;
01703 
01704   for (unsigned int c=0; c<this->n_children(); c++)
01705     {
01706       const Elem* const current_child = this->child(c);
01707       if (current_child && current_child != remote_elem)
01708         if (current_child->has_neighbor(neighbor_in))
01709           min_p_level =
01710             current_child->min_new_p_level_by_neighbor(neighbor_in,
01711                                                        min_p_level);
01712     }
01713 
01714   return min_p_level;
01715 }
01716 
01717 #endif // #ifdef LIBMESH_ENABLE_AMR
01718 
01719 
01720 
01721 
01722 bool Elem::contains_point (const Point& p, Real tol) const
01723 {
01724   // We currently allow the user to enlarge the bounding box by
01725   // providing a tol > TOLERANCE (so this routine is identical to
01726   // Elem::close_to_point()), but print a warning so that the
01727   // user can eventually switch his code over to calling close_to_point()
01728   // instead, which is intended to be used for this purpose.
01729   if ( tol > TOLERANCE )
01730     {
01731       libmesh_do_once(libMesh::err
01732                       << "WARNING: Resizing bounding box to match user-specified tolerance!\n"
01733                       << "In the future, calls to Elem::contains_point() with tol > TOLERANCE\n"
01734                       << "will be more optimized, but should not be used\n"
01735                       << "to search for points 'close to' elements!\n"
01736                       << "Instead, use Elem::close_to_point() for this purpose.\n"
01737                       << std::endl;);
01738       return this->point_test(p, tol, tol);
01739     }
01740   else
01741     return this->point_test(p, TOLERANCE, tol);
01742 }
01743 
01744 
01745 
01746 
01747 bool Elem::close_to_point (const Point& p, Real tol) const
01748 {
01749   // This test uses the user's passed-in tolerance for the
01750   // bounding box test as well, thereby allowing the routine to
01751   // find points which are not only "in" the element, but also
01752   // "nearby" to within some tolerance.
01753   return this->point_test(p, tol, tol);
01754 }
01755 
01756 
01757 
01758 
01759 bool Elem::point_test(const Point& p, Real box_tol, Real map_tol) const
01760 {
01761   libmesh_assert_greater (box_tol, 0.);
01762   libmesh_assert_greater (map_tol, 0.);
01763 
01764   // This is a great optimization on first order elements, but it
01765   // could return false negatives on higher orders
01766   if (this->default_order() == FIRST)
01767     {
01768       // Check to make sure the element *could* contain this point, so we
01769       // can avoid an expensive inverse_map call if it doesn't.
01770       bool
01771 #if LIBMESH_DIM > 2
01772         point_above_min_z = false,
01773         point_below_max_z = false,
01774 #endif
01775 #if LIBMESH_DIM > 1
01776         point_above_min_y = false,
01777         point_below_max_y = false,
01778 #endif
01779         point_above_min_x = false,
01780         point_below_max_x = false;
01781 
01782       // For relative bounding box checks in physical space
01783       const Real my_hmax = this->hmax();
01784 
01785       for (unsigned int n=0; n != this->n_nodes(); ++n)
01786         {
01787           Point pe = this->point(n);
01788           point_above_min_x = point_above_min_x || (pe(0) - my_hmax*box_tol <= p(0));
01789           point_below_max_x = point_below_max_x || (pe(0) + my_hmax*box_tol >= p(0));
01790 #if LIBMESH_DIM > 1
01791           point_above_min_y = point_above_min_y || (pe(1) - my_hmax*box_tol <= p(1));
01792           point_below_max_y = point_below_max_y || (pe(1) + my_hmax*box_tol >= p(1));
01793 #endif
01794 #if LIBMESH_DIM > 2
01795           point_above_min_z = point_above_min_z || (pe(2) - my_hmax*box_tol <= p(2));
01796           point_below_max_z = point_below_max_z || (pe(2) + my_hmax*box_tol >= p(2));
01797 #endif
01798         }
01799 
01800       if (
01801 #if LIBMESH_DIM > 2
01802           !point_above_min_z ||
01803           !point_below_max_z ||
01804 #endif
01805 #if LIBMESH_DIM > 1
01806           !point_above_min_y ||
01807           !point_below_max_y ||
01808 #endif
01809           !point_above_min_x ||
01810           !point_below_max_x)
01811         return false;
01812     }
01813 
01814   // Declare a basic FEType.  Will be a Lagrange
01815   // element by default.
01816   FEType fe_type(this->default_order());
01817 
01818   // To be on the safe side, we converge the inverse_map() iteration
01819   // to a slightly tighter tolerance than that requested by the
01820   // user...
01821   const Point mapped_point = FEInterface::inverse_map(this->dim(),
01822                                                       fe_type,
01823                                                       this,
01824                                                       p,
01825                                                       0.1*map_tol, // <- this is |dx| tolerance, the Newton residual should be ~ |dx|^2
01826                                                       /*secure=*/ false);
01827 
01828   // Check that the refspace point maps back to p!  This is only necessary
01829   // for 1D and 2D elements, 3D elements always live in 3D.
01830   //
01831   // TODO: The contains_point() function could most likely be implemented
01832   // more efficiently in the element sub-classes themselves, at least for
01833   // the linear element types.
01834   if (this->dim() < 3)
01835     {
01836       Point xyz = FEInterface::map(this->dim(),
01837                                    fe_type,
01838                                    this,
01839                                    mapped_point);
01840 
01841       // Compute the distance between the original point and the re-mapped point.
01842       // They should be in the same place.
01843       Real dist = (xyz - p).size();
01844 
01845 
01846       // If dist is larger than some fraction of the tolerance, then return false.
01847       // This can happen when e.g. a 2D element is living in 3D, and
01848       // FEInterface::inverse_map() maps p onto the projection of the element,
01849       // effectively "tricking" FEInterface::on_reference_element().
01850       if (dist > this->hmax() * map_tol)
01851         return false;
01852     }
01853 
01854 
01855 
01856   return FEInterface::on_reference_element(mapped_point, this->type(), map_tol);
01857 }
01858 
01859 
01860 
01861 
01862 void Elem::print_info (std::ostream& os) const
01863 {
01864   os << this->get_info()
01865      << std::endl;
01866 }
01867 
01868 
01869 
01870 std::string Elem::get_info () const
01871 {
01872   std::ostringstream oss;
01873 
01874   oss << "  Elem Information"                                      << '\n'
01875       << "   id()=";
01876 
01877   if (this->valid_id())
01878     oss << this->id();
01879   else
01880     oss << "invalid";
01881 
01882   oss << ", processor_id()=" << this->processor_id()               << '\n';
01883 
01884   oss << "   type()="    << Utility::enum_to_string(this->type())  << '\n'
01885       << "   dim()="     << this->dim()                            << '\n'
01886       << "   n_nodes()=" << this->n_nodes()                        << '\n';
01887 
01888   for (unsigned int n=0; n != this->n_nodes(); ++n)
01889     oss << "    " << n << *this->get_node(n);
01890 
01891   oss << "   n_sides()=" << this->n_sides()                        << '\n';
01892 
01893   for (unsigned int s=0; s != this->n_sides(); ++s)
01894     {
01895       oss << "    neighbor(" << s << ")=";
01896       if (this->neighbor(s))
01897         oss << this->neighbor(s)->id() << '\n';
01898       else
01899         oss << "NULL\n";
01900     }
01901 
01902   oss << "   hmin()=" << this->hmin()
01903       << ", hmax()=" << this->hmax()                               << '\n'
01904       << "   volume()=" << this->volume()                          << '\n'
01905       << "   active()=" << this->active()
01906       << ", ancestor()=" << this->ancestor()
01907       << ", subactive()=" << this->subactive()
01908       << ", has_children()=" << this->has_children()               << '\n'
01909       << "   parent()=";
01910   if (this->parent())
01911     oss << this->parent()->id() << '\n';
01912   else
01913     oss << "NULL\n";
01914   oss << "   level()=" << this->level()
01915       << ", p_level()=" << this->p_level()                         << '\n'
01916 #ifdef LIBMESH_ENABLE_AMR
01917       << "   refinement_flag()=" << Utility::enum_to_string(this->refinement_flag())        << '\n'
01918       << "   p_refinement_flag()=" << Utility::enum_to_string(this->p_refinement_flag())    << '\n'
01919 #endif
01920 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
01921       << "   infinite()=" << this->infinite()    << '\n';
01922   if (this->infinite())
01923     oss << "   origin()=" << this->origin()    << '\n'
01924 #endif
01925       ;
01926 
01927   oss << "   DoFs=";
01928   for (unsigned int s=0; s != this->n_systems(); ++s)
01929     for (unsigned int v=0; v != this->n_vars(s); ++v)
01930       for (unsigned int c=0; c != this->n_comp(s,v); ++c)
01931         oss << '(' << s << '/' << v << '/' << this->dof_number(s,v,c) << ") ";
01932 
01933 
01934   return oss.str();
01935 }
01936 
01937 
01938 
01939 void Elem::nullify_neighbors ()
01940 {
01941   // Tell any of my neighbors about my death...
01942   // Looks strange, huh?
01943   for (unsigned int n=0; n<this->n_neighbors(); n++)
01944     {
01945       Elem* current_neighbor = this->neighbor(n);
01946       if (current_neighbor && current_neighbor != remote_elem)
01947         {
01948           // Note:  it is possible that I see the neighbor
01949           // (which is coarser than me)
01950           // but they don't see me, so avoid that case.
01951           if (current_neighbor->level() == this->level())
01952             {
01953               const unsigned int w_n_a_i = current_neighbor->which_neighbor_am_i(this);
01954               libmesh_assert_less (w_n_a_i, current_neighbor->n_neighbors());
01955               current_neighbor->set_neighbor(w_n_a_i, NULL);
01956               this->set_neighbor(n, NULL);
01957             }
01958         }
01959     }
01960 }
01961 
01962 
01963 
01964 
01965 unsigned int Elem::n_second_order_adjacent_vertices (const unsigned int) const
01966 {
01967   // for linear elements, always return 0
01968   return 0;
01969 }
01970 
01971 
01972 
01973 unsigned short int Elem::second_order_adjacent_vertex (const unsigned int,
01974                                                        const unsigned int) const
01975 {
01976   // for linear elements, always return 0
01977   return 0;
01978 }
01979 
01980 
01981 
01982 std::pair<unsigned short int, unsigned short int>
01983 Elem::second_order_child_vertex (const unsigned int) const
01984 {
01985   // for linear elements, always return 0
01986   return std::pair<unsigned short int, unsigned short int>(0,0);
01987 }
01988 
01989 
01990 
01991 ElemType Elem::first_order_equivalent_type (const ElemType et)
01992 {
01993   switch (et)
01994     {
01995     case EDGE2:
01996     case EDGE3:
01997     case EDGE4:
01998       return EDGE2;
01999     case TRI3:
02000     case TRI6:
02001       return TRI3;
02002     case QUAD4:
02003     case QUAD8:
02004     case QUAD9:
02005       return QUAD4;
02006     case TET4:
02007     case TET10:
02008       return TET4;
02009     case HEX8:
02010     case HEX27:
02011     case HEX20:
02012       return HEX8;
02013     case PRISM6:
02014     case PRISM15:
02015     case PRISM18:
02016       return PRISM6;
02017     case PYRAMID5:
02018     case PYRAMID13:
02019     case PYRAMID14:
02020       return PYRAMID5;
02021 
02022 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
02023 
02024     case INFQUAD4:
02025     case INFQUAD6:
02026       return INFQUAD4;
02027     case INFHEX8:
02028     case INFHEX16:
02029     case INFHEX18:
02030       return INFHEX8;
02031     case INFPRISM6:
02032     case INFPRISM12:
02033       return INFPRISM6;
02034 
02035 #endif
02036 
02037     default:
02038       // unknown element
02039       return INVALID_ELEM;
02040     }
02041 }
02042 
02043 
02044 
02045 ElemType Elem::second_order_equivalent_type (const ElemType et,
02046                                              const bool full_ordered)
02047 {
02048   /* for second-order elements, always return \p INVALID_ELEM
02049    * since second-order elements should not be converted
02050    * into something else.  Only linear elements should
02051    * return something sensible here
02052    */
02053   switch (et)
02054     {
02055     case EDGE2:
02056       {
02057         // full_ordered not relevant
02058         return EDGE3;
02059       }
02060 
02061     case TRI3:
02062       {
02063         // full_ordered not relevant
02064         return TRI6;
02065       }
02066 
02067     case QUAD4:
02068       {
02069         if (full_ordered)
02070           return QUAD9;
02071         else
02072           return QUAD8;
02073       }
02074 
02075     case TET4:
02076       {
02077         // full_ordered not relevant
02078         return TET10;
02079       }
02080 
02081     case HEX8:
02082       {
02083         // see below how this correlates with INFHEX8
02084         if (full_ordered)
02085           return HEX27;
02086         else
02087           return HEX20;
02088       }
02089 
02090     case PRISM6:
02091       {
02092         if (full_ordered)
02093           return PRISM18;
02094         else
02095           return PRISM15;
02096       }
02097 
02098     case PYRAMID5:
02099       {
02100         if (full_ordered)
02101           return PYRAMID14;
02102         else
02103           return PYRAMID13;
02104 
02105         return INVALID_ELEM;
02106       }
02107 
02108 
02109 
02110 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
02111 
02112       // infinite elements
02113     case INFEDGE2:
02114       {
02115         return INVALID_ELEM;
02116       }
02117 
02118     case INFQUAD4:
02119       {
02120         // full_ordered not relevant
02121         return INFQUAD6;
02122       }
02123 
02124     case INFHEX8:
02125       {
02126         /*
02127          * Note that this matches with \p Hex8:
02128          * For full-ordered, \p InfHex18 and \p Hex27
02129          * belong together, and for not full-ordered,
02130          * \p InfHex16 and \p Hex20 belong together.
02131          */
02132         if (full_ordered)
02133           return INFHEX18;
02134         else
02135           return INFHEX16;
02136       }
02137 
02138     case INFPRISM6:
02139       {
02140         // full_ordered not relevant
02141         return INFPRISM12;
02142       }
02143 
02144 #endif
02145 
02146 
02147     default:
02148       {
02149         // second-order element
02150         return INVALID_ELEM;
02151       }
02152     }
02153 }
02154 
02155 
02156 
02157 Elem::side_iterator Elem::boundary_sides_begin()
02158 {
02159   Predicates::BoundarySide<SideIter> bsp;
02160   return side_iterator(this->_first_side(), this->_last_side(), bsp);
02161 }
02162 
02163 
02164 
02165 
02166 Elem::side_iterator Elem::boundary_sides_end()
02167 {
02168   Predicates::BoundarySide<SideIter> bsp;
02169   return side_iterator(this->_last_side(), this->_last_side(), bsp);
02170 }
02171 
02172 
02173 
02174 
02175 Real Elem::volume () const
02176 {
02177   // The default implementation builds a finite element of the correct
02178   // order and sums up the JxW contributions.  This can be expensive,
02179   // so the various element types can overload this method and compute
02180   // the volume more efficiently.
02181   FEType fe_type (this->default_order() , LAGRANGE);
02182 
02183   UniquePtr<FEBase> fe (FEBase::build(this->dim(),
02184                                       fe_type));
02185 
02186   const std::vector<Real>& JxW = fe->get_JxW();
02187 
02188   // The default quadrature rule should integrate the mass matrix,
02189   // thus it should be plenty to compute the area
02190   QGauss qrule (this->dim(), fe_type.default_quadrature_order());
02191 
02192   fe->attach_quadrature_rule(&qrule);
02193 
02194   fe->reinit(this);
02195 
02196   Real vol=0.;
02197   for (unsigned int qp=0; qp<qrule.n_points(); ++qp)
02198     vol += JxW[qp];
02199 
02200   return vol;
02201 
02202 }
02203 
02204 
02205 
02206 unsigned int Elem::opposite_side(const unsigned int /*s*/) const
02207 {
02208   // If the subclass didn't rederive this, using it is an error
02209   libmesh_not_implemented();
02210 }
02211 
02212 
02213 
02214 unsigned int Elem::opposite_node(const unsigned int /*n*/,
02215                                  const unsigned int /*s*/) const
02216 {
02217   // If the subclass didn't rederive this, using it is an error
02218   libmesh_not_implemented();
02219 }
02220 
02221 } // namespace libMesh