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)