LCOV - code coverage report
Current view: top level - src/postprocessors - KEigenvalue.C (source / functions) Hit Total Coverage
Test: neams-th-coe/cardinal: be601f Lines: 53 63 84.1 %
Date: 2025-07-15 20:50:38 Functions: 6 6 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 "KEigenvalue.h"
      22             : #include "openmc/eigenvalue.h"
      23             : #include "openmc/math_functions.h"
      24             : #include "openmc/constants.h"
      25             : 
      26             : registerMooseObject("CardinalApp", KEigenvalue);
      27             : 
      28             : InputParameters
      29        1549 : KEigenvalue::validParams()
      30             : {
      31        1549 :   InputParameters params = GeneralPostprocessor::validParams();
      32        1549 :   params += OpenMCBase::validParams();
      33        1549 :   params.addClassDescription("k eigenvalue computed by OpenMC");
      34        3098 :   params.addParam<MooseEnum>("value_type",
      35        3098 :                              getEigenvalueEnum(),
      36             :                              "Type of eigenvalue global tally to report");
      37        3098 :   params.addParam<MooseEnum>(
      38             :       "output",
      39        3098 :       getStatsOutputEnum(),
      40             :       "The value to output. Options are $k_{eff}$ (mean), the standard deviation "
      41             :       "of $k_{eff}$ (std_dev), or the relative error of $k_{eff}$ (rel_err).");
      42        1549 :   return params;
      43           0 : }
      44             : 
      45         507 : KEigenvalue::KEigenvalue(const InputParameters & parameters)
      46             :   : GeneralPostprocessor(parameters),
      47             :     OpenMCBase(this, parameters),
      48         507 :     _type(getParam<MooseEnum>("value_type").getEnum<eigenvalue::EigenvalueEnum>()),
      49        1521 :     _output(getParam<MooseEnum>("output").getEnum<statistics::OutputEnum>())
      50             : {
      51         507 :   if (openmc::settings::run_mode != openmc::RunMode::EIGENVALUE)
      52           4 :     mooseError("Eigenvalues are only computed when running OpenMC in eigenvalue mode!");
      53         503 : }
      54             : 
      55             : Real
      56         538 : KEigenvalue::getValue() const
      57             : {
      58         538 :   switch (_output)
      59             :   {
      60         428 :     case statistics::OutputEnum::Mean:
      61         428 :       return kMean();
      62             : 
      63          78 :     case statistics::OutputEnum::StDev:
      64          78 :       return KStandardDeviation();
      65             : 
      66          32 :     case statistics::OutputEnum::RelError:
      67          32 :       return kRelativeError();
      68             : 
      69           0 :     default:
      70           0 :       mooseError("Internal error: Unhandled statistics::OutputEnum enum in KEigenvalue.");
      71             :       break;
      72             :   }
      73             : }
      74             : 
      75             : Real
      76         564 : KEigenvalue::kMean() const
      77             : {
      78         564 :   int n = openmc::simulation::n_realizations;
      79             :   const auto & gt = openmc::simulation::global_tallies;
      80             : 
      81         564 :   switch (_type)
      82             :   {
      83             :     case eigenvalue::collision:
      84          48 :       return gt(openmc::GlobalTally::K_COLLISION, openmc::TallyResult::SUM) / n;
      85             :     case eigenvalue::absorption:
      86          40 :       return gt(openmc::GlobalTally::K_ABSORPTION, openmc::TallyResult::SUM) / n;
      87             :     case eigenvalue::tracklength:
      88          40 :       return gt(openmc::GlobalTally::K_TRACKLENGTH, openmc::TallyResult::SUM) / n;
      89         436 :     case eigenvalue::combined:
      90             :     {
      91         436 :       if (n <= 3)
      92           0 :         mooseError("Cannot compute combined k-effective estimate with fewer than 4 realizations!\n"
      93             :           "Please change the 'value_type' to either 'collision', 'tracklength', or 'absorption'.");
      94             : 
      95             :       double k_eff[2];
      96         436 :       openmc::openmc_get_keff(k_eff);
      97         436 :       return k_eff[0];
      98             :     }
      99           0 :     default:
     100           0 :       mooseError("Internal error: Unhandled EigenvalueEnum in KEigenvalue!");
     101             :   }
     102             : }
     103             : 
     104             : Real
     105         134 : KEigenvalue::KStandardDeviation() const
     106             : {
     107             :   const auto & gt = openmc::simulation::global_tallies;
     108         134 :   int n = openmc::simulation::n_realizations;
     109             : 
     110             :   double t_n1 = 1.0;
     111         134 :   if (openmc::settings::confidence_intervals)
     112             :   {
     113             :     double alpha = 1.0 - openmc::CONFIDENCE_LEVEL;
     114           0 :     t_n1 = openmc::t_percentile(1.0 - alpha / 2.0, n - 1);
     115             :   }
     116             : 
     117         134 :   switch (_type)
     118             :   {
     119             :     case eigenvalue::collision:
     120             :     {
     121          16 :       double mean = gt(openmc::GlobalTally::K_COLLISION, openmc::TallyResult::SUM) / n;
     122          16 :       double sum_sq = gt(openmc::GlobalTally::K_COLLISION, openmc::TallyResult::SUM_SQ);
     123          16 :       return t_n1 * stdev(mean, sum_sq, openmc::simulation::n_realizations);
     124             :     }
     125             :     case eigenvalue::absorption:
     126             :     {
     127          16 :       double mean = gt(openmc::GlobalTally::K_ABSORPTION, openmc::TallyResult::SUM) / n;
     128          16 :       double sum_sq = gt(openmc::GlobalTally::K_ABSORPTION, openmc::TallyResult::SUM_SQ);
     129          16 :       return t_n1 * stdev(mean, sum_sq, openmc::simulation::n_realizations);
     130             :     }
     131             :     case eigenvalue::tracklength:
     132             :     {
     133          16 :       double mean = gt(openmc::GlobalTally::K_TRACKLENGTH, openmc::TallyResult::SUM) / n;
     134          16 :       double sum_sq = gt(openmc::GlobalTally::K_TRACKLENGTH, openmc::TallyResult::SUM_SQ);
     135          16 :       return t_n1 * stdev(mean, sum_sq, openmc::simulation::n_realizations);
     136             :     }
     137          86 :     case eigenvalue::combined:
     138             :     {
     139          86 :       if (n <= 3)
     140           0 :         mooseError("Cannot compute combined k-effective standard deviation with fewer than 4 "
     141             :                    "realizations!");
     142             : 
     143             :       double k_eff[2];
     144          86 :       openmc::openmc_get_keff(k_eff);
     145          86 :       return k_eff[1];
     146             :     }
     147           0 :     default:
     148           0 :       mooseError("Internal error: Unhandled StandardDeviationEnum in KEigenvalue!");
     149             :   }
     150             : }
     151             : 
     152             : Real
     153          56 : KEigenvalue::kRelativeError() const
     154             : {
     155          56 :   const auto mean = kMean();
     156          56 :   return mean > 0.0 ? KStandardDeviation() / kMean() : 0.0;
     157             : }
     158             : 
     159             : #endif

Generated by: LCOV version 1.14