LCOV - code coverage report
Current view: top level - src/components - HeatSourceFromTotalPower.C (source / functions) Hit Total Coverage
Test: idaholab/moose thermal_hydraulics: #30301 (3b550b) with base 2ad78d Lines: 72 73 98.6 %
Date: 2025-07-30 13:02:48 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //* This file is part of the MOOSE framework
       2             : //* https://mooseframework.inl.gov
       3             : //*
       4             : //* All rights reserved, see COPYRIGHT for full restrictions
       5             : //* https://github.com/idaholab/moose/blob/master/COPYRIGHT
       6             : //*
       7             : //* Licensed under LGPL 2.1, please see LICENSE for details
       8             : //* https://www.gnu.org/licenses/lgpl-2.1.html
       9             : 
      10             : #include "HeatSourceFromTotalPower.h"
      11             : #include "HeatStructureCylindricalBase.h"
      12             : #include "HeatStructurePlate.h"
      13             : #include "TotalPowerBase.h"
      14             : 
      15             : registerMooseObject("ThermalHydraulicsApp", HeatSourceFromTotalPower);
      16             : 
      17             : InputParameters
      18         432 : HeatSourceFromTotalPower::validParams()
      19             : {
      20         432 :   InputParameters params = HeatSourceBase::validParams();
      21         864 :   params.addRequiredParam<std::string>("power", "Component that provides total power");
      22         864 :   params.addParam<Real>(
      23         864 :       "power_fraction", 1., "Fraction of the total power that goes into the heat structure [-]");
      24         864 :   params.addParam<FunctionName>("power_shape_function", "Axial power shape [-]");
      25         864 :   params.declareControllable("power_fraction");
      26         432 :   params.addClassDescription("Heat generation from total power");
      27         432 :   return params;
      28           0 : }
      29             : 
      30         216 : HeatSourceFromTotalPower::HeatSourceFromTotalPower(const InputParameters & parameters)
      31             :   : HeatSourceBase(parameters),
      32         432 :     _power_fraction(getParam<Real>("power_fraction")),
      33         432 :     _has_psf(isParamValid("power_shape_function")),
      34         432 :     _power_shape_func(_has_psf ? getParam<FunctionName>("power_shape_function") : "")
      35             : {
      36         216 :   checkSizeGreaterThan<std::string>("regions", 0);
      37         216 : }
      38             : 
      39             : void
      40         216 : HeatSourceFromTotalPower::init()
      41             : {
      42         216 :   HeatSourceBase::init();
      43             : 
      44         432 :   if (hasComponent<TotalPowerBase>("power"))
      45             :   {
      46         214 :     const TotalPowerBase & rp = getComponent<TotalPowerBase>("power");
      47         214 :     _power_var_name = rp.getPowerVariableName();
      48             :   }
      49         216 : }
      50             : 
      51             : void
      52         216 : HeatSourceFromTotalPower::check() const
      53             : {
      54         216 :   HeatSourceBase::check();
      55             : 
      56         216 :   checkComponentOfTypeExists<TotalPowerBase>("power");
      57         216 : }
      58             : 
      59             : void
      60         208 : HeatSourceFromTotalPower::addMooseObjects()
      61             : {
      62             :   /// The heat structure component we work with
      63         208 :   const HeatStructureInterface & hs = getComponent<HeatStructureInterface>("hs");
      64         208 :   const HeatStructureBase * hs_base = dynamic_cast<const HeatStructureBase *>(&hs);
      65             : 
      66             :   Real n_units, length;
      67         208 :   if (hs_base)
      68             :   {
      69             :     n_units = hs_base->getNumberOfUnits();
      70         200 :     length = hs_base->getLength();
      71             :   }
      72             :   else // HeatStructureFromFile3D
      73             :   {
      74             :     n_units = 1.0;
      75             :     length = 1.0;
      76             :   }
      77             : 
      78             :   const HeatStructureCylindricalBase * hs_cyl =
      79         208 :       dynamic_cast<const HeatStructureCylindricalBase *>(&hs);
      80             :   const bool is_cylindrical = hs_cyl != nullptr;
      81             : 
      82         208 :   const HeatStructurePlate * hs_plate = dynamic_cast<const HeatStructurePlate *>(&hs);
      83             :   const bool is_plate = hs_plate != nullptr;
      84             : 
      85         208 :   if (!_has_psf)
      86             :   {
      87         234 :     _power_shape_func = genName(name(), "power_shape_fn");
      88         117 :     std::string class_name = "ConstantFunction";
      89         117 :     InputParameters pars = _factory.getValidParams(class_name);
      90         117 :     pars.set<Real>("value") = 1. / length;
      91         117 :     getTHMProblem().addFunction(class_name, _power_shape_func, pars);
      92         117 :   }
      93             : 
      94         208 :   const std::string power_shape_integral_name = _has_psf
      95         208 :                                                     ? genName(name(), _power_shape_func, "integral")
      96         442 :                                                     : genName(_power_shape_func, "integral");
      97             : 
      98             :   {
      99             :     const std::string class_name =
     100         242 :         is_cylindrical ? "FunctionElementIntegralRZ" : "FunctionElementIntegral";
     101         208 :     InputParameters pars = _factory.getValidParams(class_name);
     102         208 :     pars.set<std::vector<SubdomainName>>("block") = _subdomain_names;
     103         208 :     pars.set<FunctionName>("function") = _power_shape_func;
     104         208 :     if (is_cylindrical)
     105             :     {
     106         174 :       pars.set<Point>("axis_point") = hs_cyl->getPosition();
     107         174 :       pars.set<RealVectorValue>("axis_dir") = hs_cyl->getDirection();
     108             :     }
     109         624 :     pars.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL};
     110             :     // TODO: This seems to produce incorrect output files, even though this is the line
     111             :     // that should be here, becuase we don't want this PPS to be in any output. The effect
     112             :     // of this line is correct, but for some reason, MOOSE will start output scalar variables
     113             :     // even though we did not ask it to do so. Refs idaholab/thm#
     114             :     // pars.set<std::vector<OutputName>>("outputs") = getTHMProblem().getOutputsVector("none");
     115         208 :     getTHMProblem().addPostprocessor(class_name, power_shape_integral_name, pars);
     116         208 :   }
     117             : 
     118             :   {
     119             :     const std::string class_name =
     120         242 :         is_cylindrical ? "ADHeatStructureHeatSourceRZ" : "ADHeatStructureHeatSource";
     121         208 :     InputParameters pars = _factory.getValidParams(class_name);
     122         416 :     pars.set<NonlinearVariableName>("variable") = HeatConductionModel::TEMPERATURE;
     123         208 :     pars.set<std::vector<SubdomainName>>("block") = _subdomain_names;
     124         208 :     pars.set<Real>("num_units") = n_units;
     125         208 :     pars.set<Real>("power_fraction") = _power_fraction;
     126         208 :     pars.set<FunctionName>("power_shape_function") = _power_shape_func;
     127         208 :     pars.set<std::vector<VariableName>>("total_power") =
     128         416 :         std::vector<VariableName>(1, _power_var_name);
     129         208 :     if (is_cylindrical)
     130             :     {
     131         174 :       pars.set<Point>("axis_point") = hs_cyl->getPosition();
     132         174 :       pars.set<RealVectorValue>("axis_dir") = hs_cyl->getDirection();
     133             :     }
     134          34 :     else if (is_plate)
     135             :     {
     136             :       // For plate heat structure, the element integral of the power shape only
     137             :       // integrates over x and y, not z, so the depth still needs to be applied.
     138          26 :       pars.set<Real>("scale") = 1.0 / hs_plate->getDepth();
     139             :     }
     140         416 :     pars.set<PostprocessorName>("power_shape_integral_pp") = power_shape_integral_name;
     141         416 :     std::string mon = genName(name(), "heat_src");
     142         208 :     getTHMProblem().addKernel(class_name, mon, pars);
     143         416 :     connectObject(pars, mon, "power_fraction");
     144         208 :   }
     145         416 : }

Generated by: LCOV version 1.14