LCOV - code coverage report
Current view: top level - include/utils - Calculators.h (source / functions) Hit Total Coverage
Test: idaholab/moose stochastic_tools: f45d79 Lines: 43 46 93.5 %
Date: 2025-07-25 05:00:46 Functions: 26 26 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #pragma once
      11             : 
      12             : #include "MooseTypes.h"
      13             : #include "MultiMooseEnum.h"
      14             : #include "MathUtils.h"
      15             : 
      16             : #include "libmesh/parallel.h"
      17             : 
      18             : #include <vector>
      19             : #include <memory>
      20             : #include <numeric>
      21             : 
      22             : class MooseEnumItem;
      23             : 
      24             : namespace StochasticTools
      25             : {
      26             : 
      27             : /*
      28             :  * Free function that returns the available statistics available to the Statistics object(s)
      29             :  */
      30             : MultiMooseEnum makeCalculatorEnum();
      31             : 
      32             : /* Base class for computing statistics (e.g., mean, min) for use with Statistics object
      33             :  *
      34             :  * The purpose of these objects are to provide an API for computing statistics in serial or parallel
      35             :  * without any state. This allows future statistics to be quickly added and for each statistic
      36             :  * to be used with the BootstrapCalculator for computing bootstrap statistics such as confidence
      37             :  * level intervals.
      38             :  *
      39             :  * The calculators are evaluating using the following sequence:
      40             :  * \code
      41             :  *     auto calculator = makeCalculator<InType, OutType>(*this, type);
      42             :  *     calculator->initializeCalculator();
      43             :  *     for (const typename InType::value_type & val : data)
      44             :  *       calculator->updateCalculator(data);
      45             :  *     calculator->finalizeCalculator(is_distributed);
      46             :  *     OutType stat = calculator->getValue();
      47             :  * \endcode
      48             :  * The base Calculator class does this automatically with an input vector of data:
      49             :  * \code
      50             :  *     auto calculator = makeCalculator<InType, OutType>(*this, type);
      51             :  *     OutType stat = calculator->compute(data, is_distributed);
      52             :  * \endcode
      53             :  * The base class has state checks to make sure these functions are called
      54             :  * in the correct order.
      55             :  *
      56             :  * To create new Calculator objects first create the Calculator class and then update the
      57             :  * the initialize, update, finalize, and get virtual functions.
      58             :  *
      59             :  * Explicit instantiations are generated in the C file.
      60             :  */
      61             : template <typename InType, typename OutType>
      62             : class Calculator : public libMesh::ParallelObject
      63             : {
      64             : public:
      65       32182 :   Calculator(const libMesh::ParallelObject & other, const std::string & name)
      66    16307826 :     : libMesh::ParallelObject(other), _name(name), _state(CalculatorState::NONE)
      67             :   {
      68             :   }
      69             : 
      70           0 :   virtual ~Calculator() = default;
      71             :   /**
      72             :    * Evaluate the calculator on the full vector of data. This is basically a convenient
      73             :    * wrapper around initializeCalculator, updateCalculator, finalizeCalculator, and getvalue.
      74             :    */
      75             :   OutType compute(const InType &, bool);
      76             : 
      77             :   /**
      78             :    * Public function that must be called before updateCalculator and finalizeCalculator.
      79             :    * Sets _state to INITIALIZED
      80             :    */
      81             :   void initializeCalculator();
      82             :   /**
      83             :    * Public function to update calculator with a piece of data.
      84             :    * _state mush be INITIALIZED
      85             :    */
      86             :   void updateCalculator(const typename InType::value_type &);
      87             :   /**
      88             :    * Public function to finalize the resulting calculator value.
      89             :    * _state must be INITLIALIZED
      90             :    * Sets _state to FINALIZED
      91             :    */
      92             :   void finalizeCalculator(bool);
      93             :   /**
      94             :    * Public function to return the calculated value
      95             :    * _state must be FINALIZED
      96             :    */
      97             :   OutType getValue() const;
      98             : 
      99    16266012 :   const std::string & name() const { return _name; }
     100             : 
     101             : protected:
     102             :   /**
     103             :    * This function is used to reset the calculator to its initial state and prepare it
     104             :    * for another evaluation. This usually involves clearing class members.
     105             :    */
     106             :   virtual void initialize() = 0;
     107             :   /**
     108             :    * Updating the calculator with a piece of data. Sometimes some clever arithmetic
     109             :    * is required to avoid storing data.
     110             :    */
     111             :   virtual void update(const typename InType::value_type &) = 0;
     112             :   /**
     113             :    * This is used to compute the resulting calculator value by performing necessary
     114             :    * arithmetic and parallel communication. This only called once after all the input
     115             :    * data is entered through update.
     116             :    */
     117             :   virtual void finalize(bool) = 0;
     118             :   /**
     119             :    * Returns the resulting calculator value. It is important to not modify member
     120             :    * data here so the calculator can retain its state.
     121             :    */
     122             :   virtual OutType get() const = 0;
     123             : 
     124             : private:
     125             :   enum CalculatorState
     126             :   {
     127             :     NONE,
     128             :     INITIALIZED,
     129             :     FINALIZED
     130             :   };
     131             : 
     132             :   const std::string _name;
     133             :   CalculatorState _state;
     134             : };
     135             : 
     136             : template <typename InType, typename OutType>
     137             : class Mean : public Calculator<InType, OutType>
     138             : {
     139             : public:
     140     8330810 :   using Calculator<InType, OutType>::Calculator;
     141             : 
     142             : protected:
     143             :   virtual void initialize() override;
     144             :   virtual void update(const typename InType::value_type & val) override;
     145             :   virtual void finalize(bool is_distributed) override;
     146    13059411 :   virtual OutType get() const override { return _sum; }
     147             : 
     148             :   dof_id_type _count;
     149             :   OutType _sum;
     150             : };
     151             : 
     152             : template <typename InType, typename OutType>
     153          32 : class MeanAbsoluteValue : public Mean<InType, OutType>
     154             : {
     155             : public:
     156      384480 :   using Mean<InType, OutType>::Mean;
     157             : 
     158             : protected:
     159             :   virtual void update(const typename InType::value_type & val) override;
     160             : };
     161             : 
     162             : template <typename InType, typename OutType>
     163             : class Ratio : public Calculator<InType, OutType>
     164             : {
     165             : public:
     166         952 :   using Calculator<InType, OutType>::Calculator;
     167             : 
     168             : protected:
     169             :   virtual void initialize() override;
     170             :   virtual void update(const typename InType::value_type & val) override;
     171             :   virtual void finalize(bool is_distributed) override;
     172      200272 :   virtual OutType get() const override { return _max / _min; }
     173             : 
     174             :   OutType _min;
     175             :   OutType _max;
     176             : };
     177             : 
     178             : template <typename InType, typename OutType>
     179         119 : class Min : public Ratio<InType, OutType>
     180             : {
     181             : public:
     182         326 :   using Ratio<InType, OutType>::Ratio;
     183             : 
     184             : protected:
     185      200292 :   virtual OutType get() const override { return this->_min; }
     186             : };
     187             : 
     188             : template <typename InType, typename OutType>
     189         119 : class Max : public Ratio<InType, OutType>
     190             : {
     191             : public:
     192         326 :   using Ratio<InType, OutType>::Ratio;
     193             : 
     194             : protected:
     195      200292 :   virtual OutType get() const override { return this->_max; }
     196             : };
     197             : 
     198             : template <typename InType, typename OutType>
     199         119 : class Sum : public Mean<InType, OutType>
     200             : {
     201             : public:
     202        2854 :   using Mean<InType, OutType>::Mean;
     203             : 
     204             : protected:
     205             :   virtual void finalize(bool is_distributed) override;
     206             : };
     207             : 
     208             : template <typename InType, typename OutType>
     209             : class StdDev : public Calculator<InType, OutType>
     210             : {
     211             : public:
     212     7943364 :   using Calculator<InType, OutType>::Calculator;
     213             : 
     214             : protected:
     215             :   virtual void initialize() override;
     216             :   virtual void update(const typename InType::value_type & val) override;
     217             :   virtual void finalize(bool is_distributed) override;
     218    11131009 :   virtual OutType get() const override { return _sum_of_square; }
     219             : 
     220             :   dof_id_type _count;
     221             :   OutType _sum;
     222             :   OutType _sum_of_square;
     223             : };
     224             : 
     225             : template <typename InType, typename OutType>
     226         119 : class StdErr : public StdDev<InType, OutType>
     227             : {
     228             : public:
     229         322 :   using StdDev<InType, OutType>::StdDev;
     230             : 
     231             : protected:
     232             :   virtual void finalize(bool is_distributed) override;
     233             : };
     234             : 
     235             : template <typename InType, typename OutType>
     236             : class L2Norm : public Calculator<InType, OutType>
     237             : {
     238             : public:
     239         326 :   using Calculator<InType, OutType>::Calculator;
     240             : 
     241             : protected:
     242             :   virtual void initialize() override;
     243             :   virtual void update(const typename InType::value_type & val) override;
     244             :   virtual void finalize(bool is_distributed) override;
     245      200292 :   virtual OutType get() const override { return _l2_norm; }
     246             : 
     247             :   OutType _l2_norm;
     248             : };
     249             : 
     250             : template <typename InType, typename OutType>
     251             : class Median : public Calculator<InType, OutType>
     252             : {
     253             : public:
     254         192 :   using Calculator<InType, OutType>::Calculator;
     255             : 
     256             : protected:
     257             :   virtual void initialize() override;
     258             :   virtual void update(const typename InType::value_type & val) override;
     259             :   virtual void finalize(bool is_distributed) override;
     260      200182 :   virtual OutType get() const override { return _median; }
     261             : 
     262             :   std::vector<OutType> _storage;
     263             :   OutType _median;
     264             : };
     265             : 
     266             : /*
     267             :  * Free function for building a const Calculator object for use by Statistics object.
     268             :  *
     269             :  * Explicit instantiations in C file.
     270             :  */
     271             : template <typename InType = std::vector<Real>, typename OutType = Real>
     272             : std::unique_ptr<Calculator<InType, OutType>> makeCalculator(const MooseEnumItem & item,
     273             :                                                             const libMesh::ParallelObject & other);
     274             : 
     275             : /*
     276             :  * Simple struct that makeCalculator wraps around, this is so building calculators
     277             :  * can be partially specialized.
     278             :  */
     279             : template <typename InType, typename OutType>
     280             : struct CalculatorBuilder
     281             : {
     282             :   static std::unique_ptr<Calculator<InType, OutType>> build(const MooseEnumItem & item,
     283             :                                                             const libMesh::ParallelObject & other);
     284             : };
     285             : 
     286             : template <typename InType, typename OutType>
     287             : OutType
     288        5807 : Calculator<InType, OutType>::compute(const InType & data, bool is_distributed)
     289             : {
     290             :   initializeCalculator();
     291     4568560 :   for (const auto & val : data)
     292             :     updateCalculator(val);
     293        5807 :   finalizeCalculator(is_distributed);
     294        5807 :   return getValue();
     295             : }
     296             : 
     297             : template <typename InType, typename OutType>
     298             : void
     299             : Calculator<InType, OutType>::initializeCalculator()
     300             : {
     301    28098276 :   initialize();
     302    11802242 :   _state = CalculatorState::INITIALIZED;
     303    16296034 : }
     304             : 
     305             : template <typename InType, typename OutType>
     306             : void
     307             : Calculator<InType, OutType>::updateCalculator(const typename InType::value_type & val)
     308             : {
     309             :   mooseAssert(_state == CalculatorState::INITIALIZED, "Calculator is in wrong state.");
     310  2039413844 :   update(val);
     311     5322429 : }
     312             : 
     313             : template <typename InType, typename OutType>
     314             : void
     315    28098276 : Calculator<InType, OutType>::finalizeCalculator(bool is_distributed)
     316             : {
     317    28098276 :   if (_state != CalculatorState::INITIALIZED)
     318           0 :     ::mooseError("Calculator is in wrong state.");
     319    28098276 :   finalize(is_distributed);
     320    28098276 :   _state = CalculatorState::FINALIZED;
     321    28098276 : }
     322             : 
     323             : template <typename InType, typename OutType>
     324             : OutType
     325    28095052 : Calculator<InType, OutType>::getValue() const
     326             : {
     327    28095052 :   if (_state != CalculatorState::FINALIZED)
     328           0 :     ::mooseError("Calculator is in wrong state.");
     329    28095052 :   return get();
     330             : }
     331             : 
     332             : // makeCalculator //////////////////////////////////////////////////////////////////////////////////
     333             : template <typename InType, typename OutType>
     334             : std::unique_ptr<Calculator<InType, OutType>>
     335             : makeCalculator(const MooseEnumItem & item, const libMesh::ParallelObject & other)
     336             : {
     337       12055 :   return CalculatorBuilder<InType, OutType>::build(item, other);
     338             : }
     339             : 
     340             : } // namespace

Generated by: LCOV version 1.14