https://mooseframework.inl.gov
TriInterWrapperPowerIC.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 "TriInterWrapperPowerIC.h"
11 #include "Function.h"
12 #include "TriInterWrapperMesh.h"
13 
15 
18 {
20  params.addClassDescription("Computes linear power rate (W/m) that goes into interwrapper cells "
21  "in a triangular subchannel lattice");
22  params.addParam<Real>("power", 0.0, "The total heating power [W]");
23  params.addParam<std::string>("filename",
24  "file_was_not_found",
25  "name of power profile .txt file (should be a single column). It's "
26  "a Radial Power Profile. [UnitLess]");
27  params.addParam<FunctionName>("axial_heat_rate",
28  "1.0",
29  "user provided normalized function of axial heat rate [Unitless]. "
30  "The integral over pin length should equal the heated length");
31  return params;
32 }
33 
35  : TriInterWrapperBaseIC(params),
36  _power(getParam<Real>("power")),
37  _numberoflines(0),
38  _filename(getParam<std::string>("filename")),
39  _axial_heat_rate(getFunction("axial_heat_rate"))
40 {
41  auto n_assemblies = _mesh.getNumOfAssemblies();
42 
43  _power_dis.resize(n_assemblies);
44  _pin_power_correction.resize(n_assemblies);
45  _ref_power.resize(n_assemblies);
46  _ref_qprime.resize(n_assemblies);
47  _estimate_power.resize(n_assemblies);
48  for (unsigned int i = 0; i < n_assemblies; i++)
49  {
50  _power_dis[i] = 0.0;
51  _pin_power_correction[i] = 1.0;
52  }
53 
54  if (_filename.compare("file_was_not_found"))
55  {
56 
57  Real vin;
58  std::ifstream inFile;
59 
60  while (inFile >> vin)
61  _numberoflines += 1;
62 
63  inFile.open(_filename);
64  if (!inFile)
65  mooseError(name(), ": Unable to open file: ", _filename);
66 
67  if (inFile.fail() && !inFile.eof())
68  mooseError(name(), ": Non numerical input at line: ", _numberoflines);
69 
70  if (_numberoflines != n_assemblies)
71  mooseError(name(), ": Radial profile file doesn't have correct size: ", n_assemblies);
72  inFile.close();
73 
74  inFile.open(_filename);
75  int i = 0;
76  while (inFile >> vin)
77  {
78  _power_dis[i] = vin;
79  i++;
80  }
81  inFile.close();
82  }
83  Real sum = 0.0;
84 
85  for (unsigned int i = 0; i < n_assemblies; i++)
86  {
87  sum = sum + _power_dis[i];
88  }
89  // full pin (100%) power of one pin [W]
90  auto fpin_power = _power / sum;
91  // actual pin power [W]
92  for (unsigned int i = 0; i < n_assemblies; i++)
93  {
94  _ref_power[i] = _power_dis[i] * fpin_power;
95  }
96 
97  // Convert the actual pin power to a linear heat rate [W/m]
98  auto heated_length = _mesh.getHeatedLength();
99 
100  for (unsigned int i = 0; i < n_assemblies; i++)
101  {
102  _ref_qprime[i] = _ref_power[i] / heated_length;
103  }
104 }
105 
106 void
108 {
109  auto n_assemblies = _mesh.getNumOfAssemblies();
110  auto nz = _mesh.getNumOfAxialCells();
111  auto z_grid = _mesh.getZGrid();
112  auto heated_length = _mesh.getHeatedLength();
113  auto unheated_length_entry = _mesh.getHeatedLengthEntry();
114 
115  _estimate_power.resize(n_assemblies);
116 
117  for (unsigned int iz = 1; iz < nz + 1; iz++)
118  {
119  // Compute the height of this element.
120  auto dz = z_grid[iz] - z_grid[iz - 1];
121  // Compute axial location of nodes.
122  auto z2 = z_grid[iz];
123  auto z1 = z_grid[iz - 1];
124  Point p1(0, 0, z1 - unheated_length_entry);
125  Point p2(0, 0, z2 - unheated_length_entry);
126  // cycle through pins
127 
128  if (z2 > unheated_length_entry && z2 <= unheated_length_entry + heated_length)
129  {
130  for (unsigned int i_pin = 0; i_pin < n_assemblies; i_pin++)
131  {
132  // use of trapezoidal rule to calculate local power
133  _estimate_power[i_pin] +=
134  _ref_qprime[i_pin] * (_axial_heat_rate.value(_t, p1) + _axial_heat_rate.value(_t, p2)) *
135  dz / 2.0;
136  }
137  }
138  }
139  for (unsigned int i_pin = 0; i_pin < n_assemblies; i_pin++)
140  {
141  _pin_power_correction[i_pin] = _ref_power[i_pin] / _estimate_power[i_pin];
142  }
143 }
144 
145 Real
147 {
148  // Determine which subchannel this point is in.
150  auto subch_type = _mesh.getSubchannelType(i);
151  Real sum = 0.0;
152  auto heated_length = _mesh.getHeatedLength();
153  auto unheated_length_entry = _mesh.getHeatedLengthEntry();
154  Point p1(0, 0, unheated_length_entry);
155  // Point P = p - p1;
156 
157  // if we are adjacent to the heated part of the fuel Pin
158  if (p(2) >= unheated_length_entry && p(2) <= unheated_length_entry + heated_length)
159  {
160  if (subch_type == EChannelType::CENTER)
161  {
162  for (unsigned int j = 0; j < 3; j++)
163  {
164  auto rod_idx = _mesh.getPinIndex(i, j);
165  sum = sum + 1.0 / 6.0 * _ref_qprime[rod_idx] * _pin_power_correction[rod_idx] *
167  }
168  return sum;
169  }
170  else if (subch_type == EChannelType::EDGE)
171  {
172  for (unsigned int j = 0; j < 2; j++)
173  {
174  auto rod_idx = _mesh.getPinIndex(i, j);
175  sum = sum + 1.0 / 4.0 * _ref_qprime[rod_idx] * _pin_power_correction[rod_idx] *
177  }
178  return sum;
179  }
180  else if (subch_type == EChannelType::CORNER)
181  {
182  auto rod_idx = _mesh.getPinIndex(i, 0);
183  sum = 1.0 / 6.0 * _ref_qprime[rod_idx] * _pin_power_correction[rod_idx] *
185  return sum;
186  }
187  }
188  return 0.;
189 }
TriInterWrapperPowerIC(const InputParameters &params)
An abstract class for ICs for hexagonal fuel assemblies.
std::vector< Real > _ref_qprime
average linear heat rate over the whole pin in W/m
virtual const unsigned int & getNumOfAxialCells() const
Return the number of axial cells.
virtual EChannelType getSubchannelType(unsigned int index) const override
Return the type of the inter-wrapper for given inter-wrapper index.
Real value(const Point &p) override
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
virtual const Real & getHeatedLength() const
Return heated length.
virtual const Real & getHeatedLengthEntry() const
Return unheated length at entry.
registerMooseObject("SubChannelApp", TriInterWrapperPowerIC)
static InputParameters validParams()
std::vector< Real > _ref_power
actual pin power in W
virtual const unsigned int & getNumOfAssemblies() const override
Return the number of assemblies.
std::string _filename
pin power distribution file name
virtual const std::string & name() const
static InputParameters validParams()
unsigned int _numberoflines
number of lines
std::vector< Real > _pin_power_correction
its the correction that will be applied to the estimated calculation [unitless]
virtual const unsigned int & getPinIndex(const unsigned int channel_idx, const unsigned int neighbor_idx)
Return Pin index given inter_wrapper index and local neighbor index.
std::vector< Real > _estimate_power
its a vector which will hold the total estimated power of each pin [W]
TriInterWrapperMesh & _mesh
Real _power
total power of the fuel assembly
Sets the axial heat rate for each pin according to a radial power distribution and a user defined axi...
std::vector< Real > _power_dis
pin power distribution from the input file given in "_filename"
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual unsigned int getSubchannelIndexFromPoint(const Point &p) const override
Return a inter-wrapper index for a given physical point p
virtual const std::vector< Real > & getZGrid() const
Get axial location of layers.
void mooseError(Args &&... args) const
void addClassDescription(const std::string &doc_string)
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
virtual Real value(Real t, const Point &p) const
const Function & _axial_heat_rate
normalized axial power distribution
virtual void initialSetup() override