18 #include "libmesh/libmesh_config.h" 
   20 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 
   25 #include "libmesh/inf_elem_builder.h" 
   26 #include "libmesh/libmesh_logging.h" 
   27 #include "libmesh/mesh_tools.h" 
   28 #include "libmesh/face_inf_quad4.h" 
   29 #include "libmesh/face_inf_quad6.h" 
   30 #include "libmesh/cell_inf_prism6.h" 
   31 #include "libmesh/cell_inf_prism12.h" 
   32 #include "libmesh/cell_inf_hex8.h" 
   33 #include "libmesh/cell_inf_hex16.h" 
   34 #include "libmesh/cell_inf_hex18.h" 
   35 #include "libmesh/mesh_base.h" 
   36 #include "libmesh/remote_elem.h" 
   46   Point origin = (b_box.first + b_box.second) / 2;
 
   51       libMesh::out << 
" Determined origin for Infinite Elements:" 
   88                                             const bool be_verbose,
 
   89                                             std::vector<const Node *> * inner_boundary_nodes)
 
   91   START_LOG(
"build_inf_elem()", 
"InfElemBuilder");
 
   98   Point origin(origin_x.second, origin_y.second, origin_z.second);
 
  102   if ( !origin_x.first || !origin_y.first || !origin_z.first)
 
  106       const Point auto_origin = (b_box.first+b_box.second)/2;
 
  110         origin(0) = auto_origin(0);
 
  113         origin(1) = auto_origin(1);
 
  117         origin(2) = auto_origin(2);
 
  122           libMesh::out << 
" Origin for Infinite Elements:" << std::endl;
 
  125             libMesh::out << 
"  determined x-coordinate" << std::endl;
 
  127             libMesh::out << 
"  determined y-coordinate" << std::endl;
 
  129             libMesh::out << 
"  determined z-coordinate" << std::endl;
 
  140       libMesh::out << 
" Origin for Infinite Elements:" << std::endl;
 
  152   if (inner_boundary_nodes != 
nullptr)
 
  170                          unsigned int>> inner_faces;
 
  183                        << 
" convert the <int,int> list to a Node * list..." 
  199       std::vector<dof_id_type> inner_boundary_node_numbers;
 
  200       inner_boundary_node_numbers.reserve(4*inner_faces.size());
 
  204       for (
const auto & p : inner_faces)
 
  210           for (
const Node & node : side->node_ref_range())
 
  211             inner_boundary_node_numbers.push_back(node.id());
 
  222       const std::size_t ibn_size_before = inner_boundary_node_numbers.size();
 
  224       std::sort (inner_boundary_node_numbers.begin(), inner_boundary_node_numbers.end());
 
  226         std::unique (inner_boundary_node_numbers.begin(), inner_boundary_node_numbers.end());
 
  228       std::size_t unique_size = 
std::distance(inner_boundary_node_numbers.begin(), unique_end);
 
  229       libmesh_assert_less_equal (unique_size, ibn_size_before);
 
  235       inner_boundary_nodes->reserve (unique_size);
 
  236       inner_boundary_nodes->clear();
 
  238       for (
const auto & dof : 
as_range(inner_boundary_node_numbers.begin(), unique_end))
 
  241           inner_boundary_nodes->push_back(node);
 
  246                      << 
" target nodes." << std::endl;
 
  257   STOP_LOG(
"build_inf_elem()", 
"InfElemBuilder");
 
  280                                     const bool be_verbose,
 
  282                                     unsigned int>> * inner_faces)
 
  287       libMesh::out << 
" Building Infinite Elements:" << std::endl;
 
  288       libMesh::out << 
"  updating element neighbor tables..." << std::endl;
 
  290       libMesh::out << 
" Verbose mode disabled in non-debug mode." << std::endl;
 
  298   LOG_SCOPE(
"build_inf_elem()", 
"InfElemBuilder");
 
  302   std::set<std::pair<dof_id_type,unsigned int>> faces;
 
  303   std::set<std::pair<dof_id_type,unsigned int>> ofaces;
 
  306   std::set<dof_id_type> onodes;
 
  318       if (x_sym || y_sym || z_sym)
 
  319         libMesh::out << 
", skipping sides in symmetry planes..." << std::endl;
 
  329     for (
auto s : elem->side_index_range())
 
  330       if (elem->neighbor_ptr(s) == 
nullptr)
 
  334           std::unique_ptr<Elem> side(elem->build_side_ptr(s));
 
  345           for (
const Node & node : side->node_ref_range())
 
  348               const Point dist_from_origin =
 
  352                 if (
std::abs(dist_from_origin(0)) > 1.e-3)
 
  356                 if (
std::abs(dist_from_origin(1)) > 1.e-3)
 
  360                 if (
std::abs(dist_from_origin(2)) > 1.e-3)
 
  386           sym_side = (x_sym && on_x_sym) || (y_sym && on_y_sym) || (z_sym && on_z_sym);
 
  389             faces.insert( std::make_pair(elem->id(), s) );
 
  409     onodes.insert(max_r_node);
 
  413     auto face_it = faces.begin();
 
  414     auto face_end = faces.end();
 
  415     unsigned int facesfound=0;
 
  416     while (face_it != face_end) {
 
  417       std::pair<dof_id_type, unsigned int> p = *face_it;
 
  424       for (
const Node & node : side->node_ref_range())
 
  425         if (onodes.count(node.id()))
 
  434           for (
const Node & node : side->node_ref_range())
 
  435             onodes.insert(node.id());
 
  438           face_it = faces.erase(face_it); 
 
  448       if (facesfound>0 && face_it == faces.end())
 
  451           face_it    = faces.begin();
 
  463                  << 
" outer boundary faces" 
  470   if (inner_faces != 
nullptr)
 
  471     *inner_faces = faces;
 
  479   std::map<dof_id_type, Node *> outer_nodes;
 
  486 #ifdef LIBMESH_ENABLE_UNIQUE_ID 
  492   for (
const auto & dof : onodes)
 
  508 #ifdef LIBMESH_ENABLE_UNIQUE_ID 
  511           outer_nodes[dof] = new_node;
 
  523   for (
auto & p : ofaces)
 
  532       bool is_higher_order_elem = 
false;
 
  545           is_higher_order_elem = 
true;
 
  555           is_higher_order_elem = 
true;
 
  564           el->
set_node(16) = side->node_ptr(8);
 
  565           el->
set_node(17) = outer_nodes[side->node_id(8)];
 
  566           is_higher_order_elem=
true;
 
  576           el->
set_node(4) = side->node_ptr(2);
 
  581           libMesh::out << 
"InfElemBuilder::build_inf_elem(Point, bool, bool, bool, bool): " 
  582                        << 
"invalid face element " 
  587       const unsigned int n_base_vertices = side->n_vertices();
 
  596           libmesh_assert_less_equal(el->
n_sides(), 6);
 
  597           el->
set_id (belem.
id() * 6 + p.second + old_max_elem_id);
 
  599 #ifdef LIBMESH_ENABLE_UNIQUE_ID 
  600           el->
set_unique_id() = old_max_unique_id + old_max_node_id + belem.
id();
 
  620                       unsigned int n_shared_vertices = 0;
 
  621                       for (
unsigned int i = 0; i != n_base_vertices; ++i)
 
  622                         for (
auto & node : remote_side->node_ref_range())
 
  623                           if (side->node_ptr(i) == &node &&
 
  627                       if (n_shared_vertices + 1 >= belem.
dim())
 
  638       for (
unsigned int i=0; i<n_base_vertices; i++)
 
  640           el->
set_node(i                ) = side->node_ptr(i);
 
  641           el->
set_node(i+n_base_vertices) = outer_nodes[side->node_id(i)];
 
  647       if (is_higher_order_elem)
 
  653           const unsigned int n_safe_base_nodes   = el->
n_vertices();
 
  655           for (
unsigned int i=n_base_vertices; i<n_safe_base_nodes; i++)
 
  657               el->
set_node(i+n_base_vertices)   = side->node_ptr(i);
 
  659                 outer_nodes[side->node_id(i)];
 
  675                  << 
" infinite elements and " 
  677                  << 
" nodes to the mesh" 
  689 #endif // LIBMESH_ENABLE_INFINITE_ELEMENTS