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