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 "xtensor/xview.hpp" 26 : 27 : /// Forward declarations. 28 : class OpenMCCellAverageProblem; 29 : class MooseMesh; 30 : class AuxiliarySystem; 31 : class FilterBase; 32 : 33 : class TallyBase : public MooseObject 34 : { 35 : public: 36 : static InputParameters validParams(); 37 : 38 : TallyBase(const InputParameters & parameters); 39 : 40 : /** 41 : * A function which the derivied tally must override to create the OpenMC spatial filter 42 : * the object maps to. 43 : * @return a pair where the first entry is the filter index in the global filter array and the 44 : * second entry is the OpenMC filter 45 : */ 46 : virtual std::pair<unsigned int, openmc::Filter *> spatialFilter() = 0; 47 : 48 : /** 49 : * A function to initialize the tally object. Override with care. 50 : */ 51 : virtual void initializeTally(); 52 : 53 : /** 54 : * A function to reset the tally object. Override with care. 55 : */ 56 : virtual void resetTally(); 57 : 58 : /** 59 : * A function which stores the results of this tally into the created 60 : * auxvariables. This calls storeResultsInner. 61 : * @param[in] var_numbers variables which the tally will store results in 62 : * @param[in] local_score index into the tally's local array of scores which represents the 63 : * current score being stored 64 : * @param[in] global_score index into the global array of tally results 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 : unsigned int global_score, 72 : const std::string & output_type); 73 : 74 : /** 75 : * Add a score to this tally. 76 : * @param[in] score score to add 77 : */ 78 : void addScore(const std::string & score); 79 : 80 : /** 81 : * A function which computes and stores the sum and mean of the tally across all bins for a 82 : * particular score. 83 : */ 84 : void computeSumAndMean(); 85 : 86 : /** 87 : * Relax the tally and normalize it according to some normalization factor 'norm'. This tends to 88 : * either be the sum of the over all bins OR a global tally over the entire problem. 89 : * 90 : * NOTE: This function relaxes the tally _distribution_, and not the actual magnitude of the sum. 91 : * That is, we relax the shape distribution and then multiply it by the power 92 : * (for k-eigenvalue) or source strength (for fixed source) of the current step before 93 : * applying it to MOOSE. If the magnitude of the power or source strength is constant in time, 94 : * there is zero error in this. But if the magnitude of the tally varies in time, we are basically 95 : * relaxing the distribution of the tally, but then multiplying it by the _current_ mean tally 96 : * magnitude. 97 : * 98 : * There will be very small errors in these approximations unless the power/source strength 99 : * change dramatically with iteration. But because relaxation is itself a numerical approximation, 100 : * this is still inconsequential at the end of the day as long as your problem has converged 101 : * the relaxed tally to the raw (unrelaxed) tally. 102 : * @param[in] local_score the local index of the current score to normalize 103 : * @param[in] alpha the relaxation factor 104 : * @param[in] norm the normalization factor 105 : */ 106 : void relaxAndNormalizeTally(unsigned int local_score, const Real & alpha, const Real & norm); 107 : 108 : /** 109 : * Get the OpenMC tally that this object wraps. 110 : * @return the OpenMC tally object 111 : */ 112 : const openmc::Tally * getWrappedTally() const; 113 : 114 : /** 115 : * Get the ID of the tally this object wraps. 116 : */ 117 : int32_t getTallyID() const; 118 : 119 : /** 120 : * Get the list of scores this tally uses. 121 : * @return list of scores this tally uses 122 : */ 123 2498 : const std::vector<std::string> & getScores() const { return _tally_score; } 124 : 125 : /** 126 : * Get the index corresponding to a specific score. 127 : * @param[in] score the score 128 : * @return the index of the score, -1 indicates the score does not exist 129 : */ 130 : int scoreIndex(const std::string & score) const; 131 : 132 : /** 133 : * Gets the auxvariable names for use in creating and storing tally results. 134 : * This allows for the splitting of tally results into energy bins, angular bins, etc. 135 : * 136 : * @return vector of variable names to be associated with this tally 137 : */ 138 : const std::vector<std::string> & getAuxVarNames() const { return _tally_name; } 139 : 140 : /** 141 : * Gets the output names to append to the end of the '_tally_name' when adding tally auxvariables 142 : * for additional outputs. 143 : * @return additional tally outputs 144 : */ 145 : const std::vector<std::string> & getOutputs() const { return _output_name; } 146 : 147 : /** 148 : * Get the estimator used in this tally. 149 : * @return the tally estimator 150 : */ 151 1344 : openmc::TallyEstimator getTallyEstimator() const { return _estimator; } 152 : 153 : /** 154 : * Get the mean for a score summed over all bins. 155 : * @param[in] local_score the index representing a tally score 156 : * @return mean for a score summed over all bins. 157 : */ 158 : const Real & getMean(unsigned int local_score) const { return _local_mean_tally[local_score]; } 159 : 160 : /** 161 : * Get the sum for a score summed over all bins. 162 : * @param[in] local_score the index representing a tally score 163 : * @return sum for a score summed over all bins. 164 : */ 165 3552 : const Real & getSum(unsigned int local_score) const { return _local_sum_tally[local_score]; } 166 : 167 : /** 168 : * Get a vector of variable names corresponding to the provided score. 169 : * @param[in] score the score that the user wishes to fetch variable names from 170 : * @return a vector of variables corresponding to the score 171 : */ 172 : std::vector<std::string> getScoreVars(const std::string & score) const; 173 : 174 : /** 175 : * Check to see if the given external filter bin is skipped during normalization. 176 : * @param[in] ext_bin the external filter bin 177 : * @return whether the bin is skipped during normalization or not 178 : */ 179 : bool extBinSkipped(unsigned int ext_bin) const { return _ext_bins_to_skip[ext_bin]; } 180 : 181 : /** 182 : * Check to see if this tally uses a trigger or not. 183 : * @return whether this tally uses a trigger or not 184 : */ 185 2400 : bool hasTrigger() const { return _tally_trigger != nullptr; } 186 : 187 : /** 188 : * Check to see if this tally adds additional output variables or not. 189 : * @return whether this tally adds additional output variables or not 190 : */ 191 10192 : bool hasOutputs() const { return _has_outputs; } 192 : 193 : /** 194 : * Check to see if this tally contains a specific score. 195 : * @param[in] score the score to check 196 : * @return whether this tally has 197 : */ 198 1732 : bool hasScore(const std::string & score) const 199 : { 200 1732 : return std::find(_tally_score.begin(), _tally_score.end(), score) != _tally_score.end(); 201 : } 202 : 203 : /** 204 : * Check to see if the user has requested special names for the tallies. 205 : * @return whether this tally names stored values something other than '_tally_score' 206 : */ 207 18 : bool renamesTallyVars() const { return _renames_tally_vars; } 208 : 209 : /** 210 : * Get the total number of external filter bins applied to this tally. 211 : * @return the total number of external filter bins. 212 : */ 213 2417 : unsigned int numExtFilterBins() const { return _num_ext_filter_bins; } 214 : 215 : protected: 216 : /** 217 : * A function which stores the results of this tally into the created 218 : * auxvariables. This must be implemented by the derived class. 219 : * @param[in] var_numbers variables which the tally will store results in 220 : * @param[in] local_score index into the tally's local array of scores which represents the 221 : * current score being stored 222 : * @param[in] global_score index into the global array of tally results which represents the 223 : * current score being stored 224 : * @param[in] tally_vals the tally values to store 225 : * @param[in] norm_by_src_rate whether or not tally_vals should be normalized by the source rate 226 : * @return the sum of the tally over all bins. 227 : */ 228 : virtual Real storeResultsInner(const std::vector<unsigned int> & var_numbers, 229 : unsigned int local_score, 230 : unsigned int global_score, 231 : std::vector<xt::xtensor<double, 1>> tally_vals, 232 : bool norm_by_src_rate = true) = 0; 233 : 234 : /** 235 : * Set an auxiliary elemental variable to a specified value 236 : * @param[in] var_num variable number 237 : * @param[in] elem_ids element IDs to set 238 : * @param[in] value value to set 239 : */ 240 : void fillElementalAuxVariable(const unsigned int & var_num, 241 : const std::vector<unsigned int> & elem_ids, 242 : const Real & value); 243 : 244 : /** 245 : * Applies triggers to a tally. This is often the local tally wrapped by this object. 246 : * @param[in] tally the tally to apply triggers to 247 : */ 248 : void applyTriggersToLocalTally(openmc::Tally * tally); 249 : 250 : /// The OpenMCCellAverageProblem using the tally system. 251 : OpenMCCellAverageProblem & _openmc_problem; 252 : 253 : /// The MooseMesh. 254 : MooseMesh & _mesh; 255 : 256 : /// The aux system. 257 : AuxiliarySystem & _aux; 258 : 259 : /// The external filters added in the [Problem/Filters] block. 260 : std::vector<std::shared_ptr<FilterBase>> _ext_filters; 261 : 262 : /// The OpenMC estimator to use with this tally. 263 : openmc::TallyEstimator _estimator; 264 : 265 : /// OpenMC tally score(s) to use with this tally. 266 : std::vector<std::string> _tally_score; 267 : 268 : /// Auxiliary variable name(s) for this tally. 269 : std::vector<std::string> _tally_name; 270 : 271 : /// The OpenMC tally object this class wraps. 272 : openmc::Tally * _local_tally = nullptr; 273 : 274 : /// The index of the OpenMC tally this object wraps. 275 : unsigned int _local_tally_index; 276 : 277 : /// The index of the first filter added by this tally. 278 : unsigned int _filter_index; 279 : 280 : /// The number of non-spatial bins in this tally. 281 : unsigned int _num_ext_filter_bins = 1; 282 : 283 : /// Sum value of this tally across all bins. Indexed by score. 284 : std::vector<Real> _local_sum_tally; 285 : 286 : /** 287 : * Mean value of this tally across all bins; only used for fixed source mode. 288 : * Indexed by score. 289 : */ 290 : std::vector<Real> _local_mean_tally; 291 : 292 : /** 293 : * Type of trigger to apply to OpenMC tallies to indicate when 294 : * the simulation is complete. These can be used to on-the-fly adjust the number 295 : * of active batches in order to reach some desired criteria (which is specified 296 : * by this parameter). 297 : */ 298 : const MultiMooseEnum * _tally_trigger; 299 : 300 : /** 301 : * Thresholds to use for accepting this tally when using triggers. Indexed by 302 : * score. 303 : */ 304 : std::vector<Real> _tally_trigger_threshold; 305 : 306 : /** 307 : * Whether tally bins for certain scores should ignore bins with zeros when computing 308 : * trigger metrics. Indexed by the tally score. 309 : */ 310 : std::vector<bool> _trigger_ignore_zeros; 311 : 312 : /** 313 : * Current fixed point iteration tally result; for instance, when using constant 314 : * relaxation, the tally is updated as: 315 : * q(n+1) = (1-a) * q(n) + a * PHI(q(n), s) 316 : * where q(n+1) is _current_tally, a is the relaxation factor, q(n) 317 : * is _previous_tally, and PHI is the most-recently-computed tally result 318 : * (the _current_raw_tally). 319 : */ 320 : std::vector<xt::xtensor<double, 1>> _current_tally; 321 : 322 : /// Previous fixed point iteration tally result (after relaxation) 323 : std::vector<xt::xtensor<double, 1>> _previous_tally; 324 : 325 : /// Current "raw" tally output from Monte Carlo solution 326 : std::vector<xt::xtensor<double, 1>> _current_raw_tally; 327 : 328 : /// Current "raw" tally relative error. 329 : std::vector<xt::xtensor<double, 1>> _current_raw_tally_rel_error; 330 : 331 : /// Current "raw" tally standard deviation 332 : std::vector<xt::xtensor<double, 1>> _current_raw_tally_std_dev; 333 : 334 : /// Whether this tally stores results in variables names something other than '_tally_score'. 335 : const bool _renames_tally_vars; 336 : 337 : /// Whether this tally has additional outputs or not. 338 : const bool _has_outputs; 339 : 340 : /// Suffixes to apply to 'tally_name' in order to name the fields in the 'output'. 341 : std::vector<std::string> _output_name; 342 : 343 : /// Whether the problem uses adaptive mesh refinement or not. 344 : const bool _is_adaptive; 345 : 346 : /// External filter bins to skip while computing the tally sum and mean for normalization. 347 : std::vector<bool> _ext_bins_to_skip; 348 : 349 : /// Tolerance for setting zero tally 350 : static constexpr Real ZERO_TALLY_THRESHOLD = 1e-12; 351 : };