LCOV - code coverage report
Current view: top level - src/userobjects - OpenMCDomainFilterEditor.C (source / functions) Hit Total Coverage
Test: neams-th-coe/cardinal: 93e9c4 Lines: 74 94 78.7 %
Date: 2026-07-16 12:06:10 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          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

Generated by: LCOV version 1.14