Line data Source code
1 : /********************************************************************/ 2 : /* SOFTWARE COPYRIGHT NOTIFICATION */ 3 : /* Cardinal */ 4 : /* */ 5 : /* (c) 2024 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 "OpenMCDomainFilterEditor.h" 22 : #include "openmc/tallies/tally.h" 23 : #include "openmc/tallies/filter.h" 24 : #include "openmc/tallies/filter_cell.h" 25 : #include "openmc/tallies/filter_material.h" 26 : #include "openmc/tallies/filter_universe.h" 27 : #include "openmc/tallies/filter_mesh.h" 28 : 29 : registerMooseObject("CardinalApp", OpenMCDomainFilterEditor); 30 : 31 : InputParameters 32 62 : OpenMCDomainFilterEditor::validParams() 33 : { 34 62 : InputParameters params = GeneralUserObject::validParams(); 35 62 : params += OpenMCBase::validParams(); 36 124 : params.addParam<bool>("create_filter", false, "Whether to create the filter if it doesn't exist"); 37 124 : params.addRequiredParam<int32_t>("filter_id", "The ID of the filter to modify"); 38 124 : params.addRequiredParam<MooseEnum>("filter_type", getFilterTypeEnum(), "The type of filter"); 39 124 : params.addRequiredParam<std::vector<std::string>>("bins", "The bins to apply in the filter"); 40 124 : params.declareControllable("bins"); 41 62 : params.addClassDescription("A UserObject for creating and managing OpenMC domain tally filters"); 42 62 : return params; 43 0 : } 44 : 45 34 : OpenMCDomainFilterEditor::OpenMCDomainFilterEditor(const InputParameters & parameters) 46 : : GeneralUserObject(parameters), 47 : OpenMCBase(this, parameters), 48 34 : _create_filter(getParam<bool>("create_filter")), 49 68 : _filter_id(getParam<int32_t>("filter_id")), 50 102 : _filter_type(getParam<MooseEnum>("filter_type").getEnum<OpenMCFilterType>()) 51 : { 52 34 : if (_openmc_problem->runRandomRay()) 53 2 : mooseError("OpenMCDomainFilterEditor is not supported when running the random ray solver!"); 54 : 55 32 : bool filter_exists = this->filterExists(); 56 : 57 : // if create_filter is set to true, but the filter already exists, display a warning 58 32 : if (_create_filter && filter_exists) 59 4 : paramWarning("filter_id", 60 4 : "Filter " + std::to_string(_filter_id) + 61 : " already exists in the OpenMC XML model"); 62 : 63 32 : if (!_create_filter && !filter_exists) 64 2 : paramError("filter_id", 65 2 : "Filter " + std::to_string(_filter_id) + 66 : " does not exist and create_filter is false"); 67 : 68 : // if the filter doesn't exist at this point and no other errors have been raised, 69 : // create the filter 70 28 : if (!filter_exists) 71 52 : openmc::Filter::create(filterTypeEnumToString(_filter_type), _filter_id); 72 : 73 : // at this point the filter exists and the filter type is set, check that the type is valid 74 30 : checkFilterTypeMatch(); 75 28 : } 76 : 77 : void 78 30 : OpenMCDomainFilterEditor::checkFilterTypeMatch() const 79 : { 80 : // check this UO's filter type against the one in the OpenMC model 81 30 : std::string existing_type_str = openmc::model::tally_filters[filterIndex()]->type_str(); 82 30 : OpenMCFilterType existing_type = stringToFilterTypeEnum(existing_type_str); 83 : 84 30 : if (existing_type != _filter_type) 85 2 : paramError("filter_id", 86 4 : "An existing filter, Filter " + std::to_string(_filter_id) + ", is of type \"" + 87 2 : existing_type_str + "\" and cannot be changed to type \"" + 88 2 : filterTypeEnumToString(_filter_type) + "\""); 89 28 : } 90 : 91 : bool 92 32 : OpenMCDomainFilterEditor::filterExists() const 93 : { 94 32 : return openmc::model::filter_map.find(_filter_id) != openmc::model::filter_map.end(); 95 : } 96 : 97 : int32_t 98 78 : OpenMCDomainFilterEditor::filterIndex() const 99 : { 100 78 : return openmc::model::filter_map.at(_filter_id); 101 : } 102 : 103 : void 104 48 : OpenMCDomainFilterEditor::execute() 105 : { 106 48 : openmc::Filter * filter = openmc::model::tally_filters[filterIndex()].get(); 107 : 108 : // TODO: update if webcontrols starts to support integral types 109 : std::vector<int32_t> ids, bins; 110 144 : for (auto bin_id : getParam<std::vector<std::string>>("bins")) 111 : { 112 48 : ids.push_back(std::stoi(bin_id)); 113 : } 114 : 115 48 : if (_filter_type == OpenMCFilterType::cell) 116 : { 117 16 : openmc::CellFilter * cell_filter = dynamic_cast<openmc::CellFilter *>(filter); 118 16 : if (!cell_filter) 119 0 : paramError("filter_id", "Filter " + std::to_string(_filter_id) + " is not a cell filter"); 120 : 121 32 : for (auto id : ids) 122 16 : bins.push_back(openmc::model::cell_map.at(id)); 123 16 : cell_filter->set_cells(bins); 124 : } 125 32 : else if (_filter_type == OpenMCFilterType::material) 126 : { 127 16 : openmc::MaterialFilter * material_filter = dynamic_cast<openmc::MaterialFilter *>(filter); 128 16 : if (!material_filter) 129 0 : paramError("filter_id", "Filter " + std::to_string(_filter_id) + " is not a material filter"); 130 : 131 32 : for (auto id : ids) 132 16 : bins.push_back(openmc::model::material_map.at(id)); 133 16 : material_filter->set_materials(bins); 134 : } 135 16 : else if (_filter_type == OpenMCFilterType::universe) 136 : { 137 16 : openmc::UniverseFilter * universe_filter = dynamic_cast<openmc::UniverseFilter *>(filter); 138 16 : if (!universe_filter) 139 0 : paramError("filter_id", "Filter " + std::to_string(_filter_id) + " is not a universe filter"); 140 : 141 32 : for (auto id : ids) 142 16 : bins.push_back(openmc::model::universe_map.at(id)); 143 16 : universe_filter->set_universes(bins); 144 : } 145 0 : else if (_filter_type == OpenMCFilterType::mesh) 146 : { 147 0 : openmc::MeshFilter * mesh_filter = dynamic_cast<openmc::MeshFilter *>(filter); 148 0 : if (!mesh_filter) 149 0 : paramError("filter_id", "Filter " + std::to_string(_filter_id) + " is not a mesh filter"); 150 : 151 0 : if (bins.size() != 1) 152 0 : paramError("filter_id", 153 0 : "Mesh filter must have exactly one bin; instead, it has " + 154 0 : std::to_string(bins.size()) + " bins"); 155 : 156 0 : for (auto id : ids) 157 0 : bins.push_back(openmc::model::mesh_map.at(id)); 158 0 : mesh_filter->set_mesh(bins[0]); 159 : } 160 48 : } 161 : 162 : std::string 163 28 : OpenMCDomainFilterEditor::filterTypeEnumToString(OpenMCFilterType t) const 164 : { 165 : if (t == OpenMCFilterType::cell) 166 10 : return "cell"; 167 : else if (t == OpenMCFilterType::material) 168 8 : return "material"; 169 : else if (t == OpenMCFilterType::universe) 170 10 : return "universe"; 171 : else if (t == OpenMCFilterType::mesh) 172 0 : return "mesh"; 173 : else if (t == OpenMCFilterType::none) 174 0 : return "none"; 175 : else 176 0 : mooseError("Invalid filter type"); 177 : } 178 : 179 : OpenMCFilterType 180 30 : OpenMCDomainFilterEditor::stringToFilterTypeEnum(const std::string & s) const 181 : { 182 30 : if (s == "cell") 183 : return OpenMCFilterType::cell; 184 16 : else if (s == "material") 185 : return OpenMCFilterType::material; 186 8 : else if (s == "universe") 187 : return OpenMCFilterType::universe; 188 0 : else if (s == "mesh") 189 : return OpenMCFilterType::mesh; 190 : else 191 0 : mooseError("Invalid filter type"); 192 : } 193 : 194 : void 195 2 : OpenMCDomainFilterEditor::duplicateFilterError(const int32_t & id) const 196 : { 197 2 : paramError("filter_id", 198 2 : "Filter ID (" + std::to_string(id) + ") found in multiple OpenMCDomainFilterEditors"); 199 : } 200 : 201 : #endif