libMesh
fe_abstract.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2024 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 
19 
20 #ifndef LIBMESH_FE_ABSTRACT_H
21 #define LIBMESH_FE_ABSTRACT_H
22 
23 // Local includes
24 #include "libmesh/reference_counted_object.h"
25 #include "libmesh/point.h"
26 #include "libmesh/vector_value.h"
27 #include "libmesh/fe_type.h"
28 #include "libmesh/fe_map.h"
29 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
30 #include "libmesh/tensor_value.h"
31 #endif
32 
33 // C++ includes
34 #include <cstddef>
35 #include <vector>
36 #include <memory>
37 
38 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
39 #define virtual_for_inffe virtual
40 #else
41 #define virtual_for_inffe
42 #endif
43 
44 
45 namespace libMesh
46 {
47 
48 
49 // forward declarations
50 template <typename T> class DenseMatrix;
51 template <typename T> class DenseVector;
52 class BoundaryInfo;
53 class DofConstraints;
54 class DofMap;
55 class Elem;
56 class MeshBase;
57 template <typename T> class NumericVector;
58 class QBase;
59 enum ElemType : int;
60 
61 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
62 class NodeConstraints;
63 #endif
64 
65 #ifdef LIBMESH_ENABLE_PERIODIC
66 class PeriodicBoundaries;
67 class PointLocatorBase;
68 #endif
69 
70 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
71 template <unsigned int Dim, FEFamily T_radial, InfMapType T_map>
72 class InfFE;
73 #endif
74 
75 
76 
99 class FEAbstract : public ReferenceCountedObject<FEAbstract>
100 {
101 protected:
102 
108  FEAbstract (const unsigned int dim,
109  const FEType & fet);
110 
111 public:
112 
116  virtual ~FEAbstract();
117 
124  static std::unique_ptr<FEAbstract> build (const unsigned int dim,
125  const FEType & type);
126 
141  virtual void reinit (const Elem * elem,
142  const std::vector<Point> * const pts = nullptr,
143  const std::vector<Real> * const weights = nullptr) = 0;
144 
150  virtual void reinit_dual_shape_coeffs (const Elem * /*elem*/,
151  const std::vector<Point> & /*pts*/,
152  const std::vector<Real> & /*JxW*/)
153  {
154  libmesh_error_msg("Customized dual shape coefficient calculation has not been implemented for this FE type.");
155  }
156 
161  virtual void reinit_default_dual_shape_coeffs (const Elem * /*elem*/)
162  {
163  libmesh_error_msg("Default dual shape coefficient calculation has not been implemented for this FE type.");
164  }
165 
174  virtual void reinit (const Elem * elem,
175  const unsigned int side,
176  const Real tolerance = TOLERANCE,
177  const std::vector<Point> * const pts = nullptr,
178  const std::vector<Real> * const weights = nullptr) = 0;
179 
188  virtual void edge_reinit (const Elem * elem,
189  const unsigned int edge,
190  const Real tolerance = TOLERANCE,
191  const std::vector<Point> * pts = nullptr,
192  const std::vector<Real> * weights = nullptr) = 0;
193 
198  virtual void side_map (const Elem * elem,
199  const Elem * side,
200  const unsigned int s,
201  const std::vector<Point> & reference_side_points,
202  std::vector<Point> & reference_points) = 0;
203 
211  static bool on_reference_element(const Point & p,
212  const ElemType t,
213  const Real eps = TOLERANCE);
218  static void get_refspace_nodes(const ElemType t,
219  std::vector<Point> & nodes);
220 
221 
222 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
223 
227  static void compute_node_constraints (NodeConstraints & constraints,
228  const Elem * elem);
229 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
230 
231 #ifdef LIBMESH_ENABLE_PERIODIC
232 
233 #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
234 
238  static void compute_periodic_node_constraints (NodeConstraints & constraints,
239  const PeriodicBoundaries & boundaries,
240  const MeshBase & mesh,
241  const PointLocatorBase * point_locator,
242  const Elem * elem);
243 #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
244 
245 #endif // LIBMESH_ENABLE_PERIODIC
246 
250  unsigned int get_dim() const
251  { return dim; }
252 
261  void get_nothing() const
262  { calculate_nothing = true; }
263 
271  virtual_for_inffe
272  const std::vector<Point> & get_xyz() const
273  { calculate_map = true; return this->_fe_map->get_xyz(); }
274 
275 
276 #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
277 
284  virtual const std::vector<Real> & get_JxWxdecay_sq () const
285  { return get_JxW();}
286 #endif
287 
294  virtual_for_inffe
295  const std::vector<Real> & get_JxW() const
296  { calculate_map = true; return this->_fe_map->get_JxW(); }
297 
302  virtual_for_inffe
303  const std::vector<RealGradient> & get_dxyzdxi() const
304  { calculate_map = true; return this->_fe_map->get_dxyzdxi(); }
305 
310  virtual_for_inffe
311  const std::vector<RealGradient> & get_dxyzdeta() const
312  { calculate_map = true; return this->_fe_map->get_dxyzdeta(); }
313 
318  virtual_for_inffe
319  const std::vector<RealGradient> & get_dxyzdzeta() const
320  { return _fe_map->get_dxyzdzeta(); }
321 
322 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
323 
327  virtual_for_inffe
328  const std::vector<RealGradient> & get_d2xyzdxi2() const
329  { calculate_map = true; return this->_fe_map->get_d2xyzdxi2(); }
330 
334  virtual_for_inffe
335  const std::vector<RealGradient> & get_d2xyzdeta2() const
336  { calculate_map = true; return this->_fe_map->get_d2xyzdeta2(); }
337 
341  virtual_for_inffe
342  const std::vector<RealGradient> & get_d2xyzdzeta2() const
343  { calculate_map = true; return this->_fe_map->get_d2xyzdzeta2(); }
344 
348  virtual_for_inffe
349  const std::vector<RealGradient> & get_d2xyzdxideta() const
350  { calculate_map = true; return this->_fe_map->get_d2xyzdxideta(); }
351 
355  virtual_for_inffe
356  const std::vector<RealGradient> & get_d2xyzdxidzeta() const
357  { calculate_map = true; return this->_fe_map->get_d2xyzdxidzeta(); }
358 
362  virtual_for_inffe
363  const std::vector<RealGradient> & get_d2xyzdetadzeta() const
364  { calculate_map = true; return this->_fe_map->get_d2xyzdetadzeta(); }
365 
366 #endif
367 
372  virtual_for_inffe
373  const std::vector<Real> & get_dxidx() const
374  { calculate_map = true; return this->_fe_map->get_dxidx(); }
375 
380  virtual_for_inffe
381  const std::vector<Real> & get_dxidy() const
382  { calculate_map = true; return this->_fe_map->get_dxidy(); }
383 
388  virtual_for_inffe
389  const std::vector<Real> & get_dxidz() const
390  { calculate_map = true; return this->_fe_map->get_dxidz(); }
391 
396  virtual_for_inffe
397  const std::vector<Real> & get_detadx() const
398  { calculate_map = true; return this->_fe_map->get_detadx(); }
399 
404  virtual_for_inffe
405  const std::vector<Real> & get_detady() const
406  { calculate_map = true; return this->_fe_map->get_detady(); }
407 
412  virtual_for_inffe
413  const std::vector<Real> & get_detadz() const
414  { calculate_map = true; return this->_fe_map->get_detadz(); }
415 
420  virtual_for_inffe
421  const std::vector<Real> & get_dzetadx() const
422  { calculate_map = true; return this->_fe_map->get_dzetadx(); }
423 
428  virtual_for_inffe
429  const std::vector<Real> & get_dzetady() const
430  { calculate_map = true; return this->_fe_map->get_dzetady(); }
431 
436  virtual_for_inffe
437  const std::vector<Real> & get_dzetadz() const
438  { calculate_map = true; return this->_fe_map->get_dzetadz(); }
439 
443  virtual_for_inffe
444  const std::vector<std::vector<Point>> & get_tangents() const
445  { calculate_map = true; return this->_fe_map->get_tangents(); }
446 
450  virtual_for_inffe
451  const std::vector<Point> & get_normals() const
452  { calculate_map = true; return this->_fe_map->get_normals(); }
453 
454 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
455 
458  virtual_for_inffe
459  const std::vector<Real> & get_curvatures() const
460  { calculate_map = true; return this->_fe_map->get_curvatures();}
461 
462 #endif
463 
468  virtual void attach_quadrature_rule (QBase * q) = 0;
469 
475  virtual unsigned int n_shape_functions () const = 0;
476 
481  virtual unsigned int n_quadrature_points () const = 0;
482 
488  ElemType get_type() const { return elem_type; }
489 
494  unsigned int get_p_level() const { return _p_level; }
495 
499  FEType get_fe_type() const { return fe_type; }
500 
504  Order get_order() const
505  { return static_cast<Order>(fe_type.order + _p_level); }
506 
510  void set_fe_order(int new_order) { fe_type.order = new_order; }
511 
515  virtual FEContinuity get_continuity() const = 0;
516 
521  virtual bool is_hierarchic() const = 0;
522 
526  FEFamily get_family() const { return fe_type.family; }
527 
533  const FEMap & get_fe_map() const { return *_fe_map.get(); }
534  FEMap & get_fe_map() { return *_fe_map.get(); }
535 
539  void print_JxW(std::ostream & os) const;
540 
546  virtual void print_phi(std::ostream & os) const =0;
547  virtual void print_dual_phi(std::ostream & os) const =0;
548 
554  virtual void print_dphi(std::ostream & os) const =0;
555  virtual void print_dual_dphi(std::ostream & os) const =0;
556 
557 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
558 
564  virtual void print_d2phi(std::ostream & os) const =0;
565  virtual void print_dual_d2phi(std::ostream & os) const =0;
566 
567 #endif
568 
573  void print_xyz(std::ostream & os) const;
574 
578  void print_info(std::ostream & os) const;
579 
583  friend std::ostream & operator << (std::ostream & os, const FEAbstract & fe);
584 
588  virtual void request_phi() const = 0;
589  virtual void request_dual_phi() const = 0;
590 
594  virtual void request_dphi() const = 0;
595  virtual void request_dual_dphi() const = 0;
596 
600  void set_calculate_dual(const bool val){calculate_dual = val; }
601 
606 
611 
616 
617 protected:
618 
631  virtual void compute_shape_functions(const Elem *, const std::vector<Point> & ) =0;
632 
633  std::unique_ptr<FEMap> _fe_map;
634 
635 
639  const unsigned int dim;
640 
645  mutable bool calculations_started;
646 
650  mutable bool calculate_dual;
651 
656 
660  mutable bool calculate_nothing;
661 
665  mutable bool calculate_map;
666 
670  mutable bool calculate_phi;
671 
675  mutable bool calculate_dphi;
676 
677 #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
678 
681  mutable bool calculate_d2phi;
682 #else
683  // Otherwise several interfaces need to be redone.
684  const bool calculate_d2phi=false;
685 
686 #endif
687 
691  mutable bool calculate_curl_phi;
692 
696  mutable bool calculate_div_phi;
697 
701  mutable bool calculate_dphiref;
702 
703 
710 
716 
726  unsigned int _elem_p_level;
727 
732  unsigned int _p_level;
733 
738 
744 
751  virtual bool shapes_need_reinit() const = 0;
752 
757 };
758 
759 } // namespace libMesh
760 
761 #endif // LIBMESH_FE_ABSTRACT_H
virtual void print_dual_phi(std::ostream &os) const =0
Order get_order() const
Definition: fe_abstract.h:504
bool calculate_d2phi
Should we calculate shape function hessians?
Definition: fe_abstract.h:681
bool calculate_curl_phi
Should we calculate shape function curls?
Definition: fe_abstract.h:691
class FEType hides (possibly multiple) FEFamily and approximation orders, thereby enabling specialize...
Definition: fe_type.h:182
FEFamily family
The type of finite element.
Definition: fe_type.h:207
virtual bool is_hierarchic() const =0
ElemType
Defines an enum for geometric element types.
virtual void print_phi(std::ostream &os) const =0
Prints the value of each shape function at each quadrature point.
void set_calculate_dual(const bool val)
set calculate_dual as needed
Definition: fe_abstract.h:600
unsigned int get_p_level() const
Definition: fe_abstract.h:494
bool calculations_started
Have calculations with this object already been started? Then all get_* functions should already have...
Definition: fe_abstract.h:645
Order
defines an enum for polynomial orders.
Definition: enum_order.h:40
bool calculate_phi
Should we calculate shape functions?
Definition: fe_abstract.h:670
virtual void reinit_default_dual_shape_coeffs(const Elem *)
This re-computes the dual shape function coefficients using DEFAULT qrule.
Definition: fe_abstract.h:161
unsigned int _p_level
The p refinement level the current data structures are set up for.
Definition: fe_abstract.h:732
virtual_for_inffe const std::vector< RealGradient > & get_d2xyzdetadzeta() const
Definition: fe_abstract.h:363
bool shapes_on_quadrature
A flag indicating if current data structures correspond to quadrature rule points.
Definition: fe_abstract.h:743
static void compute_node_constraints(NodeConstraints &constraints, const Elem *elem)
Computes the nodal constraint contributions (for non-conforming adapted meshes), using Lagrange geome...
Definition: fe_abstract.C:845
virtual_for_inffe const std::vector< Real > & get_curvatures() const
Definition: fe_abstract.h:459
virtual_for_inffe const std::vector< RealGradient > & get_dxyzdeta() const
Definition: fe_abstract.h:311
unsigned int get_dim() const
Definition: fe_abstract.h:250
ElemType get_type() const
Definition: fe_abstract.h:488
virtual_for_inffe const std::vector< RealGradient > & get_d2xyzdxi2() const
Definition: fe_abstract.h:328
static constexpr Real TOLERANCE
virtual_for_inffe const std::vector< Real > & get_dxidz() const
Definition: fe_abstract.h:389
We&#39;re using a class instead of a typedef to allow forward declarations and future flexibility...
unsigned int _elem_p_level
The element p-refinement level the current data structures are set up for.
Definition: fe_abstract.h:726
virtual_for_inffe const std::vector< RealGradient > & get_dxyzdzeta() const
Definition: fe_abstract.h:319
virtual void request_dual_dphi() const =0
This is the base class from which all geometric element types are derived.
Definition: elem.h:94
MeshBase & mesh
virtual unsigned int n_quadrature_points() const =0
FEAbstract(const unsigned int dim, const FEType &fet)
Constructor.
Definition: fe_abstract.C:48
virtual_for_inffe const std::vector< RealGradient > & get_d2xyzdxideta() const
Definition: fe_abstract.h:349
The Node constraint storage format.
Definition: dof_map.h:146
virtual void request_dual_phi() const =0
OrderWrapper order
The approximation order of the element.
Definition: fe_type.h:201
bool calculate_default_dual_coeff
Are we calculating the coefficient for the dual basis using the default qrule?
Definition: fe_abstract.h:655
The libMesh namespace provides an interface to certain functionality in the library.
virtual_for_inffe const std::vector< std::vector< Point > > & get_tangents() const
Definition: fe_abstract.h:444
bool calculate_div_phi
Should we calculate shape function divergences?
Definition: fe_abstract.h:696
virtual_for_inffe const std::vector< RealGradient > & get_d2xyzdeta2() const
Definition: fe_abstract.h:335
virtual void request_phi() const =0
request phi calculations
static bool on_reference_element(const Point &p, const ElemType t, const Real eps=TOLERANCE)
Definition: fe_abstract.C:601
This is the MeshBase class.
Definition: mesh_base.h:74
virtual_for_inffe const std::vector< Real > & get_dxidy() const
Definition: fe_abstract.h:381
virtual FEContinuity get_continuity() const =0
virtual void print_dual_d2phi(std::ostream &os) const =0
FEType get_fe_type() const
Definition: fe_abstract.h:499
virtual_for_inffe const std::vector< Real > & get_detadz() const
Definition: fe_abstract.h:413
virtual_for_inffe const std::vector< RealGradient > & get_d2xyzdzeta2() const
Definition: fe_abstract.h:342
virtual unsigned int n_shape_functions() const =0
virtual void print_dphi(std::ostream &os) const =0
Prints the value of each shape function&#39;s derivative at each quadrature point.
const unsigned int dim
The dimensionality of the object.
Definition: fe_abstract.h:639
void print_xyz(std::ostream &os) const
Prints the spatial location of each quadrature point (on the physical element).
Definition: fe_abstract.C:812
virtual_for_inffe const std::vector< RealGradient > & get_d2xyzdxidzeta() const
Definition: fe_abstract.h:356
virtual const std::vector< Real > & get_JxWxdecay_sq() const
This function is the variant of get_JxW() for InfFE.
Definition: fe_abstract.h:284
static void get_refspace_nodes(const ElemType t, std::vector< Point > &nodes)
Definition: fe_abstract.C:373
void add_p_level_in_reinit(bool value)
Indicate whether to add p-refinement levels in init/reinit methods.
Definition: fe_abstract.h:610
virtual_for_inffe const std::vector< Real > & get_JxW() const
Definition: fe_abstract.h:295
virtual void reinit(const Elem *elem, const std::vector< Point > *const pts=nullptr, const std::vector< Real > *const weights=nullptr)=0
This is at the core of this class.
virtual bool shapes_need_reinit() const =0
QBase * qrule
A pointer to the quadrature rule employed.
Definition: fe_abstract.h:737
virtual_for_inffe const std::vector< Point > & get_xyz() const
Definition: fe_abstract.h:272
This is the base class for point locators.
virtual_for_inffe const std::vector< Real > & get_detadx() const
Definition: fe_abstract.h:397
This class implements reference counting.
void get_nothing() const
Definition: fe_abstract.h:261
bool calculate_dphiref
Should we calculate reference shape function gradients?
Definition: fe_abstract.h:701
virtual_for_inffe const std::vector< Real > & get_detady() const
Definition: fe_abstract.h:405
void print_JxW(std::ostream &os) const
Prints the Jacobian times the weight for each quadrature point.
Definition: fe_abstract.C:805
void print_info(std::ostream &os) const
Prints all the relevant information about the current element.
Definition: fe_abstract.C:818
virtual void request_dphi() const =0
request dphi calculations
bool _add_p_level_in_reinit
Whether to add p-refinement levels in init/reinit methods.
Definition: fe_abstract.h:756
virtual void edge_reinit(const Elem *elem, const unsigned int edge, const Real tolerance=TOLERANCE, const std::vector< Point > *pts=nullptr, const std::vector< Real > *weights=nullptr)=0
Reinitializes all the physical element-dependent data based on the edge of the element elem...
void set_calculate_default_dual_coeff(const bool val)
set calculate_default_dual_coeff as needed
Definition: fe_abstract.h:605
virtual void compute_shape_functions(const Elem *, const std::vector< Point > &)=0
After having updated the jacobian and the transformation from local to global coordinates in FEMap::c...
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual_for_inffe const std::vector< Point > & get_normals() const
Definition: fe_abstract.h:451
bool calculate_dphi
Should we calculate shape function gradients?
Definition: fe_abstract.h:675
bool calculate_map
Are we calculating mapping functions?
Definition: fe_abstract.h:665
FEMap & get_fe_map()
Definition: fe_abstract.h:534
FEContinuity
defines an enum for finite element types to libmesh_assert a certain level (or type? Hcurl?) of continuity.
virtual_for_inffe const std::vector< Real > & get_dxidx() const
Definition: fe_abstract.h:373
virtual_for_inffe const std::vector< Real > & get_dzetady() const
Definition: fe_abstract.h:429
virtual_for_inffe const std::vector< Real > & get_dzetadz() const
Definition: fe_abstract.h:437
static const bool value
Definition: xdr_io.C:54
static std::unique_ptr< FEAbstract > build(const unsigned int dim, const FEType &type)
Builds a specific finite element type.
Definition: fe_abstract.C:77
FEFamily get_family() const
Definition: fe_abstract.h:526
virtual void print_dual_dphi(std::ostream &os) const =0
friend std::ostream & operator<<(std::ostream &os, const FEAbstract &fe)
Same as above, but allows you to print to a stream.
Definition: fe_abstract.C:834
virtual ~FEAbstract()
Destructor.
virtual void reinit_dual_shape_coeffs(const Elem *, const std::vector< Point > &, const std::vector< Real > &)
This re-computes the dual shape function coefficients using CUSTOMIZED qrule.
Definition: fe_abstract.h:150
void set_fe_order(int new_order)
Sets the base FE order of the finite element.
Definition: fe_abstract.h:510
virtual_for_inffe const std::vector< Real > & get_dzetadx() const
Definition: fe_abstract.h:421
virtual void print_d2phi(std::ostream &os) const =0
Prints the value of each shape function&#39;s second derivatives at each quadrature point.
virtual_for_inffe const std::vector< RealGradient > & get_dxyzdxi() const
Definition: fe_abstract.h:303
const FEMap & get_fe_map() const
Definition: fe_abstract.h:533
FEFamily
defines an enum for finite element families.
This class forms the foundation from which generic finite elements may be derived.
Definition: fe_abstract.h:99
FEType fe_type
The finite element type for this object.
Definition: fe_abstract.h:709
std::unique_ptr< FEMap > _fe_map
Definition: fe_abstract.h:633
bool calculate_dual
Are we calculating dual basis?
Definition: fe_abstract.h:650
Class contained in FE that encapsulates mapping (i.e.
Definition: fe_map.h:47
ElemType elem_type
The element type the current data structures are set up for.
Definition: fe_abstract.h:715
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
virtual void attach_quadrature_rule(QBase *q)=0
Provides the class with the quadrature rule.
The QBase class provides the basic functionality from which various quadrature rules can be derived...
Definition: quadrature.h:53
void ErrorVector unsigned int
Definition: adjoints_ex3.C:360
bool calculate_nothing
Are we potentially deliberately calculating nothing?
Definition: fe_abstract.h:660
static void compute_periodic_node_constraints(NodeConstraints &constraints, const PeriodicBoundaries &boundaries, const MeshBase &mesh, const PointLocatorBase *point_locator, const Elem *elem)
Computes the node position constraint equation contributions (for meshes with periodic boundary condi...
Definition: fe_abstract.C:1037
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)=0
Computes the reference space quadrature points on the side of an element based on the side quadrature...
bool add_p_level_in_reinit() const
Whether to add p-refinement levels in init/reinit methods.
Definition: fe_abstract.h:615