libMesh::InfElemBuilder Class Reference

#include <inf_elem_builder.h>

List of all members.

Public Types

typedef std::pair< bool, double > InfElemOriginValue

Public Member Functions

 InfElemBuilder (MeshBase &mesh)
const Point build_inf_elem (const bool be_verbose=false)
const Point build_inf_elem (const InfElemOriginValue &origin_x, const InfElemOriginValue &origin_y, const InfElemOriginValue &origin_z, const bool x_sym=false, const bool y_sym=false, const bool z_sym=false, const bool be_verbose=false, std::vector< const Node * > *inner_boundary_nodes=NULL)

Private Member Functions

void build_inf_elem (const Point &origin, const bool x_sym=false, const bool y_sym=false, const bool z_sym=false, const bool be_verbose=false, std::set< std::pair< dof_id_type, unsigned int > > *inner_faces=NULL)

Private Attributes

MeshBase_mesh

Detailed Description

This class is used to build infinite elements on top of an existing mesh. It only makes sense to use this if LIBMESH_ENABLE_INFINITE_ELEMENTS is true.

Author:
original code by Daniel Dreyer, converted to InfElemBuilder class by John W. Peterson, 2004.

Definition at line 52 of file inf_elem_builder.h.


Member Typedef Documentation

typedef std::pair<bool, double> libMesh::InfElemBuilder::InfElemOriginValue

Useful typedef

Definition at line 64 of file inf_elem_builder.h.


Constructor & Destructor Documentation

libMesh::InfElemBuilder::InfElemBuilder ( MeshBase mesh  )  [inline, explicit]

Constructor.

Definition at line 59 of file inf_elem_builder.h.

00059 : _mesh(mesh) {}


Member Function Documentation

void libMesh::InfElemBuilder::build_inf_elem ( const Point origin,
const bool  x_sym = false,
const bool  y_sym = false,
const bool  z_sym = false,
const bool  be_verbose = false,
std::set< std::pair< dof_id_type, unsigned int > > *  inner_faces = NULL 
) [private]

Build infinite elements atop a volume-based mesh. Actual implementation.

Definition at line 281 of file inf_elem_builder.C.

References _mesh, std::abs(), libMesh::MeshBase::active_elements_begin(), libMesh::MeshBase::active_elements_end(), libMesh::MeshBase::add_elem(), libMesh::MeshBase::add_point(), libMesh::Elem::build_side(), libMeshEnums::EDGE2, libMeshEnums::EDGE3, libMesh::MeshBase::elem(), end, libMesh::MeshBase::find_neighbors(), libMesh::DofObject::id(), libMesh::MeshBase::is_serial(), libMesh::MeshBase::libmesh_assert_valid_parallel_ids(), libMesh::MeshBase::max_elem_id(), libMesh::MeshBase::max_node_id(), libMesh::MeshBase::n_elem(), libMesh::Elem::n_neighbors(), libMesh::Elem::n_vertices(), libMesh::Elem::neighbor(), libMesh::MeshBase::node(), libMesh::out, libMesh::MeshBase::point(), libMesh::DofObject::processor_id(), libMeshEnums::QUAD4, libMeshEnums::QUAD8, libMeshEnums::QUAD9, libMesh::Real, libMesh::DofObject::set_id(), libMesh::Elem::set_node(), side, libMesh::TypeVector< T >::size(), libMeshEnums::TRI3, and libMeshEnums::TRI6.

00288 {
00289   if (be_verbose)
00290     {
00291 #ifdef DEBUG
00292       libMesh::out << " Building Infinite Elements:" << std::endl;
00293       libMesh::out << "  updating element neighbor tables..." << std::endl;
00294 #else
00295       libMesh::out << " Verbose mode disabled in non-debug mode." << std::endl;
00296 #endif
00297     }
00298 
00299 
00300   // update element neighbors
00301   this->_mesh.find_neighbors();
00302 
00303   START_LOG("build_inf_elem()", "InfElemBuilder");
00304 
00305   // A set for storing element number, side number pairs.
00306   // pair.first == element number, pair.second == side number
00307   std::set< std::pair<dof_id_type,unsigned int> > faces;
00308   std::set< std::pair<dof_id_type,unsigned int> > ofaces;
00309 
00310   // A set for storing node numbers on the outer faces.
00311   std::set<dof_id_type> onodes;
00312 
00313   // The distance to the farthest point in the mesh from the origin
00314   Real max_r=0.;
00315 
00316   // The index of the farthest point in the mesh from the origin
00317   int max_r_node = -1;
00318 
00319 #ifdef DEBUG
00320   if (be_verbose)
00321     {
00322       libMesh::out << "  collecting boundary sides";
00323       if (x_sym || y_sym || z_sym)
00324         libMesh::out << ", skipping sides in symmetry planes..." << std::endl;
00325       else
00326         libMesh::out << "..." << std::endl;
00327     }
00328 #endif
00329 
00330   // Iterate through all elements and sides, collect indices of all active
00331   // boundary sides in the faces set. Skip sides which lie in symmetry planes.
00332   // Later, sides of the inner boundary will be sorted out.
00333   {
00334     MeshBase::element_iterator       it  = this->_mesh.active_elements_begin();
00335     const MeshBase::element_iterator end = this->_mesh.active_elements_end();
00336 
00337     for(; it != end; ++it)
00338       {
00339         Elem* elem = *it;
00340 
00341         for (unsigned int s=0; s<elem->n_neighbors(); s++)
00342           {
00343             // check if elem(e) is on the boundary
00344             if (elem->neighbor(s) == NULL)
00345               {
00346                 // note that it is safe to use the Elem::side() method,
00347                 // which gives a non-full-ordered element
00348                 AutoPtr<Elem> side(elem->build_side(s));
00349 
00350                 // bool flags for symmetry detection
00351                 bool sym_side=false;
00352                 bool on_x_sym=true;
00353                 bool on_y_sym=true;
00354                 bool on_z_sym=true;
00355 
00356 
00357                 // Loop over the nodes to check whether they are on the symmetry planes,
00358                 // and therefore sufficient to use a non-full-ordered side element
00359                 for(unsigned int n=0; n<side->n_nodes(); n++)
00360                   {
00361                     const Point dist_from_origin = this->_mesh.point(side->node(n)) - origin;
00362 
00363                     if(x_sym)
00364                       if( std::abs(dist_from_origin(0)) > 1.e-3 )
00365                         on_x_sym=false;
00366 
00367                     if(y_sym)
00368                       if( std::abs(dist_from_origin(1)) > 1.e-3 )
00369                         on_y_sym=false;
00370 
00371                     if(z_sym)
00372                       if( std::abs(dist_from_origin(2)) > 1.e-3 )
00373                         on_z_sym=false;
00374 
00375                     //        if(x_sym)
00376                     //          if( std::abs(dist_from_origin(0)) > 1.e-6 )
00377                     //            on_x_sym=false;
00378 
00379                     //        if(y_sym)
00380                     //          if( std::abs(dist_from_origin(1)) > 1.e-6 )
00381                     //            on_y_sym=false;
00382 
00383                     //        if(z_sym)
00384                     //          if( std::abs(dist_from_origin(2)) > 1.e-6 )
00385                     //            on_z_sym=false;
00386 
00387                     //find the node most distant from origin
00388 
00389                     Real r = dist_from_origin.size();
00390                     if (r > max_r)
00391                       {
00392                         max_r = r;
00393                         max_r_node=side->node(n);
00394                       }
00395 
00396                   }
00397 
00398                 sym_side = (x_sym && on_x_sym) || (y_sym && on_y_sym) || (z_sym && on_z_sym);
00399 
00400                 if (!sym_side)
00401                   faces.insert( std::make_pair(elem->id(), s) );
00402 
00403               } // neighbor(s) == NULL
00404           } // sides
00405       } // elems
00406   }
00407 
00408 
00409 
00410 
00411 
00412 
00413   //  If a boundary side has one node on the outer boundary,
00414   //  all points of this side are on the outer boundary.
00415   //  Start with the node most distant from origin, which has
00416   //  to be on the outer boundary, then recursively find all
00417   //  sides and nodes connected to it. Found sides are moved
00418   //  from faces to ofaces, nodes are collected in onodes.
00419   //  Here, the search is done iteratively, because, depending on
00420   //  the mesh, a very high level of recursion might be necessary.
00421   if (max_r_node > 0)
00422     onodes.insert(max_r_node);
00423 
00424 
00425   {
00426     std::set< std::pair<dof_id_type,unsigned int> >::iterator face_it = faces.begin();
00427     unsigned int facesfound=0;
00428     while (face_it != faces.end()) {
00429 
00430       std::pair<dof_id_type, unsigned int> p;
00431       p = *face_it;
00432 
00433       // This has to be a full-ordered side element,
00434       // since we need the correct n_nodes,
00435       AutoPtr<Elem> side(this->_mesh.elem(p.first)->build_side(p.second));
00436 
00437       bool found=false;
00438       for(unsigned int sn=0; sn<side->n_nodes(); sn++)
00439         if(onodes.count(side->node(sn)))
00440           {
00441             found=true;
00442             break;
00443           }
00444 
00445 
00446       // If a new oface is found, include its nodes in onodes
00447       if(found)
00448         {
00449           for(unsigned int sn=0; sn<side->n_nodes(); sn++)
00450             onodes.insert(side->node(sn));
00451 
00452           ofaces.insert(p);
00453           face_it++;                    // iteration is done here
00454           faces.erase(p);
00455 
00456           facesfound++;
00457         }
00458 
00459       else
00460         face_it++;                      // iteration is done here
00461 
00462 
00463       // If at least one new oface was found in this cycle,
00464       // do another search cycle.
00465       if(facesfound>0 && face_it == faces.end())
00466         {
00467           facesfound = 0;
00468           face_it    = faces.begin();
00469         }
00470 
00471     }
00472   }
00473 
00474 
00475 #ifdef DEBUG
00476   if (be_verbose)
00477     libMesh::out << "  found "
00478                   << faces.size()
00479                   << " inner and "
00480                   << ofaces.size()
00481                   << " outer boundary faces"
00482                   << std::endl;
00483 #endif
00484 
00485   // When the user provided a non-null pointer to
00486   // inner_faces, that implies he wants to have
00487   // this std::set.  For now, simply copy the data.
00488   if (inner_faces != NULL)
00489     *inner_faces = faces;
00490 
00491   // free memory, clear our local variable, no need
00492   // for it any more.
00493   faces.clear();
00494 
00495 
00496   // outer_nodes maps onodes to their duplicates
00497   std::map<dof_id_type, Node *> outer_nodes;
00498 
00499   // We may need to pick our own object ids in parallel
00500   dof_id_type old_max_node_id = _mesh.max_node_id();
00501   dof_id_type old_max_elem_id = _mesh.max_elem_id();
00502 
00503   // for each boundary node, add an outer_node with
00504   // double distance from origin.
00505   std::set<dof_id_type>::iterator on_it = onodes.begin();
00506   for( ; on_it != onodes.end(); ++on_it)
00507     {
00508       Point p = (Point(this->_mesh.point(*on_it)) * 2) - origin;
00509       if (_mesh.is_serial())
00510         {
00511           // Add with a default id in serial
00512           outer_nodes[*on_it]=this->_mesh.add_point(p);
00513         }
00514       else
00515         {
00516           // Pick a unique id in parallel
00517           Node &bnode = _mesh.node(*on_it);
00518           dof_id_type new_id = bnode.id() + old_max_node_id;
00519           outer_nodes[*on_it] =
00520             this->_mesh.add_point(p, new_id,
00521                                   bnode.processor_id());
00522         }
00523     }
00524 
00525 
00526 #ifdef DEBUG
00527   // for verbose, remember n_elem
00528   dof_id_type n_conventional_elem = this->_mesh.n_elem();
00529 #endif
00530 
00531 
00532   // build Elems based on boundary side type
00533   std::set< std::pair<dof_id_type,unsigned int> >::iterator face_it = ofaces.begin();
00534   for( ; face_it != ofaces.end(); ++face_it)
00535     {
00536       // Shortcut to the pair being iterated over
00537       std::pair<dof_id_type,unsigned int> p = *face_it;
00538 
00539       // build a full-ordered side element to get the base nodes
00540       AutoPtr<Elem> side(this->_mesh.elem(p.first)->build_side(p.second));
00541 
00542       // create cell depending on side type, assign nodes,
00543       // use braces to force scope.
00544       bool is_higher_order_elem = false;
00545       {
00546         Elem* el;
00547         switch(side->type())
00548         {
00549           // 3D infinite elements
00550           // TRIs
00551           case TRI3:
00552             el=new InfPrism6;
00553             break;
00554 
00555           case TRI6:
00556             el=new InfPrism12;
00557             is_higher_order_elem = true;
00558             break;
00559 
00560           // QUADs
00561           case QUAD4:
00562             el=new InfHex8;
00563             break;
00564 
00565           case QUAD8:
00566             el=new InfHex16;
00567             is_higher_order_elem = true;
00568             break;
00569 
00570           case QUAD9:
00571             el=new InfHex18;
00572 
00573             // the method of assigning nodes (which follows below)
00574             // omits in the case of QUAD9 the bubble node; therefore
00575             // we assign these first by hand here.
00576             el->set_node(16) = side->get_node(8);
00577             el->set_node(17) = outer_nodes[side->node(8)];
00578             is_higher_order_elem=true;
00579             break;
00580 
00581           // 2D infinite elements
00582           case EDGE2:
00583             el=new InfQuad4;
00584             break;
00585 
00586           case EDGE3:
00587             el=new InfQuad6;
00588             el->set_node(4) = side->get_node(2);
00589             break;
00590 
00591           // 1D infinite elements not supported
00592           default:
00593             libMesh::out << "InfElemBuilder::build_inf_elem(Point, bool, bool, bool, bool): "
00594                           << "invalid face element "
00595                           << std::endl;
00596             continue;
00597         }
00598 
00599         // In parallel, assign unique ids to the new element
00600         if (!_mesh.is_serial())
00601           {
00602             Elem *belem = _mesh.elem(p.first);
00603             el->processor_id() = belem->processor_id();
00604             // We'd better not have elements with more than 6 sides
00605             el->set_id (belem->id() * 6 + p.second + old_max_elem_id);
00606           }
00607 
00608         // assign vertices to the new infinite element
00609         const unsigned int n_base_vertices = side->n_vertices();
00610         for(unsigned int i=0; i<n_base_vertices; i++)
00611           {
00612             el->set_node(i                ) = side->get_node(i);
00613             el->set_node(i+n_base_vertices) = outer_nodes[side->node(i)];
00614           }
00615 
00616 
00617         // when this is a higher order element,
00618         // assign also the nodes in between
00619         if (is_higher_order_elem)
00620           {
00621             // n_safe_base_nodes is the number of nodes in \p side
00622             // that may be safely assigned using below for loop.
00623             // Actually, n_safe_base_nodes is _identical_ with el->n_vertices(),
00624             // since for QUAD9, the 9th node was already assigned above
00625             const unsigned int n_safe_base_nodes   = el->n_vertices();
00626 
00627             for(unsigned int i=n_base_vertices; i<n_safe_base_nodes; i++)
00628               {
00629                 el->set_node(i+n_base_vertices)   = side->get_node(i);
00630                 el->set_node(i+n_safe_base_nodes) = outer_nodes[side->node(i)];
00631               }
00632           }
00633 
00634 
00635         // add infinite element to mesh
00636         this->_mesh.add_elem(el);
00637       } // el goes out of scope
00638     } // for
00639 
00640 
00641 #ifdef DEBUG
00642   _mesh.libmesh_assert_valid_parallel_ids();
00643 
00644   if (be_verbose)
00645     libMesh::out << "  added "
00646                   << this->_mesh.n_elem() - n_conventional_elem
00647                   << " infinite elements and "
00648                   << onodes.size()
00649                   << " nodes to the mesh"
00650                   << std::endl
00651                   << std::endl;
00652 #endif
00653 
00654   STOP_LOG("build_inf_elem()", "InfElemBuilder");
00655 }

const Point libMesh::InfElemBuilder::build_inf_elem ( const InfElemOriginValue origin_x,
const InfElemOriginValue origin_y,
const InfElemOriginValue origin_z,
const bool  x_sym = false,
const bool  y_sym = false,
const bool  z_sym = false,
const bool  be_verbose = false,
std::vector< const Node * > *  inner_boundary_nodes = NULL 
)
Returns:
the origin of the infinite elements. Builds infinite elements atop a volume-based mesh. Finds all faces on the outer boundary and build infinite elements on them. Using the InfElemOriginValue the user can prescribe only selected origin coordinates. The remaining coordinates are computed from the center of the bounding box of the mesh.

During the search for faces on which infinite elements are built, interior faces that are not on symmetry planes are found, too. When an (optional) pointer to inner_boundary_nodes is provided, then this vector will be filled with the nodes that lie on the inner boundary.

Faces which lie in at least one symmetry plane are skipped. The three optional booleans x_sym, y_sym, z_sym indicate symmetry planes (through the origin, obviously) perpendicular to the x, y and z direction, respectively. The flag be_verbose enables some diagnostic output.

Definition at line 85 of file inf_elem_builder.C.

References _mesh, libMesh::MeshTools::bounding_box(), build_inf_elem(), libMesh::Elem::build_side(), libMesh::MeshBase::elem(), libMesh::MeshBase::node(), libMesh::out, libMesh::MeshBase::prepare_for_use(), libMesh::MeshBase::print_info(), side, and libMesh::TypeVector< T >::write_unformatted().

00093 {
00094   START_LOG("build_inf_elem()", "InfElemBuilder");
00095 
00096   // first determine the origin of the
00097   // infinite elements.  For this, the
00098   // origin defaults to the given values,
00099   // and may be overridden when the user
00100   // provided values
00101   Point origin(origin_x.second, origin_y.second, origin_z.second);
00102 
00103   // when only _one_ of the origin coordinates is _not_
00104   // given, we have to determine it on our own
00105   if ( !origin_x.first || !origin_y.first || !origin_z.first)
00106     {
00107       // determine origin
00108       const MeshTools::BoundingBox b_box = MeshTools::bounding_box(_mesh);
00109       const Point auto_origin = (b_box.first+b_box.second)/2;
00110 
00111       // override default values, if necessary
00112       if (!origin_x.first)
00113           origin(0) = auto_origin(0);
00114       if (!origin_y.first)
00115           origin(1) = auto_origin(1);
00116       if (!origin_z.first)
00117           origin(2) = auto_origin(2);
00118 
00119       if (be_verbose)
00120         {
00121           libMesh::out << " Origin for Infinite Elements:" << std::endl;
00122 
00123           if (!origin_x.first)
00124               libMesh::out << "  determined x-coordinate" << std::endl;
00125           if (!origin_y.first)
00126               libMesh::out << "  determined y-coordinate" << std::endl;
00127           if (!origin_z.first)
00128               libMesh::out << "  determined z-coordinate" << std::endl;
00129 
00130           libMesh::out << "  coordinates: ";
00131           origin.write_unformatted(libMesh::out);
00132           libMesh::out << std::endl;
00133         }
00134     }
00135 
00136   else if (be_verbose)
00137 
00138     {
00139       libMesh::out << " Origin for Infinite Elements:" << std::endl;
00140       libMesh::out << "  coordinates: ";
00141       origin.write_unformatted(libMesh::out);
00142       libMesh::out << std::endl;
00143     }
00144 
00145 
00146 
00147   // Now that we have the origin, check if the user provided an \p
00148   // inner_boundary_nodes.  If so, we pass a std::set to the actual
00149   // implementation of the build_inf_elem(), so that we can convert
00150   // this to the Node* vector
00151   if (inner_boundary_nodes != NULL)
00152     {
00153       // note that the std::set that we will get
00154       // from build_inf_elem() uses the index of
00155       // the element in this->_elements vector,
00156       // and the second entry is the side index
00157       // for this element.  Therefore, we do _not_
00158       // need to renumber nodes and elements
00159       // prior to building the infinite elements.
00160       //
00161       // However, note that this method here uses
00162       // node id's... Do we need to renumber?
00163 
00164 
00165       // Form the list of faces of elements which finally
00166       // will tell us which nodes should receive boundary
00167       // conditions (to form the std::vector<const Node*>)
00168       std::set< std::pair<dof_id_type,
00169                           unsigned int> > inner_faces;
00170 
00171 
00172       // build infinite elements
00173       this->build_inf_elem(origin,
00174                            x_sym, y_sym, z_sym,
00175                            be_verbose,
00176                            &inner_faces);
00177 
00178       if (be_verbose)
00179         {
00180           this->_mesh.print_info();
00181           libMesh::out << "Data pre-processing:" << std::endl
00182                         << " convert the <int,int> list to a Node* list..."
00183                         << std::endl;
00184         }
00185 
00186       // First use a std::vector<dof_id_type> that holds
00187       // the global node numbers.  Then sort this vector,
00188       // so that it can be made unique (no multiple occurence
00189       // of a node), and then finally insert the Node* in
00190       // the vector inner_boundary_nodes.
00191       //
00192       // Reserve memory for the vector<> with
00193       // 4 times the size of the number of elements in the
00194       // std::set. This is a good bet for Quad4 face elements.
00195       // For higher-order elements, this probably _has_ to lead
00196       // to additional allocations...
00197       // Practice has to show how this affects performance.
00198       std::vector<dof_id_type> inner_boundary_node_numbers;
00199       inner_boundary_node_numbers.reserve(4*inner_faces.size());
00200 
00201       // Now transform the set of pairs to a list of (possibly
00202       // duplicate) global node numbers.
00203       std::set< std::pair<dof_id_type,unsigned int> >::iterator face_it = inner_faces.begin();
00204       const std::set< std::pair<dof_id_type,unsigned int> >::iterator face_end = inner_faces.end();
00205       for(; face_it!=face_end; ++face_it)
00206         {
00207           std::pair<dof_id_type,unsigned int> p = *face_it;
00208 
00209           // build a full-ordered side element to get _all_ the base nodes
00210           AutoPtr<Elem> side( this->_mesh.elem(p.first)->build_side(p.second) );
00211 
00212           // insert all the node numbers in inner_boundary_node_numbers
00213           for (unsigned int n=0; n< side->n_nodes(); n++)
00214               inner_boundary_node_numbers.push_back(side->node(n));
00215         }
00216 
00217 
00218       // inner_boundary_node_numbers now still holds multiple entries of
00219       // node numbers.  So first sort, then unique the vector.
00220       // Note that \p std::unique only puts the new ones in
00221       // front, while to leftovers are @e not deleted.  Instead,
00222       // it returns a pointer to the end of the unique range.
00223       //TODO:[BSK] int_ibn_size_before is not the same type as unique_size!
00224 #ifndef NDEBUG
00225       const std::size_t ibn_size_before = inner_boundary_node_numbers.size();
00226 #endif
00227       std::sort (inner_boundary_node_numbers.begin(), inner_boundary_node_numbers.end());
00228       std::vector<dof_id_type>::iterator unique_end =
00229           std::unique (inner_boundary_node_numbers.begin(), inner_boundary_node_numbers.end());
00230 
00231       std::size_t unique_size = std::distance(inner_boundary_node_numbers.begin(), unique_end);
00232       libmesh_assert_less_equal (unique_size, ibn_size_before);
00233 
00234       // Finally, create const Node* in the inner_boundary_nodes
00235       // vector.  Reserve, not resize (otherwise, the push_back
00236       // would append the interesting nodes, while NULL-nodes
00237       // live in the resize'd area...
00238       inner_boundary_nodes->reserve (unique_size);
00239       inner_boundary_nodes->clear();
00240 
00241 
00242       std::vector<dof_id_type>::iterator pos_it = inner_boundary_node_numbers.begin();
00243       for (; pos_it != unique_end; ++pos_it)
00244         {
00245           const Node& node = this->_mesh.node(*pos_it);
00246           inner_boundary_nodes->push_back(&node);
00247         }
00248 
00249       if (be_verbose)
00250           libMesh::out << "  finished identifying " << unique_size
00251                         << " target nodes." << std::endl;
00252     }
00253 
00254   else
00255 
00256     {
00257       // There are no inner boundary nodes, so simply build the infinite elements
00258       this->build_inf_elem(origin, x_sym, y_sym, z_sym, be_verbose);
00259     }
00260 
00261 
00262   STOP_LOG("build_inf_elem()", "InfElemBuilder");
00263 
00264   // when finished with building the Ifems,
00265   // it remains to prepare the mesh for use:
00266   // find neighbors again, partition (if needed)...
00267   this->_mesh.prepare_for_use (/*skip_renumber =*/ false);
00268 
00269   return origin;
00270 }

const Point libMesh::InfElemBuilder::build_inf_elem ( const bool  be_verbose = false  ) 

Build infinite elements atop a volume-based mesh, determine origin automatically. Also returns the origin as a const Point to make it more obvious that the origin should not change after the infinite elements have been built. When symmetry planes are present, use the version with optional symmetry switches. The flag be_verbose enables some diagnostic output.

Definition at line 44 of file inf_elem_builder.C.

References _mesh, libMesh::MeshTools::bounding_box(), libMesh::out, libMesh::MeshBase::prepare_for_use(), libMesh::processor_id(), and libMesh::TypeVector< T >::write_unformatted().

Referenced by build_inf_elem().

00045 {
00046   // determine origin automatically,
00047   // works only if the mesh has no symmetry planes.
00048   const MeshTools::BoundingBox b_box = MeshTools::bounding_box(_mesh);
00049   Point origin = (b_box.first + b_box.second) / 2;
00050 
00051   if (be_verbose && libMesh::processor_id() == 0)
00052     {
00053 #ifdef DEBUG
00054       libMesh::out << " Determined origin for Infinite Elements:"
00055                     << std::endl
00056                     << "  ";
00057       origin.write_unformatted(libMesh::out);
00058       libMesh::out << std::endl;
00059 #endif
00060     }
00061 
00062   // Call the protected implementation function with the
00063   // automatically determined origin.
00064   this->build_inf_elem(origin, false, false, false, be_verbose);
00065 
00066   // when finished with building the Ifems,
00067   // it remains to prepare the mesh for use:
00068   // find neighbors (again), partition (if needed)...
00069   this->_mesh.prepare_for_use (/*skip_renumber =*/ false);
00070 
00071   return origin;
00072 }


Member Data Documentation

Reference to the mesh we're building infinite elements for.

Definition at line 126 of file inf_elem_builder.h.

Referenced by build_inf_elem().


The documentation for this class was generated from the following files:

Site Created By: libMesh Developers
Last modified: February 05 2013 19:55:27 UTC

Hosted By:
SourceForge.net Logo