LCOV - code coverage report
Current view: top level - include/tallies - TallyBase.h (source / functions) Hit Total Coverage
Test: neams-th-coe/cardinal: cf347a Lines: 8 8 100.0 %
Date: 2026-06-03 12:57:15 Functions: 2 2 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /********************************************************************/
       2             : /*                  SOFTWARE COPYRIGHT NOTIFICATION                 */
       3             : /*                             Cardinal                             */
       4             : /*                                                                  */
       5             : /*                  (c) 2021 UChicago Argonne, LLC                  */
       6             : /*                        ALL RIGHTS RESERVED                       */
       7             : /*                                                                  */
       8             : /*                 Prepared by UChicago Argonne, LLC                */
       9             : /*               Under Contract No. DE-AC02-06CH11357               */
      10             : /*                With the U. S. Department of Energy               */
      11             : /*                                                                  */
      12             : /*             Prepared by Battelle Energy Alliance, LLC            */
      13             : /*               Under Contract No. DE-AC07-05ID14517               */
      14             : /*                With the U. S. Department of Energy               */
      15             : /*                                                                  */
      16             : /*                 See LICENSE for full restrictions                */
      17             : /********************************************************************/
      18             : 
      19             : #pragma once
      20             : 
      21             : #include "MooseObject.h"
      22             : #include "CardinalEnums.h"
      23             : 
      24             : #include "openmc/tallies/tally.h"
      25             : #include "openmc/tensor.h"
      26             : 
      27             : /// Forward declarations.
      28             : class OpenMCCellAverageProblem;
      29             : class MooseMesh;
      30             : class AuxiliarySystem;
      31             : class FilterBase;
      32             : 
      33             : typedef openmc::tensor::Tensor<double> OMCTensor;
      34             : 
      35             : class TallyBase : public MooseObject
      36             : {
      37             : public:
      38             :   static InputParameters validParams();
      39             : 
      40             :   TallyBase(const InputParameters & parameters);
      41             : 
      42             :   /**
      43             :    * A function which the derivied tally must override to create the OpenMC spatial filter
      44             :    * the object maps to.
      45             :    * @return a pair where the first entry is the filter index in the global filter array and the
      46             :    * second entry is the OpenMC filter
      47             :    */
      48             :   virtual std::pair<unsigned int, openmc::Filter *> spatialFilter() = 0;
      49             : 
      50             :   /**
      51             :    * A function to initialize the tally object. Override with care.
      52             :    */
      53             :   virtual void initializeTally();
      54             : 
      55             :   /**
      56             :    * A function to reset the tally object. Override with care.
      57             :    */
      58             :   virtual void resetTally();
      59             : 
      60             :   /**
      61             :    * A function which stores the results of this tally into the created
      62             :    * auxvariables. This calls storeResultsInner.
      63             :    * @param[in] var_numbers variables which the tally will store results in
      64             :    * @param[in] local_score index into the tally's local array of scores which represents the
      65             :    * current score being stored
      66             :    * @param[in] output_type the output type
      67             :    * @return the sum of the tally over all bins. Only applicable for 'output_type = relaxed'
      68             :    */
      69             :   Real storeResults(const std::vector<unsigned int> & var_numbers,
      70             :                     unsigned int local_score,
      71             :                     const std::string & output_type);
      72             : 
      73             :   /**
      74             :    * Add a score to this tally.
      75             :    * @param[in] score score to add
      76             :    */
      77             :   void addScore(const std::string & score);
      78             : 
      79             :   /**
      80             :    * A function which sets the relaxation type and factor for a tally.
      81             :    * @param[in] relaxation_type the type of relaxation to use
      82             :    * @param[in] factor the relaxation factor to use (for constant relxation or no relaxation)
      83             :    */
      84             :   virtual void setRelaxation(relaxation::RelaxationEnum relaxation_type,
      85             :                              const Real & relaxation_factor);
      86             : 
      87             :   /**
      88             :    * A function which computes and stores the sum and mean of the tally across all bins for a
      89             :    * particular score.
      90             :    */
      91             :   void computeSumAndMean();
      92             : 
      93             :   /**
      94             :    * A function which gathers the sums and means from all tallies linked to this tally.
      95             :    */
      96             :   virtual void gatherLinkedSum();
      97             : 
      98             :   /**
      99             :    * A function which renormalizes this tally based on the gathered sum from linked tallies.
     100             :    */
     101             :   virtual void renormalizeLinkedTallies();
     102             : 
     103             :   /**
     104             :    * Relax the tally and normalize it according to some normalization factor 'norm'. This tends to
     105             :    * either be the sum of the over all bins OR a global tally over the entire problem.
     106             :    *
     107             :    * NOTE: This function relaxes the tally _distribution_, and not the actual magnitude of the sum.
     108             :    * That is, we relax the shape distribution and then multiply it by the power
     109             :    * (for k-eigenvalue) or source strength (for fixed source) of the current step before
     110             :    * applying it to MOOSE. If the magnitude of the power or source strength is constant in time,
     111             :    * there is zero error in this. But if the magnitude of the tally varies in time, we are basically
     112             :    * relaxing the distribution of the tally, but then multiplying it by the _current_ mean tally
     113             :    * magnitude.
     114             :    *
     115             :    * There will be very small errors in these approximations unless the power/source strength
     116             :    * change dramatically with iteration. But because relaxation is itself a numerical approximation,
     117             :    * this is still inconsequential at the end of the day as long as your problem has converged
     118             :    * the relaxed tally to the raw (unrelaxed) tally.
     119             :    */
     120             :   void relaxAndNormalizeTally();
     121             : 
     122             :   /**
     123             :    * Add a linked tally for normalization.
     124             :    * @param[in] tally the other tally to link for normalization
     125             :    */
     126             :   void addLinkedTally(const TallyBase * other);
     127             : 
     128             :   /**
     129             :    * Get the local OpenMC tally that this object wraps.
     130             :    * @return the OpenMC tally object
     131             :    */
     132             :   const openmc::Tally * getWrappedTally() const;
     133             : 
     134             :   /**
     135             :    * Get the global OpenMC tally that this object wraps.
     136             :    * @return the OpenMC tally object
     137             :    */
     138             :   const openmc::Tally * getWrappedGlobalTally() const;
     139             : 
     140             :   /**
     141             :    * Get the ID of the tally this object wraps.
     142             :    */
     143             :   int32_t getTallyID() const;
     144             : 
     145             :   /**
     146             :    * Get the global ID of the tally this object wraps.
     147             :    */
     148             :   int32_t getGlobalTallyID() const;
     149             : 
     150             :   /**
     151             :    * Get the list of scores this tally uses.
     152             :    * @return list of scores this tally uses
     153             :    */
     154             :   const std::vector<std::string> & getScores() const { return _tally_score; }
     155             : 
     156             :   /**
     157             :    * Get the index corresponding to a specific score.
     158             :    * @param[in] score the score
     159             :    * @return the index of the score, -1 indicates the score does not exist
     160             :    */
     161             :   int scoreIndex(const std::string & score) const;
     162             : 
     163             :   /**
     164             :    * Gets the auxvariable names for use in creating and storing tally results.
     165             :    * This allows for the splitting of tally results into energy bins, angular bins, etc.
     166             :    *
     167             :    * @return vector of variable names to be associated with this tally
     168             :    */
     169             :   const std::vector<std::string> & getAuxVarNames() const { return _tally_name; }
     170             : 
     171             :   /**
     172             :    * Gets the output names to append to the end of the '_tally_name' when adding tally auxvariables
     173             :    * for additional outputs.
     174             :    * @return additional tally outputs
     175             :    */
     176             :   const std::vector<std::string> & getOutputs() const { return _output_name; }
     177             : 
     178             :   /**
     179             :    * Get the estimator used in this tally.
     180             :    * @return the tally estimator
     181             :    */
     182             :   openmc::TallyEstimator getTallyEstimator() const { return _estimator; }
     183             : 
     184             :   /**
     185             :    * Get the mean for a score summed over all bins.
     186             :    * @param[in] local_score the index representing a tally score
     187             :    * @return mean for a score summed over all bins.
     188             :    */
     189      178152 :   const Real & getMean(unsigned int local_score) const { return _local_mean_tally[local_score]; }
     190             : 
     191             :   /**
     192             :    * Get the sum for a score summed over all bins.
     193             :    * @param[in] local_score the index representing a tally score
     194             :    * @return sum for a score summed over all bins.
     195             :    */
     196             :   const Real & getSum(unsigned int local_score) const { return _local_sum_tally[local_score]; }
     197             : 
     198             :   /**
     199             :    * Get a vector of variable names corresponding to the provided score.
     200             :    * @param[in] score the score that the user wishes to fetch variable names from
     201             :    * @return a vector of variables corresponding to the score
     202             :    */
     203             :   std::vector<std::string> getScoreVars(const std::string & score) const;
     204             : 
     205             :   /**
     206             :    * Check to see if the given external filter bin is skipped during normalization.
     207             :    * @param[in] ext_bin the external filter bin
     208             :    * @return whether the bin is skipped during normalization or not
     209             :    */
     210             :   bool extBinSkipped(unsigned int ext_bin) const { return _ext_bins_to_skip[ext_bin]; }
     211             : 
     212             :   /**
     213             :    * Check to see if this tally uses a trigger or not.
     214             :    * @return whether this tally uses a trigger or not
     215             :    */
     216        2508 :   bool hasTrigger() const { return _tally_trigger != nullptr; }
     217             : 
     218             :   /**
     219             :    * Check to see if this tally adds additional output variables or not.
     220             :    * @return whether this tally adds additional output variables or not
     221             :    */
     222       10744 :   bool hasOutputs() const { return _has_outputs; }
     223             : 
     224             :   /**
     225             :    * Check to see if this tally contains a specific score.
     226             :    * @param[in] score the score to check
     227             :    * @return whether this tally has
     228             :    */
     229        3982 :   bool hasScore(const std::string & score) const
     230             :   {
     231        3982 :     return std::find(_tally_score.begin(), _tally_score.end(), score) != _tally_score.end();
     232             :   }
     233             : 
     234             :   /**
     235             :    * Check to see if the user has requested special names for the tallies.
     236             :    * @return whether this tally names stored values something other than '_tally_score'
     237             :    */
     238          18 :   bool renamesTallyVars() const { return _renames_tally_vars; }
     239             : 
     240             :   /**
     241             :    * Get the total number of external filter bins applied to this tally.
     242             :    * @return the total number of external filter bins.
     243             :    */
     244        2524 :   unsigned int numExtFilterBins() const { return _num_ext_filter_bins; }
     245             : 
     246             :   /**
     247             :    * A function to get the blocks associated with this CellTally.
     248             :    * @return a set of blocks associated with this tally.
     249             :    */
     250             :   const std::set<SubdomainID> & getBlocks() const { return _tally_blocks; }
     251             : 
     252             :   /**
     253             :    * Whether this tally requires a global tally or not.
     254             :    * @return if the tally adds a global tally in addition to a mapped local tally
     255             :    */
     256        6902 :   virtual bool addingGlobalTally() const { return _needs_global_tally; }
     257             : 
     258             :   /**
     259             :    * Get the vector of tallies linked to this tally object for normalization
     260             :    * @return the vector of linked tallies
     261             :    */
     262             :   const std::vector<const TallyBase *> & linkedTallies() const { return _linked_tallies; }
     263             : 
     264             : protected:
     265             :   /**
     266             :    * A function which stores the results of this tally into the created
     267             :    * auxvariables. This must be implemented by the derived class.
     268             :    * @param[in] var_numbers variables which the tally will store results in
     269             :    * @param[in] local_score index into the tally's local array of scores which represents the
     270             :    * current score being stored
     271             :    * @param[in] tally_vals the tally values to store
     272             :    * @param[in] norm_by_src_rate whether or not tally_vals should be normalized by the source rate
     273             :    * @return the sum of the tally over all bins.
     274             :    */
     275             :   virtual Real storeResultsInner(const std::vector<unsigned int> & var_numbers,
     276             :                                  unsigned int local_score,
     277             :                                  const std::vector<OMCTensor> & tally_vals,
     278             :                                  bool norm_by_src_rate = true) = 0;
     279             : 
     280             :   /**
     281             :    * Set an auxiliary elemental variable to a specified value
     282             :    * @param[in] var_num variable number
     283             :    * @param[in] elem_ids element IDs to set
     284             :    * @param[in] value value to set
     285             :    */
     286             :   void fillElementalAuxVariable(const unsigned int & var_num,
     287             :                                 const std::vector<unsigned int> & elem_ids,
     288             :                                 const Real & value);
     289             : 
     290             :   /**
     291             :    * Applies triggers to a tally. This is often the local tally wrapped by this object.
     292             :    * @param[in] tally the tally to apply triggers to
     293             :    */
     294             :   void applyTriggersToLocalTally(openmc::Tally * tally);
     295             : 
     296             :   /**
     297             :    * Factor by which to normalize a tally
     298             :    * @param[in] score index for the tally score
     299             :    * @return value to divide tally sum by for normalization
     300             :    */
     301             :   Real tallyNormalization(unsigned int score) const;
     302             : 
     303             :   /**
     304             :    * Check the sum of the tallies against the global tally
     305             :    * @param[in] score tally score
     306             :    */
     307             :   void checkTallySum(const unsigned int & score) const;
     308             : 
     309             :   /**
     310             :    * Check that the tally normalization gives a total tally sum of 1.0 (when normalized
     311             :    * against the total tally value).
     312             :    * @param[in] sum sum of the tally
     313             :    * @param[in] score tally score
     314             :    */
     315             :   void checkNormalization(const Real & sum, unsigned int score) const;
     316             : 
     317             :   /// The OpenMCCellAverageProblem using the tally system.
     318             :   OpenMCCellAverageProblem & _openmc_problem;
     319             : 
     320             :   /// The MooseMesh.
     321             :   MooseMesh & _mesh;
     322             : 
     323             :   /// The aux system.
     324             :   AuxiliarySystem & _aux;
     325             : 
     326             :   /// The external filters added in the [Problem/Filters] block.
     327             :   std::vector<std::shared_ptr<FilterBase>> _ext_filters;
     328             : 
     329             :   /// The OpenMC estimator to use with this tally.
     330             :   openmc::TallyEstimator _estimator;
     331             : 
     332             :   /// OpenMC tally score(s) to use with this tally.
     333             :   std::vector<std::string> _tally_score;
     334             : 
     335             :   /// Auxiliary variable name(s) for this tally.
     336             :   std::vector<std::string> _tally_name;
     337             : 
     338             :   /// The OpenMC tally object this class wraps.
     339             :   openmc::Tally * _local_tally = nullptr;
     340             : 
     341             :   /// The index of the OpenMC tally this object wraps.
     342             :   unsigned int _local_tally_index;
     343             : 
     344             :   /**
     345             :    * The global OpenMC tally object this class wraps. Used for global normalization
     346             :    * and error-checking of the sum of local tally results over all bins.
     347             :    */
     348             :   openmc::Tally * _global_tally = nullptr;
     349             : 
     350             :   /// The index of the global OpenMC tally this object wraps.
     351             :   unsigned int _global_tally_index;
     352             : 
     353             :   /// The index of the first filter added by this tally.
     354             :   unsigned int _filter_index;
     355             : 
     356             :   /// The number of non-spatial bins in this tally.
     357             :   unsigned int _num_ext_filter_bins = 1;
     358             : 
     359             :   /// Sum value of this tally across all bins. Indexed by score.
     360             :   std::vector<Real> _local_sum_tally;
     361             : 
     362             :   /**
     363             :    * Sum value of the global tally associated with this tally object. Each entry in
     364             :    * _global_sum_tally corresponds to a score in _tally_score. As an example,
     365             :    * _global_sum_tally[0] corresponds to the score located at _tally_score[0].
     366             :    */
     367             :   std::vector<Real> _global_sum_tally;
     368             : 
     369             :   /**
     370             :    * Mean value of this tally across all bins; only used for fixed source mode.
     371             :    * Each entry in _local_mean_tally corresponds to a score in _tally_score. As
     372             :    * an example, _local_mean_tally[0] corresponds to the score located at
     373             :    * _tally_score[0].
     374             :    */
     375             :   std::vector<Real> _local_mean_tally;
     376             : 
     377             :   /// Linked sum value across all bins. Indexed by score.
     378             :   std::vector<Real> _linked_local_sum_tally;
     379             : 
     380             :   /**
     381             :    * Type of trigger to apply to OpenMC tallies to indicate when
     382             :    * the simulation is complete. These can be used to on-the-fly adjust the number
     383             :    * of active batches in order to reach some desired criteria (which is specified
     384             :    * by this parameter).
     385             :    */
     386             :   const MultiMooseEnum * _tally_trigger;
     387             : 
     388             :   /**
     389             :    * Thresholds to use for accepting this tally when using triggers. Indexed by
     390             :    * score.
     391             :    */
     392             :   std::vector<Real> _tally_trigger_threshold;
     393             : 
     394             :   /**
     395             :    * Whether tally bins for certain scores should ignore bins with zeros when computing
     396             :    * trigger metrics. Indexed by the tally score.
     397             :    */
     398             :   std::vector<bool> _trigger_ignore_zeros;
     399             : 
     400             :   /**
     401             :    * Current fixed point iteration tally result; for instance, when using constant
     402             :    * relaxation, the tally is updated as:
     403             :    * q(n+1) = (1-a) * q(n) + a * PHI(q(n), s)
     404             :    * where q(n+1) is _current_tally, a is the relaxation factor, q(n)
     405             :    * is _previous_tally, and PHI is the most-recently-computed tally result
     406             :    * (the _current_raw_tally).
     407             :    */
     408             :   std::vector<OMCTensor> _current_tally;
     409             : 
     410             :   /// Previous fixed point iteration tally result (after relaxation)
     411             :   std::vector<OMCTensor> _previous_tally;
     412             : 
     413             :   /// Current "raw" tally output from Monte Carlo solution
     414             :   std::vector<OMCTensor> _current_raw_tally;
     415             : 
     416             :   /// Current "raw" tally relative error.
     417             :   std::vector<OMCTensor> _current_raw_tally_rel_error;
     418             : 
     419             :   /// Current "raw" tally standard deviation
     420             :   std::vector<OMCTensor> _current_raw_tally_std_dev;
     421             : 
     422             :   /**
     423             :    * How to normalize the OpenMC tally into units of W/volume. If 'true',
     424             :    * normalization is performed by dividing each local tally against a problem-global
     425             :    * tally. The advantage of this approach is that some non-zero tally regions of the
     426             :    * OpenMC domain can be excluded from multiphysics feedback (without us having to guess
     427             :    * what the power of the *included* part of the domain is). This can let us do
     428             :    * "zooming" type calculations, where perhaps we only want to send T/H feedback to
     429             :    * one bundle in a full core.
     430             :    *
     431             :    * If 'false', normalization is performed by dividing each local tally by the sum
     432             :    * of the local tally itself. The advantage of this approach becomes evident when
     433             :    * using mesh tallies. If a mesh tally does not perfectly align with an OpenMC cell -
     434             :    * for instance, a first-order sphere mesh will not perfectly match the volume of a
     435             :    * TRISO pebble - then not all of the power actually produced in the pebble is
     436             :    * tallies on the mesh approximation to that pebble. Therefore, if you set a core
     437             :    * power of 1 MW and you normalized based on a global tally, you'd always
     438             :    * miss some of that power when sending to MOOSE. So, in this case, it is better to
     439             :    * normalize against the local tally itself so that the correct power is preserved.
     440             :    */
     441             :   const bool _normalize_by_global;
     442             : 
     443             :   /**
     444             :    * Whether to check the tallies against the global tally;
     445             :    * if set to true, and the tallies added for the 'tally_blocks' do not
     446             :    * sum to the global tally, an error is thrown. If you are
     447             :    * only performing multiphysics feedback for, say, a single assembly in a
     448             :    * full-core OpenMC model, you must set this check to false, because there
     449             :    * are known fission sources outside the domain of interest.
     450             :    *
     451             :    * If not specified, then this is set to 'true' if normalizing by a global
     452             :    * tally, and to 'false' if normalizing by the local tally (because when we choose
     453             :    * to normalize by the local tally, we're probably using mesh tallies). But you can
     454             :    * of course still set a value for this parameter to override the default.
     455             :    */
     456             :   const bool _check_tally_sum;
     457             : 
     458             :   /**
     459             :    * Whether a global tally is required for the sake of normalization and/or checking
     460             :    * the tally sum
     461             :    */
     462             :   const bool _needs_global_tally;
     463             : 
     464             :   /// Whether this tally stores results in variables names something other than '_tally_score'.
     465             :   const bool _renames_tally_vars;
     466             : 
     467             :   /// Whether this tally has additional outputs or not.
     468             :   const bool _has_outputs;
     469             : 
     470             :   /// Suffixes to apply to 'tally_name' in order to name the fields in the 'output'.
     471             :   std::vector<std::string> _output_name;
     472             : 
     473             :   /// Whether the problem uses adaptive mesh refinement or not.
     474             :   const bool _is_adaptive;
     475             : 
     476             :   /// External filter bins to skip while computing the tally sum and mean for normalization.
     477             :   std::vector<bool> _ext_bins_to_skip;
     478             : 
     479             :   /// Blocks for which to add tallies.
     480             :   std::set<SubdomainID> _tally_blocks;
     481             : 
     482             :   /// Other tallies linked for normalization.
     483             :   std::vector<const TallyBase *> _linked_tallies;
     484             : 
     485             :   /// The type of relaxation this tally should employ.
     486             :   relaxation::RelaxationEnum _relaxation_type;
     487             : 
     488             :   /// The relaxation factor this tally should use (for constant relaxation).
     489             :   Real _relaxation_factor;
     490             : 
     491             :   /// Tolerance for setting zero tally
     492             :   static constexpr Real ZERO_TALLY_THRESHOLD = 1e-12;
     493             : };

Generated by: LCOV version 1.14