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