24 #include "libmesh/libmesh_config.h" 
   25 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 
   26 #include "libmesh/inf_fe.h" 
   27 #include "libmesh/inf_fe_macro.h" 
   28 #include "libmesh/quadrature.h" 
   29 #include "libmesh/enum_quadrature_type.h" 
   30 #include "libmesh/elem.h" 
   36 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_base>
 
   40                                         const std::vector<Point> * 
const pts,
 
   41                                         const std::vector<Real> * 
const weights)
 
   43   if (weights != 
nullptr)
 
   44     libmesh_not_implemented_msg(
"ERROR: User-specified weights for infinite elements are not implemented!");
 
   47     libmesh_not_implemented_msg(
"ERROR: User-specified points for infinite elements are not implemented!");
 
   50   libmesh_assert_not_equal_to (Dim, 1);
 
   60   const std::unique_ptr<const Elem> side(inf_elem->
build_side_ptr(s));
 
   63   elem_type = inf_elem->
type();
 
   66   bool radial_qrule_initialized = 
false;
 
   72     current_fe_type.radial_order = 0;
 
   74   if (current_fe_type.radial_order != fe_type.radial_order)
 
   78           current_fe_type.radial_order = fe_type.radial_order;
 
   88           base_qrule=
QBase::build(qrule->type(), side->dim(), qrule->get_order());
 
   94           base_qrule->init(side->type(), side->p_level());
 
   96       radial_qrule_initialized = 
true;
 
  100   if (this->get_type() != inf_elem->
type() ||
 
  101       base_fe->shapes_need_reinit()        ||
 
  102       radial_qrule_initialized)
 
  103     this->init_face_shape_functions (qrule->get_points(), side.get());
 
  107   this->_fe_map->compute_face_map(this->
dim, _total_qrule_weights, side.get());
 
  110   const std::vector<Real> JxW_int(this->_fe_map->get_JxW());
 
  114   std::vector<Point> qp;
 
  115   this->inverse_map (inf_elem, this->_fe_map->get_xyz(), qp, tolerance);
 
  129   this->reinit  (inf_elem, &qp);
 
  132   this->_fe_map->get_JxW() = JxW_int;
 
  139 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_base>
 
  143                                              const std::vector<Point> * 
const pts,
 
  144                                              const std::vector<Real> * 
const )
 
  148   libmesh_not_implemented_msg(
"ERROR: Edge conditions for infinite elements not implemented!");
 
  151     libmesh_not_implemented_msg(
"ERROR: User-specified points for infinite elements not implemented!");
 
  157 template <
unsigned int Dim, FEFamily T_radial, InfMapType T_base>
 
  159                                                            const Elem * inf_side)
 
  164   libmesh_assert_equal_to (Dim, 3);
 
  167   this->init_radial_shape_functions(inf_side);
 
  171     this->update_base_elem(inf_side);
 
  174     this->update_base_elem(inf_side->
parent());
 
  177   base_qrule->init(base_elem->type(), inf_side->
p_level());
 
  183       libmesh_assert_equal_to (Dim, 3);
 
  185       base_fe->attach_quadrature_rule(base_qrule.get());
 
  190       base_fe->attach_quadrature_rule(base_qrule.get());
 
  194   base_fe->_fe_map->get_xyz();
 
  195   base_fe->_fe_map->get_JxW();
 
  198   base_fe->init_base_shape_functions(base_fe->qrule->get_points(),
 
  202   const unsigned int n_radial_qp =
 
  203     cast_int<unsigned int>(som.size());
 
  204   const unsigned int n_base_qp   = base_qrule->n_points();
 
  205   const unsigned int n_total_qp  = n_radial_qp * n_base_qp;
 
  208   _total_qrule_weights.resize(n_total_qp);
 
  214     const Order    base_mapping_order     ( base_elem->default_order() );
 
  218     const unsigned int n_radial_mapping_sf =
 
  219       inf_side->
infinite() ? cast_int<unsigned int>(radial_map.size()) : 1;
 
  221     const unsigned int n_base_mapping_shape_functions =
 
  224     const unsigned int n_total_mapping_shape_functions =
 
  225       n_radial_mapping_sf * n_base_mapping_shape_functions;
 
  229     _radial_node_index.resize    (n_total_mapping_shape_functions);
 
  230     _base_node_index.resize      (n_total_mapping_shape_functions);
 
  237         for (
unsigned int n=0; n<n_total_mapping_shape_functions; n++)
 
  239             compute_node_indices (inf_face_elem_type,
 
  242                                   _radial_node_index[n]);
 
  244             libmesh_assert_less (_base_node_index[n], n_base_mapping_shape_functions);
 
  245             libmesh_assert_less (_radial_node_index[n], n_radial_mapping_sf);
 
  250         for (
unsigned int n=0; n<n_total_mapping_shape_functions; n++)
 
  252             _base_node_index[n] = n;
 
  253             _radial_node_index[n] = 0;
 
  258     std::vector<std::vector<Real>> & psi_map = this->_fe_map->get_psi();
 
  259     std::vector<std::vector<Real>> & dpsidxi_map = this->_fe_map->get_dpsidxi();
 
  260     std::vector<std::vector<Real>> & dpsideta_map = this->_fe_map->get_dpsideta();
 
  261     psi_map.resize          (n_total_mapping_shape_functions);
 
  262     dpsidxi_map.resize      (n_total_mapping_shape_functions);
 
  263     dpsideta_map.resize     (n_total_mapping_shape_functions);
 
  264 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  265     std::vector<std::vector<Real>> & d2psidxi2_map = this->_fe_map->get_d2psidxi2();
 
  266     std::vector<std::vector<Real>> & d2psidxideta_map = this->_fe_map->get_d2psidxideta();
 
  267     std::vector<std::vector<Real>> & d2psideta2_map = this->_fe_map->get_d2psideta2();
 
  268     d2psidxi2_map.resize    (n_total_mapping_shape_functions);
 
  269     d2psidxideta_map.resize (n_total_mapping_shape_functions);
 
  270     d2psideta2_map.resize   (n_total_mapping_shape_functions);
 
  273     for (
unsigned int i=0; i<n_total_mapping_shape_functions; i++)
 
  275         psi_map[i].resize         (n_total_qp);
 
  276         dpsidxi_map[i].resize     (n_total_qp);
 
  277         dpsideta_map[i].resize    (n_total_qp);
 
  278 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  279         d2psidxi2_map[i].resize   (n_total_qp);
 
  280         d2psidxideta_map[i].resize(n_total_qp);
 
  281         d2psideta2_map[i].resize  (n_total_qp);
 
  288         const std::vector<std::vector<Real>> & S_map  = (base_fe->get_fe_map()).get_phi_map();
 
  289         const std::vector<std::vector<Real>> & Ss_map = (base_fe->get_fe_map()).get_dphidxi_map();
 
  291         for (
unsigned int rp=0; rp<n_radial_qp; rp++)  
 
  292           for (
unsigned int bp=0; bp<n_base_qp; bp++)  
 
  293             for (
unsigned int ti=0; ti<n_total_mapping_shape_functions; ti++)  
 
  296                 const unsigned int bi = _base_node_index  [ti];
 
  297                 const unsigned int ri = _radial_node_index[ti];
 
  298                 psi_map          [ti][bp+rp*n_base_qp] = S_map [bi][bp] * radial_map   [ri][rp];
 
  299                 dpsidxi_map      [ti][bp+rp*n_base_qp] = Ss_map[bi][bp] * radial_map   [ri][rp];
 
  300                 dpsideta_map     [ti][bp+rp*n_base_qp] = S_map [bi][bp] * dradialdv_map[ri][rp];
 
  303 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  304                 d2psidxi2_map    [ti][bp+rp*n_base_qp] = 0.;
 
  305                 d2psidxideta_map [ti][bp+rp*n_base_qp] = 0.;
 
  306                 d2psideta2_map   [ti][bp+rp*n_base_qp] = 0.;
 
  313         const std::vector<std::vector<Real>> & S_map  = (base_fe->get_fe_map()).get_phi_map();
 
  314         const std::vector<std::vector<Real>> & Ss_map = (base_fe->get_fe_map()).get_dphidxi_map();
 
  315         const std::vector<std::vector<Real>> & St_map = (base_fe->get_fe_map()).get_dphideta_map();
 
  316         for (
unsigned int bp=0; bp<n_base_qp; bp++)  
 
  317           for (
unsigned int ti=0; ti<n_total_mapping_shape_functions; ti++)  
 
  319               psi_map      [ti][bp] = S_map[ti][bp] ;
 
  320               dpsidxi_map  [ti][bp] = Ss_map[ti][bp] ;
 
  321               dpsideta_map [ti][bp] = St_map[ti][bp] ;
 
  322 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  323               d2psidxi2_map    [ti][bp] = 0.;
 
  324               d2psidxideta_map [ti][bp] = 0.;
 
  325               d2psideta2_map   [ti][bp] = 0.;
 
  333     const std::vector<Real> & radial_qw = radial_qrule->get_weights();
 
  334     const std::vector<Real> & base_qw   = base_qrule->get_weights();
 
  336     libmesh_assert_equal_to (radial_qw.size(), n_radial_qp);
 
  337     libmesh_assert_equal_to (base_qw.size(), n_base_qp);
 
  339     for (
unsigned int rp=0; rp<n_radial_qp; rp++)
 
  340       for (
unsigned int bp=0; bp<n_base_qp; bp++)
 
  342           _total_qrule_weights[bp + rp*n_base_qp] = radial_qw[rp] * base_qw[bp];
 
  368 #endif //ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS