https://mooseframework.inl.gov
Loading...
Searching...
No Matches
SCMFrictionUpdatedChengTodreas.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
11
13
16{
18 params.addClassDescription("Class that computes the axial friction factor using the updated "
19 "Cheng Todreas correlations.");
20 return params;
21}
22
24 : SCMFrictionClosureBase(parameters),
25 _is_tri_lattice(dynamic_cast<const TriSubChannelMesh *>(&_subchannel_mesh) != nullptr),
26 _tri_sch_mesh(dynamic_cast<const TriSubChannelMesh *>(&_subchannel_mesh)),
27 _quad_sch_mesh(dynamic_cast<const QuadSubChannelMesh *>(&_subchannel_mesh)),
28 _has_wire_wrap(_is_tri_lattice && _tri_sch_mesh->getWireDiameter() != 0.0 &&
29 _tri_sch_mesh->getWireLeadLength() != 0.0)
30{
31 if (_is_tri_lattice &&
33 mooseError("Wire-wrapped bundle friction requires both wire diameter and wire lead length. "
34 "Set both to zero for a bare pin bundle.");
35
37 {
38 const auto pitch = _subchannel_mesh.getPitch();
39 const auto pin_diameter = _subchannel_mesh.getPinDiameter();
40 const auto p_over_d = pitch / pin_diameter;
41 const auto wire_lead_to_diameter = _tri_sch_mesh->getWireLeadLength() / pin_diameter;
42 const unsigned int Nr = _tri_sch_mesh->getNumOfRings();
43 const unsigned int num_pins = 1 + 3 * Nr * (Nr - 1);
44
45 // The updated Cheng-Todreas detailed triangular friction factor correlation is based on
46 // data spanning 1.0 <= P/D <= 1.42, 4 <= H/D <= 52, 7 <= Npin <= 271,
47 // and 50 <= Re <= 1e6.
48 if (p_over_d < 1.0 || p_over_d > 1.42)
49 flagSolutionWarning("Pitch-over-pin diameter ratio (P/D) outside the updated "
50 "Cheng-Todreas friction correlation data range.");
51 if (_has_wire_wrap && (wire_lead_to_diameter < 8.0 || wire_lead_to_diameter > 52.0))
52 flagSolutionWarning("Wire lead length-over-pin diameter ratio (H/D) outside the updated "
53 "Cheng-Todreas friction correlation data range.");
54 if (num_pins < 7 || num_pins > 271)
55 flagSolutionWarning("Number of pins outside the updated Cheng-Todreas friction correlation "
56 "data range.");
57 }
58}
59
60Real
62{
64 return computeTriLatticeFrictionFactor(friction_args);
65 else
66 return computeQuadLatticeFrictionFactor(friction_args);
67}
68
69Real
71 const FrictionStruct & friction_args) const
72{
73 const auto Re = friction_args.Re;
74 const auto i_ch = friction_args.i_ch;
75 const auto S = friction_args.S;
76 const auto w_perim = friction_args.w_perim;
77 const auto Dh_i = 4.0 * S / w_perim;
78 Real aL, b1L, b2L, cL;
79 Real aT, b1T, b2T, cT;
80 const Real & pitch = _subchannel_mesh.getPitch();
81 const Real & pin_diameter = _subchannel_mesh.getPinDiameter();
82 const Real & wire_lead_length = _tri_sch_mesh->getWireLeadLength();
83 const Real & wire_diameter = _tri_sch_mesh->getWireDiameter();
84 const auto p_over_d = pitch / pin_diameter;
85 const auto subch_type = _subchannel_mesh.getSubchannelType(i_ch);
86 // This gap is a constant value for the whole assembly. Might want to make it
87 // subchannel specific in the future if we have duct deformation.
88 const auto gap = _tri_sch_mesh->getDuctToPinGap();
89 const auto w_over_d = (pin_diameter + gap) / pin_diameter;
90
91 if (Re < 50.0 || Re > 1.0e6)
92 flagSolutionWarning("Reynolds number (Re) outside the updated Cheng-Todreas friction "
93 "correlation data range.");
94
95 const auto ReL = std::pow(10, (p_over_d - 1)) * 320.0;
96 const auto ReT = std::pow(10, 0.7 * (p_over_d - 1)) * 1.0E+4;
97 const auto psi = std::log(Re / ReL) / std::log(ReT / ReL);
98
99 // Find the coefficients of bare Pin bundle friction factor
100 // correlations for turbulent and laminar flow regimes. Todreas & Kazimi, Nuclear Systems
101 // second edition, Volume 1, Chapter 9.6
102 if (subch_type == EChannelType::CENTER)
103 {
104 if (p_over_d < 1.1)
105 {
106 aL = 26.0;
107 b1L = 888.2;
108 b2L = -3334.0;
109 aT = 0.09378;
110 b1T = 1.398;
111 b2T = -8.664;
112 }
113 else
114 {
115 aL = 62.97;
116 b1L = 216.9;
117 b2L = -190.2;
118 aT = 0.1458;
119 b1T = 0.03632;
120 b2T = -0.03333;
121 }
122 // laminar flow friction factor for bare Pin bundle - Center subchannel
123 cL = aL + b1L * (p_over_d - 1) + b2L * Utility::pow<2>((p_over_d - 1));
124 // turbulent flow friction factor for bare Pin bundle - Center subchannel
125 cT = aT + b1T * (p_over_d - 1) + b2T * Utility::pow<2>((p_over_d - 1));
126 }
127 else if (subch_type == EChannelType::EDGE)
128 {
129 if (w_over_d < 1.1)
130 {
131 aL = 26.18;
132 b1L = 554.5;
133 b2L = -1480.0;
134 aT = 0.09377;
135 b1T = 0.8732;
136 b2T = -3.341;
137 }
138 else
139 {
140 aL = 44.4;
141 b1L = 256.7;
142 b2L = -267.6;
143 aT = 0.1430;
144 b1T = 0.04199;
145 b2T = -0.04428;
146 }
147 // laminar flow friction factor for bare Pin bundle - Edge subchannel
148 cL = aL + b1L * (w_over_d - 1) + b2L * Utility::pow<2>((w_over_d - 1));
149 // turbulent flow friction factor for bare Pin bundle - Edge subchannel
150 cT = aT + b1T * (w_over_d - 1) + b2T * Utility::pow<2>((w_over_d - 1));
151 }
152 else
153 {
154 if (w_over_d < 1.1)
155 {
156 aL = 26.98;
157 b1L = 1636.0;
158 b2L = -10050.0;
159 aT = 0.1004;
160 b1T = 1.625;
161 b2T = -11.85;
162 }
163 else
164 {
165 aL = 87.26;
166 b1L = 38.59;
167 b2L = -55.12;
168 aT = 0.1499;
169 b1T = 0.006706;
170 b2T = -0.009567;
171 }
172 // laminar flow friction factor for bare Pin bundle - Corner subchannel
173 cL = aL + b1L * (w_over_d - 1) + b2L * Utility::pow<2>((w_over_d - 1));
174 // turbulent flow friction factor for bare Pin bundle - Corner subchannel
175 cT = aT + b1T * (w_over_d - 1) + b2T * Utility::pow<2>((w_over_d - 1));
176 }
177
178 // Find the coefficients of wire-wrapped Pin bundle friction factor
179 // correlations for turbulent and laminar flow regimes. Todreas & Kazimi, Nuclear Systems
180 // Volume 1 Chapter 9-6 also Chen and Todreas (2018).
181 if (_has_wire_wrap)
182 {
183 const auto theta =
184 std::acos(wire_lead_length /
185 std::sqrt(Utility::pow<2>(wire_lead_length) +
186 Utility::pow<2>(libMesh::pi * (pin_diameter + wire_diameter))));
187 const auto wd_t = (19.56 - 98.71 * (wire_diameter / pin_diameter) +
188 303.47 * Utility::pow<2>((wire_diameter / pin_diameter))) *
189 std::pow((wire_lead_length / pin_diameter), -0.541);
190 const auto wd_l = 1.4 * wd_t;
191 const auto ws_t = -11.0 * std::log(wire_lead_length / pin_diameter) + 19.0;
192 const auto ws_l = ws_t;
193 Real ar = 0.0;
194 Real a_p = 0.0;
195
196 if (subch_type == EChannelType::CENTER)
197 {
198 // wetted perimeter for center subchannel and bare Pin bundle
199 const Real pw_p = libMesh::pi * pin_diameter / 2.0;
200 // wire projected area - center subchannel wire-wrapped bundle
201 ar = libMesh::pi * (pin_diameter + wire_diameter) * wire_diameter / 6.0;
202 // bare Pin bundle center subchannel flow area (normal area + wire area)
203 a_p = S + libMesh::pi * Utility::pow<2>(wire_diameter) / 8.0 / std::cos(theta);
204 // turbulent friction factor equation constant - Center subchannel
205 cT *= (pw_p / w_perim);
206 cT += wd_t * (3.0 * ar / a_p) * (Dh_i / wire_lead_length) *
207 std::pow((Dh_i / wire_diameter), 0.18);
208 // laminar friction factor equation constant - Center subchannel
209 cL *= (pw_p / w_perim);
210 cL += wd_l * (3.0 * ar / a_p) * (Dh_i / wire_lead_length) * (Dh_i / wire_diameter);
211 }
212 else if (subch_type == EChannelType::EDGE)
213 {
214 // wire projected area - edge subchannel wire-wrapped bundle
215 ar = libMesh::pi * (pin_diameter + wire_diameter) * wire_diameter / 4.0;
216 // bare Pin bundle edge subchannel flow area (normal area + wire area)
217 a_p = S + libMesh::pi * Utility::pow<2>(wire_diameter) / 8.0 / std::cos(theta);
218 // turbulent friction factor equation constant - Edge subchannel
219 const Real turbulent_wire_correction =
220 1 + ws_t * (ar / a_p) * Utility::pow<2>(std::tan(theta));
221 if (!std::isfinite(turbulent_wire_correction) || turbulent_wire_correction < 0.0)
222 mooseError("The exponentiated term in the Cheng-Todreas turbulent wire correction must be "
223 "non-negative and finite for an edge subchannel. Computed ",
224 turbulent_wire_correction,
225 ".");
226 cT *= std::pow(turbulent_wire_correction, 1.41);
227 // laminar friction factor equation constant - Edge subchannel
228 cL *= (1 + ws_l * (ar / a_p) * Utility::pow<2>(std::tan(theta)));
229 }
230 else
231 {
232 // wire projected area - corner subchannel wire-wrapped bundle
233 ar = libMesh::pi * (pin_diameter + wire_diameter) * wire_diameter / 6.0;
234 // bare Pin bundle corner subchannel flow area (normal area + wire area)
235 a_p = S + libMesh::pi * Utility::pow<2>(wire_diameter) / 24.0 / std::cos(theta);
236 // turbulent friction factor equation constant - Corner subchannel
237 const Real turbulent_wire_correction =
238 1 + ws_t * (ar / a_p) * Utility::pow<2>(std::tan(theta));
239 if (!std::isfinite(turbulent_wire_correction) || turbulent_wire_correction < 0.0)
240 mooseError("The exponentiated term in the Cheng-Todreas turbulent wire correction must be "
241 "non-negative and finite for a corner subchannel. Computed ",
242 turbulent_wire_correction,
243 ".");
244 cT *= std::pow(turbulent_wire_correction, 1.41);
245 // laminar friction factor equation constant - Corner subchannel
246 cL *= (1 + ws_l * (ar / a_p) * Utility::pow<2>(std::tan(theta)));
247 }
248 }
249 // laminar friction factor and turbulent friction factor coefficients
250 const Real bL = -1.0;
251 const Real bT = -0.18;
252 auto fL = cL * std::pow(Re, bL);
253 auto fT = cT * std::pow(Re, bT);
254
255 if (Re < ReL)
256 {
257 // laminar flow
258 return fL;
259 }
260 else if (Re > ReT)
261 {
262 // turbulent flow
263 return fT;
264 }
265 else
266 {
267 // transient flow: psi definition uses a Bulk ReT/ReL number, same for all channels
268 return fL * std::pow((1 - psi), 1.0 / 3.0) * (1 - std::pow(psi, 7)) +
269 fT * std::pow(psi, 1.0 / 3.0);
270 }
271}
272
273Real
275 const FrictionStruct & friction_args) const
276{
277 const auto Re = friction_args.Re;
278 const auto i_ch = friction_args.i_ch;
280 Real aL, b1L, b2L, cL;
281 Real aT, b1T, b2T, cT;
282 const auto pitch = _subchannel_mesh.getPitch();
283 const auto pin_diameter = _subchannel_mesh.getPinDiameter();
284 // This gap is a constant value for the whole assembly. Might want to make it
285 // subchannel specific in the future if we have duct deformation.
286 const auto side_gap = _quad_sch_mesh->getSideGap();
287 const auto w = (pin_diameter / 2.0) + (pitch / 2.0) + side_gap;
288 const auto p_over_d = pitch / pin_diameter;
289 const auto w_over_d = w / pin_diameter;
290 const auto ReL = std::pow(10, (p_over_d - 1)) * 320.0;
291 const auto ReT = std::pow(10, 0.7 * (p_over_d - 1)) * 1.0E+4;
292 const auto psi = std::log(Re / ReL) / std::log(ReT / ReL);
293 const auto subch_type = _subchannel_mesh.getSubchannelType(i_ch);
294
295 // Find the coefficients of bare Pin bundle friction factor
296 // correlations for turbulent and laminar flow regimes. Todreas & Kazimi, Nuclear Systems Volume
297 // 1
298 if (subch_type == EChannelType::CENTER)
299 {
300 if (p_over_d < 1.1)
301 {
302 aL = 26.37;
303 b1L = 374.2;
304 b2L = -493.9;
305 aT = 0.09423;
306 b1T = 0.5806;
307 b2T = -1.239;
308 }
309 else
310 {
311 aL = 35.55;
312 b1L = 263.7;
313 b2L = -190.2;
314 aT = 0.1339;
315 b1T = 0.09059;
316 b2T = -0.09926;
317 }
318 // laminar flow friction factor for bare Pin bundle - Center subchannel
319 cL = aL + b1L * (p_over_d - 1) + b2L * Utility::pow<2>((p_over_d - 1));
320 // turbulent flow friction factor for bare Pin bundle - Center subchannel
321 cT = aT + b1T * (p_over_d - 1) + b2T * Utility::pow<2>((p_over_d - 1));
322 }
323 else if (subch_type == EChannelType::EDGE)
324 {
325 if (p_over_d < 1.1)
326 {
327 aL = 26.18;
328 b1L = 554.5;
329 b2L = -1480;
330 aT = 0.09377;
331 b1T = 0.8732;
332 b2T = -3.341;
333 }
334 else
335 {
336 aL = 44.40;
337 b1L = 256.7;
338 b2L = -267.6;
339 aT = 0.1430;
340 b1T = 0.04199;
341 b2T = -0.04428;
342 }
343 // laminar flow friction factor for bare Pin bundle - Edge subchannel
344 cL = aL + b1L * (w_over_d - 1) + b2L * Utility::pow<2>((w_over_d - 1));
345 // turbulent flow friction factor for bare Pin bundle - Edge subchannel
346 cT = aT + b1T * (w_over_d - 1) + b2T * Utility::pow<2>((w_over_d - 1));
347 }
348 else
349 {
350 if (p_over_d < 1.1)
351 {
352 aL = 28.62;
353 b1L = 715.9;
354 b2L = -2807;
355 aT = 0.09755;
356 b1T = 1.127;
357 b2T = -6.304;
358 }
359 else
360 {
361 aL = 58.83;
362 b1L = 160.7;
363 b2L = -203.5;
364 aT = 0.1452;
365 b1T = 0.02681;
366 b2T = -0.03411;
367 }
368 // laminar flow friction factor for bare Pin bundle - Corner subchannel
369 cL = aL + b1L * (w_over_d - 1) + b2L * Utility::pow<2>((w_over_d - 1));
370 // turbulent flow friction factor for bare Pin bundle - Corner subchannel
371 cT = aT + b1T * (w_over_d - 1) + b2T * Utility::pow<2>((w_over_d - 1));
372 }
373 // laminar friction factor and turbulent friction factor coefficients
374 const Real bL = -1.0;
375 const Real bT = -0.18;
376 auto fL = cL * std::pow(Re, bL);
377 auto fT = cT * std::pow(Re, bT);
378
379 if (Re < ReL)
380 {
381 // laminar flow
382 return fL;
383 }
384 else if (Re > ReT)
385 {
386 // turbulent flow
387 return fT;
388 }
389 else
390 {
391 // transient flow: psi definition uses a Bulk ReT/ReL number, same for all channels
392 return fL * std::pow((1 - psi), 1.0 / 3.0) * (1 - std::pow(psi, 7)) +
393 fT * std::pow(psi, 1.0 / 3.0);
394 }
395}
const double Re
registerMooseObject("SubChannelApp", SCMFrictionUpdatedChengTodreas)
void addClassDescription(const std::string &doc_string)
void mooseError(Args &&... args) const
Creates the mesh of subchannels in a quadrilateral lattice.
const Real & getSideGap() const
Returns the side gap, not to be confused with the gap between pins, this refers to the gap next to th...
const SubChannelMesh & _subchannel_mesh
Reference to the subchannel mesh.
Base class for friction closures used in SCM.
static InputParameters validParams()
Class that calculates the friction factor based on the updated Cheng & Todreas correlations (Cheng et...
Real computeQuadLatticeFrictionFactor(const FrictionStruct &friction_info) const
Real computeTriLatticeFrictionFactor(const FrictionStruct &friction_info) const
const QuadSubChannelMesh *const _quad_sch_mesh
Pointer to the quad lattice mesh.
virtual Real computeFrictionFactor(const FrictionStruct &friction_info) const override
Computes the friction factor for the local conditions.
bool _is_tri_lattice
Keep track of the lattice type.
const TriSubChannelMesh *const _tri_sch_mesh
Pointer to the tri lattice mesh.
const bool _has_wire_wrap
Whether the triangular assembly has wire-wrap geometry.
SCMFrictionUpdatedChengTodreas(const InputParameters &parameters)
virtual const Real & getPitch() const
Return the undeformed pitch between 2 subchannels.
virtual EChannelType getSubchannelType(unsigned int index) const =0
Return the type of the subchannel for given subchannel index.
virtual const Real & getPinDiameter() const
Return undeformed Pin diameter.
Mesh class for triangular, edge and corner subchannels for hexagonal lattice fuel assemblies.
const Real & getWireDiameter() const
Return wire diameter.
const Real & getDuctToPinGap() const
Return the the gap thickness between the duct and peripheral fuel pins.
const Real & getWireLeadLength() const
Return the wire lead length.
const unsigned int & getNumOfRings() const
Return the number of fuel-pin rings, counting the center pin as the first ring.
const Real pi
structure with the needed information to compute the friction factor at a specific subchannel cell