20 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 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);
112 origin(1) = auto_origin(1);
114 origin(2) = auto_origin(2);
118 libMesh::out <<
" Origin for Infinite Elements:" << std::endl;
121 libMesh::out <<
" determined x-coordinate" << std::endl;
123 libMesh::out <<
" determined y-coordinate" << std::endl;
125 libMesh::out <<
" determined z-coordinate" << std::endl;
136 libMesh::out <<
" Origin for Infinite Elements:" << std::endl;
148 if (inner_boundary_nodes !=
nullptr)
166 unsigned int>> inner_faces;
179 <<
" convert the <int,int> list to a Node * list..." 195 std::vector<dof_id_type> inner_boundary_node_numbers;
196 inner_boundary_node_numbers.reserve(4*inner_faces.size());
200 std::set<std::pair<dof_id_type,unsigned int>>::iterator face_it = inner_faces.begin();
201 const std::set<std::pair<dof_id_type,unsigned int>>::iterator face_end = inner_faces.end();
202 for (; face_it!=face_end; ++face_it)
204 std::pair<dof_id_type,unsigned int> p = *face_it;
210 for (
unsigned int n=0; n<
side->n_nodes(); n++)
211 inner_boundary_node_numbers.push_back(
side->node_id(n));
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());
225 std::vector<dof_id_type>::iterator unique_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();
239 std::vector<dof_id_type>::iterator pos_it = inner_boundary_node_numbers.begin();
240 for (; pos_it != unique_end; ++pos_it)
243 inner_boundary_nodes->push_back(node);
248 <<
" target nodes." << std::endl;
259 STOP_LOG(
"build_inf_elem()",
"InfElemBuilder");
282 const bool be_verbose,
284 unsigned int>> * inner_faces)
289 libMesh::out <<
" Building Infinite Elements:" << std::endl;
290 libMesh::out <<
" updating element neighbor tables..." << std::endl;
292 libMesh::out <<
" Verbose mode disabled in non-debug mode." << std::endl;
300 LOG_SCOPE(
"build_inf_elem()",
"InfElemBuilder");
304 std::set<std::pair<dof_id_type,unsigned int>> faces;
305 std::set<std::pair<dof_id_type,unsigned int>> ofaces;
308 std::set<dof_id_type> onodes;
320 if (x_sym || y_sym || z_sym)
321 libMesh::out <<
", skipping sides in symmetry planes..." << std::endl;
331 for (
auto s : elem->side_index_range())
332 if (elem->neighbor_ptr(s) ==
nullptr)
336 std::unique_ptr<Elem>
side(elem->build_side_ptr(s));
347 for (
unsigned int n=0; n<
side->n_nodes(); n++)
349 const Point dist_from_origin =
353 if (
std::abs(dist_from_origin(0)) > 1.e-3)
357 if (
std::abs(dist_from_origin(1)) > 1.e-3)
361 if (
std::abs(dist_from_origin(2)) > 1.e-3)
382 max_r_node=
side->node_id(n);
387 sym_side = (x_sym && on_x_sym) || (y_sym && on_y_sym) || (z_sym && on_z_sym);
390 faces.insert( std::make_pair(elem->id(), s) );
410 onodes.insert(max_r_node);
414 auto face_it = faces.begin();
415 auto face_end = faces.end();
416 unsigned int facesfound=0;
417 while (face_it != face_end) {
418 std::pair<dof_id_type, unsigned int> p = *face_it;
425 for (
unsigned int sn=0; sn<
side->n_nodes(); sn++)
426 if (onodes.count(
side->node_id(sn)))
435 for (
unsigned int sn=0; sn<
side->n_nodes(); sn++)
436 onodes.insert(
side->node_id(sn));
439 face_it = faces.erase(face_it);
449 if (facesfound>0 && face_it == faces.end())
452 face_it = faces.begin();
464 <<
" outer boundary faces" 471 if (inner_faces !=
nullptr)
472 *inner_faces = faces;
480 std::map<dof_id_type, Node *> outer_nodes;
487 #ifdef LIBMESH_ENABLE_UNIQUE_ID 493 std::set<dof_id_type>::iterator on_it = onodes.begin();
494 for ( ; on_it != onodes.end(); ++on_it)
510 #ifdef LIBMESH_ENABLE_UNIQUE_ID 513 outer_nodes[*on_it] = new_node;
525 for (
auto & p : ofaces)
534 bool is_higher_order_elem =
false;
547 is_higher_order_elem =
true;
557 is_higher_order_elem =
true;
568 is_higher_order_elem=
true;
583 libMesh::out <<
"InfElemBuilder::build_inf_elem(Point, bool, bool, bool, bool): " 584 <<
"invalid face element " 589 const unsigned int n_base_vertices =
side->n_vertices();
598 libmesh_assert_less_equal(el->
n_sides(), 6);
599 el->
set_id (belem.
id() * 6 + p.second + old_max_elem_id);
601 #ifdef LIBMESH_ENABLE_UNIQUE_ID 602 el->
set_unique_id() = old_max_unique_id + old_max_node_id + belem.
id();
622 unsigned int n_shared_vertices = 0;
623 for (
unsigned int i = 0; i != n_base_vertices; ++i)
624 for (
auto & node : remote_side->node_ref_range())
625 if (
side->node_ptr(i) == &node &&
629 if (n_shared_vertices + 1 >= belem.
dim())
640 for (
unsigned int i=0; i<n_base_vertices; i++)
643 el->
set_node(i+n_base_vertices) = outer_nodes[
side->node_id(i)];
649 if (is_higher_order_elem)
655 const unsigned int n_safe_base_nodes = el->
n_vertices();
657 for (
unsigned int i=n_base_vertices; i<n_safe_base_nodes; i++)
661 outer_nodes[
side->node_id(i)];
677 <<
" infinite elements and " 679 <<
" nodes to the mesh" 691 #endif // LIBMESH_ENABLE_INFINITE_ELEMENTS
unique_id_type & set_unique_id()
A 3D infinite hexahedral element with 8 nodes.
virtual Node *& set_node(const unsigned int i)
A geometric point in (x,y,z) space associated with a DOF.
virtual unique_id_type parallel_max_unique_id() const =0
IntRange< unsigned short > side_index_range() const
A 2D infinite quadrilateral element with 4 nodes.
The base class for all geometric element types.
virtual bool is_node_on_side(const unsigned int n, const unsigned int s) const =0
virtual SimpleRange< element_iterator > active_element_ptr_range()=0
virtual Node * add_point(const Point &p, const dof_id_type id=DofObject::invalid_id, const processor_id_type proc_id=DofObject::invalid_processor_id)=0
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i, bool proxy=true)=0
virtual bool is_serial() const
virtual void find_neighbors(const bool reset_remote_elements=false, const bool reset_current_list=true)=0
void write_unformatted(std::ostream &out, const bool newline=true) const
std::pair< bool, double > InfElemOriginValue
A 3D infinite prismatic element with 12 nodes.
A 3D infinite hexahedral element with 16 nodes.
virtual Elem * add_elem(Elem *e)=0
virtual dof_id_type max_elem_id() const =0
void prepare_for_use(const bool skip_renumber_nodes_and_elements=false, const bool skip_find_neighbors=false)
A 2D infinite quadrilateral element with 6 nodes.
void set_neighbor(const unsigned int i, Elem *n)
virtual unsigned int n_sides() const =0
const Elem * neighbor_ptr(unsigned int i) const
virtual unsigned int n_vertices() const =0
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const Point build_inf_elem(const bool be_verbose=false)
virtual unsigned short dim() const =0
virtual const Elem & elem_ref(const dof_id_type i) const
A 3D infinite prismatic element with 6 nodes.
virtual void libmesh_assert_valid_parallel_ids() const
virtual const Node & node_ref(const dof_id_type i) const
virtual const Point & point(const dof_id_type i) const =0
void print_info(std::ostream &os=libMesh::out) const
virtual dof_id_type max_node_id() const =0
virtual dof_id_type n_elem() const =0
virtual const Node * node_ptr(const dof_id_type i) const =0
processor_id_type processor_id() const
OStreamProxy out(std::cout)
processor_id_type processor_id() const
A geometric point in (x,y,z) space.
A 3D infinite hexahedral element with 18 nodes.
const RemoteElem * remote_elem