14 SCMMixingChengTodreas,
22 params.
addClassDescription(
"Class that models the turbulent mixing coefficient for wire-wrapped "
23 "triangular assemblies using the Chen Todreas correlations.");
24 MooseEnum mixing_model(
"1986 Pacio",
"1986");
28 "Mixing-model parameterization for triangular wire-wrapped Chen-Todreas correlations.");
34 _is_tri_lattice(dynamic_cast<const
TriSubChannelMesh *>(&_subchannel_mesh) != nullptr),
36 _mixing_model(getParam<
MooseEnum>(
"mixing_model")),
37 _S_soln(_subproblem.getVariable(0,
"S")),
38 _mdot_soln(_subproblem.getVariable(0,
"mdot")),
39 _rho_soln(_subproblem.getVariable(0,
"rho")),
41 _beta_1986(
std::numeric_limits<Real>::quiet_NaN()),
42 _beta_sweep(
std::numeric_limits<Real>::quiet_NaN())
45 mooseError(
"This correlation applies only for triangular assemblies");
48 mooseError(
"This correlation applies only for wire-wrapped assemblies");
52 const auto p_over_d = pitch / pin_diameter;
55 const unsigned int num_pins = 1 + 3 * Nr * (Nr - 1);
64 if (p_over_d < 1.07 || p_over_d > 1.30)
65 flagSolutionWarning(
"Pitch-over-pin diameter ratio (P/D) outside the 1986 "
66 "Cheng-Todreas mixing correlation data range.");
67 if (wire_lead_to_diameter < 4.0 || wire_lead_to_diameter > 52.0)
68 flagSolutionWarning(
"Wire lead length-over-pin diameter ratio (H/D) outside the 1986 "
69 "Cheng-Todreas mixing correlation data range.");
70 if (num_pins < 7 || num_pins > 217)
71 flagSolutionWarning(
"Number of pins outside the 1986 Cheng-Todreas mixing correlation "
76 if (p_over_d < 1.02 || p_over_d > 1.42)
77 flagSolutionWarning(
"Pitch-over-pin diameter ratio (P/D) outside the "
78 "Pacio-Chen-Todreas mixing correlation data range.");
79 if (wire_lead_to_diameter < 7.5 || wire_lead_to_diameter > 54.0)
80 flagSolutionWarning(
"Wire lead length-over-pin diameter ratio (H/D) outside the "
81 "Pacio-Chen-Todreas mixing correlation data range.");
82 if (num_pins < 19 || num_pins > 217)
83 flagSolutionWarning(
"Number of pins outside the Pacio-Chen-Todreas mixing correlation "
93 const Real p_over_d = pitch / pin_diameter;
105 if (bulk_Re < 400.0 || bulk_Re > 1.0e6)
106 flagSolutionWarning(
"Bulk Reynolds number (Reb) outside the 1986 Cheng-Todreas mixing "
107 "correlation data range.");
109 else if (bulk_Re < 10.0 || bulk_Re > 3.0e5)
110 flagSolutionWarning(
"Bulk Reynolds number (Reb) outside the Pacio-Chen-Todreas mixing "
111 "correlation data range.");
113 const Real theta = std::acos(
114 wire_lead_length / std::sqrt(Utility::pow<2>(wire_lead_length) +
115 Utility::pow<2>(
libMesh::pi * (pin_diameter + wire_diameter))));
117 const Real ReL = 320.0 * std::pow(10.0, p_over_d - 1.0);
119 const Real ReT = 10000.0 * std::pow(10.0, 0.7 * (p_over_d - 1.0));
130 const Real Ar1 =
libMesh::pi * (pin_diameter + wire_diameter) * wire_diameter / 6.0;
133 const Real A1prime = (std::sqrt(3.0) / 4.0) * Utility::pow<2>(pitch) -
142 CmL_constant = 0.055;
147 CmL_constant = 0.077;
150 const Real CmT = CmT_constant * std::pow((pitch - pin_diameter) / pin_diameter, -0.5);
152 const Real CmL = CmL_constant * std::pow((pitch - pin_diameter) / pin_diameter, -0.5);
158 else if (bulk_Re > ReT)
165 const Real psi = std::log(bulk_Re / ReL) / std::log(ReT / ReL);
167 const Real gamma = 2.0 / 3.0;
169 Cm = CmL + (CmT - CmL) * std::pow(psi, gamma);
172 _beta_1986 = Cm * std::sqrt(Ar1 / A1prime) * std::tan(theta);
181 const Real w = pin_diameter + dpgap;
183 const Real Ar2 =
libMesh::pi * (pin_diameter + wire_diameter) * wire_diameter / 4.0;
186 pitch * (w - pin_diameter / 2.0) -
libMesh::pi * Utility::pow<2>(pin_diameter) / 8.0;
199 CsL_constant = 0.413;
202 const Real CsL = CsL_constant * std::pow(wire_lead_length / pin_diameter, 0.3);
203 const Real CsT = CsT_constant * std::pow(wire_lead_length / pin_diameter, 0.3);
208 else if (bulk_Re > ReT)
215 const Real psi = std::log(bulk_Re / ReL) / std::log(ReT / ReL);
216 const Real gamma = 2.0 / 3.0;
218 Cs = CsL + (CsT - CsL) * std::pow(psi, gamma);
222 _beta_sweep = Cs * std::sqrt(Ar2 / A2prime) * std::tan(theta);
228 const unsigned int last_node)
const
254 const Real perimeter_ratio_center_edge =
255 (pitch - pin_diameter - wire_diameter / 6.0) / (pitch - pin_diameter);
256 const Real perimeter_ratio_edge_corner = (0.5 * dpgap - wire_diameter / 144.0) / dpgap;
258 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
265 Real mdot_sum[3] = {0.0, 0.0, 0.0};
266 Real rhoS_sum[3] = {0.0, 0.0, 0.0};
267 Real S_sum[3] = {0.0, 0.0, 0.0};
273 const unsigned int i_type =
283 const Real V_center = mdot_sum[0] / rhoS_sum[0] / bulk_V;
284 const Real V_edge = mdot_sum[1] / rhoS_sum[1] / bulk_V;
285 const Real V_corner = mdot_sum[2] / rhoS_sum[2] / bulk_V;
286 const Real S_total = S_sum[0] + S_sum[1] + S_sum[2];
287 const Real norm = (S_sum[0] * V_center + S_sum[1] * V_edge + S_sum[2] * V_corner) / S_total;
288 const Real X_center = V_center / norm;
289 const Real X_edge = V_edge / norm;
290 const Real X_corner = V_corner / norm;
302 const Real perimeter_ratio)
const
304 mooseAssert(
_mixing_model ==
"Pacio",
"The Pacio mixing parameter requires mixing_model = Pacio");
312 const Real theta = std::acos(
313 wire_lead_length / std::sqrt(Utility::pow<2>(wire_lead_length) +
314 Utility::pow<2>(
libMesh::pi * (pin_diameter + wire_diameter))));
316 const Real ReL = 700.0;
317 const Real ReT = 10000.0;
319 constexpr Real flow_split_exponent = 2.0 - 0.18;
323 if (MooseUtils::absoluteFuzzyEqual(Xi, Xj))
325 const Real Xavg = 0.5 * (Xi + Xj);
328 mooseError(
"The Pacio mixing correlation does not support negative flow splits "
329 "when evaluating the fractional flow-split exponent.");
333 if (MooseUtils::absoluteFuzzyEqual(Xavg, 0.0))
336 fraction = 0.5 * flow_split_exponent * std::pow(Xavg, flow_split_exponent - 2.0);
340 if (Xi < 0.0 || Xj < 0.0)
341 mooseError(
"The Pacio mixing correlation does not support negative flow splits "
342 "when evaluating the fractional flow-split exponent.");
344 fraction = (std::pow(Xi, flow_split_exponent) - std::pow(Xj, flow_split_exponent)) /
345 (Utility::pow<2>(Xi) - Utility::pow<2>(Xj));
349 const Real WmL = 0.0;
350 const Real WmT = 8.8;
354 const Real Re_eff = std::max(bulk_Re, 1.0);
355 const Real Cm_L = WmL / Re_eff;
356 const Real Cm_T = WmT * fraction / std::pow(Re_eff, 0.18);
362 else if (bulk_Re > ReT)
366 const Real psi = std::log(bulk_Re / ReL) / std::log(ReT / ReL);
370 const Real gamma = 0.362;
371 const Real lambda = 6.7;
373 Cm = Cm_L * std::pow(1.0 - psi, gamma) * (1.0 - std::pow(psi, lambda)) +
374 Cm_T * std::pow(psi, gamma);
379 const Real w = pin_diameter + dpgap;
381 const Real Ar2 =
libMesh::pi * (pin_diameter + wire_diameter) * wire_diameter / 4.0;
384 pitch * (w - pin_diameter / 2.0) -
libMesh::pi * Utility::pow<2>(pin_diameter) / 8.0;
386 return Cm * std::sqrt(Ar2 / A2prime) * std::tan(theta) * perimeter_ratio;
397 const bool center_edge =
401 const bool edge_corner =
419 const unsigned int )
const
registerMooseObjectRenamed("SubChannelApp", SCMMixingChengTodreas, "09/30/2027 24:00", SCMMixingChenTodreas)
registerMooseObject("SubChannelApp", SCMMixingChenTodreas)
const std::string & type() const
void mooseError(Args &&... args) const
const SubChannel1PhaseProblem & _scm_problem
Reference to the subchannel problem.
const SubChannelMesh & _subchannel_mesh
Reference to the subchannel mesh.
Class that calculates turbulent mixing and sweep-flow coefficients for wire-wrapped triangular lattic...
std::vector< Real > _beta_pacio_center_edge
Pacio mixing parameter of the center-edge and edge-corner gaps per axial level, from the flow split o...
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(...
void computeBulkMixingParameters() const override
Precomputes the mixing coefficients that depend only on the bulk flow.
const MooseEnum & _mixing_model
Chen-Todreas mixing-model parameterization.
Real _beta_1986
Cheng-Todreas (1986) mixing parameter of the gaps next to a center subchannel, which depends only on ...
Real computeSweepFlowMixingParameter(const unsigned int i_gap, const unsigned int iz) const override
Computes the wire-wrap sweep-flow coefficient for peripheral gaps.
SolutionHandle _mdot_soln
SCMMixingChenTodreas(const InputParameters ¶meters)
std::vector< Real > _beta_pacio_edge_corner
Real _beta_sweep
Cheng-Todreas (1986) sweep-flow coefficient of the peripheral gaps, which depends only on the geometr...
static InputParameters validParams()
bool _is_tri_lattice
Keep track of the lattice type.
void computeBlockMixingParameters(const unsigned int first_node, const unsigned int last_node) const override
Precomputes the mixing coefficients that depend on the flow solution of the axial levels first_node t...
const TriSubChannelMesh *const _tri_sch_mesh
Pointer to the triangular lattice mesh.
Real computePacioMixingParameter(const Real Xi, const Real Xj, const Real perimeter_ratio) const
Pacio mixing parameter of a gap between subchannels with flow splits Xi and Xj, including the ratio o...
Base class for turbulent mixing closures used in SCM.
static InputParameters validParams()
Real getBulkVelocity() const
Real getBulkReynoldsNumber() const
virtual unsigned int getNumOfChannels() const =0
Return the number of channels per layer.
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.