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 "GapConductance.h"
11 :
12 : // MOOSE includes
13 : #include "Function.h"
14 : #include "MooseMesh.h"
15 : #include "MooseVariable.h"
16 : #include "PenetrationLocator.h"
17 : #include "SystemBase.h"
18 : #include "AddVariableAction.h"
19 :
20 : #include "libmesh/string_to_enum.h"
21 :
22 : registerMooseObject("HeatTransferApp", GapConductance);
23 :
24 : InputParameters
25 2890 : GapConductance::validParams()
26 : {
27 2890 : InputParameters params = Material::validParams();
28 2890 : params += GapConductance::actionParameters();
29 2890 : params.addClassDescription(
30 : "Material to compute an effective gap conductance based on the thermal conductivity of the "
31 : "gap and diffusive approximation to the radiative heat transfer.");
32 :
33 5780 : params.addRequiredCoupledVar("variable", "Temperature variable");
34 :
35 : // Node based
36 5780 : params.addCoupledVar("gap_distance", "Distance across the gap");
37 5780 : params.addCoupledVar("gap_temp", "Temperature on the other side of the gap");
38 5780 : params.addParam<Real>("gap_conductivity", 1.0, "The thermal conductivity of the gap material");
39 5780 : params.addParam<FunctionName>(
40 : "gap_conductivity_function",
41 : "Thermal conductivity of the gap material as a function. Multiplied by gap_conductivity.");
42 5780 : params.addCoupledVar("gap_conductivity_function_variable",
43 : "Variable to be used in the gap_conductivity_function in place of time");
44 :
45 : // Quadrature based
46 5780 : params.addParam<bool>("quadrature",
47 5780 : false,
48 : "Whether or not to do quadrature point based gap heat "
49 : "transfer. If this is true then gap_distance and "
50 : "gap_temp should NOT be provided (and will be "
51 : "ignored); however, paired_boundary and variable are "
52 : "then required.");
53 5780 : params.addParam<BoundaryName>("paired_boundary", "The boundary to be penetrated");
54 :
55 5780 : params.addParam<Real>("stefan_boltzmann", 5.670374e-8, "The Stefan-Boltzmann constant");
56 :
57 5780 : params.addParam<bool>("use_displaced_mesh",
58 5780 : true,
59 : "Whether or not this object should use the "
60 : "displaced mesh for computation. Note that in "
61 : "the case this is true but no displacements "
62 : "are provided in the Mesh block the "
63 : "undisplaced mesh will still be used.");
64 :
65 5780 : params.addParam<bool>(
66 5780 : "warnings", false, "Whether to output warning messages concerning nodes not being found");
67 :
68 2890 : MooseEnum orders(AddVariableAction::getNonlinearVariableOrders());
69 5780 : params.addParam<MooseEnum>("order", orders, "The finite element order");
70 :
71 : // These parameter groups match the ones in ThermalContactAction
72 5780 : params.addParamNamesToGroup("gap_distance", "Gap size");
73 5780 : params.addParamNamesToGroup("paired_boundary", "Gap surface definition");
74 5780 : params.addParamNamesToGroup("order quadrature", "Integration");
75 5780 : params.addParamNamesToGroup("warnings", "Diagnostics and debug");
76 5780 : params.addParamNamesToGroup(
77 : "gap_conductivity gap_conductivity_function gap_conductivity_function_variable",
78 : "Gap conductivity");
79 :
80 2890 : return params;
81 2890 : }
82 :
83 : InputParameters
84 9398 : GapConductance::actionParameters()
85 : {
86 9398 : InputParameters params = emptyInputParameters();
87 18796 : params.addParam<std::string>(
88 : "appended_property_name", "", "Name appended to material properties to make them unique");
89 18796 : MooseEnum gap_geom_types("PLATE CYLINDER SPHERE");
90 18796 : params.addParam<MooseEnum>("gap_geometry_type", gap_geom_types, "Gap calculation type.");
91 :
92 18796 : params.addParam<RealVectorValue>("cylinder_axis_point_1",
93 : "Start point for line defining cylindrical axis");
94 18796 : params.addParam<RealVectorValue>("cylinder_axis_point_2",
95 : "End point for line defining cylindrical axis");
96 18796 : params.addParam<RealVectorValue>("sphere_origin", "Origin for sphere geometry");
97 :
98 18796 : params.addRangeCheckedParam<Real>("emissivity_primary",
99 : 1,
100 : "emissivity_primary>=0 & emissivity_primary<=1",
101 : "The emissivity of the primary surface");
102 18796 : params.addRangeCheckedParam<Real>("emissivity_secondary",
103 : 1,
104 : "emissivity_secondary>=0 & emissivity_secondary<=1",
105 : "The emissivity of the secondary surface");
106 : // Common
107 28194 : params.addRangeCheckedParam<Real>(
108 18796 : "min_gap", 1e-6, "min_gap>0", "A minimum gap (denominator) size");
109 28194 : params.addRangeCheckedParam<Real>(
110 18796 : "max_gap", 1e6, "max_gap>=0", "A maximum gap (denominator) size");
111 28194 : params.addRangeCheckedParam<unsigned int>(
112 18796 : "min_gap_order", 0, "min_gap_order<=1", "Order of the Taylor expansion below min_gap");
113 :
114 18796 : params.addParamNamesToGroup("appended_property_name", "Material property retrieval");
115 18796 : params.addParamNamesToGroup("gap_geometry_type cylinder_axis_point_1 cylinder_axis_point_2",
116 : "Gap geometry");
117 18796 : params.addParamNamesToGroup("emissivity_primary emissivity_secondary", "Radiative heat transfer");
118 18796 : params.addParamNamesToGroup("min_gap max_gap min_gap_order", "Gap size");
119 :
120 9398 : return params;
121 9398 : }
122 :
123 1889 : GapConductance::GapConductance(const InputParameters & parameters)
124 : : Material(parameters),
125 1889 : _appended_property_name(getParam<std::string>("appended_property_name")),
126 1889 : _temp(coupledValue("variable")),
127 1889 : _gap_geometry_type(declareRestartableData<GapConductance::GAP_GEOMETRY>("gap_geometry_type",
128 1889 : GapConductance::PLATE)),
129 3778 : _quadrature(getParam<bool>("quadrature")),
130 1889 : _gap_temp(0),
131 1889 : _gap_distance(88888),
132 1889 : _radius(0),
133 1889 : _r1(0),
134 1889 : _r2(0),
135 1889 : _has_info(false),
136 1889 : _gap_distance_value(_quadrature ? _zero : coupledValue("gap_distance")),
137 1889 : _gap_temp_value(_quadrature ? _zero : coupledValue("gap_temp")),
138 1889 : _gap_conductance(declareProperty<Real>("gap_conductance" + _appended_property_name)),
139 3778 : _gap_conductance_dT(declareProperty<Real>("gap_conductance" + _appended_property_name + "_dT")),
140 1889 : _gap_thermal_conductivity(declareProperty<Real>("gap_conductivity")),
141 3778 : _gap_conductivity(getParam<Real>("gap_conductivity")),
142 1889 : _gap_conductivity_function(isParamValid("gap_conductivity_function")
143 1889 : ? &getFunction("gap_conductivity_function")
144 : : nullptr),
145 1889 : _gap_conductivity_function_variable(isCoupled("gap_conductivity_function_variable")
146 1889 : ? &coupledValue("gap_conductivity_function_variable")
147 : : nullptr),
148 3778 : _stefan_boltzmann(getParam<Real>("stefan_boltzmann")),
149 3778 : _emissivity_primary(getParam<Real>("emissivity_primary")),
150 3778 : _emissivity_secondary(getParam<Real>("emissivity_secondary")),
151 3778 : _min_gap(getParam<Real>("min_gap")),
152 3778 : _min_gap_order(getParam<unsigned int>("min_gap_order")),
153 3778 : _max_gap(getParam<Real>("max_gap")),
154 1889 : _temp_var(_quadrature ? getVar("variable", 0) : nullptr),
155 1889 : _penetration_locator(nullptr),
156 1889 : _serialized_solution(_quadrature ? &_temp_var->sys().currentSolution() : nullptr),
157 1889 : _dof_map(_quadrature ? &_temp_var->sys().dofMap() : nullptr),
158 3778 : _warnings(getParam<bool>("warnings")),
159 3778 : _p1(declareRestartableData<Point>("cylinder_axis_point_1", Point(0, 1, 0))),
160 5667 : _p2(declareRestartableData<Point>("cylinder_axis_point_2", Point(0, 0, 0)))
161 : {
162 374 : _emissivity = _emissivity_primary != 0.0 && _emissivity_secondary != 0.0
163 2263 : ? 1.0 / _emissivity_primary + 1.0 / _emissivity_secondary - 1
164 : : 0.0;
165 :
166 1889 : if (_quadrature)
167 : {
168 2916 : if (!parameters.isParamValid("paired_boundary"))
169 0 : mooseError("No 'paired_boundary' provided for ", _name);
170 :
171 4374 : _penetration_locator = &_subproblem.geomSearchData().getQuadraturePenetrationLocator(
172 : parameters.get<BoundaryName>("paired_boundary"),
173 2916 : getParam<std::vector<BoundaryName>>("boundary")[0],
174 2916 : Utility::string_to_enum<Order>(parameters.get<MooseEnum>("order")));
175 : }
176 : else
177 : {
178 862 : if (!isCoupled("gap_distance"))
179 0 : paramError("gap_distance", "needed if not using quadrature point based gap heat");
180 :
181 862 : if (!isCoupled("gap_temp"))
182 0 : paramError("gap_temp", "needed if not using quadrature point based gap heat");
183 : }
184 :
185 1889 : if (_mesh.uniformRefineLevel() != 0)
186 2 : mooseError("GapConductance does not work with uniform mesh refinement.");
187 1887 : }
188 :
189 : void
190 1881 : GapConductance::initialSetup()
191 : {
192 : ///set generated from the passed in vector of subdomain names
193 : const auto & check_subdomains =
194 1881 : blockRestricted() && !blockIDs().empty() ? blockIDs() : meshBlockIDs();
195 1881 : if (check_subdomains.empty())
196 0 : mooseError("No subdomains found");
197 :
198 : // make sure all subdomains are using the same coordinate system
199 1881 : Moose::CoordinateSystemType coord_system = _fe_problem.getCoordSystem(*check_subdomains.begin());
200 5665 : for (auto subdomain : check_subdomains)
201 3784 : if (_fe_problem.getCoordSystem(subdomain) != coord_system)
202 0 : mooseError(
203 : "The GapConductance model requires all subdomains to have the same coordinate system.");
204 :
205 : // Select proper coordinate system and geometry (plate, cylinder, spheres)
206 1881 : setGapGeometryParameters(
207 1881 : _pars, coord_system, _fe_problem.getAxisymmetricRadialCoord(), _gap_geometry_type, _p1, _p2);
208 1881 : }
209 :
210 : void
211 3872 : GapConductance::setGapGeometryParameters(const InputParameters & params,
212 : const Moose::CoordinateSystemType coord_sys,
213 : unsigned int axisymmetric_radial_coord,
214 : GAP_GEOMETRY & gap_geometry_type,
215 : Point & p1,
216 : Point & p2)
217 : {
218 7744 : if (params.isParamSetByUser("gap_geometry_type"))
219 : {
220 1392 : gap_geometry_type =
221 1392 : GapConductance::GAP_GEOMETRY(int(params.get<MooseEnum>("gap_geometry_type")));
222 : }
223 : else
224 : {
225 2480 : if (coord_sys == Moose::COORD_XYZ)
226 1828 : gap_geometry_type = GapConductance::PLATE;
227 652 : else if (coord_sys == Moose::COORD_RZ)
228 652 : gap_geometry_type = GapConductance::CYLINDER;
229 0 : else if (coord_sys == Moose::COORD_RSPHERICAL)
230 0 : gap_geometry_type = GapConductance::SPHERE;
231 : }
232 :
233 3872 : if (gap_geometry_type == GapConductance::PLATE)
234 : {
235 1964 : if (coord_sys == Moose::COORD_RSPHERICAL)
236 0 : ::mooseError("'gap_geometry_type = PLATE' cannot be used with models having a spherical "
237 : "coordinate system.");
238 : }
239 1908 : else if (gap_geometry_type == GapConductance::CYLINDER)
240 : {
241 1444 : if (coord_sys == Moose::COORD_XYZ)
242 : {
243 1584 : if (!params.isParamValid("cylinder_axis_point_1") ||
244 1584 : !params.isParamValid("cylinder_axis_point_2"))
245 0 : ::mooseError("For 'gap_geometry_type = CYLINDER' to be used with a Cartesian model, "
246 : "'cylinder_axis_point_1' and 'cylinder_axis_point_2' must be specified.");
247 528 : p1 = params.get<RealVectorValue>("cylinder_axis_point_1");
248 528 : p2 = params.get<RealVectorValue>("cylinder_axis_point_2");
249 : }
250 916 : else if (coord_sys == Moose::COORD_RZ)
251 : {
252 1832 : if (params.isParamValid("cylinder_axis_point_1") ||
253 1832 : params.isParamValid("cylinder_axis_point_2"))
254 0 : ::mooseError("The 'cylinder_axis_point_1' and 'cylinder_axis_point_2' cannot be specified "
255 : "with axisymmetric models. The y-axis is used as the cylindrical axis of "
256 : "symmetry.");
257 :
258 916 : if (axisymmetric_radial_coord == 0) // R-Z problem
259 : {
260 872 : p1 = Point(0, 0, 0);
261 872 : p2 = Point(0, 1, 0);
262 : }
263 : else // Z-R problem
264 : {
265 44 : p1 = Point(0, 0, 0);
266 44 : p2 = Point(1, 0, 0);
267 : }
268 : }
269 0 : else if (coord_sys == Moose::COORD_RSPHERICAL)
270 0 : ::mooseError("'gap_geometry_type = CYLINDER' cannot be used with models having a spherical "
271 : "coordinate system.");
272 : }
273 464 : else if (gap_geometry_type == GapConductance::SPHERE)
274 : {
275 464 : if (coord_sys == Moose::COORD_XYZ || coord_sys == Moose::COORD_RZ)
276 : {
277 664 : if (!params.isParamValid("sphere_origin"))
278 0 : ::mooseError("For 'gap_geometry_type = SPHERE' to be used with a Cartesian or axisymmetric "
279 : "model, 'sphere_origin' must be specified.");
280 332 : p1 = params.get<RealVectorValue>("sphere_origin");
281 : }
282 132 : else if (coord_sys == Moose::COORD_RSPHERICAL)
283 : {
284 264 : if (params.isParamValid("sphere_origin"))
285 0 : ::mooseError("The 'sphere_origin' cannot be specified with spherical models. x=0 is used "
286 : "as the spherical origin.");
287 132 : p1 = Point(0, 0, 0);
288 : }
289 : }
290 3872 : }
291 :
292 : void
293 2916093 : GapConductance::computeQpProperties()
294 : {
295 2916093 : computeGapValues();
296 2916093 : computeQpConductance();
297 2916093 : }
298 :
299 : void
300 2916093 : GapConductance::computeQpConductance()
301 : {
302 2916093 : if (_has_info)
303 : {
304 2662292 : _gap_conductance[_qp] = h_conduction() + h_radiation();
305 2662292 : _gap_conductance_dT[_qp] = dh_conduction() + dh_radiation();
306 : }
307 : else
308 : {
309 253801 : _gap_conductance[_qp] = 0;
310 253801 : _gap_conductance_dT[_qp] = 0;
311 : }
312 2916093 : }
313 :
314 : Real
315 2828180 : GapConductance::gapAttenuation(Real adjusted_length, Real min_gap, unsigned int min_gap_order)
316 : {
317 : mooseAssert(min_gap > 0, "min_gap must be larger than zero.");
318 :
319 2828180 : if (adjusted_length > min_gap)
320 2803040 : return 1.0 / adjusted_length;
321 : else
322 25140 : switch (min_gap_order)
323 : {
324 12516 : case 0:
325 12516 : return 1.0 / min_gap;
326 :
327 12624 : case 1:
328 12624 : return 1.0 / min_gap - (adjusted_length - min_gap) / (min_gap * min_gap);
329 :
330 0 : default:
331 0 : ::mooseError("Invalid Taylor expansion order");
332 : }
333 : }
334 :
335 : Real
336 2662292 : GapConductance::h_conduction()
337 : {
338 2662292 : _gap_thermal_conductivity[_qp] = gapK();
339 2662292 : const Real adjusted_length = gapLength(_gap_geometry_type, _radius, _r1, _r2, _max_gap);
340 2662292 : return _gap_thermal_conductivity[_qp] * gapAttenuation(adjusted_length, _min_gap, _min_gap_order);
341 : }
342 :
343 : Real
344 2662292 : GapConductance::dh_conduction()
345 : {
346 2662292 : return 0.0;
347 : }
348 :
349 : Real
350 2662292 : GapConductance::h_radiation()
351 : {
352 : /*
353 : Gap conductance due to radiation is based on the diffusion approximation:
354 :
355 : q12 = sigma*Fe*(T1^4 - T2^4) ~ hr(T1 - T2)
356 : where sigma is the Stefan-Boltzmann constant, Fe is an emissivity
357 : function, T1 and T2 are the temperatures of the two surfaces, and
358 : hr is the radiant gap conductance. Solving for hr,
359 :
360 : hr = sigma*Fe*(T1^4 - T2^4) / (T1 - T2)
361 : which can be factored to give:
362 :
363 : hr = sigma*Fe*(T1^2 + T2^2) * (T1 + T2)
364 :
365 : Assuming the gap is between infinite parallel planes, the emissivity
366 : function is given by:
367 :
368 : Fe = 1 / (1/e1 + 1/e2 - 1)
369 :
370 : For cylinders and spheres, see Fundamentals of Heat and Mass Transfer,
371 : Sixth Edition, John Wiley & Sons, Table 13.3.
372 :
373 : For cylinders:
374 :
375 : Fe = 1 / (1/e1 + (1/e2 - 1) * (r1/r2))
376 :
377 : q21 = -q12 * (r1/r2)
378 :
379 : For spheres:
380 :
381 : Fe = 1 / (1/e1 + (1/e2 - 1) * (r1/r2)^2)
382 :
383 : q21 = -q12 * (r1/r2)^2
384 : */
385 :
386 2662292 : if (_emissivity == 0.0)
387 : return 0.0;
388 :
389 : // We add 'surface_integration_factor' to account for the surface integration of the conductance
390 : // due to radiation.
391 : Real surface_integration_factor = 1.0;
392 :
393 969248 : if (_gap_geometry_type == GapConductance::CYLINDER)
394 : {
395 928774 : _emissivity = 1.0 / _emissivity_primary + (1.0 / _emissivity_secondary - 1) * _r1 / _r2;
396 928774 : if (_r2 == _radius)
397 464387 : surface_integration_factor = _r1 / _r2;
398 : }
399 40474 : else if (_gap_geometry_type == GapConductance::SPHERE)
400 : {
401 34026 : _emissivity =
402 34026 : 1.0 / _emissivity_primary + (1.0 / _emissivity_secondary - 1) * _r1 * _r1 / (_r2 * _r2);
403 34026 : if (_r2 == _radius)
404 11925 : surface_integration_factor = _r1 * _r1 / (_r2 * _r2);
405 : }
406 :
407 : const Real temp_func =
408 969248 : (_temp[_qp] * _temp[_qp] + _gap_temp * _gap_temp) * (_temp[_qp] + _gap_temp);
409 :
410 969248 : return _stefan_boltzmann * temp_func / _emissivity * surface_integration_factor;
411 : }
412 :
413 : Real
414 2662292 : GapConductance::dh_radiation()
415 : {
416 2662292 : if (_emissivity == 0.0)
417 : return 0.0;
418 :
419 : Real surface_integration_factor = 1.0;
420 :
421 969248 : if (_gap_geometry_type == GapConductance::CYLINDER)
422 : {
423 928774 : _emissivity = 1.0 / _emissivity_primary + (1.0 / _emissivity_secondary - 1) * _r1 / _r2;
424 928774 : if (_r2 == _radius)
425 464387 : surface_integration_factor = _r1 / _r2;
426 : }
427 40474 : else if (_gap_geometry_type == GapConductance::SPHERE)
428 : {
429 34026 : _emissivity =
430 34026 : 1.0 / _emissivity_primary + (1.0 / _emissivity_secondary - 1) * _r1 * _r1 / (_r2 * _r2);
431 34026 : if (_r2 == _radius)
432 11925 : surface_integration_factor = _r1 * _r1 / (_r2 * _r2);
433 : }
434 :
435 969248 : const Real temp_func = 3 * _temp[_qp] * _temp[_qp] + _gap_temp * (2 * _temp[_qp] + _gap_temp);
436 :
437 969248 : return _stefan_boltzmann * temp_func / _emissivity * surface_integration_factor;
438 : }
439 :
440 : Real
441 2994068 : GapConductance::gapLength(const GapConductance::GAP_GEOMETRY & gap_geom,
442 : const Real radius,
443 : const Real r1,
444 : const Real r2,
445 : const Real max_gap)
446 : {
447 2994068 : if (gap_geom == GapConductance::CYLINDER)
448 1293979 : return gapCyl(radius, r1, r2, max_gap);
449 1700089 : else if (gap_geom == GapConductance::SPHERE)
450 581240 : return gapSphere(radius, r1, r2, max_gap);
451 : else
452 1118849 : return gapRect(r2 - r1, max_gap);
453 : }
454 :
455 : Real
456 1118849 : GapConductance::gapRect(const Real distance, const Real max_gap)
457 : {
458 1118849 : return std::min(distance, max_gap);
459 : }
460 :
461 : Real
462 1293979 : GapConductance::gapCyl(const Real radius, const Real r1, const Real r2, const Real max_denom)
463 : {
464 1293979 : const Real denominator = radius * std::log(r2 / r1);
465 1293979 : return std::min(denominator, max_denom);
466 : }
467 :
468 : Real
469 581240 : GapConductance::gapSphere(const Real radius, const Real r1, const Real r2, const Real max_denom)
470 : {
471 581240 : const Real denominator = radius * radius * ((1.0 / r1) - (1.0 / r2));
472 581240 : return std::min(denominator, max_denom);
473 : }
474 :
475 : Real
476 2662292 : GapConductance::gapK()
477 : {
478 2662292 : Real gap_conductivity = _gap_conductivity;
479 :
480 2662292 : if (_gap_conductivity_function)
481 : {
482 0 : if (_gap_conductivity_function_variable)
483 0 : gap_conductivity *= _gap_conductivity_function->value(
484 0 : (*_gap_conductivity_function_variable)[_qp], _q_point[_qp]);
485 : else
486 0 : gap_conductivity *= _gap_conductivity_function->value(_t, _q_point[_qp]);
487 : }
488 :
489 2662292 : return gap_conductivity;
490 : }
491 :
492 : void
493 2916093 : GapConductance::computeGapValues()
494 : {
495 2916093 : if (!_quadrature)
496 : {
497 890305 : _has_info = true;
498 890305 : _gap_temp = _gap_temp_value[_qp];
499 890305 : _gap_distance = _gap_distance_value[_qp];
500 : }
501 : else
502 : {
503 2025788 : Node * qnode = _mesh.getQuadratureNode(_current_elem, _current_side, _qp);
504 2025788 : PenetrationInfo * pinfo = _penetration_locator->_penetration_info[qnode->id()];
505 :
506 2025788 : _gap_temp = 0.0;
507 2025788 : _gap_distance = 88888;
508 2025788 : _has_info = false;
509 :
510 2025788 : if (pinfo)
511 : {
512 1771987 : _gap_distance = pinfo->_distance;
513 1771987 : _has_info = true;
514 :
515 1771987 : const Elem * secondary_side = pinfo->_side;
516 : std::vector<std::vector<Real>> & secondary_side_phi = pinfo->_side_phi;
517 : std::vector<dof_id_type> secondary_side_dof_indices;
518 :
519 1771987 : _dof_map->dof_indices(secondary_side, secondary_side_dof_indices, _temp_var->number());
520 :
521 8080843 : for (unsigned int i = 0; i < secondary_side_dof_indices.size(); ++i)
522 : {
523 : // The zero index is because we only have one point that the phis are evaluated at
524 6308856 : _gap_temp +=
525 6308856 : secondary_side_phi[i][0] * (*(*_serialized_solution))(secondary_side_dof_indices[i]);
526 : }
527 1771987 : }
528 : else
529 : {
530 253801 : if (_warnings)
531 0 : mooseWarning("No gap value information found for node ",
532 0 : qnode->id(),
533 : " on processor ",
534 0 : processor_id(),
535 : " at coordinate ",
536 0 : Point(*qnode));
537 : }
538 : }
539 :
540 2916093 : Point current_point(_q_point[_qp]);
541 2916093 : computeGapRadii(
542 2916093 : _gap_geometry_type, current_point, _p1, _p2, _gap_distance, _normals[_qp], _r1, _r2, _radius);
543 2916093 : }
544 :
545 : void
546 23243853 : GapConductance::computeGapRadii(const GapConductance::GAP_GEOMETRY gap_geometry_type,
547 : const Point & current_point,
548 : const Point & p1,
549 : const Point & p2,
550 : const Real & gap_distance,
551 : const Point & current_normal,
552 : Real & r1,
553 : Real & r2,
554 : Real & radius)
555 : {
556 23243853 : if (gap_geometry_type == GapConductance::CYLINDER)
557 : {
558 : // The vector _p1 + t*(_p2-_p1) defines the cylindrical axis. The point along this
559 : // axis closest to current_point is found by the following for t:
560 : const Point p2p1(p2 - p1);
561 : const Point p1pc(p1 - current_point);
562 7585150 : const Real t = -(p1pc * p2p1) / p2p1.norm_sq();
563 :
564 : // The nearest point on the cylindrical axis to current_point is p.
565 : const Point p(p1 + t * p2p1);
566 : Point rad_vec(current_point - p);
567 7585150 : Real rad = rad_vec.norm();
568 : rad_vec /= rad;
569 : Real rad_dot_norm = rad_vec * current_normal;
570 :
571 7585150 : if (rad_dot_norm > 0)
572 : {
573 4012951 : r1 = rad;
574 4012951 : r2 = rad - gap_distance; // note, gap_distance is negative
575 4012951 : radius = r1;
576 : }
577 3572199 : else if (rad_dot_norm < 0)
578 : {
579 3572199 : r1 = rad + gap_distance;
580 3572199 : r2 = rad;
581 3572199 : radius = r2;
582 : }
583 : else
584 0 : ::mooseError("Issue with cylindrical flux calc. normals.\n");
585 : }
586 15658703 : else if (gap_geometry_type == GapConductance::SPHERE)
587 : {
588 : const Point origin_to_curr_point(current_point - p1);
589 : const Real normal_dot = origin_to_curr_point * current_normal;
590 5640552 : const Real curr_point_radius = origin_to_curr_point.norm();
591 5640552 : if (normal_dot > 0) // on inside surface
592 : {
593 5058565 : r1 = curr_point_radius;
594 5058565 : r2 = curr_point_radius - gap_distance; // gap_distance is negative
595 5058565 : radius = r1;
596 : }
597 581987 : else if (normal_dot < 0) // on outside surface
598 : {
599 581987 : r1 = curr_point_radius + gap_distance; // gap_distance is negative
600 581987 : r2 = curr_point_radius;
601 581987 : radius = r2;
602 : }
603 : else
604 0 : ::mooseError("Issue with spherical flux calc. normals. \n");
605 : }
606 : else
607 : {
608 10018151 : r2 = -gap_distance;
609 10018151 : r1 = 0;
610 10018151 : radius = 0;
611 : }
612 23243853 : }
|