LCOV - code coverage report
Current view: top level - include/fe - fe_base.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4541 (8e443e) with base 41ae1d Lines: 73 127 57.5 %
Date: 2026-09-07 22:42:35 Functions: 33 88 37.5 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // The libMesh Finite Element Library.
       2             : // Copyright (C) 2002-2026 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_BASE_H
      21             : #define LIBMESH_FE_BASE_H
      22             : 
      23             : // Local includes
      24             : #include "libmesh/libmesh_common.h"
      25             : #include "libmesh/compare_types.h"
      26             : #include "libmesh/fe_abstract.h"
      27             : #include "libmesh/fe_transformation_base.h"
      28             : #include "libmesh/point.h"
      29             : #include "libmesh/reference_counted_object.h"
      30             : #include "libmesh/tensor_tools.h"
      31             : #include "libmesh/type_n_tensor.h"
      32             : #include "libmesh/vector_value.h"
      33             : #include "libmesh/dense_matrix.h"
      34             : 
      35             : // C++ includes
      36             : #include <cstddef>
      37             : #include <vector>
      38             : #include <memory>
      39             : 
      40             : namespace libMesh
      41             : {
      42             : 
      43             : 
      44             : // forward declarations
      45             : template <typename T> class DenseMatrix;
      46             : template <typename T> class DenseVector;
      47             : class BoundaryInfo;
      48             : class DofConstraints;
      49             : class DofMap;
      50             : class Elem;
      51             : class MeshBase;
      52             : template <typename T> class NumericVector;
      53             : class QBase;
      54             : template <typename T> class FETransformationBase;
      55             : class FEType;
      56             : 
      57             : #ifdef LIBMESH_ENABLE_NODE_CONSTRAINTS
      58             : class NodeConstraints;
      59             : #endif
      60             : 
      61             : #ifdef LIBMESH_ENABLE_PERIODIC
      62             : class PeriodicBoundaries;
      63             : class PointLocatorBase;
      64             : #endif
      65             : 
      66             : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
      67             : template <unsigned int Dim, FEFamily T_radial, InfMapType T_map>
      68             : class InfFE;
      69             : #endif
      70             : 
      71             : /**
      72             :  * This class forms the foundation from which generic finite
      73             :  * elements may be derived.  In the current implementation the
      74             :  * templated derived class \p FE offers a wide variety of commonly
      75             :  * used finite element concepts.  Check there for details.
      76             :  *
      77             :  * Use the \p FEGenericBase<OutputType>::build() method to create an
      78             :  * object of any of the derived classes which is compatible with
      79             :  * OutputType.
      80             :  *
      81             :  * \author Benjamin S. Kirk
      82             :  * \date 2002
      83             :  */
      84             : template <typename OutputType>
      85             : class FEGenericBase : public FEAbstract
      86             : {
      87             : protected:
      88             : 
      89             :   /**
      90             :    * Constructor.  Optionally initializes required data
      91             :    * structures.  Protected so that this base class
      92             :    * cannot be explicitly instantiated.
      93             :    */
      94             :   FEGenericBase (const unsigned int dim,
      95             :                  const FEType & fet);
      96             : 
      97             : public:
      98             : 
      99             :   /**
     100             :    * Destructor.
     101             :    */
     102             :   virtual ~FEGenericBase();
     103             : 
     104             :   /**
     105             :    * Builds a specific finite element type.  A \p
     106             :    * std::unique_ptr<FEGenericBase> is returned to prevent a memory leak. This
     107             :    * way the user need not remember to delete the object.
     108             :    *
     109             :    * The build call will fail if the OutputType of this class is not
     110             :    * compatible with the output required for the requested \p type
     111             :    */
     112             :   static std::unique_ptr<FEGenericBase> build (const unsigned int dim,
     113             :                                                const FEType & type);
     114             : 
     115             :   /**
     116             :    * Convenient typedefs for gradients of output, hessians of output,
     117             :    * and potentially-complex-valued versions of same.
     118             :    */
     119             :   typedef OutputType                                                      OutputShape;
     120             :   typedef typename TensorTools::IncrementRank<OutputShape>::type          OutputGradient;
     121             :   typedef typename TensorTools::IncrementRank<OutputGradient>::type       OutputTensor;
     122             :   typedef typename TensorTools::DecrementRank<OutputShape>::type          OutputDivergence;
     123             :   typedef typename TensorTools::MakeNumber<OutputShape>::type             OutputNumber;
     124             :   typedef typename TensorTools::IncrementRank<OutputNumber>::type         OutputNumberGradient;
     125             :   typedef typename TensorTools::IncrementRank<OutputNumberGradient>::type OutputNumberTensor;
     126             :   typedef typename TensorTools::DecrementRank<OutputNumber>::type         OutputNumberDivergence;
     127             : 
     128             : 
     129             : 
     130             : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
     131             : 
     132             :   /**
     133             :    * Builds a specific infinite element type.  A \p
     134             :    * std::unique_ptr<FEGenericBase> is returned to prevent a memory leak. This
     135             :    * way the user need not remember to delete the object.
     136             :    *
     137             :    * The build call will fail if the OutputShape of this class is not
     138             :    * compatible with the output required for the requested \p type
     139             :    */
     140             :   static std::unique_ptr<FEGenericBase> build_InfFE (const unsigned int dim,
     141             :                                                      const FEType & type);
     142             : 
     143             : #endif
     144             : 
     145             : #ifdef LIBMESH_ENABLE_AMR
     146             : 
     147             :   /**
     148             :    * Computes the constraint matrix contributions (for
     149             :    * non-conforming adapted meshes) corresponding to
     150             :    * variable number \p var_number, using generic
     151             :    * projections.
     152             :    */
     153             :   static void compute_proj_constraints (DofConstraints & constraints,
     154             :                                         DofMap & dof_map,
     155             :                                         const unsigned int variable_number,
     156             :                                         const Elem * elem);
     157             : 
     158             :   /**
     159             :    * Creates a local projection on \p coarse_elem, based on the
     160             :    * DoF values in \p global_vector for it's children.  Computes a
     161             :    * vector of coefficients corresponding to dof_indices for only the
     162             :    * single given \p var
     163             :    */
     164             : 
     165             :   static void coarsened_dof_values(const NumericVector<Number> & global_vector,
     166             :                                    const DofMap & dof_map,
     167             :                                    const Elem * coarse_elem,
     168             :                                    DenseVector<Number> & coarse_dofs,
     169             :                                    const unsigned int var,
     170             :                                    const bool use_old_dof_indices = false);
     171             : 
     172             :   /**
     173             :    * Creates a local projection on \p coarse_elem, based on the
     174             :    * DoF values in \p global_vector for it's children.  Computes a
     175             :    * vector of coefficients corresponding to all dof_indices.
     176             :    */
     177             : 
     178             :   static void coarsened_dof_values(const NumericVector<Number> & global_vector,
     179             :                                    const DofMap & dof_map,
     180             :                                    const Elem * coarse_elem,
     181             :                                    DenseVector<Number> & coarse_dofs,
     182             :                                    const bool use_old_dof_indices = false);
     183             : 
     184             : #endif // #ifdef LIBMESH_ENABLE_AMR
     185             : 
     186             : #ifdef LIBMESH_ENABLE_PERIODIC
     187             : 
     188             :   /**
     189             :    * Computes the constraint matrix contributions (for
     190             :    * meshes with periodic boundary conditions) corresponding to
     191             :    * variable number \p var_number, using generic projections.
     192             :    */
     193             :   static void compute_periodic_constraints (DofConstraints & constraints,
     194             :                                             DofMap & dof_map,
     195             :                                             const PeriodicBoundaries & boundaries,
     196             :                                             const MeshBase & mesh,
     197             :                                             const PointLocatorBase * point_locator,
     198             :                                             const unsigned int variable_number,
     199             :                                             const Elem * elem);
     200             : 
     201             : #endif // LIBMESH_ENABLE_PERIODIC
     202             : 
     203             :   /**
     204             :    * \returns The shape function values at the quadrature points
     205             :    * on the element.
     206             :    */
     207        6520 :   const std::vector<std::vector<OutputShape>> & get_phi() const
     208        6520 :   { libmesh_assert(!calculations_started || calculate_phi);
     209   323978286 :     calculate_phi = true; return phi; }
     210             : 
     211             :   /**
     212             :    * \returns The dual (biorthogonal) shape function values at the quadrature
     213             :    * points on the element.
     214             :    *
     215             :    * The dual basis is constructed to satisfy
     216             :    * \f$ \int \Phi_j N_k \, d\gamma = \delta_{jk} \int N_k \, d\gamma \f$
     217             :    * against the primal basis \f$ N \f$. That biorthogonality is what makes a
     218             :    * mortar coupling matrix diagonal, so a Lagrange multiplier can be condensed
     219             :    * with a diagonal inverse.
     220             :    *
     221             :    * \note On QUAD8 and TRI6 these functions are biorthogonal to a locally
     222             :    * transformed primal basis rather than to \f$ N \f$ itself: \f$ \int N_k \f$
     223             :    * is not positive on those faces (exactly 0 at a TRI6 vertex, -1/3 at a QUAD8
     224             :    * corner), so the usual construction degenerates. For those two element types
     225             :    * \f$ \int \Phi_j N_k \f$ is therefore not diagonal; it factors as
     226             :    * \f$ D = \tilde{D} T^{-1} \f$ with \f$ \tilde{D} \f$ diagonal, leaving
     227             :    * \f$ D^{-1} = T \tilde{D}^{-1} \f$ sparse and cheap to apply. The functions
     228             :    * returned here are still expressed in the primal basis, so the type and
     229             :    * meaning of this return value are unchanged. See Popp, Wohlmuth, Gee and
     230             :    * Wall, SIAM J. Sci. Comput. 34(4):B421-B446, 2012, Sec. 4.4.1 and Eq. (4.12).
     231             :    */
     232           0 :   const std::vector<std::vector<OutputShape>> & get_dual_phi() const
     233             :   {
     234           0 :     libmesh_assert(!calculations_started || calculate_dual);
     235           0 :     calculate_dual = true;
     236             :     // Dual phi computation relies on primal phi computation
     237           0 :     this->request_phi();
     238           0 :     return dual_phi;
     239             :   }
     240             : 
     241      953109 :   virtual void request_phi() const override
     242      953109 :   { get_phi(); }
     243             : 
     244           0 :   virtual void request_dual_phi() const override
     245           0 :   { get_dual_phi(); }
     246             : 
     247             :   /**
     248             :    * \returns The shape function derivatives at the quadrature
     249             :    * points.
     250             :    */
     251      107648 :   const std::vector<std::vector<OutputGradient>> & get_dphi() const
     252      107648 :   { libmesh_assert(!calculations_started || calculate_dphi);
     253   276147866 :     calculate_dphi = calculate_dphiref = true; return dphi; }
     254             : 
     255             :   /**
     256             :    * \returns The dual shape function derivatives at the quadrature points.
     257             :    *
     258             :    * \note See get_dual_phi() for the QUAD8/TRI6 caveat.
     259             :    */
     260           0 :   const std::vector<std::vector<OutputGradient>> & get_dual_dphi() const
     261           0 :   { libmesh_assert(!calculations_started || calculate_dphi);
     262           0 :     calculate_dphi = calculate_dual = calculate_dphiref = true; return dual_dphi; }
     263             : 
     264      101652 :   virtual void request_dphi() const override
     265      101652 :   { get_dphi(); }
     266             : 
     267           0 :   virtual void request_dual_dphi() const override
     268           0 :   { get_dual_dphi(); }
     269             : 
     270             :   /**
     271             :    * \returns The coefficients expressing the dual basis in the primal basis.
     272             :    *
     273             :    * \note See get_dual_phi() for the QUAD8/TRI6 caveat.
     274             :    */
     275           0 :   const DenseMatrix<Real> & get_dual_coeff() const
     276           0 :   { return dual_coeff; }
     277             : 
     278             :   /**
     279             :    * \returns The curl of the shape function at the quadrature
     280             :    * points.
     281             :    */
     282             :   virtual_for_inffe
     283      525637 :   const std::vector<std::vector<OutputShape>> & get_curl_phi() const
     284      202175 :   { libmesh_assert(!calculations_started || calculate_curl_phi);
     285     2859877 :     calculate_curl_phi = calculate_dphiref = true; return curl_phi; }
     286             : 
     287             :   /**
     288             :    * \returns The divergence of the shape function at the quadrature
     289             :    * points.
     290             :    */
     291             :   virtual_for_inffe
     292      140745 :   const std::vector<std::vector<OutputDivergence>> & get_div_phi() const
     293       47027 :   { libmesh_assert(!calculations_started || calculate_div_phi);
     294      687657 :     calculate_div_phi = calculate_dphiref = true; return div_phi; }
     295             : 
     296             :   /**
     297             :    * \returns The shape function x-derivative at the quadrature
     298             :    * points.
     299             :    */
     300           0 :   const std::vector<std::vector<OutputShape>> & get_dphidx() const
     301           0 :   { libmesh_assert(!calculations_started || calculate_dphi);
     302           0 :     calculate_dphi = calculate_dphiref = true; return dphidx; }
     303             : 
     304             :   /**
     305             :    * \returns The shape function y-derivative at the quadrature
     306             :    * points.
     307             :    */
     308           0 :   const std::vector<std::vector<OutputShape>> & get_dphidy() const
     309           0 :   { libmesh_assert(!calculations_started || calculate_dphi);
     310           0 :     calculate_dphi = calculate_dphiref = true; return dphidy; }
     311             : 
     312             :   /**
     313             :    * \returns The shape function z-derivative at the quadrature
     314             :    * points.
     315             :    */
     316           0 :   const std::vector<std::vector<OutputShape>> & get_dphidz() const
     317           0 :   { libmesh_assert(!calculations_started || calculate_dphi);
     318           0 :     calculate_dphi = calculate_dphiref = true; return dphidz; }
     319             : 
     320             :   /**
     321             :    * \returns The shape function xi-derivative at the quadrature
     322             :    * points.
     323             :    */
     324     8149204 :   const std::vector<std::vector<OutputShape>> & get_dphidxi() const
     325     8149204 :   { libmesh_assert(!calculations_started || calculate_dphiref);
     326    89327523 :     calculate_dphiref = true; return dphidxi; }
     327             : 
     328             :   /**
     329             :    * \returns The shape function eta-derivative at the quadrature
     330             :    * points.
     331             :    */
     332     8128085 :   const std::vector<std::vector<OutputShape>> & get_dphideta() const
     333     8128085 :   { libmesh_assert(!calculations_started || calculate_dphiref);
     334     8128085 :     calculate_dphiref = true; return dphideta; }
     335             : 
     336             :   /**
     337             :    * \returns The shape function zeta-derivative at the quadrature
     338             :    * points.
     339             :    */
     340     1254814 :   const std::vector<std::vector<OutputShape>> & get_dphidzeta() const
     341     1254814 :   { libmesh_assert(!calculations_started || calculate_dphiref);
     342     1254814 :     calculate_dphiref = true; return dphidzeta; }
     343             : 
     344             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     345             : 
     346             :   /**
     347             :    * \returns The shape function second derivatives at the quadrature
     348             :    * points.
     349             :    */
     350      176227 :   const std::vector<std::vector<OutputTensor>> & get_d2phi() const
     351      176227 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     352     2226397 :     calculate_d2phi = calculate_dphiref = true; return d2phi; }
     353             : 
     354             :   /**
     355             :    * \returns The dual shape function second derivatives at the quadrature
     356             :    * points.
     357             :    *
     358             :    * \note See get_dual_phi() for the QUAD8/TRI6 caveat.
     359             :    */
     360           0 :   const std::vector<std::vector<OutputTensor>> & get_dual_d2phi() const
     361           0 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     362           0 :     calculate_d2phi = calculate_dual = calculate_dphiref = true; return dual_d2phi; }
     363             : 
     364             :   /**
     365             :    * \returns The shape function second derivatives at the quadrature
     366             :    * points.
     367             :    */
     368           0 :   const std::vector<std::vector<OutputShape>> & get_d2phidx2() const
     369           0 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     370           0 :     calculate_d2phi = calculate_dphiref = true; return d2phidx2; }
     371             : 
     372             :   /**
     373             :    * \returns The shape function second derivatives at the quadrature
     374             :    * points.
     375             :    */
     376           0 :   const std::vector<std::vector<OutputShape>> & get_d2phidxdy() const
     377           0 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     378           0 :     calculate_d2phi = calculate_dphiref = true; return d2phidxdy; }
     379             : 
     380             :   /**
     381             :    * \returns The shape function second derivatives at the quadrature
     382             :    * points.
     383             :    */
     384           0 :   const std::vector<std::vector<OutputShape>> & get_d2phidxdz() const
     385           0 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     386           0 :     calculate_d2phi = calculate_dphiref = true; return d2phidxdz; }
     387             : 
     388             :   /**
     389             :    * \returns The shape function second derivatives at the quadrature
     390             :    * points.
     391             :    */
     392           0 :   const std::vector<std::vector<OutputShape>> & get_d2phidy2() const
     393           0 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     394           0 :     calculate_d2phi =  calculate_dphiref = true; return d2phidy2; }
     395             : 
     396             :   /**
     397             :    * \returns The shape function second derivatives at the quadrature
     398             :    * points.
     399             :    */
     400           0 :   const std::vector<std::vector<OutputShape>> & get_d2phidydz() const
     401           0 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     402           0 :     calculate_d2phi = calculate_dphiref = true; return d2phidydz; }
     403             : 
     404             :   /**
     405             :    * \returns The shape function second derivatives at the quadrature
     406             :    * points.
     407             :    */
     408           0 :   const std::vector<std::vector<OutputShape>> & get_d2phidz2() const
     409           0 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     410           0 :     calculate_d2phi = calculate_dphiref = true; return d2phidz2; }
     411             : 
     412             :   /**
     413             :    * \returns The shape function second derivatives at the quadrature
     414             :    * points, in reference coordinates
     415             :    */
     416      524820 :   const std::vector<std::vector<OutputShape>> & get_d2phidxi2() const
     417      524820 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     418     6608235 :     calculate_d2phi = calculate_dphiref = true; return d2phidxi2; }
     419             : 
     420             :   /**
     421             :    * \returns The shape function second derivatives at the quadrature
     422             :    * points, in reference coordinates
     423             :    */
     424      517160 :   const std::vector<std::vector<OutputShape>> & get_d2phidxideta() const
     425      517160 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     426      517160 :     calculate_d2phi = calculate_dphiref = true; return d2phidxideta; }
     427             : 
     428             :   /**
     429             :    * \returns The shape function second derivatives at the quadrature
     430             :    * points, in reference coordinates
     431             :    */
     432      435393 :   const std::vector<std::vector<OutputShape>> & get_d2phidxidzeta() const
     433      435393 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     434      435393 :     calculate_d2phi = calculate_dphiref = true; return d2phidxidzeta; }
     435             : 
     436             :   /**
     437             :    * \returns The shape function second derivatives at the quadrature
     438             :    * points, in reference coordinates
     439             :    */
     440      517160 :   const std::vector<std::vector<OutputShape>> & get_d2phideta2() const
     441      517160 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     442      517160 :     calculate_d2phi = calculate_dphiref = true; return d2phideta2; }
     443             : 
     444             :   /**
     445             :    * \returns The shape function second derivatives at the quadrature
     446             :    * points, in reference coordinates
     447             :    */
     448      435393 :   const std::vector<std::vector<OutputShape>> & get_d2phidetadzeta() const
     449      435393 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     450      435393 :     calculate_d2phi = calculate_dphiref = true; return d2phidetadzeta; }
     451             : 
     452             :   /**
     453             :    * \returns The shape function second derivatives at the quadrature
     454             :    * points, in reference coordinates
     455             :    */
     456      435393 :   const std::vector<std::vector<OutputShape>> & get_d2phidzeta2() const
     457      435393 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     458      435393 :     calculate_d2phi = calculate_dphiref = true; return d2phidzeta2; }
     459             : 
     460             : #endif //LIBMESH_ENABLE_SECOND_DERIVATIVES
     461             : 
     462             : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
     463             : 
     464             :   /**
     465             :    * \returns The global first derivative of the phase term
     466             :    * which is used in infinite elements, evaluated at the
     467             :    * quadrature points.
     468             :    *
     469             :    * In case of the general finite element class \p FE this
     470             :    * field is initialized to all zero, so that the variational
     471             :    * formulation for an infinite element produces correct element
     472             :    * matrices for a mesh using both finite and infinite elements.
     473             :    */
     474           0 :   const std::vector<OutputGradient> & get_dphase() const
     475           0 :   { return dphase; }
     476             : 
     477             : 
     478             :   /**
     479             :    * \returns The multiplicative weight at each quadrature point.
     480             :    * This weight is used for certain infinite element weak
     481             :    * formulations, so that weighted Sobolev spaces are
     482             :    * used for the trial function space.  This renders the
     483             :    * variational form easily computable.
     484             :    *
     485             :    * In case of the general finite element class \p FE this
     486             :    * field is initialized to all ones, so that the variational
     487             :    * formulation for an infinite element produces correct element
     488             :    * matrices for a mesh using both finite and infinite elements.
     489             :    */
     490           2 :   virtual const std::vector<Real> & get_Sobolev_weight() const
     491           2 :   { return weight; }
     492             : 
     493             :   /**
     494             :    * \returns The first global derivative of the multiplicative
     495             :    * weight at each quadrature point. See \p get_Sobolev_weight()
     496             :    * for details.  In case of \p FE initialized to all zero.
     497             :    */
     498           0 :   virtual const std::vector<RealGradient> & get_Sobolev_dweight() const
     499           0 :   { return dweight; }
     500             : 
     501             :   /**
     502             :    * \returns The multiplicative weight (see \p get_Sobolev_weight)
     503             :    * but weighted with the radial coordinate square.
     504             :    *
     505             :    * In finite elements, this gives just 1, similar to \p get_Sobolev_Weight()
     506             :    */
     507        1340 :   virtual const std::vector<Real> & get_Sobolev_weightxR_sq() const
     508        1340 :   { return weight; }
     509             : 
     510             :   /**
     511             :    * \returns The first global derivative of the multiplicative weight
     512             :    * (see \p dget_Sobolev_weight) but weighted with the square of the
     513             :    * radial coordinate.
     514             :    *
     515             :    * In finite elements, this is 0.
     516             :    */
     517        1340 :   virtual const std::vector<RealGradient> & get_Sobolev_dweightxR_sq() const
     518        1340 :   { return dweight; }
     519             : 
     520             :   /**
     521             :    * \returns The shape function \p phi (for FE) and \p phi weighted by r/decay
     522             :    *  for InfFE.
     523             :    *
     524             :    * To compensate for the decay function applied to the Jacobian (see \p get_JxWxdecay_sq),
     525             :    * the wave function \p phi should be divided by  this function.
     526             :    *
     527             :    * The factor r must be compensated for by the Sobolev \p weight.
     528             :    * (i.e. by using \p get_Sobolev_weightxR_sq())
     529             :    **/
     530        1340 :   virtual const std::vector<std::vector<OutputShape>> & get_phi_over_decayxR () const
     531        1340 :   { return get_phi();}
     532             : 
     533             :   /**
     534             :    * \returns the gradient of the shape function (see \p get_dphi()),
     535             :    * but in case of \p InfFE, weighted with r/decay.
     536             :    * See \p  get_phi_over_decayxR() for details.
     537             :    */
     538        1340 :   virtual const std::vector<std::vector<OutputGradient>> & get_dphi_over_decayxR () const
     539        1340 :   { return get_dphi();}
     540             : 
     541             :   /**
     542             :    * \returns the gradient of the shape function (see \p get_dphi()),
     543             :    * but in case of \p InfFE, weighted with 1/decay.
     544             :    *
     545             :    * In contrast to the shape function, its gradient stays finite
     546             :    * when divided by the decay function.
     547             :    */
     548           0 :   virtual const std::vector<std::vector<OutputGradient>> & get_dphi_over_decay () const
     549           0 :   { return get_dphi();}
     550             : 
     551             : #endif
     552             : 
     553             :   /**
     554             :    * Prints the value of each shape function at each quadrature point.
     555             :    */
     556             :   virtual void print_phi(std::ostream & os) const override;
     557             :   virtual void print_dual_phi(std::ostream & os) const override;
     558             : 
     559             :   /**
     560             :    * Prints the value of each shape function's derivative
     561             :    * at each quadrature point.
     562             :    */
     563             :   virtual void print_dphi(std::ostream & os) const override;
     564             :   virtual void print_dual_dphi(std::ostream & os) const override;
     565             : 
     566             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     567             : 
     568             :   /**
     569             :    * Prints the value of each shape function's second derivatives
     570             :    * at each quadrature point.
     571             :    */
     572             :   virtual void print_d2phi(std::ostream & os) const override;
     573             :   virtual void print_dual_d2phi(std::ostream & os) const override;
     574             : 
     575             : #endif
     576             : 
     577             : 
     578             : protected:
     579             : 
     580             : 
     581             : 
     582             : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
     583             : 
     584             :   /**
     585             :    * Initialize the data fields for the base of an
     586             :    * an infinite element.  Implement this in the derived
     587             :    * class \p FE<Dim,T>.
     588             :    */
     589             :   virtual void init_base_shape_functions(const std::vector<Point> & qp,
     590             :                                          const Elem * e) = 0;
     591             : 
     592             : #endif
     593             : 
     594             :   /**
     595             :    * Determine which values are to be calculated, for both the FE
     596             :    * itself and for the FEMap.
     597             :    */
     598             :   virtual_for_inffe
     599             :   void determine_calculations();
     600             : 
     601             :   /**
     602             :    * \returns true iff no calculations have been requested of this
     603             :    * FE object or of its associated FEMap
     604             :    */
     605    27878742 :   bool calculating_nothing() const
     606             :   {
     607    29745627 :     return calculate_nothing &&
     608     1866885 :       !this->calculate_phi && !this->calculate_dphi &&
     609             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     610     1866885 :       !this->calculate_d2phi &&
     611             : #endif
     612    29909284 :       !this->calculate_curl_phi && !this->calculate_div_phi &&
     613     4372758 :       !this->calculate_map;
     614             :   }
     615             : 
     616             :   /**
     617             :    * After having updated the jacobian and the transformation
     618             :    * from local to global coordinates in \p FEMap::compute_map(),
     619             :    * the first derivatives of the shape functions are
     620             :    * transformed to global coordinates, giving \p dphi,
     621             :    * \p dphidx, \p dphidy, and \p dphidz. This method
     622             :    * should rarely be re-defined in derived classes, but
     623             :    * still should be usable for children. Therefore, keep
     624             :    * it protected.
     625             :    */
     626             :   virtual void compute_shape_functions(const Elem * elem, const std::vector<Point> & qp) override;
     627             : 
     628             :   /**
     629             :    * Compute the dual basis coefficients \p dual_coeff
     630             :    * we rely on the \p JxW (or weights) and the \p phi values,
     631             :    * which can come from default or customized qrule
     632             :    */
     633             :   void compute_dual_shape_coeffs(const std::vector<Real> & JxW, const std::vector<std::vector<OutputShape>> & phi);
     634             : 
     635             :   /**
     636             :    * Compute \p dual_phi, \p dual_dphi, \p dual_d2phi
     637             :    * It is only valid for this to be called after reinit has occurred with a
     638             :    * quadrature rule
     639             :    */
     640             :   void compute_dual_shape_functions();
     641             : 
     642             :   /**
     643             :    * Object that handles computing shape function values, gradients, etc
     644             :    * in the physical domain.
     645             :    */
     646             :   std::unique_ptr<FETransformationBase<OutputType>> _fe_trans;
     647             : 
     648             :   /**
     649             :    * Shape function values.
     650             :    */
     651             :   std::vector<std::vector<OutputShape>>   phi;
     652             :   std::vector<std::vector<OutputShape>>   dual_phi;
     653             : 
     654             :   /**
     655             :    * Shape function derivative values.
     656             :    */
     657             :   std::vector<std::vector<OutputGradient>>  dphi;
     658             :   std::vector<std::vector<OutputGradient>>  dual_dphi;
     659             : 
     660             :   /**
     661             :    * Coefficient matrix for the dual basis.
     662             :    */
     663             :   mutable DenseMatrix<Real> dual_coeff;
     664             : 
     665             :   /**
     666             :    * Shape function curl values. Only defined for vector types.
     667             :    */
     668             :   std::vector<std::vector<OutputShape>> curl_phi;
     669             : 
     670             :   /**
     671             :    * Shape function divergence values. Only defined for vector types.
     672             :    */
     673             :   std::vector<std::vector<OutputDivergence>> div_phi;
     674             : 
     675             :   /**
     676             :    * Shape function derivatives in the xi direction.
     677             :    */
     678             :   std::vector<std::vector<OutputShape>>   dphidxi;
     679             : 
     680             :   /**
     681             :    * Shape function derivatives in the eta direction.
     682             :    */
     683             :   std::vector<std::vector<OutputShape>>   dphideta;
     684             : 
     685             :   /**
     686             :    * Shape function derivatives in the zeta direction.
     687             :    */
     688             :   std::vector<std::vector<OutputShape>>   dphidzeta;
     689             : 
     690             :   /**
     691             :    * Shape function derivatives in the x direction.
     692             :    */
     693             :   std::vector<std::vector<OutputShape>>   dphidx;
     694             : 
     695             :   /**
     696             :    * Shape function derivatives in the y direction.
     697             :    */
     698             :   std::vector<std::vector<OutputShape>>   dphidy;
     699             : 
     700             :   /**
     701             :    * Shape function derivatives in the z direction.
     702             :    */
     703             :   std::vector<std::vector<OutputShape>>   dphidz;
     704             : 
     705             : 
     706             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     707             : 
     708             :   /**
     709             :    * Shape function second derivative values.
     710             :    */
     711             :   std::vector<std::vector<OutputTensor>>  d2phi;
     712             :   std::vector<std::vector<OutputTensor>>  dual_d2phi;
     713             : 
     714             :   /**
     715             :    * Shape function second derivatives in the xi direction.
     716             :    */
     717             :   std::vector<std::vector<OutputShape>>   d2phidxi2;
     718             : 
     719             :   /**
     720             :    * Shape function second derivatives in the xi-eta direction.
     721             :    */
     722             :   std::vector<std::vector<OutputShape>>   d2phidxideta;
     723             : 
     724             :   /**
     725             :    * Shape function second derivatives in the xi-zeta direction.
     726             :    */
     727             :   std::vector<std::vector<OutputShape>>   d2phidxidzeta;
     728             : 
     729             :   /**
     730             :    * Shape function second derivatives in the eta direction.
     731             :    */
     732             :   std::vector<std::vector<OutputShape>>   d2phideta2;
     733             : 
     734             :   /**
     735             :    * Shape function second derivatives in the eta-zeta direction.
     736             :    */
     737             :   std::vector<std::vector<OutputShape>>   d2phidetadzeta;
     738             : 
     739             :   /**
     740             :    * Shape function second derivatives in the zeta direction.
     741             :    */
     742             :   std::vector<std::vector<OutputShape>>   d2phidzeta2;
     743             : 
     744             :   /**
     745             :    * Shape function second derivatives in the x direction.
     746             :    */
     747             :   std::vector<std::vector<OutputShape>>   d2phidx2;
     748             : 
     749             :   /**
     750             :    * Shape function second derivatives in the x-y direction.
     751             :    */
     752             :   std::vector<std::vector<OutputShape>>   d2phidxdy;
     753             : 
     754             :   /**
     755             :    * Shape function second derivatives in the x-z direction.
     756             :    */
     757             :   std::vector<std::vector<OutputShape>>   d2phidxdz;
     758             : 
     759             :   /**
     760             :    * Shape function second derivatives in the y direction.
     761             :    */
     762             :   std::vector<std::vector<OutputShape>>   d2phidy2;
     763             : 
     764             :   /**
     765             :    * Shape function second derivatives in the y-z direction.
     766             :    */
     767             :   std::vector<std::vector<OutputShape>>   d2phidydz;
     768             : 
     769             :   /**
     770             :    * Shape function second derivatives in the z direction.
     771             :    */
     772             :   std::vector<std::vector<OutputShape>>   d2phidz2;
     773             : 
     774             : #endif
     775             : 
     776             : 
     777             : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
     778             : 
     779             :   //--------------------------------------------------------------
     780             :   /* protected members for infinite elements, which are accessed
     781             :    * from the outside through some inline functions
     782             :    */
     783             : 
     784             : 
     785             :   /**
     786             :    * Used for certain infinite element families:
     787             :    * the first derivatives of the phase term in global coordinates,
     788             :    * over all quadrature points.
     789             :    */
     790             :   std::vector<OutputGradient> dphase;
     791             : 
     792             :   /**
     793             :    * Used for certain infinite element families:
     794             :    * the global derivative of the additional radial weight \f$ 1/{r^2} \f$,
     795             :    * over all quadrature points.
     796             :    */
     797             :   std::vector<RealGradient> dweight;
     798             : 
     799             :   /**
     800             :    * Used for certain infinite element families:
     801             :    * the additional radial weight \f$ 1/{r^2} \f$ in local coordinates,
     802             :    * over all quadrature points.
     803             :    */
     804             :   std::vector<Real>  weight;
     805             : 
     806             : #endif
     807             : 
     808             : private:
     809             : 
     810             : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
     811             : 
     812             :   /**
     813             :    * Make all \p InfFE<Dim,T_radial,T_map> classes friends
     814             :    * so that they can safely used \p FE<Dim-1,T_base> through
     815             :    * a \p FEGenericBase * as base approximation.
     816             :    */
     817             :   template <unsigned int friend_Dim, FEFamily friend_T_radial, InfMapType friend_T_map>
     818             :   friend class InfFE;
     819             : 
     820             : #endif
     821             : 
     822             : 
     823             : };
     824             : 
     825             : // --------------------------------------------------------------------
     826             : // Generic templates. We specialize for OutputType = Real, so these are
     827             : // only used for OutputType = RealVectorValue
     828             : template <typename OutputType>
     829           0 : void FEGenericBase<OutputType>::compute_dual_shape_functions ()
     830             : {
     831           0 :   libmesh_error_msg(
     832             :       "Computation of dual shape functions for vector finite element "
     833             :       "families is not currently implemented");
     834             : }
     835             : 
     836             : template <typename OutputType>
     837           0 : void FEGenericBase<OutputType>::compute_dual_shape_coeffs(const std::vector<Real> & /*JxW*/, const std::vector<std::vector<OutputShape>> & /*phi_vals*/)
     838             : {
     839           0 :   libmesh_error_msg(
     840             :       "Computation of dual shape functions for vector finite element "
     841             :       "families is not currently implemented");
     842             : }
     843             : 
     844             : // -----------------------------------------------------------
     845             : // Forward declaration of specialization
     846             : template <>
     847             : void FEGenericBase<Real>::compute_dual_shape_functions();
     848             : 
     849             : template <>
     850             : void FEGenericBase<Real>::compute_dual_shape_coeffs(const std::vector<Real> & /*JxW*/, const std::vector<std::vector<OutputShape>> & /*phi_vals*/);
     851             : 
     852             : 
     853             : // Typedefs for convenience and backwards compatibility
     854             : typedef FEGenericBase<Real> FEBase;
     855             : typedef FEGenericBase<RealGradient> FEVectorBase;
     856             : 
     857             : 
     858             : 
     859             : 
     860             : // ------------------------------------------------------------
     861             : // FEGenericBase class inline members
     862             : template <typename OutputType>
     863             : inline
     864    16955391 : FEGenericBase<OutputType>::FEGenericBase(const unsigned int d,
     865             :                                          const FEType & fet) :
     866             :   FEAbstract(d,fet),
     867    15267342 :   _fe_trans( FETransformationBase<OutputType>::build(fet) ),
     868    15267342 :   phi(),
     869    15267342 :   dual_phi(),
     870    15267342 :   dphi(),
     871    15267342 :   dual_dphi(),
     872             :   curl_phi(),
     873             :   div_phi(),
     874             :   dphidxi(),
     875             :   dphideta(),
     876             :   dphidzeta(),
     877             :   dphidx(),
     878             :   dphidy(),
     879             :   dphidz()
     880             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     881             :   ,d2phi(),
     882             :   dual_d2phi(),
     883             :   d2phidxi2(),
     884             :   d2phidxideta(),
     885             :   d2phidxidzeta(),
     886             :   d2phideta2(),
     887             :   d2phidetadzeta(),
     888             :   d2phidzeta2(),
     889             :   d2phidx2(),
     890             :   d2phidxdy(),
     891             :   d2phidxdz(),
     892             :   d2phidy2(),
     893             :   d2phidydz(),
     894    14694900 :   d2phidz2()
     895             : #endif
     896             : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
     897             :   ,dphase(),
     898             :   dweight(),
     899     2260491 :   weight()
     900             : #endif
     901             : {
     902    16955391 : }
     903             : 
     904             : 
     905             : 
     906             : template <typename OutputType>
     907             : inline
     908    16955391 : FEGenericBase<OutputType>::~FEGenericBase()
     909             : {
     910    19215277 : }
     911             : 
     912             : } // namespace libMesh
     913             : 
     914             : #endif // LIBMESH_FE_BASE_H

Generated by: LCOV version 1.14