LCOV - code coverage report
Current view: top level - include/reporters - Reporter.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 27 28 96.4 %
Date: 2025-07-17 01:28:37 Functions: 92 121 76.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             : // Moose includes
      13             : #include "MooseTypes.h"
      14             : #include "OutputInterface.h"
      15             : #include "ReporterData.h"
      16             : #include "InputParameters.h"
      17             : 
      18             : // System includes
      19             : #include <type_traits>
      20             : 
      21             : // Forward declarations
      22             : class FEProblemBase;
      23             : 
      24             : /**
      25             :  * Reporter objects allow for the declaration of arbitrary data types that are aggregate values
      26             :  * for a simulation. These aggregate values are then available to other objects for use. They
      27             :  * operate with the typical producer/consumer relationship. The Reporter object produces values
      28             :  * that other objects consume.
      29             :  *
      30             :  * Originally, MOOSE included a Postprocessor system that allowed for an object to produce a
      31             :  * single scalar value for consumption by other objects. Then a companion system was created,
      32             :  * the VectorPostprocessor system, that allowed for an object to produce many std::vector<Real>
      33             :  * values. The Reporter system is the generalization of these two ideas and follows closely the
      34             :  * original design of the VectorPostprocessor system.
      35             :  *
      36             :  * In practice, the Reporter system provided the following features over the two previous systems.
      37             :  *
      38             :  * 1. It can create arbitrary data types rather than only Real and std::vector<Real>
      39             :  * 2. It can create many values per object. This was possible for VectorPostprocessor objects but
      40             :  *    not for Postprocessors. Therefore, this allows a single Reporter to provide multiple values
      41             :  *    and consolidate similar items. For example, a "counter" object replaced several individual
      42             :  *    Postprocessor objects.
      43             :  * 3. The ReporterContext system allows for each data value to have special operation within a
      44             :  *    single object. Previously the VectorPostprocessor system had capability to perform
      45             :  *    broadcasting, but it was applied to all vectors in the object.
      46             :  */
      47             : class Reporter : public OutputInterface
      48             : {
      49             : public:
      50             :   static InputParameters validParams();
      51             :   Reporter(const MooseObject * moose_object);
      52       57371 :   virtual ~Reporter() = default;
      53             :   virtual void store(nlohmann::json & json) const;
      54             : 
      55             :   /**
      56             :    * @returns Whether or not this Reporter should store its value at this specific time.
      57             :    *
      58             :    * Basic Reporters (those that are not GeneralReporters) will store at all times
      59             :    * when requested.
      60             :    */
      61           0 :   virtual bool shouldStore() const { return true; }
      62             : 
      63             :   /**
      64             :    * Method that can be overriden to declare "late" Reporter values.
      65             :    *
      66             :    * Values are considered "late" when they need to be declared after all
      67             :    * other Reporters have been instantiated. This is called by the
      68             :    * "declare_late_reporters" task, which should be called right after
      69             :    * the "add_reporters" task.
      70             :    */
      71       60578 :   virtual void declareLateValues() {}
      72             : 
      73             : protected:
      74             :   ///@{
      75             :   /**
      76             :    * Method to define a value that the Reporter object is to produced.
      77             :    * @tparam T The C++ type of the value to be produced
      78             :    * @tparam S (optional) Context type for performing special operations. For example
      79             :    *           using the ReporterBroadcastContext will automatically broadcast the produced value
      80             :    *           from the root processor.
      81             :    * @param name A unique name for the value to be produced.
      82             :    * @param mode (optional) The mode that indicates how the value produced is represented in
      83             :    *             parallel, there is more information about this below
      84             :    * @param args (optional) Any number of optional arguments passed into the ReporterContext given
      85             :    *             by the S template parameter. If S = ReporterContext then the first argument
      86             :    *             can be used as the default value (see ReporterContext.h).
      87             :    *
      88             :    * The 'mode' indicates how the value that is produced is represented in parallel. It is the
      89             :    * responsibility of the Reporter object to get it to that state. The ReporterContext objects
      90             :    * are designed to help with this. The mode can be one of the following:
      91             :    *
      92             :    *     ReporterMode::ROOT Indicates that the value produced is complete/correct on the
      93             :    *                        root processor for the object.
      94             :    *     ReporterMode::REPLICATED Indicates that the value produced is complete/correct on
      95             :    *                              all processors AND that the value is the same on all
      96             :    *                              processors
      97             :    *     ReporterMode::DISTRIBUTED Indicates that the value produced is complete/correct on
      98             :    *                               all processors AND that the value is NOT the same on all
      99             :    *                               processors
     100             :    *
     101             :    * WARNING! Using the "default value" in ReporterContext:
     102             :    * The Reporter system, like the systems before it, allow for objects that consume values to be
     103             :    * constructed prior to the produce objects. When a value is requested either by a producer
     104             :    * (Reporter) or consumer (ReporterInterface) the data is allocated. As such the assigned default
     105             :    * value from the producer should not be relied upon on the consumer side during object
     106             :    * construction.
     107             :    *
     108             :    * NOTE:
     109             :    * The ReporterContext is just a mechanism to allow for handling of values in special ways. In
     110             :    * practice it might be better to have specific methods for these special cases. For example,
     111             :    * a declareBroadcastValue, etc. Please refer to the ReporterData object for more information
     112             :    * on how the data system operates for Reporter values.
     113             :    */
     114             :   template <typename T, template <typename> class S = ReporterGeneralContext, typename... Args>
     115             :   T & declareValue(const std::string & param_name, Args &&... args);
     116             :   template <typename T, template <typename> class S = ReporterGeneralContext, typename... Args>
     117             :   T & declareValue(const std::string & param_name, ReporterMode mode, Args &&... args);
     118             :   template <typename T, template <typename> class S = ReporterGeneralContext, typename... Args>
     119             :   T & declareValueByName(const ReporterValueName & value_name, Args &&... args);
     120             :   template <typename T, template <typename> class S = ReporterGeneralContext, typename... Args>
     121             :   T & declareValueByName(const ReporterValueName & value_name, ReporterMode mode, Args &&... args);
     122             : 
     123             :   template <typename T, typename S, typename... Args>
     124             :   T & declareValue(const std::string & param_name, Args &&... args);
     125             :   template <typename T, typename S, typename... Args>
     126             :   T & declareValue(const std::string & param_name, ReporterMode mode, Args &&... args);
     127             :   template <typename T, typename S, typename... Args>
     128             :   T & declareValueByName(const ReporterValueName & value_name, Args &&... args);
     129             :   template <typename T, typename S, typename... Args>
     130             :   T & declareValueByName(const ReporterValueName & value_name, ReporterMode mode, Args &&... args);
     131             :   ///@}
     132             : 
     133             :   /**
     134             :    * Declare a unused value with type T.
     135             :    *
     136             :    * This is useful when you have a reporter that has optional values. In this case,
     137             :    * you want to create references to all reporter values. However, because some values
     138             :    * are optional, you need _something_ to fill into the reference. This helper will
     139             :    * create a unused value. It also allows for the passing of arguments in the case
     140             :    * that your value is not trivially default constructable (constructable by default
     141             :    * without arguments).
     142             :    */
     143             :   template <typename T, typename... Args>
     144             :   T & declareUnusedValue(Args &&... args);
     145             : 
     146             : private:
     147             :   /**
     148             :    * Internal base struct for use in storing unused values.
     149             :    *
     150             :    * In order to store a vector of arbitrary unused values for declareUnusedValue(),
     151             :    * we need some base object that is constructable without template arguments.
     152             :    */
     153             :   struct UnusedWrapperBase
     154             :   {
     155             :     /// Needed for polymorphism
     156        5138 :     virtual ~UnusedWrapperBase() {}
     157             :   };
     158             : 
     159             :   /**
     160             :    * Internal struct for storing a unused value. This allows for the storage
     161             :    * of arbitrarily typed objects in a single vector for use in
     162             :    * declareUnusedValue().
     163             :    */
     164             :   template <typename T>
     165             :   struct UnusedWrapper : UnusedWrapperBase
     166             :   {
     167             :     T value;
     168             :   };
     169             : 
     170             :   /**
     171             :    * @returns The ReporterValueName associated with the parameter \p param_name.
     172             :    *
     173             :    * Performs error checking on if the parameter is valid.
     174             :    */
     175             :   const ReporterValueName & getReporterValueName(const std::string & param_name) const;
     176             : 
     177             :   /// The MooseObject creating this Reporter
     178             :   const MooseObject & _reporter_moose_object;
     179             : 
     180             :   /// Ref. to MooseObject params
     181             :   const InputParameters & _reporter_params;
     182             : 
     183             :   /// The name of the MooseObject, from "_object_name" param
     184             :   const std::string & _reporter_name;
     185             : 
     186             :   /// Needed for access to FEProblemBase::getReporterData
     187             :   FEProblemBase & _reporter_fe_problem;
     188             : 
     189             :   /// Data storage
     190             :   ReporterData & _reporter_data;
     191             : 
     192             :   /// Storage for unused values declared with declareUnusedValue().
     193             :   std::vector<std::unique_ptr<UnusedWrapperBase>> _unused_values;
     194             : };
     195             : 
     196             : template <typename T, template <typename> class S, typename... Args>
     197             : T &
     198         103 : Reporter::declareValue(const std::string & param_name, Args &&... args)
     199             : {
     200         103 :   return declareValue<T, S<T>>(param_name, REPORTER_MODE_UNSET, args...);
     201             : }
     202             : 
     203             : template <typename T, template <typename> class S, typename... Args>
     204             : T &
     205          43 : Reporter::declareValue(const std::string & param_name, ReporterMode mode, Args &&... args)
     206             : {
     207          43 :   return declareValue<T, S<T>>(param_name, mode, args...);
     208             : }
     209             : 
     210             : template <typename T, typename S, typename... Args>
     211             : T &
     212             : Reporter::declareValue(const std::string & param_name, Args &&... args)
     213             : {
     214             :   return declareValue<T, S>(param_name, REPORTER_MODE_UNSET, args...);
     215             : }
     216             : 
     217             : template <typename T, typename S, typename... Args>
     218             : T &
     219         146 : Reporter::declareValue(const std::string & param_name, ReporterMode mode, Args &&... args)
     220             : {
     221         146 :   return declareValueByName<T, S>(getReporterValueName(param_name), mode, args...);
     222             : }
     223             : 
     224             : template <typename T, template <typename> class S, typename... Args>
     225             : T &
     226        4085 : Reporter::declareValueByName(const ReporterValueName & value_name, Args &&... args)
     227             : {
     228        4085 :   return declareValueByName<T, S<T>>(value_name, REPORTER_MODE_UNSET, args...);
     229             : }
     230             : 
     231             : template <typename T, template <typename> class S, typename... Args>
     232             : T &
     233        2195 : Reporter::declareValueByName(const ReporterValueName & value_name,
     234             :                              ReporterMode mode,
     235             :                              Args &&... args)
     236             : {
     237        2195 :   return declareValueByName<T, S<T>>(value_name, mode, args...);
     238             : }
     239             : 
     240             : template <typename T, typename S, typename... Args>
     241             : T &
     242             : Reporter::declareValueByName(const ReporterValueName & value_name, Args &&... args)
     243             : {
     244             :   return declareValueByName<T, S>(value_name, REPORTER_MODE_UNSET, args...);
     245             : }
     246             : 
     247             : template <typename T, typename S, typename... Args>
     248             : T &
     249        8030 : Reporter::declareValueByName(const ReporterValueName & value_name,
     250             :                              ReporterMode mode,
     251             :                              Args &&... args)
     252             : {
     253        8030 :   const ReporterName state_name(_reporter_name, value_name);
     254             : 
     255       16060 :   buildOutputHideVariableList({state_name.getCombinedName()});
     256             : 
     257             :   // Only thread 0 will declare the reporter value. The rest will get a reference
     258             :   // to an UnusedValue
     259       16060 :   const THREAD_ID tid = _reporter_moose_object.parameters().isParamValid("_tid")
     260        8030 :                             ? _reporter_moose_object.parameters().get<THREAD_ID>("_tid")
     261             :                             : 0;
     262        8030 :   if (tid)
     263          10 :     return declareUnusedValue<T>();
     264        8020 :   return _reporter_data.declareReporterValue<T, S>(
     265        8012 :       state_name, mode, _reporter_moose_object, args...);
     266       16052 : }
     267             : 
     268             : template <typename T, typename... Args>
     269             : T &
     270        5138 : Reporter::declareUnusedValue(Args &&... args)
     271             : {
     272        5138 :   _unused_values.emplace_back(std::make_unique<UnusedWrapper<T>>(std::forward(args)...));
     273        5138 :   UnusedWrapper<T> * wrapper = dynamic_cast<UnusedWrapper<T> *>(_unused_values.back().get());
     274        5138 :   return wrapper->value;
     275             : }

Generated by: LCOV version 1.14