LCOV - code coverage report
Current view: top level - include/fe - fe_base.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 73 127 57.5 %
Date: 2025-08-19 19:27:09 Functions: 34 88 38.6 %
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_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       21096 :   const std::vector<std::vector<OutputShape>> & get_phi() const
     208       21096 :   { libmesh_assert(!calculations_started || calculate_phi);
     209   315998006 :     calculate_phi = true; return phi; }
     210             : 
     211           0 :   const std::vector<std::vector<OutputShape>> & get_dual_phi() const
     212             :   {
     213           0 :     libmesh_assert(!calculations_started || calculate_dual);
     214           0 :     calculate_dual = true;
     215             :     // Dual phi computation relies on primal phi computation
     216           0 :     this->request_phi();
     217           0 :     return dual_phi;
     218             :   }
     219             : 
     220      835107 :   virtual void request_phi() const override
     221      835107 :   { get_phi(); }
     222             : 
     223           0 :   virtual void request_dual_phi() const override
     224           0 :   { get_dual_phi(); }
     225             : 
     226             :   /**
     227             :    * \returns The shape function derivatives at the quadrature
     228             :    * points.
     229             :    */
     230      120021 :   const std::vector<std::vector<OutputGradient>> & get_dphi() const
     231      120021 :   { libmesh_assert(!calculations_started || calculate_dphi);
     232   274662976 :     calculate_dphi = calculate_dphiref = true; return dphi; }
     233             : 
     234           0 :   const std::vector<std::vector<OutputGradient>> & get_dual_dphi() const
     235           0 :   { libmesh_assert(!calculations_started || calculate_dphi);
     236           0 :     calculate_dphi = calculate_dual = calculate_dphiref = true; return dual_dphi; }
     237             : 
     238       98759 :   virtual void request_dphi() const override
     239       98759 :   { get_dphi(); }
     240             : 
     241           0 :   virtual void request_dual_dphi() const override
     242           0 :   { get_dual_dphi(); }
     243             : 
     244           0 :   const DenseMatrix<Real> & get_dual_coeff() const
     245           0 :   { return dual_coeff; }
     246             : 
     247             :   /**
     248             :    * \returns The curl of the shape function at the quadrature
     249             :    * points.
     250             :    */
     251             :   virtual_for_inffe
     252      642716 :   const std::vector<std::vector<OutputShape>> & get_curl_phi() const
     253      245740 :   { libmesh_assert(!calculations_started || calculate_curl_phi);
     254     2607164 :     calculate_curl_phi = calculate_dphiref = true; return curl_phi; }
     255             : 
     256             :   /**
     257             :    * \returns The divergence of the shape function at the quadrature
     258             :    * points.
     259             :    */
     260             :   virtual_for_inffe
     261      177876 :   const std::vector<std::vector<OutputDivergence>> & get_div_phi() const
     262       59412 :   { libmesh_assert(!calculations_started || calculate_div_phi);
     263      710964 :     calculate_div_phi = calculate_dphiref = true; return div_phi; }
     264             : 
     265             :   /**
     266             :    * \returns The shape function x-derivative at the quadrature
     267             :    * points.
     268             :    */
     269           0 :   const std::vector<std::vector<OutputShape>> & get_dphidx() const
     270           0 :   { libmesh_assert(!calculations_started || calculate_dphi);
     271           0 :     calculate_dphi = calculate_dphiref = true; return dphidx; }
     272             : 
     273             :   /**
     274             :    * \returns The shape function y-derivative at the quadrature
     275             :    * points.
     276             :    */
     277           0 :   const std::vector<std::vector<OutputShape>> & get_dphidy() const
     278           0 :   { libmesh_assert(!calculations_started || calculate_dphi);
     279           0 :     calculate_dphi = calculate_dphiref = true; return dphidy; }
     280             : 
     281             :   /**
     282             :    * \returns The shape function z-derivative at the quadrature
     283             :    * points.
     284             :    */
     285           0 :   const std::vector<std::vector<OutputShape>> & get_dphidz() const
     286           0 :   { libmesh_assert(!calculations_started || calculate_dphi);
     287           0 :     calculate_dphi = calculate_dphiref = true; return dphidz; }
     288             : 
     289             :   /**
     290             :    * \returns The shape function xi-derivative at the quadrature
     291             :    * points.
     292             :    */
     293     8026275 :   const std::vector<std::vector<OutputShape>> & get_dphidxi() const
     294     8026275 :   { libmesh_assert(!calculations_started || calculate_dphiref);
     295    87428895 :     calculate_dphiref = true; return dphidxi; }
     296             : 
     297             :   /**
     298             :    * \returns The shape function eta-derivative at the quadrature
     299             :    * points.
     300             :    */
     301     8005115 :   const std::vector<std::vector<OutputShape>> & get_dphideta() const
     302     8005115 :   { libmesh_assert(!calculations_started || calculate_dphiref);
     303     8005115 :     calculate_dphiref = true; return dphideta; }
     304             : 
     305             :   /**
     306             :    * \returns The shape function zeta-derivative at the quadrature
     307             :    * points.
     308             :    */
     309     1246460 :   const std::vector<std::vector<OutputShape>> & get_dphidzeta() const
     310     1246460 :   { libmesh_assert(!calculations_started || calculate_dphiref);
     311     1246460 :     calculate_dphiref = true; return dphidzeta; }
     312             : 
     313             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     314             : 
     315             :   /**
     316             :    * \returns The shape function second derivatives at the quadrature
     317             :    * points.
     318             :    */
     319      176228 :   const std::vector<std::vector<OutputTensor>> & get_d2phi() const
     320      176228 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     321     2226351 :     calculate_d2phi = calculate_dphiref = true; return d2phi; }
     322             : 
     323           0 :   const std::vector<std::vector<OutputTensor>> & get_dual_d2phi() const
     324           0 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     325           0 :     calculate_d2phi = calculate_dual = calculate_dphiref = true; return dual_d2phi; }
     326             : 
     327             :   /**
     328             :    * \returns The shape function second derivatives at the quadrature
     329             :    * points.
     330             :    */
     331           0 :   const std::vector<std::vector<OutputShape>> & get_d2phidx2() const
     332           0 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     333           0 :     calculate_d2phi = calculate_dphiref = true; return d2phidx2; }
     334             : 
     335             :   /**
     336             :    * \returns The shape function second derivatives at the quadrature
     337             :    * points.
     338             :    */
     339           0 :   const std::vector<std::vector<OutputShape>> & get_d2phidxdy() const
     340           0 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     341           0 :     calculate_d2phi = calculate_dphiref = true; return d2phidxdy; }
     342             : 
     343             :   /**
     344             :    * \returns The shape function second derivatives at the quadrature
     345             :    * points.
     346             :    */
     347           0 :   const std::vector<std::vector<OutputShape>> & get_d2phidxdz() const
     348           0 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     349           0 :     calculate_d2phi = calculate_dphiref = true; return d2phidxdz; }
     350             : 
     351             :   /**
     352             :    * \returns The shape function second derivatives at the quadrature
     353             :    * points.
     354             :    */
     355           0 :   const std::vector<std::vector<OutputShape>> & get_d2phidy2() const
     356           0 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     357           0 :     calculate_d2phi =  calculate_dphiref = true; return d2phidy2; }
     358             : 
     359             :   /**
     360             :    * \returns The shape function second derivatives at the quadrature
     361             :    * points.
     362             :    */
     363           0 :   const std::vector<std::vector<OutputShape>> & get_d2phidydz() const
     364           0 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     365           0 :     calculate_d2phi = calculate_dphiref = true; return d2phidydz; }
     366             : 
     367             :   /**
     368             :    * \returns The shape function second derivatives at the quadrature
     369             :    * points.
     370             :    */
     371           0 :   const std::vector<std::vector<OutputShape>> & get_d2phidz2() const
     372           0 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     373           0 :     calculate_d2phi = calculate_dphiref = true; return d2phidz2; }
     374             : 
     375             :   /**
     376             :    * \returns The shape function second derivatives at the quadrature
     377             :    * points, in reference coordinates
     378             :    */
     379      521543 :   const std::vector<std::vector<OutputShape>> & get_d2phidxi2() const
     380      521543 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     381     6568893 :     calculate_d2phi = calculate_dphiref = true; return d2phidxi2; }
     382             : 
     383             :   /**
     384             :    * \returns The shape function second derivatives at the quadrature
     385             :    * points, in reference coordinates
     386             :    */
     387      513883 :   const std::vector<std::vector<OutputShape>> & get_d2phidxideta() const
     388      513883 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     389      513883 :     calculate_d2phi = calculate_dphiref = true; return d2phidxideta; }
     390             : 
     391             :   /**
     392             :    * \returns The shape function second derivatives at the quadrature
     393             :    * points, in reference coordinates
     394             :    */
     395      432120 :   const std::vector<std::vector<OutputShape>> & get_d2phidxidzeta() const
     396      432120 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     397      432120 :     calculate_d2phi = calculate_dphiref = true; return d2phidxidzeta; }
     398             : 
     399             :   /**
     400             :    * \returns The shape function second derivatives at the quadrature
     401             :    * points, in reference coordinates
     402             :    */
     403      513883 :   const std::vector<std::vector<OutputShape>> & get_d2phideta2() const
     404      513883 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     405      513883 :     calculate_d2phi = calculate_dphiref = true; return d2phideta2; }
     406             : 
     407             :   /**
     408             :    * \returns The shape function second derivatives at the quadrature
     409             :    * points, in reference coordinates
     410             :    */
     411      432120 :   const std::vector<std::vector<OutputShape>> & get_d2phidetadzeta() const
     412      432120 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     413      432120 :     calculate_d2phi = calculate_dphiref = true; return d2phidetadzeta; }
     414             : 
     415             :   /**
     416             :    * \returns The shape function second derivatives at the quadrature
     417             :    * points, in reference coordinates
     418             :    */
     419      432120 :   const std::vector<std::vector<OutputShape>> & get_d2phidzeta2() const
     420      432120 :   { libmesh_assert(!calculations_started || calculate_d2phi);
     421      432120 :     calculate_d2phi = calculate_dphiref = true; return d2phidzeta2; }
     422             : 
     423             : #endif //LIBMESH_ENABLE_SECOND_DERIVATIVES
     424             : 
     425             : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
     426             : 
     427             :   /**
     428             :    * \returns The global first derivative of the phase term
     429             :    * which is used in infinite elements, evaluated at the
     430             :    * quadrature points.
     431             :    *
     432             :    * In case of the general finite element class \p FE this
     433             :    * field is initialized to all zero, so that the variational
     434             :    * formulation for an infinite element produces correct element
     435             :    * matrices for a mesh using both finite and infinite elements.
     436             :    */
     437           0 :   const std::vector<OutputGradient> & get_dphase() const
     438           0 :   { return dphase; }
     439             : 
     440             : 
     441             :   /**
     442             :    * \returns The multiplicative weight at each quadrature point.
     443             :    * This weight is used for certain infinite element weak
     444             :    * formulations, so that weighted Sobolev spaces are
     445             :    * used for the trial function space.  This renders the
     446             :    * variational form easily computable.
     447             :    *
     448             :    * In case of the general finite element class \p FE this
     449             :    * field is initialized to all ones, so that the variational
     450             :    * formulation for an infinite element produces correct element
     451             :    * matrices for a mesh using both finite and infinite elements.
     452             :    */
     453           2 :   virtual const std::vector<Real> & get_Sobolev_weight() const
     454           2 :   { return weight; }
     455             : 
     456             :   /**
     457             :    * \returns The first global derivative of the multiplicative
     458             :    * weight at each quadrature point. See \p get_Sobolev_weight()
     459             :    * for details.  In case of \p FE initialized to all zero.
     460             :    */
     461           0 :   virtual const std::vector<RealGradient> & get_Sobolev_dweight() const
     462           0 :   { return dweight; }
     463             : 
     464             :   /**
     465             :    * \returns The multiplicative weight (see \p get_Sobolev_weight)
     466             :    * but weighted with the radial coordinate square.
     467             :    *
     468             :    * In finite elements, this gives just 1, similar to \p get_Sobolev_Weight()
     469             :    */
     470        1340 :   virtual const std::vector<Real> & get_Sobolev_weightxR_sq() const
     471        1340 :   { return weight; }
     472             : 
     473             :   /**
     474             :    * \returns The first global derivative of the multiplicative weight
     475             :    * (see \p dget_Sobolev_weight) but weighted with the square of the
     476             :    * radial coordinate.
     477             :    *
     478             :    * In finite elements, this is 0.
     479             :    */
     480        1340 :   virtual const std::vector<RealGradient> & get_Sobolev_dweightxR_sq() const
     481        1340 :   { return dweight; }
     482             : 
     483             :   /**
     484             :    * \returns The shape function \p phi (for FE) and \p phi weighted by r/decay
     485             :    *  for InfFE.
     486             :    *
     487             :    * To compensate for the decay function applied to the Jacobian (see \p get_JxWxdecay_sq),
     488             :    * the wave function \p phi should be divided by  this function.
     489             :    *
     490             :    * The factor r must be compensated for by the Sobolev \p weight.
     491             :    * (i.e. by using \p get_Sobolev_weightxR_sq())
     492             :    **/
     493        1340 :   virtual const std::vector<std::vector<OutputShape>> & get_phi_over_decayxR () const
     494        1340 :   { return get_phi();}
     495             : 
     496             :   /**
     497             :    * \returns the gradient of the shape function (see \p get_dphi()),
     498             :    * but in case of \p InfFE, weighted with r/decay.
     499             :    * See \p  get_phi_over_decayxR() for details.
     500             :    */
     501        1340 :   virtual const std::vector<std::vector<OutputGradient>> & get_dphi_over_decayxR () const
     502        1340 :   { return get_dphi();}
     503             : 
     504             :   /**
     505             :    * \returns the gradient of the shape function (see \p get_dphi()),
     506             :    * but in case of \p InfFE, weighted with 1/decay.
     507             :    *
     508             :    * In contrast to the shape function, its gradient stays finite
     509             :    * when divided by the decay function.
     510             :    */
     511           0 :   virtual const std::vector<std::vector<OutputGradient>> & get_dphi_over_decay () const
     512           0 :   { return get_dphi();}
     513             : 
     514             : #endif
     515             : 
     516             :   /**
     517             :    * Prints the value of each shape function at each quadrature point.
     518             :    */
     519             :   virtual void print_phi(std::ostream & os) const override;
     520             :   virtual void print_dual_phi(std::ostream & os) const override;
     521             : 
     522             :   /**
     523             :    * Prints the value of each shape function's derivative
     524             :    * at each quadrature point.
     525             :    */
     526             :   virtual void print_dphi(std::ostream & os) const override;
     527             :   virtual void print_dual_dphi(std::ostream & os) const override;
     528             : 
     529             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     530             : 
     531             :   /**
     532             :    * Prints the value of each shape function's second derivatives
     533             :    * at each quadrature point.
     534             :    */
     535             :   virtual void print_d2phi(std::ostream & os) const override;
     536             :   virtual void print_dual_d2phi(std::ostream & os) const override;
     537             : 
     538             : #endif
     539             : 
     540             : 
     541             : protected:
     542             : 
     543             : 
     544             : 
     545             : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
     546             : 
     547             :   /**
     548             :    * Initialize the data fields for the base of an
     549             :    * an infinite element.  Implement this in the derived
     550             :    * class \p FE<Dim,T>.
     551             :    */
     552             :   virtual void init_base_shape_functions(const std::vector<Point> & qp,
     553             :                                          const Elem * e) = 0;
     554             : 
     555             : #endif
     556             : 
     557             :   /**
     558             :    * Determine which values are to be calculated, for both the FE
     559             :    * itself and for the FEMap.
     560             :    */
     561             :   virtual_for_inffe
     562             :   void determine_calculations();
     563             : 
     564             :   /**
     565             :    * \returns true iff no calculations have been requested of this
     566             :    * FE object or of its associated FEMap
     567             :    */
     568    26448917 :   bool calculating_nothing() const
     569             :   {
     570    28251018 :     return calculate_nothing &&
     571     1802101 :       !this->calculate_phi && !this->calculate_dphi &&
     572             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     573     1802101 :       !this->calculate_d2phi &&
     574             : #endif
     575    28409303 :       !this->calculate_curl_phi && !this->calculate_div_phi &&
     576     4190748 :       !this->calculate_map;
     577             :   }
     578             : 
     579             :   /**
     580             :    * After having updated the jacobian and the transformation
     581             :    * from local to global coordinates in \p FEMap::compute_map(),
     582             :    * the first derivatives of the shape functions are
     583             :    * transformed to global coordinates, giving \p dphi,
     584             :    * \p dphidx, \p dphidy, and \p dphidz. This method
     585             :    * should rarely be re-defined in derived classes, but
     586             :    * still should be usable for children. Therefore, keep
     587             :    * it protected.
     588             :    */
     589             :   virtual void compute_shape_functions(const Elem * elem, const std::vector<Point> & qp) override;
     590             : 
     591             :   /**
     592             :    * Compute the dual basis coefficients \p dual_coeff
     593             :    * we rely on the \p JxW (or weights) and the \p phi values,
     594             :    * which can come from default or customized qrule
     595             :    */
     596             :   void compute_dual_shape_coeffs(const std::vector<Real> & JxW, const std::vector<std::vector<OutputShape>> & phi);
     597             : 
     598             :   /**
     599             :    * Compute \p dual_phi, \p dual_dphi, \p dual_d2phi
     600             :    * It is only valid for this to be called after reinit has occurred with a
     601             :    * quadrature rule
     602             :    */
     603             :   void compute_dual_shape_functions();
     604             : 
     605             :   /**
     606             :    * Object that handles computing shape function values, gradients, etc
     607             :    * in the physical domain.
     608             :    */
     609             :   std::unique_ptr<FETransformationBase<OutputType>> _fe_trans;
     610             : 
     611             :   /**
     612             :    * Shape function values.
     613             :    */
     614             :   std::vector<std::vector<OutputShape>>   phi;
     615             :   std::vector<std::vector<OutputShape>>   dual_phi;
     616             : 
     617             :   /**
     618             :    * Shape function derivative values.
     619             :    */
     620             :   std::vector<std::vector<OutputGradient>>  dphi;
     621             :   std::vector<std::vector<OutputGradient>>  dual_dphi;
     622             : 
     623             :   /**
     624             :    * Coefficient matrix for the dual basis.
     625             :    */
     626             :   mutable DenseMatrix<Real> dual_coeff;
     627             : 
     628             :   /**
     629             :    * Shape function curl values. Only defined for vector types.
     630             :    */
     631             :   std::vector<std::vector<OutputShape>> curl_phi;
     632             : 
     633             :   /**
     634             :    * Shape function divergence values. Only defined for vector types.
     635             :    */
     636             :   std::vector<std::vector<OutputDivergence>> div_phi;
     637             : 
     638             :   /**
     639             :    * Shape function derivatives in the xi direction.
     640             :    */
     641             :   std::vector<std::vector<OutputShape>>   dphidxi;
     642             : 
     643             :   /**
     644             :    * Shape function derivatives in the eta direction.
     645             :    */
     646             :   std::vector<std::vector<OutputShape>>   dphideta;
     647             : 
     648             :   /**
     649             :    * Shape function derivatives in the zeta direction.
     650             :    */
     651             :   std::vector<std::vector<OutputShape>>   dphidzeta;
     652             : 
     653             :   /**
     654             :    * Shape function derivatives in the x direction.
     655             :    */
     656             :   std::vector<std::vector<OutputShape>>   dphidx;
     657             : 
     658             :   /**
     659             :    * Shape function derivatives in the y direction.
     660             :    */
     661             :   std::vector<std::vector<OutputShape>>   dphidy;
     662             : 
     663             :   /**
     664             :    * Shape function derivatives in the z direction.
     665             :    */
     666             :   std::vector<std::vector<OutputShape>>   dphidz;
     667             : 
     668             : 
     669             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     670             : 
     671             :   /**
     672             :    * Shape function second derivative values.
     673             :    */
     674             :   std::vector<std::vector<OutputTensor>>  d2phi;
     675             :   std::vector<std::vector<OutputTensor>>  dual_d2phi;
     676             : 
     677             :   /**
     678             :    * Shape function second derivatives in the xi direction.
     679             :    */
     680             :   std::vector<std::vector<OutputShape>>   d2phidxi2;
     681             : 
     682             :   /**
     683             :    * Shape function second derivatives in the xi-eta direction.
     684             :    */
     685             :   std::vector<std::vector<OutputShape>>   d2phidxideta;
     686             : 
     687             :   /**
     688             :    * Shape function second derivatives in the xi-zeta direction.
     689             :    */
     690             :   std::vector<std::vector<OutputShape>>   d2phidxidzeta;
     691             : 
     692             :   /**
     693             :    * Shape function second derivatives in the eta direction.
     694             :    */
     695             :   std::vector<std::vector<OutputShape>>   d2phideta2;
     696             : 
     697             :   /**
     698             :    * Shape function second derivatives in the eta-zeta direction.
     699             :    */
     700             :   std::vector<std::vector<OutputShape>>   d2phidetadzeta;
     701             : 
     702             :   /**
     703             :    * Shape function second derivatives in the zeta direction.
     704             :    */
     705             :   std::vector<std::vector<OutputShape>>   d2phidzeta2;
     706             : 
     707             :   /**
     708             :    * Shape function second derivatives in the x direction.
     709             :    */
     710             :   std::vector<std::vector<OutputShape>>   d2phidx2;
     711             : 
     712             :   /**
     713             :    * Shape function second derivatives in the x-y direction.
     714             :    */
     715             :   std::vector<std::vector<OutputShape>>   d2phidxdy;
     716             : 
     717             :   /**
     718             :    * Shape function second derivatives in the x-z direction.
     719             :    */
     720             :   std::vector<std::vector<OutputShape>>   d2phidxdz;
     721             : 
     722             :   /**
     723             :    * Shape function second derivatives in the y direction.
     724             :    */
     725             :   std::vector<std::vector<OutputShape>>   d2phidy2;
     726             : 
     727             :   /**
     728             :    * Shape function second derivatives in the y-z direction.
     729             :    */
     730             :   std::vector<std::vector<OutputShape>>   d2phidydz;
     731             : 
     732             :   /**
     733             :    * Shape function second derivatives in the z direction.
     734             :    */
     735             :   std::vector<std::vector<OutputShape>>   d2phidz2;
     736             : 
     737             : #endif
     738             : 
     739             : 
     740             : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
     741             : 
     742             :   //--------------------------------------------------------------
     743             :   /* protected members for infinite elements, which are accessed
     744             :    * from the outside through some inline functions
     745             :    */
     746             : 
     747             : 
     748             :   /**
     749             :    * Used for certain infinite element families:
     750             :    * the first derivatives of the phase term in global coordinates,
     751             :    * over all quadrature points.
     752             :    */
     753             :   std::vector<OutputGradient> dphase;
     754             : 
     755             :   /**
     756             :    * Used for certain infinite element families:
     757             :    * the global derivative of the additional radial weight \f$ 1/{r^2} \f$,
     758             :    * over all quadrature points.
     759             :    */
     760             :   std::vector<RealGradient> dweight;
     761             : 
     762             :   /**
     763             :    * Used for certain infinite element families:
     764             :    * the additional radial weight \f$ 1/{r^2} \f$ in local coordinates,
     765             :    * over all quadrature points.
     766             :    */
     767             :   std::vector<Real>  weight;
     768             : 
     769             : #endif
     770             : 
     771             : private:
     772             : 
     773             : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
     774             : 
     775             :   /**
     776             :    * Make all \p InfFE<Dim,T_radial,T_map> classes friends
     777             :    * so that they can safely used \p FE<Dim-1,T_base> through
     778             :    * a \p FEGenericBase * as base approximation.
     779             :    */
     780             :   template <unsigned int friend_Dim, FEFamily friend_T_radial, InfMapType friend_T_map>
     781             :   friend class InfFE;
     782             : 
     783             : #endif
     784             : 
     785             : 
     786             : };
     787             : 
     788             : // --------------------------------------------------------------------
     789             : // Generic templates. We specialize for OutputType = Real, so these are
     790             : // only used for OutputType = RealVectorValue
     791             : template <typename OutputType>
     792           0 : void FEGenericBase<OutputType>::compute_dual_shape_functions ()
     793             : {
     794           0 :   libmesh_error_msg(
     795             :       "Computation of dual shape functions for vector finite element "
     796             :       "families is not currently implemented");
     797             : }
     798             : 
     799             : template <typename OutputType>
     800           0 : void FEGenericBase<OutputType>::compute_dual_shape_coeffs(const std::vector<Real> & /*JxW*/, const std::vector<std::vector<OutputShape>> & /*phi_vals*/)
     801             : {
     802           0 :   libmesh_error_msg(
     803             :       "Computation of dual shape functions for vector finite element "
     804             :       "families is not currently implemented");
     805             : }
     806             : 
     807             : // -----------------------------------------------------------
     808             : // Forward declaration of specialization
     809             : template <>
     810             : void FEGenericBase<Real>::compute_dual_shape_functions();
     811             : 
     812             : template <>
     813             : void FEGenericBase<Real>::compute_dual_shape_coeffs(const std::vector<Real> & /*JxW*/, const std::vector<std::vector<OutputShape>> & /*phi_vals*/);
     814             : 
     815             : 
     816             : // Typedefs for convenience and backwards compatibility
     817             : typedef FEGenericBase<Real> FEBase;
     818             : typedef FEGenericBase<RealGradient> FEVectorBase;
     819             : 
     820             : 
     821             : 
     822             : 
     823             : // ------------------------------------------------------------
     824             : // FEGenericBase class inline members
     825             : template <typename OutputType>
     826             : inline
     827    15326404 : FEGenericBase<OutputType>::FEGenericBase(const unsigned int d,
     828             :                                          const FEType & fet) :
     829             :   FEAbstract(d,fet),
     830    13587717 :   _fe_trans( FETransformationBase<OutputType>::build(fet) ),
     831    13587717 :   phi(),
     832    13587717 :   dual_phi(),
     833    13587717 :   dphi(),
     834    13587717 :   dual_dphi(),
     835             :   curl_phi(),
     836             :   div_phi(),
     837             :   dphidxi(),
     838             :   dphideta(),
     839             :   dphidzeta(),
     840             :   dphidx(),
     841             :   dphidy(),
     842             :   dphidz()
     843             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     844             :   ,d2phi(),
     845             :   dual_d2phi(),
     846             :   d2phidxi2(),
     847             :   d2phidxideta(),
     848             :   d2phidxidzeta(),
     849             :   d2phideta2(),
     850             :   d2phidetadzeta(),
     851             :   d2phidzeta2(),
     852             :   d2phidx2(),
     853             :   d2phidxdy(),
     854             :   d2phidxdz(),
     855             :   d2phidy2(),
     856             :   d2phidydz(),
     857    13018191 :   d2phidz2()
     858             : #endif
     859             : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
     860             :   ,dphase(),
     861             :   dweight(),
     862     2308213 :   weight()
     863             : #endif
     864             : {
     865    15326404 : }
     866             : 
     867             : 
     868             : 
     869             : template <typename OutputType>
     870             : inline
     871    15326404 : FEGenericBase<OutputType>::~FEGenericBase()
     872             : {
     873    17634024 : }
     874             : 
     875             : } // namespace libMesh
     876             : 
     877             : #endif // LIBMESH_FE_BASE_H

Generated by: LCOV version 1.14