LCOV - code coverage report
Current view: top level - src/userobjects - OpenMCDomainFilterEditor.C (source / functions) Hit Total Coverage
Test: neams-th-coe/cardinal: be601f Lines: 72 88 81.8 %
Date: 2025-07-15 20:50:38 Functions: 9 9 100.0 %
Legend: Lines: hit not hit

          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

Generated by: LCOV version 1.14