LCOV - code coverage report
Current view: top level - src/indicators - ElementOpticalDepthIndicator.C (source / functions) Hit Total Coverage
Test: neams-th-coe/cardinal: ddd5f2 Lines: 54 58 93.1 %
Date: 2026-06-07 19:35:24 Functions: 3 3 100.0 %
Legend: Lines: hit not hit

          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             : 
      21             : #include "ElementOpticalDepthIndicator.h"
      22             : 
      23             : #include "CardinalEnums.h"
      24             : #include "TallyBase.h"
      25             : #include "UserErrorChecking.h"
      26             : 
      27             : registerMooseObject("CardinalApp", ElementOpticalDepthIndicator);
      28             : 
      29             : InputParameters
      30          62 : ElementOpticalDepthIndicator::validParams()
      31             : {
      32          62 :   auto params = OpenMCIndicator::validParams();
      33          62 :   params.addClassDescription(
      34             :       "A class which returns the estimate of a given element's optical depth under the assumption "
      35             :       "that "
      36             :       "elements with a large optical depth experience large solution gradients.");
      37         124 :   params.addRequiredParam<MooseEnum>("rxn_rate",
      38         124 :                                      getSingleTallyScoreEnum(),
      39             :                                      "The reaction rate to use for computing the optical depth.");
      40         124 :   params.addParam<MooseEnum>(
      41             :       "h_type",
      42         186 :       MooseEnum("min max cube_root", "max"),
      43             :       "The estimate for the length of the element used to compute the optical depth. Options are "
      44             :       "the "
      45             :       "minimum vertex separation (min), the maximum vertex separation (max), and the cube root of "
      46             :       "the element volume (cube_root).");
      47         124 :   params.addParam<bool>(
      48             :       "invert",
      49         124 :       false,
      50             :       "Whether the optical depth is computed as the optical depth (false) or the inverse of the "
      51             :       "optical depth (true).");
      52         124 :   params.addParam<std::string>(
      53             :       "rxn_rate_tally",
      54             :       "The name of the tally to fetch the reaction rate variable from. Only required if "
      55             :       "your problem contains multiple tallies which accumulate the same reaction rate.");
      56         124 :   params.addParam<std::string>(
      57             :       "flux_tally",
      58             :       "The name of the tally to fetch the flux variable from. Only required if "
      59             :       "your problem contains multiple tallies which accumulate flux.");
      60             : 
      61          62 :   return params;
      62           0 : }
      63             : 
      64          28 : ElementOpticalDepthIndicator::ElementOpticalDepthIndicator(const InputParameters & parameters)
      65             :   : OpenMCIndicator(parameters),
      66          28 :     _h_type(getParam<MooseEnum>("h_type").getEnum<HType>()),
      67          84 :     _invert(getParam<bool>("invert"))
      68             : {
      69          28 :   auto score = getScore("rxn_rate");
      70             : 
      71             :   // Error check to make sure the score is a reaction rate score and to make sure one of the
      72             :   // [Tallies] has added the score and a flux score.
      73          26 :   if (!_openmc_problem->isReactionRateScore(score))
      74           2 :     paramError(
      75             :         "rxn_rate",
      76           2 :         "At present the ElementOpticalDepthIndicator only works with reaction rate scores. " +
      77           2 :             std::string(getParam<MooseEnum>("rxn_rate")) + " is not a valid reaction rate score.");
      78             : 
      79          24 :   if (!_openmc_problem->hasScore("flux"))
      80           2 :     mooseError("In order to use an ElementOpticalDepthIndicator one of your [Tallies] must add a "
      81             :                "flux score.");
      82             : 
      83          22 :   auto rxn_rate_tally_name = tallyByScore(score, "rxn_rate_tally");
      84          44 :   auto flux_tally_name = tallyByScore("flux", "flux_tally");
      85             : 
      86             :   // Check to ensure the reaction rate / flux variables are CONSTANT MONOMIALS.
      87             :   bool const_mon = true;
      88          22 :   for (const auto v :
      89          66 :        _openmc_problem->getTallyScoreVariables(score, rxn_rate_tally_name, _tid, "", true))
      90          22 :     const_mon &= v->feType() == FEType(CONSTANT, MONOMIAL);
      91          22 :   for (const auto v :
      92          66 :        _openmc_problem->getTallyScoreVariables("flux", flux_tally_name, _tid, "", true))
      93          22 :     const_mon &= v->feType() == FEType(CONSTANT, MONOMIAL);
      94             : 
      95          22 :   if (!const_mon)
      96           0 :     paramError("rxn_rate",
      97             :                "ElementOpticalDepthIndicator only supports CONSTANT MONOMIAL field variables. "
      98             :                "Please ensure your [Tallies] are adding CONSTANT MONOMIAL field variables.");
      99             : 
     100             :   // Grab the reaction rate / flux variables from the [Tallies].
     101             :   _rxn_rates =
     102          22 :       _openmc_problem->getTallyScoreVariableValues(score, rxn_rate_tally_name, _tid, "", true);
     103             :   _scalar_fluxes =
     104          44 :       _openmc_problem->getTallyScoreVariableValues("flux", flux_tally_name, _tid, "", true);
     105          22 : }
     106             : 
     107             : void
     108        5632 : ElementOpticalDepthIndicator::computeIndicator()
     109             : {
     110             :   Real rxn_rate = 0.0;
     111             :   Real scalar_flux = 0.0;
     112             : 
     113       11264 :   for (const auto & var : _rxn_rates)
     114        5632 :     rxn_rate += (*var)[0];
     115             : 
     116       11264 :   for (const auto & var : _scalar_fluxes)
     117        5632 :     scalar_flux += (*var)[0];
     118             : 
     119        5632 :   auto od = scalar_flux < libMesh::TOLERANCE ? 0.0 : rxn_rate / scalar_flux;
     120             : 
     121        5632 :   switch (_h_type)
     122             :   {
     123        1024 :     case HType::Min:
     124        1024 :       od /= _current_elem->hmin();
     125        1024 :       break;
     126        1024 :     case HType::Max:
     127        1024 :       od /= _current_elem->hmax();
     128        1024 :       break;
     129        3584 :     case HType::CubeRoot:
     130        3584 :       od /= std::cbrt(_current_elem->volume());
     131        3584 :       break;
     132           0 :     default:
     133           0 :       mooseError("Internal error: unhandled HType enum state in ElementOpticalDepthIndicator.");
     134             :       break;
     135             :   }
     136             : 
     137        5632 :   if (_invert && od > libMesh::TOLERANCE)
     138        1536 :     _field_var.setNodalValue(1.0 / od);
     139             :   else
     140        4096 :     _field_var.setNodalValue(od);
     141        5632 : }
     142             : 
     143             : #endif

Generated by: LCOV version 1.14