21 #include "libmesh/elem.h" 
   22 #include "libmesh/fe.h" 
   23 #include "libmesh/fe_interface.h" 
   24 #include "libmesh/fe_macro.h" 
   25 #include "libmesh/libmesh_logging.h" 
   26 #include "libmesh/quadrature.h" 
   27 #include "libmesh/tensor_value.h" 
   28 #include "libmesh/enum_elem_type.h" 
   36 template <
unsigned int Dim, FEFamily T>
 
   45   libmesh_assert_equal_to (T, this->get_family());
 
   49 template <
unsigned int Dim, FEFamily T>
 
   53                             static_cast<Order>(this->fe_type.order + this->_p_level));
 
   57 template <
unsigned int Dim, FEFamily T>
 
   68 template <
unsigned int Dim, FEFamily T>
 
   72   return this->qrule->n_points();
 
   76 template <
unsigned int Dim, FEFamily T>
 
   80                              std::vector<unsigned int> & di)
 
   83   libmesh_assert_less (s, elem->
n_sides());
 
   86   unsigned int nodenum = 0;
 
   88   for (
unsigned int n = 0; n != 
n_nodes; ++n)
 
   90       const unsigned int n_dofs = n_dofs_at_node(elem->
type(),
 
   91                                                  static_cast<Order>(o + elem->
p_level()), n);
 
   93         for (
unsigned int i = 0; i != n_dofs; ++i)
 
   94           di.push_back(nodenum++);
 
  102 template <
unsigned int Dim, FEFamily T>
 
  106                              std::vector<unsigned int> & di)
 
  109   libmesh_assert_less (e, elem->
n_edges());
 
  112   unsigned int nodenum = 0;
 
  114   for (
unsigned int n = 0; n != 
n_nodes; ++n)
 
  116       const unsigned int n_dofs = n_dofs_at_node(elem->
type(),
 
  117                                                  static_cast<Order>(o + elem->
p_level()), n);
 
  119         for (
unsigned int i = 0; i != n_dofs; ++i)
 
  120           di.push_back(nodenum++);
 
  128 template <
unsigned int Dim, FEFamily T>
 
  130                        const std::vector<Point> * 
const pts,
 
  131                        const std::vector<Real> * 
const weights)
 
  138   this->determine_calculations();
 
  142   bool cached_nodes_still_fit = 
false;
 
  152           this->elem_type = elem->
type();
 
  153           this->_p_level = elem->
p_level();
 
  156           this->_fe_map->template init_reference_to_physical_map<Dim>
 
  158           this->init_shape_functions (*pts, elem);
 
  161           this->shapes_on_quadrature = 
false;
 
  176           if (this->qrule->shapes_need_reinit())
 
  177             this->shapes_on_quadrature = 
false;
 
  179           if (this->elem_type != elem->
type() ||
 
  180               this->_p_level != elem->
p_level() ||
 
  181               !this->shapes_on_quadrature)
 
  184               this->elem_type = elem->
type();
 
  185               this->_p_level = elem->
p_level();
 
  187               this->_fe_map->template init_reference_to_physical_map<Dim>
 
  188                 (this->qrule->get_points(), elem);
 
  189               this->init_shape_functions (this->qrule->get_points(), elem);
 
  191               if (this->shapes_need_reinit())
 
  193                   cached_nodes.resize(elem->
n_nodes());
 
  195                     cached_nodes[n] = elem->
point(n);
 
  202               cached_nodes_still_fit = 
true;
 
  203               if (cached_nodes.size() != elem->
n_nodes())
 
  204                 cached_nodes_still_fit = 
false;
 
  208                     if (!(elem->
point(n) - elem->
point(0)).relative_fuzzy_equals
 
  209                         ((cached_nodes[n] - cached_nodes[0]), 1e-13))
 
  211                         cached_nodes_still_fit = 
false;
 
  216               if (this->shapes_need_reinit() && !cached_nodes_still_fit)
 
  218                   this->_fe_map->template init_reference_to_physical_map<Dim>
 
  219                     (this->qrule->get_points(), elem);
 
  220                   this->init_shape_functions (this->qrule->get_points(), elem);
 
  221                   cached_nodes.resize(elem->
n_nodes());
 
  223                     cached_nodes[n] = elem->
point(n);
 
  228           this->shapes_on_quadrature = 
true;
 
  242               this->qrule->get_points() =
 
  243                 std::vector<Point>(1,
Point(0));
 
  245               this->qrule->get_weights() =
 
  246                 std::vector<Real>(1,1);
 
  250               this->qrule->get_points().clear();
 
  251               this->qrule->get_weights().clear();
 
  254           this->init_shape_functions (this->qrule->get_points(), elem);
 
  257         this->init_shape_functions (*pts, elem);
 
  263       if (weights != 
nullptr)
 
  265           this->_fe_map->compute_map (this->
dim, *weights, elem, this->calculate_d2phi);
 
  269           std::vector<Real> dummy_weights (pts->size(), 1.);
 
  270           this->_fe_map->compute_map (this->
dim, dummy_weights, elem, this->calculate_d2phi);
 
  275       this->_fe_map->compute_map (this->
dim, this->qrule->get_weights(), elem, this->calculate_d2phi);
 
  280   if (!cached_nodes_still_fit)
 
  283         this->compute_shape_functions (elem,*pts);
 
  285         this->compute_shape_functions(elem,this->qrule->get_points());
 
  291 template <
unsigned int Dim, FEFamily T>
 
  296   LOG_SCOPE(
"init_shape_functions()", 
"FE");
 
  299   const unsigned int n_qp = cast_int<unsigned int>(qp.size());
 
  303   const unsigned int n_approx_shape_functions =
 
  304     this->n_shape_functions(this->get_type(),
 
  310   if (this->calculate_phi)
 
  311     this->phi.resize     (n_approx_shape_functions);
 
  313   if (this->calculate_dphi)
 
  315       this->dphi.resize    (n_approx_shape_functions);
 
  316       this->dphidx.resize  (n_approx_shape_functions);
 
  317       this->dphidy.resize  (n_approx_shape_functions);
 
  318       this->dphidz.resize  (n_approx_shape_functions);
 
  321   if (this->calculate_dphiref)
 
  324         this->dphidxi.resize (n_approx_shape_functions);
 
  327         this->dphideta.resize      (n_approx_shape_functions);
 
  330         this->dphidzeta.resize     (n_approx_shape_functions);
 
  333   if (this->calculate_curl_phi && (FEInterface::field_type(T) == 
TYPE_VECTOR))
 
  334     this->curl_phi.resize(n_approx_shape_functions);
 
  336   if (this->calculate_div_phi && (FEInterface::field_type(T) == 
TYPE_VECTOR))
 
  337     this->div_phi.resize(n_approx_shape_functions);
 
  339 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  340   if (this->calculate_d2phi)
 
  342       this->d2phi.resize     (n_approx_shape_functions);
 
  343       this->d2phidx2.resize  (n_approx_shape_functions);
 
  344       this->d2phidxdy.resize (n_approx_shape_functions);
 
  345       this->d2phidxdz.resize (n_approx_shape_functions);
 
  346       this->d2phidy2.resize  (n_approx_shape_functions);
 
  347       this->d2phidydz.resize (n_approx_shape_functions);
 
  348       this->d2phidz2.resize  (n_approx_shape_functions);
 
  351         this->d2phidxi2.resize (n_approx_shape_functions);
 
  355           this->d2phidxideta.resize (n_approx_shape_functions);
 
  356           this->d2phideta2.resize   (n_approx_shape_functions);
 
  360           this->d2phidxidzeta.resize  (n_approx_shape_functions);
 
  361           this->d2phidetadzeta.resize (n_approx_shape_functions);
 
  362           this->d2phidzeta2.resize    (n_approx_shape_functions);
 
  365 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  367   for (
unsigned int i=0; i<n_approx_shape_functions; i++)
 
  369       if (this->calculate_phi)
 
  370         this->phi[i].resize         (n_qp);
 
  371       if (this->calculate_dphi)
 
  373           this->dphi[i].resize        (n_qp);
 
  374           this->dphidx[i].resize      (n_qp);
 
  375           this->dphidy[i].resize      (n_qp);
 
  376           this->dphidz[i].resize      (n_qp);
 
  379       if (this->calculate_dphiref)
 
  382             this->dphidxi[i].resize(n_qp);
 
  385             this->dphideta[i].resize(n_qp);
 
  388             this->dphidzeta[i].resize(n_qp);
 
  391       if (this->calculate_curl_phi && (FEInterface::field_type(T) == 
TYPE_VECTOR))
 
  392         this->curl_phi[i].resize(n_qp);
 
  394       if (this->calculate_div_phi && (FEInterface::field_type(T) == 
TYPE_VECTOR))
 
  395         this->div_phi[i].resize(n_qp);
 
  397 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  398       if (this->calculate_d2phi)
 
  400           this->d2phi[i].resize     (n_qp);
 
  401           this->d2phidx2[i].resize  (n_qp);
 
  402           this->d2phidxdy[i].resize (n_qp);
 
  403           this->d2phidxdz[i].resize (n_qp);
 
  404           this->d2phidy2[i].resize  (n_qp);
 
  405           this->d2phidydz[i].resize (n_qp);
 
  406           this->d2phidz2[i].resize  (n_qp);
 
  408             this->d2phidxi2[i].resize (n_qp);
 
  411               this->d2phidxideta[i].resize (n_qp);
 
  412               this->d2phideta2[i].resize   (n_qp);
 
  416               this->d2phidxidzeta[i].resize  (n_qp);
 
  417               this->d2phidetadzeta[i].resize (n_qp);
 
  418               this->d2phidzeta2[i].resize    (n_qp);
 
  421 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  425 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 
  433     this->
weight.resize  (n_qp);
 
  434     this->dweight.resize (n_qp);
 
  435     this->dphase.resize  (n_qp);
 
  437     for (
unsigned int p=0; p<n_qp; p++)
 
  440         this->dweight[p].zero();
 
  441         this->dphase[p].zero();
 
  445 #endif // ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 
  462         if (this->calculate_dphiref)
 
  463           for (
unsigned int i=0; i<n_approx_shape_functions; i++)
 
  464             for (
unsigned int p=0; p<n_qp; p++)
 
  466 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  467         if (this->calculate_d2phi)
 
  468           for (
unsigned int i=0; i<n_approx_shape_functions; i++)
 
  469             for (
unsigned int p=0; p<n_qp; p++)
 
  471 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  483         if (this->calculate_dphiref)
 
  484           for (
unsigned int i=0; i<n_approx_shape_functions; i++)
 
  485             for (
unsigned int p=0; p<n_qp; p++)
 
  490 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  491         if (this->calculate_d2phi)
 
  492           for (
unsigned int i=0; i<n_approx_shape_functions; i++)
 
  493             for (
unsigned int p=0; p<n_qp; p++)
 
  499 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  512         if (this->calculate_dphiref)
 
  513           for (
unsigned int i=0; i<n_approx_shape_functions; i++)
 
  514             for (
unsigned int p=0; p<n_qp; p++)
 
  520 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  521         if (this->calculate_d2phi)
 
  522           for (
unsigned int i=0; i<n_approx_shape_functions; i++)
 
  523             for (
unsigned int p=0; p<n_qp; p++)
 
  532 #endif // ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES 
  539       libmesh_error_msg(
"Invalid dimension Dim = " << Dim);
 
  545 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS 
  547 template <
unsigned int Dim, FEFamily T>
 
  551   this->elem_type = e->
type();
 
  552   this->_fe_map->template init_reference_to_physical_map<Dim>(qp, e);
 
  553   init_shape_functions(qp, e);
 
  556 #endif // LIBMESH_ENABLE_INFINITE_ELEMENTS