LCOV - code coverage report
Current view: top level - include/reporters - Reporter.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: #32971 (54bef8) with base c6cf66 Lines: 28 28 100.0 %
Date: 2026-05-29 20:35:17 Functions: 116 144 80.6 %
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       62688 :   virtual ~Reporter() = default;
      53             : 
      54             : #ifdef MOOSE_KOKKOS_ENABLED
      55             :   /**
      56             :    * Special constructor used for Kokkos functor copy during parallel dispatch
      57             :    */
      58             :   Reporter(const Reporter & object, const Moose::Kokkos::FunctorCopy & key);
      59             : #endif
      60             : 
      61             :   virtual void store(nlohmann::json & json) const;
      62             : 
      63             :   /**
      64             :    * @returns Whether or not this Reporter should store its value at this specific time.
      65             :    *
      66             :    * Basic Reporters (those that are not GeneralReporters) will store at all times
      67             :    * when requested.
      68             :    */
      69          22 :   virtual bool shouldStore() const { return true; }
      70             : 
      71             :   /**
      72             :    * Method that can be overriden to declare "late" Reporter values.
      73             :    *
      74             :    * Values are considered "late" when they need to be declared after all
      75             :    * other Reporters have been instantiated. This is called by the
      76             :    * "declare_late_reporters" task, which should be called right after
      77             :    * the "add_reporters" task.
      78             :    */
      79       64881 :   virtual void declareLateValues() {}
      80             : 
      81             : protected:
      82             :   ///@{
      83             :   /**
      84             :    * Method to define a value that the Reporter object is to produced.
      85             :    * @tparam T The C++ type of the value to be produced
      86             :    * @tparam S (optional) Context type for performing special operations. For example
      87             :    *           using the ReporterBroadcastContext will automatically broadcast the produced value
      88             :    *           from the root processor.
      89             :    * @param name A unique name for the value to be produced.
      90             :    * @param mode (optional) The mode that indicates how the value produced is represented in
      91             :    *             parallel, there is more information about this below
      92             :    * @param args (optional) Any number of optional arguments passed into the ReporterContext given
      93             :    *             by the S template parameter. If S = ReporterContext then the first argument
      94             :    *             can be used as the default value (see ReporterContext.h).
      95             :    *
      96             :    * The 'mode' indicates how the value that is produced is represented in parallel. It is the
      97             :    * responsibility of the Reporter object to get it to that state. The ReporterContext objects
      98             :    * are designed to help with this. The mode can be one of the following:
      99             :    *
     100             :    *     ReporterMode::ROOT Indicates that the value produced is complete/correct on the
     101             :    *                        root processor for the object.
     102             :    *     ReporterMode::REPLICATED Indicates that the value produced is complete/correct on
     103             :    *                              all processors AND that the value is the same on all
     104             :    *                              processors
     105             :    *     ReporterMode::DISTRIBUTED Indicates that the value produced is complete/correct on
     106             :    *                               all processors AND that the value is NOT the same on all
     107             :    *                               processors
     108             :    *
     109             :    * WARNING! Using the "default value" in ReporterContext:
     110             :    * The Reporter system, like the systems before it, allow for objects that consume values to be
     111             :    * constructed prior to the produce objects. When a value is requested either by a producer
     112             :    * (Reporter) or consumer (ReporterInterface) the data is allocated. As such the assigned default
     113             :    * value from the producer should not be relied upon on the consumer side during object
     114             :    * construction.
     115             :    *
     116             :    * NOTE:
     117             :    * The ReporterContext is just a mechanism to allow for handling of values in special ways. In
     118             :    * practice it might be better to have specific methods for these special cases. For example,
     119             :    * a declareBroadcastValue, etc. Please refer to the ReporterData object for more information
     120             :    * on how the data system operates for Reporter values.
     121             :    */
     122             :   template <typename T, template <typename> class S = ReporterGeneralContext, typename... Args>
     123             :   T & declareValue(const std::string & param_name, Args &&... args);
     124             :   template <typename T, template <typename> class S = ReporterGeneralContext, typename... Args>
     125             :   T & declareValue(const std::string & param_name, ReporterMode mode, Args &&... args);
     126             :   template <typename T, template <typename> class S = ReporterGeneralContext, typename... Args>
     127             :   T & declareValueByName(const ReporterValueName & value_name, Args &&... args);
     128             :   template <typename T, template <typename> class S = ReporterGeneralContext, typename... Args>
     129             :   T & declareValueByName(const ReporterValueName & value_name, ReporterMode mode, Args &&... args);
     130             : 
     131             :   template <typename T, typename S, typename... Args>
     132             :   T & declareValue(const std::string & param_name, Args &&... args);
     133             :   template <typename T, typename S, typename... Args>
     134             :   T & declareValue(const std::string & param_name, ReporterMode mode, Args &&... args);
     135             :   template <typename T, typename S, typename... Args>
     136             :   T & declareValueByName(const ReporterValueName & value_name, Args &&... args);
     137             :   template <typename T, typename S, typename... Args>
     138             :   T & declareValueByName(const ReporterValueName & value_name, ReporterMode mode, Args &&... args);
     139             :   ///@}
     140             : 
     141             :   /**
     142             :    * Declare a unused value with type T.
     143             :    *
     144             :    * This is useful when you have a reporter that has optional values. In this case,
     145             :    * you want to create references to all reporter values. However, because some values
     146             :    * are optional, you need _something_ to fill into the reference. This helper will
     147             :    * create a unused value. It also allows for the passing of arguments in the case
     148             :    * that your value is not trivially default constructable (constructable by default
     149             :    * without arguments).
     150             :    */
     151             :   template <typename T, typename... Args>
     152             :   T & declareUnusedValue(Args &&... args);
     153             : 
     154             : private:
     155             :   /**
     156             :    * Internal base struct for use in storing unused values.
     157             :    *
     158             :    * In order to store a vector of arbitrary unused values for declareUnusedValue(),
     159             :    * we need some base object that is constructable without template arguments.
     160             :    */
     161             :   struct UnusedWrapperBase
     162             :   {
     163             :     /// Needed for polymorphism
     164        5154 :     virtual ~UnusedWrapperBase() {}
     165             :   };
     166             : 
     167             :   /**
     168             :    * Internal struct for storing a unused value. This allows for the storage
     169             :    * of arbitrarily typed objects in a single vector for use in
     170             :    * declareUnusedValue().
     171             :    */
     172             :   template <typename T>
     173             :   struct UnusedWrapper : UnusedWrapperBase
     174             :   {
     175             :     T value;
     176             :   };
     177             : 
     178             :   /**
     179             :    * @returns The ReporterValueName associated with the parameter \p param_name.
     180             :    *
     181             :    * Performs error checking on if the parameter is valid.
     182             :    */
     183             :   const ReporterValueName & getReporterValueName(const std::string & param_name) const;
     184             : 
     185             :   /// The MooseObject creating this Reporter
     186             :   const MooseObject & _reporter_moose_object;
     187             : 
     188             :   /// Ref. to MooseObject params
     189             :   const InputParameters & _reporter_params;
     190             : 
     191             :   /// The name of the MooseObject, from "_object_name" param
     192             :   const std::string & _reporter_name;
     193             : 
     194             :   /// Needed for access to FEProblemBase::getReporterData
     195             :   FEProblemBase & _reporter_fe_problem;
     196             : 
     197             :   /// Data storage
     198             :   ReporterData & _reporter_data;
     199             : 
     200             :   /// Storage for unused values declared with declareUnusedValue().
     201             :   std::vector<std::unique_ptr<UnusedWrapperBase>> _unused_values;
     202             : };
     203             : 
     204             : template <typename T, template <typename> class S, typename... Args>
     205             : T &
     206         130 : Reporter::declareValue(const std::string & param_name, Args &&... args)
     207             : {
     208         130 :   return declareValue<T, S<T>>(param_name, REPORTER_MODE_UNSET, args...);
     209             : }
     210             : 
     211             : template <typename T, template <typename> class S, typename... Args>
     212             : T &
     213          39 : Reporter::declareValue(const std::string & param_name, ReporterMode mode, Args &&... args)
     214             : {
     215          39 :   return declareValue<T, S<T>>(param_name, mode, args...);
     216             : }
     217             : 
     218             : template <typename T, typename S, typename... Args>
     219             : T &
     220             : Reporter::declareValue(const std::string & param_name, Args &&... args)
     221             : {
     222             :   return declareValue<T, S>(param_name, REPORTER_MODE_UNSET, args...);
     223             : }
     224             : 
     225             : template <typename T, typename S, typename... Args>
     226             : T &
     227         169 : Reporter::declareValue(const std::string & param_name, ReporterMode mode, Args &&... args)
     228             : {
     229         169 :   return declareValueByName<T, S>(getReporterValueName(param_name), mode, args...);
     230             : }
     231             : 
     232             : template <typename T, template <typename> class S, typename... Args>
     233             : T &
     234        4945 : Reporter::declareValueByName(const ReporterValueName & value_name, Args &&... args)
     235             : {
     236        4945 :   return declareValueByName<T, S<T>>(value_name, REPORTER_MODE_UNSET, args...);
     237             : }
     238             : 
     239             : template <typename T, template <typename> class S, typename... Args>
     240             : T &
     241        2649 : Reporter::declareValueByName(const ReporterValueName & value_name,
     242             :                              ReporterMode mode,
     243             :                              Args &&... args)
     244             : {
     245        2649 :   return declareValueByName<T, S<T>>(value_name, mode, args...);
     246             : }
     247             : 
     248             : template <typename T, typename S, typename... Args>
     249             : T &
     250             : Reporter::declareValueByName(const ReporterValueName & value_name, Args &&... args)
     251             : {
     252             :   return declareValueByName<T, S>(value_name, REPORTER_MODE_UNSET, args...);
     253             : }
     254             : 
     255             : template <typename T, typename S, typename... Args>
     256             : T &
     257        9642 : Reporter::declareValueByName(const ReporterValueName & value_name,
     258             :                              ReporterMode mode,
     259             :                              Args &&... args)
     260             : {
     261        9642 :   const ReporterName state_name(_reporter_name, value_name);
     262             : 
     263       28926 :   buildOutputHideVariableList({state_name.getCombinedName()});
     264             : 
     265             :   // Only thread 0 will declare the reporter value. The rest will get a reference
     266             :   // to an UnusedValue
     267       19284 :   const THREAD_ID tid = _reporter_moose_object.parameters().isParamValid("_tid")
     268        9570 :                             ? _reporter_moose_object.parameters().get<THREAD_ID>("_tid")
     269             :                             : 0;
     270        9642 :   if (tid)
     271          26 :     return declareUnusedValue<T>();
     272        9616 :   return _reporter_data.declareReporterValue<T, S>(
     273        9538 :       state_name, mode, _reporter_moose_object, args...);
     274       19278 : }
     275             : 
     276             : template <typename T, typename... Args>
     277             : T &
     278        5154 : Reporter::declareUnusedValue(Args &&... args)
     279             : {
     280        5154 :   _unused_values.emplace_back(std::make_unique<UnusedWrapper<T>>(std::forward(args)...));
     281        5154 :   UnusedWrapper<T> * wrapper = dynamic_cast<UnusedWrapper<T> *>(_unused_values.back().get());
     282        5154 :   return wrapper->value;
     283             : }

Generated by: LCOV version 1.14