20 #include "libmesh/libmesh_config.h"
21 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
22 #include "libmesh/inf_fe.h"
23 #include "libmesh/inf_fe_macro.h"
24 #include "libmesh/fe.h"
25 #include "libmesh/fe_interface.h"
26 #include "libmesh/fe_compute_data.h"
27 #include "libmesh/elem.h"
35 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
40 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
44 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
47 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
57 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
75 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
82 unsigned int n_base, n_radial;
83 compute_node_indices(inf_elem_type, n, n_base, n_radial);
104 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
122 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
125 const std::vector<Number> & ,
126 std::vector<Number> & nodal_soln)
129 if (!_warned_for_nodal_soln)
131 libMesh::err <<
"WARNING: nodal_soln(...) does _not_ work for infinite elements." << std::endl
132 <<
" Will return an empty nodal solution. Use " << std::endl
133 <<
" InfFE<Dim,T_radial,T_map>::compute_data(..) instead!" << std::endl;
134 _warned_for_nodal_soln =
true;
157 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
160 const unsigned int i,
163 libmesh_assert_not_equal_to (Dim, 0);
169 libMesh::err <<
"WARNING: InfFE<Dim,T_radial,T_map>::shape(...) does _not_" << std::endl
170 <<
" return the correct trial function! Use " << std::endl
171 <<
" InfFE<Dim,T_radial,T_map>::compute_data(..) instead!"
173 _warned_for_shape =
true;
179 const Real v (p(Dim-1));
181 unsigned int i_base, i_radial;
182 compute_shape_indices(fet, inf_elem_type, i, i_base, i_radial);
201 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
203 const Elem * inf_elem,
204 const unsigned int i,
208 libmesh_assert_not_equal_to (Dim, 0);
214 libMesh::err <<
"WARNING: InfFE<Dim,T_radial,T_map>::shape(...) does _not_" << std::endl
215 <<
" return the correct trial function! Use " << std::endl
216 <<
" InfFE<Dim,T_radial,T_map>::compute_data(..) instead!"
218 _warned_for_shape =
true;
223 const Real v (p(Dim-1));
224 std::unique_ptr<const Elem> base_el (inf_elem->
build_side_ptr(0));
226 unsigned int i_base, i_radial;
227 compute_shape_indices(fet, inf_elem->
type(), i, i_base, i_radial);
239 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
242 const unsigned int i,
243 const unsigned int j,
246 libmesh_assert_not_equal_to (Dim, 0);
247 libmesh_assert_greater (Dim,j);
252 libMesh::err <<
"WARNING: InfFE<Dim,T_radial,T_map>::shape_deriv(...) does _not_" << std::endl
253 <<
" return the correct trial function gradients! Use " << std::endl
254 <<
" InfFE<Dim,T_radial,T_map>::compute_data(..) instead!"
256 _warned_for_dshape =
true;
262 const Real v (p(Dim-1));
264 unsigned int i_base, i_radial;
265 compute_shape_indices(fe_t, inf_elem_type, i, i_base, i_radial);
283 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
285 const Elem * inf_elem,
286 const unsigned int i,
287 const unsigned int j,
290 libmesh_assert_not_equal_to (Dim, 0);
291 libmesh_assert_greater (Dim,j);
296 libMesh::err <<
"WARNING: InfFE<Dim,T_radial,T_map>::shape_deriv(...) does _not_" << std::endl
297 <<
" return the correct trial function gradients! Use " << std::endl
298 <<
" InfFE<Dim,T_radial,T_map>::compute_data(..) instead!"
300 _warned_for_dshape =
true;
304 const Real v (p(Dim-1));
306 std::unique_ptr<const Elem> base_el (inf_elem->
build_side_ptr(0));
308 unsigned int i_base, i_radial;
310 if ((-1. > v ) || (v > 1.))
316 compute_shape_indices(fe_t, inf_elem->
type(), i, i_base, i_radial);
336 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
338 const Elem * inf_elem,
342 libmesh_assert_not_equal_to (Dim, 0);
347 const Real v (p(Dim-1));
348 std::unique_ptr<const Elem> base_el (inf_elem->
build_side_ptr(0));
356 Real interpolated_dist = 0.;
368 const unsigned int n_base_nodes = base_el->n_nodes();
371 const Order base_mapping_order (base_el->default_order());
372 const ElemType base_mapping_elem_type (base_el->type());
375 for (
unsigned int n=0; n<n_base_nodes; n++)
376 interpolated_dist +=
Point(base_el->point(n) - origin).
norm()
383 const unsigned int n_base_nodes = base_el->n_nodes();
386 const Order base_mapping_order (base_el->default_order());
387 const ElemType base_mapping_elem_type (base_el->type());
390 for (
unsigned int n=0; n<n_base_nodes; n++)
391 interpolated_dist +=
Point(base_el->point(n) - origin).
norm()
397 libmesh_error_msg(
"Unknown Dim = " << Dim);
405 data.phase = interpolated_dist
410 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
421 const Number time_harmonic = exp(exponent);
423 const Number time_harmonic = 1;
424 #endif //LIBMESH_USE_COMPLEX_NUMBERS
431 const unsigned int n_dof = n_dofs (fet, inf_elem->
type());
432 data.shape.resize(n_dof);
433 if (
data.need_derivative())
435 data.dshape.resize(n_dof);
436 data.local_transform.resize(Dim);
438 for (
unsigned int d=0; d<Dim; d++)
439 data.local_transform[d].resize(Dim);
445 std::vector<Point> pt(1);
448 fe->reinit(inf_elem, &pt);
451 data.local_transform[0][0] = fe->get_dxidx()[0];
452 data.local_transform[1][0] = fe->get_detadx()[0];
453 data.local_transform[1][1] = fe->get_detady()[0];
454 data.local_transform[0][1] = fe->get_dxidy()[0];
457 data.local_transform[2][0] = fe->get_dzetadx()[0];
458 data.local_transform[2][1] = fe->get_dzetady()[0];
459 data.local_transform[2][2] = fe->get_dzetadz()[0];
460 data.local_transform[1][2] = fe->get_detadz()[0];
461 data.local_transform[0][2] = fe->get_dxidz()[0];
465 for (
unsigned int i=0; i<n_dof; i++)
468 unsigned int i_base, i_radial;
469 compute_shape_indices(fet, inf_elem->
type(), i, i_base, i_radial);
477 if (
data.need_derivative())
496 #ifdef LIBMESH_USE_COMPLEX_NUMBERS
506 libmesh_not_implemented();
514 libmesh_error_msg(
"compute_data() for 1-dimensional InfFE not implemented.");
522 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
524 const unsigned int outer_node_index,
525 unsigned int & base_node,
526 unsigned int & radial_node)
528 switch (inf_elem_type)
532 libmesh_assert_less (outer_node_index, 2);
534 radial_node = outer_node_index;
542 libmesh_assert_less (outer_node_index, 4);
543 base_node = outer_node_index % 2;
544 radial_node = outer_node_index / 2;
550 libmesh_assert_less (outer_node_index, 6);
551 base_node = outer_node_index % 3;
552 radial_node = outer_node_index / 3;
558 libmesh_assert_less (outer_node_index, 8);
559 base_node = outer_node_index % 4;
560 radial_node = outer_node_index / 4;
568 switch (outer_node_index)
574 base_node = outer_node_index;
582 base_node = outer_node_index-2;
601 libmesh_error_msg(
"Unrecognized outer_node_index = " << outer_node_index);
609 switch (outer_node_index)
617 base_node = outer_node_index;
627 base_node = outer_node_index-4;
637 base_node = outer_node_index-4;
647 base_node = outer_node_index-8;
653 libmesh_assert_equal_to (inf_elem_type,
INFHEX18);
661 libmesh_assert_equal_to (inf_elem_type,
INFHEX18);
668 libmesh_error_msg(
"Unrecognized outer_node_index = " << outer_node_index);
675 switch (outer_node_index)
682 base_node = outer_node_index;
691 base_node = outer_node_index-3;
700 base_node = outer_node_index-3;
709 base_node = outer_node_index-6;
714 libmesh_error_msg(
"Unrecognized outer_node_index = " << outer_node_index);
720 libmesh_error_msg(
"ERROR: Bad infinite element type=" << inf_elem_type <<
", node=" << outer_node_index);
729 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
731 const unsigned int outer_node_index,
732 unsigned int & base_node,
733 unsigned int & radial_node)
735 libmesh_assert_not_equal_to (inf_elem_type,
INVALID_ELEM);
737 static std::vector<unsigned int> _static_base_node_index;
738 static std::vector<unsigned int> _static_radial_node_index;
757 if (inf_elem_type==_compute_node_indices_fast_current_elem_type)
759 base_node = _static_base_node_index [outer_node_index];
760 radial_node = _static_radial_node_index[outer_node_index];
766 _compute_node_indices_fast_current_elem_type = inf_elem_type;
770 switch (inf_elem_type)
813 libmesh_error_msg(
"ERROR: Bad infinite element type=" << inf_elem_type <<
", node=" << outer_node_index);
817 _static_base_node_index.resize (
n_nodes);
818 _static_radial_node_index.resize(
n_nodes);
820 for (
unsigned int n=0; n<
n_nodes; n++)
821 compute_node_indices (inf_elem_type,
823 _static_base_node_index [outer_node_index],
824 _static_radial_node_index[outer_node_index]);
827 base_node = _static_base_node_index [outer_node_index];
828 radial_node = _static_radial_node_index[outer_node_index];
838 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_map>
841 const unsigned int i,
842 unsigned int & base_shape,
843 unsigned int & radial_shape)
872 const unsigned int radial_order_p_one = radial_order+1;
889 switch (inf_elem_type)
894 n_base_side_nodes = 0;
895 n_base_face_nodes = 0;
904 n_base_side_nodes = 0;
905 n_base_face_nodes = 0;
914 n_base_side_nodes = 1;
915 n_base_face_nodes = 0;
924 n_base_side_nodes = 0;
925 n_base_face_nodes = 0;
934 n_base_side_nodes = 4;
935 n_base_face_nodes = 0;
944 n_base_side_nodes = 4;
945 n_base_face_nodes = 1;
955 n_base_side_nodes = 0;
956 n_base_face_nodes = 0;
965 n_base_side_nodes = 3;
966 n_base_face_nodes = 0;
973 libmesh_error_msg(
"Unrecognized inf_elem_type = " << inf_elem_type);
979 const unsigned int n_dof_at_base_vertices = n_base_vertices*n_base_vertex_dof;
980 const unsigned int n_dof_at_all_vertices = n_dof_at_base_vertices*radial_order_p_one;
982 const unsigned int n_dof_at_base_sides = n_base_side_nodes*n_base_side_dof;
983 const unsigned int n_dof_at_all_sides = n_dof_at_base_sides*radial_order_p_one;
985 const unsigned int n_dof_at_base_face = n_base_face_nodes*n_base_face_dof;
986 const unsigned int n_dof_at_all_faces = n_dof_at_base_face*radial_order_p_one;
990 if (i < n_dof_at_base_vertices)
997 else if (i < n_dof_at_all_vertices)
1004 const unsigned int i_offset = i - n_dof_at_base_vertices;
1007 radial_shape = (i_offset % radial_order) + 1;
1008 base_shape = i_offset / radial_order;
1011 else if (i < n_dof_at_all_vertices+n_dof_at_base_sides)
1015 base_shape = i - radial_order * n_dof_at_base_vertices;
1018 else if (i < n_dof_at_all_vertices+n_dof_at_all_sides)
1021 const unsigned int i_offset = i - (n_dof_at_all_vertices
1022 + n_dof_at_base_sides);
1023 radial_shape = (i_offset % radial_order) + 1;
1024 base_shape = (i_offset / radial_order) + n_dof_at_base_vertices;
1027 else if (i < n_dof_at_all_vertices+n_dof_at_all_sides+n_dof_at_base_face)
1031 base_shape = i - radial_order*(n_dof_at_base_vertices
1032 + n_dof_at_base_sides);
1035 else if (i < n_dof_at_all_vertices+n_dof_at_all_sides+n_dof_at_all_faces)
1038 const unsigned int i_offset = i - (n_dof_at_all_vertices
1039 + n_dof_at_all_sides
1040 + n_dof_at_base_face);
1041 radial_shape = (i_offset % radial_order) + 1;
1042 base_shape = (i_offset / radial_order) + n_dof_at_base_vertices + n_dof_at_base_sides;
1045 else if (i < n_dof_at_all_vertices+n_dof_at_all_sides+n_dof_at_all_faces+n_base_elem_dof)
1049 base_shape = i - (n_dof_at_all_vertices
1050 + n_dof_at_all_sides
1051 + n_dof_at_all_faces);
1056 libmesh_assert_less (i, n_dofs(fet, inf_elem_type));
1058 const unsigned int i_offset = i - (n_dof_at_all_vertices
1059 + n_dof_at_all_sides
1060 + n_dof_at_all_faces
1062 radial_shape = (i_offset % radial_order) + 1;
1063 base_shape = (i_offset / radial_order) + n_dof_at_base_vertices + n_dof_at_base_sides + n_dof_at_base_face;
1114 #endif //ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS