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