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 "AddTallyAction.h" 21 : 22 : #include "OpenMCCellAverageProblem.h" 23 : #include "DelimitedFileReader.h" 24 : 25 : registerMooseAction("CardinalApp", AddTallyAction, "add_tallies"); 26 : 27 : InputParameters 28 2258 : AddTallyAction::validParams() 29 : { 30 2258 : auto params = MooseObjectAction::validParams(); 31 2258 : params.addClassDescription("Adds tally(s) for use in simulations containing an " 32 : "OpenMCCellAverageProblem."); 33 : /** 34 : * These params are used to add multiple mesh tallies that use the same mesh but are 35 : * translated through the domain. 36 : */ 37 4516 : params.addParam<std::vector<Point>>( 38 : "mesh_translations", 39 : "Coordinates to which each mesh template should be " 40 : "translated, if multiple unstructured meshes " 41 : "are desired. Units must match those used to define the [Mesh]."); 42 4516 : params.addParam<std::vector<FileName>>( 43 : "mesh_translations_file", 44 : "File providing the coordinates to which each mesh " 45 : "template should be translated, if multiple " 46 : "unstructured meshes are desired. Units must match those used to define the [Mesh]"); 47 : 48 2258 : return params; 49 0 : } 50 : 51 2258 : AddTallyAction::AddTallyAction(const InputParameters & parameters) : MooseObjectAction(parameters) 52 : { 53 2258 : if (_type == "MeshTally") 54 : { 55 1218 : if (isParamValid("mesh_translations") && isParamValid("mesh_translations_file")) 56 0 : mooseError("Both 'mesh_translations' and 'mesh_translations_file' cannot be specified"); 57 : 58 393 : fillMeshTranslations(); 59 : } 60 : else 61 : { 62 7460 : if (isParamValid("mesh_translations") || isParamValid("mesh_translations_file")) 63 0 : mooseError("Mesh translations only apply to mesh-based tallies. 'mesh_translations' / " 64 : "'mesh_translations_file' cannot be specified"); 65 : } 66 2256 : } 67 : 68 : void 69 2155 : AddTallyAction::act() 70 : { 71 2155 : if (_current_task == "add_tallies") 72 : { 73 2155 : if (_type == "MeshTally") 74 : { 75 : // Add translated mesh tallies. 76 1131 : for (unsigned int i = 0; i < _mesh_translations.size(); ++i) 77 755 : addMeshTally(i, _mesh_translations[i]); 78 : 79 : // Link them together for shared normalization. 80 1120 : for (const auto & tally_1 : _linked_mesh_tallies) 81 2592 : for (const auto & tally_2 : _linked_mesh_tallies) 82 1848 : if (tally_1 != tally_2) 83 1104 : tally_1->addLinkedTally(tally_2.get()); 84 376 : _linked_mesh_tallies.clear(); 85 : } 86 : else 87 1768 : addTally(); 88 : } 89 2111 : } 90 : 91 : void 92 755 : AddTallyAction::addMeshTally(unsigned int instance, const Point & translation) 93 : { 94 755 : auto openmc_problem = dynamic_cast<OpenMCCellAverageProblem *>(_problem.get()); 95 : 96 755 : if (!openmc_problem) 97 0 : mooseError("The simulation must use an OpenMCCellAverageProblem when using the tally system!"); 98 : 99 755 : std::string obj_name = _name; 100 755 : if (_mesh_translations.size() > 1) 101 : { 102 552 : if (instance != 0) 103 736 : obj_name += "_" + Moose::stringify(instance); 104 : 105 552 : _moose_object_pars.set<unsigned int>("instance") = instance; 106 552 : _moose_object_pars.set<Point>("mesh_translation") = translation * openmc_problem->scaling(); 107 : } 108 : 109 755 : _moose_object_pars.set<OpenMCCellAverageProblem *>("_openmc_problem") = openmc_problem; 110 1499 : _linked_mesh_tallies.push_back(openmc_problem->addTally(_type, obj_name, _moose_object_pars)); 111 744 : } 112 : 113 : void 114 1768 : AddTallyAction::addTally() 115 : { 116 1768 : auto openmc_problem = dynamic_cast<OpenMCCellAverageProblem *>(_problem.get()); 117 : 118 1768 : if (!openmc_problem) 119 0 : mooseError("The simulation must use an OpenMCCellAverageProblem when using the tally system!"); 120 : 121 1768 : _moose_object_pars.set<OpenMCCellAverageProblem *>("_openmc_problem") = openmc_problem; 122 1768 : openmc_problem->addTally(_type, _name, _moose_object_pars); 123 1735 : } 124 : 125 : void 126 393 : AddTallyAction::fillMeshTranslations() 127 : { 128 786 : if (isParamValid("mesh_translations")) 129 : { 130 648 : _mesh_translations = getParam<std::vector<Point>>("mesh_translations"); 131 216 : if (_mesh_translations.empty()) 132 0 : mooseError("mesh_translations cannot be empty!"); 133 : } 134 354 : else if (isParamValid("mesh_translations_file")) 135 : { 136 : std::vector<FileName> mesh_translations_file = 137 54 : getParam<std::vector<FileName>>("mesh_translations_file"); 138 18 : if (mesh_translations_file.empty()) 139 0 : mooseError("mesh_translations_file cannot be empty!"); 140 : 141 34 : for (const auto & f : mesh_translations_file) 142 : { 143 18 : MooseUtils::DelimitedFileReader file(f, &_communicator); 144 : file.setFormatFlag(MooseUtils::DelimitedFileReader::FormatFlag::ROWS); 145 18 : file.read(); 146 : 147 18 : const std::vector<std::vector<double>> & data = file.getData(); 148 18 : readMeshTranslations(data); 149 16 : } 150 16 : } 151 : else 152 159 : _mesh_translations = {Point(0.0, 0.0, 0.0)}; 153 391 : } 154 : 155 : void 156 18 : AddTallyAction::readMeshTranslations(const std::vector<std::vector<double>> & data) 157 : { 158 66 : for (const auto & d : data) 159 : { 160 50 : if (d.size() != OpenMCCellAverageProblem::DIMENSION) 161 2 : paramError("mesh_translations_file", 162 : "All entries in 'mesh_translations_file' " 163 : "must contain exactly ", 164 : OpenMCCellAverageProblem::DIMENSION, 165 : " coordinates."); 166 : 167 : // OpenMCCellAverageProblem::DIMENSION will always be 3 168 48 : _mesh_translations.push_back(Point(d[0], d[1], d[2])); 169 : } 170 16 : } 171 : #endif