Line data Source code
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 "RadiationTransferAction.h"
11 : #include "Factory.h"
12 : #include "MooseMesh.h"
13 : #include "MeshGeneratorMesh.h"
14 : #include "FEProblemBase.h"
15 : #include "PatchSidesetGenerator.h"
16 : #include "ViewFactorRayBC.h"
17 : #include "ViewFactorRayStudy.h"
18 :
19 : registerMooseAction("HeatTransferApp", RadiationTransferAction, "append_mesh_generator");
20 : registerMooseAction("HeatTransferApp", RadiationTransferAction, "add_user_object");
21 : registerMooseAction("HeatTransferApp", RadiationTransferAction, "add_bc");
22 : registerMooseAction("HeatTransferApp", RadiationTransferAction, "add_ray_boundary_condition");
23 : registerMooseAction("HeatTransferApp", RadiationTransferAction, "add_aux_variable");
24 : registerMooseAction("HeatTransferApp", RadiationTransferAction, "add_aux_kernel");
25 :
26 : InputParameters
27 432 : RadiationTransferAction::validParams()
28 : {
29 432 : InputParameters params = Action::validParams();
30 432 : params.addClassDescription(
31 : "This action sets up the net radiation calculation between specified sidesets.");
32 :
33 864 : params.addRequiredParam<std::vector<BoundaryName>>(
34 : "boundary", "The boundaries that participate in the radiative exchange.");
35 :
36 864 : params.addParam<std::vector<BoundaryName>>(
37 : "adiabatic_boundary",
38 : {},
39 : "The adiabatic boundaries that participate in the radiative exchange.");
40 :
41 864 : params.addParam<std::vector<BoundaryName>>(
42 : "fixed_temperature_boundary",
43 : {},
44 : "The fixed temperature boundaries that participate in the radiative exchange.");
45 :
46 864 : params.addParam<std::vector<FunctionName>>(
47 : "fixed_boundary_temperatures", {}, "The temperatures of the fixed boundary.");
48 :
49 864 : params.addRequiredParam<std::vector<unsigned int>>("n_patches",
50 : "Number of radiation patches per sideset.");
51 : MultiMooseEnum partitioning(
52 432 : "default=-3 metis=-2 parmetis=-1 linear=0 centroid hilbert_sfc morton_sfc", "default");
53 432 : partitioning.addValidName("grid");
54 864 : params.addParam<MultiMooseEnum>(
55 : "partitioners",
56 : partitioning,
57 : "Specifies a mesh partitioner to use when preparing the radiation patches.");
58 :
59 432 : MultiMooseEnum direction("x y z radial");
60 864 : params.addParam<MultiMooseEnum>("centroid_partitioner_directions",
61 : direction,
62 : "Specifies the sort direction if using the centroid partitioner. "
63 : "Available options: x, y, z, radial");
64 :
65 864 : params.addRequiredParam<VariableName>("temperature", "The coupled temperature variable.");
66 864 : params.addRequiredParam<std::vector<FunctionName>>("emissivity",
67 : "Emissivities for each boundary.");
68 :
69 864 : MooseEnum view_factor_calculator("analytical ray_tracing", "ray_tracing");
70 864 : params.addParam<MooseEnum>(
71 : "view_factor_calculator", view_factor_calculator, "The view factor calculator being used.");
72 :
73 864 : params.addParam<bool>(
74 864 : "print_view_factor_info", false, "Flag to print information about computed view factors.");
75 1296 : params.addParam<bool>("normalize_view_factor",
76 864 : true,
77 : "Determines if view factors are normalized to sum to one (consistent with "
78 : "their definition).");
79 :
80 : std::vector<BoundaryName> empty = {};
81 864 : params.addParam<std::vector<BoundaryName>>(
82 : "symmetry_boundary",
83 : empty,
84 : "The sidesets that represent symmetry lines/planes for the problem. These sidesets do not "
85 : "participate in the radiative exchange"
86 : "so they should not be listed in the sidesets parameter.");
87 :
88 864 : MooseEnum qtypes("GAUSS GRID", "GRID");
89 864 : params.addParam<MooseEnum>(
90 : "ray_tracing_face_type", qtypes, "The face quadrature rule type used for ray tracing.");
91 :
92 : MooseEnum qorders("CONSTANT FIRST SECOND THIRD FOURTH FIFTH SIXTH SEVENTH EIGHTH NINTH TENTH "
93 : "ELEVENTH TWELFTH THIRTEENTH FOURTEENTH FIFTEENTH SIXTEENTH SEVENTEENTH "
94 : "EIGHTTEENTH NINTEENTH TWENTIETH",
95 864 : "CONSTANT");
96 864 : params.addParam<MooseEnum>(
97 : "ray_tracing_face_order", qorders, "The face quadrature rule order used for ray tracing.");
98 :
99 864 : params.addParam<unsigned int>(
100 : "polar_quad_order",
101 864 : 16,
102 : "Order of the polar quadrature [polar angle is between ray and normal]. Must be even. Only "
103 : "used if view_factor_calculator = ray_tracing.");
104 864 : params.addParam<unsigned int>(
105 : "azimuthal_quad_order",
106 864 : 8,
107 : "Order of the azimuthal quadrature per quadrant [azimuthal angle is measured in "
108 : "a plane perpendicular to the normal]. Only used if view_factor_calculator = "
109 : "ray_tracing.");
110 :
111 864 : params.addParam<bool>("add_heat_flux_aux", false, "If true, add a heat flux aux variable");
112 864 : params.addParam<VariableName>(
113 : "heat_flux_variable",
114 : "Heat flux aux variable name; this must be provided if 'add_heat_flux_aux' is true");
115 864 : params.addParam<std::vector<SubdomainName>>(
116 : "heat_flux_aux_block", "Subdomains to use for heat flux aux if 'add_heat_flux_aux' is true");
117 :
118 432 : return params;
119 432 : }
120 :
121 432 : RadiationTransferAction::RadiationTransferAction(const InputParameters & params)
122 : : Action(params),
123 432 : _boundary_names(getParam<std::vector<BoundaryName>>("boundary")),
124 864 : _view_factor_calculator(getParam<MooseEnum>("view_factor_calculator")),
125 1296 : _add_heat_flux_aux(getParam<bool>("add_heat_flux_aux"))
126 : {
127 432 : const auto & symmetry_names = getParam<std::vector<BoundaryName>>("symmetry_boundary");
128 :
129 432 : if (_view_factor_calculator != "ray_tracing")
130 : {
131 720 : for (const auto & param_name : {"polar_quad_order",
132 : "azimuthal_quad_order",
133 : "ray_tracing_face_type",
134 900 : "ray_tracing_face_order"})
135 1440 : if (params.isParamSetByUser(param_name))
136 0 : paramWarning(param_name,
137 : "Only used for view_factor_calculator = ray_tracing. It is ignored for this "
138 : "calculation.");
139 :
140 180 : if (symmetry_names.size())
141 0 : paramError("symmetry_boundary",
142 : "Symmetry boundaries are only supported with view_factor_calculator = "
143 : "ray_tracing.");
144 : }
145 : else
146 : {
147 : // check that there is no overlap between sidesets and symmetry sidesets
148 1470 : for (const auto & name : _boundary_names)
149 1218 : if (std::find(symmetry_names.begin(), symmetry_names.end(), name) != symmetry_names.end())
150 0 : paramError("boundary",
151 : "Boundary ",
152 : name,
153 : " is present in parameter boundary and symmetry_boundary.");
154 : }
155 :
156 432 : if (_add_heat_flux_aux)
157 : {
158 84 : if (isParamValid("heat_flux_variable"))
159 42 : _heat_flux_variable = getParam<VariableName>("heat_flux_variable");
160 : else
161 0 : paramError("heat_flux_variable",
162 : "If 'add_heat_flux_aux' is true, then this parameter must be provided.");
163 :
164 84 : if (isParamValid("heat_flux_aux_block"))
165 126 : _heat_flux_aux_block = getParam<std::vector<SubdomainName>>("heat_flux_aux_block");
166 : else
167 0 : paramError("heat_flux_aux_block",
168 : "If 'add_heat_flux_aux' is true, then this parameter must be provided.");
169 : }
170 :
171 432 : checkBoundaryParameterIsSubset("adiabatic_boundary");
172 432 : checkBoundaryParameterIsSubset("fixed_temperature_boundary");
173 432 : }
174 :
175 : void
176 864 : RadiationTransferAction::checkBoundaryParameterIsSubset(const std::string & param) const
177 : {
178 864 : const auto boundary_names = getParam<std::vector<BoundaryName>>(param);
179 1686 : for (const auto & bname : boundary_names)
180 822 : if (std::find(_boundary_names.begin(), _boundary_names.end(), bname) == _boundary_names.end())
181 0 : paramError(param, "The boundaries in '" + param + "' must be a subset of 'boundary'.");
182 864 : }
183 :
184 : void
185 422 : RadiationTransferAction::act()
186 : {
187 422 : if (_current_task == "append_mesh_generator")
188 72 : addMeshGenerator();
189 350 : else if (_current_task == "add_user_object")
190 : {
191 70 : addRadiationObject();
192 70 : addRayStudyObject();
193 70 : addViewFactorObject();
194 : }
195 280 : else if (_current_task == "add_bc")
196 70 : addRadiationBCs();
197 210 : else if (_current_task == "add_ray_boundary_condition")
198 70 : addRayBCs();
199 140 : else if (_current_task == "add_aux_variable" && _add_heat_flux_aux)
200 7 : addHeatFluxAuxVariable();
201 133 : else if (_current_task == "add_aux_kernel" && _add_heat_flux_aux)
202 7 : addHeatFluxAuxKernel();
203 422 : }
204 :
205 : void
206 70 : RadiationTransferAction::addRadiationBCs() const
207 : {
208 70 : InputParameters params = _factory.getValidParams("GrayLambertNeumannBC");
209 :
210 : // set boundary
211 70 : std::vector<std::vector<std::string>> radiation_patch_names = bcRadiationPatchNames();
212 : std::vector<BoundaryName> boundary_names;
213 252 : for (auto & e1 : radiation_patch_names)
214 511 : for (auto & e2 : e1)
215 329 : boundary_names.push_back(e2);
216 :
217 70 : params.set<std::vector<BoundaryName>>("boundary") = boundary_names;
218 :
219 : // set temperature variable
220 210 : params.set<NonlinearVariableName>("variable") = getParam<VariableName>("temperature");
221 :
222 : // set radiationuserobject
223 140 : params.set<UserObjectName>("surface_radiation_object_name") = radiationObjectName();
224 :
225 140 : _problem->addBoundaryCondition("GrayLambertNeumannBC", "gray_lamber_neumann_bc_" + _name, params);
226 70 : }
227 :
228 : void
229 70 : RadiationTransferAction::addViewFactorObject() const
230 : {
231 : // this userobject is only executed on initial
232 70 : ExecFlagEnum exec_enum = MooseUtils::getDefaultExecFlagEnum();
233 210 : exec_enum = {EXEC_INITIAL};
234 :
235 70 : if (_view_factor_calculator == "analytical")
236 : {
237 : // this branch adds the UnobstructedPlanarViewFactor
238 28 : InputParameters params = _factory.getValidParams("UnobstructedPlanarViewFactor");
239 56 : params.set<std::vector<BoundaryName>>("boundary") = radiationPatchBoundaryNames();
240 28 : params.set<ExecFlagEnum>("execute_on") = exec_enum;
241 :
242 56 : _problem->addUserObject("UnobstructedPlanarViewFactor", viewFactorObjectName(), params);
243 28 : }
244 42 : else if (_view_factor_calculator == "ray_tracing")
245 : {
246 : // this branch adds the ray tracing UO
247 42 : InputParameters params = _factory.getValidParams("RayTracingViewFactor");
248 84 : params.set<std::vector<BoundaryName>>("boundary") = radiationPatchBoundaryNames();
249 42 : params.set<ExecFlagEnum>("execute_on") = exec_enum;
250 84 : params.set<UserObjectName>("ray_study_name") = rayStudyName();
251 84 : params.set<bool>("print_view_factor_info") = getParam<bool>("print_view_factor_info");
252 84 : params.set<bool>("normalize_view_factor") = getParam<bool>("normalize_view_factor");
253 84 : _problem->addUserObject("RayTracingViewFactor", viewFactorObjectName(), params);
254 42 : }
255 140 : }
256 :
257 : void
258 70 : RadiationTransferAction::addRayStudyObject() const
259 : {
260 70 : if (_view_factor_calculator == "analytical")
261 28 : return;
262 :
263 42 : InputParameters params = _factory.getValidParams("ViewFactorRayStudy");
264 :
265 84 : params.set<std::vector<BoundaryName>>("boundary") = radiationPatchBoundaryNames();
266 :
267 : // set this object to be execute on initial only
268 42 : ExecFlagEnum exec_enum = MooseUtils::getDefaultExecFlagEnum();
269 84 : exec_enum = {EXEC_INITIAL};
270 42 : params.set<ExecFlagEnum>("execute_on") = exec_enum;
271 :
272 : // set face order
273 126 : params.set<MooseEnum>("face_order") = getParam<MooseEnum>("ray_tracing_face_order");
274 126 : params.set<MooseEnum>("face_type") = getParam<MooseEnum>("ray_tracing_face_type");
275 :
276 : // set angular quadrature
277 84 : params.set<unsigned int>("polar_quad_order") = getParam<unsigned int>("polar_quad_order");
278 84 : params.set<unsigned int>("azimuthal_quad_order") = getParam<unsigned int>("azimuthal_quad_order");
279 84 : _problem->addUserObject("ViewFactorRayStudy", rayStudyName(), params);
280 84 : }
281 :
282 : void
283 70 : RadiationTransferAction::addRayBCs() const
284 : {
285 70 : if (_view_factor_calculator == "analytical")
286 : return;
287 :
288 : {
289 42 : InputParameters params = _factory.getValidParams("ViewFactorRayBC");
290 84 : params.set<std::vector<BoundaryName>>("boundary") = radiationPatchBoundaryNames();
291 42 : params.set<RayTracingStudy *>("_ray_tracing_study") =
292 42 : &_problem->getUserObject<ViewFactorRayStudy>(rayStudyName());
293 84 : _problem->addObject<RayBoundaryConditionBase>("ViewFactorRayBC", rayBCName(), params);
294 42 : }
295 :
296 : // add symmetry BCs if applicable
297 84 : const auto & symmetry_names = getParam<std::vector<BoundaryName>>("symmetry_boundary");
298 42 : if (symmetry_names.size() > 0)
299 : {
300 7 : InputParameters params = _factory.getValidParams("ReflectRayBC");
301 7 : params.set<std::vector<BoundaryName>>("boundary") = symmetry_names;
302 7 : params.set<RayTracingStudy *>("_ray_tracing_study") =
303 7 : &_problem->getUserObject<ViewFactorRayStudy>(rayStudyName());
304 14 : _problem->addObject<RayBoundaryConditionBase>("ReflectRayBC", symmetryRayBCName(), params);
305 7 : }
306 : }
307 :
308 : UserObjectName
309 133 : RadiationTransferAction::rayStudyName() const
310 : {
311 266 : return "ray_study_uo_" + _name;
312 : }
313 :
314 : std::string
315 42 : RadiationTransferAction::rayBCName() const
316 : {
317 42 : return "ray_bc_" + _name;
318 : }
319 :
320 : std::string
321 7 : RadiationTransferAction::symmetryRayBCName() const
322 : {
323 7 : return "symmetry_ray_bc_" + _name;
324 : }
325 :
326 : UserObjectName
327 140 : RadiationTransferAction::viewFactorObjectName() const
328 : {
329 280 : return "view_factor_uo_" + _name;
330 : }
331 :
332 : UserObjectName
333 147 : RadiationTransferAction::radiationObjectName() const
334 : {
335 294 : return "view_factor_surface_radiation_" + _name;
336 : }
337 :
338 : void
339 70 : RadiationTransferAction::addRadiationObject() const
340 : {
341 70 : std::vector<std::vector<std::string>> radiation_patch_names = radiationPatchNames();
342 :
343 : // input parameter check
344 210 : std::vector<FunctionName> emissivity = getParam<std::vector<FunctionName>>("emissivity");
345 70 : if (emissivity.size() != _boundary_names.size())
346 0 : mooseError("emissivity parameter needs to be the same size as the boundary parameter.");
347 :
348 : // the action only sets up ViewFactorObjectSurfaceRadiation, because after splitting
349 : // faces auotmatically, it makes no sense to require view factor input by hand.
350 70 : InputParameters params = _factory.getValidParams("ViewFactorObjectSurfaceRadiation");
351 210 : params.set<std::vector<VariableName>>("temperature") = {getParam<VariableName>("temperature")};
352 :
353 : std::vector<FunctionName> extended_emissivity;
354 385 : for (unsigned int j = 0; j < _boundary_names.size(); ++j)
355 896 : for (unsigned int i = 0; i < nPatch(j); ++i)
356 581 : extended_emissivity.push_back(emissivity[j]);
357 70 : params.set<std::vector<FunctionName>>("emissivity") = extended_emissivity;
358 :
359 : // add boundary parameter
360 140 : params.set<std::vector<BoundaryName>>("boundary") = radiationPatchBoundaryNames();
361 :
362 : // add adiabatic_boundary parameter if required
363 140 : if (isParamValid("adiabatic_boundary"))
364 140 : params.set<std::vector<BoundaryName>>("adiabatic_boundary") = adiabaticPatchBoundaryNames();
365 :
366 : // add isothermal sidesets if required
367 140 : if (isParamValid("fixed_temperature_boundary"))
368 : {
369 140 : if (!isParamValid("fixed_boundary_temperatures"))
370 0 : mooseError("fixed_temperature_boundary is provided so fixed_boundary_temperatures must be "
371 : "provided too");
372 :
373 : std::vector<BoundaryName> fixed_T_boundary_names =
374 140 : getParam<std::vector<BoundaryName>>("fixed_temperature_boundary");
375 :
376 : std::vector<FunctionName> fixed_T_funcs =
377 210 : getParam<std::vector<FunctionName>>("fixed_boundary_temperatures");
378 :
379 : // check length of fixed_boundary_temperatures
380 70 : if (fixed_T_funcs.size() != fixed_T_boundary_names.size())
381 0 : mooseError("Size of parameter fixed_boundary_temperatures and fixed_temperature_boundary "
382 : "must be equal.");
383 :
384 : std::vector<BoundaryName> fixed_T_patch_names;
385 : std::vector<FunctionName> fixed_T_function_names;
386 105 : for (unsigned int k = 0; k < fixed_T_boundary_names.size(); ++k)
387 : {
388 : BoundaryName bnd_name = fixed_T_boundary_names[k];
389 :
390 : // find the right entry in _boundary_names
391 35 : auto it = std::find(_boundary_names.begin(), _boundary_names.end(), bnd_name);
392 :
393 : // check if entry was found: it must be found or an error would occur later
394 35 : if (it == _boundary_names.end())
395 0 : mooseError("Fixed temperature sideset ", bnd_name, " not present in boundary.");
396 :
397 : // this is the position in the _boundary_names vector; this is what
398 : // we are really after
399 : auto index = std::distance(_boundary_names.begin(), it);
400 :
401 : // collect the correct boundary names
402 105 : for (auto & e : radiation_patch_names[index])
403 : {
404 70 : fixed_T_patch_names.push_back(e);
405 70 : fixed_T_function_names.push_back(fixed_T_funcs[k]);
406 : }
407 : }
408 70 : params.set<std::vector<BoundaryName>>("fixed_temperature_boundary") = fixed_T_patch_names;
409 70 : params.set<std::vector<FunctionName>>("fixed_boundary_temperatures") = fixed_T_function_names;
410 70 : }
411 :
412 : // the view factor userobject name
413 140 : params.set<UserObjectName>("view_factor_object_name") = viewFactorObjectName();
414 :
415 : // this userobject needs to be executed on linear and timestep end
416 70 : ExecFlagEnum exec_enum = MooseUtils::getDefaultExecFlagEnum();
417 210 : exec_enum = {EXEC_LINEAR, EXEC_TIMESTEP_END};
418 70 : params.set<ExecFlagEnum>("execute_on") = exec_enum;
419 :
420 : // add the object
421 140 : _problem->addUserObject("ViewFactorObjectSurfaceRadiation", radiationObjectName(), params);
422 280 : }
423 :
424 : std::vector<std::vector<std::string>>
425 70 : RadiationTransferAction::radiationPatchNames() const
426 : {
427 70 : std::vector<std::vector<std::string>> radiation_patch_names(_boundary_names.size());
428 70 : std::vector<BoundaryID> boundary_ids = _mesh->getBoundaryIDs(_boundary_names);
429 385 : for (unsigned int j = 0; j < boundary_ids.size(); ++j)
430 : {
431 315 : boundary_id_type bid = boundary_ids[j];
432 315 : std::string base_name = _mesh->getBoundaryName(bid);
433 : std::vector<std::string> bnames;
434 896 : for (unsigned int i = 0; i < nPatch(j); ++i)
435 : {
436 581 : std::stringstream ss;
437 581 : ss << base_name << "_" << i;
438 581 : bnames.push_back(ss.str());
439 581 : }
440 315 : radiation_patch_names[j] = bnames;
441 315 : }
442 70 : return radiation_patch_names;
443 70 : }
444 :
445 : std::vector<std::vector<std::string>>
446 70 : RadiationTransferAction::bcRadiationPatchNames() const
447 : {
448 140 : auto ad_bnd_names = getParam<std::vector<BoundaryName>>("adiabatic_boundary");
449 210 : auto ft_bnd_names = getParam<std::vector<BoundaryName>>("fixed_temperature_boundary");
450 : std::vector<std::vector<std::string>> radiation_patch_names;
451 70 : std::vector<BoundaryID> boundary_ids = _mesh->getBoundaryIDs(_boundary_names);
452 385 : for (unsigned int j = 0; j < boundary_ids.size(); ++j)
453 : {
454 315 : boundary_id_type bid = boundary_ids[j];
455 : BoundaryName bnd_name = _boundary_names[j];
456 :
457 : // check if this sideset is adiabatic or isothermal
458 315 : auto it_a = std::find(ad_bnd_names.begin(), ad_bnd_names.end(), bnd_name);
459 315 : auto it_t = std::find(ft_bnd_names.begin(), ft_bnd_names.end(), bnd_name);
460 315 : if (it_a != ad_bnd_names.end() || it_t != ft_bnd_names.end())
461 : continue;
462 :
463 182 : std::string base_name = _mesh->getBoundaryName(bid);
464 : std::vector<std::string> bnames;
465 511 : for (unsigned int i = 0; i < nPatch(j); ++i)
466 : {
467 329 : std::stringstream ss;
468 329 : ss << base_name << "_" << i;
469 329 : bnames.push_back(ss.str());
470 329 : }
471 182 : radiation_patch_names.push_back(bnames);
472 182 : }
473 70 : return radiation_patch_names;
474 70 : }
475 :
476 : std::vector<BoundaryName>
477 301 : RadiationTransferAction::patchBoundaryNames(
478 : const std::vector<BoundaryName> & boundary_names_or_ids) const
479 : {
480 : std::vector<BoundaryName> patch_boundary_names;
481 301 : std::vector<BoundaryID> ids = _mesh->getBoundaryIDs(boundary_names_or_ids);
482 1463 : for (const auto i : index_range(boundary_names_or_ids))
483 : {
484 : const auto boundary_name_or_id = boundary_names_or_ids[i];
485 1162 : const auto it = std::find(_boundary_names.begin(), _boundary_names.end(), boundary_name_or_id);
486 : mooseAssert(it != _boundary_names.end(), boundary_name_or_id + " not found in 'boundary'.");
487 : const auto boundary_index = std::distance(_boundary_names.begin(), it);
488 1162 : const auto n_patches = nPatch(boundary_index);
489 1162 : const auto boundary_name = _mesh->getBoundaryName(ids[i]);
490 3227 : for (const auto j : make_range(n_patches))
491 : {
492 2065 : std::stringstream ss;
493 2065 : ss << boundary_name << "_" << j;
494 2065 : patch_boundary_names.push_back(ss.str());
495 2065 : }
496 : }
497 301 : return patch_boundary_names;
498 301 : }
499 :
500 : std::vector<BoundaryName>
501 231 : RadiationTransferAction::radiationPatchBoundaryNames() const
502 : {
503 231 : return patchBoundaryNames(_boundary_names);
504 : }
505 :
506 : std::vector<BoundaryName>
507 70 : RadiationTransferAction::adiabaticPatchBoundaryNames() const
508 : {
509 : std::vector<BoundaryName> patch_boundary_names;
510 140 : if (isParamValid("adiabatic_boundary"))
511 : patch_boundary_names =
512 280 : patchBoundaryNames(getParam<std::vector<BoundaryName>>("adiabatic_boundary"));
513 70 : return patch_boundary_names;
514 0 : }
515 :
516 : void
517 72 : RadiationTransferAction::addMeshGenerator()
518 : {
519 144 : std::vector<unsigned int> n_patches = getParam<std::vector<unsigned int>>("n_patches");
520 144 : MultiMooseEnum partitioners = getParam<MultiMooseEnum>("partitioners");
521 144 : if (!_pars.isParamSetByUser("partitioners"))
522 : {
523 14 : partitioners.clearSetValues();
524 70 : for (unsigned int j = 0; j < _boundary_names.size(); ++j)
525 112 : partitioners.setAdditionalValue("metis");
526 : }
527 :
528 216 : MultiMooseEnum direction = getParam<MultiMooseEnum>("centroid_partitioner_directions");
529 :
530 : // check input parameters
531 72 : if (_boundary_names.size() != n_patches.size())
532 0 : mooseError("n_patches parameter must have same length as boundary parameter.");
533 :
534 72 : if (_boundary_names.size() != partitioners.size())
535 0 : mooseError("partitioners parameter must have same length as boundary parameter.");
536 :
537 395 : for (unsigned int j = 0; j < partitioners.size(); ++j)
538 323 : if (partitioners[j] == "centroid" && direction.size() != _boundary_names.size())
539 0 : mooseError(
540 : "centroid partitioner is selected for at least one sideset. "
541 : "centroid_partitioner_directions parameter must have same length as boundary parameter.");
542 :
543 : // check if mesh is a MeshGeneratorMesh
544 72 : std::shared_ptr<MeshGeneratorMesh> mg_mesh = std::dynamic_pointer_cast<MeshGeneratorMesh>(_mesh);
545 72 : if (!mg_mesh)
546 0 : mooseError("This action adds MeshGenerator objects and therefore only works with a "
547 : "MeshGeneratorMesh.");
548 :
549 395 : for (unsigned int j = 0; j < _boundary_names.size(); ++j)
550 : {
551 646 : InputParameters params = _factory.getValidParams("PatchSidesetGenerator");
552 646 : params.set<BoundaryName>("boundary") = _boundary_names[j];
553 323 : params.set<unsigned int>("n_patches") = n_patches[j];
554 323 : params.set<MooseEnum>("partitioner") = partitioners[j];
555 :
556 323 : if (partitioners[j] == "centroid")
557 352 : params.set<MooseEnum>("centroid_partitioner_direction") = direction[j];
558 :
559 646 : _app.appendMeshGenerator("PatchSidesetGenerator", meshGeneratorName(j), params);
560 323 : }
561 72 : }
562 :
563 : unsigned int
564 3465 : RadiationTransferAction::nPatch(unsigned int j) const
565 : {
566 3465 : const MeshGenerator * mg = &_app.getMeshGenerator(meshGeneratorName(j));
567 3465 : const PatchSidesetGenerator * psg = dynamic_cast<const PatchSidesetGenerator *>(mg);
568 3465 : if (!psg)
569 0 : mooseError("Failed to convert mesh generator ", mg->name(), " to PatchSidesetGenerator.");
570 3465 : return psg->nPatches();
571 : }
572 :
573 : MeshGeneratorName
574 3788 : RadiationTransferAction::meshGeneratorName(unsigned int j) const
575 : {
576 3788 : std::stringstream ss;
577 3788 : ss << "patch_side_set_generator_" << _boundary_names[j];
578 3788 : return ss.str();
579 3788 : }
580 :
581 : void
582 7 : RadiationTransferAction::addHeatFluxAuxVariable() const
583 : {
584 7 : const std::string var_type = "MooseVariable";
585 7 : auto params = _factory.getValidParams(var_type);
586 7 : params.set<std::vector<SubdomainName>>("block") = _heat_flux_aux_block;
587 14 : params.set<MooseEnum>("order") = "CONSTANT";
588 14 : params.set<MooseEnum>("family") = "MONOMIAL";
589 7 : _problem->addAuxVariable(var_type, _heat_flux_variable, params);
590 14 : }
591 :
592 : void
593 7 : RadiationTransferAction::addHeatFluxAuxKernel() const
594 : {
595 7 : const std::string class_name = "GrayLambertRadiationHeatFluxAux";
596 7 : InputParameters params = _factory.getValidParams(class_name);
597 14 : params.set<AuxVariableName>("variable") = _heat_flux_variable;
598 14 : params.set<std::vector<BoundaryName>>("boundary") = radiationPatchBoundaryNames();
599 14 : params.set<UserObjectName>("surface_radiation_object") = radiationObjectName();
600 28 : params.set<ExecFlagEnum>("execute_on") = {EXEC_INITIAL, EXEC_TIMESTEP_END};
601 7 : _problem->addAuxKernel(class_name, "radiation_heat_flux_aux_kernel", params);
602 21 : }
|