https://mooseframework.inl.gov
SCMQuadPowerAux.C
Go to the documentation of this file.
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 "SCMQuadPowerAux.h"
11 #include "Function.h"
12 #include "QuadSubChannelMesh.h"
13 #include "SCM.h"
14 
15 registerMooseObject("SubChannelApp", SCMQuadPowerAux);
16 
19 {
21  params.addClassDescription(
22  "Computes axial power rate (W/m) assigned to the fuel pins in a quadrilateral lattice "
23  "arrangement");
24  params.addRequiredParam<PostprocessorName>(
25  "power", "The postprocessor or Real to use for the total power of the subassembly [W]");
26  params.addRequiredParam<std::string>(
27  "filename", "name of radial power profile .txt file (should be a single column) [UnitLess].");
28  params.addParam<FunctionName>("axial_heat_rate",
29  "1.0",
30  "user provided normalized function of axial heat rate [Unitless]. "
31  "The integral over pin length should equal the heated length");
32  return params;
33 }
34 
36  : AuxKernel(parameters),
37  _quadMesh(SCM::getConstMesh<QuadSubChannelMesh>(_mesh)),
38  _power(getPostprocessorValue("power")),
39  _numberoflines(0),
40  _filename(getParam<std::string>("filename")),
41  _axial_heat_rate(getFunction("axial_heat_rate"))
42 {
43  if (processor_id() > 0)
44  return;
45 
46  if (!_quadMesh.pinMeshExist())
47  mooseError(name(), ": This object requires a pin mesh.");
48 
49  auto n_pins = _quadMesh.getNumOfPins();
50  // Matrix sizing
51  _power_dis.resize(n_pins, 1);
52  _power_dis.setZero();
53  _pin_power_correction.resize(n_pins, 1);
54  _pin_power_correction.setOnes();
55 
56  Real vin;
57  std::ifstream inFile;
58 
59  inFile.open(_filename);
60  if (!inFile)
61  mooseError(name(), "unable to open file : ", _filename);
62 
63  while (inFile >> vin)
64  _numberoflines += 1;
65 
66  if (inFile.fail() && !inFile.eof())
67  mooseError(name(), " non numerical input at line : ", _numberoflines);
68 
69  if (_numberoflines != n_pins)
70  mooseError(name(), " Radial profile file doesn't have correct size : ", n_pins);
71  inFile.close();
72 
73  inFile.open(_filename);
74  int i(0);
75  while (inFile >> vin)
76  {
77  _power_dis(i, 0) = vin;
78  i++;
79  }
80  inFile.close();
81  _console << " Power distribution matrix :\n" << _power_dis << " \n";
82 }
83 
84 void
86 {
87  if (processor_id() > 0)
88  return;
89 
90  auto n_pins = _quadMesh.getNumOfPins();
91  auto nz = _quadMesh.getNumOfAxialCells();
92  auto z_grid = _quadMesh.getZGrid();
93  auto heated_length = _quadMesh.getHeatedLength();
94  auto unheated_length_entry = _quadMesh.getHeatedLengthEntry();
95  auto sum = _power_dis.sum();
96 
97  // full (100%) power of one pin [W]
98  auto fpin_power = _power / sum;
99  // actual pin power [W]
100  _ref_power = _power_dis * fpin_power;
101  // Convert the actual pin power to a linear heat rate [W/m]
102  _ref_qprime = _ref_power / heated_length;
103 
104  _estimate_power.resize(n_pins, 1);
105  _estimate_power.setZero();
106  for (unsigned int iz = 1; iz < nz + 1; iz++)
107  {
108  // Compute axial location of nodes.
109  auto z2 = z_grid[iz];
110  auto z1 = z_grid[iz - 1];
111  Point p1(0, 0, z1 - unheated_length_entry);
112  Point p2(0, 0, z2 - unheated_length_entry);
113  auto heat1 = _axial_heat_rate.value(_t, p1);
114  auto heat2 = _axial_heat_rate.value(_t, p2);
115  if (MooseUtils::absoluteFuzzyGreaterThan(z2, unheated_length_entry) &&
116  MooseUtils::absoluteFuzzyLessThan(z1, unheated_length_entry + heated_length))
117  {
118  // cycle through pins
119  for (unsigned int i_pin = 0; i_pin < n_pins; i_pin++)
120  {
121  // Compute the height of this element.
122  auto dz = z2 - z1;
123 
124  // calculation of power for the first heated segment if nodes don't align
125  if (MooseUtils::absoluteFuzzyGreaterThan(z2, unheated_length_entry) &&
126  MooseUtils::absoluteFuzzyLessThan(z1, unheated_length_entry))
127  {
128  heat1 = 0.0;
129  }
130 
131  // calculation of power for the last heated segment if nodes don't align
132  if (MooseUtils::absoluteFuzzyGreaterThan(z2, unheated_length_entry + heated_length) &&
133  MooseUtils::absoluteFuzzyLessThan(z1, unheated_length_entry + heated_length))
134  {
135  heat2 = 0.0;
136  }
137 
138  _estimate_power(i_pin) += _ref_qprime(i_pin) * (heat1 + heat2) * dz / 2.0;
139  }
140  }
141  }
142 
143  // if a Pin has zero power (_ref_qprime(i_pin) = 0) then I need to avoid dividing by zero. I
144  // divide by a wrong non-zero number which is not correct but this error doesn't mess things
145  // cause _ref_qprime(i_pin) = 0.0
146  auto total_power = 0.0;
147  for (unsigned int i_pin = 0; i_pin < n_pins; i_pin++)
148  {
149  total_power += _estimate_power(i_pin);
150  if (_estimate_power(i_pin) == 0.0)
151  _estimate_power(i_pin) = 1.0;
152  }
153  // We need to correct the linear power assigned to the nodes of each pin
154  // so that the total power calculated by the trapezoidal rule agrees with the power assigned
155  // by the user.
157  _console << "###########################################" << std::endl;
158  _console << "Total power estimation by Aux kernel before correction: " << total_power << " [W] "
159  << std::endl;
160  _console << "Aux Power correction vector :\n" << _pin_power_correction << " \n";
161 }
162 
163 Real
165 {
166  Point p = *_current_node;
167  auto heated_length = _quadMesh.getHeatedLength();
168  auto unheated_length_entry = _quadMesh.getHeatedLengthEntry();
169  Point p1(0, 0, unheated_length_entry);
170  Point P = p - p1;
171 
173  if (MooseUtils::absoluteFuzzyGreaterEqual(p(2), unheated_length_entry) &&
174  MooseUtils::absoluteFuzzyLessEqual(p(2), unheated_length_entry + heated_length))
175  {
176  auto i_pin = _quadMesh.getPinIndexFromPoint(p);
177  return _ref_qprime(i_pin) * _pin_power_correction(i_pin) * _axial_heat_rate.value(_t, P);
178  }
179  else
180  return 0.0;
181 }
Eigen::MatrixXd _pin_power_correction
The correction that will be applied to the estimated calculation [unitless].
const QuadSubChannelMesh & _quadMesh
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
virtual const std::vector< Real > & getZGrid() const
Get axial location of layers.
Eigen::MatrixXd _estimate_power
Matrix which will hold the total estimated power of each pin [W].
const Node *const & _current_node
static InputParameters validParams()
Creates the mesh of subchannels in a quadrilateral lattice.
Eigen::MatrixXd _ref_power
Actual pin power [W].
Eigen::MatrixXd _ref_qprime
Average linear heat rate over the whole pin [W/m].
void addRequiredParam(const std::string &name, const std::string &doc_string)
const std::string & name() const
unsigned int _numberoflines
The number of lines associated with the radial power profile .txt file.
Sets the axial heat rate for each pin according to a radial power distribution and a user defined axi...
virtual const Real & getHeatedLength() const
Return heated length.
const T & getConstMesh(const MooseMesh &mesh)
function to cast const mesh
Definition: SCM.h:21
Eigen::MatrixXd _power_dis
Matrix that holds the relative pin power.
const PostprocessorValue & _power
The total power of the assembly.
bool pinMeshExist() const
Return if Pin Mesh exists or not.
virtual void initialSetup() override
virtual Real computeValue() override
virtual unsigned int getNumOfAxialCells() const
Return the number of axial cells.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
const Real p
std::string _filename
The name of the radial power profile file.
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
unsigned int getPinIndexFromPoint(const Point &p) const override
Return a pin index for a given physical point p
static InputParameters validParams()
const ConsoleStream _console
virtual Real value(Real t, const Point &p) const
processor_id_type processor_id() const
unsigned int getNumOfPins() const override
Return the number of pins.
const Function & _axial_heat_rate
Definition: SCM.h:16
virtual const Real & getHeatedLengthEntry() const
Return unheated length at entry.
registerMooseObject("SubChannelApp", SCMQuadPowerAux)
SCMQuadPowerAux(const InputParameters &params)