14 #include "MooseMesh.h"
15 #include "MooseVariable.h"
16 #include "PenetrationLocator.h"
17 #include "SystemBase.h"
18 #include "AddVariableAction.h"
20 #include "libmesh/string_to_enum.h"
32 params.addRequiredCoupledVar(
"variable",
"Temperature variable");
35 params.addCoupledVar(
"gap_distance",
"Distance across the gap");
36 params.addCoupledVar(
"gap_temp",
"Temperature on the other side of the gap");
37 params.addParam<Real>(
"gap_conductivity", 1.0,
"The thermal conductivity of the gap material");
38 params.addParam<FunctionName>(
39 "gap_conductivity_function",
40 "Thermal conductivity of the gap material as a function. Multiplied by gap_conductivity.");
41 params.addCoupledVar(
"gap_conductivity_function_variable",
42 "Variable to be used in the gap_conductivity_function in place of time");
45 params.addParam<
bool>(
"quadrature",
47 "Whether or not to do quadrature point based gap heat "
48 "transfer. If this is true then gap_distance and "
49 "gap_temp should NOT be provided (and will be "
50 "ignored); however, paired_boundary and variable are "
52 params.addParam<BoundaryName>(
"paired_boundary",
"The boundary to be penetrated");
54 params.addParam<Real>(
"stefan_boltzmann", 5.669e-8,
"The Stefan-Boltzmann constant");
56 params.addParam<
bool>(
"use_displaced_mesh",
58 "Whether or not this object should use the "
59 "displaced mesh for computation. Note that in "
60 "the case this is true but no displacements "
61 "are provided in the Mesh block the "
62 "undisplaced mesh will still be used.");
64 params.addParam<
bool>(
65 "warnings",
false,
"Whether to output warning messages concerning nodes not being found");
67 MooseEnum orders(AddVariableAction::getNonlinearVariableOrders());
68 params.addParam<MooseEnum>(
"order", orders,
"The finite element order");
76 InputParameters params = emptyInputParameters();
77 params.addParam<std::string>(
78 "appended_property_name",
"",
"Name appended to material properties to make them unique");
79 MooseEnum gap_geom_types(
"PLATE CYLINDER SPHERE");
80 params.addParam<MooseEnum>(
"gap_geometry_type", gap_geom_types,
"Gap calculation type.");
82 params.addParam<RealVectorValue>(
"cylinder_axis_point_1",
83 "Start point for line defining cylindrical axis");
84 params.addParam<RealVectorValue>(
"cylinder_axis_point_2",
85 "End point for line defining cylindrical axis");
86 params.addParam<RealVectorValue>(
"sphere_origin",
"Origin for sphere geometry");
88 params.addRangeCheckedParam<Real>(
"emissivity_1",
90 "emissivity_1>=0 & emissivity_1<=1",
91 "The emissivity of the fuel surface");
92 params.addRangeCheckedParam<Real>(
"emissivity_2",
94 "emissivity_2>=0 & emissivity_2<=1",
95 "The emissivity of the cladding surface");
98 params.addRangeCheckedParam<Real>(
99 "min_gap", 1e-6,
"min_gap>0",
"A minimum gap (denominator) size");
100 params.addRangeCheckedParam<Real>(
101 "max_gap", 1e6,
"max_gap>=0",
"A maximum gap (denominator) size");
102 params.addRangeCheckedParam<
unsigned int>(
103 "min_gap_order", 0,
"min_gap_order<=1",
"Order of the Taylor expansion below min_gap");
109 : Material(parameters),
110 _appended_property_name(getParam<std::string>(
"appended_property_name")),
111 _temp(coupledValue(
"variable")),
114 _quadrature(getParam<bool>(
"quadrature")),
116 _gap_distance(88888),
121 _gap_distance_value(_quadrature ? _zero : coupledValue(
"gap_distance")),
122 _gap_temp_value(_quadrature ? _zero : coupledValue(
"gap_temp")),
123 _gap_conductance(declareProperty<Real>(
"gap_conductance" + _appended_property_name)),
124 _gap_conductance_dT(declareProperty<Real>(
"gap_conductance" + _appended_property_name +
"_dT")),
125 _gap_thermal_conductivity(declareProperty<Real>(
"gap_conductivity")),
126 _gap_conductivity(getParam<Real>(
"gap_conductivity")),
127 _gap_conductivity_function(isParamValid(
"gap_conductivity_function")
128 ? &getFunction(
"gap_conductivity_function")
130 _gap_conductivity_function_variable(isCoupled(
"gap_conductivity_function_variable")
131 ? &coupledValue(
"gap_conductivity_function_variable")
133 _stefan_boltzmann(getParam<Real>(
"stefan_boltzmann")),
134 _emissivity(getParam<Real>(
"emissivity_1") != 0.0 && getParam<Real>(
"emissivity_2") != 0.0
135 ? 1.0 / getParam<Real>(
"emissivity_1") + 1.0 / getParam<Real>(
"emissivity_2") -
138 _min_gap(getParam<Real>(
"min_gap")),
139 _min_gap_order(getParam<unsigned int>(
"min_gap_order")),
140 _max_gap(getParam<Real>(
"max_gap")),
141 _temp_var(_quadrature ? getVar(
"variable", 0) : NULL),
142 _penetration_locator(NULL),
143 _serialized_solution(_quadrature ? &_temp_var->sys().currentSolution() : NULL),
144 _dof_map(_quadrature ? &_temp_var->sys().dofMap() : NULL),
145 _warnings(getParam<bool>(
"warnings")),
146 _p1(declareRestartableData<Point>(
"cylinder_axis_point_1", Point(0, 1, 0))),
147 _p2(declareRestartableData<Point>(
"cylinder_axis_point_2", Point(0, 0, 0)))
151 if (!parameters.isParamValid(
"paired_boundary"))
152 mooseError(std::string(
"No 'paired_boundary' provided for ") + _name);
156 if (!isCoupled(
"gap_distance"))
157 mooseError(std::string(
"No 'gap_distance' provided for ") + _name);
159 if (!isCoupled(
"gap_temp"))
160 mooseError(std::string(
"No 'gap_temp' provided for ") + _name);
166 parameters.get<BoundaryName>(
"paired_boundary"),
167 getParam<std::vector<BoundaryName>>(
"boundary")[0],
168 Utility::string_to_enum<Order>(parameters.get<MooseEnum>(
"order")));
171 if (_mesh.uniformRefineLevel() != 0)
172 mooseError(
"GapConductance does not work with uniform mesh refinement.");
184 const Moose::CoordinateSystemType coord_sys,
185 unsigned int axisymmetric_radial_coord,
190 if (params.isParamSetByUser(
"gap_geometry_type"))
197 if (coord_sys == Moose::COORD_XYZ)
199 else if (coord_sys == Moose::COORD_RZ)
201 else if (coord_sys == Moose::COORD_RSPHERICAL)
207 if (coord_sys == Moose::COORD_RSPHERICAL)
208 ::mooseError(
"'gap_geometry_type = PLATE' cannot be used with models having a spherical "
209 "coordinate system.");
213 if (coord_sys == Moose::COORD_XYZ)
215 if (!params.isParamValid(
"cylinder_axis_point_1") ||
216 !params.isParamValid(
"cylinder_axis_point_2"))
217 ::mooseError(
"For 'gap_geometry_type = CYLINDER' to be used with a Cartesian model, "
218 "'cylinder_axis_point_1' and 'cylinder_axis_point_2' must be specified.");
219 p1 = params.get<RealVectorValue>(
"cylinder_axis_point_1");
220 p2 = params.get<RealVectorValue>(
"cylinder_axis_point_2");
222 else if (coord_sys == Moose::COORD_RZ)
224 if (params.isParamValid(
"cylinder_axis_point_1") ||
225 params.isParamValid(
"cylinder_axis_point_2"))
226 ::mooseError(
"The 'cylinder_axis_point_1' and 'cylinder_axis_point_2' cannot be specified "
227 "with axisymmetric models. The y-axis is used as the cylindrical axis of "
230 if (axisymmetric_radial_coord == 0)
241 else if (coord_sys == Moose::COORD_RSPHERICAL)
242 ::mooseError(
"'gap_geometry_type = CYLINDER' cannot be used with models having a spherical "
243 "coordinate system.");
247 if (coord_sys == Moose::COORD_XYZ || coord_sys == Moose::COORD_RZ)
249 if (!params.isParamValid(
"sphere_origin"))
250 ::mooseError(
"For 'gap_geometry_type = SPHERE' to be used with a Cartesian or axisymmetric "
251 "model, 'sphere_origin' must be specified.");
252 p1 = params.get<RealVectorValue>(
"sphere_origin");
254 else if (coord_sys == Moose::COORD_RSPHERICAL)
256 if (params.isParamValid(
"sphere_origin"))
257 ::mooseError(
"The 'sphere_origin' cannot be specified with spherical models. x=0 is used "
258 "as the spherical origin.");
289 mooseAssert(min_gap > 0,
"min_gap must be larger than zero.");
291 if (adjusted_length > min_gap)
292 return 1.0 / adjusted_length;
294 switch (min_gap_order)
297 return 1.0 / min_gap;
300 return 1.0 / min_gap - (adjusted_length - min_gap) / (min_gap * min_gap);
303 ::mooseError(
"Invalid Taylor expansion order");
345 const Real temp_func =
365 return gapCyl(radius, r1, r2, max_gap);
367 return gapSphere(radius, r1, r2, max_gap);
369 return gapRect(r2 - r1, max_gap);
375 return std::min(distance, max_gap);
381 const Real denominator = radius * std::log(r2 / r1);
382 return std::min(denominator, max_denom);
388 const Real denominator = radius * radius * ((1.0 / r1) - (1.0 / r2));
389 return std::min(denominator, max_denom);
406 return gap_conductivity;
420 Node * qnode = _mesh.getQuadratureNode(_current_elem, _current_side, _qp);
432 const Elem * slave_side = pinfo->_side;
433 std::vector<std::vector<Real>> & slave_side_phi = pinfo->_side_phi;
434 std::vector<dof_id_type> slave_side_dof_indices;
438 for (
unsigned int i = 0; i < slave_side_dof_indices.size(); ++i)
441 _gap_temp += slave_side_phi[i][0] * (*(*_serialized_solution))(slave_side_dof_indices[i]);
447 mooseWarning(
"No gap value information found for node ",
456 Point current_point(_q_point[_qp]);
463 const Point & current_point,
466 const Real & gap_distance,
467 const Point & current_normal,
476 const Point p2p1(p2 - p1);
477 const Point p1pc(p1 - current_point);
478 const Real t = -(p1pc * p2p1) / p2p1.norm_sq();
481 const Point p(p1 + t * p2p1);
482 Point rad_vec(current_point - p);
483 Real rad = rad_vec.norm();
485 Real rad_dot_norm = rad_vec * current_normal;
487 if (rad_dot_norm > 0)
490 r2 = rad - gap_distance;
493 else if (rad_dot_norm < 0)
495 r1 = rad + gap_distance;
500 ::mooseError(
"Issue with cylindrical flux calc. normals.\n");
504 const Point origin_to_curr_point(current_point - p1);
505 const Real normal_dot = origin_to_curr_point * current_normal;
506 const Real curr_point_radius = origin_to_curr_point.norm();
509 r1 = curr_point_radius;
510 r2 = curr_point_radius - gap_distance;
513 else if (normal_dot < 0)
515 r1 = curr_point_radius + gap_distance;
516 r2 = curr_point_radius;
520 ::mooseError(
"Issue with spherical flux calc. normals. \n");