LCOV - code coverage report
Current view: top level - include/reporters - ReporterData.h (source / functions) Hit Total Coverage
Test: idaholab/moose framework: 2bf808 Lines: 83 99 83.8 %
Date: 2025-07-17 01:28:37 Functions: 153 668 22.9 %
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 "RestartableData.h"
      13             : #include "JsonIO.h"
      14             : #include "MooseUtils.h"
      15             : #include "ReporterState.h"
      16             : #include "ReporterContext.h"
      17             : #include "libmesh/parallel_object.h"
      18             : #include "libmesh/dense_vector.h"
      19             : #include <memory>
      20             : 
      21             : class MooseApp;
      22             : class Receiver;
      23             : 
      24             : /**
      25             :  * This is a helper class for managing the storage of declared Reporter object values. This design
      26             :  * of the system is a generalization of the VectorPostprocessor system that the Reporter objects
      27             :  * replaced.
      28             :  *
      29             :  * Foremost, this object doesn't store the data. It simply acts as helper for using the restart
      30             :  * system of the MooseApp. This object automatically handles the old, older, ... data. All
      31             :  * declarations create std::pair<T, std::vector<T>> restartable data on the MooseApp, where the
      32             :  * first value is the current value and the data in the vector are the older data.
      33             :  *
      34             :  * The ReporterState object is a RestartableData object that serves as a helper for managing the
      35             :  * time history. A "context" object also exists that uses the ReporterState for performing special
      36             :  * operations. Refer to ReporterState.h/C for more information.
      37             :  *
      38             :  * It is important to note that the Reporter values are not threaded. However, the Reporter
      39             :  * objects are UserObject based, so the calculation of the values can be threaded.
      40             :  *
      41             :  * This object also relies on ReporterName objects, which are simply a combination of the
      42             :  * Reporter object name and the data name. If you recall the VectorPostprocessor system on which
      43             :  * this is based required an object name and a vector name. The ReporterName class simply provides
      44             :  * a convenient way to provide that information in a single object. Special Parser syntax
      45             :  * was also defined so that application developers do not have to have input parameters for
      46             :  * both the object and data names (see Parser.C/h).
      47             :  */
      48             : class ReporterData
      49             : {
      50             : public:
      51             :   class WriteKey
      52             :   {
      53             :     /**
      54             :      * An object that can be passed to FEProblemBase::getReporterData to provide non-const access
      55             :      * the ReporterData object that is used to store reporter values.
      56             :      *
      57             :      * An attempt was made to limit access to the ReporterData as much as possible to encourage
      58             :      * developers to use the Reporter and ReporterInterface. This key also prevents the need for
      59             :      * FEProblemBase to give friend access to these classes, which gives complete access.
      60             :      * Thanks for the idea @loganharbour
      61             :      */
      62      141865 :     WriteKey() {} // private constructor
      63             :     friend class Reporter;
      64             :     friend class Postprocessor;
      65             :     friend class Receiver;
      66             :     friend class ConstantPostprocessor;
      67             :     friend class VectorPostprocessor;
      68             :     friend class ReporterTransferInterface;
      69             :   };
      70             : 
      71             :   ReporterData(MooseApp & moose_app);
      72             : 
      73             :   /**
      74             :    * Return True if a Reporter value with the given type and name have been created.
      75             :    */
      76             :   template <typename T>
      77             :   bool hasReporterValue(const ReporterName & reporter_name) const;
      78             : 
      79             :   /**
      80             :    * Return True if a Reporter value with any type exists with the given name.
      81             :    */
      82             :   bool hasReporterValue(const ReporterName & reporter_name) const;
      83             : 
      84             :   /**
      85             :    * @returns True if a ReporterState is defined for the Reporter with name \p reporter_name
      86             :    * and the given type.
      87             :    */
      88             :   template <typename T>
      89             :   bool hasReporterState(const ReporterName & reporter_name) const;
      90             : 
      91             :   /**
      92             :    * @returns True if a ReporterState is defined for the Reporter with name \p reporter_name.
      93             :    */
      94             :   bool hasReporterState(const ReporterName & reporter_name) const;
      95             : 
      96             :   /**
      97             :    * Return a list of all reporter names
      98             :    */
      99             :   std::set<ReporterName> getReporterNames() const;
     100             : 
     101             :   /**
     102             :    * Return a list of all postprocessor names
     103             :    */
     104             :   std::set<std::string> getPostprocessorNames() const;
     105             : 
     106             :   /**
     107             :    * Get all real reporter values including postprocessor and vector postprocessor values into a
     108             :    * dense vector
     109             :    */
     110             :   DenseVector<Real> getAllRealReporterValues() const;
     111             : 
     112             :   /**
     113             :    * Get full names of all real reporter values
     114             :    * Note: For a postprocessor, the full name is the postprocessor name plus '/value'.
     115             :    *       For a vector postprocessor, the full name is the vector postprocessor name
     116             :    *       plus the vector name followed by '/#' where '#' is the index of the vector.
     117             :    */
     118             :   std::vector<std::string> getAllRealReporterFullNames() const;
     119             : 
     120             :   /**
     121             :    * Method for returning read only references to Reporter values.
     122             :    * @tparam T The Reporter value C++ type.
     123             :    * @param reporter_name The name of the reporter value, which includes the object name and the
     124             :    *                      data name.
     125             :    * @param consumer The MooseObject consuming the Reporter value (for error reporting)
     126             :    * @param mode The mode that the value will be consumed by the by the ReporterInterface object
     127             :    * @param time_index (optional) When not provided or zero is provided the current value is
     128             :    *                   returned. If an index greater than zero is provided then the corresponding
     129             :    *                   old data is returned (1 = old, 2 = older, etc.).
     130             :    */
     131             :   template <typename T>
     132             :   const T & getReporterValue(const ReporterName & reporter_name,
     133             :                              const MooseObject & consumer,
     134             :                              const ReporterMode & mode,
     135             :                              const std::size_t time_index = 0) const;
     136             : 
     137             :   /**
     138             :    * Method for returning a read-only reference to Reporter values that already exist.
     139             :    * @tparam T The Reporter value C++ type.
     140             :    * @param reporter_name The name of the reporter value, which includes the object name and the
     141             :    *                      data name.
     142             :    * @param time_index (optional) When not provided or zero is provided the current value is
     143             :    *                   returned. If an index greater than zero is provided then the corresponding
     144             :    *                   old data is returned (1 = old, 2 = older, etc.).
     145             :    */
     146             :   template <typename T>
     147             :   const T & getReporterValue(const ReporterName & reporter_name,
     148             :                              const std::size_t time_index = 0) const;
     149             : 
     150             :   /**
     151             :    * Method for setting Reporter values that already exist.
     152             :    * @tparam T The Reporter value C++ type.
     153             :    * @param reporter_name The name of the reporter value, which includes the object name and the
     154             :    *                      data name.
     155             :    * @param value The value to which the Reporter will be changed to.
     156             :    * @param time_index (optional) When not provided or zero is provided the current value is
     157             :    *                   returned. If an index greater than zero is provided then the corresponding
     158             :    *                   old data is returned (1 = old, 2 = older, etc.).
     159             :    * WARNING!
     160             :    * This method is designed for setting values outside of the traditional interfaces such as is
     161             :    * necessary for Transfers. This is an advanced capability that should be used with caution.
     162             :    *
     163             :    * @see FEProblemBase::setPostprocessorValueByName
     164             :    */
     165             :   template <typename T>
     166             :   void setReporterValue(const ReporterName & reporter_name,
     167             :                         const T & value,
     168             :                         const std::size_t time_index = 0);
     169             : 
     170             :   /**
     171             :    * Method for setting that a specific time index is requested for a Reporter value.
     172             :    * @tparam T The Reporter value C++ type.
     173             :    * @param reporter_name The name of the reporter value, which includes the object name and the
     174             :    *                      data name.
     175             :    * @param time_index The time index that is needed
     176             :    */
     177             :   template <typename T>
     178             :   void needReporterTimeIndex(const ReporterName & reporter_name, const std::size_t time_index);
     179             : 
     180             :   ///@{
     181             :   /**
     182             :    * Method for returning a writable reference to the current Reporter value. This method is
     183             :    * used by the Reporter class to produce values.
     184             :    * @tparam T The Reporter value C++ type.
     185             :    * @tparam S (optional) The ReporterContext for performing specialized actions after the
     186             :    * values have been computed. For example, ReporterBroadcastContext automatically broadcasts
     187             :    *           the computed value. See ReporterState.C/h for more information.
     188             :    * @param reporter_name The name of the reporter value, which includes the object name and the
     189             :    *                      data name.
     190             :    * @param mode The mode that the produced value will be computed by the Reporter object
     191             :    * @param producer The MooseObject that produces this value
     192             :    * @param args (optional) Any number of optional arguments passed into the Context type given
     193             :    *             by the S template parameter. If S = ReporterContext then the first argument
     194             :    *             can be used as the default value (see ReporterContext.h).
     195             :    *
     196             :    * The ReporterContext objects allow for custom handling of data (e.g., broadcasting the
     197             :    * value). The get/declare methods can be called in any order thus an the underlying
     198             :    * RestartableData object is often created by the get method before it is declared. Therefore
     199             :    * the custom functionality cannot be handled by specializing the
     200             :    * RestartableData/ReporterState object directly because the state is often created prior to
     201             :    * the declaration that dictates how the produced value shall be computed. Thus, the reason
     202             :    * for the separate ReporterContext objects.
     203             :    */
     204             :   template <typename T, typename S, typename... Args>
     205             :   T & declareReporterValue(const ReporterName & reporter_name,
     206             :                            const ReporterMode & mode,
     207             :                            const MooseObject & producer,
     208             :                            Args &&... args);
     209             : 
     210             :   /**
     211             :    * Helper function for performing post calculation actions via the ReporterContext objects.
     212             :    *
     213             :    * If you recall, the original VectorPostprocessor system included the ability to perform some
     214             :    * scatter and broadcast actions via the special call on the storage helper object. This
     215             :    * is a replacement for that method that leverages the ReporterContext objects to perform
     216             :    * value specific actions, including some automatic operations depending how the data is
     217             :    * produced and consumed.
     218             :    *
     219             :    * See FEProblemBase::joinAndFinalize
     220             :    */
     221             :   void finalize(const std::string & object_name);
     222             : 
     223             :   /**
     224             :    * At the end of a timestep this method is called to copy the values back in time in preparation
     225             :    * for the next timestep.
     226             :    *
     227             :    * See FEProblemBase::advanceState
     228             :    */
     229             :   void copyValuesBack();
     230             : 
     231             :   /**
     232             :    * When a time step fails, this method is called to revert the current reporter values to their
     233             :    * old state. @see FEProblemBase::restoreSolutions
     234             :    *
     235             :    * @param verbose Set true to print whether the reporters were restored or not.
     236             :    */
     237             :   void restoreState(bool verbose = false);
     238             : 
     239             :   /**
     240             :    * Perform integrity check for get/declare calls
     241             :    */
     242             :   void check() const;
     243             : 
     244             :   /**
     245             :    * Return true if the supplied mode exists in the produced Reporter values
     246             :    *
     247             :    * @see CSV.C/h
     248             :    */
     249             :   bool hasReporterWithMode(const std::string & obj_name, const ReporterMode & mode) const;
     250             : 
     251             :   /**
     252             :    * @returns The ReporterContextBase associated with the Reporter with name \p reporter_name.
     253             :    */
     254             :   ///@{
     255             :   const ReporterContextBase & getReporterContextBase(const ReporterName & reporter_name) const;
     256             :   ReporterContextBase & getReporterContextBase(const ReporterName & reporter_name);
     257             :   ///@}
     258             : 
     259             :   /**
     260             :    * @Returns The ReporterStateBase associated with the Reporter with name \p reporter_name.
     261             :    */
     262             :   ///@{
     263             :   const ReporterStateBase & getReporterStateBase(const ReporterName & reporter_name) const;
     264             :   ReporterStateBase & getReporterStateBase(const ReporterName & reporter_name);
     265             :   ///@}
     266             : 
     267             :   /**
     268             :    * Return the ReporterProducerEnum for an existing ReporterValue
     269             :    * @param reporter_name The name of the reporter value, which includes the object name and the
     270             :    *                      data name.
     271             :    */
     272             :   const ReporterProducerEnum & getReporterMode(const ReporterName & reporter_name) const;
     273             : 
     274             :   /**
     275             :    * Gets information pertaining to the Reporter with state \p state and possibly
     276             :    * context \p context.
     277             :    */
     278             :   static std::string getReporterInfo(const ReporterStateBase & state,
     279             :                                      const ReporterContextBase * context);
     280             : 
     281             :   /**
     282             :    * Gets information pertaining to the Reporter with name \p reporter_name.
     283             :    */
     284             :   std::string getReporterInfo(const ReporterName & reporter_name) const;
     285             : 
     286             :   /**
     287             :    * Gets information about all declared/requested Reporters.
     288             :    */
     289             :   std::string getReporterInfo() const;
     290             : 
     291             : private:
     292             :   /// For accessing the restart/recover system, which is where Reporter values are stored
     293             :   MooseApp & _app;
     294             : 
     295             :   /**
     296             :    * Helper method for creating the necessary RestartableData for Reporter values.
     297             :    * @tparam T The desired C++ type for the Reporter value
     298             :    * @param reporter_name Object/data name for the Reporter value
     299             :    * @param declare Flag indicating if the ReporterValue is being declared or read. This flag
     300             :    *                is passed to the existing MooseApp restart/recover system that errors if a
     301             :    *                value is declared multiple times.
     302             :    * @param moose_object The object requesting/declaring the state, used in error handling.
     303             :    */
     304             :   template <typename T>
     305             :   ReporterState<T> & getReporterStateHelper(const ReporterName & reporter_name,
     306             :                                             bool declare,
     307             :                                             const MooseObject * moose_object = nullptr) const;
     308             : 
     309             :   /**
     310             :    * Helper for registering data with the MooseApp to avoid cyclic includes
     311             :    */
     312             :   RestartableDataValue & getRestartableDataHelper(std::unique_ptr<RestartableDataValue> data_ptr,
     313             :                                                   bool declare) const;
     314             : 
     315             :   /// Map from ReporterName -> Reporter state. We need to keep track of all of the states that are
     316             :   /// created so that we can check them after Reporter declaration to make sure all states have
     317             :   /// a producer (are delcared). We cannot check _context_ptrs, because a context is only
     318             :   /// defined for Reporters that have been declared. This is mutable so that it can be inserted
     319             :   /// into when requesting Reporter values.
     320             :   mutable std::map<ReporterName, ReporterStateBase *> _states;
     321             : 
     322             :   /// The ReporterContext objects are created when a value is declared. The context objects
     323             :   /// include a reference to the associated ReporterState values. This container stores the
     324             :   /// context object for each Reporter value.
     325             :   std::map<ReporterName, std::unique_ptr<ReporterContextBase>> _context_ptrs;
     326             : };
     327             : 
     328             : template <typename T>
     329             : ReporterState<T> &
     330     1247527 : ReporterData::getReporterStateHelper(const ReporterName & reporter_name,
     331             :                                      bool declare,
     332             :                                      const MooseObject * moose_object /* = nullptr */) const
     333             : {
     334     1247527 :   if (hasReporterState(reporter_name))
     335             :   {
     336     1169894 :     const auto error_helper =
     337         108 :         [this, &reporter_name, &moose_object, &declare](const std::string & suffix)
     338             :     {
     339          12 :       std::stringstream oss;
     340             :       oss << "While " << (declare ? "declaring" : "requesting") << " a "
     341             :           << reporter_name.specialTypeToName() << " value with the name \""
     342          12 :           << reporter_name.getValueName() << "\"";
     343          12 :       if (!reporter_name.isPostprocessor() && !reporter_name.isVectorPostprocessor())
     344          12 :         oss << " and type \"" << MooseUtils::prettyCppType<T>() << "\"";
     345          12 :       oss << ",\na Reporter with the same name " << suffix << ".\n\n";
     346          12 :       oss << getReporterInfo(reporter_name);
     347             : 
     348          12 :       if (moose_object)
     349          12 :         moose_object->mooseError(oss.str());
     350             :       else
     351           0 :         mooseError(oss.str());
     352           0 :     };
     353             : 
     354     1169894 :     if (declare && hasReporterValue(reporter_name))
     355           4 :       error_helper("has already been declared");
     356     1169890 :     if (!hasReporterState<T>(reporter_name))
     357             :     {
     358           8 :       std::stringstream oss;
     359           4 :       oss << "has been " << (declare || !hasReporterValue(reporter_name) ? "requested" : "declared")
     360          12 :           << " with a different type";
     361           8 :       error_helper(oss.str());
     362           0 :     }
     363             :   }
     364             : 
     365             :   // Reporter states are stored as restartable data. The act of registering restartable data
     366             :   // may be done multiple times with the same name, which will happen when more than one
     367             :   // get value is done, or a get value and a declare is done. With this, we create a new
     368             :   // state every time, but said created state may not be the actual state if this state
     369             :   // is already registered as restartable data. Therefore, we create a state, and then
     370             :   // cast the restartable data received back to a state (which may be different than
     371             :   // the one we created, but that's okay)
     372     1247515 :   auto state_unique_ptr = std::make_unique<ReporterState<T>>(reporter_name);
     373     1247515 :   auto & restartable_value = getRestartableDataHelper(std::move(state_unique_ptr), declare);
     374             : 
     375     1247515 :   auto * state = dynamic_cast<ReporterState<T> *>(&restartable_value);
     376             :   mooseAssert(state, "Cast failed. The check above must be broken!");
     377             : 
     378             :   // See declareReporterValue for a comment on what happens if a state for the same
     379             :   // name is requested but with different special types. TLDR: ReporterNames with
     380             :   // different special types are not unique so they'll be the same entry
     381     1247515 :   _states.emplace(reporter_name, state);
     382             : 
     383     1247515 :   return *state;
     384     1247515 : }
     385             : 
     386             : template <typename T>
     387             : const T &
     388       51090 : ReporterData::getReporterValue(const ReporterName & reporter_name,
     389             :                                const MooseObject & consumer,
     390             :                                const ReporterMode & mode,
     391             :                                const std::size_t time_index /* = 0 */) const
     392             : {
     393       51090 :   auto & state = getReporterStateHelper<T>(reporter_name, /* declare = */ false, &consumer);
     394       51086 :   state.addConsumer(mode, consumer);
     395       51086 :   return state.value(time_index);
     396             : }
     397             : 
     398             : template <typename T, typename S, typename... Args>
     399             : T &
     400       77633 : ReporterData::declareReporterValue(const ReporterName & reporter_name,
     401             :                                    const ReporterMode & mode,
     402             :                                    const MooseObject & producer,
     403             :                                    Args &&... args)
     404             : {
     405             :   // Get/create the ReporterState
     406       77633 :   auto & state = getReporterStateHelper<T>(reporter_name, /* declare = */ true, &producer);
     407             : 
     408             :   // They key in _states (ReporterName) is not unique by special type. This is done on purpose
     409             :   // because we want to store reporter names a single name regardless of special type.
     410             :   // Because of this, we have the case where someone could request a reporter value
     411             :   // that is later declared as a pp or a vpp value. In this case, when it is first
     412             :   // requested, the _state entry will have a key and name with a special type of ANY.
     413             :   // When it's declared here (later), we will still find the correct entry because
     414             :   // we don't check the special type in the key/name. But... we want the actual
     415             :   // key and name to represent a pp or a vpp. Therefore, we'll set it properly,
     416             :   // remove the entry in the map (which has the ANY key), and re-add it so that it
     417             :   // has the pp/vpp key. This allows us to identify Reporters that really represent
     418             :   // pps/vpps in output and in error reporting.
     419       77625 :   if (reporter_name.isPostprocessor() && !state.getReporterName().isPostprocessor())
     420             :   {
     421          12 :     state.setIsPostprocessor();
     422          12 :     _states.erase(reporter_name);
     423          12 :     _states.emplace(reporter_name, &state);
     424             :   }
     425       96218 :   else if (reporter_name.isVectorPostprocessor() &&
     426       18605 :            !state.getReporterName().isVectorPostprocessor())
     427             :   {
     428          12 :     state.setIsVectorPostprocessor();
     429          12 :     _states.erase(reporter_name);
     430          12 :     _states.emplace(reporter_name, &state);
     431             :   }
     432             : 
     433             :   mooseAssert(!_context_ptrs.count(reporter_name), "Context already exists");
     434             : 
     435             :   // Create the ReporterContext
     436       77625 :   auto context_ptr = std::make_unique<S>(_app, producer, state, args...);
     437       77625 :   context_ptr->init(mode); // initialize the mode, see ContextReporter
     438       77625 :   _context_ptrs.emplace(reporter_name, std::move(context_ptr));
     439             : 
     440      155250 :   return state.value();
     441       77625 : }
     442             : 
     443             : template <typename T>
     444             : bool
     445     1819349 : ReporterData::hasReporterValue(const ReporterName & reporter_name) const
     446             : {
     447     1819349 :   if (!hasReporterValue(reporter_name))
     448       38692 :     return false;
     449     1780657 :   return dynamic_cast<const ReporterContext<T> *>(&getReporterContextBase(reporter_name));
     450             : }
     451             : 
     452             : template <typename T>
     453             : bool
     454     1169890 : ReporterData::hasReporterState(const ReporterName & reporter_name) const
     455             : {
     456     1169890 :   if (!hasReporterState(reporter_name))
     457           0 :     return false;
     458     1169890 :   return dynamic_cast<const ReporterState<T> *>(&getReporterStateBase(reporter_name));
     459             : }
     460             : 
     461             : template <typename T>
     462             : const T &
     463     1114164 : ReporterData::getReporterValue(const ReporterName & reporter_name,
     464             :                                const std::size_t time_index) const
     465             : {
     466     1114164 :   if (!hasReporterValue<T>(reporter_name))
     467           0 :     mooseError("Reporter name \"",
     468             :                reporter_name,
     469             :                "\" with type \"",
     470             :                MooseUtils::prettyCppType<T>(),
     471             :                "\" is not declared.");
     472             : 
     473             :   // Force the const version of value, which does not allow for increasing time index
     474             :   return static_cast<const ReporterState<T> &>(
     475     1114164 :              getReporterStateHelper<T>(reporter_name, /* declare = */ false))
     476     1114164 :       .value(time_index);
     477             : }
     478             : 
     479             : template <typename T>
     480             : void
     481      536045 : ReporterData::setReporterValue(const ReporterName & reporter_name,
     482             :                                const T & value,
     483             :                                const std::size_t time_index)
     484             : {
     485             :   // https://stackoverflow.com/questions/123758/how-do-i-remove-code-duplication-between-similar-const-and-non-const-member-func
     486      536045 :   const auto & me = *this;
     487      536045 :   const_cast<T &>(me.getReporterValue<T>(reporter_name, time_index)) = value;
     488      536045 : }
     489             : 
     490             : template <typename T>
     491             : void
     492        4640 : ReporterData::needReporterTimeIndex(const ReporterName & reporter_name,
     493             :                                     const std::size_t time_index)
     494             : {
     495        4640 :   getReporterValue<T>(reporter_name, 0); // for error checking that it is declared
     496        4640 :   getReporterStateHelper<T>(reporter_name, /* declare = */ false).value(time_index);
     497        4640 : }
     498             : 
     499             : // This is defined here to avoid cyclic includes, see ReporterContext.h
     500             : template <typename T>
     501             : void
     502        2768 : ReporterContext<T>::transfer(ReporterData & r_data,
     503             :                              const ReporterName & r_name,
     504             :                              unsigned int time_index) const
     505             : {
     506        2768 :   r_data.setReporterValue<T>(r_name, _state.value(), time_index);
     507        2768 : }
     508             : 
     509             : // This is defined here to avoid cyclic includes, see ReporterContext.h
     510             : template <typename T>
     511             : void
     512         608 : ReporterContext<T>::transferToVector(ReporterData & r_data,
     513             :                                      const ReporterName & r_name,
     514             :                                      dof_id_type index,
     515             :                                      unsigned int time_index) const
     516             : {
     517             :   std::vector<T> & vec =
     518         608 :       const_cast<std::vector<T> &>(r_data.getReporterValue<std::vector<T>>(r_name, time_index));
     519             : 
     520         608 :   if (index >= vec.size())
     521           0 :     mooseError(
     522             :         "Requested index ", index, " is outside the bounds of the vector reporter value ", r_name);
     523         608 :   vec[index] = _state.value();
     524         608 : }
     525             : 
     526             : // This is defined here to avoid cyclic includes, see ReporterContext.h
     527             : template <typename T>
     528             : void
     529         192 : ReporterContext<T>::transferFromVector(ReporterData & r_data,
     530             :                                        const ReporterName & r_name,
     531             :                                        dof_id_type index,
     532             :                                        unsigned int time_index) const
     533             : {
     534             :   if constexpr (is_std_vector<T>::value)
     535             :   {
     536         192 :     if (index >= _state.value().size())
     537           0 :       mooseError("Requested index ",
     538             :                  index,
     539             :                  " is outside the bounds of the vector reporter value ",
     540             :                  r_name);
     541             : 
     542             :     using R = typename T::value_type;
     543         192 :     r_data.setReporterValue<R>(r_name, _state.value()[index], time_index);
     544             :   }
     545             :   else
     546             :   {
     547           0 :     libmesh_ignore(r_data);
     548           0 :     libmesh_ignore(r_name);
     549           0 :     libmesh_ignore(index);
     550           0 :     libmesh_ignore(time_index);
     551           0 :     mooseError("transferFromVector can only be used for reporter types that are specializatons of "
     552             :                "std::vector.");
     553             :   }
     554         192 : }
     555             : 
     556             : // This is defined here to avoid cyclic includes, see ReporterContext.h
     557             : template <typename T>
     558             : void
     559         189 : ReporterGeneralContext<T>::declareClone(ReporterData & r_data,
     560             :                                         const ReporterName & r_name,
     561             :                                         const ReporterMode & mode,
     562             :                                         const MooseObject & producer) const
     563             : {
     564         189 :   r_data.declareReporterValue<T, ReporterGeneralContext<T>>(r_name, mode, producer);
     565         189 : }
     566             : 
     567             : // This is defined here to avoid cyclic includes, see ReporterContext.h
     568             : template <typename T>
     569             : void
     570         423 : ReporterGeneralContext<T>::declareVectorClone(ReporterData & r_data,
     571             :                                               const ReporterName & r_name,
     572             :                                               const ReporterMode & mode,
     573             :                                               const MooseObject & producer) const
     574             : {
     575         423 :   r_data.declareReporterValue<std::vector<T>, ReporterVectorContext<T>>(r_name, mode, producer);
     576         423 : }
     577             : 
     578             : // This is defined here to avoid cyclic includes, see ReporterContext.h
     579             : template <typename T>
     580             : void
     581           0 : ReporterVectorContext<T>::declareClone(ReporterData &,
     582             :                                        const ReporterName &,
     583             :                                        const ReporterMode &,
     584             :                                        const MooseObject &) const
     585             : {
     586           0 :   mooseError("Cannot create clone with ReporterVectorContext.");
     587             : }
     588             : 
     589             : // This is defined here to avoid cyclic includes, see ReporterContext.h
     590             : template <typename T>
     591             : void
     592           0 : ReporterVectorContext<T>::declareVectorClone(ReporterData &,
     593             :                                              const ReporterName &,
     594             :                                              const ReporterMode &,
     595             :                                              const MooseObject &) const
     596             : {
     597           0 :   mooseError("Cannot create clone with ReporterVectorContext.");
     598             : }

Generated by: LCOV version 1.14