LCOV - code coverage report
Current view: top level - include/utils - Calculators.h (source / functions) Hit Total Coverage
Test: idaholab/moose stochastic_tools: #31405 (292dce) with base fef103 Lines: 43 46 93.5 %
Date: 2025-09-04 07:57:52 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       34193 :   Calculator(const libMesh::ParallelObject & other, const std::string & name)
      66    17663832 :     : 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    17619448 :   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     9019872 :   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    14144980 :   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          34 : class MeanAbsoluteValue : public Mean<InType, OutType>
     154             : {
     155             : public:
     156      408510 :   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        1016 :   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      220292 :   virtual OutType get() const override { return _max / _min; }
     173             : 
     174             :   OutType _min;
     175             :   OutType _max;
     176             : };
     177             : 
     178             : template <typename InType, typename OutType>
     179         126 : class Min : public Ratio<InType, OutType>
     180             : {
     181             : public:
     182         348 :   using Ratio<InType, OutType>::Ratio;
     183             : 
     184             : protected:
     185      220314 :   virtual OutType get() const override { return this->_min; }
     186             : };
     187             : 
     188             : template <typename InType, typename OutType>
     189         126 : class Max : public Ratio<InType, OutType>
     190             : {
     191             : public:
     192         348 :   using Ratio<InType, OutType>::Ratio;
     193             : 
     194             : protected:
     195      220314 :   virtual OutType get() const override { return this->_max; }
     196             : };
     197             : 
     198             : template <typename InType, typename OutType>
     199         126 : class Sum : public Mean<InType, OutType>
     200             : {
     201             : public:
     202        3036 :   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     8608200 :   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    12071913 :   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         126 : class StdErr : public StdDev<InType, OutType>
     227             : {
     228             : public:
     229         343 :   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         348 :   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      220314 :   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         203 :   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      220193 :   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        6230 : Calculator<InType, OutType>::compute(const InType & data, bool is_distributed)
     289             : {
     290             :   initializeCalculator();
     291     4613435 :   for (const auto & val : data)
     292             :     updateCalculator(val);
     293        6230 :   finalizeCalculator(is_distributed);
     294        6230 :   return getValue();
     295             : }
     296             : 
     297             : template <typename InType, typename OutType>
     298             : void
     299             : Calculator<InType, OutType>::initializeCalculator()
     300             : {
     301    30448282 :   initialize();
     302    12796973 :   _state = CalculatorState::INITIALIZED;
     303    17651309 : }
     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  2123807298 :   update(val);
     311     5455053 : }
     312             : 
     313             : template <typename InType, typename OutType>
     314             : void
     315    30448282 : Calculator<InType, OutType>::finalizeCalculator(bool is_distributed)
     316             : {
     317    30448282 :   if (_state != CalculatorState::INITIALIZED)
     318           0 :     ::mooseError("Calculator is in wrong state.");
     319    30448282 :   finalize(is_distributed);
     320    30448282 :   _state = CalculatorState::FINALIZED;
     321    30448282 : }
     322             : 
     323             : template <typename InType, typename OutType>
     324             : OutType
     325    30444906 : Calculator<InType, OutType>::getValue() const
     326             : {
     327    30444906 :   if (_state != CalculatorState::FINALIZED)
     328           0 :     ::mooseError("Calculator is in wrong state.");
     329    30444906 :   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       12802 :   return CalculatorBuilder<InType, OutType>::build(item, other);
     338             : }
     339             : 
     340             : } // namespace

Generated by: LCOV version 1.14