LCOV - code coverage report
Current view: top level - src/tallies - TallyBase.C (source / functions) Hit Total Coverage
Test: neams-th-coe/cardinal: f3518d Lines: 260 267 97.4 %
Date: 2025-10-01 10:06:53 Functions: 14 14 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             : #ifdef ENABLE_OPENMC_COUPLING
      20             : #include "TallyBase.h"
      21             : 
      22             : #include "OpenMCCellAverageProblem.h"
      23             : #include "UserErrorChecking.h"
      24             : #include "AuxiliarySystem.h"
      25             : #include "FilterBase.h"
      26             : 
      27             : #include "AngularLegendreFilter.h"
      28             : #include "EnergyOutFilter.h"
      29             : #include "DelayedGroupFilter.h"
      30             : 
      31             : #include "openmc/settings.h"
      32             : 
      33             : InputParameters
      34        4837 : TallyBase::validParams()
      35             : {
      36        4837 :   auto params = MooseObject::validParams();
      37        9674 :   params.addParam<MultiMooseEnum>(
      38             :       "score",
      39        9674 :       getTallyScoreEnum(),
      40             :       "Score(s) to use in the OpenMC tallies. If not specified, defaults to 'kappa_fission'");
      41        9674 :   params.addParam<MooseEnum>(
      42        9674 :       "estimator", getTallyEstimatorEnum(), "Type of tally estimator to use in OpenMC");
      43        9674 :   params.addParam<std::vector<std::string>>(
      44             :       "name",
      45             :       "Auxiliary variable name(s) to use for OpenMC tallies. "
      46             :       "If not specified, defaults to the names of the scores");
      47             : 
      48        9674 :   params.addParam<std::vector<SubdomainName>>(
      49             :       "block",
      50             :       "Subdomains for which to add tallies in OpenMC. If not provided, "
      51             :       "tallies will be applied over the entire domain corresponding to the [Mesh] block.");
      52        9674 :   params.addParam<std::vector<SubdomainName>>("blocks",
      53             :                                               "This parameter is deprecated, use 'block' instead!");
      54             : 
      55        4837 :   MultiMooseEnum tally_trigger("rel_err none");
      56        9674 :   params.addParam<MultiMooseEnum>(
      57             :       "trigger",
      58             :       tally_trigger,
      59             :       "Trigger criterion to determine when OpenMC simulation is complete "
      60             :       "based on tallies. If multiple scores are specified in 'score, "
      61             :       "this same trigger is applied to all scores.");
      62        9674 :   params.addRangeCheckedParam<std::vector<Real>>(
      63             :       "trigger_threshold", "trigger_threshold > 0", "Threshold for the tally trigger");
      64        9674 :   params.addParam<std::vector<bool>>(
      65             :       "trigger_ignore_zeros",
      66             :       {false},
      67             :       "Whether tally bins with zero scores are ignored when computing the tally trigger. If only "
      68             :       "one "
      69             :       "value of 'trigger_ignore_zeros' is provided, that value is applied to all tally scores.");
      70             : 
      71             :   MultiMooseEnum openmc_outputs(
      72        4837 :       "unrelaxed_tally_std_dev unrelaxed_tally_rel_error unrelaxed_tally");
      73        9674 :   params.addParam<MultiMooseEnum>(
      74             :       "output",
      75             :       openmc_outputs,
      76             :       "UNRELAXED field(s) to output from OpenMC for each tally score. "
      77             :       "unrelaxed_tally_std_dev will write the standard deviation of "
      78             :       "each tally into auxiliary variables "
      79             :       "named *_std_dev. unrelaxed_tally_rel_error will write the "
      80             :       "relative standard deviation (unrelaxed_tally_std_dev / unrelaxed_tally) "
      81             :       "of each tally into auxiliary variables named *_rel_error. "
      82             :       "unrelaxed_tally will write the raw unrelaxed tally into auxiliary "
      83             :       "variables named *_raw (replace * with 'name').");
      84             : 
      85        9674 :   params.addParam<std::vector<std::string>>("filters", "External filters to add to this tally.");
      86             : 
      87        4837 :   params.addPrivateParam<OpenMCCellAverageProblem *>("_openmc_problem");
      88             : 
      89        4837 :   params.registerBase("Tally");
      90        4837 :   params.registerSystemAttributeName("Tally");
      91             : 
      92        4837 :   return params;
      93        4837 : }
      94             : 
      95        2567 : TallyBase::TallyBase(const InputParameters & parameters)
      96             :   : MooseObject(parameters),
      97        2567 :     _openmc_problem(*getParam<OpenMCCellAverageProblem *>("_openmc_problem")),
      98        2567 :     _mesh(_openmc_problem.mesh()),
      99        2567 :     _aux(_openmc_problem.getAuxiliarySystem()),
     100        2815 :     _tally_trigger(isParamValid("trigger") ? &getParam<MultiMooseEnum>("trigger") : nullptr),
     101        7701 :     _trigger_ignore_zeros(getParam<std::vector<bool>>("trigger_ignore_zeros")),
     102        5134 :     _renames_tally_vars(isParamValid("name")),
     103        5134 :     _has_outputs(isParamValid("output")),
     104        7701 :     _is_adaptive(_openmc_problem.hasAdaptivity())
     105             : {
     106        5134 :   if (isParamValid("score"))
     107             :   {
     108        2960 :     const auto & scores = getParam<MultiMooseEnum>("score");
     109        3354 :     for (const auto & score : scores)
     110        3748 :       _tally_score.push_back(_openmc_problem.enumToTallyScore(score));
     111             :   }
     112             :   else
     113        2174 :     _tally_score = {"kappa-fission"};
     114             : 
     115             :   const bool heating =
     116        2567 :       std::find(_tally_score.begin(), _tally_score.end(), "heating") != _tally_score.end();
     117             :   const bool nu_scatter =
     118        2567 :       std::find(_tally_score.begin(), _tally_score.end(), "nu-scatter") != _tally_score.end();
     119             : 
     120        5134 :   if (isParamValid("estimator"))
     121             :   {
     122         350 :     auto estimator = getParam<MooseEnum>("estimator").getEnum<tally::TallyEstimatorEnum>();
     123             : 
     124             :     // Photon heating tallies cannot use tracklength estimators.
     125         350 :     if (estimator == tally::tracklength && openmc::settings::photon_transport && heating)
     126           2 :       paramError("estimator",
     127             :                  "Tracklength estimators are currently incompatible with photon transport and "
     128             :                  "heating scores! For more information: https://tinyurl.com/3wre3kwt");
     129             : 
     130         348 :     if (estimator != tally::analog && nu_scatter)
     131           2 :       paramError("estimator", "Non-analog estimators are not supported for nu_scatter scores!");
     132             : 
     133         346 :     _estimator = _openmc_problem.tallyEstimator(estimator);
     134             :   }
     135             :   else
     136             :   {
     137             :     /**
     138             :      * Set a default of tracklength for all tallies other then heating tallies in photon transport
     139             :      * and nu_scatter tallies. This behavior must be overridden in derived tallies that implement
     140             :      * mesh filters.
     141             :      */
     142        2217 :     _estimator = openmc::TallyEstimator::TRACKLENGTH;
     143             : 
     144        2217 :     if (nu_scatter && !(heating && openmc::settings::photon_transport))
     145           8 :       _estimator = openmc::TallyEstimator::ANALOG;
     146        2209 :     else if (nu_scatter && heating && openmc::settings::photon_transport)
     147           2 :       paramError(
     148             :           "estimator",
     149             :           "A single tally cannot score both nu_scatter and heating when photon transport is "
     150             :           "enabled, as both scores require different estimators. Consider adding one tally "
     151             :           "which scores nu_scatter (with an analog estimator), and a second tally that scores "
     152             :           "heating (with a collision estimator).");
     153             : 
     154        2215 :     if (heating && openmc::settings::photon_transport)
     155           8 :       _estimator = openmc::TallyEstimator::COLLISION;
     156             :   }
     157             : 
     158        2561 :   if (heating && !openmc::settings::photon_transport)
     159         140 :     mooseWarning(
     160             :         "When using the 'heating' score with photon transport disabled, energy deposition\n"
     161             :         "from photons is neglected unless you specifically ran NJOY to produce MT=301 with\n"
     162             :         "photon energy deposited locally (not true for any pre-packaged OpenMC data libraries\n"
     163             :         "on openmc.org).\n\n"
     164             :         "If you did NOT specifically run NJOY yourself with this customization, we recommend\n"
     165             :         "using the 'heating_local' score instead, which will capture photon energy deposition.\n"
     166             :         "Otherwise, you will underpredict the true energy deposition.");
     167             : 
     168        7683 :   if (isParamValid("trigger") != isParamValid("trigger_threshold"))
     169           2 :     paramError("trigger",
     170             :                "You must either specify none or both of 'trigger' and "
     171             :                "'trigger_threshold'. You have specified only one.");
     172             : 
     173        2559 :   if (_tally_trigger)
     174             :   {
     175         244 :     checkRequiredParam(parameters, "trigger_threshold", "using tally triggers");
     176         244 :     _tally_trigger_threshold = getParam<std::vector<Real>>("trigger_threshold");
     177             : 
     178         122 :     if (_tally_trigger->size() != _tally_score.size())
     179           2 :       paramError("trigger",
     180           2 :                  "'trigger' (size " + std::to_string(_tally_trigger->size()) +
     181           2 :                      ") must have the same length as 'score' (size " +
     182           2 :                      std::to_string(_tally_score.size()) + ")");
     183             : 
     184         120 :     if (_tally_trigger_threshold.size() != _tally_score.size())
     185           2 :       paramError("trigger_threshold",
     186           2 :                  "'trigger_threshold' (size " + std::to_string(_tally_trigger_threshold.size()) +
     187           2 :                      ") must have the same length as 'score' (size " +
     188           2 :                      std::to_string(_tally_score.size()) + ")");
     189             : 
     190         118 :     if (_trigger_ignore_zeros.size() > 1)
     191             :     {
     192           2 :       if (_tally_score.size() != _trigger_ignore_zeros.size())
     193           2 :         paramError("trigger_ignore_zeros",
     194           2 :                    "'trigger_ignore_zeros' (size " + std::to_string(_trigger_ignore_zeros.size()) +
     195           2 :                        ") must have the same length as 'score' (size " +
     196           2 :                        std::to_string(_tally_score.size()) + ")");
     197             :     }
     198         116 :     else if (_trigger_ignore_zeros.size() == 1)
     199         114 :       _trigger_ignore_zeros.resize(_tally_score.size(), _trigger_ignore_zeros[0]);
     200             : 
     201         230 :     _openmc_problem.checkEmptyVector(_trigger_ignore_zeros, "trigger_ignore_zeros");
     202             :   }
     203             : 
     204             :   // Fetch the filters required by this tally. Error if the filter hasn't been added yet.
     205        5102 :   if (isParamValid("filters"))
     206             :   {
     207        2482 :     for (const auto & filter_name : getParam<std::vector<std::string>>("filters"))
     208             :     {
     209        2262 :       if (!_openmc_problem.hasFilter(filter_name))
     210           4 :         paramError("filters", "Filter with the name " + filter_name + " does not exist!");
     211             : 
     212        1130 :       _ext_filters.push_back(_openmc_problem.getFilter(filter_name));
     213             :     }
     214             :   }
     215             : 
     216             :   // Check the estimator to make sure it doesn't conflict with certain filters.
     217        3673 :   for (auto & f : _ext_filters)
     218             :   {
     219        1130 :     if ((dynamic_cast<AngularLegendreFilter *>(f.get()) ||
     220        1130 :          dynamic_cast<EnergyOutFilter *>(f.get())) &&
     221         216 :         _estimator != openmc::TallyEstimator::ANALOG)
     222           8 :       paramError("estimator",
     223           4 :                  "The filter " + f->name() +
     224             :                      " requires an analog estimator! Please ensure 'estimator' is set to analog.");
     225             : 
     226        1126 :     if (dynamic_cast<DelayedGroupFilter *>(f.get()))
     227          26 :       for (const auto & s : _tally_score)
     228          18 :         if (s != "delayed-nu-fission" && s != "decay-rate")
     229           4 :           paramError("score",
     230           2 :                      "The filter " + f->name() +
     231             :                          " can only be used with delayed_nu_fission and decay_rate scores!");
     232             :   }
     233             : 
     234        5086 :   if (isParamValid("name"))
     235        1722 :     _tally_name = getParam<std::vector<std::string>>("name");
     236             :   else
     237             :   {
     238        4212 :     for (auto score : _tally_score)
     239             :     {
     240             :       std::replace(score.begin(), score.end(), '-', '_');
     241        2243 :       _tally_name.push_back(score);
     242             :     }
     243             :   }
     244             : 
     245        2543 :   if (_has_outputs)
     246             :   {
     247             :     // names of output are appended to ends of 'name'
     248         422 :     for (const auto & o : getParam<MultiMooseEnum>("output"))
     249             :     {
     250             :       std::string name = o;
     251             : 
     252         150 :       if (o == "UNRELAXED_TALLY_STD_DEV")
     253         172 :         _output_name.push_back("std_dev");
     254          64 :       else if (o == "UNRELAXED_TALLY_REL_ERROR")
     255          48 :         _output_name.push_back("rel_error");
     256          40 :       else if (o == "UNRELAXED_TALLY")
     257          80 :         _output_name.push_back("raw");
     258             :       else
     259           0 :         mooseError("Unhandled OutputEnum in OpenMCCellAverageProblem!");
     260             :     }
     261             :   }
     262             : 
     263        2543 :   if (_tally_name.size() != _tally_score.size())
     264           2 :     paramError("name", "'name' must be the same length as 'score'!");
     265             : 
     266             :   // Modify the variable names so they take into account the bins in the external filters.
     267        2541 :   auto all_var_names = _tally_name;
     268        3665 :   for (const auto & filter : _ext_filters)
     269             :   {
     270             :     std::vector<std::string> n;
     271        3212 :     for (unsigned int i = 0; i < all_var_names.size(); ++i)
     272        5568 :       for (unsigned int j = 0; j < filter->numBins(); ++j)
     273        6960 :         n.push_back(all_var_names[i] + "_" + filter->binName(j));
     274             : 
     275        1124 :     all_var_names = n;
     276             : 
     277        1124 :     _num_ext_filter_bins *= filter->numBins();
     278        1124 :   }
     279        2541 :   _tally_name = all_var_names;
     280             : 
     281             :   // A map of external filter bins to skip when computing sums and means for normalization.
     282        2541 :   std::vector<bool> skip{false};
     283        3665 :   for (const auto & filter : _ext_filters)
     284             :   {
     285             :     std::vector<bool> s;
     286        2960 :     for (unsigned int i = 0; i < skip.size(); ++i)
     287        4916 :       for (unsigned int j = 0; j < filter->numBins(); ++j)
     288        3504 :         s.push_back(skip[i] || filter->skipBin(j));
     289             : 
     290        1124 :     skip = s;
     291             :   }
     292        2541 :   _ext_bins_to_skip = skip;
     293             : 
     294        5082 :   if (isParamSetByUser("blocks"))
     295           0 :     mooseError("This parameter is deprecated, use 'block' instead!");
     296             : 
     297        5082 :   if (isParamValid("block"))
     298             :   {
     299        4899 :     auto block_names = getParam<std::vector<SubdomainName>>("block");
     300        1633 :     if (block_names.empty())
     301           2 :       paramError("block", "Subdomain names must be provided if using 'block'!");
     302             : 
     303        1631 :     auto block_ids = _openmc_problem.getMooseMesh().getSubdomainIDs(block_names);
     304        1631 :     std::copy(
     305        1631 :         block_ids.begin(), block_ids.end(), std::inserter(_tally_blocks, _tally_blocks.end()));
     306             : 
     307             :     // Check to make sure all of the blocks are in the mesh.
     308        1631 :     const auto & subdomains = _openmc_problem.getMooseMesh().meshSubdomains();
     309        4550 :     for (std::size_t b = 0; b < block_names.size(); ++b)
     310        2921 :       if (subdomains.find(block_ids[b]) == subdomains.end())
     311           4 :         paramError("block",
     312           2 :                    "Block '" + block_names[b] + "' specified in 'block' not found in mesh!");
     313        1629 :   }
     314             :   else
     315             :   {
     316             :     // Tally over all mesh blocks if no blocks are provided.
     317        1987 :     for (const auto & s : _openmc_problem.getMooseMesh().meshSubdomains())
     318        1079 :       _tally_blocks.insert(s);
     319             :   }
     320             : 
     321        2537 :   _openmc_problem.checkDuplicateEntries(_tally_name, "name");
     322        2535 :   _openmc_problem.checkDuplicateEntries(_tally_score, "score");
     323             : 
     324        2533 :   _local_sum_tally.resize(_tally_score.size(), 0.0);
     325        2533 :   _local_mean_tally.resize(_tally_score.size(), 0.0);
     326             : 
     327        2533 :   _current_tally.resize(_tally_score.size());
     328        2533 :   _current_raw_tally.resize(_tally_score.size());
     329        2533 :   _current_raw_tally_rel_error.resize(_tally_score.size());
     330        2533 :   _current_raw_tally_std_dev.resize(_tally_score.size());
     331        2533 :   _previous_tally.resize(_tally_score.size());
     332        4707 : }
     333             : 
     334             : void
     335        2521 : TallyBase::initializeTally()
     336             : {
     337             :   // Clear cached results.
     338        2521 :   _local_sum_tally.clear();
     339        2521 :   _local_sum_tally.resize(_tally_score.size(), 0.0);
     340        2521 :   _local_mean_tally.clear();
     341        2521 :   _local_mean_tally.resize(_tally_score.size(), 0.0);
     342             : 
     343        2521 :   _current_tally.resize(_tally_score.size());
     344        2521 :   _current_raw_tally.resize(_tally_score.size());
     345        2521 :   _current_raw_tally_rel_error.resize(_tally_score.size());
     346        2521 :   _current_raw_tally_std_dev.resize(_tally_score.size());
     347        2521 :   _previous_tally.resize(_tally_score.size());
     348             : 
     349        2521 :   auto [index, spatial_filter] = spatialFilter();
     350        2511 :   _filter_index = index;
     351             : 
     352             :   std::vector<openmc::Filter *> filters;
     353        3635 :   for (auto & filter : _ext_filters)
     354        1124 :     filters.push_back(filter->getWrappedFilter());
     355             :   // We add the spatial filter last to minimize the number of cache
     356             :   // misses during the OpenMC -> Cardinal transfer.
     357        2511 :   filters.push_back(spatial_filter);
     358             : 
     359             :   // Create the tally, assign the required filters and apply the triggers.
     360        2511 :   _local_tally_index = openmc::model::tallies.size();
     361        2511 :   _local_tally = openmc::Tally::create();
     362        2511 :   _local_tally->set_scores(_tally_score);
     363        2511 :   _local_tally->estimator_ = _estimator;
     364        2511 :   _local_tally->set_filters(filters);
     365        2511 :   applyTriggersToLocalTally(_local_tally);
     366        2511 : }
     367             : 
     368             : void
     369          86 : TallyBase::resetTally()
     370             : {
     371             :   // Erase the tally.
     372          86 :   openmc::model::tallies.erase(openmc::model::tallies.begin() + _local_tally_index);
     373             : 
     374             :   // Erase the filter(s).
     375          86 :   openmc::model::tally_filters.erase(openmc::model::tally_filters.begin() + _filter_index);
     376          86 : }
     377             : 
     378             : Real
     379        3878 : TallyBase::storeResults(const std::vector<unsigned int> & var_numbers,
     380             :                         unsigned int local_score,
     381             :                         unsigned int global_score,
     382             :                         const std::string & output_type)
     383             : {
     384             :   Real total = 0.0;
     385             : 
     386        3878 :   if (output_type == "relaxed")
     387        3606 :     total += storeResultsInner(var_numbers, local_score, global_score, _current_tally);
     388         272 :   else if (output_type == "rel_error")
     389          32 :     storeResultsInner(var_numbers, local_score, global_score, _current_raw_tally_rel_error, false);
     390         240 :   else if (output_type == "std_dev")
     391         136 :     storeResultsInner(var_numbers, local_score, global_score, _current_raw_tally_std_dev);
     392         104 :   else if (output_type == "raw")
     393         104 :     storeResultsInner(var_numbers, local_score, global_score, _current_raw_tally);
     394             :   else
     395           0 :     mooseError("Unknown external output " + output_type);
     396             : 
     397        3878 :   return total;
     398             : }
     399             : 
     400             : void
     401          16 : TallyBase::addScore(const std::string & score)
     402             : {
     403          16 :   _tally_score.push_back(score);
     404             : 
     405          48 :   std::vector<std::string> score_names({score});
     406             :   std::replace(score_names.back().begin(), score_names.back().end(), '-', '_');
     407             : 
     408             :   // Modify the variable name and add extra names for the external filter bins.
     409          24 :   for (const auto & filter : _ext_filters)
     410             :   {
     411             :     std::vector<std::string> n;
     412          16 :     for (unsigned int i = 0; i < score_names.size(); ++i)
     413          24 :       for (unsigned int j = 0; j < filter->numBins(); ++j)
     414          32 :         n.push_back(score_names[i] + "_" + filter->binName(j));
     415             : 
     416           8 :     score_names = n;
     417           8 :   }
     418          16 :   std::copy(score_names.begin(), score_names.end(), std::back_inserter(_tally_name));
     419             : 
     420          16 :   _local_sum_tally.resize(_tally_score.size(), 0.0);
     421          16 :   _local_mean_tally.resize(_tally_score.size(), 0.0);
     422             : 
     423          16 :   _current_tally.resize(_tally_score.size());
     424          16 :   _current_raw_tally.resize(_tally_score.size());
     425          16 :   _current_raw_tally_rel_error.resize(_tally_score.size());
     426          16 :   _current_raw_tally_std_dev.resize(_tally_score.size());
     427          16 :   _previous_tally.resize(_tally_score.size());
     428          32 : }
     429             : 
     430             : void
     431        3214 : TallyBase::computeSumAndMean()
     432             : {
     433        6822 :   for (unsigned int score = 0; score < _tally_score.size(); ++score)
     434             :   {
     435        3608 :     _local_sum_tally[score] = 0.0;
     436             : 
     437        3608 :     const unsigned int mapped_bins = _local_tally->n_filter_bins() / _num_ext_filter_bins;
     438        8616 :     for (unsigned int ext = 0; ext < _num_ext_filter_bins; ++ext)
     439      873078 :       for (unsigned int m = 0; m < mapped_bins; ++m)
     440      868070 :         if (!_ext_bins_to_skip[ext])
     441      865278 :           _local_sum_tally[score] +=
     442     1730556 :               xt::view(_local_tally->results_,
     443      865278 :                        xt::all(),
     444             :                        score,
     445      865278 :                        static_cast<int>(openmc::TallyResult::SUM))[ext * mapped_bins + m];
     446             : 
     447        3608 :     _local_mean_tally[score] = _local_sum_tally[score] / _local_tally->n_realizations_;
     448             :   }
     449        3214 : }
     450             : 
     451             : void
     452        3606 : TallyBase::relaxAndNormalizeTally(unsigned int local_score, const Real & alpha, const Real & norm)
     453             : {
     454        3606 :   auto & current = _current_tally[local_score];
     455             :   auto & previous = _previous_tally[local_score];
     456             :   auto & current_raw = _current_raw_tally[local_score];
     457             :   auto & current_raw_rel_error = _current_raw_tally_rel_error[local_score];
     458             :   auto & current_raw_std_dev = _current_raw_tally_std_dev[local_score];
     459             : 
     460        3606 :   auto mean_tally = _openmc_problem.tallySum(_local_tally, local_score);
     461             :   /**
     462             :    * If the value over the whole domain is zero, then the values in the individual bins must be
     463             :    * zero. We need to avoid divide-by-zeros.
     464             :    */
     465        3606 :   current_raw = std::abs(norm) < ZERO_TALLY_THRESHOLD
     466       10826 :                     ? static_cast<xt::xtensor<double, 1>>(mean_tally * 0.0)
     467        7212 :                     : static_cast<xt::xtensor<double, 1>>(mean_tally / norm);
     468             : 
     469        3606 :   auto sum_sq = xt::view(_local_tally->results_,
     470        3606 :                          xt::all(),
     471             :                          local_score,
     472        3606 :                          static_cast<int>(openmc::TallyResult::SUM_SQ));
     473             :   current_raw_rel_error =
     474        3606 :       _openmc_problem.relativeError(mean_tally, sum_sq, _local_tally->n_realizations_);
     475           0 :   current_raw_std_dev = current_raw_rel_error * current_raw;
     476             : 
     477        3606 :   if (_openmc_problem.fixedPointIteration() == 0 || alpha == 1.0)
     478             :   {
     479        3262 :     current = current_raw;
     480        3262 :     previous = current_raw;
     481             :     return;
     482             :   }
     483             : 
     484             :   // Save the current tally (from the previous iteration) into the previous one.
     485             :   std::copy(current.cbegin(), current.cend(), previous.begin());
     486             : 
     487             :   // Relax the tallies by alpha. TODO: skip relaxation when alpha is one.
     488         688 :   auto relaxed_tally = (1.0 - alpha) * previous + alpha * current_raw;
     489         344 :   std::copy(relaxed_tally.cbegin(), relaxed_tally.cend(), current.begin());
     490        3950 : }
     491             : 
     492             : const openmc::Tally *
     493        3035 : TallyBase::getWrappedTally() const
     494             : {
     495        3035 :   if (!_local_tally)
     496           0 :     mooseError("This tally has not been initialized!");
     497             : 
     498        3035 :   return _local_tally;
     499             : }
     500             : 
     501             : int32_t
     502        2509 : TallyBase::getTallyID() const
     503             : {
     504        2509 :   return getWrappedTally()->id();
     505             : }
     506             : 
     507             : int
     508        1052 : TallyBase::scoreIndex(const std::string & score) const
     509             : {
     510        1052 :   if (!hasScore(score))
     511           0 :     mooseError("Internal error: tally " + name() + " does not contain the score " + score);
     512             : 
     513        1052 :   return std::find(_tally_score.begin(), _tally_score.end(), score) - _tally_score.begin();
     514             : }
     515             : 
     516             : std::vector<std::string>
     517         104 : TallyBase::getScoreVars(const std::string & score) const
     518             : {
     519             :   std::vector<std::string> score_vars;
     520         104 :   if (!hasScore(score))
     521             :     return score_vars;
     522             : 
     523             :   unsigned int idx =
     524         104 :       std::find(_tally_score.begin(), _tally_score.end(), score) - _tally_score.begin();
     525         104 :   std::copy(_tally_name.begin() + idx * _num_ext_filter_bins,
     526         104 :             _tally_name.begin() + (idx + 1) * _num_ext_filter_bins,
     527             :             std::back_inserter(score_vars));
     528             : 
     529             :   return score_vars;
     530           0 : }
     531             : 
     532             : void
     533     1419054 : TallyBase::fillElementalAuxVariable(const unsigned int & var_num,
     534             :                                     const std::vector<unsigned int> & elem_ids,
     535             :                                     const Real & value)
     536             : {
     537     1419054 :   auto & solution = _aux.solution();
     538     1419054 :   auto sys_number = _aux.number();
     539             : 
     540             :   // loop over all the elements and set the specified variable to the specified value
     541    96871310 :   for (const auto & e : elem_ids)
     542             :   {
     543    95452256 :     auto elem_ptr = _openmc_problem.getMooseMesh().queryElemPtr(e);
     544             : 
     545    95452256 :     if (!_openmc_problem.isLocalElem(elem_ptr))
     546    56382896 :       continue;
     547             : 
     548    39069360 :     auto dof_idx = elem_ptr->dof_number(sys_number, var_num, 0);
     549    39069360 :     solution.set(dof_idx, value);
     550             :   }
     551     1419054 : }
     552             : 
     553             : void
     554        2511 : TallyBase::applyTriggersToLocalTally(openmc::Tally * tally)
     555             : {
     556        2511 :   if (_tally_trigger)
     557         252 :     for (int score = 0; score < _tally_score.size(); ++score)
     558         276 :       tally->triggers_.push_back({_openmc_problem.triggerMetric((*_tally_trigger)[score]),
     559             :                                   _tally_trigger_threshold[score],
     560             :                                   _trigger_ignore_zeros[score],
     561             :                                   score});
     562        2511 : }
     563             : #endif

Generated by: LCOV version 1.14