39 #define REINIT_ERROR(_dim, _type, _func)                        \    41   void FE<_dim,_type>::_func(const Elem *,                      \    44                              const std::vector<Point> * const,  \    45                              const std::vector<Real> * const)    47 #define SIDEMAP_ERROR(_dim, _type, _func)                       \    49   void FE<_dim,_type>::_func(const Elem *,                      \    52                              const std::vector<Point> &,        \    55 #define FACE_EDGE_SHAPE_ERROR(_dim, _func)                              \    57   void FEMap::_func<_dim>(const std::vector<Point> &,                   \    60     libmesh_error_msg("ERROR: This method makes no sense for low-D elements!"); \    65 REINIT_ERROR(0, 
CLOUGH, reinit)      { libmesh_error_msg(
"ERROR: Cannot reinit 0D CLOUGH elements!");      }
    66 REINIT_ERROR(0, 
CLOUGH, edge_reinit) { libmesh_error_msg(
"ERROR: Cannot edge_reinit 0D CLOUGH elements!"); }
    67 SIDEMAP_ERROR(0, 
CLOUGH, side_map)   { libmesh_error_msg(
"ERROR: Cannot side_map 0D CLOUGH elements!"); }
    70 REINIT_ERROR(0, 
HERMITE, edge_reinit) { libmesh_error_msg(
"ERROR: Cannot edge_reinit 0D HERMITE elements!"); }
    82 REINIT_ERROR(0, 
LAGRANGE, edge_reinit) { libmesh_error_msg(
"ERROR: Cannot edge_reinit 0D LAGRANGE elements!"); }
    94 REINIT_ERROR(0, 
MONOMIAL, edge_reinit) { libmesh_error_msg(
"ERROR: Cannot edge_reinit 0D MONOMIAL elements!"); }
    97 REINIT_ERROR(0, 
SCALAR, reinit)      { libmesh_error_msg(
"ERROR: Cannot reinit 0D SCALAR elements!"); }
    98 REINIT_ERROR(0, 
SCALAR, edge_reinit) { libmesh_error_msg(
"ERROR: Cannot edge_reinit 0D SCALAR elements!"); }
    99 SIDEMAP_ERROR(0, 
SCALAR, side_map)   { libmesh_error_msg(
"ERROR: Cannot side_map 0D SCALAR elements!"); }
   101 REINIT_ERROR(0, 
XYZ, reinit)      { libmesh_error_msg(
"ERROR: Cannot reinit 0D XYZ elements!"); }
   102 REINIT_ERROR(0, 
XYZ, edge_reinit) { libmesh_error_msg(
"ERROR: Cannot edge_reinit 0D XYZ elements!"); }
   103 SIDEMAP_ERROR(0, 
XYZ, side_map)   { libmesh_error_msg(
"ERROR: Cannot side_map 0D XYZ elements!"); }
   109 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES   115 REINIT_ERROR(0, 
SZABAB, edge_reinit) { libmesh_error_msg(
"ERROR: Cannot edge_reinit 0D SZABAB elements!"); }
   120 REINIT_ERROR(1, 
CLOUGH, edge_reinit)        { libmesh_error_msg(
"ERROR: Cannot edge_reinit 1D CLOUGH elements!"); }
   121 REINIT_ERROR(1, 
HERMITE, edge_reinit)       { libmesh_error_msg(
"ERROR: Cannot edge_reinit 1D HERMITE elements!"); }
   124 REINIT_ERROR(1, 
LAGRANGE, edge_reinit)      { libmesh_error_msg(
"ERROR: Cannot edge_reinit 1D LAGRANGE elements!"); }
   127 REINIT_ERROR(1, 
XYZ, edge_reinit)           { libmesh_error_msg(
"ERROR: Cannot edge_reinit 1D XYZ elements!"); }
   128 REINIT_ERROR(1, 
MONOMIAL, edge_reinit)      { libmesh_error_msg(
"ERROR: Cannot edge_reinit 1D MONOMIAL elements!"); }
   129 REINIT_ERROR(1, 
SCALAR, edge_reinit)        { libmesh_error_msg(
"ERROR: Cannot edge_reinit 1D SCALAR elements!"); }
   133 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES   135 REINIT_ERROR(1, 
SZABAB, edge_reinit)        { libmesh_error_msg(
"ERROR: Cannot edge_reinit 1D SZABAB elements!"); }
   141 template <
unsigned int Dim, FEFamily T>
   143                        const unsigned int s,
   145                        const std::vector<Point> * 
const pts,
   146                        const std::vector<Real> * 
const weights)
   148   libmesh_assert(elem);
   149   libmesh_assert (this->qrule != 
nullptr || pts != 
nullptr);
   156   this->_fe_map->calculations_started = 
false;
   157   this->_fe_map->get_JxW();
   158   this->_fe_map->get_xyz();
   159   this->determine_calculations();
   166   unsigned int side_p_level = elem->
p_level();
   175       this->shapes_on_quadrature = 
false;
   178       this->_fe_map->template init_face_shape_functions<Dim>(*pts, 
side.get());
   181       if (weights != 
nullptr)
   183           this->_fe_map->compute_face_map (Dim, *weights, 
side.get());
   187           std::vector<Real> dummy_weights (pts->size(), 1.);
   188           this->_fe_map->compute_face_map (Dim, dummy_weights, 
side.get());
   196       this->qrule->init(
side->type(), side_p_level);
   198       if (this->qrule->shapes_need_reinit())
   199         this->shapes_on_quadrature = 
false;
   204       if ((this->get_type() != elem->
type())    ||
   205           (
side->type() != last_side)           ||
   206           (this->get_p_level() != side_p_level) ||
   207           this->shapes_need_reinit()            ||
   208           !this->shapes_on_quadrature)
   211           this->elem_type = elem->
type();
   214           last_side = 
side->type();
   217           this->_p_level = side_p_level;
   220           this->_fe_map->template init_face_shape_functions<Dim>(this->qrule->get_points(),  
side.get());
   224       this->_fe_map->compute_face_map (Dim, this->qrule->get_weights(), 
side.get());
   227       this->shapes_on_quadrature = 
true;
   231   const std::vector<Real> JxW_int(this->_fe_map->get_JxW());
   234   bool shapes_on_quadrature_side = this->shapes_on_quadrature;
   238   const std::vector<Point> * ref_qp;
   242     ref_qp = &this->qrule->get_points();
   244   std::vector<Point> qp;
   245   this->side_map(elem, 
side.get(), s, *ref_qp, qp);
   249   this->reinit  (elem, &qp);
   251   this->shapes_on_quadrature = shapes_on_quadrature_side;
   254   this->_fe_map->get_JxW() = JxW_int;
   259 template <
unsigned int Dim, FEFamily T>
   261                             const unsigned int e,
   262                             const Real tolerance,
   263                             const std::vector<Point> * 
const pts,
   264                             const std::vector<Real> * 
const weights)
   266   libmesh_assert(elem);
   267   libmesh_assert (this->qrule != 
nullptr || pts != 
nullptr);
   269   libmesh_assert_not_equal_to (Dim, 1);
   274   this->_fe_map->calculations_started = 
false;
   275   this->_fe_map->get_JxW();
   276   this->_fe_map->get_xyz();
   277   this->determine_calculations();
   287       this->shapes_on_quadrature = 
false;
   290       this->_fe_map->template init_edge_shape_functions<Dim> (*pts, edge.get());
   293       if (weights != 
nullptr)
   295           this->_fe_map->compute_edge_map (Dim, *weights, edge.get());
   299           std::vector<Real> dummy_weights (pts->size(), 1.);
   300           this->_fe_map->compute_edge_map (Dim, dummy_weights, edge.get());
   308       this->qrule->init(edge->type(), elem->
p_level());
   310       if (this->qrule->shapes_need_reinit())
   311         this->shapes_on_quadrature = 
false;
   314       if ((this->get_type() != elem->
type())                   ||
   315           (edge->type() != 
static_cast<int>(last_edge))        || 
   316           this->shapes_need_reinit()                           ||
   317           !this->shapes_on_quadrature)
   320           this->elem_type = elem->
type();
   323           last_edge = edge->type();
   326           this->_fe_map->template init_edge_shape_functions<Dim> (this->qrule->get_points(), edge.get());
   330       this->_fe_map->compute_edge_map (Dim, this->qrule->get_weights(), edge.get());
   333       this->shapes_on_quadrature = 
true;
   337   const std::vector<Real> JxW_int(this->_fe_map->get_JxW());
   341   std::vector<Point> qp;
   342   this->inverse_map (elem, this->_fe_map->get_xyz(), qp, tolerance);
   346   this->reinit  (elem, &qp);
   349   this->_fe_map->get_JxW() = JxW_int;
   352 template <
unsigned int Dim, FEFamily T>
   355                           const unsigned int s,
   356                           const std::vector<Point> & reference_side_points,
   357                           std::vector<Point> &       reference_points)
   360   this->calculate_phi = 
true;
   361   this->determine_calculations();
   363   unsigned int side_p_level = elem->
p_level();
   367   if (
side->type() != last_side ||
   368       side_p_level != this->_p_level ||
   369       !this->shapes_on_quadrature)
   372       this->elem_type = elem->
type();
   373       this->_p_level = side_p_level;
   376       last_side = 
side->type();
   379       this->_fe_map->template init_face_shape_functions<Dim>(reference_side_points, 
side);
   382   const unsigned int n_points =
   383     cast_int<unsigned int>(reference_side_points.size());
   384   reference_points.resize(n_points);
   385   for (
unsigned int i = 0; i < n_points; i++)
   386     reference_points[i].
zero();
   388   std::vector<unsigned int> elem_nodes_map;
   389   elem_nodes_map.resize(
side->n_nodes());
   390   for (
unsigned int j = 0; j < 
side->n_nodes(); j++)
   391     for (
unsigned int i = 0; i < elem->
n_nodes(); i++)
   393         elem_nodes_map[j] = i;
   394   std::vector<Point> refspace_nodes;
   395   this->get_refspace_nodes(elem->
type(), refspace_nodes);
   397   const std::vector<std::vector<Real>> & psi_map = this->_fe_map->get_psi();
   402       const Point & side_node = refspace_nodes[elem_nodes_map[i]];
   403       for (
unsigned int p=0; p<n_points; p++)
   404         reference_points[p].add_scaled (side_node, psi_map[i][p]);
   408 template<
unsigned int Dim>
   413   LOG_SCOPE(
"init_face_shape_functions()", 
"FEMap");
   415   libmesh_assert(
side);
   422   const Order    mapping_order     (
side->default_order());
   426   const unsigned int n_qp = cast_int<unsigned int>(qp.size());
   428   const unsigned int n_mapping_shape_functions =
   435     this->
psi_map.resize        (n_mapping_shape_functions);
   440         this->
dpsidxi_map.resize    (n_mapping_shape_functions);
   456   for (
unsigned int i=0; i<n_mapping_shape_functions; i++)
   461         this->
psi_map[i].resize        (n_qp);
   483       for (
unsigned int p=0; p<n_qp; p++)
   513 template<
unsigned int Dim>
   518   LOG_SCOPE(
"init_edge_shape_functions()", 
"FEMap");
   520   libmesh_assert(edge);
   531   const unsigned int n_qp = cast_int<unsigned int>(qp.size());
   533   const unsigned int n_mapping_shape_functions =
   540     this->
psi_map.resize        (n_mapping_shape_functions);
   542     this->
dpsidxi_map.resize    (n_mapping_shape_functions);
   546   for (
unsigned int i=0; i<n_mapping_shape_functions; i++)
   551         this->
psi_map[i].resize        (n_qp);
   560       for (
unsigned int p=0; p<n_qp; p++)
   577   libmesh_assert(
side);
   582   LOG_SCOPE(
"compute_face_map()", 
"FEMap");
   585   const unsigned int n_qp = cast_int<unsigned int>(qw.size());
   598             this->
xyz.resize(n_qp);
   603             this->
JxW.resize(n_qp);
   613         libmesh_assert (elem);
   620                 libmesh_assert_equal_to (
side->node_id(0),
   628           libmesh_assert_equal_to (this->
psi_map.size(), 1);
   631         for (
unsigned int p=0; p<n_qp; p++)
   641                 this->
JxW[p] = 1.0*qw[p];
   657             this->
xyz.resize(n_qp);
   664               this->
JxW.resize(n_qp);
   676         for (
unsigned int p=0; p<n_qp; p++)
   682                 this->
tangents[p].resize(LIBMESH_DIM-1); 
   689         const unsigned int n_mapping_shape_functions =
   691                                              side->default_order());
   694         for (
unsigned int i=0; i<n_mapping_shape_functions; i++) 
   696             const Point & side_point = 
side->point(i);
   698             for (
unsigned int p=0; p<n_qp; p++) 
   701                   this->
xyz[p].add_scaled          (side_point, this->
psi_map[i][p]);
   712             for (
unsigned int p=0; p<n_qp; p++)
   722 #elif LIBMESH_DIM == 3   727                 libmesh_assert(elem);
   758                     libmesh_assert_not_equal_to (denominator, 0);
   764             for (
unsigned int p=0; p<n_qp; p++)
   768                 libmesh_assert_greater (the_jac, 0.);
   770                 this->
JxW[p] = the_jac*qw[p];
   786             this->
xyz.resize(n_qp);
   793               this->
JxW.resize(n_qp);
   805         for (
unsigned int p=0; p<n_qp; p++)
   811                 this->
tangents[p].resize(LIBMESH_DIM-1); 
   823         const unsigned int n_mapping_shape_functions =
   825                                              side->default_order());
   828         for (
unsigned int i=0; i<n_mapping_shape_functions; i++) 
   830             const Point & side_point = 
side->point(i);
   832             for (
unsigned int p=0; p<n_qp; p++) 
   835                   this->
xyz[p].add_scaled         (side_point, this->
psi_map[i][p]);
   853             for (
unsigned int p=0; p<n_qp; p++)
   873                     const Real G  =  this->dxyzdeta_map[p].norm_sq();
   875                     const Real numerator   = E*N -2.*F*M + G*L;
   876                     const Real denominator = E*G - F*F;
   877                     libmesh_assert_not_equal_to (denominator, 0.);
   884             for (
unsigned int p=0; p<n_qp; p++)
   894                 const Real g21 = g12;
   901                 const Real the_jac = std::sqrt(g11*g22 - g12*g21);
   903                 libmesh_assert_greater (the_jac, 0.);
   905                 this->
JxW[p] = the_jac*qw[p];
   915       libmesh_error_msg(
"Invalid dimension dim = " << dim);
   923                              const std::vector<Real> & qw,
   926   libmesh_assert(edge);
   937   libmesh_assert_equal_to (dim, 3);  
   939   LOG_SCOPE(
"compute_edge_map()", 
"FEMap");
   945   const unsigned int n_qp = cast_int<unsigned int>(qw.size());
   949     this->
xyz.resize(n_qp);
   956       this->
JxW.resize(n_qp);
   967   for (
unsigned int p=0; p<n_qp; p++)
   986   for (
unsigned int i=0,
   987        psi_map_size=cast_int<unsigned int>(
psi_map.size());
   988        i != psi_map_size; i++) 
   992       for (
unsigned int p=0; p<n_qp; p++) 
   995             this->
xyz[p].add_scaled             (edge_point, this->
psi_map[i][p]);
  1006     for (
unsigned int p=0; p<n_qp; p++)
  1016         libmesh_assert_greater (the_jac, 0.);
  1018         this->
JxW[p] = the_jac*qw[p];
  1024 FACE_EDGE_SHAPE_ERROR(0,init_face_shape_functions)
  1025 template void FEMap::init_face_shape_functions<1>(
const std::vector<Point> &, 
const Elem *);
  1026 template void FEMap::init_face_shape_functions<2>(
const std::vector<Point> &, 
const Elem *);
  1027 template void FEMap::init_face_shape_functions<3>(
const std::vector<Point> &, 
const Elem *);
  1029 FACE_EDGE_SHAPE_ERROR(0,init_edge_shape_functions)
  1030 template void FEMap::init_edge_shape_functions<1>(
const std::vector<Point> &, 
const Elem *);
  1031 template void FEMap::init_edge_shape_functions<2>(
const std::vector<Point> &, 
const Elem *);
  1032 template void FEMap::init_edge_shape_functions<3>(
const std::vector<Point> &, 
const Elem *);
  1046 template void FE<1,CLOUGH>::reinit(
Elem const *, 
unsigned int, 
Real, 
const std::vector<Point> * 
const, 
const std::vector<Real> * 
const);
  1052 template void FE<1,SCALAR>::reinit(
Elem const *, 
unsigned int, 
Real, 
const std::vector<Point> * 
const, 
const std::vector<Real> * 
const);
  1054 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES  1057 template void FE<1,SZABAB>::reinit(
Elem const *, 
unsigned int, 
Real, 
const std::vector<Point> * 
const, 
const std::vector<Real> * 
const);
  1060 template void FE<1,XYZ>::reinit(
Elem const *, 
unsigned int, 
Real, 
const std::vector<Point> * 
const, 
const std::vector<Real> * 
const);
  1061 template void FE<1,XYZ>::side_map(
Elem const *, 
Elem const *, 
const unsigned int, 
const std::vector<Point> &, std::vector<Point> &);
  1078 template void FE<2,CLOUGH>::reinit(
Elem const *, 
unsigned int, 
Real, 
const std::vector<Point> * 
const, 
const std::vector<Real> * 
const);
  1087 template void FE<2,SCALAR>::reinit(
Elem const *, 
unsigned int, 
Real, 
const std::vector<Point> * 
const, 
const std::vector<Real> * 
const);
  1090 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES  1094 template void FE<2,SZABAB>::reinit(
Elem const *, 
unsigned int, 
Real, 
const std::vector<Point> * 
const, 
const std::vector<Real> * 
const);
  1099 template void FE<2,XYZ>::reinit(
Elem const *, 
unsigned int, 
Real, 
const std::vector<Point> * 
const, 
const std::vector<Real> * 
const);
  1100 template void FE<2,XYZ>::side_map(
Elem const *, 
Elem const *, 
const unsigned int, 
const std::vector<Point> &, std::vector<Point> &);
  1124 template void FE<3,CLOUGH>::reinit(
Elem const *, 
unsigned int, 
Real, 
const std::vector<Point> * 
const, 
const std::vector<Real> * 
const);
  1133 template void FE<3,SCALAR>::reinit(
Elem const *, 
unsigned int, 
Real, 
const std::vector<Point> * 
const, 
const std::vector<Real> * 
const);
  1136 #ifdef LIBMESH_ENABLE_HIGHER_ORDER_SHAPES  1140 template void FE<3,SZABAB>::reinit(
Elem const *, 
unsigned int, 
Real, 
const std::vector<Point> * 
const, 
const std::vector<Real> * 
const);
  1144 template void FE<3,XYZ>::reinit(
Elem const *, 
unsigned int, 
Real, 
const std::vector<Point> * 
const, 
const std::vector<Real> * 
const);
  1145 template void FE<3,XYZ>::side_map(
Elem const *, 
Elem const *, 
const unsigned int, 
const std::vector<Point> &, std::vector<Point> &);
 
void init_edge_shape_functions(const std::vector< Point > &qp, const Elem *edge)
 
Real dzdeta_map(const unsigned int p) const
 
std::vector< std::vector< Real > > dpsideta_map
 
std::vector< std::vector< Real > > psi_map
 
std::vector< std::vector< Real > > d2psideta2_map
 
virtual void side_map(const Elem *elem, const Elem *side, const unsigned int s, const std::vector< Point > &reference_side_points, std::vector< Point > &reference_points) override
 
static OutputShape shape(const ElemType t, const Order o, const unsigned int i, const Point &p)
 
static Point map_xi(const Elem *elem, const Point &reference_point)
 
void compute_edge_map(int dim, const std::vector< Real > &qw, const Elem *side)
 
SIDEMAP_ERROR(0, CLOUGH, side_map)
 
REINIT_ERROR(0, CLOUGH, reinit)
 
Real dxdeta_map(const unsigned int p) const
 
Real dzdxi_map(const unsigned int p) const
 
The base class for all geometric element types. 
 
IntRange< std::size_t > index_range(const std::vector< T > &vec)
 
static OutputShape shape_deriv(const ElemType t, const Order o, const unsigned int i, const unsigned int j, const Point &p)
 
unsigned int p_level() const
 
long double max(long double a, double b)
 
std::vector< std::vector< Real > > d2psidxideta_map
 
std::vector< RealGradient > d2xyzdxideta_map
 
virtual std::unique_ptr< Elem > build_side_ptr(const unsigned int i, bool proxy=true)=0
 
virtual void reinit(const Elem *elem, const std::vector< Point > *const pts=nullptr, const std::vector< Real > *const weights=nullptr) override
 
std::vector< RealGradient > dxyzdxi_map
 
virtual unsigned int n_shape_functions() const override
 
TypeVector< T > unit() const
 
std::vector< RealGradient > d2xyzdeta2_map
 
virtual unsigned int n_nodes() const =0
 
std::vector< RealGradient > d2xyzdxi2_map
 
TypeVector< typename CompareTypes< T, T2 >::supertype > cross(const TypeVector< T2 > &v) const
 
std::vector< Real > curvatures
 
std::vector< std::vector< Real > > d2psidxi2_map
 
std::vector< Point > normals
 
static Point map_eta(const Elem *elem, const Point &reference_point)
 
const Elem * neighbor_ptr(unsigned int i) const
 
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
 
Real dydeta_map(const unsigned int p) const
 
std::vector< std::vector< Real > > dpsidxi_map
 
std::vector< std::vector< Point > > tangents
 
std::vector< RealGradient > dxyzdeta_map
 
Real dxdxi_map(const unsigned int p) const
 
void determine_calculations()
 
Real dydxi_map(const unsigned int p) const
 
virtual void compute_face_map(int dim, const std::vector< Real > &qw, const Elem *side)
 
virtual std::unique_ptr< Elem > build_edge_ptr(const unsigned int i)=0
 
virtual Order default_order() const =0
 
virtual void edge_reinit(const Elem *elem, const unsigned int edge, const Real tolerance=TOLERANCE, const std::vector< Point > *const pts=nullptr, const std::vector< Real > *const weights=nullptr) override
 
virtual ElemType type() const =0
 
A geometric point in (x,y,z) space. 
 
dof_id_type node_id(const unsigned int i) const
 
const Point & point(const unsigned int i) const
 
static OutputShape shape_second_deriv(const ElemType t, const Order o, const unsigned int i, const unsigned int j, const Point &p)
 
void init_face_shape_functions(const std::vector< Point > &qp, const Elem *side)
 
static Point inverse_map(const Elem *elem, const Point &p, const Real tolerance=TOLERANCE, const bool secure=true)