https://mooseframework.inl.gov
ViewFactorBase.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 "ViewFactorBase.h"
11 #include "libmesh/quadrature.h"
12 
13 #include <limits>
14 
17 {
19  params.addParam<Real>("view_factor_tol",
20  std::numeric_limits<Real>::max(),
21  "Tolerance for checking view factors. Default is to allow everything.");
22  params.addParam<bool>(
23  "print_view_factor_info", false, "Flag to print information about computed view factors.");
24  params.addParam<bool>("normalize_view_factor",
25  true,
26  "Determines if view factors are normalized to sum to one (consistent with "
27  "their definition).");
28 
29  MooseEnum normalization_method("lagrange_multiplier inverse_row_sum", "lagrange_multiplier");
30  normalization_method.addDocumentation("lagrange_multiplier", "Uses Lagrange multiplier method");
31  normalization_method.addDocumentation("inverse_row_sum",
32  "Divides each view factor by its row sum");
33  params.addParam<MooseEnum>("normalization_method",
34  normalization_method,
35  "Normalization method to use if 'normalize_view_factor' is 'true'.");
36 
37  params.addClassDescription(
38  "A base class for automatic computation of view factors between sidesets.");
39  return params;
40 }
41 
43  : SideUserObject(parameters),
44  _n_sides(boundaryIDs().size()),
45  _areas(_n_sides),
46  _view_factor_tol(getParam<Real>("view_factor_tol")),
47  _normalize_view_factor(getParam<bool>("normalize_view_factor")),
48  _normalization_method(
49  getParam<MooseEnum>("normalization_method").getEnum<NormalizationMethod>()),
50  _print_view_factor_info(getParam<bool>("print_view_factor_info"))
51 {
52  // sizing the view factor array
53  _view_factors.resize(_n_sides);
54  for (auto & v : _view_factors)
55  v.resize(_n_sides);
56 
57  // set up the map from the side id to the local index & side name to local index
58  std::vector<BoundaryName> boundary_names = getParam<std::vector<BoundaryName>>("boundary");
59  for (unsigned int j = 0; j < boundary_names.size(); ++j)
60  _side_name_index[boundary_names[j]] = j;
61 }
62 
63 unsigned int
65 {
66  auto it = _side_name_index.find(name);
67  if (it == _side_name_index.end())
68  mooseError("Boundary ", name, " does not exist.");
69  return it->second;
70 }
71 
72 Real
74 {
75  auto from_name = _mesh.getBoundaryName(from_id);
76  auto to_name = _mesh.getBoundaryName(to_id);
77 
78  return getViewFactor(from_name, to_name);
79 }
80 
81 Real
82 ViewFactorBase::getViewFactor(BoundaryName from_name, BoundaryName to_name) const
83 {
84  auto from = _side_name_index.find(from_name);
85  auto to = _side_name_index.find(to_name);
86  if (from == _side_name_index.end())
87  mooseError("Boundary id ",
88  _mesh.getBoundaryID(from_name),
89  " with name ",
90  from_name,
91  " not listed in boundary parameter.");
92 
93  if (to == _side_name_index.end())
94  mooseError("Boundary id ",
95  _mesh.getBoundaryID(to_name),
96  " with name ",
97  to_name,
98  " not listed in boundary parameter.");
99 
100  return _view_factors[from->second][to->second];
101 }
102 
103 void
105 {
106  std::fill(_areas.begin(), _areas.end(), 0);
107 }
108 
109 void
111 {
112  // compute areas
113  auto current_boundary_name = _mesh.getBoundaryName(_current_boundary_id);
114  auto it = _side_name_index.find(current_boundary_name);
115  if (it == _side_name_index.end())
116  mooseError("Current boundary name: ",
117  current_boundary_name,
118  " with id ",
120  " not in boundary parameter.");
121 
122  _areas[it->second] += _current_side_volume;
123 }
124 
125 void
127 {
128  gatherSum(_areas);
129 
132 }
133 
134 void
136 {
137  const auto & pps = static_cast<const ViewFactorBase &>(y);
138  for (unsigned int i = 0; i < _n_sides; ++i)
139  _areas[i] += pps._areas[i];
140 
142 }
143 
144 Real
145 ViewFactorBase::devReciprocity(unsigned int i, unsigned int j) const
146 {
147  return _view_factors[i][j] - _areas[j] / _areas[i] * _view_factors[j][i];
148 }
149 
150 Real
152 {
153  Real v = 0;
154  for (unsigned int i = 0; i < _n_sides; ++i)
155  for (unsigned int j = i + 1; j < _n_sides; ++j)
156  {
157  Real s = std::abs(devReciprocity(i, j));
158  if (s > v)
159  v = s;
160  }
161  return v;
162 }
163 
164 Real
165 ViewFactorBase::viewFactorRowSum(unsigned int i) const
166 {
167  Real s = 0;
168  for (unsigned int to = 0; to < _n_sides; ++to)
169  s += _view_factors[i][to];
170  return s;
171 }
172 
173 Real
175 {
176  Real v = 0;
177  for (unsigned int i = 0; i < _n_sides; ++i)
178  {
179  Real s = std::abs(1 - viewFactorRowSum(i));
180  if (s > v)
181  v = s;
182  }
183  return v;
184 }
185 
186 void
188 {
189  // collect statistics
190  Real max_sum_deviation = maxDevRowSum();
191  Real max_reciprocity_deviation = maxDevReciprocity();
192  Real max_correction = std::numeric_limits<Real>::lowest();
193  Real min_correction = std::numeric_limits<Real>::max();
194 
196  _console << "\nSum of all view factors from side i to all other faces before normalization.\n"
197  << std::endl;
198 
199  // check view factors
201  for (unsigned int from = 0; from < _n_sides; ++from)
202  _console << "View factors from sideset " << boundaryNames()[from] << " sum to "
203  << viewFactorRowSum(from) << std::endl;
204 
205  if (max_sum_deviation > _view_factor_tol)
206  mooseError("Maximum deviation of view factor row sum is ",
207  max_sum_deviation,
208  " exceeding the set tolerance of ",
210 
211  // normalize view factors
213  {
215  _console << "\nNormalizing view factors.\n" << std::endl;
216 
217  const auto view_factors_original = _view_factors;
218 
219  switch (_normalization_method)
220  {
223  break;
226  break;
227  default:
228  mooseError("Invalid normalization method.");
229  }
230 
231  // compute max and min correction for reporting
232  for (const auto i : make_range(_n_sides))
233  for (const auto j : make_range(_n_sides))
234  {
235  const Real correction = _view_factors[i][j] - view_factors_original[i][j];
236  min_correction = std::min(correction, min_correction);
237  max_correction = std::max(correction, max_correction);
238  }
239  }
240 
242  {
243  _console << "\nFinal view factors.\n" << std::endl;
244  for (unsigned int from = 0; from < _n_sides; ++from)
245  {
246  std::string from_name;
247  for (auto pair : _side_name_index)
248  if (pair.second == from)
249  from_name = pair.first;
250  auto from_id = _mesh.getBoundaryID(from_name);
251 
252  for (unsigned int to = 0; to < _n_sides; ++to)
253  {
254  std::string to_name;
255  for (auto pair : _side_name_index)
256  if (pair.second == to)
257  to_name = pair.first;
258  auto to_id = _mesh.getBoundaryID(to_name);
259  _console << from_name << " (" << from_id << ") -> " << to_name << " (" << to_id
260  << ") = " << _view_factors[from][to] << std::endl;
261  }
262  }
263  }
264 
265  // check sum of view factors and maximum deviation on reciprocity
266  Real max_sum_deviation_after_normalization = maxDevRowSum();
267  Real max_reciprocity_deviation_after_normalization = maxDevReciprocity();
268 
269  // print summary
270  _console << std::endl;
271  _console << COLOR_CYAN << "Summary of the view factor computation"
272  << "\n"
273  << COLOR_DEFAULT << std::endl;
275  _console << "Normalization is performed." << std::endl;
276  else
277  _console << "Normalization is skipped." << std::endl;
278  _console << std::setw(60) << std::left << "Number of patches: " << _n_sides << std::endl;
279  _console << std::setw(60) << std::left
280  << "Max deviation sum = 1 before normalization: " << max_sum_deviation << std::endl;
281  _console << std::setw(60) << std::left
282  << "Max deviation from reciprocity before normalization: " << max_reciprocity_deviation
283  << std::endl;
285  {
286  _console << std::setw(60) << std::left << "Maximum correction: " << max_correction << std::endl;
287  _console << std::setw(60) << std::left << "Minimum correction: " << min_correction << std::endl;
288  _console << std::setw(60) << "Max deviation sum = 1 after normalization: "
289  << max_sum_deviation_after_normalization << std::endl;
290  _console << std::setw(60) << std::left << "Max deviation from reciprocity after normalization: "
291  << max_reciprocity_deviation_after_normalization << std::endl;
292  _console << std::endl;
293  }
294 }
295 
296 void
298 {
299  // allocate space
300  DenseVector<Real> rhs(_n_sides);
301  DenseVector<Real> lmults(_n_sides);
303 
304  // equations for the Lagrange multiplier
305  for (unsigned int i = 0; i < _n_sides; ++i)
306  {
307  // set the right hand side
308  rhs(i) = 1 - viewFactorRowSum(i);
309 
310  // contribution from the delta_ii element
311  matrix(i, i) = -0.5;
312 
313  // contributions from the upper diagonal
314  for (unsigned int j = i + 1; j < _n_sides; ++j)
315  {
316  Real ar = _areas[i] / _areas[j];
317  Real f = 2 * (1 + ar * ar);
318  matrix(i, i) += -1 / f;
319  matrix(i, j) += -1 / f * ar;
320  rhs(i) += ar * ar / (1 + ar * ar) * devReciprocity(i, j);
321  }
322 
323  // contributions from the lower diagonal
324  for (unsigned int j = 0; j < i; ++j)
325  {
326  Real ar = _areas[j] / _areas[i];
327  Real f = 2 * (1 + ar * ar);
328  matrix(i, i) += -1 / f * ar * ar;
329  matrix(i, j) += -1 / f * ar;
330  rhs(i) -= ar * devReciprocity(j, i) * (1 - ar * ar / (1 + ar * ar));
331  }
332  }
333 
334  // solve the linear system
335  matrix.lu_solve(rhs, lmults);
336 
337  // perform corrections but store view factors to temporary array
338  // because we cannot modify _view_factors as it's used in this calc
339  std::vector<std::vector<Real>> vf_temp = _view_factors;
340  for (unsigned int i = 0; i < _n_sides; ++i)
341  for (unsigned int j = 0; j < _n_sides; ++j)
342  {
343  Real correction;
344  if (i == j)
345  correction = -0.5 * lmults(i);
346  else
347  {
348  Real ar = _areas[i] / _areas[j];
349  Real f = 2 * (1 + ar * ar);
350  correction = -(lmults(i) + lmults(j) * ar + 2 * ar * ar * devReciprocity(i, j)) / f;
351  }
352 
353  // update the temporary view factor
354  vf_temp[i][j] += correction;
355  }
356  _view_factors = vf_temp;
357 }
358 
359 void
361 {
362  for (unsigned int i = 0; i < _n_sides; ++i)
363  {
364  const Real row_sum = viewFactorRowSum(i);
365  for (auto & v : _view_factors[i])
366  v /= row_sum;
367  }
368 }
369 
370 unsigned int
371 ViewFactorBase::indexHelper(unsigned int i, unsigned int j) const
372 {
373  mooseAssert(i <= j, "indexHelper requires i <= j");
374  if (i == j)
375  return _n_sides + i;
376  unsigned int pos = 2 * _n_sides;
377  for (unsigned int l = 0; l < _n_sides; ++l)
378  for (unsigned int m = l + 1; m < _n_sides; ++m)
379  {
380  if (l == i && m == j)
381  return pos;
382  else
383  ++pos;
384  }
385  mooseError("Should never get here");
386  return 0;
387 }
virtual void finalizeViewFactor()=0
a purely virtural function called in finalize, must be overriden by derived class ...
void gatherSum(T &value)
static InputParameters validParams()
unsigned int indexHelper(unsigned int i, unsigned int j) const
helper for finding index of correction for i,j-th entry
void addParam(const std::string &name, const std::initializer_list< typename T::value_type > &value, const std::string &doc_string)
std::vector< Real > _areas
area of the sides i
virtual void finalize() override final
std::unordered_map< std::string, unsigned int > _side_name_index
boundary name to index map
const Real _view_factor_tol
view factor tolerance
ViewFactorBase(const InputParameters &parameters)
unsigned int _n_sides
number of boundaries of this side uo
const bool _print_view_factor_info
const std::string & getBoundaryName(const BoundaryID boundary_id) const
const double v
NormalizationMethod
How to normalize view factors.
const std::vector< double > y
const bool _normalize_view_factor
whether to normalize view factors so vf[from][:] sums to one
Real devReciprocity(unsigned int i, unsigned int j) const
this function computes the deviation from reciprocity defined as Fij - Aj/Ai * Fji ...
Real getViewFactor(BoundaryID from_id, BoundaryID to_id) const
public interface for obtaining view factors
void normalizeUsingLagrangeMultiplier()
normalizes view factors by Lagrange multiplier method
virtual void execute() override
A base class for automatic computation of view factors between sidesets.
const Real & _current_side_volume
void normalizeUsingInverseRowSum()
normalizes view factors by inverse row sum
const std::string & name() const
const BoundaryID & _current_boundary_id
Real maxDevRowSum() const
maximum deviation of any view factor row sum from 1
std::vector< std::vector< Real > > _view_factors
the view factor from side i to side j
Real f(Real x)
Test function for Brents method.
boundary_id_type BoundaryID
const std::string name
Definition: Setup.h:21
unsigned int getSideNameIndex(std::string name) const
helper function to get the index from the boundary name
Real viewFactorRowSum(unsigned int i) const
sum of a row in the view factor matrix
virtual void threadJoinViewFactor(const UserObject &y)=0
a purely virtual function called in finalize, must be overriden by derived class
static InputParameters validParams()
void checkAndNormalizeViewFactor()
this function checks & normalizes view factors to sum to one, this is not always
void lu_solve(const DenseVector< Real > &b, DenseVector< Real > &x)
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
MooseMesh & _mesh
virtual void threadJoin(const UserObject &y) override final
IntRange< T > make_range(T beg, T end)
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")
const ConsoleStream _console
const std::vector< BoundaryName > & boundaryNames() const
const NormalizationMethod _normalization_method
How to normalize view factors.
Real maxDevReciprocity() const
this function computes the maximum absolute value of the deviation from reciprocity ...
BoundaryID getBoundaryID(const BoundaryName &boundary_name) const
virtual void initialize() override