LCOV - code coverage report
Current view: top level - include/fe - fe_abstract.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 48 68 70.6 %
Date: 2025-08-19 19:27:09 Functions: 29 40 72.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2025 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             : 
      77             : /**
      78             :  * This class forms the foundation from which generic finite elements
      79             :  * may be derived.  In the current implementation, the templated
      80             :  * derived class \p FE offers a wide variety of commonly used finite
      81             :  * element concepts.  Check there for details.  Use the \p
      82             :  * FEAbstract::build() method to create an object of any of the
      83             :  * derived classes.
      84             :  *
      85             :  * \note In the present design, the number of virtual members is kept
      86             :  * to a minimum for performance reasons, although this is not based on
      87             :  * rigorous profiling.
      88             :  *
      89             :  * All calls to static members of the \p FE classes should be
      90             :  * requested through the \p FEInterface.  This interface class
      91             :  * approximates runtime polymorphism for the templated finite element
      92             :  * classes.  Even internal library classes, like \p DofMap, request
      93             :  * the number of DOFs through this interface class.  This approach
      94             :  * also enables the co-existence of various element-based schemes.
      95             :  *
      96             :  * \author Benjamin S. Kirk
      97             :  * \date 2002
      98             :  */
      99     1738687 : class FEAbstract : public ReferenceCountedObject<FEAbstract>
     100             : {
     101             : protected:
     102             : 
     103             :   /**
     104             :    * Constructor.  Optionally initializes required data
     105             :    * structures.  Protected so that this base class
     106             :    * cannot be explicitly instantiated.
     107             :    */
     108             :   FEAbstract (const unsigned int dim,
     109             :               const FEType & fet);
     110             : 
     111             : public:
     112             : 
     113             :   /**
     114             :    * Destructor.
     115             :    */
     116             :   virtual ~FEAbstract();
     117             : 
     118             :   /**
     119             :    * Builds a specific finite element type.
     120             :    *
     121             :    * \returns A std::unique_ptr<FEAbstract> to the FE object to prevent
     122             :    * memory leaks.
     123             :    */
     124             :   static std::unique_ptr<FEAbstract> build (const unsigned int dim,
     125             :                                             const FEType & type);
     126             : 
     127             :   /**
     128             :    * This is at the core of this class. Use this for each
     129             :    * new element in the mesh.  Reinitializes the requested physical
     130             :    * element-dependent data based on the current element
     131             :    * \p elem. By default the element data are computed at the quadrature
     132             :    * points specified by the quadrature rule \p qrule, but any set
     133             :    * of points on the reference element may be specified in the optional
     134             :    * argument \p pts.
     135             :    *
     136             :    * \note The FE classes decide which data to initialize based on
     137             :    * which accessor functions such as \p get_phi() or \p get_d2phi()
     138             :    * have been called, so all such accessors should be called before
     139             :    * the first \p reinit().
     140             :    */
     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             : 
     145             :   /**
     146             :    * This re-computes the dual shape function coefficients using CUSTOMIZED qrule.
     147             :    * The dual shape coefficients are utilized when calculating dual shape functions.
     148             :    * This has not been implemented for InfFE
     149             :    */
     150           0 :   virtual void reinit_dual_shape_coeffs (const Elem * /*elem*/,
     151             :                                          const std::vector<Point> & /*pts*/,
     152             :                                          const std::vector<Real> & /*JxW*/)
     153             :   {
     154           0 :     libmesh_error_msg("Customized dual shape coefficient calculation has not been implemented for this FE type.");
     155             :   }
     156             : 
     157             :   /**
     158             :    * This re-computes the dual shape function coefficients using DEFAULT qrule.
     159             :    * This has not been implemented for InfFE
     160             :    */
     161           0 :   virtual void reinit_default_dual_shape_coeffs (const Elem * /*elem*/)
     162             :   {
     163           0 :     libmesh_error_msg("Default dual shape coefficient calculation has not been implemented for this FE type.");
     164             :   }
     165             : 
     166             :   /**
     167             :    * Reinitializes all the physical element-dependent data based on
     168             :    * the \p side of the element \p elem.  The \p tolerance parameter
     169             :    * is passed to the involved call to \p inverse_map().  By default the
     170             :    * element data are computed at the quadrature points specified by the
     171             :    * quadrature rule \p qrule, but any set of points on the reference
     172             :    * \em side element may be specified in the optional argument \p pts.
     173             :    */
     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             : 
     180             :   /**
     181             :    * Reinitializes all the physical element-dependent data based on
     182             :    * the \p edge of the element \p elem.  The \p tolerance parameter
     183             :    * is passed to the involved call to \p inverse_map().  By default the
     184             :    * element data are computed at the quadrature points specified by the
     185             :    * quadrature rule \p qrule, but any set of points on the reference
     186             :    * \em edge element may be specified in the optional argument \p pts.
     187             :    */
     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             : 
     194             :   /**
     195             :    * Computes the reference space quadrature points on the side of
     196             :    * an element based on the side quadrature points.
     197             :    */
     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             : 
     204             : #ifdef LIBMESH_ENABLE_DEPRECATED
     205             :   /**
     206             :    * \returns \p true if the point p is located on the reference element
     207             :    * for element type t, false otherwise.  Since we are doing floating
     208             :    * point comparisons here the parameter \p eps can be specified to
     209             :    * indicate a tolerance.  For example, \f$ x \le 1 \f$  becomes
     210             :    * \f$ x \le 1 + \epsilon \f$.
     211             :    *
     212             :    * \deprecated This method overload does not support all finite
     213             :    * element types; e.g. the reference element for an arbitrary
     214             :    * polygon or polyhedron type may differ from element to element.
     215             :    * Use \p Elem::on_reference_element() instead.
     216             :    */
     217             :   static bool on_reference_element(const Point & p,
     218             :                                    const ElemType t,
     219             :                                    const Real eps = TOLERANCE);
     220             : #endif // LIBMESH_ENABLE_DEPRECATED
     221             : 
     222             :   /**
     223             :    * \returns The reference space coordinates of \p nodes based on the
     224             :    * element type.
     225             :    */
     226             :   static void get_refspace_nodes(const ElemType t,
     227             :                                  std::vector<Point> & nodes);
     228             : 
     229             : 
     230             : #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
     231             :   /**
     232             :    * Computes the nodal constraint contributions (for
     233             :    * non-conforming adapted meshes), using Lagrange geometry
     234             :    */
     235             :   static void compute_node_constraints (NodeConstraints & constraints,
     236             :                                         const Elem * elem);
     237             : #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
     238             : 
     239             : #ifdef LIBMESH_ENABLE_PERIODIC
     240             : 
     241             : #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
     242             :   /**
     243             :    * Computes the node position constraint equation contributions (for
     244             :    * meshes with periodic boundary conditions)
     245             :    */
     246             :   static void compute_periodic_node_constraints (NodeConstraints & constraints,
     247             :                                                  const PeriodicBoundaries & boundaries,
     248             :                                                  const MeshBase & mesh,
     249             :                                                  const PointLocatorBase * point_locator,
     250             :                                                  const Elem * elem);
     251             : #endif // LIBMESH_ENABLE_NODE_CONSTRAINTS
     252             : 
     253             : #endif // LIBMESH_ENABLE_PERIODIC
     254             : 
     255             :   /**
     256             :    * \returns the dimension of this FE
     257             :    */
     258      376976 :   unsigned int get_dim() const
     259     4122910 :   { return dim; }
     260             : 
     261             :   /**
     262             :    * \returns nothing, but lets the FE know you're explicitly
     263             :    * prerequesting calculations.  This is useful when you only want
     264             :    * the FE for n_quadrature_points, n_dofs_on_side, or other methods
     265             :    * that don't require shape function calculations, but you don't
     266             :    * want libMesh "backwards compatibility" mode to assume you've made
     267             :    * no prerequests and need to calculate everything.
     268             :    */
     269        3190 :   void get_nothing() const
     270     1140494 :   { calculate_nothing = true; }
     271             : 
     272             :   /**
     273             :    * \returns The \p xyz spatial locations of the quadrature
     274             :    * points on the element.
     275             :    *
     276             :    * It is overwritten by infinite elements since there
     277             :    * \p FEMap cannot be used to compute \p xyz.
     278             :    */
     279             :   virtual_for_inffe
     280     2578587 :   const std::vector<Point> & get_xyz() const
     281     9208048 :   { calculate_map = true; return this->_fe_map->get_xyz(); }
     282             : 
     283             : 
     284             : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
     285             :   /**
     286             :    * This function is the variant of \p get_JxW() for \p InfFE.
     287             :    * Since J diverges there, a respectize decay-function must be
     288             :    * applied to obtain well-defined quantities.
     289             :    *
     290             :    * For FE, it is equivalent to the common \p get_JxW().
     291             :    */
     292        1344 :   virtual const std::vector<Real> & get_JxWxdecay_sq () const
     293        1344 :   { return get_JxW();}
     294             : #endif
     295             : 
     296             :   /**
     297             :    * \returns The element Jacobian times the quadrature weight for
     298             :    * each quadrature point.
     299             :    *
     300             :    * For \p InfFE, use \p get_JxWxdecay_sq() instead.
     301             :    */
     302             :   virtual_for_inffe
     303    12087941 :   const std::vector<Real> & get_JxW() const
     304    49031076 :   { calculate_map = true; return this->_fe_map->get_JxW(); }
     305             : 
     306             :   /**
     307             :    * \returns The element tangents in xi-direction at the quadrature
     308             :    * points.
     309             :    */
     310             :   virtual_for_inffe
     311          14 :   const std::vector<RealGradient> & get_dxyzdxi() const
     312          18 :   { calculate_map = true; return this->_fe_map->get_dxyzdxi(); }
     313             : 
     314             :   /**
     315             :    * \returns The element tangents in eta-direction at the quadrature
     316             :    * points.
     317             :    */
     318             :   virtual_for_inffe
     319          14 :   const std::vector<RealGradient> & get_dxyzdeta() const
     320          18 :   { calculate_map = true; return this->_fe_map->get_dxyzdeta(); }
     321             : 
     322             :   /**
     323             :    * \returns The element tangents in zeta-direction at the quadrature
     324             :    * points.
     325             :    */
     326             :   virtual_for_inffe
     327           0 :   const std::vector<RealGradient> & get_dxyzdzeta() const
     328           0 :   { return _fe_map->get_dxyzdzeta(); }
     329             : 
     330             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     331             : 
     332             :   /**
     333             :    * \returns The second partial derivatives in xi.
     334             :    */
     335             :   virtual_for_inffe
     336          14 :   const std::vector<RealGradient> & get_d2xyzdxi2() const
     337          18 :   { calculate_map = true; return this->_fe_map->get_d2xyzdxi2(); }
     338             : 
     339             :   /**
     340             :    * \returns The second partial derivatives in eta.
     341             :    */
     342             :   virtual_for_inffe
     343          10 :   const std::vector<RealGradient> & get_d2xyzdeta2() const
     344          10 :   { calculate_map = true; return this->_fe_map->get_d2xyzdeta2(); }
     345             : 
     346             :   /**
     347             :    * \returns The second partial derivatives in zeta.
     348             :    */
     349             :   virtual_for_inffe
     350           0 :   const std::vector<RealGradient> & get_d2xyzdzeta2() const
     351           0 :   { calculate_map = true; return this->_fe_map->get_d2xyzdzeta2(); }
     352             : 
     353             :   /**
     354             :    * \returns The second partial derivatives in xi-eta.
     355             :    */
     356             :   virtual_for_inffe
     357          10 :   const std::vector<RealGradient> & get_d2xyzdxideta() const
     358          10 :   { calculate_map = true; return this->_fe_map->get_d2xyzdxideta(); }
     359             : 
     360             :   /**
     361             :    * \returns The second partial derivatives in xi-zeta.
     362             :    */
     363             :   virtual_for_inffe
     364           0 :   const std::vector<RealGradient> & get_d2xyzdxidzeta() const
     365           0 :   { calculate_map = true; return this->_fe_map->get_d2xyzdxidzeta(); }
     366             : 
     367             :   /**
     368             :    * \returns The second partial derivatives in eta-zeta.
     369             :    */
     370             :   virtual_for_inffe
     371           0 :   const std::vector<RealGradient> & get_d2xyzdetadzeta() const
     372           0 :   { calculate_map = true; return this->_fe_map->get_d2xyzdetadzeta(); }
     373             : 
     374             : #endif
     375             : 
     376             :   /**
     377             :    * \returns The dxi/dx entry in the transformation
     378             :    * matrix from physical to local coordinates.
     379             :    */
     380             :   virtual_for_inffe
     381        2659 :   const std::vector<Real> & get_dxidx() const
     382        3537 :   { calculate_map = true; return this->_fe_map->get_dxidx(); }
     383             : 
     384             :   /**
     385             :    * \returns The dxi/dy entry in the transformation
     386             :    * matrix from physical to local coordinates.
     387             :    */
     388             :   virtual_for_inffe
     389        2659 :   const std::vector<Real> & get_dxidy() const
     390        3537 :   { calculate_map = true; return this->_fe_map->get_dxidy(); }
     391             : 
     392             :   /**
     393             :    * \returns The dxi/dz entry in the transformation
     394             :    * matrix from physical to local coordinates.
     395             :    */
     396             :   virtual_for_inffe
     397        2659 :   const std::vector<Real> & get_dxidz() const
     398        3537 :   { calculate_map = true; return this->_fe_map->get_dxidz(); }
     399             : 
     400             :   /**
     401             :    * \returns The deta/dx entry in the transformation
     402             :    * matrix from physical to local coordinates.
     403             :    */
     404             :   virtual_for_inffe
     405        2659 :   const std::vector<Real> & get_detadx() const
     406        3537 :   { calculate_map = true; return this->_fe_map->get_detadx(); }
     407             : 
     408             :   /**
     409             :    * \returns The deta/dy entry in the transformation
     410             :    * matrix from physical to local coordinates.
     411             :    */
     412             :   virtual_for_inffe
     413        2659 :   const std::vector<Real> & get_detady() const
     414        3537 :   { calculate_map = true; return this->_fe_map->get_detady(); }
     415             : 
     416             :   /**
     417             :    * \returns The deta/dz entry in the transformation
     418             :    * matrix from physical to local coordinates.
     419             :    */
     420             :   virtual_for_inffe
     421        2659 :   const std::vector<Real> & get_detadz() const
     422        3537 :   { calculate_map = true; return this->_fe_map->get_detadz(); }
     423             : 
     424             :   /**
     425             :    * \returns The dzeta/dx entry in the transformation
     426             :    * matrix from physical to local coordinates.
     427             :    */
     428             :   virtual_for_inffe
     429           0 :   const std::vector<Real> & get_dzetadx() const
     430           0 :   { calculate_map = true; return this->_fe_map->get_dzetadx(); }
     431             : 
     432             :   /**
     433             :    * \returns The dzeta/dy entry in the transformation
     434             :    * matrix from physical to local coordinates.
     435             :    */
     436             :   virtual_for_inffe
     437           0 :   const std::vector<Real> & get_dzetady() const
     438           0 :   { calculate_map = true; return this->_fe_map->get_dzetady(); }
     439             : 
     440             :   /**
     441             :    * \returns The dzeta/dz entry in the transformation
     442             :    * matrix from physical to local coordinates.
     443             :    */
     444             :   virtual_for_inffe
     445           0 :   const std::vector<Real> & get_dzetadz() const
     446           0 :   { calculate_map = true; return this->_fe_map->get_dzetadz(); }
     447             : 
     448             :   /**
     449             :    * \returns The tangent vectors for face integration.
     450             :    */
     451             :   virtual_for_inffe
     452           2 :   const std::vector<std::vector<Point>> & get_tangents() const
     453           2 :   { calculate_map = true; return this->_fe_map->get_tangents(); }
     454             : 
     455             :   /**
     456             :    * \returns The outward pointing normal vectors for face integration.
     457             :    */
     458             :   virtual_for_inffe
     459      669158 :   const std::vector<Point> & get_normals() const
     460      951616 :   { calculate_map = true; return this->_fe_map->get_normals(); }
     461             : 
     462             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     463             :   /**
     464             :    * \returns The curvatures for use in face integration.
     465             :    */
     466             :   virtual_for_inffe
     467           0 :   const std::vector<Real> & get_curvatures() const
     468           0 :   { calculate_map = true; return this->_fe_map->get_curvatures();}
     469             : 
     470             : #endif
     471             : 
     472             :   /**
     473             :    * Provides the class with the quadrature rule.  Implement
     474             :    * this in derived classes.
     475             :    */
     476             :   virtual void attach_quadrature_rule (QBase * q) = 0;
     477             : 
     478             :   /**
     479             :    * \returns The total number of approximation shape functions
     480             :    * for the current element.  Useful during matrix assembly.
     481             :    * Implement this in derived classes.
     482             :    */
     483             :   virtual unsigned int n_shape_functions () const = 0;
     484             : 
     485             :   /**
     486             :    * \returns The total number of quadrature points with which this
     487             :    * was last reinitialized.  Useful during matrix assembly.
     488             :    */
     489             :   virtual unsigned int n_quadrature_points () const;
     490             : 
     491             :   /**
     492             :    * \returns The element that the current shape functions have been
     493             :    * calculated for.  Useful in determining when shape functions must
     494             :    * be recomputed.
     495             :    */
     496             :   const Elem * get_elem()  const { return _elem; }
     497             : 
     498             :   /**
     499             :    * \returns The element type that the current shape functions
     500             :    * have been calculated for, or \p INVALID_ELEM if no such element
     501             :    * exists.  Useful in determining when shape functions must be
     502             :    * recomputed.
     503             :    *
     504             :    * This is generally redundant with _elem->type(), but must be
     505             :    * cached separately for cases (such as internal FE use in
     506             :    * QComposite) where _elem might be a dangling pointer to a
     507             :    * temporary.
     508             :    */
     509   132150294 :   ElemType get_type() const { return _elem_type; }
     510             : 
     511             :   /**
     512             :    * \returns The p refinement level that the current shape
     513             :    * functions have been calculated for.
     514             :    */
     515             :   unsigned int get_p_level() const { return _p_level; }
     516             : 
     517             :   /**
     518             :    * \returns The FE Type (approximation order and family) of the finite element.
     519             :    */
     520   244546265 :   FEType get_fe_type()  const { return fe_type; }
     521             : 
     522             :   /**
     523             :    * \returns The approximation order of the finite element.
     524             :    */
     525     3663995 :   Order get_order() const
     526    47882383 :   { return fe_type.order + _p_level; }
     527             : 
     528             :   /**
     529             :    * Sets the *base* FE order of the finite element.
     530             :    */
     531       29590 :   void set_fe_order(int new_order) { fe_type.order = new_order; }
     532             : 
     533             :   /**
     534             :    * \returns The continuity level of the finite element.
     535             :    */
     536             :   virtual FEContinuity get_continuity() const = 0;
     537             : 
     538             :   /**
     539             :    * \returns \p true if the finite element's higher order shape functions are
     540             :    * hierarchic
     541             :    */
     542             :   virtual bool is_hierarchic() const = 0;
     543             : 
     544             :   /**
     545             :    * \returns The finite element family of this element.
     546             :    */
     547      614477 :   FEFamily get_family()  const { return fe_type.family; }
     548             : 
     549             :   /**
     550             :    * \returns The mapping object
     551             :    *
     552             :    * \note for InfFE, this gives a useless object.
     553             :    */
     554    81695088 :   const FEMap & get_fe_map() const { return *_fe_map.get(); }
     555       17936 :   FEMap & get_fe_map() { return *_fe_map.get(); }
     556             : 
     557             :   /**
     558             :    * Prints the Jacobian times the weight for each quadrature point.
     559             :    */
     560             :   void print_JxW(std::ostream & os) const;
     561             : 
     562             :   /**
     563             :    * Prints the value of each shape function at each quadrature point.
     564             :    * Implement in derived class since this depends on whether the element
     565             :    * is vector-valued or not.
     566             :    */
     567             :   virtual void print_phi(std::ostream & os) const =0;
     568             :   virtual void print_dual_phi(std::ostream & os) const =0;
     569             : 
     570             :   /**
     571             :    * Prints the value of each shape function's derivative
     572             :    * at each quadrature point. Implement in derived class since this
     573             :    * depends on whether the element is vector-valued or not.
     574             :    */
     575             :   virtual void print_dphi(std::ostream & os) const =0;
     576             :   virtual void print_dual_dphi(std::ostream & os) const =0;
     577             : 
     578             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     579             : 
     580             :   /**
     581             :    * Prints the value of each shape function's second derivatives
     582             :    * at each quadrature point. Implement in derived class since this
     583             :    * depends on whether the element is vector-valued or not.
     584             :    */
     585             :   virtual void print_d2phi(std::ostream & os) const =0;
     586             :   virtual void print_dual_d2phi(std::ostream & os) const =0;
     587             : 
     588             : #endif
     589             : 
     590             :   /**
     591             :    * Prints the spatial location of each quadrature point
     592             :    * (on the physical element).
     593             :    */
     594             :   void print_xyz(std::ostream & os) const;
     595             : 
     596             :   /**
     597             :    * Prints all the relevant information about the current element.
     598             :    */
     599             :   void print_info(std::ostream & os) const;
     600             : 
     601             :   /**
     602             :    * Same as above, but allows you to print to a stream.
     603             :    */
     604             :   friend std::ostream & operator << (std::ostream & os, const FEAbstract & fe);
     605             : 
     606             :   /**
     607             :    * request phi calculations
     608             :    */
     609             :   virtual void request_phi() const = 0;
     610             :   virtual void request_dual_phi() const = 0;
     611             : 
     612             :   /**
     613             :    * request dphi calculations
     614             :    */
     615             :   virtual void request_dphi() const = 0;
     616             :   virtual void request_dual_dphi() const = 0;
     617             : 
     618             :   /**
     619             :    * set calculate_dual as needed
     620             :    */
     621             :   void set_calculate_dual(const bool val){calculate_dual = val; }
     622             : 
     623             :   /**
     624             :    * set calculate_default_dual_coeff as needed
     625             :    */
     626        6348 :   void set_calculate_default_dual_coeff(const bool val){calculate_default_dual_coeff = val; }
     627             : 
     628             :   /**
     629             :    * Indicate whether to add p-refinement levels in init/reinit methods
     630             :    */
     631    15297148 :   void add_p_level_in_reinit(bool value) { _add_p_level_in_reinit = value; }
     632             : 
     633             :   /**
     634             :    * Whether to add p-refinement levels in init/reinit methods
     635             :    */
     636     4183357 :   bool add_p_level_in_reinit() const { return _add_p_level_in_reinit; }
     637             : 
     638             : protected:
     639             : 
     640             :   /**
     641             :    * After having updated the jacobian and the transformation
     642             :    * from local to global coordinates in \p FEMap::compute_map(),
     643             :    * the first derivatives of the shape functions are
     644             :    * transformed to global coordinates, giving \p dphi,
     645             :    * \p dphidx, \p dphidy, and \p dphidz. This method
     646             :    * should rarely be re-defined in derived classes, but
     647             :    * still should be usable for children. Therefore, keep
     648             :    * it protected. This needs to be implemented in the
     649             :    * derived class since this function depends on whether
     650             :    * the shape functions are vector-valued or not.
     651             :    */
     652             :   virtual void compute_shape_functions(const Elem *, const std::vector<Point> & ) =0;
     653             : 
     654             :   std::unique_ptr<FEMap> _fe_map;
     655             : 
     656             : 
     657             :   /**
     658             :    * The dimensionality of the object
     659             :    */
     660             :   const unsigned int dim;
     661             : 
     662             :   /**
     663             :    * Have calculations with this object already been started?
     664             :    * Then all get_* functions should already have been called.
     665             :    */
     666             :   mutable bool calculations_started;
     667             : 
     668             :   /**
     669             :    * Are we calculating dual basis?
     670             :    */
     671             :   mutable bool calculate_dual;
     672             : 
     673             :   /**
     674             :    * Are we calculating the coefficient for the dual basis using the default qrule?
     675             :    */
     676             :   mutable bool calculate_default_dual_coeff;
     677             : 
     678             :   /**
     679             :    * Are we potentially deliberately calculating nothing?
     680             :    */
     681             :   mutable bool calculate_nothing;
     682             : 
     683             :   /**
     684             :    * Are we calculating mapping functions?
     685             :    */
     686             :   mutable bool calculate_map;
     687             : 
     688             :   /**
     689             :    * Should we calculate shape functions?
     690             :    */
     691             :   mutable bool calculate_phi;
     692             : 
     693             :   /**
     694             :    * Should we calculate shape function gradients?
     695             :    */
     696             :   mutable bool calculate_dphi;
     697             : 
     698             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     699             :   /**
     700             :    * Should we calculate shape function hessians?
     701             :    */
     702             :   mutable bool calculate_d2phi;
     703             : #else
     704             :   // Otherwise several interfaces need to be redone.
     705             :   const bool calculate_d2phi=false;
     706             : 
     707             : #endif
     708             : 
     709             :   /**
     710             :    * Should we calculate shape function curls?
     711             :    */
     712             :   mutable bool calculate_curl_phi;
     713             : 
     714             :   /**
     715             :    * Should we calculate shape function divergences?
     716             :    */
     717             :   mutable bool calculate_div_phi;
     718             : 
     719             :   /**
     720             :    * Should we calculate reference shape function gradients?
     721             :    */
     722             :   mutable bool calculate_dphiref;
     723             : 
     724             : 
     725             :   /**
     726             :    * The finite element type for this object.
     727             :    *
     728             :    * \note This should be constant for the object.
     729             :    */
     730             :   FEType fe_type;
     731             : 
     732             :   /**
     733             :    * The element type the current data structures were set up for.
     734             :    */
     735             :   ElemType _elem_type;
     736             : 
     737             :   /**
     738             :    * The element the current data structures were set up for.
     739             :    */
     740             :   const Elem * _elem;
     741             : 
     742             :   /**
     743             :    * The element p-refinement level the current data structures are
     744             :    * set up for. Note that this is different from \p _p_level which
     745             :    * is the p-refinement level this finite elment object is operating
     746             :    * at, e.g. how many dofs per elem, etc. On the other hand, this data
     747             :    * member can indicate things like the order of the quadrature rule.
     748             :    * We will use this primarily to determine whether cached data is still
     749             :    * valid
     750             :    */
     751             :   unsigned int _elem_p_level;
     752             : 
     753             :   /**
     754             :    * The p refinement level the current data structures are
     755             :    * set up for.
     756             :    */
     757             :   unsigned int _p_level;
     758             : 
     759             :   /**
     760             :    * A pointer to the quadrature rule employed
     761             :    */
     762             :   QBase * qrule;
     763             : 
     764             :   /**
     765             :    * A flag indicating if current data structures
     766             :    * correspond to quadrature rule points
     767             :    */
     768             :   bool shapes_on_quadrature;
     769             : 
     770             :   /**
     771             :    * The total number of quadrature points
     772             :    * for the current configuration
     773             :    */
     774             :   unsigned int _n_total_qp;
     775             : 
     776             :   /**
     777             :    * \returns \p true when the shape functions (for
     778             :    * this \p FEFamily) depend on the particular
     779             :    * element, and therefore needs to be re-initialized
     780             :    * for each new element.  \p false otherwise.
     781             :    */
     782             :   virtual bool shapes_need_reinit() const = 0;
     783             : 
     784             :   /**
     785             :    * Whether to add p-refinement levels in init/reinit methods
     786             :    */
     787             :   bool _add_p_level_in_reinit;
     788             : };
     789             : 
     790             : } // namespace libMesh
     791             : 
     792             : #endif // LIBMESH_FE_ABSTRACT_H

Generated by: LCOV version 1.14