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
|