www.mooseframework.org
GrayLambertSurfaceRadiationBase.C
Go to the documentation of this file.
1 //* This file is part of the MOOSE framework
2 //* https://www.mooseframework.org
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 
11 #include "MathUtils.h"
12 #include "Function.h"
13 #include "libmesh/quadrature.h"
14 
15 #include <cmath>
16 
18 
19 InputParameters
21 {
22  InputParameters params = SideUserObject::validParams();
23  params.addParam<Real>(
24  "stefan_boltzmann_constant",
25  5.670367e-8,
26  "The Stefan-Boltzmann constant. Default value is in units of [W / m^2 K^4].");
27  params.addRequiredCoupledVar("temperature", "The coupled temperature variable.");
28  params.addRequiredParam<std::vector<Real>>("emissivity", "Emissivities for each boundary.");
29  params.addParam<std::vector<BoundaryName>>(
30  "fixed_temperature_boundary",
31  "The list of boundary IDs from the mesh with fixed temperatures.");
32  params.addParam<std::vector<FunctionName>>("fixed_boundary_temperatures",
33  "The temperatures of the fixed boundary.");
34  params.addParam<std::vector<BoundaryName>>(
35  "adiabatic_boundary", "The list of boundary IDs from the mesh that are adiabatic.");
36 
37  params.addClassDescription(
38  "This object implements the exchange of heat by radiation between sidesets.");
39  return params;
40 }
41 
43  : SideUserObject(parameters),
44  _sigma_stefan_boltzmann(getParam<Real>("stefan_boltzmann_constant")),
45  _n_sides(boundaryIDs().size()),
46  _temperature(coupledValue("temperature")),
47  _emissivity(getParam<std::vector<Real>>("emissivity")),
48  _radiosity(_n_sides),
49  _heat_flux_density(_n_sides),
50  _side_temperature(_n_sides),
51  _side_type(_n_sides),
52  _areas(_n_sides),
53  _beta(_n_sides),
54  _surface_irradiation(_n_sides)
55 {
56  // set up the map from the side id to the local index & check
57  // note that boundaryIDs is not in the right order anymore!
58  {
59  std::vector<BoundaryName> boundary_names = getParam<std::vector<BoundaryName>>("boundary");
60 
61  for (unsigned int j = 0; j < boundary_names.size(); ++j)
62  {
63  if (boundary_names[j] == "ANY_BOUNDARY_ID")
64  paramError("boundary", "boundary must be explicitly provided.");
65 
66  _side_id_index[_mesh.getBoundaryID(boundary_names[j])] = j;
68  }
69 
70  // consistency check on emissivity, must be as many entries as boundary
71  if (boundary_names.size() != _emissivity.size())
72  paramError("emissivity", "The number of entries must match the number of boundary entries.");
73  }
74 
75  // get the fixed boundaries of the system if any are provided
76  if (isParamValid("fixed_temperature_boundary"))
77  {
78  // if fixed_temperature_boundary is valid, then fixed_side_temperatures must be
79  // valid, too
80  if (!isParamValid("fixed_boundary_temperatures"))
81  paramError("fixed_boundary_temperatures",
82  "fixed_temperature_boundary is provided, but fixed_boundary_temperatures is not.");
83 
84  auto fst_fn = getParam<std::vector<FunctionName>>("fixed_boundary_temperatures");
85  for (auto & fn : fst_fn)
86  _fixed_side_temperature.push_back(&getFunctionByName(fn));
87 
88  // get the fixed boundaries and temperatures
89  std::vector<BoundaryName> boundary_names =
90  getParam<std::vector<BoundaryName>>("fixed_temperature_boundary");
91 
92  if (boundary_names.size() != _fixed_side_temperature.size())
93  paramError(
94  "fixed_boundary_temperatures",
95  "fixed_boundary_temperatures and fixed_temperature_boundary must have the same length.");
96 
97  unsigned int index = 0;
98  for (auto & name : boundary_names)
99  {
100  _fixed_side_id_index[_mesh.getBoundaryID(name)] = index;
101  index++;
102  }
103 
104  // check that fixed side ids is a subset of boundary ids
105  // and update _side_type info
106  for (auto & p : _fixed_side_id_index)
107  {
108  if (_side_id_index.find(p.first) == _side_id_index.end())
109  paramError("fixed_temperature_boundary",
110  "fixed_temperature_boundary must be a subset of boundary.");
111  _side_type[_side_id_index.find(p.first)->second] = FIXED_TEMPERATURE;
112  }
113  }
114 
115  // get the fixed boundaries of the system if any are provided
116  if (isParamValid("adiabatic_boundary"))
117  {
118  // get the adiabatic boundaries and temperatures
119  std::vector<BoundaryName> boundary_names =
120  getParam<std::vector<BoundaryName>>("adiabatic_boundary");
121 
122  for (auto & name : boundary_names)
123  _adiabatic_side_ids.insert(_mesh.getBoundaryID(name));
124 
125  // check that adiabatic side ids is a subset of boundary ids
126  // and update _side_type info
127  for (auto & id : _adiabatic_side_ids)
128  {
129  if (_side_id_index.find(id) == _side_id_index.end())
130  paramError("adiabatic_boundary", "adiabatic_boundary must be a subset of boundary.");
131  _side_type[_side_id_index.find(id)->second] = ADIABATIC;
132  }
133 
134  // make sure that adiabatic boundaries are not already fixed boundaries
135  for (auto & id : _adiabatic_side_ids)
136  if (_fixed_side_id_index.find(id) != _fixed_side_id_index.end())
137  paramError("adiabatic_boundary", "Isothermal boundary cannot also be adiabatic boundary.");
138  }
139 }
140 
141 void
143 {
144  mooseAssert(_side_id_index.find(_current_boundary_id) != _side_id_index.end(),
145  "Current boundary id not in _side_id_index.");
146  unsigned int index = _side_id_index.find(_current_boundary_id)->second;
147 
148  for (unsigned int qp = 0; qp < _qrule->n_points(); qp++)
149  {
150  _areas[index] += _JxW[qp] * _coord[qp];
151 
152  Real temp = 0;
153  if (_side_type[index] == ADIABATIC)
154  continue;
155  else if (_side_type[index] == VARIABLE_TEMPERATURE)
156  temp = _temperature[qp];
157  else if (_side_type[index] == FIXED_TEMPERATURE)
158  {
159  unsigned int iso_index = _fixed_side_id_index.find(_current_boundary_id)->second;
160  temp = _fixed_side_temperature[iso_index]->value(_t, _q_point[qp]);
161  }
162 
163  _beta[index] += _JxW[qp] * _coord[qp] * _sigma_stefan_boltzmann * _emissivity[index] *
164  MathUtils::pow(temp, 4);
165  _side_temperature[index] += _JxW[qp] * _coord[qp] * temp;
166  }
167 }
168 
169 void
171 {
172  // view factors are obtained here to make sure that another object had
173  // time to compute them on exec initial
175 
176  // initialize areas, beta, side temps
177  for (unsigned int j = 0; j < _n_sides; ++j)
178  {
179  _areas[j] = 0;
180  _beta[j] = 0;
181  _side_temperature[j] = 0;
182  }
183 }
184 
185 void
187 {
188  // need to do some parallel communiction here
189  gatherSum(_areas);
190  gatherSum(_beta);
191  gatherSum(_side_temperature);
192 
193  // first compute averages from the totals
194  for (unsigned int j = 0; j < _n_sides; ++j)
195  {
196  _beta[j] /= _areas[j];
197  _side_temperature[j] /= _areas[j];
198  }
199 
200  // matrix and rhs vector for the view factor calculation
201  DenseMatrix<Real> matrix(_n_sides, _n_sides);
202  DenseVector<Real> rhs(_n_sides);
203  DenseVector<Real> radiosity(_n_sides);
204  for (unsigned int i = 0; i < _n_sides; ++i)
205  {
206  rhs(i) = _beta[i];
207  matrix(i, i) = 1;
208  for (unsigned int j = 0; j < _n_sides; ++j)
209  {
210  if (_side_type[i] == ADIABATIC)
211  matrix(i, j) -= _view_factors[i][j];
212  else
213  matrix(i, j) -= (1 - _emissivity[i]) * _view_factors[i][j];
214  }
215  }
216 
217  // compute the radiosityes
218  matrix.lu_solve(rhs, radiosity);
219 
220  // store the radiosity, temperatures and heat flux density for each surface
221  for (unsigned int i = 0; i < _n_sides; ++i)
222  {
223  _radiosity[i] = radiosity(i);
224 
225  // _heat_flux_density is obtained from a somewhat cumbersome relation
226  // but it has the advantage that we do not divide by 1 - emissivity
227  // which blows up for black bodies
228  _heat_flux_density[i] = radiosity(i);
229  for (unsigned int j = 0; j < _n_sides; ++j)
230  _heat_flux_density[i] -= _view_factors[i][j] * radiosity(j);
231 
232  if (_side_type[i] == ADIABATIC)
233  _side_temperature[i] =
234  std::pow((radiosity(i) + (1 - _emissivity[i]) / _emissivity[i] * _heat_flux_density[i]) /
236  0.25);
237 
238  // compute the surface irradiation into i from the radiosities
239  _surface_irradiation[i] = 0;
240  for (unsigned int j = 0; j < _n_sides; ++j)
241  _surface_irradiation[i] += _view_factors[i][j] * radiosity(j);
242  }
243 }
244 
245 void
247 {
248  const GrayLambertSurfaceRadiationBase & pps =
249  static_cast<const GrayLambertSurfaceRadiationBase &>(y);
250 
251  for (unsigned int j = 0; j < _n_sides; ++j)
252  {
253  _areas[j] += pps._areas[j];
255  _beta[j] += pps._beta[j];
256  }
257 }
258 
259 std::set<BoundaryID>
261 {
262  std::set<BoundaryID> surface_ids;
263  for (auto & p : _side_id_index)
264  surface_ids.insert(p.first);
265  return surface_ids;
266 }
267 
268 Real
270 {
271  if (_side_id_index.find(id) == _side_id_index.end())
272  return 0;
273  return _surface_irradiation[_side_id_index.find(id)->second];
274 }
275 
276 Real
278 {
279  if (_side_id_index.find(id) == _side_id_index.end())
280  return 0;
281  return _heat_flux_density[_side_id_index.find(id)->second];
282 }
283 
284 Real
286 {
287  if (_side_id_index.find(id) == _side_id_index.end())
288  return 0;
289  return _side_temperature[_side_id_index.find(id)->second];
290 }
291 
292 Real
294 {
295  if (_side_id_index.find(id) == _side_id_index.end())
296  return 0;
297  return _radiosity[_side_id_index.find(id)->second];
298 }
299 
300 Real
302 {
303  if (_side_id_index.find(id) == _side_id_index.end())
304  return 1;
305  return _emissivity[_side_id_index.find(id)->second];
306 }
307 
308 Real
309 GrayLambertSurfaceRadiationBase::getViewFactor(BoundaryID from_id, BoundaryID to_id) const
310 {
311  if (_side_id_index.find(from_id) == _side_id_index.end())
312  return 0;
313  if (_side_id_index.find(to_id) == _side_id_index.end())
314  return 0;
315  return _view_factors[_side_id_index.find(from_id)->second][_side_id_index.find(to_id)->second];
316 }
GrayLambertSurfaceRadiationBase.h
GrayLambertSurfaceRadiationBase::_surface_irradiation
std::vector< Real > _surface_irradiation
the irradiation into each surface
Definition: GrayLambertSurfaceRadiationBase.h:97
pow
ExpressionBuilder::EBTerm pow(const ExpressionBuilder::EBTerm &left, T exponent)
Definition: ExpressionBuilder.h:673
GrayLambertSurfaceRadiationBase::threadJoin
virtual void threadJoin(const UserObject &y) override
Definition: GrayLambertSurfaceRadiationBase.C:246
GrayLambertSurfaceRadiationBase::FIXED_TEMPERATURE
Definition: GrayLambertSurfaceRadiationBase.h:40
GrayLambertSurfaceRadiationBase::ADIABATIC
Definition: GrayLambertSurfaceRadiationBase.h:41
GrayLambertSurfaceRadiationBase::_fixed_side_temperature
std::vector< const Function * > _fixed_side_temperature
side id to index map, side ids can have holes or be out of order
Definition: GrayLambertSurfaceRadiationBase.h:73
GrayLambertSurfaceRadiationBase::getSurfaceIrradiation
Real getSurfaceIrradiation(BoundaryID id) const
public interface of this UserObject
Definition: GrayLambertSurfaceRadiationBase.C:269
GrayLambertSurfaceRadiationBase::finalize
virtual void finalize() override
Definition: GrayLambertSurfaceRadiationBase.C:186
GrayLambertSurfaceRadiationBase::getSurfaceEmissivity
Real getSurfaceEmissivity(BoundaryID id) const
Definition: GrayLambertSurfaceRadiationBase.C:301
GrayLambertSurfaceRadiationBase::_sigma_stefan_boltzmann
const Real _sigma_stefan_boltzmann
Stefan-Boltzmann constant.
Definition: GrayLambertSurfaceRadiationBase.h:61
GrayLambertSurfaceRadiationBase::_temperature
const VariableValue & _temperature
the coupled temperature variable
Definition: GrayLambertSurfaceRadiationBase.h:67
GrayLambertSurfaceRadiationBase::GrayLambertSurfaceRadiationBase
GrayLambertSurfaceRadiationBase(const InputParameters &parameters)
Definition: GrayLambertSurfaceRadiationBase.C:42
GrayLambertSurfaceRadiationBase::_fixed_side_id_index
std::map< unsigned int, unsigned int > _fixed_side_id_index
side id to index map for isothermal boundaries, side ids can have holes or be out of order
Definition: GrayLambertSurfaceRadiationBase.h:100
validParams
InputParameters validParams()
name
const std::string name
Definition: Setup.h:21
GrayLambertSurfaceRadiationBase::_radiosity
std::vector< Real > _radiosity
the radiosity of each surface
Definition: GrayLambertSurfaceRadiationBase.h:76
GrayLambertSurfaceRadiationBase::validParams
static InputParameters validParams()
Definition: GrayLambertSurfaceRadiationBase.C:20
GrayLambertSurfaceRadiationBase::execute
virtual void execute() override
Definition: GrayLambertSurfaceRadiationBase.C:142
GrayLambertSurfaceRadiationBase::getSurfaceRadiosity
Real getSurfaceRadiosity(BoundaryID id) const
Definition: GrayLambertSurfaceRadiationBase.C:293
GrayLambertSurfaceRadiationBase::initialize
virtual void initialize() override
Definition: GrayLambertSurfaceRadiationBase.C:170
defineLegacyParams
defineLegacyParams(GrayLambertSurfaceRadiationBase)
GrayLambertSurfaceRadiationBase::_heat_flux_density
std::vector< Real > _heat_flux_density
the heat flux density qdot
Definition: GrayLambertSurfaceRadiationBase.h:79
GrayLambertSurfaceRadiationBase::_beta
std::vector< Real > _beta
the average value of sigma * eps * T^4
Definition: GrayLambertSurfaceRadiationBase.h:94
GrayLambertSurfaceRadiationBase::_emissivity
const std::vector< Real > _emissivity
constant emissivity for each boundary
Definition: GrayLambertSurfaceRadiationBase.h:70
GrayLambertSurfaceRadiationBase::_adiabatic_side_ids
std::set< unsigned int > _adiabatic_side_ids
the set of adiabatic boundaries
Definition: GrayLambertSurfaceRadiationBase.h:103
GrayLambertSurfaceRadiationBase::VARIABLE_TEMPERATURE
Definition: GrayLambertSurfaceRadiationBase.h:39
GrayLambertSurfaceRadiationBase::_view_factors
std::vector< std::vector< Real > > _view_factors
the view factors which are set by setViewFactors by derived classes
Definition: GrayLambertSurfaceRadiationBase.h:106
GrayLambertSurfaceRadiationBase::getSurfaceIDs
std::set< BoundaryID > getSurfaceIDs() const
Definition: GrayLambertSurfaceRadiationBase.C:260
GrayLambertSurfaceRadiationBase::_side_temperature
std::vector< Real > _side_temperature
the average temperature: this could be important for adiabatic walls
Definition: GrayLambertSurfaceRadiationBase.h:82
GrayLambertSurfaceRadiationBase::getSurfaceHeatFluxDensity
Real getSurfaceHeatFluxDensity(BoundaryID id) const
Definition: GrayLambertSurfaceRadiationBase.C:277
GrayLambertSurfaceRadiationBase::_n_sides
unsigned int _n_sides
number of active boundary ids
Definition: GrayLambertSurfaceRadiationBase.h:64
GrayLambertSurfaceRadiationBase::getSurfaceTemperature
Real getSurfaceTemperature(BoundaryID id) const
Definition: GrayLambertSurfaceRadiationBase.C:285
GrayLambertSurfaceRadiationBase
GrayLambertSurfaceRadiationBase computes the heat flux on a set of surfaces in radiative heat transfe...
Definition: GrayLambertSurfaceRadiationBase.h:25
GrayLambertSurfaceRadiationBase::_side_type
std::vector< enum RAD_BND_TYPE > _side_type
the type of the side, allows lookup index -> type
Definition: GrayLambertSurfaceRadiationBase.h:85
GrayLambertSurfaceRadiationBase::getViewFactor
Real getViewFactor(BoundaryID from_id, BoundaryID to_id) const
Definition: GrayLambertSurfaceRadiationBase.C:309
GrayLambertSurfaceRadiationBase::_side_id_index
std::map< BoundaryID, unsigned int > _side_id_index
side id to index map, side ids can have holes or be out of order
Definition: GrayLambertSurfaceRadiationBase.h:88
GrayLambertSurfaceRadiationBase::setViewFactors
virtual std::vector< std::vector< Real > > setViewFactors()=0
a purely virtual function that defines where view factors come from
GrayLambertSurfaceRadiationBase::_areas
std::vector< Real > _areas
the area by participating side set
Definition: GrayLambertSurfaceRadiationBase.h:91