LCOV - code coverage report
Current view: top level - include/systems - fem_context.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4546 (ebe2b5) with base a20bc7 Lines: 77 98 78.6 %
Date: 2026-09-11 19:50:22 Functions: 29 41 70.7 %
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_FEM_CONTEXT_H
      21             : #define LIBMESH_FEM_CONTEXT_H
      22             : 
      23             : // Local Includes
      24             : #include "libmesh/diff_context.h"
      25             : #include "libmesh/id_types.h"
      26             : #include "libmesh/enum_quadrature_type.h"
      27             : #include "libmesh/fe_type.h"
      28             : #include "libmesh/fe_base.h"
      29             : #include "libmesh/vector_value.h"
      30             : 
      31             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
      32             : #include "libmesh/tensor_value.h"
      33             : #endif
      34             : 
      35             : // C++ includes
      36             : #include <map>
      37             : #include <set>
      38             : 
      39             : namespace libMesh
      40             : {
      41             : 
      42             : // Forward Declarations
      43             : class BoundaryInfo;
      44             : class Elem;
      45             : template <typename T> class FEGenericBase;
      46             : typedef FEGenericBase<Real> FEBase;
      47             : class QBase;
      48             : class Point;
      49             : template <typename T> class NumericVector;
      50             : 
      51             : /**
      52             :  * This class provides all data required for a physics package
      53             :  * (e.g. an FEMSystem subclass) to perform local element residual
      54             :  * and jacobian integrations.
      55             :  *
      56             :  * This class is part of the new DifferentiableSystem framework,
      57             :  * which is still experimental.  Users of this framework should
      58             :  * beware of bugs and future API changes.
      59             :  *
      60             :  * \author Roy H. Stogner
      61             :  * \date 2009
      62             :  */
      63             : class FEMContext : public DiffContext
      64             : {
      65             : public:
      66             : 
      67             :   /**
      68             :    * Constructor.  Allocates some but fills no data structures.
      69             :    *
      70             :    * Optionally specify a limited number of variables to be "active"
      71             :    * and thus calculated on.  If \p active_vars is null then
      72             :    * calculations will be prepared for every variable in \p sys.
      73             :    */
      74             :   explicit
      75             :   FEMContext (const System & sys,
      76             :               const std::vector<unsigned int> * active_vars = nullptr,
      77             :               bool allocate_local_matrices = true);
      78             : 
      79             :   /**
      80             :    * Constructor.  Specify the extra quadrature order instead
      81             :    * of getting it from \p sys.
      82             :    *
      83             :    * Optionally specify a limited number of variables to be "active"
      84             :    * and thus calculated on.  If \p active_vars is null then
      85             :    * calculations will be prepared for every variable in \p sys.
      86             :    */
      87             :   explicit
      88             :   FEMContext (const System & sys,
      89             :               int extra_quadrature_order,
      90             :               const std::vector<unsigned int> * active_vars = nullptr,
      91             :               bool allocate_local_matrices = true);
      92             : 
      93             : 
      94             :   /**
      95             :    * Destructor.
      96             :    */
      97             :   virtual ~FEMContext ();
      98             : 
      99             :   /**
     100             :    * Use quadrature rules designed to over-integrate a mass matrix,
     101             :    * plus \p extra_quadrature_order.
     102             :    */
     103             :   void use_default_quadrature_rules(int extra_quadrature_order=0);
     104             : 
     105             :   /**
     106             :    * Use quadrature rules designed to exactly integrate unweighted
     107             :    * undistorted basis functions, plus \p extra_quadrature_order.
     108             :    */
     109             :   void use_unweighted_quadrature_rules(int extra_quadrature_order=0);
     110             : 
     111             :   /**
     112             :    * Use a specified quadrature rule type \p qt for every element,
     113             :    * side, and edge dimension, at the default quadrature order for the
     114             :    * hardest FE type plus \p extra_quadrature_order.
     115             :    *
     116             :    * This is useful when the default Gauss rules (whose points lie in
     117             :    * the element interior) are inadequate.  For example, rules whose
     118             :    * points include the element vertices (\p QTRAP, \p QSIMPSON, \p
     119             :    * QNODAL, \p QGAUSS_LOBATTO) can detect integrand behavior that is
     120             :    * localized at element corners --- a feature interior Gauss points
     121             :    * can miss entirely.  Note that not every quadrature type is defined
     122             :    * for every element type (e.g. \p QGAUSS_LOBATTO is only available for
     123             :    * tensor-product elements); it is the caller's responsibility to pick
     124             :    * a type compatible with the mesh.
     125             :    */
     126             :   void use_quadrature_rules(QuadratureType qt, int extra_quadrature_order=0);
     127             : 
     128             :   /**
     129             :    * Reports if the boundary id is found on the current side
     130             :    */
     131             :   bool has_side_boundary_id(boundary_id_type id) const;
     132             : 
     133             :   /**
     134             :    * As above, but fills in the std::set provided by the user.
     135             :    */
     136             :   void side_boundary_ids(std::vector<boundary_id_type> & vec_to_fill) const;
     137             : 
     138             :   /**
     139             :    * \returns The value of the solution variable \p var at the
     140             :    * quadrature point \p qp on the current element interior.
     141             :    *
     142             :    * \note This API is currently present for backward compatibility.
     143             :    */
     144             :   Number interior_value(unsigned int var, unsigned int qp) const;
     145             : 
     146             :   /**
     147             :    * \returns The value of the solution variable \p var at the quadrature
     148             :    * point \p qp on the current element side.
     149             :    *
     150             :    * \note This API currently is present for backward compatibility.
     151             :    */
     152             :   Number side_value(unsigned int var, unsigned int qp) const;
     153             : 
     154             :   /**
     155             :    * \returns The value of the solution variable \p var at the physical
     156             :    * point \p p on the current element.
     157             :    *
     158             :    * \note This API is currently present for backward compatibility.
     159             :    */
     160             :   Number point_value(unsigned int var, const Point & p) const;
     161             : 
     162             :   /**
     163             :    * \returns The gradient of the solution variable \p var at the quadrature
     164             :    * point \p qp on the current element interior.
     165             :    *
     166             :    * \note This API is currently present for backward compatibility.
     167             :    */
     168             :   Gradient interior_gradient(unsigned int var, unsigned int qp) const;
     169             : 
     170             :   /**
     171             :    * \returns The gradient of the solution variable \p var at the quadrature
     172             :    * point \p qp on the current element side.
     173             :    *
     174             :    * \note This API is currently present for backward compatibility.
     175             :    */
     176             :   Gradient side_gradient(unsigned int var, unsigned int qp) const;
     177             : 
     178             :   /**
     179             :    * \returns The gradient of the solution variable \p var at the physical
     180             :    * point \p p on the current element.
     181             :    *
     182             :    * \note This API is currently present for backward compatibility.
     183             :    */
     184             :   Gradient point_gradient(unsigned int var, const Point & p) const;
     185             : 
     186             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     187             :   /**
     188             :    * \returns The hessian of the solution variable \p var at the quadrature
     189             :    * point \p qp on the current element interior.
     190             :    *
     191             :    * \note This API is currently present for backward compatibility.
     192             :    */
     193             :   Tensor interior_hessian(unsigned int var, unsigned int qp) const;
     194             : 
     195             :   /**
     196             :    * \returns The hessian of the solution variable \p var at the quadrature
     197             :    * point \p qp on the current element side.
     198             :    *
     199             :    * \note This API is currently present for backward compatibility.
     200             :    */
     201             :   Tensor side_hessian(unsigned int var, unsigned int qp) const;
     202             : 
     203             :   /**
     204             :    * \returns The hessian of the solution variable \p var at the physical
     205             :    * point \p p on the current element.
     206             :    *
     207             :    * \note This API currently present for backward compatibility.
     208             :    */
     209             :   Tensor point_hessian(unsigned int var, const Point & p) const;
     210             : 
     211             : #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
     212             : 
     213             :   /**
     214             :    * \returns The value of the fixed_solution variable \p var at the quadrature
     215             :    * point \p qp on the current element interior.
     216             :    *
     217             :    * \note This API is currently present for backward compatibility.
     218             :    */
     219             :   Number fixed_interior_value(unsigned int var, unsigned int qp) const;
     220             : 
     221             :   /**
     222             :    * \returns The value of the fixed_solution variable \p var at the quadrature
     223             :    * point \p qp on the current element side.
     224             :    *
     225             :    * \note This API is currently present for backward compatibility.
     226             :    */
     227             :   Number fixed_side_value(unsigned int var, unsigned int qp) const;
     228             : 
     229             :   /**
     230             :    * \returns The value of the fixed_solution variable \p var at the physical
     231             :    * point \p p on the current element.
     232             :    *
     233             :    * \note This API is currently present for backward compatibility.
     234             :    */
     235             :   Number fixed_point_value(unsigned int var, const Point & p) const;
     236             : 
     237             :   /**
     238             :    * \returns The gradient of the fixed_solution variable \p var at the quadrature
     239             :    * point \p qp on the current element interior.
     240             :    *
     241             :    * \note This API is currently present for backward compatibility.
     242             :    */
     243             :   Gradient fixed_interior_gradient(unsigned int var, unsigned int qp) const;
     244             : 
     245             :   /**
     246             :    * \returns The gradient of the fixed_solution variable \p var at the quadrature
     247             :    * point \p qp on the current element side.
     248             :    *
     249             :    * \note This API is currently present for backward compatibility.
     250             :    */
     251             :   Gradient fixed_side_gradient(unsigned int var, unsigned int qp) const;
     252             : 
     253             :   /**
     254             :    * \returns The gradient of the fixed_solution variable \p var at the physical
     255             :    * point \p p on the current element.
     256             :    *
     257             :    * \note This API is currently present for backward compatibility.
     258             :    */
     259             :   Gradient fixed_point_gradient(unsigned int var, const Point & p) const;
     260             : 
     261             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     262             :   /**
     263             :    * \returns The hessian of the fixed_solution variable \p var at the quadrature
     264             :    * point \p qp on the current element interior.
     265             :    *
     266             :    * \note This API is currently present for backward compatibility.
     267             :    */
     268             :   Tensor fixed_interior_hessian(unsigned int var, unsigned int qp) const;
     269             : 
     270             :   /**
     271             :    * \returns The hessian of the fixed_solution variable \p var at the quadrature
     272             :    * point \p qp on the current element side.
     273             :    *
     274             :    * \note This API is currently present for backward compatibility.
     275             :    */
     276             :   Tensor fixed_side_hessian(unsigned int var, unsigned int qp) const;
     277             : 
     278             :   /**
     279             :    * \returns The hessian of the fixed_solution variable \p var at the physical
     280             :    * point \p p on the current element.
     281             :    *
     282             :    * \note This API is currently present for backward compatibility.
     283             :    */
     284             :   Tensor fixed_point_hessian (unsigned int var, const Point & p) const;
     285             : 
     286             : #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
     287             : 
     288             :   /**
     289             :    * Accessor for interior finite element object for variable var for
     290             :    * the largest dimension in the mesh. We default to the largest mesh dim
     291             :    * if this method is called before the Elem * is set in the FEMContext,
     292             :    * e.g. in FEMSystem::init_context (or a subclass).
     293             :    */
     294             :   template<typename OutputShape>
     295    15589464 :   void get_element_fe( unsigned int var, FEGenericBase<OutputShape> *& fe ) const
     296    15589464 :   { this->get_element_fe<OutputShape>(var,fe,this->get_elem_dim()); }
     297             : 
     298             :   /**
     299             :    * Accessor for interior finite element object for scalar-valued variable var
     300             :    * for the largest dimension in the mesh. We default to the largest mesh dim
     301             :    * if this method is called before the Elem * is set in the FEMContext,
     302             :    * e.g. in FEMSystem::init_context (or a subclass).
     303             :    */
     304           0 :   FEBase * get_element_fe( unsigned int var ) const
     305           0 :   { return this->get_element_fe(var,this->get_elem_dim()); }
     306             : 
     307             :   /**
     308             :    * Accessor for interior finite element object for variable var for
     309             :    * dimension dim.
     310             :    */
     311             :   template<typename OutputShape>
     312             :   void get_element_fe( unsigned int var, FEGenericBase<OutputShape> *& fe,
     313             :                        unsigned short dim ) const;
     314             : 
     315             :   /**
     316             :    * Accessor for interior finite element object for variable var for
     317             :    * dimension dim.
     318             :    */
     319             :   void get_element_fe( unsigned int var, FEAbstract *& fe,
     320             :                        unsigned short dim ) const;
     321             : 
     322             :   /**
     323             :    * Accessor for interior finite element object for scalar-valued variable var for
     324             :    * dimension dim.
     325             :    */
     326             :   FEBase * get_element_fe( unsigned int var, unsigned short dim ) const;
     327             : 
     328             :   /**
     329             :    * Accessor for edge/face (2D/3D) finite element object for variable var
     330             :    * for the largest dimension in the mesh. We default to the largest mesh dim
     331             :    * if this method is called before the Elem * is set in the FEMContext,
     332             :    * e.g. in FEMSystem::init_context (or a subclass).
     333             :    */
     334             :   template<typename OutputShape>
     335      569205 :   void get_side_fe( unsigned int var, FEGenericBase<OutputShape> *& fe ) const
     336      569205 :   { this->get_side_fe<OutputShape>(var,fe,this->get_elem_dim()); }
     337             : 
     338             :   /**
     339             :    * Accessor for side finite element object for scalar-valued variable var
     340             :    * for the largest dimension in the mesh. We default to the largest mesh dim
     341             :    * if this method is called before the Elem * is set in the FEMContext,
     342             :    * e.g. in FEMSystem::init_context (or a subclass).
     343             :    */
     344           0 :   FEBase * get_side_fe( unsigned int var ) const
     345           0 :   { return this->get_side_fe(var,this->get_elem_dim()); }
     346             : 
     347             :   /**
     348             :    * Accessor for edge/face (2D/3D) finite element object for variable var
     349             :    * for dimension dim.
     350             :    */
     351             :   template<typename OutputShape>
     352             :   void get_side_fe( unsigned int var, FEGenericBase<OutputShape> *& fe,
     353             :                     unsigned short dim ) const;
     354             : 
     355             :   /**
     356             :    * Accessor for edge/face (2D/3D) finite element object for variable var
     357             :    * for dimension dim.
     358             :    */
     359             :   void get_side_fe( unsigned int var, FEAbstract *& fe,
     360             :                     unsigned short dim ) const;
     361             : 
     362             :   /**
     363             :    * Accessor for side finite element object for scalar-valued variable var
     364             :    * for dimension dim.
     365             :    */
     366             :   FEBase * get_side_fe( unsigned int var, unsigned short dim ) const;
     367             : 
     368             :   /**
     369             :    * Accessor for edge (3D only!) finite element object for variable var.
     370             :    */
     371             :   template<typename OutputShape>
     372             :   void get_edge_fe( unsigned int var, FEGenericBase<OutputShape> *& fe ) const;
     373             : 
     374             :   void get_edge_fe( unsigned int var, FEAbstract *& fe ) const;
     375             : 
     376             :   /**
     377             :    * Accessor for edge (3D only!) finite element object for scalar-valued variable var.
     378             :    */
     379             :   FEBase * get_edge_fe( unsigned int var ) const;
     380             : 
     381             :   /**
     382             :    * \returns The value of the solution variable \p var at the quadrature
     383             :    * point \p qp on the current element interior.
     384             :    *
     385             :    * \note This is the preferred API.
     386             :    */
     387             :   template<typename OutputType>
     388             :   void interior_value(unsigned int var,
     389             :                       unsigned int qp,
     390             :                       OutputType & u) const;
     391             : 
     392             :   /**
     393             :    * Fills a vector of values of the _system_vector at the all the quadrature
     394             :    * points in the current element interior.
     395             :    */
     396             :   template<typename OutputType>
     397             :   void interior_values(unsigned int var,
     398             :                        const NumericVector<Number> & _system_vector,
     399             :                        std::vector<OutputType> & interior_values_vector) const;
     400             : 
     401             :   /**
     402             :    * \returns The value of the solution variable \p var at the quadrature
     403             :    * point \p qp on the current element side.
     404             :    *
     405             :    * \note This is the preferred API.
     406             :    */
     407             :   template<typename OutputType>
     408             :   void side_value(unsigned int var,
     409             :                   unsigned int qp,
     410             :                   OutputType & u) const;
     411             : 
     412             :   /**
     413             :    * Fills a vector of values of the _system_vector at the all the quadrature
     414             :    * points on the current element side.
     415             :    */
     416             :   template<typename OutputType>
     417             :   void side_values(unsigned int var,
     418             :                    const NumericVector<Number> & _system_vector,
     419             :                    std::vector<OutputType> & side_values_vector) const;
     420             : 
     421             :   /**
     422             :    * \returns The value of the solution variable \p var at the physical
     423             :    * point \p p on the current element.
     424             :    *
     425             :    * \note This is the preferred API.
     426             :    *
     427             :    * Allows evaluation of points within a relative tolerance outside
     428             :    * the element.
     429             :    */
     430             :   template<typename OutputType>
     431             :   void point_value(unsigned int var,
     432             :                    const Point & p,
     433             :                    OutputType & u,
     434             :                    const Real tolerance = TOLERANCE) const;
     435             : 
     436             :   /**
     437             :    * \returns The gradient of the solution variable \p var at the quadrature
     438             :    * point \p qp on the current element interior.
     439             :    *
     440             :    * \note This is the preferred API.
     441             :    */
     442             :   template<typename OutputType>
     443             :   void interior_gradient(unsigned int var, unsigned int qp,
     444             :                          OutputType & du) const;
     445             : 
     446             :   /**
     447             :    * Fills a vector with the gradient of the solution variable \p var at all the quadrature
     448             :    * points in the current element interior.
     449             :    *
     450             :    * \note This is the preferred API.
     451             :    */
     452             :   template<typename OutputType>
     453             :   void interior_gradients(unsigned int var,
     454             :                           const NumericVector<Number> & _system_vector,
     455             :                           std::vector<OutputType> & interior_gradients_vector) const;
     456             : 
     457             :   /**
     458             :    * \returns The gradient of the solution variable \p var at the quadrature
     459             :    * point \p qp on the current element side.
     460             :    *
     461             :    * \note This is the preferred API.
     462             :    */
     463             :   template<typename OutputType>
     464             :   void side_gradient(unsigned int var,
     465             :                      unsigned int qp,
     466             :                      OutputType & du) const;
     467             : 
     468             :   /**
     469             :    * Fills a vector with the gradient of the solution variable \p var at all the quadrature
     470             :    * points on the current element side.
     471             :    *
     472             :    * \note This is the preferred API.
     473             :    */
     474             :   template<typename OutputType>
     475             :   void side_gradients(unsigned int var,
     476             :                       const NumericVector<Number> & _system_vector,
     477             :                       std::vector<OutputType> & side_gradients_vector) const;
     478             : 
     479             :   /**
     480             :    * \returns The gradient of the solution variable \p var at the physical
     481             :    * point \p p on the current element.
     482             :    *
     483             :    * \note This is the preferred API.
     484             :    *
     485             :    * Allows evaluation of points within a relative tolerance outside
     486             :    * the element.
     487             :    */
     488             :   template<typename OutputType>
     489             :   void point_gradient(unsigned int var,
     490             :                       const Point & p,
     491             :                       OutputType & grad_u,
     492             :                       const Real tolerance = TOLERANCE) const;
     493             : 
     494             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     495             :   /**
     496             :    * \returns The hessian of the solution variable \p var at the quadrature
     497             :    * point \p qp on the current element interior.
     498             :    *
     499             :    * \note This is the preferred API.
     500             :    */
     501             :   template<typename OutputType>
     502             :   void interior_hessian(unsigned int var,
     503             :                         unsigned int qp,
     504             :                         OutputType & d2u) const;
     505             : 
     506             :   /**
     507             :    * Fills a vector of hessians of the _system_vector at the all the
     508             :    * quadrature points in the current element interior. This is the
     509             :    * preferred API.
     510             :    */
     511             :   template<typename OutputType>
     512             :   void interior_hessians(unsigned int var,
     513             :                          const NumericVector<Number> & _system_vector,
     514             :                          std::vector<OutputType> & d2u_vals) const;
     515             : 
     516             :   /**
     517             :    * \returns The hessian of the solution variable \p var at the quadrature
     518             :    * point \p qp on the current element side.
     519             :    *
     520             :    * \note This is the preferred API.
     521             :    */
     522             :   template<typename OutputType>
     523             :   void side_hessian(unsigned int var,
     524             :                     unsigned int qp,
     525             :                     OutputType & d2u) const;
     526             : 
     527             :   /**
     528             :    * Fills a vector of hessians of the _system_vector at the all the
     529             :    * quadrature points on the current element side.  This is the
     530             :    * preferred API.
     531             :    */
     532             :   template<typename OutputType>
     533             :   void side_hessians(unsigned int var,
     534             :                      const NumericVector<Number> & _system_vector,
     535             :                      std::vector<OutputType> & d2u_vals) const;
     536             : 
     537             :   /**
     538             :    * \returns The hessian of the solution variable \p var at the physical
     539             :    * point \p p on the current element.
     540             :    *
     541             :    * \note This is the preferred API.
     542             :    *
     543             :    * Allows evaluation of points within a relative tolerance outside
     544             :    * the element.
     545             :    */
     546             :   template<typename OutputType>
     547             :   void point_hessian(unsigned int var,
     548             :                      const Point & p,
     549             :                      OutputType & hess_u,
     550             :                      const Real tolerance = TOLERANCE) const;
     551             : 
     552             : #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
     553             : 
     554             :   /**
     555             :    * \returns The time derivative (rate) of the solution variable
     556             :    * \p var at the quadrature point \p qp on the current element
     557             :    * interior.
     558             :    */
     559             :   template<typename OutputType>
     560             :   void interior_rate(unsigned int var,
     561             :                      unsigned int qp,
     562             :                      OutputType & u) const;
     563             : 
     564             : 
     565             :   /**
     566             :    * \returns The time derivative (rate) of the solution gradient
     567             :    * of variable \p var at the quadrature point \p qp on the current
     568             :    * element interior.
     569             :    */
     570             :   template<typename OutputType>
     571             :   void interior_rate_gradient(unsigned int var,
     572             :                               unsigned int qp,
     573             :                               OutputType & u) const;
     574             : 
     575             : 
     576             :   /**
     577             :    * \returns The time derivative (rate) of the solution variable
     578             :    * \p var at the quadrature point \p qp on the current element side.
     579             :    */
     580             :   template<typename OutputType>
     581             :   void side_rate(unsigned int var,
     582             :                  unsigned int qp,
     583             :                  OutputType & u) const;
     584             : 
     585             :   /**
     586             :    * \returns The time derivative (rate) of the solution variable
     587             :    * \p var at the physical point \p p on the current element.
     588             :    */
     589             :   template<typename OutputType>
     590             :   void point_rate(unsigned int var,
     591             :                   const Point & p,
     592             :                   OutputType & u) const;
     593             : 
     594             :   /**
     595             :    * \returns The second time derivative (acceleration) of the solution variable
     596             :    * \p var at the quadrature point \p qp on the current element
     597             :    * interior.
     598             :    */
     599             :   template<typename OutputType>
     600             :   void interior_accel(unsigned int var,
     601             :                       unsigned int qp,
     602             :                       OutputType & u) const;
     603             : 
     604             :   /**
     605             :    * \returns The second time derivative (acceleration) of the solution variable
     606             :    * \p var at the quadrature point \p qp on the current element side.
     607             :    */
     608             :   template<typename OutputType>
     609             :   void side_accel(unsigned int var,
     610             :                   unsigned int qp,
     611             :                   OutputType & u) const;
     612             : 
     613             :   /**
     614             :    * \returns The second time derivative (acceleration) of the solution variable
     615             :    * \p var at the physical point \p p on the current element.
     616             :    */
     617             :   template<typename OutputType>
     618             :   void point_accel(unsigned int var,
     619             :                    const Point & p,
     620             :                    OutputType & u) const;
     621             : 
     622             :   /**
     623             :    * \returns The value of the fixed_solution variable \p var at the quadrature
     624             :    * point \p qp on the current element interior.
     625             :    *
     626             :    * \note This is the preferred API.
     627             :    */
     628             :   template<typename OutputType>
     629             :   void fixed_interior_value(unsigned int var,
     630             :                             unsigned int qp,
     631             :                             OutputType & u) const;
     632             : 
     633             :   /**
     634             :    * \returns The value of the fixed_solution variable \p var at the quadrature
     635             :    * point \p qp on the current element side.
     636             :    *
     637             :    * \note This is the preferred API.
     638             :    */
     639             :   template<typename OutputType>
     640             :   void fixed_side_value(unsigned int var,
     641             :                         unsigned int qp,
     642             :                         OutputType & u) const;
     643             : 
     644             :   /**
     645             :    * \returns The value of the fixed_solution variable \p var at the physical
     646             :    * point \p p on the current element.
     647             :    *
     648             :    * \note This is the preferred API.
     649             :    *
     650             :    * Allows evaluation of points within a relative tolerance outside
     651             :    * the element.
     652             :    */
     653             :   template<typename OutputType>
     654             :   void fixed_point_value(unsigned int var,
     655             :                          const Point & p,
     656             :                          OutputType & u,
     657             :                          const Real tolerance = TOLERANCE) const;
     658             : 
     659             :   /**
     660             :    * \returns The gradient of the fixed_solution variable \p var at the quadrature
     661             :    * point \p qp on the current element interior.
     662             :    *
     663             :    * \note This is the preferred API.
     664             :    */
     665             :   template<typename OutputType>
     666             :   void fixed_interior_gradient(unsigned int var,
     667             :                                unsigned int qp,
     668             :                                OutputType & grad_u) const;
     669             : 
     670             :   /**
     671             :    * \returns The gradient of the fixed_solution variable \p var at the quadrature
     672             :    * point \p qp on the current element side.
     673             :    *
     674             :    * \note This is the preferred API.
     675             :    */
     676             :   template<typename OutputType>
     677             :   void fixed_side_gradient(unsigned int var,
     678             :                            unsigned int qp,
     679             :                            OutputType & grad_u) const;
     680             : 
     681             :   /**
     682             :    * \returns The gradient of the fixed_solution variable \p var at the physical
     683             :    * point \p p on the current element.
     684             :    *
     685             :    * \note This is the preferred API.
     686             :    *
     687             :    * Allows evaluation of points within a relative tolerance outside
     688             :    * the element.
     689             :    */
     690             :   template<typename OutputType>
     691             :   void fixed_point_gradient(unsigned int var,
     692             :                             const Point & p,
     693             :                             OutputType & grad_u,
     694             :                             const Real tolerance = TOLERANCE) const;
     695             : 
     696             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
     697             :   /**
     698             :    * \returns The hessian of the fixed_solution variable \p var at the quadrature
     699             :    * point \p qp on the current element interior.
     700             :    *
     701             :    * \note This is the preferred API.
     702             :    */
     703             :   template<typename OutputType>
     704             :   void fixed_interior_hessian(unsigned int var,
     705             :                               unsigned int qp,
     706             :                               OutputType & hess_u) const;
     707             : 
     708             :   /**
     709             :    * \returns The hessian of the fixed_solution variable \p var at the quadrature
     710             :    * point \p qp on the current element side.
     711             :    *
     712             :    * \note This is the preferred API.
     713             :    */
     714             :   template<typename OutputType>
     715             :   void fixed_side_hessian(unsigned int var,
     716             :                           unsigned int qp,
     717             :                           OutputType & hess_u) const;
     718             : 
     719             :   /**
     720             :    * \returns The hessian of the fixed_solution variable \p var at the physical
     721             :    * point \p p on the current element.
     722             :    *
     723             :    * \note This is the preferred API.
     724             :    *
     725             :    * Allows evaluation of points within a relative tolerance outside
     726             :    * the element.
     727             :    */
     728             :   template<typename OutputType>
     729             :   void fixed_point_hessian(unsigned int var,
     730             :                            const Point & p,
     731             :                            OutputType & hess_u,
     732             :                            const Real tolerance = TOLERANCE) const;
     733             : 
     734             : #endif // LIBMESH_ENABLE_SECOND_DERIVATIVES
     735             : 
     736             :   /**
     737             :    * \returns The curl of the solution variable \p var at the physical
     738             :    * point \p p on the current element.
     739             :    */
     740             :   template<typename OutputType>
     741             :   void interior_curl(unsigned int var,
     742             :                      unsigned int qp,
     743             :                      OutputType & curl_u) const;
     744             : 
     745             :   /**
     746             :    * \returns The curl of the solution variable \p var at the physical
     747             :    * point \p p on the current element.
     748             :    *
     749             :    * Allows evaluation of points within a relative tolerance outside
     750             :    * the element.
     751             :    */
     752             :   template<typename OutputType>
     753             :   void point_curl(unsigned int var,
     754             :                   const Point & p,
     755             :                   OutputType & curl_u,
     756             :                   const Real tolerance = TOLERANCE) const;
     757             : 
     758             :   /**
     759             :    * \returns The divergence of the solution variable \p var at the physical
     760             :    * point \p p on the current element.
     761             :    */
     762             :   template<typename OutputType>
     763             :   void interior_div(unsigned int var,
     764             :                     unsigned int qp,
     765             :                     OutputType & div_u) const;
     766             : 
     767             :   // should be protected:
     768             :   /**
     769             :    * Resets the current time in the context. Additionally, reinitialize Elem
     770             :    * and FE objects if there's a moving mesh present in the system such that
     771             :    * the mesh is deformed to its position at \f$ t_{\theta} \f$.
     772             :    */
     773             :   virtual void elem_reinit(Real theta) override;
     774             : 
     775             :   /**
     776             :    * Resets the current time in the context. Additionally, reinitialize Elem
     777             :    * and FE objects if there's a moving mesh present in the system such that
     778             :    * the mesh is deformed to its position at \f$ t_{\theta} \f$.
     779             :    */
     780             :   virtual void elem_side_reinit(Real theta) override;
     781             : 
     782             :   /**
     783             :    * Resets the current time in the context. Additionally, reinitialize Elem
     784             :    * and FE objects if there's a moving mesh present in the system such that
     785             :    * the mesh is deformed to its position at \f$ t_{\theta} \f$.
     786             :    */
     787             :   virtual void elem_edge_reinit(Real theta) override;
     788             : 
     789             :   /**
     790             :    * Gives derived classes the opportunity to reinitialize data needed
     791             :    * for nonlocal calculations at a new point within a timestep
     792             :    */
     793             :   virtual void nonlocal_reinit(Real theta) override;
     794             : 
     795             :   /**
     796             :    * Reinitializes local data vectors/matrices on the current geometric element
     797             :    */
     798             :   virtual void pre_fe_reinit(const System &,
     799             :                              const Elem * e);
     800             : 
     801             :   /**
     802             :    * Reinitializes interior FE objects on the current geometric element
     803             :    */
     804             :   virtual void elem_fe_reinit(const std::vector<Point> * const pts = nullptr);
     805             : 
     806             :   /**
     807             :    * Reinitializes side FE objects on the current geometric element
     808             :    */
     809             :   virtual void side_fe_reinit();
     810             : 
     811             :   /**
     812             :    * Reinitializes edge FE objects on the current geometric element
     813             :    */
     814             :   virtual void edge_fe_reinit();
     815             : 
     816             :   /**
     817             :    * Accessor for element interior quadrature rule for the dimension of the
     818             :    * current _elem.
     819             :    */
     820           0 :   const QBase & get_element_qrule() const
     821           0 :   { return this->get_element_qrule(this->get_elem_dim()); }
     822             : 
     823             :   /**
     824             :    * Accessor for element side quadrature rule for the dimension of the
     825             :    * current _elem.
     826             :    */
     827         743 :   const QBase & get_side_qrule() const
     828         743 :   { return this->get_side_qrule(this->get_elem_dim()); }
     829             : 
     830             :   /**
     831             :    * Accessor for element interior quadrature rule.
     832             :    */
     833           0 :   const QBase & get_element_qrule( unsigned short dim ) const
     834           0 :   { libmesh_assert(_element_qrule[dim]);
     835    16201782 :     return *(this->_element_qrule[dim]); }
     836             : 
     837             :   /**
     838             :    * Accessor for element side quadrature rule.
     839             :    */
     840         743 :   const QBase & get_side_qrule( unsigned short dim ) const
     841             :   {
     842         743 :     libmesh_assert(_side_qrule[dim]);
     843       11004 :     return *(this->_side_qrule[dim]);
     844             :   }
     845             : 
     846             :   /**
     847             :    * Accessor for element edge quadrature rule.
     848             :    */
     849           0 :   const QBase & get_edge_qrule() const
     850           0 :   { return *(this->_edge_qrule); }
     851             : 
     852             :   /**
     853             :    * Tells the FEMContext that system \p sys contains the
     854             :    * isoparametric Lagrangian variables which correspond to the
     855             :    * coordinates of mesh nodes, in problems where the mesh itself is
     856             :    * expected to move in time.
     857             :    *
     858             :    * This should be set automatically if the FEMPhysics requires it.
     859             :    */
     860      320500 :   virtual void set_mesh_system(System * sys)
     861      320500 :   { this->_mesh_sys = sys; }
     862             : 
     863             :   /**
     864             :    * Accessor for moving mesh System
     865             :    */
     866             :   const System * get_mesh_system() const
     867             :   { return this->_mesh_sys; }
     868             : 
     869             :   /**
     870             :    * Accessor for moving mesh System
     871             :    */
     872             :   System * get_mesh_system()
     873             :   { return this->_mesh_sys; }
     874             : 
     875             :   /**
     876             :    * Accessor for x-variable of moving mesh System
     877             :    */
     878           0 :   unsigned int get_mesh_x_var() const
     879       23616 :   { return _mesh_x_var; }
     880             : 
     881             :   /**
     882             :    * Accessor for x-variable of moving mesh System
     883             :    *
     884             :    * This should be set automatically if the FEMPhysics requires it.
     885             :    */
     886       10450 :   void set_mesh_x_var(unsigned int x_var)
     887      320500 :   { _mesh_x_var = x_var; }
     888             : 
     889             :   /**
     890             :    * Accessor for y-variable of moving mesh System
     891             :    */
     892           0 :   unsigned int get_mesh_y_var() const
     893       23616 :   { return _mesh_y_var; }
     894             : 
     895             :   /**
     896             :    * Accessor for y-variable of moving mesh System
     897             :    *
     898             :    * This should be set automatically if the FEMPhysics requires it.
     899             :    */
     900       10450 :   void set_mesh_y_var(unsigned int y_var)
     901      320500 :   { _mesh_y_var = y_var; }
     902             : 
     903             :   /**
     904             :    * Accessor for z-variable of moving mesh System
     905             :    */
     906           0 :   unsigned int get_mesh_z_var() const
     907       23616 :   { return _mesh_z_var; }
     908             : 
     909             :   /**
     910             :    * Accessor for z-variable of moving mesh System
     911             :    *
     912             :    * This should be set automatically if the FEMPhysics requires it.
     913             :    */
     914       10450 :   void set_mesh_z_var(unsigned int z_var)
     915      320500 :   { _mesh_z_var = z_var; }
     916             : 
     917             :   /**
     918             :    * Test for current Elem object
     919             :    */
     920    18753172 :   bool has_elem() const
     921   181100200 :   { return (this->_elem != nullptr); }
     922             : 
     923             :   /**
     924             :    * Accessor for current Elem object
     925             :    */
     926     5764112 :   const Elem & get_elem() const
     927     5764112 :   { libmesh_assert(this->_elem);
     928    16344923 :     return *(this->_elem); }
     929             : 
     930             :   /**
     931             :    * Accessor for current Elem object
     932             :    */
     933    25910629 :   Elem & get_elem()
     934    25910629 :   { libmesh_assert(this->_elem);
     935   143016860 :     return *(const_cast<Elem *>(this->_elem)); }
     936             : 
     937             :   /**
     938             :    * Accessor for current side of Elem object
     939             :    */
     940     1144038 :   unsigned char get_side() const
     941     9306544 :   { return side; }
     942             : 
     943             :   /**
     944             :    * Accessor for current edge of Elem object
     945             :    */
     946       11524 :   unsigned char get_edge() const
     947      146872 :   { return edge; }
     948             : 
     949             :   /**
     950             :    * Accessor for cached mesh dimension. This is the largest dimension
     951             :    * of the elements in the mesh. For the dimension of this->_elem, use
     952             :    * get_elem_dim();
     953             :    */
     954       34346 :   unsigned char get_dim() const
     955      378126 :   { return this->_dim; }
     956             : 
     957             :   /**
     958             :    * \returns The dimension of this->_elem. For mixed dimension meshes, this
     959             :    * may be different from get_dim().  If no element init has happened
     960             :    * yet, fall back on get_dim().
     961             :    */
     962     1916460 :   unsigned char get_elem_dim() const
     963   619612553 :   { return this->_elem ? this->_elem_dim : this->_dim; }
     964             : 
     965             :   /**
     966             :    * \returns Set of dimensions of elements present in the mesh at
     967             :    * context initialization.
     968             :    */
     969       96662 :   const std::set<unsigned char> & elem_dimensions() const
     970       96662 :   { return _elem_dims; }
     971             : 
     972             :   /**
     973             :    * Uses the coordinate data specified by mesh_*_position configuration
     974             :    * to set the geometry of \p elem to the value it would take after a fraction
     975             :    * \p theta of a timestep.
     976             :    */
     977             :   void elem_position_set(Real theta);
     978             : 
     979             :   /**
     980             :    * Uses the geometry of \p elem to set the coordinate data specified
     981             :    * by mesh_*_position configuration.
     982             :    */
     983             :   void elem_position_get();
     984             : 
     985             :   /**
     986             :    * Enum describing what data to use when initializing algebraic
     987             :    * structures on each element.
     988             :    */
     989             :   enum AlgebraicType { NONE = 0,  // Do not reinitialize dof_indices
     990             :                        DOFS_ONLY, // Reinitialize dof_indices, not
     991             :                                   // algebraic structures
     992             :                        CURRENT,   // Use dof_indices, current solution
     993             :                        OLD,       // Use old_dof_indices, custom solution
     994             :                        OLD_DOFS_ONLY}; // Reinitialize old_dof_indices, not
     995             :                                        // algebraic structures
     996             : 
     997             :   /**
     998             :    * Setting which determines whether to initialize algebraic
     999             :    * structures (elem_*) on each element and set their values from
    1000             :    * current_local_solution.  Algebraic initialization may be disabled
    1001             :    * for efficiency in cases where FEMContext is only used as a
    1002             :    * convenient container of FE objects.
    1003             :    */
    1004       24740 :   void set_algebraic_type(const AlgebraicType atype)
    1005      330691 :   { _atype = atype; }
    1006             : 
    1007             :   /*
    1008             :    * Get the current AlgebraicType setting
    1009             :    */
    1010   418526547 :   AlgebraicType algebraic_type() const { return _atype; }
    1011             : 
    1012             :   /**
    1013             :    * Set a NumericVector to be used in place of current_local_solution
    1014             :    * for calculating elem_solution.  Set to nullptr to restore the
    1015             :    * current_local_solution behavior.  Advanced DifferentiableSystem
    1016             :    * specific capabilities will only be enabled in the
    1017             :    * current_local_solution case.
    1018             :    */
    1019       13858 :   void set_custom_solution(const NumericVector<Number> * custom_sol)
    1020       76065 :   { _custom_solution = custom_sol; }
    1021             : 
    1022             :   /**
    1023             :    * Calls set_jacobian_tolerance() on all the FE objects controlled
    1024             :    * by this class. (Actually, it calls this on the underlying)
    1025             :    */
    1026             :   void set_jacobian_tolerance(Real tol);
    1027             : 
    1028             :   /**
    1029             :    * Current side for side_* to examine
    1030             :    */
    1031             :   unsigned char side;
    1032             : 
    1033             :   /**
    1034             :    * Current edge for edge_* to examine
    1035             :    */
    1036             :   unsigned char edge;
    1037             : 
    1038             :   /**
    1039             :    * Helper function for creating quadrature rules
    1040             :    */
    1041             :   FEType find_hardest_fe_type();
    1042             : 
    1043             :   /**
    1044             :    * Helper function for attaching quadrature rules
    1045             :    */
    1046             :   void attach_quadrature_rules();
    1047             : 
    1048             :   /**
    1049             :    * Return a pointer to the vector of active variables being computed
    1050             :    * for, or a null pointer if all variables in the system are active.
    1051             :    */
    1052       63698 :   const std::vector<unsigned int> * active_vars() const { return _active_vars.get(); }
    1053             : 
    1054             :   /**
    1055             :    * Helper function to reduce some code duplication in the *_point_* methods.
    1056             :    *
    1057             :    * get_derivative_level should be -1 to get_ everything, 0 to
    1058             :    * get_phi, 1 to get_dphi, 2 to get_d2phi, or 3 to get_curl_phi
    1059             :    */
    1060             :   template<typename OutputShape>
    1061             :   FEGenericBase<OutputShape> * build_new_fe(const FEGenericBase<OutputShape> * fe,
    1062             :                                             const Point & p,
    1063             :                                             const Real tolerance = TOLERANCE,
    1064             :                                             const int get_derivative_level = -1) const;
    1065             : 
    1066             : protected:
    1067             : 
    1068             :   /**
    1069             :    * Variables on which to enable calculations, or nullptr if all
    1070             :    * variables in the System are to be enabled
    1071             :    */
    1072             :   std::unique_ptr<const std::vector<unsigned int>> _active_vars;
    1073             : 
    1074             :   /**
    1075             :    * System from which to acquire moving mesh information
    1076             :    */
    1077             :   System * _mesh_sys;
    1078             : 
    1079             :   /**
    1080             :    * Variables from which to acquire moving mesh information
    1081             :    */
    1082             :   unsigned int _mesh_x_var, _mesh_y_var, _mesh_z_var;
    1083             : 
    1084             :   /**
    1085             :    * Keep track of what type of algebra reinitialization is to be done
    1086             :    */
    1087             :   AlgebraicType _atype;
    1088             : 
    1089             :   /**
    1090             :    * Data with which to do algebra reinitialization
    1091             :    */
    1092             :   const NumericVector<Number> * _custom_solution;
    1093             : 
    1094             :   mutable std::unique_ptr<FEGenericBase<Real>>         _real_fe;
    1095             :   mutable std::unique_ptr<FEGenericBase<RealGradient>> _real_grad_fe;
    1096             :   mutable int _real_fe_derivative_level;
    1097             :   mutable int _real_grad_fe_derivative_level;
    1098             : 
    1099             : #ifdef LIBMESH_ENABLE_INFINITE_ELEMENTS
    1100             :   mutable bool _real_fe_is_inf;
    1101             :   mutable bool _real_grad_fe_is_inf;
    1102             : #endif
    1103             : 
    1104             :   template<typename OutputShape>
    1105             :   FEGenericBase<OutputShape> * cached_fe( const unsigned int elem_dim,
    1106             :                                           const FEType fe_type,
    1107             :                                           const int get_derivative_level ) const;
    1108             : 
    1109             :   /**
    1110             :    * Helper function to promote accessor usage
    1111             :    */
    1112             :   void set_elem( const Elem * e );
    1113             : 
    1114             :   // gcc-3.4, oracle 12.3 require this typedef to be public
    1115             :   // in order to use it in a return type
    1116             : public:
    1117             : 
    1118             :   /**
    1119             :    * Helper typedef to simplify refactoring
    1120             :    */
    1121             :   typedef const DenseSubVector<Number> & (DiffContext::*diff_subsolution_getter)(unsigned int) const;
    1122             : 
    1123             : protected:
    1124             :   /**
    1125             :    * Helper nested class for C++03-compatible "template typedef"
    1126             :    */
    1127             :   template <typename OutputType>
    1128             :   struct FENeeded
    1129             :   {
    1130             :     // Rank decrementer helper types
    1131             :     typedef typename TensorTools::DecrementRank<OutputType>::type Rank1Decrement;
    1132             :     typedef typename TensorTools::DecrementRank<Rank1Decrement>::type Rank2Decrement;
    1133             : 
    1134             :     // Typedefs for "Value getter" function pointer
    1135             :     typedef typename TensorTools::MakeReal<OutputType>::type value_shape;
    1136             :     typedef FEGenericBase<value_shape> value_base;
    1137             :     typedef void (FEMContext::*value_getter) (unsigned int, value_base *&, unsigned short) const;
    1138             : 
    1139             :     // Typedefs for "Grad getter" function pointer
    1140             :     typedef typename TensorTools::MakeReal<Rank1Decrement>::type grad_shape;
    1141             :     typedef FEGenericBase<grad_shape> grad_base;
    1142             :     typedef void (FEMContext::*grad_getter) (unsigned int, grad_base *&, unsigned short) const;
    1143             : 
    1144             :     // Typedefs for "Hessian getter" function pointer
    1145             :     typedef typename TensorTools::MakeReal<Rank2Decrement>::type hess_shape;
    1146             :     typedef FEGenericBase<hess_shape> hess_base;
    1147             :     typedef void (FEMContext::*hess_getter) (unsigned int, hess_base *&, unsigned short) const;
    1148             :   };
    1149             : 
    1150             : 
    1151             : 
    1152             :   /**
    1153             :    * Helper function to reduce some code duplication in the
    1154             :    * *interior_value methods.
    1155             :    */
    1156             :   template<typename OutputType,
    1157             :            typename FENeeded<OutputType>::value_getter fe_getter,
    1158             :            diff_subsolution_getter subsolution_getter>
    1159             :   void some_value(unsigned int var, unsigned int qp, OutputType & u) const;
    1160             : 
    1161             :   /**
    1162             :    * Helper function to reduce some code duplication in the
    1163             :    * *interior_gradient methods.
    1164             :    */
    1165             :   template<typename OutputType,
    1166             :            typename FENeeded<OutputType>::grad_getter fe_getter,
    1167             :            diff_subsolution_getter subsolution_getter>
    1168             :   void some_gradient(unsigned int var, unsigned int qp, OutputType & u) const;
    1169             : 
    1170             : #ifdef LIBMESH_ENABLE_SECOND_DERIVATIVES
    1171             :   /**
    1172             :    * Helper function to reduce some code duplication in the
    1173             :    * *interior_hessian methods.
    1174             :    */
    1175             :   template<typename OutputType,
    1176             :            typename FENeeded<OutputType>::hess_getter fe_getter,
    1177             :            diff_subsolution_getter subsolution_getter>
    1178             :   void some_hessian(unsigned int var, unsigned int qp, OutputType & u) const;
    1179             : #endif
    1180             : 
    1181             :   /**
    1182             :    * Finite element objects for each variable's interior, sides and edges.
    1183             :    * We store FE objects for each element dimension present in the mesh,
    1184             :    * except for edge_fe which only applies to 3D elements.
    1185             :    */
    1186             :   std::vector<std::map<FEType, std::unique_ptr<FEAbstract>>> _element_fe;
    1187             :   std::vector<std::map<FEType, std::unique_ptr<FEAbstract>>> _side_fe;
    1188             :   std::map<FEType, std::unique_ptr<FEAbstract>> _edge_fe;
    1189             : 
    1190             : 
    1191             :   /**
    1192             :    * Pointers to the same finite element objects, but indexed
    1193             :    * by variable number. We store FE objects for each element dimension
    1194             :    * present in the mesh, except for edge_fe_var which only applies
    1195             :    * for 3D elements.
    1196             :    */
    1197             :   std::vector<std::vector<FEAbstract *>> _element_fe_var;
    1198             :   std::vector<std::vector<FEAbstract *>> _side_fe_var;
    1199             :   std::vector<FEAbstract *> _edge_fe_var;
    1200             : 
    1201             :   /**
    1202             :    * Saved reference to BoundaryInfo on the mesh for this System.
    1203             :    * Used to answer boundary id requests.
    1204             :    */
    1205             :   const BoundaryInfo & _boundary_info;
    1206             : 
    1207             :   /**
    1208             :    * Current element for element_* to examine
    1209             :    */
    1210             :   const Elem * _elem;
    1211             : 
    1212             :   /**
    1213             :    * Cached dimension of largest dimension element in this mesh
    1214             :    */
    1215             :   unsigned char _dim;
    1216             : 
    1217             :   /**
    1218             :    * Cached dimension of this->_elem.
    1219             :    */
    1220             :   unsigned char _elem_dim;
    1221             : 
    1222             :   /**
    1223             :    * Cached dimensions of elements in the mesh, plus dimension 0 if
    1224             :    * SCALAR variables are in use.
    1225             :    */
    1226             :   std::set<unsigned char> _elem_dims;
    1227             : 
    1228             :   /**
    1229             :    * Quadrature rule for element interior.
    1230             :    * The FEM context will try to find a quadrature rule that
    1231             :    * correctly integrates all variables. We prepare quadrature
    1232             :    * rules for each element dimension in the mesh.
    1233             :    */
    1234             :   std::vector<std::unique_ptr<QBase>> _element_qrule;
    1235             : 
    1236             :   /**
    1237             :    * Quadrature rules for element sides
    1238             :    * The FEM context will try to find a quadrature rule that
    1239             :    * correctly integrates all variables. We prepare quadrature
    1240             :    * rules for each element dimension in the mesh.
    1241             :    */
    1242             :   std::vector<std::unique_ptr<QBase>> _side_qrule;
    1243             : 
    1244             :   /**
    1245             :    * Quadrature rules for element edges.  If the FEM context is told
    1246             :    * to prepare for edge integration on 3D elements, it will try to
    1247             :    * find a quadrature rule that correctly integrates all variables.
    1248             :    * Because edge rules only apply to 3D elements, we don't need to
    1249             :    * worry about multiple dimensions
    1250             :    */
    1251             :   std::unique_ptr<QBase> _edge_qrule;
    1252             : 
    1253             :   /**
    1254             :    * The extra quadrature order for this context.
    1255             :    */
    1256             :   int _extra_quadrature_order;
    1257             : 
    1258             : private:
    1259             :   /**
    1260             :    * Helper function used in constructors to set up internal data.
    1261             :    */
    1262             :   void init_internal_data(const System & sys);
    1263             : 
    1264             :   /**
    1265             :    * Uses the coordinate data specified by mesh_*_position configuration
    1266             :    * to set the geometry of \p elem to the value it would take after a fraction
    1267             :    * \p theta of a timestep.
    1268             :    *
    1269             :    * This does the work of elem_position_set, but isn't safe to call
    1270             :    * without _mesh_sys/etc. defined first.
    1271             :    */
    1272             :   void _do_elem_position_set(Real theta);
    1273             : 
    1274             :   /**
    1275             :    * Update the time in the context object for the given value of
    1276             :    * theta, based on the values of "time" and "deltat" stored in the
    1277             :    * system which created this context.
    1278             :    */
    1279             :   void _update_time_from_system(Real theta);
    1280             : };
    1281             : 
    1282             : 
    1283             : 
    1284             : // ------------------------------------------------------------
    1285             : // FEMContext inline methods
    1286             : 
    1287             : inline
    1288           0 : void FEMContext::elem_position_set(Real theta)
    1289             : {
    1290       23040 :   if (_mesh_sys)
    1291       23040 :     this->_do_elem_position_set(theta);
    1292           0 : }
    1293             : 
    1294             : template<typename OutputShape>
    1295             : inline
    1296      470455 : void FEMContext::get_element_fe( unsigned int var, FEGenericBase<OutputShape> *& fe,
    1297             :                                  unsigned short dim ) const
    1298             : {
    1299      470455 :   libmesh_assert( !_element_fe_var[dim].empty() );
    1300      470455 :   libmesh_assert_less ( var, (_element_fe_var[dim].size() ) );
    1301   654385763 :   fe = cast_ptr<FEGenericBase<OutputShape> *>( (_element_fe_var[dim][var] ) );
    1302      470455 : }
    1303             : 
    1304             : inline
    1305       89320 : void FEMContext::get_element_fe( unsigned int var, FEAbstract *& fe,
    1306             :                                  unsigned short dim ) const
    1307             : {
    1308       89320 :   libmesh_assert( !_element_fe_var[dim].empty() );
    1309       89320 :   libmesh_assert_less ( var, (_element_fe_var[dim].size() ) );
    1310     3236655 :   fe = _element_fe_var[dim][var];
    1311       89320 : }
    1312             : 
    1313             : inline
    1314           0 : FEBase * FEMContext::get_element_fe( unsigned int var, unsigned short dim ) const
    1315             : {
    1316           0 :   libmesh_assert( !_element_fe_var[dim].empty() );
    1317           0 :   libmesh_assert_less ( var, (_element_fe_var[dim].size() ) );
    1318      421230 :   return cast_ptr<FEBase *>( (_element_fe_var[dim][var] ) );
    1319             : }
    1320             : 
    1321             : template<typename OutputShape>
    1322             : inline
    1323     1823638 : void FEMContext::get_side_fe( unsigned int var, FEGenericBase<OutputShape> *& fe,
    1324             :                               unsigned short dim ) const
    1325             : {
    1326     1823638 :   libmesh_assert( !_side_fe_var[dim].empty() );
    1327     1823638 :   libmesh_assert_less ( var, (_side_fe_var[dim].size() ) );
    1328    19146836 :   fe = cast_ptr<FEGenericBase<OutputShape> *>( (_side_fe_var[dim][var] ) );
    1329     1823638 : }
    1330             : 
    1331             : inline
    1332       37638 : void FEMContext::get_side_fe( unsigned int var, FEAbstract *& fe,
    1333             :                               unsigned short dim ) const
    1334             : {
    1335       37638 :   libmesh_assert( !_side_fe_var[dim].empty() );
    1336       37638 :   libmesh_assert_less ( var, (_side_fe_var[dim].size() ) );
    1337     1354276 :   fe = _side_fe_var[dim][var];
    1338     1241362 : }
    1339             : 
    1340             : inline
    1341           0 : FEBase * FEMContext::get_side_fe( unsigned int var, unsigned short dim ) const
    1342             : {
    1343           0 :   libmesh_assert( !_side_fe_var[dim].empty() );
    1344           0 :   libmesh_assert_less ( var, (_side_fe_var[dim].size() ) );
    1345         416 :   return cast_ptr<FEBase *>( (_side_fe_var[dim][var] ) );
    1346             : }
    1347             : 
    1348             : template<typename OutputShape>
    1349             : inline
    1350        8748 : void FEMContext::get_edge_fe( unsigned int var, FEGenericBase<OutputShape> *& fe ) const
    1351             : {
    1352        8748 :   libmesh_assert_less ( var, _edge_fe_var.size() );
    1353      129722 :   fe = cast_ptr<FEGenericBase<OutputShape> *>( _edge_fe_var[var] );
    1354        8748 : }
    1355             : 
    1356             : inline
    1357       15464 : void FEMContext::get_edge_fe( unsigned int var, FEAbstract *& fe ) const
    1358             : {
    1359       15464 :   libmesh_assert_less ( var, _edge_fe_var.size() );
    1360      582831 :   fe = _edge_fe_var[var];
    1361      551903 : }
    1362             : 
    1363             : inline
    1364             : FEBase * FEMContext::get_edge_fe( unsigned int var ) const
    1365             : {
    1366             :   libmesh_assert_less ( var, _edge_fe_var.size() );
    1367             :   return cast_ptr<FEBase *>( _edge_fe_var[var] );
    1368             : }
    1369             : 
    1370             : 
    1371             : } // namespace libMesh
    1372             : 
    1373             : #endif // LIBMESH_FEM_CONTEXT_H

Generated by: LCOV version 1.14