23 params.
addClassDescription(
"Solver class for subchannels in a triangular lattice assembly and " 24 "bare/wire-wrapped fuel pins");
46 PetscErrorCode ierr =
cleanUp();
71 Real standard_area, wire_area, additional_area, wetted_perimeter, displaced_area;
82 auto theta = std::acos(wire_lead_length /
83 std::sqrt(
std::pow(wire_lead_length, 2) +
85 for (
unsigned int iz = 0; iz <
_n_cells + 1; iz++)
87 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
93 Real rod_perimeter = 0.0;
100 (1.0 / 6.0) * 0.25 * M_PI * (*_Dpin_soln)(pin_node) * (*
_Dpin_soln)(pin_node);
101 rod_perimeter += (1.0 / 6.0) * M_PI * (*_Dpin_soln)(pin_node);
106 (1.0 / 4.0) * 0.25 * M_PI * (*_Dpin_soln)(pin_node) * (*
_Dpin_soln)(pin_node);
107 rod_perimeter += (1.0 / 4.0) * M_PI * (*_Dpin_soln)(pin_node);
114 additional_area = 0.0;
115 displaced_area = 0.0;
117 wetted_perimeter = rod_perimeter + 0.5 *
libMesh::pi * wire_diameter / std::cos(theta);
121 standard_area =
pitch * (pin_diameter / 2.0 + gap);
122 additional_area = 0.0;
123 displaced_area = (*_displacement_soln)(node)*
pitch;
126 rod_perimeter + 0.5 *
libMesh::pi * wire_diameter / std::cos(theta) +
pitch;
130 standard_area = 1.0 / std::sqrt(3.0) *
std::pow((pin_diameter / 2.0 + gap), 2.0);
131 additional_area = 0.0;
132 displaced_area = 1.0 / std::sqrt(3.0) *
133 (pin_diameter + 2.0 * gap + (*_displacement_soln)(node)) *
134 (*_displacement_soln)(node);
137 rod_perimeter +
libMesh::pi * wire_diameter / std::cos(theta) / 6.0 +
138 2.0 / std::sqrt(3.0) * (pin_diameter / 2.0 + gap + (*_displacement_soln)(node));
142 auto subchannel_area =
143 standard_area + additional_area + displaced_area - rod_area - wire_area;
146 auto overlapping_pin_area = 0.0;
147 auto overlapping_wetted_perimeter = 0.0;
151 auto pin_1 = gap_pins.first;
152 auto pin_2 = gap_pins.second;
155 auto Diameter1 = (*_Dpin_soln)(pin_node_1);
156 auto Radius1 = Diameter1 / 2.0;
157 auto Diameter2 = (*_Dpin_soln)(pin_node_2);
158 auto Radius2 = Diameter2 / 2.0;
161 if (
pitch < (Radius1 + Radius2))
163 mooseWarning(
" The gap of index : '", i_gap,
" at axial cell ", iz,
" ' is blocked.");
165 (
pitch *
pitch + Radius1 * Radius1 - Radius2 * Radius2) / (2 *
pitch * Radius1);
167 (
pitch *
pitch + Radius2 * Radius2 - Radius1 * Radius1) / (2 *
pitch * Radius2);
168 auto angle1 = 2.0 * acos(cos1);
169 auto angle2 = 2.0 * acos(cos2);
171 overlapping_wetted_perimeter += 0.5 * angle1 * Radius1 + 0.5 * angle2 * Radius2;
173 overlapping_pin_area +=
174 0.5 * Radius1 * Radius1 * acos(cos1) + 0.5 * Radius2 * Radius2 * acos(cos2) -
175 0.25 *
sqrt((-
pitch + Radius1 + Radius2) * (
pitch + Radius1 - Radius2) *
176 (
pitch - Radius1 + Radius2) * (
pitch + Radius1 + Radius2));
179 subchannel_area += overlapping_pin_area;
180 wetted_perimeter += -overlapping_wetted_perimeter;
184 for (
const auto & i_blockage : index_blockage)
186 if (i_ch == i_blockage && (
Z >= z_blockage.front() &&
Z <= z_blockage.back()))
188 subchannel_area *= reduction_blockage[index];
197 for (
unsigned int iz = 0; iz <
_n_cells + 1; iz++)
199 for (
unsigned int i_gap = 0; i_gap <
_n_gaps; i_gap++)
202 auto pin_1 = gap_pins.first;
203 auto pin_2 = gap_pins.second;
209 auto displacement = 0.0;
217 displacement += (*_displacement_soln)(node);
221 displacement = displacement / counter;
223 0.5 * (flat_to_flat - (n_rings - 1) *
pitch * std::sqrt(3.0) -
224 (*_Dpin_soln)(pin_node_1)) +
230 pitch - (*_Dpin_soln)(pin_node_1) / 2.0 - (*
_Dpin_soln)(pin_node_2) / 2.0;
239 for (
unsigned int iz = 1; iz <
_n_cells + 1; iz++)
241 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
251 _aux->solution().close();
259 auto Re = friction_args.
Re;
260 auto i_ch = friction_args.
i_ch;
261 auto S = friction_args.
S;
262 auto w_perim = friction_args.
w_perim;
263 auto Dh_i = 4.0 *
S / w_perim;
265 Real aT, b1T, b2T, cT;
270 auto p_over_d =
pitch / pin_diameter;
275 auto w_over_d = (pin_diameter + gap) / pin_diameter;
276 auto ReL =
std::pow(10, (p_over_d - 1)) * 320.0;
277 auto ReT =
std::pow(10, 0.7 * (p_over_d - 1)) * 1.0E+4;
278 auto psi = std::log(Re / ReL) / std::log(ReT / ReL);
279 const Real lambda = 7.0;
280 auto theta = std::acos(wire_lead_length /
281 std::sqrt(
std::pow(wire_lead_length, 2) +
283 auto wd_t = (19.56 - 98.71 * (wire_diameter / pin_diameter) +
284 303.47 *
std::pow((wire_diameter / pin_diameter), 2.0)) *
285 std::pow((wire_lead_length / pin_diameter), -0.541);
286 auto wd_l = 1.4 * wd_t;
287 auto ws_t = -11.0 * std::log(wire_lead_length / pin_diameter) + 19.0;
317 cL = aL + b1L * (p_over_d - 1) + b2L *
std::pow((p_over_d - 1), 2.0);
319 cT = aT + b1T * (p_over_d - 1) + b2T *
std::pow((p_over_d - 1), 2.0);
342 cL = aL + b1L * (w_over_d - 1) + b2L *
std::pow((w_over_d - 1), 2.0);
344 cT = aT + b1T * (w_over_d - 1) + b2T *
std::pow((w_over_d - 1), 2.0);
367 cL = aL + b1L * (w_over_d - 1) + b2L *
std::pow((w_over_d - 1), 2.0);
369 cT = aT + b1T * (w_over_d - 1) + b2T *
std::pow((w_over_d - 1), 2.0);
375 if ((wire_diameter != 0.0) && (wire_lead_length != 0.0))
382 ar =
libMesh::pi * (pin_diameter + wire_diameter) * wire_diameter / 6.0;
386 cT *= (pw_p / w_perim);
387 cT += wd_t * (3.0 * ar / a_p) * (Dh_i / wire_lead_length) *
388 std::pow((Dh_i / wire_diameter), 0.18);
390 cL *= (pw_p / w_perim);
391 cL += wd_l * (3.0 * ar / a_p) * (Dh_i / wire_lead_length) * (Dh_i / wire_diameter);
396 ar =
libMesh::pi * (pin_diameter + wire_diameter) * wire_diameter / 4.0;
400 cT *=
std::pow((1 + ws_t * (ar / a_p) *
std::pow(std::tan(theta), 2.0)), 1.41);
402 cL *= (1 + ws_l * (ar / a_p) *
std::pow(std::tan(theta), 2.0));
407 ar =
libMesh::pi * (pin_diameter + wire_diameter) * wire_diameter / 6.0;
411 cT *=
std::pow((1 + ws_t * (ar / a_p) *
std::pow(std::tan(theta), 2.0)), 1.41);
413 cL *= (1 + ws_l * (ar / a_p) *
std::pow(std::tan(theta), 2.0));
443 auto beta = std::numeric_limits<double>::quiet_NaN();
450 unsigned int i_ch = chans.first;
451 unsigned int j_ch = chans.second;
458 auto Si_in = (*_S_flow_soln)(node_in_i);
459 auto Sj_in = (*_S_flow_soln)(node_in_j);
460 auto Si_out = (*_S_flow_soln)(node_out_i);
461 auto Sj_out = (*_S_flow_soln)(node_out_j);
462 auto S_total = Si_in + Sj_in + Si_out + Sj_out;
463 auto Si = 0.5 * (Si_in + Si_out);
464 auto Sj = 0.5 * (Sj_in + Sj_out);
465 auto w_perim_i = 0.5 * ((*_w_perim_soln)(node_in_i) + (*
_w_perim_soln)(node_out_i));
466 auto w_perim_j = 0.5 * ((*_w_perim_soln)(node_in_j) + (*
_w_perim_soln)(node_out_j));
467 auto avg_mu = (1 / S_total) * ((*
_mu_soln)(node_out_i)*Si_out + (*
_mu_soln)(node_in_i)*Si_in +
469 auto avg_hD = 4.0 * (Si + Sj) / (w_perim_i + w_perim_j);
471 0.5 * (((*_mdot_soln)(node_in_i) + (*
_mdot_soln)(node_in_j)) / (Si_in + Sj_in) +
473 auto Re = avg_massflux * avg_hD / avg_mu;
478 auto ReT = 10000.0 *
std::pow(10.0, 0.7 * (
pitch / pin_diameter - 1));
483 (wire_lead_length != 0) && (wire_diameter != 0))
487 auto theta = std::acos(wire_lead_length /
488 std::sqrt(
std::pow(wire_lead_length, 2) +
491 auto Ar1 =
libMesh::pi * (pin_diameter + wire_diameter) * wire_diameter / 6.0;
499 auto CmL_constant = 0.0;
500 auto CmT_constant = 0.0;
505 CmL_constant = 0.055;
510 CmL_constant = 0.077;
513 auto CmT = CmT_constant *
std::pow((
pitch - pin_diameter) / pin_diameter, -0.5);
514 auto CmL = CmL_constant *
std::pow((
pitch - pin_diameter) / pin_diameter, -0.5);
526 auto psi = (std::log(Re) - std::log(ReL)) / (std::log(ReT) - std::log(ReL));
527 auto gamma = 2.0 / 3.0;
528 Cm = CmL + (CmT - CmL) *
std::pow(psi, gamma);
531 beta = Cm *
std::pow(Ar1 /
A1, 0.5) * std::tan(theta);
536 (wire_lead_length != 0) && (wire_diameter != 0))
538 auto theta = std::acos(wire_lead_length /
539 std::sqrt(
std::pow(wire_lead_length, 2) +
545 auto w = pin_diameter + dpgap;
546 auto Ar2 =
libMesh::pi * (pin_diameter + wire_diameter) * wire_diameter / 4.0;
551 auto CsL_constant = 0.0;
552 auto CsT_constant = 0.0;
561 CsL_constant = 0.413;
563 auto CsL = CsL_constant *
std::pow(wire_lead_length / pin_diameter, 0.3);
564 auto CsT = CsT_constant *
std::pow(wire_lead_length / pin_diameter, 0.3);
576 auto psi = (std::log(Re) - std::log(ReL)) / (std::log(ReT) - std::log(ReL));
577 auto gamma = 2.0 / 3.0;
578 Cs = CsL + (CsT - CsL) *
std::pow(psi, gamma);
582 beta = Cs *
std::pow(Ar2 /
A2, 0.5) * std::tan(theta);
587 else if ((wire_lead_length == 0) && (wire_diameter == 0))
594 auto k = (1 / S_total) *
599 auto cp = (1 / S_total) *
604 auto Pr = avg_mu *
cp /
k;
605 auto Pr_t = Pr * (Re / gamma) * std::sqrt(
f / 8.0);
607 auto L_x = sf *
delta;
608 auto lamda = gap / L_x;
609 auto a_x = 1.0 - 2.0 * lamda * lamda /
libMesh::pi;
610 auto z_FP_over_D = (2.0 * L_x / pin_diameter) *
611 (1 + (-0.5 * std::log(lamda) + 0.5 * std::log(4.0) - 0.25) * lamda * lamda);
612 auto Str = 1.0 / (0.822 * (gap / pin_diameter) + 0.144);
613 auto freq_factor = 2.0 /
std::pow(gamma, 2) * std::sqrt(
a / 8.0) * (avg_hD / gap);
614 auto rod_mixing = (1 / Pr_t) * lamda;
615 auto axial_mixing = a_x * z_FP_over_D * Str;
617 beta = freq_factor * (rod_mixing + axial_mixing) *
std::pow(Re, -
b / 2.0);
619 mooseAssert(beta >= 0,
"beta should be positive or zero.");
631 if (MooseUtils::absoluteFuzzyGreaterThan(z2, unheated_length_entry) &&
632 MooseUtils::absoluteFuzzyLessThan(z1, unheated_length_entry + heated_length))
654 double heat_rate_in = 0.0;
655 double heat_rate_out = 0.0;
660 heat_rate_out += factor * (*_q_prime_soln)(node_out);
661 heat_rate_in += factor * (*_q_prime_soln)(node_in);
663 return (heat_rate_in + heat_rate_out) * dz / 2.0;
684 width = 2.0 / std::sqrt(3.0) *
689 mooseError(
"Channel is not a perimetric subchannel ");
695 unsigned int last_node = (iblock + 1) *
_block_size;
696 unsigned int first_node = iblock *
_block_size + 1;
704 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
711 name(),
" : Calculation of negative Enthalpy h_out = : ", h_out,
" Axial Level= : ", 0);
719 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
722 auto dz = z_grid[iz] - z_grid[iz - 1];
724 Real edge_flux_ave = 0.0;
727 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
733 auto Si = (*_S_flow_soln)(node_in);
734 auto mdot_in = (*_mdot_soln)(node_in);
735 mdot_sum = mdot_sum + mdot_in;
736 si_sum = si_sum + Si;
739 edge_flux_ave = mdot_sum / si_sum;
741 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
745 auto mdot_in = (*_mdot_soln)(node_in);
746 auto h_in = (*_h_soln)(node_in);
747 auto volume = dz * (*_S_flow_soln)(node_in);
748 auto mdot_out = (*_mdot_soln)(node_out);
751 Real sumWijPrimeDhij = 0.0;
752 Real sweep_enthalpy = 0.0;
761 unsigned int counter = 0;
767 unsigned int ii_ch = chans.first;
768 unsigned int jj_ch = chans.second;
775 if (
_Wij(i_gap, iz) > 0.0)
776 h_star = (*_h_soln)(node_in_i);
777 else if (
_Wij(i_gap, iz) < 0.0)
778 h_star = (*_h_soln)(node_in_j);
788 (wire_lead_length != 0) && (wire_diameter != 0))
796 if ((ii_ch == sweep_donor) || (jj_ch == sweep_donor))
799 computeBeta(i_gap, iz,
true) * edge_flux_ave * Sij * (*_h_soln)(node_sweep_donor);
805 computeBeta(i_gap, iz,
true) * edge_flux_ave * Sij * (*_h_soln)(node_in);
813 _WijPrime(i_gap, iz) * (2 * h_in - (*_h_soln)(node_in_j) - (*
_h_soln)(node_in_i));
830 dist_ij =
pitch / std::sqrt(3);
836 0.66 * (
pitch / pin_diameter) *
840 e_cond += 0.5 * (thcon_i + thcon_j) * Sij * shape_factor *
845 e_cond += -0.5 * (thcon_i + thcon_j) * Sij * shape_factor *
855 auto Si = (*_S_flow_soln)(node_in_i);
856 auto dist_ij = z_grid[iz] - z_grid[iz - 1];
858 e_cond += 0.5 * (thcon_i + thcon_j) * Si * ((*
_T_soln)(node_in_j) - (*
_T_soln)(node_in_i)) /
869 auto Si = (*_S_flow_soln)(node_in_i);
870 auto dist_ij = z_grid[iz + 1] - z_grid[iz];
871 e_cond += 0.5 * (thcon_i + thcon_j) * Si *
877 (mdot_in * h_in - sumWijh - sumWijPrimeDhij + added_enthalpy + e_cond + sweep_enthalpy +
883 " : Calculation of negative Enthalpy h_out = : ",
912 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
917 auto iz_ind = iz - first_node;
919 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
923 auto S_in = (*_S_flow_soln)(node_in);
924 auto S_out = (*_S_flow_soln)(node_out);
926 auto volume = dz * S_interp;
928 PetscScalar Pe = 0.5;
932 auto w_perim_in = (*_w_perim_soln)(node_in);
933 auto w_perim_out = (*_w_perim_soln)(node_out);
944 auto Dh_i = 4.0 * S_interp / w_perim_interp;
945 Pe = mdot_loc * Dh_i *
cp / (
K * S_interp) * (mdot_loc / std::abs(mdot_loc));
950 if (iz == first_node)
952 PetscScalar value_vec_tt =
961 PetscInt col_tt = i_ch +
_n_channels * (iz_ind - 1);
963 LibmeshPetscCall(MatSetValues(
971 LibmeshPetscCall(MatSetValues(
975 PetscScalar rho_old_interp =
977 PetscScalar h_old_interp =
979 PetscScalar value_vec_tt =
_TR * rho_old_interp * h_old_interp *
volume /
_dt;
985 if (iz == first_node)
988 PetscScalar value_at =
alpha * (*_mdot_soln)(node_in) * (*
_h_soln)(node_in);
992 value_at =
alpha * (*_mdot_soln)(node_out) - (1 -
alpha) * (*_mdot_soln)(node_in);
994 LibmeshPetscCall(MatSetValues(
999 LibmeshPetscCall(MatSetValues(
1002 else if (iz == last_node)
1005 PetscScalar value_at = 1.0 * (*_mdot_soln)(node_out);
1007 LibmeshPetscCall(MatSetValues(
1010 value_at = -1.0 * (*_mdot_soln)(node_in);
1012 LibmeshPetscCall(MatSetValues(
1020 PetscScalar value_at = -
alpha * (*_mdot_soln)(node_in);
1022 LibmeshPetscCall(MatSetValues(
1025 value_at =
alpha * (*_mdot_soln)(node_out) - (1 -
alpha) * (*_mdot_soln)(node_in);
1027 LibmeshPetscCall(MatSetValues(
1032 LibmeshPetscCall(MatSetValues(
1041 auto diff_center = K_center / (cp_center + 1e-15);
1043 if (iz == first_node)
1053 auto diff_bottom = K_bottom / (cp_bottom + 1e-15);
1054 auto diff_top = K_top / (cp_top + 1e-15);
1068 PetscScalar value_at = diff_up * S_up / dz_up + diff_down * S_down / dz_down;
1069 LibmeshPetscCall(MatSetValues(
1073 value_at = 1.0 * diff_down * S_down / dz_down * (*_h_soln)(node_bottom);
1079 value_at = -diff_up * S_up / dz_up;
1080 LibmeshPetscCall(MatSetValues(
1083 else if (iz == last_node)
1090 auto diff_bottom = K_bottom / (cp_bottom + 1e-15);
1093 auto S_down = 0.5 * ((*_S_flow_soln)(node_center) + (*
_S_flow_soln)(node_bottom));
1094 auto diff_down = 0.5 * (diff_center + diff_bottom);
1099 PetscScalar value_at = diff_down * S_down / dz_down;
1100 LibmeshPetscCall(MatSetValues(
1105 value_at = -diff_down * S_down / dz_down;
1106 LibmeshPetscCall(MatSetValues(
1124 auto diff_bottom = K_bottom / (cp_bottom + 1e-15);
1125 auto diff_top = K_top / (cp_top + 1e-15);
1139 PetscScalar value_at = diff_up * S_up / dz_up + diff_down * S_down / dz_down;
1140 LibmeshPetscCall(MatSetValues(
1145 value_at = -diff_down * S_down / dz_down;
1146 LibmeshPetscCall(MatSetValues(
1151 value_at = -diff_up * S_up / dz_up;
1152 LibmeshPetscCall(MatSetValues(
1157 unsigned int counter = 0;
1158 unsigned int cross_index = iz;
1163 unsigned int ii_ch = chans.first;
1164 unsigned int jj_ch = chans.second;
1169 if (
_Wij(i_gap, cross_index) > 0.0)
1171 if (iz == first_node)
1173 h_star = (*_h_soln)(node_in_i);
1174 PetscScalar value_vec_ct = -1.0 *
alpha *
1176 _Wij(i_gap, cross_index) * h_star;
1177 PetscInt row_vec_ct = i_ch +
_n_channels * iz_ind;
1178 LibmeshPetscCall(VecSetValues(
1184 _Wij(i_gap, cross_index);
1186 PetscInt col_ct = ii_ch +
_n_channels * (iz_ind - 1);
1187 LibmeshPetscCall(MatSetValues(
1190 PetscScalar value_ct = (1.0 -
alpha) *
1192 _Wij(i_gap, cross_index);
1195 LibmeshPetscCall(MatSetValues(
1198 else if (
_Wij(i_gap, cross_index) < 0.0)
1200 if (iz == first_node)
1202 h_star = (*_h_soln)(node_in_j);
1203 PetscScalar value_vec_ct = -1.0 *
alpha *
1205 _Wij(i_gap, cross_index) * h_star;
1206 PetscInt row_vec_ct = i_ch +
_n_channels * iz_ind;
1207 LibmeshPetscCall(VecSetValues(
1213 _Wij(i_gap, cross_index);
1215 PetscInt col_ct = jj_ch +
_n_channels * (iz_ind - 1);
1216 LibmeshPetscCall(MatSetValues(
1219 PetscScalar value_ct = (1.0 -
alpha) *
1221 _Wij(i_gap, cross_index);
1224 LibmeshPetscCall(MatSetValues(
1229 if (iz == first_node)
1231 PetscScalar value_vec_ct =
1232 -2.0 *
alpha * (*_h_soln)(node_in)*
_WijPrime(i_gap, cross_index);
1233 value_vec_ct +=
alpha * (*_h_soln)(node_in_j)*
_WijPrime(i_gap, cross_index);
1234 value_vec_ct +=
alpha * (*_h_soln)(node_in_i)*
_WijPrime(i_gap, cross_index);
1235 PetscInt row_vec_ct = i_ch +
_n_channels * iz_ind;
1241 PetscScalar value_center_ct = 2.0 *
alpha *
_WijPrime(i_gap, cross_index);
1243 PetscInt col_ct = i_ch +
_n_channels * (iz_ind - 1);
1244 LibmeshPetscCall(MatSetValues(
1247 PetscScalar value_left_ct = -1.0 *
alpha *
_WijPrime(i_gap, cross_index);
1250 LibmeshPetscCall(MatSetValues(
1253 PetscScalar value_right_ct = -1.0 *
alpha *
_WijPrime(i_gap, cross_index);
1256 LibmeshPetscCall(MatSetValues(
1259 PetscScalar value_center_ct = 2.0 * (1.0 -
alpha) *
_WijPrime(i_gap, cross_index);
1262 LibmeshPetscCall(MatSetValues(
1265 PetscScalar value_left_ct = -1.0 * (1.0 -
alpha) *
_WijPrime(i_gap, cross_index);
1268 LibmeshPetscCall(MatSetValues(
1271 PetscScalar value_right_ct = -1.0 * (1.0 -
alpha) *
_WijPrime(i_gap, cross_index);
1274 LibmeshPetscCall(MatSetValues(
1293 dist_ij =
pitch / std::sqrt(3);
1301 auto A_i = K_i / cp_i;
1302 auto A_j = K_j / cp_j;
1303 auto harm_A = 2.0 * A_i * A_j / (A_i + A_j);
1305 0.66 * (
pitch / pin_diameter) *
1308 auto base_value = harm_A * shape_factor * Sij / dist_ij;
1309 auto neg_base_value = -1.0 * base_value;
1313 LibmeshPetscCall(MatSetValues(
1318 LibmeshPetscCall(MatSetValues(
1323 LibmeshPetscCall(MatSetValues(
1328 LibmeshPetscCall(MatSetValues(
1335 Real edge_flux_ave = 0.0;
1336 Real mdot_sum = 0.0;
1338 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1344 auto Si = (*_S_flow_soln)(node_in);
1345 auto mdot_in = (*_mdot_soln)(node_in);
1346 mdot_sum = mdot_sum + mdot_in;
1347 si_sum = si_sum + Si;
1350 edge_flux_ave = mdot_sum / si_sum;
1352 PetscScalar sweep_enthalpy = 0.0;
1354 (wire_diameter != 0.0) && (wire_lead_length != 0.0))
1356 auto beta_in = std::numeric_limits<double>::quiet_NaN();
1357 auto beta_out = std::numeric_limits<double>::quiet_NaN();
1365 unsigned int ii_ch = chans.first;
1366 unsigned int jj_ch = chans.second;
1372 if ((ii_ch == sweep_donor) || (jj_ch == sweep_donor))
1383 mooseAssert(!std::isnan(beta_in),
1384 "beta_in was not set. Check gap logic for i_ch = " + std::to_string(i_ch) +
1385 ", iz = " + std::to_string(iz));
1386 mooseAssert(!std::isnan(beta_out),
1387 "beta_out was not set. Check gap logic for i_ch = " + std::to_string(i_ch) +
1388 ", iz = " + std::to_string(iz));
1391 auto Sij = dz * gap;
1392 auto wsweep_in = edge_flux_ave * beta_in * Sij;
1393 auto wsweep_out = edge_flux_ave * beta_out * Sij;
1394 auto sweep_hin = (*_h_soln)(node_sweep_donor);
1395 auto sweep_hout = (*_h_soln)(node_in);
1396 sweep_enthalpy = (wsweep_in * sweep_hin - wsweep_out * sweep_hout);
1398 if (iz == first_node)
1401 PetscScalar value_hs = -sweep_enthalpy;
1408 PetscInt row_sh = i_ch +
_n_channels * (iz_ind - 1);
1409 PetscInt col_sh = i_ch +
_n_channels * (iz_ind - 1);
1410 LibmeshPetscCall(MatSetValues(
1412 PetscInt col_sh_l = sweep_donor +
_n_channels * (iz_ind - 1);
1413 PetscScalar neg_sweep_in = -1.0 * wsweep_in;
1415 LibmeshPetscCall(MatSetValues(
1423 PetscInt row_vec_ht = i_ch +
_n_channels * iz_ind;
1441 LibmeshPetscCall(MatAssemblyBegin(
_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1442 LibmeshPetscCall(MatAssemblyEnd(
_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1446 LibmeshPetscCall(MatAssemblyBegin(
_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1447 LibmeshPetscCall(MatAssemblyEnd(
_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1450 LibmeshPetscCall(MatAssemblyBegin(
_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1451 LibmeshPetscCall(MatAssemblyEnd(
_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1454 LibmeshPetscCall(MatAssemblyBegin(
_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1455 LibmeshPetscCall(MatAssemblyEnd(
_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1458 LibmeshPetscCall(MatAssemblyBegin(
_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1459 LibmeshPetscCall(MatAssemblyEnd(
_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1462 LibmeshPetscCall(MatAssemblyBegin(
_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1463 LibmeshPetscCall(MatAssemblyEnd(
_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1466 LibmeshPetscCall(MatAssemblyBegin(
_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1467 LibmeshPetscCall(MatAssemblyEnd(
_hc_sys_h_mat, MAT_FINAL_ASSEMBLY));
1469 _console <<
"Block: " << iblock <<
" - Enthalpy conservation matrix assembled" << std::endl;
1486 LibmeshPetscCall(KSPCreate(PETSC_COMM_SELF, &ksploc));
1488 LibmeshPetscCall(KSPGetPC(ksploc, &pc));
1489 LibmeshPetscCall(PCSetType(pc, PCJACOBI));
1491 LibmeshPetscCall(KSPSetOptionsPrefix(ksploc,
"h_sys_"));
1492 LibmeshPetscCall(KSPSetFromOptions(ksploc));
1496 LibmeshPetscCall(VecGetArray(sol, &xx));
1497 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
1499 auto iz_ind = iz - first_node;
1500 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1507 " : Calculation of negative Enthalpy h_out = : ",
1512 _h_soln->set(node_out, h_out);
1515 LibmeshPetscCall(KSPDestroy(&ksploc));
1516 LibmeshPetscCall(VecDestroy(&sol));
Vec _hc_radial_heat_conduction_rhs
const bool _pin_mesh_exist
Flag that informs if there is a pin mesh or not.
virtual Real computeAddedHeatPin(unsigned int i_ch, unsigned int iz) override
Function that computes the added heat coming from the fuel pins, for channel i_ch and cell iz...
virtual const std::pair< unsigned int, unsigned int > & getGapPins(unsigned int i_gap) const =0
Return a pair of pin indices for a given gap index.
virtual const Real & getPinDiameter() const
Return Pin diameter.
Mat _hc_radial_heat_conduction_mat
std::unique_ptr< SolutionHandle > _T_soln
std::unique_ptr< SolutionHandle > _h_soln
const PetscReal & _dtol
The divergence tolerance for the ksp linear solver.
const bool _monolithic_thermal_bool
Thermal monolithic bool.
virtual const std::vector< unsigned int > & getPinChannels(unsigned int i_pin) const =0
Return a vector of channel indices for a given Pin index.
T & getMesh(MooseMesh &mesh)
function to cast mesh
Real _TR
Flag that activates or deactivates the transient parts of the equations we solve by multiplication...
virtual const Real & getDuctToPinGap() const
Return the the gap thickness between the duct and peripheral fuel pins.
const PostprocessorValue & _P_out
Outlet Pressure.
SubChannelMesh & _subchannel_mesh
virtual Real computeFrictionFactor(FrictionStruct friction_args) override
Computes the axial friction factor for the sodium coolant and for each subchannel.
TriSubChannelMesh & _tri_sch_mesh
virtual const std::vector< unsigned int > & getChannelPins(unsigned int i_chan) const =0
Return a vector of pin indices for a given channel index.
virtual const std::vector< Real > & getZGrid() const
Get axial location of layers.
static const std::string K
virtual const Real & getPitch() const
Return the pitch between 2 subchannels.
virtual EChannelType getSubchannelType(unsigned int index) const =0
Return the type of the subchannel for given subchannel index.
std::unique_ptr< SolutionHandle > _S_flow_soln
virtual void computeh(int iblock) override
Computes Enthalpy per channel for block iblock.
Vec _hc_time_derivative_rhs
static InputParameters validParams()
PetscErrorCode createPetscVector(Vec &v, PetscInt n)
Petsc Functions.
int delta(unsigned int i, unsigned int j)
Delta function, which returns zero if $i j$ and unity if $i=j$.
static InputParameters validParams()
Mat _hc_sweep_enthalpy_mat
virtual Node * getPinNode(unsigned int i_pin, unsigned iz) const =0
Get the pin mesh node for a given pin index and elevation index.
PetscScalar computeInterpolatedValue(PetscScalar topValue, PetscScalar botValue, PetscScalar Peclet=0.0)
const bool _segregated_bool
Segregated solve.
virtual const unsigned int & getNumOfRings() const
Return the number of rings.
virtual const std::vector< unsigned int > & getChannelGaps(unsigned int i_chan) const =0
Return a vector of gap indices for a given channel index.
Vec _hc_cross_derivative_rhs
Real computeAddedHeatDuct(unsigned int i_ch, unsigned int iz)
Function that computes the heat added by the duct, for channel i_ch and cell iz.
Mat _hc_axial_heat_conduction_mat
Vec _hc_sweep_enthalpy_rhs
virtual Node * getChannelNode(unsigned int i_chan, unsigned iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
std::unique_ptr< SolutionHandle > _rho_soln
static const std::string cp
Vec _hc_added_heat_rhs
Enthalpy conservation - source and sink.
unsigned int _n_rings
number of rings of fuel pins
std::vector< Real > _z_grid
axial location of nodes
const std::string & name() const
Triangular subchannel solver.
virtual const Real & getHeatedLength() const
Return heated length.
static const std::string S
Real f(Real x)
Test function for Brents method.
std::unique_ptr< SolutionHandle > _q_prime_soln
static const std::string pitch
const PetscReal & _atol
The absolute convergence tolerance for the ksp linear solver.
PetscScalar computeInterpolationCoefficients(PetscScalar Peclet=0.0)
Functions that computes the interpolation scheme given the Peclet number.
std::shared_ptr< AuxiliarySystem > _aux
Mat _hc_cross_derivative_mat
Enthalpy conservation - cross flux derivative.
virtual Real getSubChannelPeripheralDuctWidth(unsigned int i_ch) override
Function that computes the width of the duct cell that the peripheral subchannel i_ch sees...
const PetscInt & _maxit
The maximum number of iterations to use for the ksp linear solver.
PetscErrorCode createPetscMatrix(Mat &M, PetscInt n, PetscInt m)
std::vector< std::vector< Real > > _gij_map
gap size
const MooseEnum _interpolation_scheme
The interpolation method used in constructing the systems.
std::unique_ptr< SolutionHandle > _Dpin_soln
virtual const std::vector< Real > & getReductionBlockage() const
Get area reduction of blocked subchannels.
Mesh class for triangular, edge and corner subchannels for hexagonal lattice fuel assemblies...
virtual unsigned int getNumOfAxialCells() const
Return the number of axial cells.
Base class for the 1-phase steady-state/transient subchannel solver.
virtual const Real & getFlatToFlat() const
Return flat to flat [m].
std::unique_ptr< SolutionHandle > _mdot_soln
virtual Real getGapWidth(unsigned int axial_index, unsigned int gap_index) const =0
Return gap width for a given gap index.
virtual const std::pair< unsigned int, unsigned int > & getSweepFlowChans(unsigned int i_chan) const
static const std::string Z
const PetscReal & _rtol
The relative convergence tolerance, (relative decrease) for the ksp linear solver.
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual const std::vector< Real > & getZBlockage() const
Get axial location of blockage (in,out) [m].
libMesh::DenseMatrix< Real > & _Wij
CTSub CT_OPERATOR_BINARY CTMul CTCompareLess CTCompareGreater CTCompareEqual _arg template * sqrt(_arg)) *_arg.template D< dtag >()) CT_SIMPLE_UNARY_FUNCTION(tanh
static const std::string alpha
virtual const Real & getCrossflowSign(unsigned int i_chan, unsigned int i_local) const =0
Return a sign for the crossflow given a subchannel index and local neighbor index.
Vec _hc_advective_derivative_rhs
virtual void initializeSolution() override
Function to initialize the solution & geometry fields.
void mooseWarning(Args &&... args) const
const bool _verbose_subchannel
Boolean to printout information related to subchannel solve.
void mooseError(Args &&... args) const
virtual const Real & getWireLeadLength() const
Return the wire lead length.
Mat _hc_advective_derivative_mat
Enthalpy conservation - advective (Eulerian) derivative;.
virtual const std::vector< unsigned int > & getIndexBlockage() const
Get index of blocked subchannels.
const bool _implicit_bool
Flag to define the usage of a implicit or explicit solution.
const ConsoleStream _console
registerMooseObject("SubChannelApp", TriSubChannel1PhaseProblem)
Mat _hc_time_derivative_mat
Enthalpy Enthalpy conservation - time derivative.
const bool _deformation
Flag that activates the effect of deformation (pin/duct) based on the auxvalues for displacement...
libMesh::DenseMatrix< Real > _WijPrime
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
Vec _hc_axial_heat_conduction_rhs
TriSubChannel1PhaseProblem(const InputParameters ¶ms)
virtual Real computeBeta(unsigned int i_gap, unsigned int iz, bool enthalpy) override
Computes turbulent mixing coefficient.
MooseUnits pow(const MooseUnits &, int)
virtual ~TriSubChannel1PhaseProblem()
std::unique_ptr< SolutionHandle > _P_soln
static const std::string k
std::unique_ptr< SolutionHandle > _w_perim_soln
static const std::string cL
virtual const Real & getHeatedLengthEntry() const
Return unheated length at entry.
const SinglePhaseFluidProperties * _fp
Solutions handles and link to TH tables properties.
Mat _hc_sys_h_mat
System matrices.
std::unique_ptr< SolutionHandle > _mu_soln
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 const Real & getWireDiameter() const
Return wire diameter.