LCOV - code coverage report
Current view: top level - include/quadrature - quadrature.h (source / functions) Hit Total Coverage
Test: libMesh/libmesh: #4229 (6a9aeb) with base 727f46 Lines: 17 18 94.4 %
Date: 2025-08-19 19:27:09 Functions: 11 13 84.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_QUADRATURE_H
      21             : #define LIBMESH_QUADRATURE_H
      22             : 
      23             : // Local includes
      24             : #include "libmesh/libmesh_common.h"
      25             : #include "libmesh/reference_counted_object.h"
      26             : #include "libmesh/point.h"
      27             : #include "libmesh/enum_elem_type.h" // INVALID_ELEM
      28             : #include "libmesh/enum_order.h" // INVALID_ORDER
      29             : 
      30             : // C++ includes
      31             : #include <vector>
      32             : #include <string>
      33             : #include <utility>
      34             : #include <memory>
      35             : 
      36             : // We used to have additional arguments to the init_0D, init_1D, etc.
      37             : // classes, but they became unused after QBase members made them
      38             : // redundant, so they were deprecated and eventually removed.  Users'
      39             : // derived classes that need to compile against both old and new
      40             : // libMesh version can test this macro to determine what signature
      41             : // their overrides should have.
      42             : #define LIBMESH_QBASE_INIT_ARGUMENTS_REMOVED
      43             : 
      44             : namespace libMesh
      45             : {
      46             : 
      47             : // forward declarations
      48             : class Elem;
      49             : enum QuadratureType : int;
      50             : 
      51             : /**
      52             :  * The \p QBase class provides the basic functionality from which
      53             :  * various quadrature rules can be derived.  It computes and stores
      54             :  * the quadrature points (in reference element space) and associated
      55             :  * weights.
      56             :  *
      57             :  * \author Benjamin S. Kirk
      58             :  * \date 2002
      59             :  * \brief Base class for all quadrature families and orders.
      60             :  */
      61             : class QBase : public ReferenceCountedObject<QBase>
      62             : {
      63             : protected:
      64             : 
      65             :   /**
      66             :    * Constructor. Protected to prevent instantiation of this base
      67             :    * class.  Use the build() method instead.
      68             :    */
      69             :   QBase (unsigned int dim,
      70             :          Order order=INVALID_ORDER);
      71             : 
      72             : public:
      73             : 
      74             :   /**
      75             :    * Copy/move ctor, copy/move assignment operator, and destructor are
      76             :    * all explicitly defaulted for this simple class.
      77             :    */
      78           0 :   QBase (const QBase &) = default;
      79             :   QBase (QBase &&) = default;
      80             :   QBase & operator= (const QBase &) = default;
      81             :   QBase & operator= (QBase &&) = default;
      82     4002233 :   virtual ~QBase() = default;
      83             : 
      84             :   /**
      85             :    * \returns A copy of this quadrature rule wrapped in a smart pointer.
      86             :    */
      87             :   virtual std::unique_ptr<QBase> clone() const;
      88             : 
      89             :   /**
      90             :    * \returns The quadrature type in derived classes.
      91             :    */
      92             :   virtual QuadratureType type() const = 0;
      93             : 
      94             :   /**
      95             :    * Builds a specific quadrature rule based on the \p name
      96             :    * string. This enables selection of the quadrature rule at
      97             :    * run-time.  The input parameter \p name must be mappable through
      98             :    * the \p Utility::string_to_enum<>() function.
      99             :    *
     100             :    * This function allocates memory, therefore a \p std::unique_ptr<QBase>
     101             :    * is returned so that the user does not accidentally leak it.
     102             :    */
     103             :   static std::unique_ptr<QBase> build (std::string_view name,
     104             :                                        const unsigned int dim,
     105             :                                        const Order order=INVALID_ORDER);
     106             : 
     107             :   /**
     108             :    * Builds a specific quadrature rule based on the QuadratureType.
     109             :    * This enables selection of the quadrature rule at run-time.
     110             :    *
     111             :    * This function allocates memory, therefore a \p std::unique_ptr<QBase>
     112             :    * is returned so that the user does not accidentally leak it.
     113             :    */
     114             :   static std::unique_ptr<QBase> build (const QuadratureType qt,
     115             :                                        const unsigned int dim,
     116             :                                        const Order order=INVALID_ORDER);
     117             : 
     118             :   /**
     119             :    * \returns The element type we're currently using.
     120             :    */
     121             :   ElemType get_elem_type() const { return _type; }
     122             : 
     123             :   /**
     124             :    * \returns The p-refinement level we're currently using.
     125             :    */
     126             :   unsigned int get_p_level() const { return _p_level; }
     127             : 
     128             :   /**
     129             :    * \returns The number of points associated with the quadrature rule.
     130             :    */
     131        6039 :   unsigned int n_points() const
     132             :   {
     133        6039 :     libmesh_assert (!_points.empty());
     134     3490469 :     return cast_int<unsigned int>(_points.size());
     135             :   }
     136             : 
     137             :   /**
     138             :    * Alias for n_points() to enable use in index_range
     139             :    *
     140             :    * \returns The number of points associated with the quadrature rule.
     141             :    */
     142             :   unsigned int size() const
     143             :   {
     144             :     return n_points();
     145             :   }
     146             : 
     147             :   /**
     148             :    * \returns The spatial dimension of the quadrature rule.
     149             :    */
     150          30 :   unsigned int get_dim() const { return _dim; }
     151             : 
     152             :   /**
     153             :    * \returns A \p std::vector containing the quadrature point locations
     154             :    * in reference element space.
     155             :    */
     156         758 :   const std::vector<Point> & get_points() const { return _points; }
     157             : 
     158             :   /**
     159             :    * \returns A \p std::vector containing the quadrature point locations
     160             :    * in reference element space as a writable reference.
     161             :    */
     162   121414216 :   std::vector<Point> & get_points() { return _points; }
     163             : 
     164             :   /**
     165             :    * \returns A constant reference to a \p std::vector containing the
     166             :    * quadrature weights.
     167             :    */
     168      164918 :   const std::vector<Real> & get_weights() const { return _weights; }
     169             : 
     170             :   /**
     171             :    * \returns A writable references to a \p std::vector containing the
     172             :    * quadrature weights.
     173             :    */
     174   145683261 :   std::vector<Real> & get_weights() { return _weights; }
     175             : 
     176             :   /**
     177             :    * \returns The \f$ i^{th} \f$ quadrature point in reference element space.
     178             :    */
     179     2210070 :   Point qp(const unsigned int i) const
     180             :   {
     181     2210070 :     libmesh_assert_less (i, _points.size());
     182    28610674 :     return _points[i];
     183             :   }
     184             : 
     185             :   /**
     186             :    * \returns The \f$ i^{th} \f$ quadrature weight.
     187             :    */
     188     2207257 :   Real w(const unsigned int i) const
     189             :   {
     190     2207257 :     libmesh_assert_less (i, _weights.size());
     191    26833724 :     return _weights[i];
     192             :   }
     193             : 
     194             :   /**
     195             :    * Initializes the data structures for a quadrature rule for the
     196             :    * element \p e.  If \p p_level is specified it overrides the element
     197             :    * p_level() elevation to use.
     198             :    */
     199             :   virtual void init (const Elem & e,
     200             :                      unsigned int p_level=invalid_uint);
     201             : 
     202             :   /**
     203             :    * Initializes the data structures for a quadrature rule for an
     204             :    * element of type \p type.  Some types, such as Polygon subclasses,
     205             :    * might require more detailed element information and so might not
     206             :    * be compatible with this API.
     207             :    *
     208             :    * New code should use the Elem-based API for most use cases, but
     209             :    * some code may initialize quadrature rules with simple ElemType
     210             :    * values like triangles and edges for use in tensor product or
     211             :    * conical product constructions; this code can set the
     212             :    * \p simple_type_only flag to avoid being identified as deprecated.
     213             :    */
     214             :   virtual void init (const ElemType type=INVALID_ELEM,
     215             :                      unsigned int p_level=0,
     216             :                      bool simple_type_only=false);
     217             : 
     218             :   /**
     219             :    * Initializes the data structures for a quadrature rule based on
     220             :    * the element, element type, and p_level settings of \p other_rule
     221             :    */
     222             :   virtual void init (const QBase & other_rule);
     223             : 
     224             :   /**
     225             :    * Initializes the data structures for an element potentially "cut"
     226             :    * by a signed distance function.  The array \p vertex_distance_func
     227             :    * contains vertex values of the signed distance function.  If the
     228             :    * signed distance function changes sign on the vertices, then the
     229             :    * element is considered to be cut.) This interface can be extended
     230             :    * by derived classes in order to subdivide the element and construct
     231             :    * a composite quadrature rule.
     232             :    */
     233             :   virtual void init (const Elem & elem,
     234             :                      const std::vector<Real> & vertex_distance_func,
     235             :                      unsigned int p_level=0);
     236             : 
     237             :   /**
     238             :    * \returns The current "total" order of the quadrature rule which
     239             :    * can vary element by element, depending on the Elem::p_level(),
     240             :    * which gets passed to us during init().
     241             :    *
     242             :    * Each additional power of p increases the quadrature order
     243             :    * required to integrate the mass matrix by 2, hence the formula
     244             :    * below.
     245             :    *
     246             :    * \todo This function should also be used in all of the Order
     247             :    * switch statements in the rules themselves.
     248             :    */
     249     6300292 :   Order get_order() const { return static_cast<Order>(_order + 2 * _p_level); }
     250             : 
     251             :   /**
     252             :    * \returns The "base" order of the quadrature rule, independent of
     253             :    * element.
     254             :    *
     255             :    * This function should be used when comparing quadrature objects
     256             :    * independently of their last initialization.
     257             :    */
     258             :   Order get_base_order() const { return static_cast<Order>(_order); }
     259             : 
     260             :   /**
     261             :    * Prints information relevant to the quadrature rule, by default to
     262             :    * libMesh::out.
     263             :    */
     264             :   void print_info(std::ostream & os=libMesh::out) const;
     265             : 
     266             :   /**
     267             :    * Maps the points of a 1D quadrature rule defined by "old_range" to
     268             :    * another 1D interval defined by "new_range" and scales the weights
     269             :    * accordingly.
     270             :    */
     271             :   void scale(std::pair<Real, Real> old_range,
     272             :              std::pair<Real, Real> new_range);
     273             : 
     274             :   /**
     275             :    * Same as above, but allows you to use the stream syntax.
     276             :    */
     277             :   friend std::ostream & operator << (std::ostream & os, const QBase & q);
     278             : 
     279             :   /**
     280             :    * \returns \p true if the shape functions need to be recalculated,
     281             :    * \p false otherwise.
     282             :    *
     283             :    * This may be required if the number of quadrature points or their
     284             :    * position changes.
     285             :    */
     286   143912918 :   virtual bool shapes_need_reinit() { return false; }
     287             : 
     288             :   /**
     289             :    * Flag (default true) controlling the use of quadrature rules with
     290             :    * negative weights.  Set this to false to require rules with all
     291             :    * positive weights.
     292             :    *
     293             :    * Rules with negative weights can be unsuitable for some problems.
     294             :    * For example, it is possible for a rule with negative weights to
     295             :    * obtain a negative result when integrating a positive function.
     296             :    *
     297             :    * A particular example: if rules with negative weights are not allowed,
     298             :    * a request for TET,THIRD (5 points) will return the TET,FIFTH (14 points)
     299             :    * rule instead, nearly tripling the computational effort required!
     300             :    */
     301             :   bool allow_rules_with_negative_weights;
     302             : 
     303             :   /**
     304             :    * The flag's value defaults to false so that one does not accidentally
     305             :    * use a nodal quadrature rule on Pyramid elements, since evaluating the
     306             :    * inverse element Jacobian (e.g. dphi) is not well-defined at the
     307             :    * Pyramid apex because the element Jacobian is zero there.
     308             :    *
     309             :    * We do not want to completely prevent someone from using a nodal
     310             :    * quadrature rule on Pyramids, however, since there are legitimate
     311             :    * use cases (lumped mass matrix) so the flag can be set to true to
     312             :    * override this behavior.
     313             :    */
     314             :   bool allow_nodal_pyramid_quadrature;
     315             : 
     316             : protected:
     317             : 
     318             : 
     319             :   /**
     320             :    * Initializes the 0D quadrature rule by filling the points and
     321             :    * weights vectors with the appropriate values.  Generally this
     322             :    * is just one point with weight 1.
     323             :    */
     324             :   virtual void init_0D ();
     325             : 
     326             :   /**
     327             :    * Initializes the 1D quadrature rule by filling the points and
     328             :    * weights vectors with the appropriate values.  The order of
     329             :    * the rule will be defined by the implementing class.
     330             :    * It is assumed that derived quadrature rules will at least
     331             :    * define the init_1D function, therefore it is pure virtual.
     332             :    */
     333             :   virtual void init_1D () = 0;
     334             : 
     335             :   /**
     336             :    * Initializes the 2D quadrature rule by filling the points and
     337             :    * weights vectors with the appropriate values.  The order of
     338             :    * the rule will be defined by the implementing class.
     339             :    * Should not be pure virtual since a derived quadrature rule
     340             :    * may only be defined in 1D.  If not overridden, throws an
     341             :    * error.
     342             :    */
     343             :   virtual void init_2D ();
     344             : 
     345             :   /**
     346             :    * Initializes the 3D quadrature rule by filling the points and
     347             :    * weights vectors with the appropriate values.  The order of
     348             :    * the rule will be defined by the implementing class.
     349             :    * Should not be pure virtual since a derived quadrature rule
     350             :    * may only be defined in 1D.  If not overridden, throws an
     351             :    * error.
     352             :    */
     353             :   virtual void init_3D ();
     354             : 
     355             :   /**
     356             :    * Constructs a 2D rule from the tensor product of \p q1D with
     357             :    * itself.  Used in the \p init_2D() routines for quadrilateral
     358             :    * element types.
     359             :    */
     360             :   void tensor_product_quad (const QBase & q1D);
     361             : 
     362             :   /**
     363             :    * Computes the tensor product quadrature rule [q1D x q1D x q1D]
     364             :    * from the 1D rule q1D.  Used in the init_3D routines for
     365             :    * hexahedral element types.
     366             :    */
     367             :   void tensor_product_hex (const QBase & q1D);
     368             : 
     369             :   /**
     370             :    * Computes the tensor product of a 1D quadrature rule and a 2D
     371             :    * quadrature rule.  Used in the init_3D routines for prismatic
     372             :    * element types.
     373             :    */
     374             :   void tensor_product_prism (const QBase & q1D, const QBase & q2D);
     375             : 
     376             :   /**
     377             :    * The spatial dimension of the quadrature rule.
     378             :    */
     379             :   unsigned int _dim;
     380             : 
     381             :   /**
     382             :    * The polynomial order which the quadrature rule is capable of
     383             :    * integrating exactly.
     384             :    */
     385             :   Order _order;
     386             : 
     387             :   /**
     388             :    * The type of element for which the current values have been
     389             :    * computed.
     390             :    */
     391             :   ElemType _type;
     392             : 
     393             :   /**
     394             :    * The element for which the current values were computed, or
     395             :    * nullptr if values were computed without a specific element.
     396             :    */
     397             :   const Elem * _elem;
     398             : 
     399             :   /**
     400             :    * The p-level of the element for which the current values have
     401             :    * been computed.
     402             :    */
     403             :   unsigned int _p_level;
     404             : 
     405             :   /**
     406             :    * The locations of the quadrature points in reference element
     407             :    * space.
     408             :    */
     409             :   std::vector<Point> _points;
     410             : 
     411             :   /**
     412             :    * The quadrature weights.  The order of the weights matches the
     413             :    * ordering of the _points vector.
     414             :    */
     415             :   std::vector<Real> _weights;
     416             : };
     417             : 
     418             : } // namespace libMesh
     419             : 
     420             : #endif // LIBMESH_QUADRATURE_H

Generated by: LCOV version 1.14