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 :
21 : #include "SetupMGXSAction.h"
22 :
23 : #include "AddOutputAction.h"
24 :
25 : #include "CardinalEnums.h"
26 : #include "OpenMCCellAverageProblem.h"
27 :
28 : registerMooseAction("CardinalApp", SetupMGXSAction, "add_tallies");
29 : registerMooseAction("CardinalApp", SetupMGXSAction, "add_filters");
30 : registerMooseAction("CardinalApp", SetupMGXSAction, "add_aux_variable");
31 : registerMooseAction("CardinalApp", SetupMGXSAction, "add_aux_kernel");
32 : registerMooseAction("CardinalApp", SetupMGXSAction, "modify_outputs");
33 :
34 : InputParameters
35 2941 : SetupMGXSAction::validParams()
36 : {
37 2941 : auto params = CardinalAction::validParams();
38 2941 : params.addClassDescription("A class which sets up multi-group cross section generation using "
39 : "Cardinal's mapped tallies.");
40 2941 : params += EnergyBinBase::validParams();
41 : // MGXS' are always reversed.
42 2941 : params.suppressParameter<bool>("reverse_bins");
43 2941 : params.set<bool>("reverse_bins") = true;
44 :
45 5882 : params.addRequiredParam<MooseEnum>(
46 5882 : "tally_type", getTallyTypeEnum(), "The type of spatial tally to use");
47 5882 : params.addRequiredParam<MooseEnum>("particle",
48 5882 : getSingleParticleFilterEnum(),
49 : "The particle to filter for. At present cross sections can "
50 : "only be generated for neutrons or photons, if 'electron' or "
51 : "'positron' are selected an error will be thrown.");
52 2941 : auto estimator_enum = getTallyEstimatorEnum();
53 5882 : estimator_enum.assign("tracklength");
54 5882 : params.addParam<MooseEnum>(
55 : "estimator",
56 : estimator_enum,
57 : "The type of estimator to use with the tallies added for MGXS generation. This is not "
58 : "applied to scattering / fission"
59 : " scores as the filters applied to those scores only support analog estimators.");
60 :
61 : // Options for MGXS generation. At a minimum, we generate multi-group total cross sections.
62 5882 : params.addParam<bool>(
63 : "add_scattering",
64 5882 : true,
65 : "Whether or not the scattering multi-group cross section matrix should be generated.");
66 5882 : params.addParam<unsigned int>("legendre_order",
67 5882 : 0,
68 : "The order of the Legendre expansion in scattering angle to use "
69 : "for generating scattering cross sections. Defaults to 0.");
70 5882 : params.addParam<bool>("transport_correction",
71 5882 : true,
72 : "Whether the in-group scattering cross section should include a P0 "
73 : "transport correction or not.");
74 :
75 5882 : params.addParam<bool>("add_fission",
76 5882 : false,
77 : "Whether or not fission multi-group cross sections (neutron production and "
78 : "the discrete chi spectrum) should be generated.");
79 :
80 5882 : params.addParam<bool>(
81 : "add_fission_heating",
82 5882 : false,
83 : "Whether or not per-group fission heating (kappa-fission) values should be generated.");
84 :
85 5882 : params.addParam<bool>("add_inverse_velocity",
86 5882 : false,
87 : "Whether or not per-group inverse velocities should be generated.");
88 :
89 5882 : params.addParam<bool>(
90 : "add_diffusion_coefficient",
91 5882 : false,
92 : "Whether or not per-group particle diffusion coefficients should be generated.");
93 5882 : params.addParam<Real>("void_diffusion_coefficient",
94 5882 : 1e3,
95 : "The value the diffusion coefficient should take in a void region.");
96 :
97 5882 : params.addParam<bool>(
98 : "add_absorption",
99 5882 : false,
100 : "Whether or not absorption multi-group cross sections should be generated.");
101 :
102 5882 : params.addParam<bool>("hide_tally_vars",
103 5882 : true,
104 : "Whether or not tally variables used to compute multi-group cross sections "
105 : "are hidden in exodus output.");
106 :
107 2941 : return params;
108 2941 : }
109 :
110 82 : SetupMGXSAction::SetupMGXSAction(const InputParameters & parameters)
111 : : CardinalAction(parameters),
112 : EnergyBinBase(this, parameters),
113 82 : _t_type(getParam<MooseEnum>("tally_type").getEnum<tally::TallyTypeEnum>()),
114 164 : _particle(getParam<MooseEnum>("particle")),
115 164 : _estimator(getParam<MooseEnum>("estimator")),
116 164 : _add_scattering(getParam<bool>("add_scattering")),
117 164 : _l_order(getParam<unsigned int>("legendre_order")),
118 164 : _transport_correction(getParam<bool>("transport_correction")),
119 164 : _add_fission(getParam<bool>("add_fission")),
120 164 : _add_kappa_fission(getParam<bool>("add_fission_heating")),
121 164 : _add_inv_vel(getParam<bool>("add_inverse_velocity")),
122 164 : _add_diffusion(getParam<bool>("add_diffusion_coefficient")),
123 164 : _void_diff(getParam<Real>("void_diffusion_coefficient")),
124 164 : _add_absorption(getParam<bool>("add_absorption")),
125 164 : _hide_tally_vars(getParam<bool>("hide_tally_vars")),
126 82 : _need_p1_scatter(false)
127 : {
128 82 : if (_particle == "electron" || _particle == "positron")
129 4 : paramError("particle",
130 : "Multi-group cross sections can only be generated for neutrons or photons.");
131 :
132 78 : if (_add_fission && _particle == "photon")
133 2 : paramError("add_fission",
134 : "Multi-group fission cross sections / chi spectra cannot be "
135 : "generated when selecting particle = 'photon'! Please set 'add_fission = false' to "
136 : "continue.");
137 :
138 76 : if (_add_kappa_fission && _particle == "photon")
139 2 : paramError("add_fission_heating",
140 : "Multi-group fission heating values cannot be "
141 : "generated when selecting particle = 'photon'! Please set add_fission_heating = "
142 : "false to continue.");
143 :
144 74 : if (_t_type == tally::TallyTypeEnum::mesh && _estimator == "tracklength")
145 : {
146 4 : if (isParamSetByUser("estimator"))
147 2 : mooseWarning(
148 : "You've selected an unstructured mesh tally discretization for your multi-group cross "
149 : "sections and requested a tracklength estimator. Unstructured mesh tallies don't "
150 : "support, tracklength estimators, the estimator will be set to 'collision' instead.");
151 :
152 0 : _estimator.assign("collision");
153 : }
154 :
155 72 : if (_estimator != "analog" && (_add_fission || _add_scattering || _add_diffusion))
156 : {
157 2 : mooseWarning("You've requested the generation of scattering / fission / diffusion group "
158 : "constants with a "
159 : "non-analog estimator. At present these MGXS don't support 'collision' / "
160 : "'tracklength' estimators, the estimator will be set to 'analog' instead.");
161 :
162 0 : _estimator.assign("analog");
163 : }
164 :
165 70 : if (_l_order > 0 && _transport_correction)
166 : {
167 4 : mooseWarning(
168 : "Transport-corrected scattering cross sections can only be used with isotropic scattering "
169 2 : "(l = 0). You've set l = " +
170 0 : Moose::stringify(_l_order) + ", the transport correction will not be applied.");
171 0 : _transport_correction = false;
172 : }
173 :
174 68 : if ((_transport_correction || _add_diffusion) && _l_order == 0)
175 42 : _need_p1_scatter = true;
176 68 : }
177 :
178 : void
179 340 : SetupMGXSAction::act()
180 : {
181 340 : if (_current_task == "add_filters")
182 68 : addFilters();
183 :
184 340 : if (_current_task == "add_tallies")
185 68 : addTallies();
186 :
187 340 : if (_current_task == "add_aux_variable")
188 68 : addAuxVars();
189 :
190 340 : if (_current_task == "add_aux_kernel")
191 68 : addAuxKernels();
192 :
193 340 : if (_current_task == "modify_outputs" && _hide_tally_vars)
194 68 : modifyOutputs();
195 340 : }
196 :
197 : OpenMCCellAverageProblem *
198 1840 : SetupMGXSAction::openmcProblem()
199 : {
200 1840 : auto p = dynamic_cast<OpenMCCellAverageProblem *>(_problem.get());
201 1840 : if (!p)
202 0 : mooseError("MGXS can only be used with problems of the type 'OpenMCCellAverageProblem'! Please "
203 : "ensure you've added one in the [Problem] block.");
204 1840 : return p;
205 : }
206 :
207 : void
208 68 : SetupMGXSAction::addFilters()
209 : {
210 : // Need an EnergyFilter for all cross sections.
211 : {
212 68 : auto params = _factory.getValidParams("EnergyFilter");
213 68 : params.set<std::vector<Real>>("energy_boundaries") = _energy_bnds;
214 68 : params.set<bool>("reverse_bins") = true;
215 :
216 68 : params.set<OpenMCCellAverageProblem *>("_openmc_problem") = openmcProblem();
217 136 : openmcProblem()->addFilter("EnergyFilter", "MGXS_EnergyFilter", params);
218 68 : }
219 :
220 : // Need a ParticleFilter for all cross sections.
221 : {
222 136 : auto params = _factory.getValidParams("ParticleFilter");
223 68 : params.set<MultiMooseEnum>("particles") =
224 272 : MultiMooseEnum(getParticleFilterEnums().getRawNames(), _particle, false);
225 :
226 68 : params.set<OpenMCCellAverageProblem *>("_openmc_problem") = openmcProblem();
227 136 : openmcProblem()->addFilter("ParticleFilter", "MGXS_ParticleFilter", params);
228 68 : }
229 :
230 : // Need an EnergyOutFilter for scattering / neutron production cross sections.
231 68 : if (_add_scattering || _add_fission || _add_diffusion)
232 : {
233 44 : auto params = _factory.getValidParams("EnergyOutFilter");
234 44 : params.set<std::vector<Real>>("energy_boundaries") = _energy_bnds;
235 44 : params.set<bool>("reverse_bins") = true;
236 :
237 44 : params.set<OpenMCCellAverageProblem *>("_openmc_problem") = openmcProblem();
238 88 : openmcProblem()->addFilter("EnergyOutFilter", "MGXS_EnergyOutFilter", params);
239 44 : }
240 :
241 : // Need an AngularLegendreFilter for scattering cross sections.
242 68 : if (_add_scattering || _add_diffusion)
243 : {
244 44 : auto params = _factory.getValidParams("AngularLegendreFilter");
245 44 : params.set<unsigned int>("order") = _need_p1_scatter ? 1 : _l_order;
246 :
247 44 : params.set<OpenMCCellAverageProblem *>("_openmc_problem") = openmcProblem();
248 88 : openmcProblem()->addFilter("AngularLegendreFilter", "MGXS_AngularLegendreFilter", params);
249 44 : }
250 68 : }
251 :
252 : void
253 68 : SetupMGXSAction::addTallies()
254 : {
255 : // Determine the string form of the tally type.
256 : std::string tally_type;
257 68 : switch (_t_type)
258 : {
259 : case tally::TallyTypeEnum::cell:
260 : tally_type = "CellTally";
261 : break;
262 :
263 : case tally::TallyTypeEnum::mesh:
264 : tally_type = "MeshTally";
265 : break;
266 :
267 0 : default:
268 0 : mooseError("Internal error: Unhandled enum in 'tally::TallyTypeEnum'.");
269 : break;
270 : }
271 :
272 : // Total and flux tally.
273 : {
274 68 : auto params = _factory.getValidParams(tally_type);
275 68 : params.set<MultiMooseEnum>("score") =
276 272 : MultiMooseEnum(getTallyScoreEnum().getRawNames(), "total flux", false);
277 68 : params.set<MooseEnum>("estimator") = _estimator;
278 136 : params.set<std::vector<std::string>>("name") = {std::string("mgxs_total"),
279 340 : std::string("mgxs_flux")};
280 136 : params.set<std::vector<std::string>>("filters") = {std::string("MGXS_EnergyFilter"),
281 340 : std::string("MGXS_ParticleFilter")};
282 68 : setObjectBlocks(params, _blocks);
283 :
284 68 : params.set<OpenMCCellAverageProblem *>("_openmc_problem") = openmcProblem();
285 136 : openmcProblem()->addTally(tally_type, "MGXS_" + tally_type + "_Total_Flux", params);
286 68 : _mgxs_tallies.push_back(openmcProblem()->getLocalTally().back().get());
287 68 : }
288 :
289 : // Scattering tally.
290 68 : if (_add_scattering || _add_diffusion)
291 : {
292 44 : auto params = _factory.getValidParams(tally_type);
293 44 : params.set<MultiMooseEnum>("score") =
294 176 : MultiMooseEnum(getTallyScoreEnum().getRawNames(), "nu_scatter", false);
295 88 : params.set<MooseEnum>("estimator") = "analog";
296 132 : params.set<std::vector<std::string>>("name") = {std::string("mgxs_scatter")};
297 88 : params.set<std::vector<std::string>>("filters") = {std::string("MGXS_EnergyFilter"),
298 : std::string("MGXS_EnergyOutFilter"),
299 : std::string("MGXS_AngularLegendreFilter"),
300 308 : std::string("MGXS_ParticleFilter")};
301 44 : setObjectBlocks(params, _blocks);
302 :
303 44 : params.set<OpenMCCellAverageProblem *>("_openmc_problem") = openmcProblem();
304 88 : openmcProblem()->addTally(tally_type, "MGXS_" + tally_type + "_Scatter", params);
305 44 : _mgxs_tallies.push_back(openmcProblem()->getLocalTally().back().get());
306 44 : }
307 :
308 : // Fission tally.
309 68 : if (_add_fission)
310 : {
311 28 : auto params = _factory.getValidParams(tally_type);
312 28 : params.set<MultiMooseEnum>("score") =
313 112 : MultiMooseEnum(getTallyScoreEnum().getRawNames(), "nu_fission", false);
314 56 : params.set<MooseEnum>("estimator") = "analog";
315 84 : params.set<std::vector<std::string>>("name") = {std::string("mgxs_fission")};
316 56 : params.set<std::vector<std::string>>("filters") = {std::string("MGXS_EnergyFilter"),
317 : std::string("MGXS_EnergyOutFilter"),
318 168 : std::string("MGXS_ParticleFilter")};
319 28 : setObjectBlocks(params, _blocks);
320 :
321 28 : params.set<OpenMCCellAverageProblem *>("_openmc_problem") = openmcProblem();
322 56 : openmcProblem()->addTally(tally_type, "MGXS_" + tally_type + "_Fission", params);
323 28 : _mgxs_tallies.push_back(openmcProblem()->getLocalTally().back().get());
324 28 : }
325 :
326 : // Kappa-fission tally.
327 68 : if (_add_kappa_fission)
328 : {
329 44 : auto params = _factory.getValidParams(tally_type);
330 44 : params.set<MultiMooseEnum>("score") =
331 176 : MultiMooseEnum(getTallyScoreEnum().getRawNames(), "kappa_fission", false);
332 44 : params.set<MooseEnum>("estimator") = _estimator;
333 132 : params.set<std::vector<std::string>>("name") = {std::string("mgxs_kappa_fission")};
334 88 : params.set<std::vector<std::string>>("filters") = {std::string("MGXS_EnergyFilter"),
335 220 : std::string("MGXS_ParticleFilter")};
336 44 : setObjectBlocks(params, _blocks);
337 :
338 44 : params.set<OpenMCCellAverageProblem *>("_openmc_problem") = openmcProblem();
339 88 : openmcProblem()->addTally(tally_type, "MGXS_" + tally_type + "_Kappa_Fission", params);
340 44 : _mgxs_tallies.push_back(openmcProblem()->getLocalTally().back().get());
341 44 : }
342 :
343 : // Inverse velocity tally.
344 68 : if (_add_inv_vel)
345 : {
346 34 : auto params = _factory.getValidParams(tally_type);
347 34 : params.set<MultiMooseEnum>("score") =
348 136 : MultiMooseEnum(getTallyScoreEnum().getRawNames(), "inverse_velocity", false);
349 34 : params.set<MooseEnum>("estimator") = _estimator;
350 102 : params.set<std::vector<std::string>>("name") = {std::string("mgxs_inverse_velocity")};
351 68 : params.set<std::vector<std::string>>("filters") = {std::string("MGXS_EnergyFilter"),
352 170 : std::string("MGXS_ParticleFilter")};
353 34 : setObjectBlocks(params, _blocks);
354 :
355 34 : params.set<OpenMCCellAverageProblem *>("_openmc_problem") = openmcProblem();
356 68 : openmcProblem()->addTally(tally_type, "MGXS_" + tally_type + "_Inverse_velocity", params);
357 34 : _mgxs_tallies.push_back(openmcProblem()->getLocalTally().back().get());
358 34 : }
359 :
360 : // Absorption tally.
361 68 : if (_add_absorption)
362 : {
363 34 : auto params = _factory.getValidParams(tally_type);
364 34 : params.set<MultiMooseEnum>("score") =
365 136 : MultiMooseEnum(getTallyScoreEnum().getRawNames(), "absorption", false);
366 34 : params.set<MooseEnum>("estimator") = _estimator;
367 102 : params.set<std::vector<std::string>>("name") = {std::string("mgxs_absorption")};
368 68 : params.set<std::vector<std::string>>("filters") = {std::string("MGXS_EnergyFilter"),
369 170 : std::string("MGXS_ParticleFilter")};
370 34 : setObjectBlocks(params, _blocks);
371 :
372 34 : params.set<OpenMCCellAverageProblem *>("_openmc_problem") = openmcProblem();
373 68 : openmcProblem()->addTally(tally_type, "MGXS_" + tally_type + "_Absorption", params);
374 34 : _mgxs_tallies.push_back(openmcProblem()->getLocalTally().back().get());
375 34 : }
376 824 : }
377 :
378 : void
379 68 : SetupMGXSAction::addAuxVars()
380 : {
381 : // Total MGXE variables.
382 196 : for (unsigned int g = 0; g < _energy_bnds.size() - 1; ++g)
383 : {
384 128 : const std::string name = "total_xs_g" + Moose::stringify(g + 1);
385 128 : auto params = _factory.getValidParams("MooseVariable");
386 256 : params.set<MooseEnum>("family") = "MONOMIAL";
387 256 : params.set<MooseEnum>("order") = "CONSTANT";
388 128 : setObjectBlocks(params, _blocks);
389 :
390 128 : openmcProblem()->checkDuplicateVariableName(name);
391 128 : _problem->addAuxVariable("MooseVariable", name, params);
392 128 : }
393 :
394 : // Scattering matrix MGXS variables.
395 68 : if (_add_scattering)
396 : {
397 124 : for (unsigned int g = 0; g < _energy_bnds.size() - 1; ++g)
398 : {
399 232 : for (unsigned int g_prime = 0; g_prime < _energy_bnds.size() - 1; ++g_prime)
400 : {
401 336 : for (unsigned int l = 0; l <= _l_order; ++l)
402 : {
403 552 : const std::string name = "scatter_xs_g" + Moose::stringify(g + 1) + "_gp" +
404 552 : Moose::stringify(g_prime + 1) + "_l" + Moose::stringify(l);
405 184 : auto params = _factory.getValidParams("MooseVariable");
406 368 : params.set<MooseEnum>("family") = "MONOMIAL";
407 368 : params.set<MooseEnum>("order") = "CONSTANT";
408 184 : setObjectBlocks(params, _blocks);
409 :
410 184 : openmcProblem()->checkDuplicateVariableName(name);
411 184 : _problem->addAuxVariable("MooseVariable", name, params);
412 184 : }
413 : }
414 : }
415 : }
416 :
417 : // Neutron production MGXS and discrete chi spectrum variables.
418 68 : if (_add_fission)
419 : {
420 76 : for (unsigned int g = 0; g < _energy_bnds.size() - 1; ++g)
421 : {
422 : {
423 48 : const std::string name = "nu_fission_xs_g" + Moose::stringify(g + 1);
424 48 : auto params = _factory.getValidParams("MooseVariable");
425 96 : params.set<MooseEnum>("family") = "MONOMIAL";
426 96 : params.set<MooseEnum>("order") = "CONSTANT";
427 48 : setObjectBlocks(params, _blocks);
428 :
429 48 : openmcProblem()->checkDuplicateVariableName(name);
430 48 : _problem->addAuxVariable("MooseVariable", name, params);
431 48 : }
432 : {
433 48 : const std::string name = "chi_g" + Moose::stringify(g + 1);
434 48 : auto params = _factory.getValidParams("MooseVariable");
435 96 : params.set<MooseEnum>("family") = "MONOMIAL";
436 96 : params.set<MooseEnum>("order") = "CONSTANT";
437 48 : setObjectBlocks(params, _blocks);
438 :
439 48 : openmcProblem()->checkDuplicateVariableName(name);
440 48 : _problem->addAuxVariable("MooseVariable", name, params);
441 48 : }
442 : }
443 : }
444 :
445 : // Discrete kappa-fission variables.
446 68 : if (_add_kappa_fission)
447 : {
448 124 : for (unsigned int g = 0; g < _energy_bnds.size() - 1; ++g)
449 : {
450 80 : const std::string name = "kappa_fission_g" + Moose::stringify(g + 1);
451 80 : auto params = _factory.getValidParams("MooseVariable");
452 160 : params.set<MooseEnum>("family") = "MONOMIAL";
453 160 : params.set<MooseEnum>("order") = "CONSTANT";
454 80 : setObjectBlocks(params, _blocks);
455 :
456 80 : openmcProblem()->checkDuplicateVariableName(name);
457 80 : _problem->addAuxVariable("MooseVariable", name, params);
458 80 : }
459 : }
460 :
461 : // Inverse velocity MGXS variables.
462 68 : if (_add_inv_vel)
463 : {
464 94 : for (unsigned int g = 0; g < _energy_bnds.size() - 1; ++g)
465 : {
466 60 : const std::string name = "inv_v_g" + Moose::stringify(g + 1);
467 60 : auto params = _factory.getValidParams("MooseVariable");
468 120 : params.set<MooseEnum>("family") = "MONOMIAL";
469 120 : params.set<MooseEnum>("order") = "CONSTANT";
470 60 : setObjectBlocks(params, _blocks);
471 :
472 60 : openmcProblem()->checkDuplicateVariableName(name);
473 60 : _problem->addAuxVariable("MooseVariable", name, params);
474 60 : }
475 : }
476 :
477 : // MG diffusion coefficients.
478 68 : if (_add_diffusion)
479 : {
480 46 : for (unsigned int g = 0; g < _energy_bnds.size() - 1; ++g)
481 : {
482 28 : const std::string name = "diff_g" + Moose::stringify(g + 1);
483 28 : auto params = _factory.getValidParams("MooseVariable");
484 56 : params.set<MooseEnum>("family") = "MONOMIAL";
485 56 : params.set<MooseEnum>("order") = "CONSTANT";
486 28 : setObjectBlocks(params, _blocks);
487 :
488 28 : openmcProblem()->checkDuplicateVariableName(name);
489 28 : _problem->addAuxVariable("MooseVariable", name, params);
490 28 : }
491 : }
492 :
493 : // Absorption MGXE variables.
494 68 : if (_add_absorption)
495 : {
496 94 : for (unsigned int g = 0; g < _energy_bnds.size() - 1; ++g)
497 : {
498 60 : const std::string name = "abs_xs_g" + Moose::stringify(g + 1);
499 60 : auto params = _factory.getValidParams("MooseVariable");
500 120 : params.set<MooseEnum>("family") = "MONOMIAL";
501 120 : params.set<MooseEnum>("order") = "CONSTANT";
502 60 : setObjectBlocks(params, _blocks);
503 :
504 60 : openmcProblem()->checkDuplicateVariableName(name);
505 60 : _problem->addAuxVariable("MooseVariable", name, params);
506 60 : }
507 : }
508 68 : }
509 :
510 : void
511 68 : SetupMGXSAction::addAuxKernels()
512 : {
513 : // Add auxkernels to compute the total MGXS'.
514 196 : for (unsigned int g = 0; g < _energy_bnds.size() - 1; ++g)
515 : {
516 128 : const auto n = "total_xs_g" + Moose::stringify(g + 1);
517 256 : auto params = _factory.getValidParams("ComputeMGXSAux");
518 256 : params.set<AuxVariableName>("variable") = n;
519 128 : params.set<std::vector<VariableName>>("rxn_rates")
520 384 : .emplace_back("mgxs_total_g" + Moose::stringify(g + 1) + "_" + std::string(_particle));
521 128 : params.set<std::vector<VariableName>>("normalize_by")
522 384 : .emplace_back("mgxs_flux_g" + Moose::stringify(g + 1) + "_" + std::string(_particle));
523 128 : setObjectBlocks(params, _blocks);
524 :
525 256 : _problem->addAuxKernel("ComputeMGXSAux", "comp_" + n, params);
526 128 : }
527 :
528 : // Add auxkernels to compute the elements of the MGXS scattering matrix.
529 68 : if (_add_scattering)
530 : {
531 124 : for (unsigned int g = 0; g < _energy_bnds.size() - 1; ++g)
532 : {
533 232 : for (unsigned int g_prime = 0; g_prime < _energy_bnds.size() - 1; ++g_prime)
534 : {
535 : // Handle within-group scattering cross sections separately for
536 : // transport-corrected P0 cross sections.
537 152 : if (g == g_prime && _transport_correction)
538 20 : continue;
539 :
540 296 : for (unsigned int l = 0; l <= _l_order; ++l)
541 : {
542 492 : const auto n = "scatter_xs_g" + Moose::stringify(g + 1) + "_gp" +
543 492 : Moose::stringify(g_prime + 1) + "_l" + Moose::stringify(l);
544 328 : auto params = _factory.getValidParams("ComputeMGXSAux");
545 328 : params.set<AuxVariableName>("variable") = n;
546 164 : params.set<std::vector<VariableName>>("rxn_rates")
547 656 : .emplace_back("mgxs_scatter_g" + Moose::stringify(g + 1) + "_gp" +
548 492 : Moose::stringify(g_prime + 1) + "_l" + Moose::stringify(l) + "_" +
549 164 : std::string(_particle));
550 164 : params.set<std::vector<VariableName>>("normalize_by")
551 492 : .emplace_back("mgxs_flux_g" + Moose::stringify(g + 1) + "_" + std::string(_particle));
552 164 : setObjectBlocks(params, _blocks);
553 :
554 328 : _problem->addAuxKernel("ComputeMGXSAux", "comp_" + n, params);
555 164 : }
556 : }
557 : }
558 :
559 44 : if (_transport_correction)
560 : {
561 30 : for (unsigned int g = 0; g < _energy_bnds.size() - 1; ++g)
562 : {
563 : const auto n =
564 80 : "scatter_xs_g" + Moose::stringify(g + 1) + "_gp" + Moose::stringify(g + 1) + "_l0";
565 40 : auto params = _factory.getValidParams("ComputeTCScatterMGXSAux");
566 40 : params.set<AuxVariableName>("variable") = n;
567 20 : params.set<std::vector<VariableName>>("p0_scatter_rxn_rate")
568 80 : .emplace_back("mgxs_scatter_g" + Moose::stringify(g + 1) + "_gp" +
569 40 : Moose::stringify(g + 1) + "_l0_" + std::string(_particle));
570 60 : for (unsigned int g_prime = 0; g_prime < _energy_bnds.size() - 1; ++g_prime)
571 80 : params.set<std::vector<VariableName>>("p1_scatter_rxn_rates")
572 160 : .emplace_back("mgxs_scatter_g" + Moose::stringify(g_prime + 1) + "_gp" +
573 80 : Moose::stringify(g + 1) + "_l1_" + std::string(_particle));
574 20 : params.set<std::vector<VariableName>>("scalar_flux")
575 60 : .emplace_back("mgxs_flux_g" + Moose::stringify(g + 1) + "_" + std::string(_particle));
576 20 : setObjectBlocks(params, _blocks);
577 :
578 40 : _problem->addAuxKernel("ComputeTCScatterMGXSAux", "comp_" + n, params);
579 20 : }
580 : }
581 : }
582 :
583 : // Add auxkernels to compute the fission neutron production MGXS and the discrete chi spectrum.
584 68 : if (_add_fission)
585 : {
586 76 : for (unsigned int g = 0; g < _energy_bnds.size() - 1; ++g)
587 : {
588 48 : const auto n = "nu_fission_xs_g" + Moose::stringify(g + 1);
589 96 : auto params = _factory.getValidParams("ComputeMGXSAux");
590 96 : params.set<AuxVariableName>("variable") = n;
591 136 : for (unsigned int g_prime = 0; g_prime < _energy_bnds.size() - 1; ++g_prime)
592 : {
593 176 : params.set<std::vector<VariableName>>("rxn_rates")
594 352 : .emplace_back("mgxs_fission_g" + Moose::stringify(g + 1) + "_gp" +
595 264 : Moose::stringify(g_prime + 1) + "_" + std::string(_particle));
596 : }
597 48 : params.set<std::vector<VariableName>>("normalize_by")
598 144 : .emplace_back("mgxs_flux_g" + Moose::stringify(g + 1) + "_" + std::string(_particle));
599 48 : setObjectBlocks(params, _blocks);
600 :
601 96 : _problem->addAuxKernel("ComputeMGXSAux", "comp_" + n, params);
602 48 : }
603 :
604 : std::vector<VariableName> all_fission;
605 76 : for (unsigned int g = 0; g < _energy_bnds.size() - 1; ++g)
606 136 : for (unsigned int g_prime = 0; g_prime < _energy_bnds.size() - 1; ++g_prime)
607 352 : all_fission.emplace_back("mgxs_fission_g" + Moose::stringify(g + 1) + "_gp" +
608 264 : Moose::stringify(g_prime + 1) + "_" + std::string(_particle));
609 :
610 76 : for (unsigned int g_prime = 0; g_prime < _energy_bnds.size() - 1; ++g_prime)
611 : {
612 48 : const auto n = "chi_g" + Moose::stringify(g_prime + 1);
613 96 : auto params = _factory.getValidParams("ComputeMGXSAux");
614 96 : params.set<AuxVariableName>("variable") = n;
615 136 : for (unsigned int g = 0; g < _energy_bnds.size() - 1; ++g)
616 : {
617 176 : params.set<std::vector<VariableName>>("rxn_rates")
618 352 : .emplace_back("mgxs_fission_g" + Moose::stringify(g + 1) + "_gp" +
619 176 : Moose::stringify(g_prime + 1) + "_" + std::string(_particle));
620 : }
621 48 : params.set<std::vector<VariableName>>("normalize_by") = all_fission;
622 48 : setObjectBlocks(params, _blocks);
623 :
624 96 : _problem->addAuxKernel("ComputeMGXSAux", "comp_" + n, params);
625 48 : }
626 28 : }
627 :
628 : // Add auxkernels to compute a group-wise kappa fission.
629 68 : if (_add_kappa_fission)
630 : {
631 124 : for (unsigned int g = 0; g < _energy_bnds.size() - 1; ++g)
632 : {
633 80 : const auto n = "kappa_fission_g" + Moose::stringify(g + 1);
634 160 : auto params = _factory.getValidParams("ComputeMGXSAux");
635 160 : params.set<AuxVariableName>("variable") = n;
636 80 : params.set<std::vector<VariableName>>("rxn_rates")
637 240 : .emplace_back("mgxs_kappa_fission_g" + Moose::stringify(g + 1) + "_" +
638 80 : std::string(_particle));
639 80 : params.set<std::vector<VariableName>>("normalize_by")
640 240 : .emplace_back("mgxs_flux_g" + Moose::stringify(g + 1) + "_" + std::string(_particle));
641 80 : setObjectBlocks(params, _blocks);
642 :
643 160 : _problem->addAuxKernel("ComputeMGXSAux", "comp_" + n, params);
644 80 : }
645 : }
646 :
647 : // Add auxkernels to compute a group-wise inverse velocity.
648 68 : if (_add_inv_vel)
649 : {
650 94 : for (unsigned int g = 0; g < _energy_bnds.size() - 1; ++g)
651 : {
652 60 : const auto n = "inv_v_g" + Moose::stringify(g + 1);
653 120 : auto params = _factory.getValidParams("ComputeMGXSAux");
654 120 : params.set<AuxVariableName>("variable") = n;
655 60 : params.set<std::vector<VariableName>>("rxn_rates")
656 180 : .emplace_back("mgxs_inverse_velocity_g" + Moose::stringify(g + 1) + "_" +
657 60 : std::string(_particle));
658 60 : params.set<std::vector<VariableName>>("normalize_by")
659 180 : .emplace_back("mgxs_flux_g" + Moose::stringify(g + 1) + "_" + std::string(_particle));
660 60 : setObjectBlocks(params, _blocks);
661 :
662 120 : _problem->addAuxKernel("ComputeMGXSAux", "comp_" + n, params);
663 60 : }
664 : }
665 :
666 : // Add auxkernels to compute MG diffusion coefficients.
667 68 : if (_add_diffusion)
668 : {
669 46 : for (unsigned int g = 0; g < _energy_bnds.size() - 1; ++g)
670 : {
671 28 : const std::string n = "diff_g" + Moose::stringify(g + 1);
672 56 : auto params = _factory.getValidParams("ComputeDiffusionCoeffMGAux");
673 56 : params.set<AuxVariableName>("variable") = n;
674 28 : params.set<std::vector<VariableName>>("total_rxn_rate")
675 84 : .emplace_back("mgxs_total_g" + Moose::stringify(g + 1) + "_" + std::string(_particle));
676 28 : params.set<std::vector<VariableName>>("scalar_flux")
677 84 : .emplace_back("mgxs_flux_g" + Moose::stringify(g + 1) + "_" + std::string(_particle));
678 28 : params.set<Real>("void_diffusion_coefficient") = _void_diff;
679 76 : for (unsigned int g_prime = 0; g_prime < _energy_bnds.size() - 1; ++g_prime)
680 96 : params.set<std::vector<VariableName>>("p1_scatter_rxn_rates")
681 192 : .emplace_back("mgxs_scatter_g" + Moose::stringify(g_prime + 1) + "_gp" +
682 96 : Moose::stringify(g + 1) + "_l1_" + std::string(_particle));
683 28 : setObjectBlocks(params, _blocks);
684 :
685 56 : _problem->addAuxKernel("ComputeDiffusionCoeffMGAux", "comp_" + n, params);
686 28 : }
687 : }
688 :
689 : // Add auxkernels to compute the absorption MGXS'.
690 68 : if (_add_absorption)
691 : {
692 94 : for (unsigned int g = 0; g < _energy_bnds.size() - 1; ++g)
693 : {
694 60 : const auto n = "abs_xs_g" + Moose::stringify(g + 1);
695 120 : auto params = _factory.getValidParams("ComputeMGXSAux");
696 120 : params.set<AuxVariableName>("variable") = n;
697 60 : params.set<std::vector<VariableName>>("rxn_rates")
698 180 : .emplace_back("mgxs_absorption_g" + Moose::stringify(g + 1) + "_" +
699 60 : std::string(_particle));
700 60 : params.set<std::vector<VariableName>>("normalize_by")
701 180 : .emplace_back("mgxs_flux_g" + Moose::stringify(g + 1) + "_" + std::string(_particle));
702 60 : setObjectBlocks(params, _blocks);
703 :
704 120 : _problem->addAuxKernel("ComputeMGXSAux", "comp_" + n, params);
705 60 : }
706 : }
707 68 : }
708 :
709 : void
710 68 : SetupMGXSAction::modifyOutputs()
711 : {
712 136 : const auto & output_actions = _app.actionWarehouse().getActionListByName("add_output");
713 388 : for (const auto & act : output_actions)
714 : {
715 : // Extract the Output action.
716 320 : AddOutputAction * action = dynamic_cast<AddOutputAction *>(act);
717 320 : if (!action)
718 68 : continue;
719 :
720 : // Hide the tally variables.
721 : InputParameters & output_params = action->getObjectParams();
722 252 : if (output_params.have_parameter<std::vector<VariableName>>("hide"))
723 862 : for (const auto & t : _mgxs_tallies)
724 2758 : for (const auto & v : t->getAuxVarNames())
725 4160 : output_params.set<std::vector<VariableName>>("hide").emplace_back(v);
726 : }
727 68 : }
728 :
729 : #endif
|