12 #include "libmesh/petsc_vector.h" 13 #include "libmesh/dense_matrix.h" 14 #include "libmesh/dense_vector.h" 29 const PetscScalar * xx;
39 for (PetscInt i = 0; i < size; i++)
40 solution_seed(i) = xx[i];
48 for (
int i = 0; i < size; i++)
49 ff[i] = Wij_residual_vector(i);
58 MooseEnum schemes(
"upwind downwind central_difference exponential",
"central_difference");
59 MooseEnum gravity_direction(
"counter_flow co_flow none",
"counter_flow");
63 params.
addRequiredParam<
unsigned int>(
"n_blocks",
"The number of blocks in the axial direction");
65 params.
addParam<
Real>(
"P_tol", 1e-6,
"Pressure tolerance");
66 params.
addParam<
Real>(
"T_tol", 1e-6,
"Temperature tolerance");
67 params.
addParam<
int>(
"T_maxit", 100,
"Maximum number of iterations for inner temperature loop");
68 params.
addParam<PetscReal>(
"rtol", 1e-6,
"Relative tolerance for ksp solver");
69 params.
addParam<PetscReal>(
"atol", 1e-6,
"Absolute tolerance for ksp solver");
70 params.
addParam<PetscReal>(
"dtol", 1e5,
"Divergence tolerance or ksp solver");
71 params.
addParam<PetscInt>(
"maxit", 1e4,
"Maximum number of iterations for ksp solver");
74 "Interpolation scheme used for the method. Default is exponential");
76 "gravity", gravity_direction,
"Direction of gravity. Default is counter_flow");
78 "implicit",
false,
"Boolean to define the use of explicit or implicit solution.");
80 "staggered_pressure",
false,
"Boolean to define the use of explicit or implicit solution.");
82 "segregated",
true,
"Boolean to define whether to use a segregated solution.");
84 "monolithic_thermal",
false,
"Boolean to define whether to use thermal monolithic solve.");
86 "verbose_subchannel",
false,
"Boolean to print out information related to subchannel solve.");
90 "Boolean that activates the deformation effect based on values for: displacement, Dpin");
91 params.
addRequiredParam<
bool>(
"compute_density",
"Flag that enables the calculation of density");
93 "Flag that enables the calculation of viscosity");
96 "Flag that informs whether we solve the Enthalpy/Temperature equations or not");
98 "P_out",
"The postprocessor (or scalar) that provides the value of outlet pressure [Pa]");
99 params.
addRequiredParam<UserObjectName>(
"fp",
"Fluid properties user object name");
107 _n_blocks(getParam<unsigned
int>(
"n_blocks")),
108 _Wij(declareRestartableData<
libMesh::DenseMatrix<
Real>>(
"Wij")),
110 _kij(_subchannel_mesh.getKij()),
112 _compute_density(getParam<bool>(
"compute_density")),
113 _compute_viscosity(getParam<bool>(
"compute_viscosity")),
114 _compute_power(getParam<bool>(
"compute_power")),
115 _pin_mesh_exist(_subchannel_mesh.pinMeshExist()),
116 _duct_mesh_exist(_subchannel_mesh.ductMeshExist()),
117 _P_out(getPostprocessorValue(
"P_out")),
118 _CT(getParam<
Real>(
"CT")),
119 _P_tol(getParam<
Real>(
"P_tol")),
120 _T_tol(getParam<
Real>(
"T_tol")),
121 _T_maxit(getParam<
int>(
"T_maxit")),
122 _rtol(getParam<PetscReal>(
"rtol")),
123 _atol(getParam<PetscReal>(
"atol")),
124 _dtol(getParam<PetscReal>(
"dtol")),
125 _maxit(getParam<PetscInt>(
"maxit")),
126 _interpolation_scheme(getParam<
MooseEnum>(
"interpolation_scheme")),
127 _gravity_direction(getParam<
MooseEnum>(
"gravity")),
128 _dir_grav(computeGravityDir(_gravity_direction)),
129 _implicit_bool(getParam<bool>(
"implicit")),
130 _staggered_pressure_bool(getParam<bool>(
"staggered_pressure")),
131 _segregated_bool(getParam<bool>(
"segregated")),
132 _monolithic_thermal_bool(getParam<bool>(
"monolithic_thermal")),
133 _verbose_subchannel(getParam<bool>(
"verbose_subchannel")),
134 _deformation(getParam<bool>(
"deformation")),
137 _duct_heat_flux_soln(nullptr),
231 ": When implicit number of blocks can't be equal to number of cells. This will " 232 "cause problems with the subchannel interpolation scheme.");
241 _fp = &getUserObject<SinglePhaseFluidProperties>(getParam<UserObjectName>(
"fp"));
270 PetscErrorCode ierr =
cleanUp();
282 LibmeshPetscCall(VecDestroy(&
_Wij_vec));
283 LibmeshPetscCall(VecDestroy(&
_prod));
284 LibmeshPetscCall(VecDestroy(&
_prodp));
352 ": Interpolation scheme should be a string: upwind, downwind, central_difference, " 359 PetscScalar botValue,
363 return alpha * botValue + (1.0 -
alpha) * topValue;
369 unsigned int last_node = (iblock + 1) *
_block_size;
370 unsigned int first_node = iblock *
_block_size + 1;
373 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
375 for (
unsigned int i_gap = 0; i_gap <
_n_gaps; i_gap++)
377 int i =
_n_gaps * (iz - first_node) + i_gap;
378 solution_seed(i) =
_Wij(i_gap, iz);
389 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
391 for (
unsigned int i_gap = 0; i_gap <
_n_gaps; i_gap++)
402 unsigned int last_node = (iblock + 1) *
_block_size;
403 unsigned int first_node = iblock *
_block_size + 1;
407 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
409 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
414 unsigned int counter = 0;
428 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
430 unsigned int iz_ind = iz - first_node;
431 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
434 unsigned int counter = 0;
438 PetscInt col = i_gap +
_n_gaps * iz_ind;
445 LibmeshPetscCall(MatAssemblyBegin(
_mc_sumWij_mat, MAT_FINAL_ASSEMBLY));
446 LibmeshPetscCall(MatAssemblyEnd(
_mc_sumWij_mat, MAT_FINAL_ASSEMBLY));
452 LibmeshPetscCall(VecDuplicate(
_Wij_vec, &loc_Wij));
456 LibmeshPetscCall(populateSolutionChan<SolutionHandle>(
458 LibmeshPetscCall(VecDestroy(&loc_prod));
459 LibmeshPetscCall(VecDestroy(&loc_Wij));
467 unsigned int last_node = (iblock + 1) *
_block_size;
468 unsigned int first_node = iblock *
_block_size + 1;
471 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
474 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
478 auto volume = dz * (*_S_flow_soln)(node_in);
481 auto mdot_out = (*_mdot_soln)(node_in) - (*
_SumWij_soln)(node_out)-time_term;
486 " : Calculation of negative mass flow mdot_out = : ",
490 " - Implicit solves are required for recirculating flow.");
498 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
501 auto iz_ind = iz - first_node;
502 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
506 auto volume = dz * (*_S_flow_soln)(node_in);
511 PetscScalar value_vec = -1.0 * time_term;
516 if (iz == first_node)
518 PetscScalar value_vec = (*_mdot_soln)(node_in);
527 PetscScalar
value = -1.0;
535 PetscScalar
value = 1.0;
542 PetscScalar value_vec_2 = -1.0 * (*_SumWij_soln)(node_out);
558 LibmeshPetscCall(KSPCreate(PETSC_COMM_SELF, &ksploc));
560 LibmeshPetscCall(KSPGetPC(ksploc, &pc));
561 LibmeshPetscCall(PCSetType(pc, PCJACOBI));
563 LibmeshPetscCall(KSPSetFromOptions(ksploc));
565 LibmeshPetscCall(populateSolutionChan<SolutionHandle>(
568 LibmeshPetscCall(KSPDestroy(&ksploc));
569 LibmeshPetscCall(VecDestroy(&sol));
577 unsigned int last_node = (iblock + 1) *
_block_size;
578 unsigned int first_node = iblock *
_block_size + 1;
581 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
585 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
589 auto rho_in = (*_rho_soln)(node_in);
590 auto rho_out = (*_rho_soln)(node_out);
591 auto mu_in = (*_mu_soln)(node_in);
592 auto S = (*_S_flow_soln)(node_in);
593 auto w_perim = (*_w_perim_soln)(node_in);
595 auto Dh_i = 4.0 *
S / w_perim;
596 auto time_term =
_TR * ((*_mdot_soln)(node_out)-
_mdot_soln->old(node_out)) * dz /
_dt -
601 auto mass_term2 = -2.0 * (*_mdot_soln)(node_out) * (*
_SumWij_soln)(node_out) /
S / rho_in;
602 auto crossflow_term = 0.0;
603 auto turbulent_term = 0.0;
604 unsigned int counter = 0;
608 unsigned int ii_ch = chans.first;
609 unsigned int jj_ch = chans.second;
614 auto rho_i = (*_rho_soln)(node_in_i);
615 auto rho_j = (*_rho_soln)(node_in_j);
616 auto Si = (*_S_flow_soln)(node_in_i);
617 auto Sj = (*_S_flow_soln)(node_in_j);
620 if (
_Wij(i_gap, iz) > 0.0)
621 u_star = (*_mdot_soln)(node_out_i) / Si / rho_i;
623 u_star = (*_mdot_soln)(node_out_j) / Sj / rho_j;
628 turbulent_term +=
_WijPrime(i_gap, iz) * (2 * (*_mdot_soln)(node_out) / rho_in /
S -
633 turbulent_term *=
_CT;
634 auto Re = (((*_mdot_soln)(node_in) /
S) * Dh_i / mu_in);
643 ki = k_grid[i_ch][iz - 1];
645 ki = k_grid[i_ch][iz];
646 auto friction_term = (fi * dz / Dh_i + ki) * 0.5 *
648 (
S * (*_rho_soln)(node_out));
650 auto DP =
std::pow(
S, -1.0) * (time_term + mass_term1 + mass_term2 + crossflow_term +
651 turbulent_term + friction_term + gravity_term);
669 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
673 auto iz_ind = iz - first_node;
674 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
681 PetscScalar Pe = 0.5;
685 auto S_in = (*_S_flow_soln)(node_in);
686 auto S_out = (*_S_flow_soln)(node_out);
688 auto w_perim_in = (*_w_perim_soln)(node_in);
689 auto w_perim_out = (*_w_perim_soln)(node_out);
693 auto mu_in = (*_mu_soln)(node_in);
694 auto mu_out = (*_mu_soln)(node_out);
696 auto Dh_i = 4.0 * S_interp / w_perim_interp;
698 auto Re = ((mdot_loc / S_interp) * Dh_i / mu_interp);
707 ki = k_grid[i_ch][iz - 1];
709 ki = k_grid[i_ch][iz];
710 Pe = 1.0 / ((fi * dz / Dh_i + ki) * 0.5) * mdot_loc / std::abs(mdot_loc);
715 auto rho_in = (*_rho_soln)(node_in);
716 auto rho_out = (*_rho_soln)(node_out);
720 auto mu_in = (*_mu_soln)(node_in);
721 auto mu_out = (*_mu_soln)(node_out);
725 auto S_in = (*_S_flow_soln)(node_in);
726 auto S_out = (*_S_flow_soln)(node_out);
730 auto w_perim_in = (*_w_perim_soln)(node_in);
731 auto w_perim_out = (*_w_perim_soln)(node_out);
735 auto Dh_i = 4.0 * S_interp / w_perim_interp;
738 if (iz == first_node)
740 PetscScalar value_vec_tt = -1.0 *
_TR *
alpha * (*_mdot_soln)(node_in)*dz /
_dt;
748 PetscInt col_tt = i_ch +
_n_channels * (iz_ind - 1);
750 LibmeshPetscCall(MatSetValues(
757 PetscScalar value_tt =
_TR * (1.0 -
alpha) * dz /
_dt;
758 LibmeshPetscCall(MatSetValues(
762 PetscScalar mdot_old_interp =
764 PetscScalar value_vec_tt =
_TR * mdot_old_interp * dz /
_dt;
770 if (iz == first_node)
774 LibmeshPetscCall(VecSetValues(
780 PetscInt col_at = i_ch +
_n_channels * (iz_ind - 1);
781 PetscScalar value_at = -1.0 * std::abs((*
_mdot_soln)(node_in)) / (S_in * rho_in);
782 LibmeshPetscCall(MatSetValues(
789 PetscScalar value_at = std::abs((*
_mdot_soln)(node_out)) / (S_out * rho_out);
790 LibmeshPetscCall(MatSetValues(
794 unsigned int counter = 0;
795 unsigned int cross_index = iz;
799 unsigned int ii_ch = chans.first;
800 unsigned int jj_ch = chans.second;
815 if (
_Wij(i_gap, cross_index) > 0.0)
817 if (iz == first_node)
819 u_star = (*_mdot_soln)(node_in_i) / S_i / rho_i;
820 PetscScalar value_vec_ct = -1.0 *
alpha *
822 _Wij(i_gap, cross_index) * u_star;
824 LibmeshPetscCall(VecSetValues(
830 _Wij(i_gap, cross_index) / S_i / rho_i;
832 PetscInt col_ct = ii_ch +
_n_channels * (iz_ind - 1);
833 LibmeshPetscCall(MatSetValues(
836 PetscScalar value_ct = (1.0 -
alpha) *
838 _Wij(i_gap, cross_index) / S_i / rho_i;
841 LibmeshPetscCall(MatSetValues(
844 else if (
_Wij(i_gap, cross_index) < 0.0)
846 if (iz == first_node)
848 u_star = (*_mdot_soln)(node_in_j) / S_j / rho_j;
849 PetscScalar value_vec_ct = -1.0 *
alpha *
851 _Wij(i_gap, cross_index) * u_star;
853 LibmeshPetscCall(VecSetValues(
859 _Wij(i_gap, cross_index) / S_j / rho_j;
861 PetscInt col_ct = jj_ch +
_n_channels * (iz_ind - 1);
862 LibmeshPetscCall(MatSetValues(
865 PetscScalar value_ct = (1.0 -
alpha) *
867 _Wij(i_gap, cross_index) / S_j / rho_j;
870 LibmeshPetscCall(MatSetValues(
874 if (iz == first_node)
876 PetscScalar value_vec_ct = -2.0 *
alpha * (*_mdot_soln)(node_in)*
_CT *
877 _WijPrime(i_gap, cross_index) / (rho_interp * S_interp);
878 value_vec_ct +=
alpha * (*_mdot_soln)(node_in_j)*
_CT *
_WijPrime(i_gap, cross_index) /
880 value_vec_ct +=
alpha * (*_mdot_soln)(node_in_i)*
_CT *
_WijPrime(i_gap, cross_index) /
888 PetscScalar value_center_ct =
891 PetscInt col_ct = i_ch +
_n_channels * (iz_ind - 1);
892 LibmeshPetscCall(MatSetValues(
895 PetscScalar value_left_ct =
899 LibmeshPetscCall(MatSetValues(
902 PetscScalar value_right_ct =
906 LibmeshPetscCall(MatSetValues(
910 PetscScalar value_center_ct =
911 2.0 * (1.0 -
alpha) *
_CT *
_WijPrime(i_gap, cross_index) / (rho_interp * S_interp);
914 LibmeshPetscCall(MatSetValues(
917 PetscScalar value_left_ct =
921 LibmeshPetscCall(MatSetValues(
924 PetscScalar value_right_ct =
928 LibmeshPetscCall(MatSetValues(
934 PetscScalar mdot_interp =
936 auto Re = ((mdot_interp / S_interp) * Dh_i / mu_interp);
945 ki = k_grid[i_ch][iz - 1];
947 ki = k_grid[i_ch][iz];
948 auto coef = (fi * dz / Dh_i + ki) * 0.5 * std::abs((*
_mdot_soln)(node_out)) /
949 (S_interp * rho_interp);
950 if (iz == first_node)
952 PetscScalar value_vec = -1.0 *
alpha * coef * (*_mdot_soln)(node_in);
974 PetscScalar value_vec =
_dir_grav * -1.0 *
_g_grav * rho_interp * dz * S_interp;
976 LibmeshPetscCall(VecSetValues(
_amc_gravity_rhs, 1, &row_vec, &value_vec, ADD_VALUES));
993 #if !PETSC_VERSION_LESS_THAN(3, 15, 0) 1035 LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
1042 LibmeshPetscCall(VecGetArray(ls, &xx));
1043 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
1045 auto iz_ind = iz - first_node;
1046 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1053 auto S_in = (*_S_flow_soln)(node_in);
1054 auto S_out = (*_S_flow_soln)(node_out);
1070 LibmeshPetscCall(VecDestroy(&ls));
1078 unsigned int last_node = (iblock + 1) *
_block_size;
1079 unsigned int first_node = iblock *
_block_size + 1;
1084 for (
unsigned int iz = last_node; iz > first_node - 1; iz--)
1087 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1098 for (
unsigned int iz = last_node; iz > first_node - 1; iz--)
1101 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1109 PetscScalar Pe = 0.5;
1111 if (iz == last_node)
1130 for (
unsigned int iz = last_node; iz > first_node - 1; iz--)
1132 auto iz_ind = iz - first_node;
1134 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1140 auto S_in = (*_S_flow_soln)(node_in);
1141 auto S_out = (*_S_flow_soln)(node_out);
1147 PetscScalar
value = -1.0 * S_interp;
1151 if (iz == last_node)
1153 PetscScalar
value = -1.0 * (*_P_soln)(node_out)*S_interp;
1161 PetscScalar
value = 1.0 * S_interp;
1168 auto dp_out = (*_DP_soln)(node_out);
1169 PetscScalar value_v = -1.0 * dp_out * S_interp;
1185 LibmeshPetscCall(KSPCreate(PETSC_COMM_SELF, &ksploc));
1187 LibmeshPetscCall(KSPGetPC(ksploc, &pc));
1188 LibmeshPetscCall(PCSetType(pc, PCJACOBI));
1190 LibmeshPetscCall(KSPSetFromOptions(ksploc));
1193 LibmeshPetscCall(VecGetArray(sol, &xx));
1195 for (
unsigned int iz = last_node; iz > first_node - 1; iz--)
1197 auto iz_ind = iz - first_node;
1198 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1206 LibmeshPetscCall(KSPDestroy(&ksploc));
1207 LibmeshPetscCall(VecDestroy(&sol));
1213 for (
unsigned int iz = last_node; iz > first_node - 1; iz--)
1215 auto iz_ind = iz - first_node;
1217 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1223 auto S_in = (*_S_flow_soln)(node_in);
1224 auto S_out = (*_S_flow_soln)(node_out);
1230 PetscScalar
value = -1.0 * S_interp;
1234 if (iz == last_node)
1236 PetscScalar
value = -1.0 * (*_P_soln)(node_out)*S_interp;
1240 auto dp_out = (*_DP_soln)(node_out);
1241 PetscScalar value_v = -1.0 * dp_out / 2.0 * S_interp;
1250 PetscScalar
value = 1.0 * S_interp;
1256 auto dp_in = (*_DP_soln)(node_in);
1257 auto dp_out = (*_DP_soln)(node_out);
1259 PetscScalar value_v = -1.0 * dp_interp * S_interp;
1271 _console <<
"Block: " << iblock <<
" - Axial momentum pressure force matrix assembled" 1280 LibmeshPetscCall(KSPCreate(PETSC_COMM_SELF, &ksploc));
1282 LibmeshPetscCall(KSPGetPC(ksploc, &pc));
1283 LibmeshPetscCall(PCSetType(pc, PCJACOBI));
1285 LibmeshPetscCall(KSPSetFromOptions(ksploc));
1288 LibmeshPetscCall(VecGetArray(sol, &xx));
1290 for (
unsigned int iz = last_node; iz > first_node - 1; iz--)
1292 auto iz_ind = iz - first_node;
1293 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1301 LibmeshPetscCall(KSPDestroy(&ksploc));
1302 LibmeshPetscCall(VecDestroy(&sol));
1311 unsigned int last_node = (iblock + 1) *
_block_size;
1312 unsigned int first_node = iblock *
_block_size + 1;
1313 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
1315 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1326 unsigned int last_node = (iblock + 1) *
_block_size;
1327 unsigned int first_node = iblock *
_block_size + 1;
1330 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1336 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
1338 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1349 unsigned int last_node = (iblock + 1) *
_block_size;
1350 unsigned int first_node = iblock *
_block_size + 1;
1353 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1359 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
1361 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1375 unsigned int last_node = (iblock + 1) *
_block_size;
1376 unsigned int first_node = iblock *
_block_size + 1;
1378 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
1381 for (
unsigned int i_gap = 0; i_gap <
_n_gaps; i_gap++)
1384 unsigned int i_ch = chans.first;
1385 unsigned int j_ch = chans.second;
1390 auto rho_i = (*_rho_soln)(node_in_i);
1391 auto rho_j = (*_rho_soln)(node_in_j);
1392 auto Si = (*_S_flow_soln)(node_in_i);
1393 auto Sj = (*_S_flow_soln)(node_in_j);
1397 auto friction_term =
_kij *
_Wij(i_gap, iz) * std::abs(
_Wij(i_gap, iz));
1398 auto DPij = (*_P_soln)(node_in_i) - (*
_P_soln)(node_in_j);
1400 auto rho_star = 0.0;
1401 if (
_Wij(i_gap, iz) > 0.0)
1403 else if (
_Wij(i_gap, iz) < 0.0)
1406 rho_star = (rho_i + rho_j) / 2.0;
1407 auto mass_term_out =
1408 (*_mdot_soln)(node_out_i) / Si / rho_i + (*
_mdot_soln)(node_out_j) / Sj / rho_j;
1410 (*_mdot_soln)(node_in_i) / Si / rho_i + (*
_mdot_soln)(node_in_j) / Sj / rho_j;
1411 auto term_out = Sij * rho_star * (Lij / dz) * mass_term_out *
_Wij(i_gap, iz);
1412 auto term_in = Sij * rho_star * (Lij / dz) * mass_term_in *
_Wij(i_gap, iz - 1);
1413 auto inertia_term = term_out - term_in;
1414 auto pressure_term = 2 *
std::pow(Sij, 2.0) * DPij * rho_star;
1419 time_term + friction_term + inertia_term - pressure_term;
1436 unsigned int last_node = (iblock + 1) *
_block_size;
1437 unsigned int first_node = iblock *
_block_size + 1;
1439 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
1442 auto iz_ind = iz - first_node;
1443 for (
unsigned int i_gap = 0; i_gap <
_n_gaps; i_gap++)
1446 unsigned int i_ch = chans.first;
1447 unsigned int j_ch = chans.second;
1454 auto rho_i_in = (*_rho_soln)(node_in_i);
1455 auto rho_i_out = (*_rho_soln)(node_out_i);
1457 auto rho_j_in = (*_rho_soln)(node_in_j);
1458 auto rho_j_out = (*_rho_soln)(node_out_j);
1462 auto S_i_in = (*_S_flow_soln)(node_in_i);
1463 auto S_i_out = (*_S_flow_soln)(node_out_i);
1464 auto S_j_in = (*_S_flow_soln)(node_in_j);
1465 auto S_j_out = (*_S_flow_soln)(node_out_j);
1472 auto rho_star = 0.0;
1473 if (
_Wij(i_gap, iz) > 0.0)
1474 rho_star = rho_i_interp;
1475 else if (
_Wij(i_gap, iz) < 0.0)
1476 rho_star = rho_j_interp;
1478 rho_star = (rho_i_interp + rho_j_interp) / 2.0;
1481 PetscScalar time_factor =
_TR * Lij * Sij * rho_star /
_dt;
1482 PetscInt row_td = i_gap +
_n_gaps * iz_ind;
1483 PetscInt col_td = i_gap +
_n_gaps * iz_ind;
1484 PetscScalar value_td = time_factor;
1485 LibmeshPetscCall(MatSetValues(
1487 PetscScalar value_td_rhs = time_factor *
_Wij_old(i_gap, iz);
1492 PetscScalar Pe = 0.5;
1494 auto mass_term_out = (*_mdot_soln)(node_out_i) / S_i_out / rho_i_out +
1495 (*
_mdot_soln)(node_out_j) / S_j_out / rho_j_out;
1496 auto mass_term_in = (*_mdot_soln)(node_in_i) / S_i_in / rho_i_in +
1497 (*
_mdot_soln)(node_in_j) / S_j_in / rho_j_in;
1498 auto term_out = Sij * rho_star * (Lij / dz) * mass_term_out / 2.0;
1499 auto term_in = Sij * rho_star * (Lij / dz) * mass_term_in / 2.0;
1500 if (iz == first_node)
1502 PetscInt row_ad = i_gap +
_n_gaps * iz_ind;
1503 PetscScalar value_ad = term_in *
alpha *
_Wij(i_gap, iz - 1);
1507 PetscInt col_ad = i_gap +
_n_gaps * iz_ind;
1508 value_ad = -1.0 * term_in * (1.0 -
alpha) + term_out *
alpha;
1509 LibmeshPetscCall(MatSetValues(
1512 col_ad = i_gap +
_n_gaps * (iz_ind + 1);
1513 value_ad = term_out * (1.0 -
alpha);
1514 LibmeshPetscCall(MatSetValues(
1517 else if (iz == last_node)
1519 PetscInt row_ad = i_gap +
_n_gaps * iz_ind;
1520 PetscInt col_ad = i_gap +
_n_gaps * (iz_ind - 1);
1521 PetscScalar value_ad = -1.0 * term_in *
alpha;
1522 LibmeshPetscCall(MatSetValues(
1525 col_ad = i_gap +
_n_gaps * iz_ind;
1526 value_ad = -1.0 * term_in * (1.0 -
alpha) + term_out *
alpha;
1527 LibmeshPetscCall(MatSetValues(
1530 value_ad = -1.0 * term_out * (1.0 -
alpha) *
_Wij(i_gap, iz);
1536 PetscInt row_ad = i_gap +
_n_gaps * iz_ind;
1537 PetscInt col_ad = i_gap +
_n_gaps * (iz_ind - 1);
1538 PetscScalar value_ad = -1.0 * term_in *
alpha;
1539 LibmeshPetscCall(MatSetValues(
1542 col_ad = i_gap +
_n_gaps * iz_ind;
1543 value_ad = -1.0 * term_in * (1.0 -
alpha) + term_out *
alpha;
1544 LibmeshPetscCall(MatSetValues(
1547 col_ad = i_gap +
_n_gaps * (iz_ind + 1);
1548 value_ad = term_out * (1.0 -
alpha);
1549 LibmeshPetscCall(MatSetValues(
1553 PetscInt row_ff = i_gap +
_n_gaps * iz_ind;
1554 PetscInt col_ff = i_gap +
_n_gaps * iz_ind;
1555 PetscScalar value_ff =
_kij * std::abs(
_Wij(i_gap, iz)) / 2.0;
1556 LibmeshPetscCall(MatSetValues(
1564 PetscScalar pressure_factor =
std::pow(Sij, 2.0) * rho_star;
1565 PetscInt row_pf = i_gap +
_n_gaps * iz_ind;
1567 PetscScalar value_pf = -1.0 *
alpha * pressure_factor;
1571 value_pf =
alpha * pressure_factor;
1575 if (iz == last_node)
1577 PetscInt row_pf = i_gap +
_n_gaps * iz_ind;
1578 PetscScalar value_pf = (1.0 -
alpha) * pressure_factor * (*
_P_soln)(node_out_i);
1581 value_pf = -1.0 * (1.0 -
alpha) * pressure_factor * (*
_P_soln)(node_out_j);
1587 row_pf = i_gap +
_n_gaps * iz_ind;
1589 value_pf = -1.0 * (1.0 -
alpha) * pressure_factor;
1590 LibmeshPetscCall(MatSetValues(
1593 value_pf = (1.0 -
alpha) * pressure_factor;
1594 LibmeshPetscCall(MatSetValues(
1600 PetscScalar pressure_factor =
std::pow(Sij, 2.0) * rho_star;
1601 PetscInt row_pf = i_gap +
_n_gaps * iz_ind;
1603 PetscScalar value_pf = -1.0 * pressure_factor;
1607 value_pf = pressure_factor;
1627 #if !PETSC_VERSION_LESS_THAN(3, 15, 0) 1664 LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
1670 LibmeshPetscCall(VecAXPY(sol_holder_W, 1.0, sol_holder_P));
1672 LibmeshPetscCall(VecGetArray(sol_holder_W, &xx));
1673 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
1675 auto iz_ind = iz - first_node;
1676 for (
unsigned int i_gap = 0; i_gap <
_n_gaps; i_gap++)
1681 LibmeshPetscCall(VecDestroy(&sol_holder_P));
1682 LibmeshPetscCall(VecDestroy(&sol_holder_W));
1690 unsigned int last_node = (iblock + 1) *
_block_size;
1691 unsigned int first_node = iblock *
_block_size + 1;
1692 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
1695 for (
unsigned int i_gap = 0; i_gap <
_n_gaps; i_gap++)
1698 unsigned int i_ch = chans.first;
1699 unsigned int j_ch = chans.second;
1704 auto Si_in = (*_S_flow_soln)(node_in_i);
1705 auto Sj_in = (*_S_flow_soln)(node_in_j);
1706 auto Si_out = (*_S_flow_soln)(node_out_i);
1707 auto Sj_out = (*_S_flow_soln)(node_out_j);
1709 auto Sij = dz * gap;
1711 0.5 * (((*_mdot_soln)(node_in_i) + (*
_mdot_soln)(node_in_j)) / (Si_in + Sj_in) +
1717 _WijPrime(i_gap, iz) = beta * avg_massflux * Sij;
1721 auto iz_ind = iz - first_node;
1722 PetscScalar base_value = beta * 0.5 * Sij;
1725 if (iz == first_node)
1727 PetscScalar value_tl = -1.0 * base_value / (Si_in + Sj_in) *
1729 PetscInt row = i_gap +
_n_gaps * iz_ind;
1735 PetscScalar value_tl = base_value / (Si_in + Sj_in);
1736 PetscInt row = i_gap +
_n_gaps * iz_ind;
1738 PetscInt col_ich = i_ch +
_n_channels * (iz_ind - 1);
1739 LibmeshPetscCall(MatSetValues(
1742 PetscInt col_jch = j_ch +
_n_channels * (iz_ind - 1);
1743 LibmeshPetscCall(MatSetValues(
1748 PetscScalar value_bl = base_value / (Si_out + Sj_out);
1749 PetscInt row = i_gap +
_n_gaps * iz_ind;
1752 LibmeshPetscCall(MatSetValues(
1756 LibmeshPetscCall(MatSetValues(
1771 LibmeshPetscCall(VecDuplicate(
_Wij_vec, &loc_Wij));
1772 LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
1778 LibmeshPetscCall(VecDestroy(&loc_prod));
1779 LibmeshPetscCall(VecDestroy(&loc_Wij));
1786 unsigned int last_node = (iblock + 1) *
_block_size;
1787 unsigned int first_node = iblock *
_block_size + 1;
1791 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
1793 for (
unsigned int i_gap = 0; i_gap <
_n_gaps; i_gap++)
1795 _Wij(i_gap, iz) = solution(i);
1816 for (
unsigned int i_gap = 0; i_gap <
_n_gaps; i_gap++)
1822 return Wij_residual_vector;
1837 LibmeshPetscCall(SNESCreate(PETSC_COMM_SELF, &snes));
1838 LibmeshPetscCall(VecCreate(PETSC_COMM_SELF, &
x));
1840 LibmeshPetscCall(VecSetFromOptions(
x));
1841 LibmeshPetscCall(VecDuplicate(
x, &r));
1843 #if PETSC_VERSION_LESS_THAN(3, 13, 0) 1844 LibmeshPetscCall(PetscOptionsSetValue(PETSC_NULL,
"-snes_mf", PETSC_NULL));
1846 LibmeshPetscCall(SNESSetUseMatrixFree(snes, PETSC_FALSE, PETSC_TRUE));
1849 ctx.iblock = iblock;
1852 LibmeshPetscCall(SNESGetKSP(snes, &ksp));
1853 LibmeshPetscCall(KSPGetPC(ksp, &pc));
1854 LibmeshPetscCall(PCSetType(pc, PCNONE));
1856 LibmeshPetscCall(SNESSetFromOptions(snes));
1857 LibmeshPetscCall(VecGetArray(
x, &xx));
1860 xx[i] = solution(i);
1862 LibmeshPetscCall(VecRestoreArray(
x, &xx));
1864 LibmeshPetscCall(SNESSolve(snes, NULL,
x));
1865 LibmeshPetscCall(VecGetArray(
x, &xx));
1869 LibmeshPetscCall(VecRestoreArray(
x, &xx));
1870 LibmeshPetscCall(VecDestroy(&
x));
1871 LibmeshPetscCall(VecDestroy(&r));
1872 LibmeshPetscCall(SNESDestroy(&snes));
1879 mooseAssert(iz > 0,
"Trapezoidal rule requires starting at index 1 at least");
1890 auto heat_rate_in = (*_duct_heat_flux_soln)(node_in_duct);
1891 auto heat_rate_out = (*_duct_heat_flux_soln)(node_out_duct);
1893 return 0.5 * (heat_rate_in + heat_rate_out) * dz * width;
1909 bool lag_block_thermal_solve =
true;
1917 std::vector<Mat> mat_array(Q * Q);
1918 std::vector<Vec> vec_array(Q);
1921 bool _axial_mass_flow_tight_coupling =
true;
1922 bool _pressure_axial_momentum_tight_coupling =
true;
1923 bool _pressure_cross_momentum_tight_coupling =
true;
1924 unsigned int first_node = iblock *
_block_size + 1;
1925 unsigned int last_node = (iblock + 1) *
_block_size;
1946 _console <<
"Starting nested system." << std::endl;
1947 _console <<
"Number of simultaneous variables: " << Q << std::endl;
1950 PetscInt field_num = 0;
1953 LibmeshPetscCall(MatAssemblyBegin(mat_array[Q * field_num + 0], MAT_FINAL_ASSEMBLY));
1954 LibmeshPetscCall(MatAssemblyEnd(mat_array[Q * field_num + 0], MAT_FINAL_ASSEMBLY));
1955 mat_array[Q * field_num + 1] = NULL;
1956 if (_axial_mass_flow_tight_coupling)
1958 LibmeshPetscCall(MatDuplicate(
_mc_sumWij_mat, MAT_COPY_VALUES, &mat_array[Q * field_num + 2]));
1959 LibmeshPetscCall(MatAssemblyBegin(mat_array[Q * field_num + 2], MAT_FINAL_ASSEMBLY));
1960 LibmeshPetscCall(MatAssemblyEnd(mat_array[Q * field_num + 2], MAT_FINAL_ASSEMBLY));
1964 mat_array[Q * field_num + 2] = NULL;
1968 mat_array[Q * field_num + 3] = NULL;
1972 if (!_axial_mass_flow_tight_coupling)
1976 LibmeshPetscCall(VecSet(sumWij_loc, 0.0));
1977 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
1979 auto iz_ind = iz - first_node;
1980 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1984 PetscScalar value_vec_2 = -1.0 * (*_SumWij_soln)(node_out);
1986 LibmeshPetscCall(VecSetValues(sumWij_loc, 1, &row_vec_2, &value_vec_2, ADD_VALUES));
1989 LibmeshPetscCall(VecAXPY(vec_array[field_num], 1.0, sumWij_loc));
1990 LibmeshPetscCall(VecDestroy(&sumWij_loc));
1994 _console <<
"Mass ok." << std::endl;
1997 if (_pressure_axial_momentum_tight_coupling)
2000 MatDuplicate(
_amc_sys_mdot_mat, MAT_COPY_VALUES, &mat_array[Q * field_num + 0]));
2001 LibmeshPetscCall(MatAssemblyBegin(mat_array[Q * field_num + 0], MAT_FINAL_ASSEMBLY));
2002 LibmeshPetscCall(MatAssemblyEnd(mat_array[Q * field_num + 0], MAT_FINAL_ASSEMBLY));
2006 mat_array[Q * field_num + 0] = NULL;
2010 LibmeshPetscCall(MatAssemblyBegin(mat_array[Q * field_num + 1], MAT_FINAL_ASSEMBLY));
2011 LibmeshPetscCall(MatAssemblyEnd(mat_array[Q * field_num + 1], MAT_FINAL_ASSEMBLY));
2012 mat_array[Q * field_num + 2] = NULL;
2015 mat_array[Q * field_num + 3] = NULL;
2019 if (_pressure_axial_momentum_tight_coupling)
2025 unsigned int last_node = (iblock + 1) *
_block_size;
2026 unsigned int first_node = iblock *
_block_size + 1;
2027 LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
2033 LibmeshPetscCall(VecAXPY(vec_array[field_num], -1.0, ls));
2034 LibmeshPetscCall(VecDestroy(&ls));
2038 _console <<
"Lin mom OK." << std::endl;
2042 mat_array[Q * field_num + 0] = NULL;
2043 if (_pressure_cross_momentum_tight_coupling)
2047 LibmeshPetscCall(MatAssemblyBegin(mat_array[Q * field_num + 1], MAT_FINAL_ASSEMBLY));
2048 LibmeshPetscCall(MatAssemblyEnd(mat_array[Q * field_num + 1], MAT_FINAL_ASSEMBLY));
2052 mat_array[Q * field_num + 1] = NULL;
2055 LibmeshPetscCall(MatDuplicate(
_cmc_sys_Wij_mat, MAT_COPY_VALUES, &mat_array[Q * field_num + 2]));
2056 LibmeshPetscCall(MatAssemblyBegin(mat_array[Q * field_num + 2], MAT_FINAL_ASSEMBLY));
2057 LibmeshPetscCall(MatAssemblyEnd(mat_array[Q * field_num + 2], MAT_FINAL_ASSEMBLY));
2060 mat_array[Q * field_num + 3] = NULL;
2065 if (_pressure_cross_momentum_tight_coupling)
2073 LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
2078 LibmeshPetscCall(VecScale(sol_holder_P, 1.0));
2079 LibmeshPetscCall(VecAXPY(vec_array[field_num], 1.0, sol_holder_P));
2080 LibmeshPetscCall(VecDestroy(&sol_holder_P));
2084 _console <<
"Cross mom ok." << std::endl;
2090 mat_array[Q * field_num + 0] = NULL;
2091 mat_array[Q * field_num + 1] = NULL;
2092 mat_array[Q * field_num + 2] = NULL;
2093 LibmeshPetscCall(MatDuplicate(
_hc_sys_h_mat, MAT_COPY_VALUES, &mat_array[Q * field_num + 3]));
2094 if (lag_block_thermal_solve)
2096 LibmeshPetscCall(MatZeroEntries(mat_array[Q * field_num + 3]));
2097 LibmeshPetscCall(MatShift(mat_array[Q * field_num + 3], 1.0));
2099 LibmeshPetscCall(MatAssemblyBegin(mat_array[Q * field_num + 3], MAT_FINAL_ASSEMBLY));
2100 LibmeshPetscCall(MatAssemblyEnd(mat_array[Q * field_num + 3], MAT_FINAL_ASSEMBLY));
2101 LibmeshPetscCall(VecDuplicate(
_hc_sys_h_rhs, &vec_array[field_num]));
2102 LibmeshPetscCall(VecCopy(
_hc_sys_h_rhs, vec_array[field_num]));
2103 if (lag_block_thermal_solve)
2105 LibmeshPetscCall(VecZeroEntries(vec_array[field_num]));
2106 LibmeshPetscCall(VecShift(vec_array[field_num], 1.0));
2110 _console <<
"Energy ok." << std::endl;
2118 LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
2128 LibmeshPetscCall(VecSet(unity_vec, 1.0));
2137 LibmeshPetscCall(VecSet(unity_vec_Wij, 1.0));
2140 Vec _Wij_old_loc_vec;
2142 LibmeshPetscCall(MatMult(mat_array[Q],
_prod, mdot_estimate));
2143 LibmeshPetscCall(MatGetDiagonal(mat_array[Q + 1], pmat_diag));
2144 LibmeshPetscCall(VecAXPY(pmat_diag, 1e-10, unity_vec));
2145 LibmeshPetscCall(VecPointwiseDivide(p_estimate, mdot_estimate, pmat_diag));
2146 LibmeshPetscCall(MatMult(mat_array[2 * Q + 1], p_estimate, sol_holder_P));
2148 LibmeshPetscCall(MatGetDiagonal(mat_array[2 * Q + 2], diag_Wij_loc));
2149 LibmeshPetscCall(VecAXPY(diag_Wij_loc, 1e-10, unity_vec_Wij));
2150 LibmeshPetscCall(VecPointwiseDivide(Wij_estimate, sol_holder_P, diag_Wij_loc));
2153 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
2155 auto iz_ind = iz - first_node;
2156 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
2158 PetscScalar sumWij = 0.0;
2159 unsigned int counter = 0;
2163 unsigned int i_ch_loc = chans.first;
2164 PetscInt row_vec = i_ch_loc +
_n_channels * iz_ind;
2165 PetscScalar loc_Wij_value;
2166 LibmeshPetscCall(VecGetValues(sol_holder_P, 1, &row_vec, &loc_Wij_value));
2171 LibmeshPetscCall(VecSetValues(sumWij_loc, 1, &row_vec, &sumWij, INSERT_VALUES));
2175 PetscScalar min_mdot;
2176 LibmeshPetscCall(VecAbs(
_prod));
2177 LibmeshPetscCall(VecMin(
_prod, NULL, &min_mdot));
2179 _console <<
"Minimum estimated mdot: " << min_mdot << std::endl;
2181 LibmeshPetscCall(VecAbs(sumWij_loc));
2182 LibmeshPetscCall(VecMax(sumWij_loc, NULL, &
_max_sumWij));
2188 _Wij_loc_vec,
_Wij, first_node, last_node,
_n_gaps));
2189 LibmeshPetscCall(VecAbs(_Wij_loc_vec));
2192 LibmeshPetscCall(VecAbs(_Wij_old_loc_vec));
2193 LibmeshPetscCall(VecAXPY(_Wij_loc_vec, -1.0, _Wij_old_loc_vec));
2194 PetscScalar relax_factor;
2195 LibmeshPetscCall(VecAbs(_Wij_loc_vec));
2196 #if !PETSC_VERSION_LESS_THAN(3, 16, 0) 2197 LibmeshPetscCall(VecMean(_Wij_loc_vec, &relax_factor));
2199 VecSum(_Wij_loc_vec, &relax_factor);
2204 _console <<
"Relax base value: " << relax_factor << std::endl;
2206 PetscScalar resistance_relaxation = 0.9;
2214 if (_added_K < 10 && _added_K >= 1.0)
2216 if (_added_K < 1.0 && _added_K >= 0.1)
2218 if (_added_K < 0.1 && _added_K >= 0.01)
2220 if (_added_K < 1e-2 && _added_K >= 1e-3)
2226 LibmeshPetscCall(VecScale(unity_vec_Wij,
_added_K));
2230 LibmeshPetscCall(MatDiagonalSet(mat_array[2 * Q + 2], unity_vec_Wij, ADD_VALUES));
2231 LibmeshPetscCall(VecDestroy(&mdot_estimate));
2232 LibmeshPetscCall(VecDestroy(&pmat_diag));
2233 LibmeshPetscCall(VecDestroy(&unity_vec));
2234 LibmeshPetscCall(VecDestroy(&p_estimate));
2235 LibmeshPetscCall(VecDestroy(&sol_holder_P));
2236 LibmeshPetscCall(VecDestroy(&diag_Wij_loc));
2237 LibmeshPetscCall(VecDestroy(&unity_vec_Wij));
2238 LibmeshPetscCall(VecDestroy(&Wij_estimate));
2239 LibmeshPetscCall(VecDestroy(&sumWij_loc));
2240 LibmeshPetscCall(VecDestroy(&_Wij_loc_vec));
2241 LibmeshPetscCall(VecDestroy(&_Wij_old_loc_vec));
2244 PetscScalar relaxation_factor_mdot, relaxation_factor_P, relaxation_factor_Wij;
2245 relaxation_factor_mdot = 1.0;
2246 relaxation_factor_P = 1.0;
2247 relaxation_factor_Wij = 0.1;
2251 _console <<
"Relax mdot: " << relaxation_factor_mdot << std::endl;
2252 _console <<
"Relax P: " << relaxation_factor_P << std::endl;
2253 _console <<
"Relax Wij: " << relaxation_factor_Wij << std::endl;
2256 PetscInt field_num = 0;
2258 LibmeshPetscCall(VecDuplicate(vec_array[field_num], &diag_mdot));
2259 LibmeshPetscCall(MatGetDiagonal(mat_array[Q * field_num + field_num], diag_mdot));
2260 LibmeshPetscCall(VecScale(diag_mdot, 1.0 / relaxation_factor_mdot));
2262 MatDiagonalSet(mat_array[Q * field_num + field_num], diag_mdot, INSERT_VALUES));
2263 LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
2265 LibmeshPetscCall(VecScale(diag_mdot, (1.0 - relaxation_factor_mdot)));
2266 LibmeshPetscCall(VecPointwiseMult(
_prod,
_prod, diag_mdot));
2267 LibmeshPetscCall(VecAXPY(vec_array[field_num], 1.0,
_prod));
2268 LibmeshPetscCall(VecDestroy(&diag_mdot));
2271 _console <<
"mdot relaxed" << std::endl;
2275 LibmeshPetscCall(VecDuplicate(vec_array[field_num], &diag_P));
2276 LibmeshPetscCall(MatGetDiagonal(mat_array[Q * field_num + field_num], diag_P));
2277 LibmeshPetscCall(VecScale(diag_P, 1.0 / relaxation_factor_P));
2278 LibmeshPetscCall(MatDiagonalSet(mat_array[Q * field_num + field_num], diag_P, INSERT_VALUES));
2280 _console <<
"Mat assembled" << std::endl;
2281 LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
2283 LibmeshPetscCall(VecScale(diag_P, (1.0 - relaxation_factor_P)));
2284 LibmeshPetscCall(VecPointwiseMult(
_prod,
_prod, diag_P));
2285 LibmeshPetscCall(VecAXPY(vec_array[field_num], 1.0,
_prod));
2286 LibmeshPetscCall(VecDestroy(&diag_P));
2289 _console <<
"P relaxed" << std::endl;
2293 LibmeshPetscCall(VecDuplicate(vec_array[field_num], &diag_Wij));
2294 LibmeshPetscCall(MatGetDiagonal(mat_array[Q * field_num + field_num], diag_Wij));
2295 LibmeshPetscCall(VecScale(diag_Wij, 1.0 / relaxation_factor_Wij));
2296 LibmeshPetscCall(MatDiagonalSet(mat_array[Q * field_num + field_num], diag_Wij, INSERT_VALUES));
2299 LibmeshPetscCall(VecScale(diag_Wij, (1.0 - relaxation_factor_Wij)));
2301 LibmeshPetscCall(VecAXPY(vec_array[field_num], 1.0,
_Wij_vec));
2302 LibmeshPetscCall(VecDestroy(&diag_Wij));
2305 _console <<
"Wij relaxed" << std::endl;
2308 _console <<
"Linear solver relaxed." << std::endl;
2311 LibmeshPetscCall(MatCreateNest(PETSC_COMM_SELF, Q, NULL, Q, NULL, mat_array.data(), &A_nest));
2312 LibmeshPetscCall(VecCreateNest(PETSC_COMM_SELF, Q, NULL, vec_array.data(), &b_nest));
2314 _console <<
"Nested system created." << std::endl;
2318 LibmeshPetscCall(KSPCreate(PETSC_COMM_SELF, &ksp));
2319 LibmeshPetscCall(KSPSetType(ksp, KSPFGMRES));
2321 LibmeshPetscCall(KSPSetOperators(ksp, A_nest, A_nest));
2323 LibmeshPetscCall(KSPGetPC(ksp, &pc));
2324 LibmeshPetscCall(PCSetType(pc, PCFIELDSPLIT));
2327 std::vector<IS> rows(Q);
2330 LibmeshPetscCall(MatNestGetISs(A_nest, rows.data(), NULL));
2331 for (PetscInt
j = 0;
j < Q; ++
j)
2334 LibmeshPetscCall(ISDuplicate(rows[M], &expand1));
2336 LibmeshPetscCall(PCFieldSplitSetIS(pc, NULL, expand1));
2337 LibmeshPetscCall(ISDestroy(&expand1));
2340 _console <<
"Linear solver assembled." << std::endl;
2343 LibmeshPetscCall(VecDuplicate(b_nest, &x_nest));
2344 LibmeshPetscCall(VecSet(x_nest, 0.0));
2345 LibmeshPetscCall(KSPSolve(ksp, b_nest, x_nest));
2348 LibmeshPetscCall(VecDestroy(&b_nest));
2349 LibmeshPetscCall(MatDestroy(&A_nest));
2350 LibmeshPetscCall(KSPDestroy(&ksp));
2351 for (PetscInt i = 0; i < Q * Q; i++)
2353 LibmeshPetscCall(MatDestroy(&mat_array[i]));
2355 for (PetscInt i = 0; i < Q; i++)
2357 LibmeshPetscCall(VecDestroy(&vec_array[i]));
2360 _console <<
"Solver elements destroyed." << std::endl;
2363 Vec sol_mdot, sol_p, sol_Wij;
2365 _console <<
"Vectors created." << std::endl;
2368 LibmeshPetscCall(VecNestGetSubVecs(x_nest, &num_vecs, &loc_vecs));
2370 _console <<
"Starting extraction." << std::endl;
2372 LibmeshPetscCall(VecCopy(loc_vecs[0], sol_mdot));
2374 LibmeshPetscCall(VecCopy(loc_vecs[1], sol_p));
2376 LibmeshPetscCall(VecCopy(loc_vecs[2], sol_Wij));
2378 _console <<
"Getting individual field solutions from coupled solver." << std::endl;
2381 PetscScalar * sol_p_array;
2382 LibmeshPetscCall(VecGetArray(sol_p, &sol_p_array));
2383 PetscScalar * sol_Wij_array;
2384 LibmeshPetscCall(VecGetArray(sol_Wij, &sol_Wij_array));
2387 LibmeshPetscCall(populateSolutionChan<SolutionHandle>(
2391 for (
unsigned int iz = last_node; iz > first_node - 1; iz--)
2393 auto iz_ind = iz - first_node;
2394 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
2404 sol_Wij,
_Wij, first_node, last_node - 1,
_n_gaps));
2409 if (lag_block_thermal_solve)
2415 LibmeshPetscCall(KSPCreate(PETSC_COMM_SELF, &ksploc));
2417 LibmeshPetscCall(KSPGetPC(ksploc, &pc));
2418 LibmeshPetscCall(PCSetType(pc, PCJACOBI));
2420 LibmeshPetscCall(KSPSetFromOptions(ksploc));
2423 LibmeshPetscCall(VecGetArray(sol, &xx));
2424 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
2426 auto iz_ind = iz - first_node;
2427 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
2434 " : Calculation of negative Enthalpy h_out = : ",
2439 _h_soln->set(node_out, h_out);
2442 LibmeshPetscCall(KSPDestroy(&ksploc));
2443 LibmeshPetscCall(VecDestroy(&sol));
2449 LibmeshPetscCall(VecCopy(loc_vecs[3], sol_h));
2450 PetscScalar * sol_h_array;
2451 LibmeshPetscCall(VecGetArray(sol_h, &sol_h_array));
2452 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
2454 auto iz_ind = iz - first_node;
2455 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
2458 auto h_out = sol_h_array[iz_ind *
_n_channels + i_ch];
2462 " : Calculation of negative Enthalpy h_out = : ",
2467 _h_soln->set(node_out, h_out);
2470 LibmeshPetscCall(VecDestroy(&sol_h));
2476 LibmeshPetscCall(populateSolutionChan<SolutionHandle>(
2481 LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
2484 LibmeshPetscCall(VecAbs(
_prod));
2492 _console <<
"Solutions assigned to MOOSE variables." << std::endl;
2495 LibmeshPetscCall(VecDestroy(&x_nest));
2496 LibmeshPetscCall(VecDestroy(&sol_mdot));
2497 LibmeshPetscCall(VecDestroy(&sol_p));
2498 LibmeshPetscCall(VecDestroy(&sol_Wij));
2499 LibmeshPetscCall(VecDestroy(&sumWij_loc));
2501 _console <<
"Solutions destroyed." << std::endl;
2509 _console <<
"Executing subchannel solver\n";
2514 _console <<
"Solution initialized" << std::endl;
2516 unsigned int P_it = 0;
2517 unsigned int P_it_max;
2527 while ((P_error >
_P_tol && P_it < P_it_max))
2532 _console <<
"Reached maximum number of axial pressure iterations" << std::endl;
2535 _console <<
"Solving Outer Iteration : " << P_it << std::endl;
2536 auto P_L2norm_old_axial =
_P_soln->L2norm();
2537 for (
unsigned int iblock = 0; iblock <
_n_blocks; iblock++)
2541 Real T_block_error = 1.0;
2543 _console <<
"Solving Block: " << iblock <<
" From first level: " << first_level
2544 <<
" to last level: " << last_level << std::endl;
2550 _console <<
"Reached maximum number of temperature iterations for block: " << iblock
2554 auto T_L2norm_old_block =
_T_soln->L2norm();
2574 _console <<
"Done with main solve." << std::endl;
2583 _console <<
"Starting thermal solve." << std::endl;
2590 _console <<
"Done with thermal solve." << std::endl;
2595 _console <<
"Start updating thermophysical properties." << std::endl;
2604 _console <<
"Done updating thermophysical properties." << std::endl;
2609 _aux->solution().close();
2611 auto T_L2norm_new =
_T_soln->L2norm();
2613 std::abs((T_L2norm_new - T_L2norm_old_block) / (T_L2norm_old_block + 1E-14));
2614 _console <<
"T_block_error: " << T_block_error << std::endl;
2620 auto P_L2norm_new_axial =
_P_soln->L2norm();
2622 std::abs((P_L2norm_new_axial - P_L2norm_old_axial) / (P_L2norm_old_axial +
_P_out + 1E-14));
2623 _console <<
"P_error :" << P_error << std::endl;
2626 _console <<
"Iteration: " << P_it << std::endl;
2627 _console <<
"Maximum iterations: " << P_it_max << std::endl;
2632 _console <<
"Finished executing subchannel solver\n";
2637 _console <<
"Commencing calculation of Pin surface temperature \n";
2638 for (
unsigned int i_pin = 0; i_pin <
_n_pins; i_pin++)
2640 for (
unsigned int iz = 0; iz <
_n_cells + 1; ++iz)
2644 Real rod_counter = 0.0;
2649 auto mu = (*_mu_soln)(node);
2650 auto S = (*_S_flow_soln)(node);
2651 auto w_perim = (*_w_perim_soln)(node);
2652 auto Dh_i = 4.0 *
S / w_perim;
2653 auto Re = (((*_mdot_soln)(node) /
S) * Dh_i /
mu);
2656 auto Pr = (*_mu_soln)(node)*
cp /
k;
2658 auto hw = Nu *
k / Dh_i;
2660 mooseError(
"Dpin should not be null or negative when computing pin powers: ",
2663 (*_q_prime_soln)(pin_node) / ((*
_Dpin_soln)(pin_node)*M_PI * hw) + (*_T_soln)(node);
2666 if (rod_counter > 0)
2667 _Tpin_soln->set(pin_node, sumTemp / rod_counter);
2669 mooseError(
"Pin was not found for pin index: " + std::to_string(i_pin));
2677 _console <<
"Commencing calculation of duct surface temperature " << std::endl;
2679 for (Node * dn : duct_nodes)
2682 auto mu = (*_mu_soln)(node_chan);
2683 auto S = (*_S_flow_soln)(node_chan);
2684 auto w_perim = (*_w_perim_soln)(node_chan);
2685 auto Dh_i = 4.0 *
S / w_perim;
2686 auto Re = (((*_mdot_soln)(node_chan) /
S) * Dh_i /
mu);
2689 auto Pr = (*_mu_soln)(node_chan)*
cp /
k;
2692 auto hw = Nu *
k / Dh_i;
2693 auto T_chan = (*_duct_heat_flux_soln)(dn) / hw + (*
_T_soln)(node_chan);
2697 _aux->solution().close();
2702 Real power_in = 0.0;
2703 Real power_out = 0.0;
2704 Real Total_surface_area = 0.0;
2705 Real Total_wetted_perimeter = 0.0;
2706 Real mass_flow_in = 0.0;
2707 Real mass_flow_out = 0.0;
2708 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
2712 Total_surface_area += (*_S_flow_soln)(node_in);
2713 Total_wetted_perimeter += (*_w_perim_soln)(node_in);
2714 power_in += (*_mdot_soln)(node_in) * (*
_h_soln)(node_in);
2715 power_out += (*_mdot_soln)(node_out) * (*
_h_soln)(node_out);
2716 mass_flow_in += (*_mdot_soln)(node_in);
2717 mass_flow_out += (*_mdot_soln)(node_out);
2719 auto h_bulk_out = power_out / mass_flow_out;
2720 auto T_bulk_out =
_fp->T_from_p_h(
_P_out, h_bulk_out);
2722 Real bulk_Dh = 4.0 * Total_surface_area / Total_wetted_perimeter;
2724 Real bulk_Re = mass_flow_in * bulk_Dh / (inlet_mu * Total_surface_area);
2727 _console <<
" ======================================= " << std::endl;
2728 _console <<
" ======== Subchannel Print Outs ======== " << std::endl;
2729 _console <<
" ======================================= " << std::endl;
2730 _console <<
"Total flow area :" << Total_surface_area <<
" m^2" << std::endl;
2731 _console <<
"Assembly hydraulic diameter :" << bulk_Dh <<
" m" << std::endl;
2732 _console <<
"Assembly Re number :" << bulk_Re <<
" [-]" << std::endl;
2733 _console <<
"Bulk coolant temperature at outlet :" << T_bulk_out <<
" K" << std::endl;
2734 _console <<
"Power added to coolant is : " << power_out - power_in <<
" Watt" << std::endl;
2735 _console <<
"Mass flow rate in is : " << mass_flow_in <<
" kg/sec" << std::endl;
2736 _console <<
"Mass balance is : " << mass_flow_out - mass_flow_in <<
" kg/sec" << std::endl;
2737 _console <<
"User defined outlet pressure is : " <<
_P_out <<
" Pa" << std::endl;
2738 _console <<
" ======================================= " << std::endl;
2741 if (MooseUtils::absoluteFuzzyLessEqual((power_out - power_in), -1.0))
2743 "Energy conservation equation might not be solved correctly, Power added to coolant: " +
2744 std::to_string(power_out - power_in) +
" Watt ");
Vec _amc_friction_force_rhs
Mat _amc_sys_mdot_mat
Axial momentum system matrix.
static const std::string PRESSURE_DROP
pressure drop
static const std::string MASS_FLOW_RATE
mass flow rate
const bool _pin_mesh_exist
Flag that informs if there is a pin mesh or not.
void computeRho(int iblock)
Computes Density per channel for block iblock.
Vec _amc_gravity_rhs
Axial momentum conservation - buoyancy force No implicit matrix.
virtual unsigned int getNumOfGapsPerLayer() const =0
Return the number of gaps per layer.
std::unique_ptr< SolutionHandle > _Tduct_soln
std::unique_ptr< SolutionHandle > _duct_heat_flux_soln
static const std::string DENSITY
density
void computeSumWij(int iblock)
Computes net diversion crossflow per channel for block iblock.
unsigned int _n_blocks
number of axial blocks
const bool _compute_power
Flag that informs if we need to solve the Enthalpy/Temperature equations or not.
static InputParameters validParams()
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.
virtual Node * getChannelNodeFromDuct(Node *channel_node)=0
Function that gets the channel node from the duct node.
T & getMesh(MooseMesh &mesh)
function to cast mesh
PetscScalar _max_sumWij_new
Mat _cmc_friction_force_mat
Cross momentum conservation - friction force.
void computeP(int iblock)
Computes Pressure per channel for block iblock.
Real _TR
Flag that activates or deactivates the transient parts of the equations we solve by multiplication...
libMesh::DenseMatrix< Real > _Wij_old
const PostprocessorValue & _P_out
Outlet Pressure.
SubChannelMesh & _subchannel_mesh
void computeT(int iblock)
Computes Temperature per channel for block iblock.
virtual void zero() override final
virtual const std::vector< Real > & getZGrid() const
Get axial location of layers.
Vec _amc_pressure_force_rhs
void computeMdot(int iblock)
Computes mass flow per channel for block iblock.
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
Vec _hc_time_derivative_rhs
const bool _compute_density
Flag that activates or deactivates the calculation of density.
Vec _mc_axial_convection_rhs
Mat _amc_friction_force_mat
Axial momentum conservation - friction force.
static const std::string PIN_DIAMETER
pin diameter
PetscScalar _added_K
Added resistances for monolithic convergence.
PetscErrorCode createPetscVector(Vec &v, PetscInt n)
Petsc Functions.
static InputParameters validParams()
Vec _cmc_advective_derivative_rhs
const Parallel::Communicator & comm() const
const bool _duct_mesh_exist
Flag that informs if there is a pin mesh or not.
static InputParameters validParams()
const Real & _T_tol
Convergence tolerance for the temperature loop in external solve.
Vec _amc_time_derivative_rhs
void computeMu(int iblock)
Computes Viscosity per channel for block iblock.
The following methods are specializations for using the Parallel::packed_range_* routines for a vecto...
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)
virtual unsigned int getNumOfPins() const =0
Return the number of pins.
bool isRestarting() const
const bool _segregated_bool
Segregated solve.
Mat _cmc_sys_Wij_mat
Lateral momentum system matrix.
Vec _amc_advective_derivative_rhs
bool _converged
Variable that informs whether we exited external solve with a converged solution or not...
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
const bool _staggered_pressure_bool
Flag to define the usage of staggered or collocated pressure.
virtual void initializeSolution()=0
Function to initialize the solution & geometry fields.
virtual const MooseVariableFieldBase & getVariable(const THREAD_ID tid, const std::string &var_name, Moose::VarKindType expected_var_type=Moose::VarKindType::VAR_ANY, Moose::VarFieldType expected_var_field_type=Moose::VarFieldType::VAR_FIELD_ANY) const override
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 _mc_sumWij_mat
Matrices and vectors to be used in implicit assembly Mass conservation Mass conservation - sum of cro...
PetscErrorCode populateVectorFromDense(Vec &x, const T &solution, const unsigned int first_axial_level, const unsigned int last_axial_level, const unsigned int cross_dimension)
static const std::string DUCT_HEAT_FLUX
duct linear heat rate
static const std::string DUCT_TEMPERATURE
duct temperature
SubChannel1PhaseProblem * schp
const Real & _CT
Turbulent modeling parameter used in axial momentum equation.
virtual Node * getChannelNode(unsigned int i_chan, unsigned iz) const =0
Get the subchannel mesh node for a given channel index and elevation index.
static const std::string WETTED_PERIMETER
wetted perimeter
virtual void computeh(int iblock)=0
Computes Enthalpy per channel for block iblock.
std::unique_ptr< SolutionHandle > _rho_soln
Mat _amc_turbulent_cross_flows_mat
Mass conservation - density time derivative No implicit matrix.
static const std::string cp
Mat _amc_advective_derivative_mat
Axial momentum conservation - advective (Eulerian) derivative.
static const std::string VISCOSITY
viscosity
Vec _hc_added_heat_rhs
Enthalpy conservation - source and sink.
std::vector< Real > _z_grid
axial location of nodes
const std::string & name() const
static const std::string PIN_TEMPERATURE
pin temperature
Vec _cmc_time_derivative_rhs
const int & _T_maxit
Maximum iterations for the inner temperature loop.
Mat _amc_pressure_force_mat
Axial momentum conservation - pressure force.
static const std::string LINEAR_HEAT_RATE
linear heat rate
Real value(unsigned n, unsigned alpha, unsigned beta, Real x)
void computeWijResidual(int iblock)
Computes Residual Matrix based on the lateral momentum conservation equation for block iblock...
const std::vector< double > x
static const std::string S
Real f(Real x)
Test function for Brents method.
std::unique_ptr< SolutionHandle > _q_prime_soln
virtual void syncSolutions(Direction direction) override
static const std::string mu
static const std::string pitch
virtual unsigned int getNumOfChannels() const =0
Return the number of channels per layer.
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.
static const std::string ENTHALPY
enthalpy
Real root(std::function< Real(Real)> const &f, Real x1, Real x2, Real tol=1.0e-12)
Finds the root of a function using Brent's method.
std::shared_ptr< AuxiliarySystem > _aux
Mat _hc_cross_derivative_mat
Enthalpy conservation - cross flux derivative.
Mat _mc_axial_convection_mat
Mass conservation - axial convection.
virtual Node * getDuctNodeFromChannel(Node *channel_node)=0
Function that gets the duct node from the channel node.
void initialSetup() override
auto Peclet(const T1 &volume_fraction, const T2 &cp, const T3 &rho, const T4 &vel, const T5 &D_h, const T6 &k)
Compute Peclet number.
virtual Real computeFrictionFactor(FrictionStruct friction_args)=0
Returns friction factor.
virtual ~SubChannel1PhaseProblem()
const PetscInt & _maxit
The maximum number of iterations to use for the ksp linear solver.
PetscErrorCode createPetscMatrix(Mat &M, PetscInt n, PetscInt m)
friend PetscErrorCode formFunction(SNES snes, Vec x, Vec f, void *ctx)
This is the residual Vector function in a form compatible with the SNES PETC solvers.
virtual const std::vector< std::vector< Real > > & getKGrid() const
Get axial cell location and value of loss coefficient.
const MooseEnum _interpolation_scheme
The interpolation method used in constructing the systems.
std::unique_ptr< SolutionHandle > _Dpin_soln
virtual Real getSubChannelPeripheralDuctWidth(unsigned int i_ch)=0
Function that computes the width of the duct cell that the peripheral subchannel i_ch sees...
virtual unsigned int getNumOfAxialCells() const
Return the number of axial cells.
Base class for the 1-phase steady-state/transient subchannel solver.
libMesh::DenseMatrix< Real > _Wij_residual_matrix
std::unique_ptr< SolutionHandle > _mdot_soln
PetscErrorCode populateDenseFromVector(const Vec &x, T &solution, const unsigned int first_axial_level, const unsigned int last_axial_level, const unsigned int cross_dimension)
static const std::string SUM_CROSSFLOW
sum of diversion crossflow
virtual Real getGapWidth(unsigned int axial_index, unsigned int gap_index) const =0
Return gap width for a given gap index.
LibmeshPetscCallQ(DMShellGetContext(dm, &ctx))
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
std::unique_ptr< SolutionHandle > _displacement_soln
PetscErrorCode formFunction(SNES, Vec x, Vec f, void *ctx)
virtual const std::vector< Node * > getDuctNodes() const =0
Function that return the vector with the maps to the nodes if they exist.
std::unique_ptr< SolutionHandle > _DP_soln
const bool _compute_viscosity
Flag that activates or deactivates the calculation of viscosity.
static const std::string PRESSURE
pressure
libMesh::DenseMatrix< Real > & _Wij
virtual void externalSolve() override
void max(const T &r, T &o, Request &req) const
void computeWijPrime(int iblock)
Computes turbulent crossflow per gap for block iblock.
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.
std::unique_ptr< SolutionHandle > _SumWij_soln
PetscErrorCode petscSnesSolver(int iblock, const libMesh::DenseVector< Real > &solution, libMesh::DenseVector< Real > &root)
Computes solution of nonlinear equation using snes and provided a residual in a formFunction.
Vec _hc_advective_derivative_rhs
libMesh::DenseVector< Real > residualFunction(int iblock, libMesh::DenseVector< Real > solution)
Computes Residual Vector based on the lateral momentum conservation equation for block iblock & updat...
static const std::string SURFACE_AREA
surface area
void mooseWarning(Args &&... args) const
void resize(const unsigned int new_m, const unsigned int new_n)
const bool _verbose_subchannel
Boolean to printout information related to subchannel solve.
PetscScalar _correction_factor
Mat _amc_cross_derivative_mat
Axial momentum conservation - cross flux derivative.
void mooseError(Args &&... args) const
const Real & _P_tol
Convergence tolerance for the pressure loop in external solve.
virtual Real computeBeta(unsigned int i_gap, unsigned int iz, bool enthalpy)=0
Computes turbulent mixing coefficient.
virtual bool solverSystemConverged(const unsigned int) override
struct SubChannel1PhaseProblem::FrictionStruct _friction_args
static const std::complex< double > j(0, 1)
Complex number "j" (also known as "i")
Mat _hc_advective_derivative_mat
Enthalpy conservation - advective (Eulerian) derivative;.
Base class for subchannel meshes.
void computeWijFromSolve(int iblock)
Computes diversion crossflow per gap for block iblock.
const bool _implicit_bool
Flag to define the usage of a implicit or explicit solution.
Mat _amc_time_derivative_mat
Axial momentum conservation - time derivative.
const ConsoleStream _console
static const std::string DISPLACEMENT
subchannel displacement
Mat _hc_time_derivative_mat
Enthalpy Enthalpy conservation - time derivative.
virtual bool isTransient() const override
PetscErrorCode implicitPetscSolve(int iblock)
Computes implicit solve using PetSc.
void computeDP(int iblock)
Computes Pressure Drop per channel for block iblock.
SubChannel1PhaseProblem(const InputParameters ¶ms)
Mat _cmc_time_derivative_mat
Cross momentum Cross momentum conservation - time derivative.
libMesh::DenseMatrix< Real > _WijPrime
virtual void initialSetup() override
PetscFunctionReturn(LIBMESH_PETSC_SUCCESS)
Vec _cmc_friction_force_rhs
processor_id_type processor_id() const
bool isRecovering() const
static const std::string TEMPERATURE
temperature
Mat _cmc_pressure_force_mat
Cross momentum conservation - pressure force.
virtual Real & dt() const
Vec _amc_turbulent_cross_flows_rhs
MooseUnits pow(const MooseUnits &, int)
std::unique_ptr< SolutionHandle > _P_soln
static const std::string k
std::unique_ptr< SolutionHandle > _w_perim_soln
void ErrorVector unsigned int
Vec _cmc_pressure_force_rhs
Vec _amc_cross_derivative_rhs
Mat _cmc_advective_derivative_mat
Cross momentum conservation - advective (Eulerian) derivative.
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.
std::unique_ptr< SolutionHandle > _Tpin_soln