LCOV - code coverage report
Current view: top level - src/components - HeatSourceFromTotalPower.C (source / functions) Hit Total Coverage
Test: idaholab/moose thermal_hydraulics: #31706 (f8ed4a) with base bb0a08 Lines: 72 73 98.6 %
Date: 2025-11-03 17:29:56 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             :   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         624 :     pars.set<std::vector<OutputName>>("outputs") = {"none"};
     111         208 :     getTHMProblem().addPostprocessor(class_name, power_shape_integral_name, pars);
     112         208 :   }
     113             : 
     114             :   {
     115             :     const std::string class_name =
     116         242 :         is_cylindrical ? "ADHeatStructureHeatSourceRZ" : "ADHeatStructureHeatSource";
     117         208 :     InputParameters pars = _factory.getValidParams(class_name);
     118         416 :     pars.set<NonlinearVariableName>("variable") = HeatConductionModel::TEMPERATURE;
     119         208 :     pars.set<std::vector<SubdomainName>>("block") = _subdomain_names;
     120         208 :     pars.set<Real>("num_units") = n_units;
     121         208 :     pars.set<Real>("power_fraction") = _power_fraction;
     122         208 :     pars.set<FunctionName>("power_shape_function") = _power_shape_func;
     123         208 :     pars.set<std::vector<VariableName>>("total_power") =
     124         416 :         std::vector<VariableName>(1, _power_var_name);
     125         208 :     if (is_cylindrical)
     126             :     {
     127         174 :       pars.set<Point>("axis_point") = hs_cyl->getPosition();
     128         174 :       pars.set<RealVectorValue>("axis_dir") = hs_cyl->getDirection();
     129             :     }
     130          34 :     else if (is_plate)
     131             :     {
     132             :       // For plate heat structure, the element integral of the power shape only
     133             :       // integrates over x and y, not z, so the depth still needs to be applied.
     134          26 :       pars.set<Real>("scale") = 1.0 / hs_plate->getDepth();
     135             :     }
     136         416 :     pars.set<PostprocessorName>("power_shape_integral_pp") = power_shape_integral_name;
     137         416 :     std::string mon = genName(name(), "heat_src");
     138         208 :     getTHMProblem().addKernel(class_name, mon, pars);
     139         416 :     connectObject(pars, mon, "power_fraction");
     140         208 :   }
     141         416 : }

Generated by: LCOV version 1.14