https://mooseframework.inl.gov
Loading...
Searching...
No Matches
SCMFrictionUpgradedChengTodreas.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 upgraded "
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 const auto Reb = _scm_problem.getBulkReynoldsNumber();
45
46 // The upgraded Cheng-Todreas detailed triangular friction factor correlation is based on
47 // data spanning 1.0 <= P/D <= 1.42, 4 <= H/D <= 52, 7 <= Npin <= 217,
48 // and 50 <= Re <= 1e6.
49 if (p_over_d < 1.0 || p_over_d > 1.42)
50 flagSolutionWarning("Pitch-over-pin diameter ratio (P/D) outside the upgraded "
51 "Cheng-Todreas friction correlation data range.");
52 if (_has_wire_wrap && (wire_lead_to_diameter < 8.0 || wire_lead_to_diameter > 52.0))
53 flagSolutionWarning("Wire lead length-over-pin diameter ratio (H/D) outside the upgraded "
54 "Cheng-Todreas friction correlation data range.");
55 if (num_pins < 7 || num_pins > 271)
56 flagSolutionWarning("Number of pins outside the upgraded Cheng-Todreas friction correlation "
57 "data range.");
58 if (Reb < 50.0 || Reb > 1.0e6)
59 flagSolutionWarning("Bulk Reynolds number (Reb) outside the upgraded Cheng-Todreas friction "
60 "correlation data range.");
61 }
62}
63
64Real
66{
68 return computeTriLatticeFrictionFactor(friction_args);
69 else
70 return computeQuadLatticeFrictionFactor(friction_args);
71}
72
73Real
75 const FrictionStruct & friction_args) const
76{
77 const auto Re = friction_args.Re;
78 // Limit the Reynolds number used in the friction-factor correlation to avoid
79 // singular behavior at zero flow.
80 const Real Re_eff = std::max(Re, 1.0);
81 const auto i_ch = friction_args.i_ch;
82 const auto S = friction_args.S;
83 const auto w_perim = friction_args.w_perim;
84 const auto Dh_i = 4.0 * S / w_perim;
85 // Bare fuel Pins coefficients, and friction factor
86 Real k1L, k2L, k3L, CfL;
87 Real k1T, k2T, k3T, CfT;
88 // Transient range parameters
89 Real CbL1, CbL2, CbT1, CbT2;
90 // Ratio of laminar over turbulent drag and sweep coefficients
91 Real CwL1, CwL2;
92 // interpolation exponent
93 Real lambda;
94 // transition smoothing coefficient
95 Real gamma;
96 const Real & pitch = _subchannel_mesh.getPitch();
97 const Real & pin_diameter = _subchannel_mesh.getPinDiameter();
98 const Real & wire_lead_length = _tri_sch_mesh->getWireLeadLength();
99 const Real & wire_diameter = _tri_sch_mesh->getWireDiameter();
100 const auto gap = _tri_sch_mesh->getDuctToPinGap();
101 const auto p_over_d = pitch / pin_diameter;
102 const auto w_over_d = (pin_diameter + gap) / pin_diameter;
103 const auto subch_type = _subchannel_mesh.getSubchannelType(i_ch);
104 CbL1 = 320;
105 CbL2 = 1.0;
106 CbT1 = 10000;
107 CbT2 = 0.7;
108 const auto ReL = std::pow(10, CbL2 * (p_over_d - 1)) * CbL1;
109 const auto ReT = std::pow(10, CbT2 * (p_over_d - 1)) * CbT1;
110 const auto Reb = _scm_problem.getBulkReynoldsNumber();
111 const auto psi = std::log(Reb / ReL) / std::log(ReT / ReL);
112
113 // Find the coefficients of bare Pin bundle friction factor
114 // correlations for turbulent and laminar flow regimes. Todreas & Kazimi, Nuclear Systems
115 // second edition, Volume 1, Chapter 9.6
116 if (subch_type == EChannelType::CENTER)
117 {
118 if (p_over_d < 1.1)
119 {
120 k1L = 26.0;
121 k2L = 888.2;
122 k3L = -3334.0;
123 k1T = 0.09378;
124 k2T = 1.398;
125 k3T = -8.664;
126 }
127 else
128 {
129 k1L = 62.97;
130 k2L = 216.9;
131 k3L = -190.2;
132 k1T = 0.1458;
133 k2T = 0.03632;
134 k3T = -0.03333;
135 }
136 // laminar flow friction factor for bare Pin bundle - Center subchannel
137 CfL = k1L + k2L * (p_over_d - 1) + k3L * Utility::pow<2>((p_over_d - 1));
138 // turbulent flow friction factor for bare Pin bundle - Center subchannel
139 CfT = k1T + k2T * (p_over_d - 1) + k3T * Utility::pow<2>((p_over_d - 1));
140 }
141 else if (subch_type == EChannelType::EDGE)
142 {
143 if (w_over_d < 1.1)
144 {
145 k1L = 26.18;
146 k2L = 554.5;
147 k3L = -1480.0;
148 k1T = 0.09377;
149 k2T = 0.8732;
150 k3T = -3.341;
151 }
152 else
153 {
154 k1L = 44.4;
155 k2L = 256.7;
156 k3L = -267.6;
157 k1T = 0.1430;
158 k2T = 0.04199;
159 k3T = -0.04428;
160 }
161 // laminar flow friction factor for bare Pin bundle - Edge subchannel
162 CfL = k1L + k2L * (w_over_d - 1) + k3L * Utility::pow<2>((w_over_d - 1));
163 // turbulent flow friction factor for bare Pin bundle - Edge subchannel
164 CfT = k1T + k2T * (w_over_d - 1) + k3T * Utility::pow<2>((w_over_d - 1));
165 }
166 else
167 {
168 if (w_over_d < 1.1)
169 {
170 k1L = 26.98;
171 k2L = 1636.0;
172 k3L = -10050.0;
173 k1T = 0.1004;
174 k2T = 1.625;
175 k3T = -11.85;
176 }
177 else
178 {
179 k1L = 87.26;
180 k2L = 38.59;
181 k3L = -55.12;
182 k1T = 0.1499;
183 k2T = 0.006706;
184 k3T = -0.009567;
185 }
186 // laminar flow friction factor for bare Pin bundle - Corner subchannel
187 CfL = k1L + k2L * (w_over_d - 1) + k3L * Utility::pow<2>((w_over_d - 1));
188 // turbulent flow friction factor for bare Pin bundle - Corner subchannel
189 CfT = k1T + k2T * (w_over_d - 1) + k3T * Utility::pow<2>((w_over_d - 1));
190 }
191
192 // Find the coefficients of wire-wrapped Pin bundle friction factor
193 // correlations for turbulent and laminar flow regimes. Todreas & Kazimi, Nuclear Systems
194 // Volume 1 Chapter 9-6 also Chen and Todreas (2018).
195 if (_has_wire_wrap)
196 {
197 const auto theta =
198 std::acos(wire_lead_length /
199 std::sqrt(Utility::pow<2>(wire_lead_length) +
200 Utility::pow<2>(libMesh::pi * (pin_diameter + wire_diameter))));
201 // wire Drag coefficient parameters
202 const Real CwT1 = 19.56;
203 const Real CwT2 = -98.71;
204 const Real CwT3 = 303.47;
205 const Real CwT4 = -0.541;
206 CwL1 = 1.4;
207 CwL2 = 1.0;
208 // Drag coefficient
209 const auto WdT = (CwT1 + CwT2 * (wire_diameter / pin_diameter) +
210 CwT3 * Utility::pow<2>((wire_diameter / pin_diameter))) *
211 std::pow((wire_lead_length / pin_diameter), CwT4);
212 const auto WdL = CwL1 * WdT;
213 // wire sweep coefficient parameters
214 const Real a = -11;
215 const Real b = 19;
216 // Sweep coefficient
217 const auto WsT = a * std::log10(wire_lead_length / pin_diameter) + b;
218 const auto WsL = CwL2 * WsT;
219 Real ar = 0.0;
220 Real a_p = 0.0;
221
222 if (subch_type == EChannelType::CENTER)
223 {
224 // wetted perimeter for center subchannel and bare Pin bundle
225 const Real pw_p = libMesh::pi * pin_diameter / 2.0;
226 // wire projected area - center subchannel wire-wrapped bundle
227 ar = libMesh::pi * (pin_diameter + wire_diameter) * wire_diameter / 6.0;
228 // bare Pin bundle center subchannel flow area (normal area + wire area)
229 a_p = S + libMesh::pi * Utility::pow<2>(wire_diameter) / 8.0 / std::cos(theta);
230 // turbulent friction factor equation constant - Center subchannel
231 CfT *= (pw_p / w_perim);
232 CfT += WdT * (3.0 * ar / a_p) * (Dh_i / wire_lead_length) *
233 std::pow((Dh_i / wire_diameter), 0.18);
234 // laminar friction factor equation constant - Center subchannel
235 CfL *= (pw_p / w_perim);
236 CfL += WdL * (3.0 * ar / a_p) * (Dh_i / wire_lead_length) * (Dh_i / wire_diameter);
237 }
238 else if (subch_type == EChannelType::EDGE)
239 {
240 // wire projected area - edge subchannel wire-wrapped bundle
241 ar = libMesh::pi * (pin_diameter + wire_diameter) * wire_diameter / 4.0;
242 // bare Pin bundle edge subchannel flow area (normal area + wire area)
243 a_p = S + libMesh::pi * Utility::pow<2>(wire_diameter) / 8.0 / std::cos(theta);
244 // turbulent friction factor equation constant - Edge subchannel
245 const Real turbulent_wire_correction =
246 1 + WsT * (ar / a_p) * Utility::pow<2>(std::tan(theta));
247 if (!std::isfinite(turbulent_wire_correction) || turbulent_wire_correction < 0.0)
248 mooseError("The exponentiated term in the Cheng-Todreas turbulent wire correction must be "
249 "non-negative and finite for an edge subchannel. Computed ",
250 turbulent_wire_correction,
251 ".");
252 CfT *= std::pow(turbulent_wire_correction, 1.41);
253 // laminar friction factor equation constant - Edge subchannel
254 CfL *= (1 + WsL * (ar / a_p) * Utility::pow<2>(std::tan(theta)));
255 }
256 else
257 {
258 // wire projected area - corner subchannel wire-wrapped bundle
259 ar = libMesh::pi * (pin_diameter + wire_diameter) * wire_diameter / 6.0;
260 // bare Pin bundle corner subchannel flow area (normal area + wire area)
261 a_p = S + libMesh::pi * Utility::pow<2>(wire_diameter) / 24.0 / std::cos(theta);
262 // turbulent friction factor equation constant - Corner subchannel
263 const Real turbulent_wire_correction =
264 1 + WsT * (ar / a_p) * Utility::pow<2>(std::tan(theta));
265 if (!std::isfinite(turbulent_wire_correction) || turbulent_wire_correction < 0.0)
266 mooseError("The exponentiated term in the Cheng-Todreas turbulent wire correction must be "
267 "non-negative and finite for a corner subchannel. Computed ",
268 turbulent_wire_correction,
269 ".");
270 CfT *= std::pow(turbulent_wire_correction, 1.41);
271 // laminar friction factor equation constant - Corner subchannel
272 CfL *= (1 + WsL * (ar / a_p) * Utility::pow<2>(std::tan(theta)));
273 }
274 }
275 // laminar friction factor and turbulent friction factor coefficients
276 const Real mL = -1.0;
277 const Real mT = -0.18;
278 auto fL = CfL * std::pow(Re_eff, mL);
279 auto fT = CfT * std::pow(Re_eff, mT);
280 gamma = 1.0 / 3.0;
281 lambda = 7.0;
282 if (Reb < ReL)
283 {
284 // laminar flow
285 return fL;
286 }
287 else if (Reb > ReT)
288 {
289 // turbulent flow
290 return fT;
291 }
292 else
293 {
294 // Transition regime is selected by bulk Reynolds number, same for all channels.
295 return fL * std::pow((1 - psi), gamma) * (1 - std::pow(psi, lambda)) +
296 fT * std::pow(psi, gamma);
297 }
298}
299
300Real
302 const FrictionStruct & friction_args) const
303{
304 const auto Re = friction_args.Re;
305 // Limit the Reynolds number used in the friction-factor correlation to avoid
306 // singular behavior k1T zero flow.
307 const Real Re_eff = std::max(Re, 1.0);
308 const auto i_ch = friction_args.i_ch;
310 Real k1L, k2L, k3L, CfL;
311 Real k1T, k2T, k3T, CfT;
312 const auto pitch = _subchannel_mesh.getPitch();
313 const auto pin_diameter = _subchannel_mesh.getPinDiameter();
314 // This gap is a constant value for the whole assembly. Might want to make it
315 // subchannel specific in the future if we have duct deformation.
316 const auto side_gap = _quad_sch_mesh->getSideGap();
317 const auto w = (pin_diameter / 2.0) + (pitch / 2.0) + side_gap;
318 const auto p_over_d = pitch / pin_diameter;
319 const auto w_over_d = w / pin_diameter;
320 const auto ReL = std::pow(10, (p_over_d - 1)) * 320.0;
321 const auto ReT = std::pow(10, 0.7 * (p_over_d - 1)) * 1.0E+4;
322 const auto Reb = _scm_problem.getBulkReynoldsNumber();
323 const auto psi = std::log(Reb / ReL) / std::log(ReT / ReL);
324 const auto subch_type = _subchannel_mesh.getSubchannelType(i_ch);
325 // interpolation exponent
326 Real lambda;
327 // transition smoothing coefficient
328 Real gamma;
329
330 // Find the coefficients of bare Pin bundle friction factor
331 // correlations for turbulent and laminar flow regimes. Todreas & Kazimi, Nuclear Systems Volume
332 // 1
333 if (subch_type == EChannelType::CENTER)
334 {
335 if (p_over_d < 1.1)
336 {
337 k1L = 26.37;
338 k2L = 374.2;
339 k3L = -493.9;
340 k1T = 0.09423;
341 k2T = 0.5806;
342 k3T = -1.239;
343 }
344 else
345 {
346 k1L = 35.55;
347 k2L = 263.7;
348 k3L = -190.2;
349 k1T = 0.1339;
350 k2T = 0.09059;
351 k3T = -0.09926;
352 }
353 // laminar flow friction factor for bare Pin bundle - Center subchannel
354 CfL = k1L + k2L * (p_over_d - 1) + k3L * Utility::pow<2>((p_over_d - 1));
355 // turbulent flow friction factor for bare Pin bundle - Center subchannel
356 CfT = k1T + k2T * (p_over_d - 1) + k3T * Utility::pow<2>((p_over_d - 1));
357 }
358 else if (subch_type == EChannelType::EDGE)
359 {
360 if (p_over_d < 1.1)
361 {
362 k1L = 26.18;
363 k2L = 554.5;
364 k3L = -1480;
365 k1T = 0.09377;
366 k2T = 0.8732;
367 k3T = -3.341;
368 }
369 else
370 {
371 k1L = 44.40;
372 k2L = 256.7;
373 k3L = -267.6;
374 k1T = 0.1430;
375 k2T = 0.04199;
376 k3T = -0.04428;
377 }
378 // laminar flow friction factor for bare Pin bundle - Edge subchannel
379 CfL = k1L + k2L * (w_over_d - 1) + k3L * Utility::pow<2>((w_over_d - 1));
380 // turbulent flow friction factor for bare Pin bundle - Edge subchannel
381 CfT = k1T + k2T * (w_over_d - 1) + k3T * Utility::pow<2>((w_over_d - 1));
382 }
383 else
384 {
385 if (p_over_d < 1.1)
386 {
387 k1L = 28.62;
388 k2L = 715.9;
389 k3L = -2807;
390 k1T = 0.09755;
391 k2T = 1.127;
392 k3T = -6.304;
393 }
394 else
395 {
396 k1L = 58.83;
397 k2L = 160.7;
398 k3L = -203.5;
399 k1T = 0.1452;
400 k2T = 0.02681;
401 k3T = -0.03411;
402 }
403 // laminar flow friction factor for bare Pin bundle - Corner subchannel
404 CfL = k1L + k2L * (w_over_d - 1) + k3L * Utility::pow<2>((w_over_d - 1));
405 // turbulent flow friction factor for bare Pin bundle - Corner subchannel
406 CfT = k1T + k2T * (w_over_d - 1) + k3T * Utility::pow<2>((w_over_d - 1));
407 }
408 // laminar friction factor and turbulent friction factor coefficients
409 const Real mL = -1.0;
410 const Real mT = -0.18;
411 auto fL = CfL * std::pow(Re_eff, mL);
412 auto fT = CfT * std::pow(Re_eff, mT);
413 gamma = 1.0 / 3.0;
414 lambda = 7.0;
415 if (Reb < ReL)
416 {
417 // laminar flow
418 return fL;
419 }
420 else if (Reb > ReT)
421 {
422 // turbulent flow
423 return fT;
424 }
425 else
426 {
427 // Transition regime is selected by bulk Reynolds number, same for all channels.
428 return fL * std::pow((1 - psi), gamma) * (1 - std::pow(psi, lambda)) +
429 fT * std::pow(psi, gamma);
430 }
431}
const double Re
registerMooseObject("SubChannelApp", SCMFrictionUpgradedChengTodreas)
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 SubChannel1PhaseProblem & _scm_problem
Reference to the subchannel problem.
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 upgraded Cheng & Todreas correlations (Cheng e...
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 bool _has_wire_wrap
Whether the triangular assembly has wire-wrap geometry.
Real computeTriLatticeFrictionFactor(const FrictionStruct &friction_info) const
const TriSubChannelMesh *const _tri_sch_mesh
Pointer to the tri lattice mesh.
const QuadSubChannelMesh *const _quad_sch_mesh
Pointer to the quad lattice mesh.
Real computeQuadLatticeFrictionFactor(const FrictionStruct &friction_info) const
SCMFrictionUpgradedChengTodreas(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