libMesh::InfElemBuilder Class Reference
#include <inf_elem_builder.h>
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.
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] |
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
InfElemOriginValuethe 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
MeshBase& libMesh::InfElemBuilder::_mesh [private] |
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: