https://mooseframework.inl.gov
Loading...
Searching...
No Matches
SCMMixingChengTodreas.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 models the turbulent mixing coefficient for wire-wrapped "
19 "triangular assemblies using the Cheng Todreas correlations.");
20 return params;
21}
22
24 : SCMMixingClosureBase(parameters),
25 _is_tri_lattice(dynamic_cast<const TriSubChannelMesh *>(&_subchannel_mesh) != nullptr),
26 _tri_sch_mesh(dynamic_cast<const TriSubChannelMesh *>(&_subchannel_mesh)),
27 _S_soln(_subproblem.getVariable(0, "S")),
28 _mdot_soln(_subproblem.getVariable(0, "mdot")),
29 _w_perim_soln(_subproblem.getVariable(0, "w_perim")),
30 _mu_soln(_subproblem.getVariable(0, "mu"))
31{
32 if (!_is_tri_lattice)
33 mooseError("This correlation applies only for triangular assemblies");
34
36 mooseError("This correlation applies only for wire-wrapped assemblies");
37
38 const Real pitch = _subchannel_mesh.getPitch();
39 const Real pin_diameter = _subchannel_mesh.getPinDiameter();
40 const Real pitch_to_diameter = pitch / pin_diameter;
41 const Real 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 // Cheng and Todreas (1986) fitted the wire-wrapped mixing parameters over the ranges
46 // 1.067 <= P/D <= 1.35, 4 <= H/D <= 52, and 7 <= Npin <= 217.
47 if (pitch_to_diameter < 1.067 || pitch_to_diameter > 1.35)
48 flagSolutionWarning("Pitch-over-pin diameter ratio (P/D) outside the Cheng-Todreas "
49 "wire-wrapped mixing correlation data range.");
50 if (wire_lead_to_diameter < 4.0 || wire_lead_to_diameter > 52.0)
51 flagSolutionWarning("Wire lead length-over-pin diameter ratio (H/D) outside the "
52 "Cheng-Todreas wire-wrapped mixing correlation data range.");
53 if (num_pins < 7 || num_pins > 217)
54 flagSolutionWarning("Number of pins outside the Cheng-Todreas wire-wrapped mixing "
55 "correlation data range.");
56}
57
58Real
59SCMMixingChengTodreas::computeMixingParameter(const unsigned int i_gap, const unsigned int iz) const
60{
61 Real beta = 0.0;
62
63 const Real pitch = _subchannel_mesh.getPitch();
64 const Real pin_diameter = _subchannel_mesh.getPinDiameter();
65
66 const Real wire_lead_length = _tri_sch_mesh->getWireLeadLength();
67 const Real wire_diameter = _tri_sch_mesh->getWireDiameter();
68 const unsigned int Nr = _tri_sch_mesh->getNumOfRings();
69
70 const auto chans = _subchannel_mesh.getGapChannels(i_gap);
71 const unsigned int i_ch = chans.first;
72 const unsigned int j_ch = chans.second;
73
74 const auto subch_type_i = _subchannel_mesh.getSubchannelType(i_ch);
75 const auto subch_type_j = _subchannel_mesh.getSubchannelType(j_ch);
76
77 const Node * const node_in_i = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
78 const Node * const node_out_i = _subchannel_mesh.getChannelNode(i_ch, iz);
79 const Node * const node_in_j = _subchannel_mesh.getChannelNode(j_ch, iz - 1);
80 const Node * const node_out_j = _subchannel_mesh.getChannelNode(j_ch, iz);
81
82 const Real Si_in = _S_soln(node_in_i);
83 const Real Sj_in = _S_soln(node_in_j);
84 const Real Si_out = _S_soln(node_out_i);
85 const Real Sj_out = _S_soln(node_out_j);
86
87 const Real S_total = Si_in + Sj_in + Si_out + Sj_out;
88 const Real Si = 0.5 * (Si_in + Si_out);
89 const Real Sj = 0.5 * (Sj_in + Sj_out);
90
91 const Real w_perim_i = 0.5 * (_w_perim_soln(node_in_i) + _w_perim_soln(node_out_i));
92 const Real w_perim_j = 0.5 * (_w_perim_soln(node_in_j) + _w_perim_soln(node_out_j));
93
94 const Real avg_mu =
95 (1.0 / S_total) * (_mu_soln(node_out_i) * Si_out + _mu_soln(node_in_i) * Si_in +
96 _mu_soln(node_out_j) * Sj_out + _mu_soln(node_in_j) * Sj_in);
97
98 const Real avg_hD = 4.0 * (Si + Sj) / (w_perim_i + w_perim_j);
99
100 const Real avg_massflux =
101 0.5 * ((_mdot_soln(node_in_i) + _mdot_soln(node_in_j)) / (Si_in + Sj_in) +
102 (_mdot_soln(node_out_i) + _mdot_soln(node_out_j)) / (Si_out + Sj_out));
103
104 const Real Re = avg_massflux * avg_hD / avg_mu;
105 if (Re < 400.0 || Re > 1.0e6)
106 flagSolutionWarning("Reynolds number (Re) outside the Cheng-Todreas wire-wrapped mixing "
107 "correlation data range.");
108
109 // Calculation of flow regime
110 const Real ReL = 320.0 * std::pow(10.0, pitch / pin_diameter - 1.0);
111 const Real ReT = 10000.0 * std::pow(10.0, 0.7 * (pitch / pin_diameter - 1.0));
112
113 // This beta is used by the global turbulent crossflow relation:
114 // w'_ij = beta * S_ij * G_bar. Peripheral sweep flow is handled separately by
115 // computeSweepFlowMixingParameter().
116 if (subch_type_i == EChannelType::CENTER || subch_type_j == EChannelType::CENTER)
117 {
118 // Calculation of geometric parameters
119 // wire angle
120 const Real theta =
121 std::acos(wire_lead_length /
122 std::sqrt(Utility::pow<2>(wire_lead_length) +
123 Utility::pow<2>(libMesh::pi * (pin_diameter + wire_diameter))));
124
125 // projected area of wire on subchannel
126 const Real Ar1 = libMesh::pi * (pin_diameter + wire_diameter) * wire_diameter / 6.0;
127
128 // bare subchannel flow area
129 const Real A1prime = (std::sqrt(3.0) / 4.0) * Utility::pow<2>(pitch) -
130 libMesh::pi * Utility::pow<2>(pin_diameter) / 8.0;
131
132 // empirical constant for mixing parameter
133 Real Cm = 0.0;
134 Real CmL_constant = 0.0;
135 Real CmT_constant = 0.0;
136
137 if (Nr == 1)
138 {
139 CmT_constant = 0.1;
140 CmL_constant = 0.055;
141 }
142 else
143 {
144 CmT_constant = 0.14;
145 CmL_constant = 0.077;
146 }
147
148 const Real CmT = CmT_constant * std::pow((pitch - pin_diameter) / pin_diameter, -0.5);
149 const Real CmL = CmL_constant * std::pow((pitch - pin_diameter) / pin_diameter, -0.5);
150
151 if (Re < ReL)
152 {
153 Cm = CmL;
154 }
155 else if (Re > ReT)
156 {
157 Cm = CmT;
158 }
159 else
160 {
161 // Simplified intermittency factor; see SCMMixingChengTodreas.md.
162 // Cheng and Todreas (1986) use a more detailed expression for psi.
163 const Real psi = (std::log(Re) - std::log(ReL)) / (std::log(ReT) - std::log(ReL));
164 const Real gamma = 2.0 / 3.0;
165 Cm = CmL + (CmT - CmL) * std::pow(psi, gamma);
166 }
167
168 // mixing parameter
169 beta = Cm * std::sqrt(Ar1 / A1prime) * std::tan(theta);
170 }
171 return beta;
172}
173
174Real
176 const unsigned int iz) const
177{
178 Real beta = 0.0;
179
180 const Real pitch = _subchannel_mesh.getPitch();
181 const Real pin_diameter = _subchannel_mesh.getPinDiameter();
182
183 const Real wire_lead_length = _tri_sch_mesh->getWireLeadLength();
184 const Real wire_diameter = _tri_sch_mesh->getWireDiameter();
185 const unsigned int Nr = _tri_sch_mesh->getNumOfRings();
186
187 const auto chans = _subchannel_mesh.getGapChannels(i_gap);
188 const unsigned int i_ch = chans.first;
189 const unsigned int j_ch = chans.second;
190
191 const auto subch_type_i = _subchannel_mesh.getSubchannelType(i_ch);
192 const auto subch_type_j = _subchannel_mesh.getSubchannelType(j_ch);
193
194 const Node * const node_in_i = _subchannel_mesh.getChannelNode(i_ch, iz - 1);
195 const Node * const node_out_i = _subchannel_mesh.getChannelNode(i_ch, iz);
196 const Node * const node_in_j = _subchannel_mesh.getChannelNode(j_ch, iz - 1);
197 const Node * const node_out_j = _subchannel_mesh.getChannelNode(j_ch, iz);
198
199 const Real Si_in = _S_soln(node_in_i);
200 const Real Sj_in = _S_soln(node_in_j);
201 const Real Si_out = _S_soln(node_out_i);
202 const Real Sj_out = _S_soln(node_out_j);
203
204 const Real S_total = Si_in + Sj_in + Si_out + Sj_out;
205 const Real Si = 0.5 * (Si_in + Si_out);
206 const Real Sj = 0.5 * (Sj_in + Sj_out);
207
208 const Real w_perim_i = 0.5 * (_w_perim_soln(node_in_i) + _w_perim_soln(node_out_i));
209 const Real w_perim_j = 0.5 * (_w_perim_soln(node_in_j) + _w_perim_soln(node_out_j));
210
211 const Real avg_mu =
212 (1.0 / S_total) * (_mu_soln(node_out_i) * Si_out + _mu_soln(node_in_i) * Si_in +
213 _mu_soln(node_out_j) * Sj_out + _mu_soln(node_in_j) * Sj_in);
214
215 const Real avg_hD = 4.0 * (Si + Sj) / (w_perim_i + w_perim_j);
216
217 const Real avg_massflux =
218 0.5 * ((_mdot_soln(node_in_i) + _mdot_soln(node_in_j)) / (Si_in + Sj_in) +
219 (_mdot_soln(node_out_i) + _mdot_soln(node_out_j)) / (Si_out + Sj_out));
220
221 const Real Re = avg_massflux * avg_hD / avg_mu;
222 if (Re < 400.0 || Re > 1.0e6)
223 flagSolutionWarning("Reynolds number (Re) outside the Cheng-Todreas wire-wrapped mixing "
224 "correlation data range.");
225
226 // Calculation of flow regime
227 const Real ReL = 320.0 * std::pow(10.0, pitch / pin_diameter - 1.0);
228 const Real ReT = 10000.0 * std::pow(10.0, 0.7 * (pitch / pin_diameter - 1.0));
229
230 if ((subch_type_i == EChannelType::CORNER || subch_type_i == EChannelType::EDGE) &&
231 (subch_type_j == EChannelType::CORNER || subch_type_j == EChannelType::EDGE))
232 {
233 const Real theta =
234 std::acos(wire_lead_length /
235 std::sqrt(Utility::pow<2>(wire_lead_length) +
236 Utility::pow<2>(libMesh::pi * (pin_diameter + wire_diameter))));
237
238 // Calculation of geometric parameters
239 // distance from pin surface to duct
240 const Real dpgap = _tri_sch_mesh->getDuctToPinGap();
241
242 // Edge pitch parameter defined as pin diameter plus distance to duct wall
243 const Real w = pin_diameter + dpgap;
244
245 const Real Ar2 = libMesh::pi * (pin_diameter + wire_diameter) * wire_diameter / 4.0;
246
247 const Real A2prime =
248 pitch * (w - pin_diameter / 2.0) - libMesh::pi * Utility::pow<2>(pin_diameter) / 8.0;
249
250 // empirical constant for mixing parameter
251 Real Cs = 0.0;
252 Real CsL_constant = 0.0;
253 Real CsT_constant = 0.0;
254
255 if (Nr == 1)
256 {
257 CsT_constant = 0.6;
258 CsL_constant = 0.33;
259 }
260 else
261 {
262 CsT_constant = 0.75;
263 CsL_constant = 0.413;
264 }
265
266 const Real CsL = CsL_constant * std::pow(wire_lead_length / pin_diameter, 0.3);
267 const Real CsT = CsT_constant * std::pow(wire_lead_length / pin_diameter, 0.3);
268
269 if (Re < ReL)
270 {
271 Cs = CsL;
272 }
273 else if (Re > ReT)
274 {
275 Cs = CsT;
276 }
277 else
278 {
279 // Simplified intermittency factor; see SCMMixingChengTodreas.md.
280 // Cheng and Todreas (1986) use a more detailed expression for psi.
281 const Real psi = (std::log(Re) - std::log(ReL)) / (std::log(ReT) - std::log(ReL));
282 const Real gamma = 2.0 / 3.0;
283 Cs = CsL + (CsT - CsL) * std::pow(psi, gamma);
284 }
285
286 // Sweep-flow coefficient used only by the peripheral enthalpy calculation.
287 beta = Cs * std::sqrt(Ar2 / A2prime) * std::tan(theta);
288 }
289
290 return beta;
291}
const double Re
registerMooseObject("SubChannelApp", SCMMixingChengTodreas)
void addClassDescription(const std::string &doc_string)
void mooseError(Args &&... args) const
const SubChannelMesh & _subchannel_mesh
Reference to the subchannel mesh.
Class that calculates turbulent mixing and sweep-flow coefficients based on the Cheng & Todreas corre...
Real computeMixingParameter(const unsigned int i_gap, const unsigned int iz) const override
Computes the turbulent mixing coefficient for the local conditions around gap(i_gap) and axial level(...
Real computeSweepFlowMixingParameter(const unsigned int i_gap, const unsigned int iz) const override
Computes the wire-wrap sweep-flow coefficient for peripheral gaps.
const TriSubChannelMesh *const _tri_sch_mesh
Pointer to the tri lattice mesh.
bool _is_tri_lattice
Keep track of the lattice type.
static InputParameters validParams()
SCMMixingChengTodreas(const InputParameters &parameters)
Base class for turbulent mixing closures used in SCM.
static InputParameters validParams()
virtual const Real & getPitch() const
Return the undeformed pitch between 2 subchannels.
virtual const std::pair< unsigned int, unsigned int > & getGapChannels(unsigned int i_gap) const =0
Return a pair of subchannel indices for a given gap index.
virtual EChannelType getSubchannelType(unsigned int index) const =0
Return the type of the subchannel for given subchannel index.
virtual Node * getChannelNode(unsigned int i_chan, unsigned int iz) const =0
Get the subchannel mesh node for a given channel index and elevation 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