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");
62 params.
addRequiredParam<
unsigned int>(
"n_blocks",
"The number of blocks in the axial direction");
64 params.
addParam<
Real>(
"P_tol", 1e-6,
"Pressure tolerance");
65 params.
addParam<
Real>(
"T_tol", 1e-6,
"Temperature tolerance");
66 params.
addParam<
int>(
"T_maxit", 100,
"Maximum number of iterations for inner temperature loop");
67 params.
addParam<PetscReal>(
"rtol", 1e-6,
"Relative tolerance for ksp solver");
68 params.
addParam<PetscReal>(
"atol", 1e-6,
"Absolute tolerance for ksp solver");
69 params.
addParam<PetscReal>(
"dtol", 1e5,
"Divergence tolerance or ksp solver");
70 params.
addParam<PetscInt>(
"maxit", 1e4,
"Maximum number of iterations for ksp solver");
72 "interpolation_scheme",
74 "Interpolation scheme used for the method. Default is central difference");
76 "implicit",
false,
"Boolean to define the use of explicit or implicit solution.");
78 "staggered_pressure",
false,
"Boolean to define the use of explicit or implicit solution.");
80 "segregated",
true,
"Boolean to define whether to use a segregated solution.");
82 "monolithic_thermal",
false,
"Boolean to define whether to use thermal monolithic solve.");
84 "verbose_subchannel",
false,
"Boolean to print out information related to subchannel solve.");
88 "Boolean that activates the deformation effect based on values for: displacement, Dpin");
89 params.
addRequiredParam<
bool>(
"compute_density",
"Flag that enables the calculation of density");
91 "Flag that enables the calculation of viscosity");
94 "Flag that informs whether we solve the Enthalpy/Temperature equations or not");
96 "P_out",
"The postprocessor (or scalar) that provides the value of outlet pressure [Pa]");
97 params.
addRequiredParam<UserObjectName>(
"fp",
"Fluid properties user object name");
105 _n_blocks(getParam<unsigned
int>(
"n_blocks")),
106 _Wij(declareRestartableData<
libMesh::DenseMatrix<
Real>>(
"Wij")),
108 _kij(_subchannel_mesh.getKij()),
110 _compute_density(getParam<bool>(
"compute_density")),
111 _compute_viscosity(getParam<bool>(
"compute_viscosity")),
112 _compute_power(getParam<bool>(
"compute_power")),
113 _pin_mesh_exist(_subchannel_mesh.pinMeshExist()),
114 _duct_mesh_exist(_subchannel_mesh.ductMeshExist()),
115 _P_out(getPostprocessorValue(
"P_out")),
116 _CT(getParam<
Real>(
"CT")),
117 _P_tol(getParam<
Real>(
"P_tol")),
118 _T_tol(getParam<
Real>(
"T_tol")),
119 _T_maxit(getParam<
int>(
"T_maxit")),
120 _rtol(getParam<PetscReal>(
"rtol")),
121 _atol(getParam<PetscReal>(
"atol")),
122 _dtol(getParam<PetscReal>(
"dtol")),
123 _maxit(getParam<PetscInt>(
"maxit")),
124 _interpolation_scheme(getParam<
MooseEnum>(
"interpolation_scheme")),
125 _implicit_bool(getParam<bool>(
"implicit")),
126 _staggered_pressure_bool(getParam<bool>(
"staggered_pressure")),
127 _segregated_bool(getParam<bool>(
"segregated")),
128 _monolithic_thermal_bool(getParam<bool>(
"monolithic_thermal")),
129 _verbose_subchannel(getParam<bool>(
"verbose_subchannel")),
130 _deformation(getParam<bool>(
"deformation")),
133 _q_prime_duct_soln(nullptr),
138 mooseError(
"Cannot use more than one MPI process.");
160 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
237 ": When implicit number of blocks can't be equal to number of cells. This will " 238 "cause problems with the subchannel interpolation scheme.");
246 _fp = &getUserObject<SinglePhaseFluidProperties>(getParam<UserObjectName>(
"fp"));
275 PetscErrorCode ierr =
cleanUp();
287 LibmeshPetscCall(VecDestroy(&
_Wij_vec));
288 LibmeshPetscCall(VecDestroy(&
_prod));
289 LibmeshPetscCall(VecDestroy(&
_prodp));
358 ": Interpolation scheme should be a string: upwind, downwind, central_difference, " 365 PetscScalar botValue,
369 return alpha * botValue + (1.0 -
alpha) * topValue;
375 unsigned int last_node = (iblock + 1) *
_block_size;
376 unsigned int first_node = iblock *
_block_size + 1;
379 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
381 for (
unsigned int i_gap = 0; i_gap <
_n_gaps; i_gap++)
383 int i =
_n_gaps * (iz - first_node) + i_gap;
384 solution_seed(i) =
_Wij(i_gap, iz);
395 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
397 for (
unsigned int i_gap = 0; i_gap <
_n_gaps; i_gap++)
408 unsigned int last_node = (iblock + 1) *
_block_size;
409 unsigned int first_node = iblock *
_block_size + 1;
413 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
415 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
420 unsigned int counter = 0;
434 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
436 unsigned int iz_ind = iz - first_node;
437 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
440 unsigned int counter = 0;
444 PetscInt col = i_gap +
_n_gaps * iz_ind;
451 LibmeshPetscCall(MatAssemblyBegin(
_mc_sumWij_mat, MAT_FINAL_ASSEMBLY));
452 LibmeshPetscCall(MatAssemblyEnd(
_mc_sumWij_mat, MAT_FINAL_ASSEMBLY));
458 LibmeshPetscCall(VecDuplicate(
_Wij_vec, &loc_Wij));
460 loc_Wij,
_Wij, first_node, last_node + 1,
_n_gaps));
462 LibmeshPetscCall(populateSolutionChan<SolutionHandle>(
464 LibmeshPetscCall(VecDestroy(&loc_prod));
465 LibmeshPetscCall(VecDestroy(&loc_Wij));
473 unsigned int last_node = (iblock + 1) *
_block_size;
474 unsigned int first_node = iblock *
_block_size + 1;
477 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
480 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
484 auto volume = dz * (*_S_flow_soln)(node_in);
487 auto mdot_out = (*_mdot_soln)(node_in) - (*
_SumWij_soln)(node_out)-time_term;
492 " : Calculation of negative mass flow mdot_out = : ",
496 " - Implicit solves are required for recirculating flow.");
504 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
507 auto iz_ind = iz - first_node;
508 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
512 auto volume = dz * (*_S_flow_soln)(node_in);
517 PetscScalar value_vec = -1.0 * time_term;
522 if (iz == first_node)
524 PetscScalar value_vec = (*_mdot_soln)(node_in);
533 PetscScalar
value = -1.0;
541 PetscScalar
value = 1.0;
548 PetscScalar value_vec_2 = -1.0 * (*_SumWij_soln)(node_out);
558 _console <<
"Block: " << iblock <<
" - Mass conservation matrix assembled" << std::endl;
566 LibmeshPetscCall(KSPCreate(PETSC_COMM_WORLD, &ksploc));
568 LibmeshPetscCall(KSPGetPC(ksploc, &pc));
569 LibmeshPetscCall(PCSetType(pc, PCJACOBI));
571 LibmeshPetscCall(KSPSetFromOptions(ksploc));
573 LibmeshPetscCall(populateSolutionChan<SolutionHandle>(
576 LibmeshPetscCall(KSPDestroy(&ksploc));
577 LibmeshPetscCall(VecDestroy(&sol));
585 unsigned int last_node = (iblock + 1) *
_block_size;
586 unsigned int first_node = iblock *
_block_size + 1;
589 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
593 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
597 auto rho_in = (*_rho_soln)(node_in);
598 auto rho_out = (*_rho_soln)(node_out);
599 auto mu_in = (*_mu_soln)(node_in);
600 auto S = (*_S_flow_soln)(node_in);
601 auto w_perim = (*_w_perim_soln)(node_in);
603 auto Dh_i = 4.0 *
S / w_perim;
604 auto time_term =
_TR * ((*_mdot_soln)(node_out)-
_mdot_soln->old(node_out)) * dz /
_dt -
609 auto mass_term2 = -2.0 * (*_mdot_soln)(node_out) * (*
_SumWij_soln)(node_out) /
S / rho_in;
610 auto crossflow_term = 0.0;
611 auto turbulent_term = 0.0;
612 unsigned int counter = 0;
616 unsigned int ii_ch = chans.first;
617 unsigned int jj_ch = chans.second;
622 auto rho_i = (*_rho_soln)(node_in_i);
623 auto rho_j = (*_rho_soln)(node_in_j);
624 auto Si = (*_S_flow_soln)(node_in_i);
625 auto Sj = (*_S_flow_soln)(node_in_j);
628 if (
_Wij(i_gap, iz) > 0.0)
629 u_star = (*_mdot_soln)(node_out_i) / Si / rho_i;
631 u_star = (*_mdot_soln)(node_out_j) / Sj / rho_j;
636 turbulent_term +=
_WijPrime(i_gap, iz) * (2 * (*_mdot_soln)(node_out) / rho_in /
S -
641 turbulent_term *=
_CT;
642 auto Re = (((*_mdot_soln)(node_in) /
S) * Dh_i / mu_in);
651 ki = k_grid[i_ch][iz - 1];
653 ki = k_grid[i_ch][iz];
654 auto friction_term = (fi * dz / Dh_i + ki) * 0.5 *
656 (
S * (*_rho_soln)(node_out));
657 auto gravity_term =
_g_grav * (*_rho_soln)(node_out)*dz *
S;
658 auto DP =
std::pow(
S, -1.0) * (time_term + mass_term1 + mass_term2 + crossflow_term +
659 turbulent_term + friction_term + gravity_term);
677 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
681 auto iz_ind = iz - first_node;
682 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
689 PetscScalar Pe = 0.5;
693 auto S_in = (*_S_flow_soln)(node_in);
694 auto S_out = (*_S_flow_soln)(node_out);
696 auto w_perim_in = (*_w_perim_soln)(node_in);
697 auto w_perim_out = (*_w_perim_soln)(node_out);
701 auto mu_in = (*_mu_soln)(node_in);
702 auto mu_out = (*_mu_soln)(node_out);
704 auto Dh_i = 4.0 * S_interp / w_perim_interp;
706 auto Re = ((mdot_loc / S_interp) * Dh_i / mu_interp);
715 ki = k_grid[i_ch][iz - 1];
717 ki = k_grid[i_ch][iz];
718 Pe = 1.0 / ((fi * dz / Dh_i + ki) * 0.5) * mdot_loc / std::abs(mdot_loc);
723 auto rho_in = (*_rho_soln)(node_in);
724 auto rho_out = (*_rho_soln)(node_out);
728 auto mu_in = (*_mu_soln)(node_in);
729 auto mu_out = (*_mu_soln)(node_out);
733 auto S_in = (*_S_flow_soln)(node_in);
734 auto S_out = (*_S_flow_soln)(node_out);
738 auto w_perim_in = (*_w_perim_soln)(node_in);
739 auto w_perim_out = (*_w_perim_soln)(node_out);
743 auto Dh_i = 4.0 * S_interp / w_perim_interp;
746 if (iz == first_node)
748 PetscScalar value_vec_tt = -1.0 *
_TR *
alpha * (*_mdot_soln)(node_in)*dz /
_dt;
756 PetscInt col_tt = i_ch +
_n_channels * (iz_ind - 1);
758 LibmeshPetscCall(MatSetValues(
765 PetscScalar value_tt =
_TR * (1.0 -
alpha) * dz /
_dt;
766 LibmeshPetscCall(MatSetValues(
770 PetscScalar mdot_old_interp =
772 PetscScalar value_vec_tt =
_TR * mdot_old_interp * dz /
_dt;
778 if (iz == first_node)
782 LibmeshPetscCall(VecSetValues(
788 PetscInt col_at = i_ch +
_n_channels * (iz_ind - 1);
789 PetscScalar value_at = -1.0 * std::abs((*
_mdot_soln)(node_in)) / (S_in * rho_in);
790 LibmeshPetscCall(MatSetValues(
797 PetscScalar value_at = std::abs((*
_mdot_soln)(node_out)) / (S_out * rho_out);
798 LibmeshPetscCall(MatSetValues(
802 unsigned int counter = 0;
803 unsigned int cross_index = iz;
807 unsigned int ii_ch = chans.first;
808 unsigned int jj_ch = chans.second;
823 if (
_Wij(i_gap, cross_index) > 0.0)
825 if (iz == first_node)
827 u_star = (*_mdot_soln)(node_in_i) / S_i / rho_i;
828 PetscScalar value_vec_ct = -1.0 *
alpha *
830 _Wij(i_gap, cross_index) * u_star;
832 LibmeshPetscCall(VecSetValues(
838 _Wij(i_gap, cross_index) / S_i / rho_i;
840 PetscInt col_ct = ii_ch +
_n_channels * (iz_ind - 1);
841 LibmeshPetscCall(MatSetValues(
844 PetscScalar value_ct = (1.0 -
alpha) *
846 _Wij(i_gap, cross_index) / S_i / rho_i;
849 LibmeshPetscCall(MatSetValues(
852 else if (
_Wij(i_gap, cross_index) < 0.0)
854 if (iz == first_node)
856 u_star = (*_mdot_soln)(node_in_j) / S_j / rho_j;
857 PetscScalar value_vec_ct = -1.0 *
alpha *
859 _Wij(i_gap, cross_index) * u_star;
861 LibmeshPetscCall(VecSetValues(
867 _Wij(i_gap, cross_index) / S_j / rho_j;
869 PetscInt col_ct = jj_ch +
_n_channels * (iz_ind - 1);
870 LibmeshPetscCall(MatSetValues(
873 PetscScalar value_ct = (1.0 -
alpha) *
875 _Wij(i_gap, cross_index) / S_j / rho_j;
878 LibmeshPetscCall(MatSetValues(
882 if (iz == first_node)
884 PetscScalar value_vec_ct = -2.0 *
alpha * (*_mdot_soln)(node_in)*
_CT *
885 _WijPrime(i_gap, cross_index) / (rho_interp * S_interp);
886 value_vec_ct +=
alpha * (*_mdot_soln)(node_in_j)*
_CT *
_WijPrime(i_gap, cross_index) /
888 value_vec_ct +=
alpha * (*_mdot_soln)(node_in_i)*
_CT *
_WijPrime(i_gap, cross_index) /
896 PetscScalar value_center_ct =
899 PetscInt col_ct = i_ch +
_n_channels * (iz_ind - 1);
900 LibmeshPetscCall(MatSetValues(
903 PetscScalar value_left_ct =
907 LibmeshPetscCall(MatSetValues(
910 PetscScalar value_right_ct =
914 LibmeshPetscCall(MatSetValues(
918 PetscScalar value_center_ct =
919 2.0 * (1.0 -
alpha) *
_CT *
_WijPrime(i_gap, cross_index) / (rho_interp * S_interp);
922 LibmeshPetscCall(MatSetValues(
925 PetscScalar value_left_ct =
929 LibmeshPetscCall(MatSetValues(
932 PetscScalar value_right_ct =
936 LibmeshPetscCall(MatSetValues(
942 PetscScalar mdot_interp =
944 auto Re = ((mdot_interp / S_interp) * Dh_i / mu_interp);
953 ki = k_grid[i_ch][iz - 1];
955 ki = k_grid[i_ch][iz];
956 auto coef = (fi * dz / Dh_i + ki) * 0.5 * std::abs((*
_mdot_soln)(node_out)) /
957 (S_interp * rho_interp);
958 if (iz == first_node)
960 PetscScalar value_vec = -1.0 *
alpha * coef * (*_mdot_soln)(node_in);
982 PetscScalar value_vec = -1.0 *
_g_grav * rho_interp * dz * S_interp;
984 LibmeshPetscCall(VecSetValues(
_amc_gravity_rhs, 1, &row_vec, &value_vec, ADD_VALUES));
1001 #if !PETSC_VERSION_LESS_THAN(3, 15, 0) 1035 _console <<
"Block: " << iblock <<
" - Linear momentum conservation matrix assembled" 1046 LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
1053 LibmeshPetscCall(VecGetArray(ls, &xx));
1054 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
1056 auto iz_ind = iz - first_node;
1057 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1064 auto S_in = (*_S_flow_soln)(node_in);
1065 auto S_out = (*_S_flow_soln)(node_out);
1081 LibmeshPetscCall(VecDestroy(&ls));
1089 unsigned int last_node = (iblock + 1) *
_block_size;
1090 unsigned int first_node = iblock *
_block_size + 1;
1095 for (
unsigned int iz = last_node; iz > first_node - 1; iz--)
1098 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1109 for (
unsigned int iz = last_node; iz > first_node - 1; iz--)
1112 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1120 PetscScalar Pe = 0.5;
1122 if (iz == last_node)
1141 for (
unsigned int iz = last_node; iz > first_node - 1; iz--)
1143 auto iz_ind = iz - first_node;
1145 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1151 auto S_in = (*_S_flow_soln)(node_in);
1152 auto S_out = (*_S_flow_soln)(node_out);
1158 PetscScalar
value = -1.0 * S_interp;
1162 if (iz == last_node)
1164 PetscScalar
value = -1.0 * (*_P_soln)(node_out)*S_interp;
1172 PetscScalar
value = 1.0 * S_interp;
1179 auto dp_out = (*_DP_soln)(node_out);
1180 PetscScalar value_v = -1.0 * dp_out * S_interp;
1196 LibmeshPetscCall(KSPCreate(PETSC_COMM_WORLD, &ksploc));
1198 LibmeshPetscCall(KSPGetPC(ksploc, &pc));
1199 LibmeshPetscCall(PCSetType(pc, PCJACOBI));
1201 LibmeshPetscCall(KSPSetFromOptions(ksploc));
1204 LibmeshPetscCall(VecGetArray(sol, &xx));
1206 for (
unsigned int iz = last_node; iz > first_node - 1; iz--)
1208 auto iz_ind = iz - first_node;
1209 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1217 LibmeshPetscCall(KSPDestroy(&ksploc));
1218 LibmeshPetscCall(VecDestroy(&sol));
1224 for (
unsigned int iz = last_node; iz > first_node - 1; iz--)
1226 auto iz_ind = iz - first_node;
1228 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1234 auto S_in = (*_S_flow_soln)(node_in);
1235 auto S_out = (*_S_flow_soln)(node_out);
1241 PetscScalar
value = -1.0 * S_interp;
1245 if (iz == last_node)
1247 PetscScalar
value = -1.0 * (*_P_soln)(node_out)*S_interp;
1251 auto dp_out = (*_DP_soln)(node_out);
1252 PetscScalar value_v = -1.0 * dp_out / 2.0 * S_interp;
1261 PetscScalar
value = 1.0 * S_interp;
1267 auto dp_in = (*_DP_soln)(node_in);
1268 auto dp_out = (*_DP_soln)(node_out);
1270 PetscScalar value_v = -1.0 * dp_interp * S_interp;
1282 _console <<
"Block: " << iblock <<
" - Axial momentum pressure force matrix assembled" 1291 LibmeshPetscCall(KSPCreate(PETSC_COMM_WORLD, &ksploc));
1293 LibmeshPetscCall(KSPGetPC(ksploc, &pc));
1294 LibmeshPetscCall(PCSetType(pc, PCJACOBI));
1296 LibmeshPetscCall(KSPSetFromOptions(ksploc));
1299 LibmeshPetscCall(VecGetArray(sol, &xx));
1301 for (
unsigned int iz = last_node; iz > first_node - 1; iz--)
1303 auto iz_ind = iz - first_node;
1304 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1312 LibmeshPetscCall(KSPDestroy(&ksploc));
1313 LibmeshPetscCall(VecDestroy(&sol));
1332 auto heat_rate_in = (*_q_prime_duct_soln)(node_in_duct);
1333 auto heat_rate_out = (*_q_prime_duct_soln)(node_out_duct);
1350 unsigned int last_node = (iblock + 1) *
_block_size;
1351 unsigned int first_node = iblock *
_block_size + 1;
1352 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
1354 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1365 unsigned int last_node = (iblock + 1) *
_block_size;
1366 unsigned int first_node = iblock *
_block_size + 1;
1369 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1375 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
1377 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1388 unsigned int last_node = (iblock + 1) *
_block_size;
1389 unsigned int first_node = iblock *
_block_size + 1;
1392 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1398 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
1400 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
1414 unsigned int last_node = (iblock + 1) *
_block_size;
1417 for (
unsigned int iz = first_node + 1; iz < last_node + 1; iz++)
1420 for (
unsigned int i_gap = 0; i_gap <
_n_gaps; i_gap++)
1423 unsigned int i_ch = chans.first;
1424 unsigned int j_ch = chans.second;
1429 auto rho_i = (*_rho_soln)(node_in_i);
1430 auto rho_j = (*_rho_soln)(node_in_j);
1431 auto Si = (*_S_flow_soln)(node_in_i);
1432 auto Sj = (*_S_flow_soln)(node_in_j);
1436 auto friction_term =
_kij *
_Wij(i_gap, iz) * std::abs(
_Wij(i_gap, iz));
1437 auto DPij = (*_P_soln)(node_in_i) - (*
_P_soln)(node_in_j);
1439 auto rho_star = 0.0;
1440 if (
_Wij(i_gap, iz) > 0.0)
1442 else if (
_Wij(i_gap, iz) < 0.0)
1445 rho_star = (rho_i + rho_j) / 2.0;
1446 auto mass_term_out =
1447 (*_mdot_soln)(node_out_i) / Si / rho_i + (*
_mdot_soln)(node_out_j) / Sj / rho_j;
1449 (*_mdot_soln)(node_in_i) / Si / rho_i + (*
_mdot_soln)(node_in_j) / Sj / rho_j;
1450 auto term_out = Sij * rho_star * (Lij / dz) * mass_term_out *
_Wij(i_gap, iz);
1451 auto term_in = Sij * rho_star * (Lij / dz) * mass_term_in *
_Wij(i_gap, iz - 1);
1452 auto inertia_term = term_out - term_in;
1453 auto pressure_term = 2 *
std::pow(Sij, 2.0) * DPij * rho_star;
1458 time_term + friction_term + inertia_term - pressure_term;
1475 unsigned int last_node = (iblock + 1) *
_block_size;
1478 for (
unsigned int iz = first_node + 1; iz < last_node + 1; iz++)
1481 auto iz_ind = iz - first_node - 1;
1482 for (
unsigned int i_gap = 0; i_gap <
_n_gaps; i_gap++)
1485 unsigned int i_ch = chans.first;
1486 unsigned int j_ch = chans.second;
1493 auto rho_i_in = (*_rho_soln)(node_in_i);
1494 auto rho_i_out = (*_rho_soln)(node_out_i);
1496 auto rho_j_in = (*_rho_soln)(node_in_j);
1497 auto rho_j_out = (*_rho_soln)(node_out_j);
1501 auto S_i_in = (*_S_flow_soln)(node_in_i);
1502 auto S_i_out = (*_S_flow_soln)(node_out_i);
1503 auto S_j_in = (*_S_flow_soln)(node_in_j);
1504 auto S_j_out = (*_S_flow_soln)(node_out_j);
1511 auto rho_star = 0.0;
1512 if (
_Wij(i_gap, iz) > 0.0)
1513 rho_star = rho_i_interp;
1514 else if (
_Wij(i_gap, iz) < 0.0)
1515 rho_star = rho_j_interp;
1517 rho_star = (rho_i_interp + rho_j_interp) / 2.0;
1520 PetscScalar time_factor =
_TR * Lij * Sij * rho_star /
_dt;
1521 PetscInt row_td = i_gap +
_n_gaps * iz_ind;
1522 PetscInt col_td = i_gap +
_n_gaps * iz_ind;
1523 PetscScalar value_td = time_factor;
1524 LibmeshPetscCall(MatSetValues(
1526 PetscScalar value_td_rhs = time_factor *
_Wij_old(i_gap, iz);
1531 PetscScalar Pe = 0.5;
1533 auto mass_term_out = (*_mdot_soln)(node_out_i) / S_i_out / rho_i_out +
1534 (*
_mdot_soln)(node_out_j) / S_j_out / rho_j_out;
1535 auto mass_term_in = (*_mdot_soln)(node_in_i) / S_i_in / rho_i_in +
1536 (*
_mdot_soln)(node_in_j) / S_j_in / rho_j_in;
1537 auto term_out = Sij * rho_star * (Lij / dz) * mass_term_out / 2.0;
1538 auto term_in = Sij * rho_star * (Lij / dz) * mass_term_in / 2.0;
1539 if (iz == first_node + 1)
1541 PetscInt row_ad = i_gap +
_n_gaps * iz_ind;
1542 PetscScalar value_ad = term_in *
alpha *
_Wij(i_gap, iz - 1);
1546 PetscInt col_ad = i_gap +
_n_gaps * iz_ind;
1547 value_ad = -1.0 * term_in * (1.0 -
alpha) + term_out *
alpha;
1548 LibmeshPetscCall(MatSetValues(
1551 col_ad = i_gap +
_n_gaps * (iz_ind + 1);
1552 value_ad = term_out * (1.0 -
alpha);
1553 LibmeshPetscCall(MatSetValues(
1556 else if (iz == last_node)
1558 PetscInt row_ad = i_gap +
_n_gaps * iz_ind;
1559 PetscInt col_ad = i_gap +
_n_gaps * (iz_ind - 1);
1560 PetscScalar value_ad = -1.0 * term_in *
alpha;
1561 LibmeshPetscCall(MatSetValues(
1564 col_ad = i_gap +
_n_gaps * iz_ind;
1565 value_ad = -1.0 * term_in * (1.0 -
alpha) + term_out *
alpha;
1566 LibmeshPetscCall(MatSetValues(
1569 value_ad = -1.0 * term_out * (1.0 -
alpha) *
_Wij(i_gap, iz);
1575 PetscInt row_ad = i_gap +
_n_gaps * iz_ind;
1576 PetscInt col_ad = i_gap +
_n_gaps * (iz_ind - 1);
1577 PetscScalar value_ad = -1.0 * term_in *
alpha;
1578 LibmeshPetscCall(MatSetValues(
1581 col_ad = i_gap +
_n_gaps * iz_ind;
1582 value_ad = -1.0 * term_in * (1.0 -
alpha) + term_out *
alpha;
1583 LibmeshPetscCall(MatSetValues(
1586 col_ad = i_gap +
_n_gaps * (iz_ind + 1);
1587 value_ad = term_out * (1.0 -
alpha);
1588 LibmeshPetscCall(MatSetValues(
1592 PetscInt row_ff = i_gap +
_n_gaps * iz_ind;
1593 PetscInt col_ff = i_gap +
_n_gaps * iz_ind;
1594 PetscScalar value_ff =
_kij * std::abs(
_Wij(i_gap, iz)) / 2.0;
1595 LibmeshPetscCall(MatSetValues(
1603 PetscScalar pressure_factor =
std::pow(Sij, 2.0) * rho_star;
1604 PetscInt row_pf = i_gap +
_n_gaps * iz_ind;
1606 PetscScalar value_pf = -1.0 *
alpha * pressure_factor;
1610 value_pf =
alpha * pressure_factor;
1614 if (iz == last_node)
1616 PetscInt row_pf = i_gap +
_n_gaps * iz_ind;
1617 PetscScalar value_pf = (1.0 -
alpha) * pressure_factor * (*
_P_soln)(node_out_i);
1620 value_pf = -1.0 * (1.0 -
alpha) * pressure_factor * (*
_P_soln)(node_out_j);
1626 row_pf = i_gap +
_n_gaps * iz_ind;
1628 value_pf = -1.0 * (1.0 -
alpha) * pressure_factor;
1629 LibmeshPetscCall(MatSetValues(
1632 value_pf = (1.0 -
alpha) * pressure_factor;
1633 LibmeshPetscCall(MatSetValues(
1639 PetscScalar pressure_factor =
std::pow(Sij, 2.0) * rho_star;
1640 PetscInt row_pf = i_gap +
_n_gaps * iz_ind;
1642 PetscScalar value_pf = -1.0 * pressure_factor;
1646 value_pf = pressure_factor;
1666 #if !PETSC_VERSION_LESS_THAN(3, 15, 0) 1692 _console <<
"Block: " << iblock <<
" - Cross flow system matrix assembled" << std::endl;
1694 _console <<
"Block: " << iblock <<
" - Cross flow pressure force matrix assembled" 1710 LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
1713 loc_holder_Wij,
_Wij, first_node, last_node,
_n_gaps));
1718 LibmeshPetscCall(VecAXPY(sol_holder_W, 1.0, sol_holder_P));
1720 LibmeshPetscCall(VecGetArray(sol_holder_W, &xx));
1721 for (
unsigned int iz = first_node + 1; iz < last_node + 1; iz++)
1723 auto iz_ind = iz - first_node - 1;
1724 for (
unsigned int i_gap = 0; i_gap <
_n_gaps; i_gap++)
1729 LibmeshPetscCall(VecDestroy(&sol_holder_P));
1730 LibmeshPetscCall(VecDestroy(&sol_holder_W));
1731 LibmeshPetscCall(VecDestroy(&loc_holder_Wij));
1739 unsigned int last_node = (iblock + 1) *
_block_size;
1740 unsigned int first_node = iblock *
_block_size + 1;
1741 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
1744 for (
unsigned int i_gap = 0; i_gap <
_n_gaps; i_gap++)
1747 unsigned int i_ch = chans.first;
1748 unsigned int j_ch = chans.second;
1753 auto Si_in = (*_S_flow_soln)(node_in_i);
1754 auto Sj_in = (*_S_flow_soln)(node_in_j);
1755 auto Si_out = (*_S_flow_soln)(node_out_i);
1756 auto Sj_out = (*_S_flow_soln)(node_out_j);
1758 auto Sij = dz * gap;
1760 0.5 * (((*_mdot_soln)(node_in_i) + (*
_mdot_soln)(node_in_j)) / (Si_in + Sj_in) +
1766 _WijPrime(i_gap, iz) = beta * avg_massflux * Sij;
1770 auto iz_ind = iz - first_node;
1771 PetscScalar base_value = beta * 0.5 * Sij;
1774 if (iz == first_node)
1776 PetscScalar value_tl = -1.0 * base_value / (Si_in + Sj_in) *
1778 PetscInt row = i_gap +
_n_gaps * iz_ind;
1784 PetscScalar value_tl = base_value / (Si_in + Sj_in);
1785 PetscInt row = i_gap +
_n_gaps * iz_ind;
1787 PetscInt col_ich = i_ch +
_n_channels * (iz_ind - 1);
1788 LibmeshPetscCall(MatSetValues(
1791 PetscInt col_jch = j_ch +
_n_channels * (iz_ind - 1);
1792 LibmeshPetscCall(MatSetValues(
1797 PetscScalar value_bl = base_value / (Si_out + Sj_out);
1798 PetscInt row = i_gap +
_n_gaps * iz_ind;
1801 LibmeshPetscCall(MatSetValues(
1805 LibmeshPetscCall(MatSetValues(
1820 LibmeshPetscCall(VecDuplicate(
_Wij_vec, &loc_Wij));
1821 LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
1827 LibmeshPetscCall(VecDestroy(&loc_prod));
1828 LibmeshPetscCall(VecDestroy(&loc_Wij));
1835 unsigned int last_node = (iblock + 1) *
_block_size;
1840 for (
unsigned int iz = first_node + 1; iz < last_node + 1; iz++)
1842 for (
unsigned int i_gap = 0; i_gap <
_n_gaps; i_gap++)
1844 _Wij(i_gap, iz) = solution(i);
1865 for (
unsigned int i_gap = 0; i_gap <
_n_gaps; i_gap++)
1871 return Wij_residual_vector;
1887 PetscCallMPI(MPI_Comm_size(PETSC_COMM_WORLD, &size));
1889 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_SUP,
"Example is only for sequential runs");
1890 LibmeshPetscCall(SNESCreate(PETSC_COMM_WORLD, &snes));
1891 LibmeshPetscCall(VecCreate(PETSC_COMM_WORLD, &
x));
1893 LibmeshPetscCall(VecSetFromOptions(
x));
1894 LibmeshPetscCall(VecDuplicate(
x, &r));
1896 #if PETSC_VERSION_LESS_THAN(3, 13, 0) 1897 LibmeshPetscCall(PetscOptionsSetValue(PETSC_NULL,
"-snes_mf", PETSC_NULL));
1899 LibmeshPetscCall(SNESSetUseMatrixFree(snes, PETSC_FALSE, PETSC_TRUE));
1902 ctx.iblock = iblock;
1905 LibmeshPetscCall(SNESGetKSP(snes, &ksp));
1906 LibmeshPetscCall(KSPGetPC(ksp, &pc));
1907 LibmeshPetscCall(PCSetType(pc, PCNONE));
1909 LibmeshPetscCall(SNESSetFromOptions(snes));
1910 LibmeshPetscCall(VecGetArray(
x, &xx));
1913 xx[i] = solution(i);
1915 LibmeshPetscCall(VecRestoreArray(
x, &xx));
1917 LibmeshPetscCall(SNESSolve(snes, NULL,
x));
1918 LibmeshPetscCall(VecGetArray(
x, &xx));
1922 LibmeshPetscCall(VecRestoreArray(
x, &xx));
1923 LibmeshPetscCall(VecDestroy(&
x));
1924 LibmeshPetscCall(VecDestroy(&r));
1925 LibmeshPetscCall(SNESDestroy(&snes));
1932 bool lag_block_thermal_solve =
true;
1940 std::vector<Mat> mat_array(Q * Q);
1941 std::vector<Vec> vec_array(Q);
1944 bool _axial_mass_flow_tight_coupling =
true;
1945 bool _pressure_axial_momentum_tight_coupling =
true;
1946 bool _pressure_cross_momentum_tight_coupling =
true;
1947 unsigned int first_node = iblock *
_block_size + 1;
1948 unsigned int last_node = (iblock + 1) *
_block_size;
1969 _console <<
"Starting nested system." << std::endl;
1970 _console <<
"Number of simultaneous variables: " << Q << std::endl;
1973 PetscInt field_num = 0;
1976 LibmeshPetscCall(MatAssemblyBegin(mat_array[Q * field_num + 0], MAT_FINAL_ASSEMBLY));
1977 LibmeshPetscCall(MatAssemblyEnd(mat_array[Q * field_num + 0], MAT_FINAL_ASSEMBLY));
1978 mat_array[Q * field_num + 1] = NULL;
1979 if (_axial_mass_flow_tight_coupling)
1981 LibmeshPetscCall(MatDuplicate(
_mc_sumWij_mat, MAT_COPY_VALUES, &mat_array[Q * field_num + 2]));
1982 LibmeshPetscCall(MatAssemblyBegin(mat_array[Q * field_num + 2], MAT_FINAL_ASSEMBLY));
1983 LibmeshPetscCall(MatAssemblyEnd(mat_array[Q * field_num + 2], MAT_FINAL_ASSEMBLY));
1987 mat_array[Q * field_num + 2] = NULL;
1991 mat_array[Q * field_num + 3] = NULL;
1995 if (!_axial_mass_flow_tight_coupling)
1999 LibmeshPetscCall(VecSet(sumWij_loc, 0.0));
2000 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
2002 auto iz_ind = iz - first_node;
2003 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
2007 PetscScalar value_vec_2 = -1.0 * (*_SumWij_soln)(node_out);
2009 LibmeshPetscCall(VecSetValues(sumWij_loc, 1, &row_vec_2, &value_vec_2, ADD_VALUES));
2012 LibmeshPetscCall(VecAXPY(vec_array[field_num], 1.0, sumWij_loc));
2013 LibmeshPetscCall(VecDestroy(&sumWij_loc));
2017 _console <<
"Mass ok." << std::endl;
2020 if (_pressure_axial_momentum_tight_coupling)
2023 MatDuplicate(
_amc_sys_mdot_mat, MAT_COPY_VALUES, &mat_array[Q * field_num + 0]));
2024 LibmeshPetscCall(MatAssemblyBegin(mat_array[Q * field_num + 0], MAT_FINAL_ASSEMBLY));
2025 LibmeshPetscCall(MatAssemblyEnd(mat_array[Q * field_num + 0], MAT_FINAL_ASSEMBLY));
2029 mat_array[Q * field_num + 0] = NULL;
2033 LibmeshPetscCall(MatAssemblyBegin(mat_array[Q * field_num + 1], MAT_FINAL_ASSEMBLY));
2034 LibmeshPetscCall(MatAssemblyEnd(mat_array[Q * field_num + 1], MAT_FINAL_ASSEMBLY));
2035 mat_array[Q * field_num + 2] = NULL;
2038 mat_array[Q * field_num + 3] = NULL;
2042 if (_pressure_axial_momentum_tight_coupling)
2048 unsigned int last_node = (iblock + 1) *
_block_size;
2049 unsigned int first_node = iblock *
_block_size + 1;
2050 LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
2056 LibmeshPetscCall(VecAXPY(vec_array[field_num], -1.0, ls));
2057 LibmeshPetscCall(VecDestroy(&ls));
2061 _console <<
"Lin mom OK." << std::endl;
2065 mat_array[Q * field_num + 0] = NULL;
2066 if (_pressure_cross_momentum_tight_coupling)
2070 LibmeshPetscCall(MatAssemblyBegin(mat_array[Q * field_num + 1], MAT_FINAL_ASSEMBLY));
2071 LibmeshPetscCall(MatAssemblyEnd(mat_array[Q * field_num + 1], MAT_FINAL_ASSEMBLY));
2075 mat_array[Q * field_num + 1] = NULL;
2078 LibmeshPetscCall(MatDuplicate(
_cmc_sys_Wij_mat, MAT_COPY_VALUES, &mat_array[Q * field_num + 2]));
2079 LibmeshPetscCall(MatAssemblyBegin(mat_array[Q * field_num + 2], MAT_FINAL_ASSEMBLY));
2080 LibmeshPetscCall(MatAssemblyEnd(mat_array[Q * field_num + 2], MAT_FINAL_ASSEMBLY));
2083 mat_array[Q * field_num + 3] = NULL;
2088 if (_pressure_cross_momentum_tight_coupling)
2096 LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
2101 LibmeshPetscCall(VecScale(sol_holder_P, 1.0));
2102 LibmeshPetscCall(VecAXPY(vec_array[field_num], 1.0, sol_holder_P));
2103 LibmeshPetscCall(VecDestroy(&sol_holder_P));
2107 _console <<
"Cross mom ok." << std::endl;
2113 mat_array[Q * field_num + 0] = NULL;
2114 mat_array[Q * field_num + 1] = NULL;
2115 mat_array[Q * field_num + 2] = NULL;
2116 LibmeshPetscCall(MatDuplicate(
_hc_sys_h_mat, MAT_COPY_VALUES, &mat_array[Q * field_num + 3]));
2117 if (lag_block_thermal_solve)
2119 LibmeshPetscCall(MatZeroEntries(mat_array[Q * field_num + 3]));
2120 LibmeshPetscCall(MatShift(mat_array[Q * field_num + 3], 1.0));
2122 LibmeshPetscCall(MatAssemblyBegin(mat_array[Q * field_num + 3], MAT_FINAL_ASSEMBLY));
2123 LibmeshPetscCall(MatAssemblyEnd(mat_array[Q * field_num + 3], MAT_FINAL_ASSEMBLY));
2124 LibmeshPetscCall(VecDuplicate(
_hc_sys_h_rhs, &vec_array[field_num]));
2125 LibmeshPetscCall(VecCopy(
_hc_sys_h_rhs, vec_array[field_num]));
2126 if (lag_block_thermal_solve)
2128 LibmeshPetscCall(VecZeroEntries(vec_array[field_num]));
2129 LibmeshPetscCall(VecShift(vec_array[field_num], 1.0));
2133 _console <<
"Energy ok." << std::endl;
2141 LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
2151 LibmeshPetscCall(VecSet(unity_vec, 1.0));
2160 LibmeshPetscCall(VecSet(unity_vec_Wij, 1.0));
2163 Vec _Wij_old_loc_vec;
2165 LibmeshPetscCall(MatMult(mat_array[Q],
_prod, mdot_estimate));
2166 LibmeshPetscCall(MatGetDiagonal(mat_array[Q + 1], pmat_diag));
2167 LibmeshPetscCall(VecAXPY(pmat_diag, 1e-10, unity_vec));
2168 LibmeshPetscCall(VecPointwiseDivide(p_estimate, mdot_estimate, pmat_diag));
2169 LibmeshPetscCall(MatMult(mat_array[2 * Q + 1], p_estimate, sol_holder_P));
2171 LibmeshPetscCall(MatGetDiagonal(mat_array[2 * Q + 2], diag_Wij_loc));
2172 LibmeshPetscCall(VecAXPY(diag_Wij_loc, 1e-10, unity_vec_Wij));
2173 LibmeshPetscCall(VecPointwiseDivide(Wij_estimate, sol_holder_P, diag_Wij_loc));
2176 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
2178 auto iz_ind = iz - first_node;
2179 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
2181 PetscScalar sumWij = 0.0;
2182 unsigned int counter = 0;
2186 unsigned int i_ch_loc = chans.first;
2187 PetscInt row_vec = i_ch_loc +
_n_channels * iz_ind;
2188 PetscScalar loc_Wij_value;
2189 LibmeshPetscCall(VecGetValues(sol_holder_P, 1, &row_vec, &loc_Wij_value));
2194 LibmeshPetscCall(VecSetValues(sumWij_loc, 1, &row_vec, &sumWij, INSERT_VALUES));
2198 PetscScalar min_mdot;
2199 LibmeshPetscCall(VecAbs(
_prod));
2200 LibmeshPetscCall(VecMin(
_prod, NULL, &min_mdot));
2202 _console <<
"Minimum estimated mdot: " << min_mdot << std::endl;
2204 LibmeshPetscCall(VecAbs(sumWij_loc));
2205 LibmeshPetscCall(VecMax(sumWij_loc, NULL, &
_max_sumWij));
2211 _Wij_loc_vec,
_Wij, first_node, last_node,
_n_gaps));
2212 LibmeshPetscCall(VecAbs(_Wij_loc_vec));
2215 LibmeshPetscCall(VecAbs(_Wij_old_loc_vec));
2216 LibmeshPetscCall(VecAXPY(_Wij_loc_vec, -1.0, _Wij_old_loc_vec));
2217 PetscScalar relax_factor;
2218 LibmeshPetscCall(VecAbs(_Wij_loc_vec));
2219 #if !PETSC_VERSION_LESS_THAN(3, 16, 0) 2220 LibmeshPetscCall(VecMean(_Wij_loc_vec, &relax_factor));
2222 VecSum(_Wij_loc_vec, &relax_factor);
2227 _console <<
"Relax base value: " << relax_factor << std::endl;
2229 PetscScalar resistance_relaxation = 0.9;
2237 if (_added_K < 10 && _added_K >= 1.0)
2239 if (_added_K < 1.0 && _added_K >= 0.1)
2241 if (_added_K < 0.1 && _added_K >= 0.01)
2243 if (_added_K < 1e-2 && _added_K >= 1e-3)
2249 LibmeshPetscCall(VecScale(unity_vec_Wij,
_added_K));
2253 LibmeshPetscCall(MatDiagonalSet(mat_array[2 * Q + 2], unity_vec_Wij, ADD_VALUES));
2254 LibmeshPetscCall(VecDestroy(&mdot_estimate));
2255 LibmeshPetscCall(VecDestroy(&pmat_diag));
2256 LibmeshPetscCall(VecDestroy(&unity_vec));
2257 LibmeshPetscCall(VecDestroy(&p_estimate));
2258 LibmeshPetscCall(VecDestroy(&sol_holder_P));
2259 LibmeshPetscCall(VecDestroy(&diag_Wij_loc));
2260 LibmeshPetscCall(VecDestroy(&unity_vec_Wij));
2261 LibmeshPetscCall(VecDestroy(&Wij_estimate));
2262 LibmeshPetscCall(VecDestroy(&sumWij_loc));
2263 LibmeshPetscCall(VecDestroy(&_Wij_loc_vec));
2264 LibmeshPetscCall(VecDestroy(&_Wij_old_loc_vec));
2267 PetscScalar relaxation_factor_mdot, relaxation_factor_P, relaxation_factor_Wij;
2268 relaxation_factor_mdot = 1.0;
2269 relaxation_factor_P = 1.0;
2270 relaxation_factor_Wij = 0.1;
2274 _console <<
"Relax mdot: " << relaxation_factor_mdot << std::endl;
2275 _console <<
"Relax P: " << relaxation_factor_P << std::endl;
2276 _console <<
"Relax Wij: " << relaxation_factor_Wij << std::endl;
2279 PetscInt field_num = 0;
2281 LibmeshPetscCall(VecDuplicate(vec_array[field_num], &diag_mdot));
2282 LibmeshPetscCall(MatGetDiagonal(mat_array[Q * field_num + field_num], diag_mdot));
2283 LibmeshPetscCall(VecScale(diag_mdot, 1.0 / relaxation_factor_mdot));
2285 MatDiagonalSet(mat_array[Q * field_num + field_num], diag_mdot, INSERT_VALUES));
2286 LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
2288 LibmeshPetscCall(VecScale(diag_mdot, (1.0 - relaxation_factor_mdot)));
2289 LibmeshPetscCall(VecPointwiseMult(
_prod,
_prod, diag_mdot));
2290 LibmeshPetscCall(VecAXPY(vec_array[field_num], 1.0,
_prod));
2291 LibmeshPetscCall(VecDestroy(&diag_mdot));
2294 _console <<
"mdot relaxed" << std::endl;
2298 LibmeshPetscCall(VecDuplicate(vec_array[field_num], &diag_P));
2299 LibmeshPetscCall(MatGetDiagonal(mat_array[Q * field_num + field_num], diag_P));
2300 LibmeshPetscCall(VecScale(diag_P, 1.0 / relaxation_factor_P));
2301 LibmeshPetscCall(MatDiagonalSet(mat_array[Q * field_num + field_num], diag_P, INSERT_VALUES));
2303 _console <<
"Mat assembled" << std::endl;
2304 LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
2306 LibmeshPetscCall(VecScale(diag_P, (1.0 - relaxation_factor_P)));
2307 LibmeshPetscCall(VecPointwiseMult(
_prod,
_prod, diag_P));
2308 LibmeshPetscCall(VecAXPY(vec_array[field_num], 1.0,
_prod));
2309 LibmeshPetscCall(VecDestroy(&diag_P));
2312 _console <<
"P relaxed" << std::endl;
2316 LibmeshPetscCall(VecDuplicate(vec_array[field_num], &diag_Wij));
2317 LibmeshPetscCall(MatGetDiagonal(mat_array[Q * field_num + field_num], diag_Wij));
2318 LibmeshPetscCall(VecScale(diag_Wij, 1.0 / relaxation_factor_Wij));
2319 LibmeshPetscCall(MatDiagonalSet(mat_array[Q * field_num + field_num], diag_Wij, INSERT_VALUES));
2322 LibmeshPetscCall(VecScale(diag_Wij, (1.0 - relaxation_factor_Wij)));
2324 LibmeshPetscCall(VecAXPY(vec_array[field_num], 1.0,
_Wij_vec));
2325 LibmeshPetscCall(VecDestroy(&diag_Wij));
2328 _console <<
"Wij relaxed" << std::endl;
2331 _console <<
"Linear solver relaxed." << std::endl;
2334 LibmeshPetscCall(MatCreateNest(PETSC_COMM_WORLD, Q, NULL, Q, NULL, mat_array.data(), &A_nest));
2335 LibmeshPetscCall(VecCreateNest(PETSC_COMM_WORLD, Q, NULL, vec_array.data(), &b_nest));
2337 _console <<
"Nested system created." << std::endl;
2341 LibmeshPetscCall(KSPCreate(PETSC_COMM_WORLD, &ksp));
2342 LibmeshPetscCall(KSPSetType(ksp, KSPFGMRES));
2344 LibmeshPetscCall(KSPSetOperators(ksp, A_nest, A_nest));
2346 LibmeshPetscCall(KSPGetPC(ksp, &pc));
2347 LibmeshPetscCall(PCSetType(pc, PCFIELDSPLIT));
2350 std::vector<IS> rows(Q);
2353 LibmeshPetscCall(MatNestGetISs(A_nest, rows.data(), NULL));
2354 for (PetscInt
j = 0;
j < Q; ++
j)
2357 LibmeshPetscCall(ISDuplicate(rows[M], &expand1));
2359 LibmeshPetscCall(PCFieldSplitSetIS(pc, NULL, expand1));
2360 LibmeshPetscCall(ISDestroy(&expand1));
2363 _console <<
"Linear solver assembled." << std::endl;
2366 LibmeshPetscCall(VecDuplicate(b_nest, &x_nest));
2367 LibmeshPetscCall(VecSet(x_nest, 0.0));
2368 LibmeshPetscCall(KSPSolve(ksp, b_nest, x_nest));
2371 LibmeshPetscCall(VecDestroy(&b_nest));
2372 LibmeshPetscCall(MatDestroy(&A_nest));
2373 LibmeshPetscCall(KSPDestroy(&ksp));
2374 for (PetscInt i = 0; i < Q * Q; i++)
2376 LibmeshPetscCall(MatDestroy(&mat_array[i]));
2378 for (PetscInt i = 0; i < Q; i++)
2380 LibmeshPetscCall(VecDestroy(&vec_array[i]));
2383 _console <<
"Solver elements destroyed." << std::endl;
2386 Vec sol_mdot, sol_p, sol_Wij;
2388 _console <<
"Vectors created." << std::endl;
2391 LibmeshPetscCall(VecNestGetSubVecs(x_nest, &num_vecs, &loc_vecs));
2393 _console <<
"Starting extraction." << std::endl;
2395 LibmeshPetscCall(VecCopy(loc_vecs[0], sol_mdot));
2397 LibmeshPetscCall(VecCopy(loc_vecs[1], sol_p));
2399 LibmeshPetscCall(VecCopy(loc_vecs[2], sol_Wij));
2401 _console <<
"Getting individual field solutions from coupled solver." << std::endl;
2404 PetscScalar * sol_p_array;
2405 LibmeshPetscCall(VecGetArray(sol_p, &sol_p_array));
2406 PetscScalar * sol_Wij_array;
2407 LibmeshPetscCall(VecGetArray(sol_Wij, &sol_Wij_array));
2410 LibmeshPetscCall(populateSolutionChan<SolutionHandle>(
2414 for (
unsigned int iz = last_node; iz > first_node - 1; iz--)
2416 auto iz_ind = iz - first_node;
2417 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
2427 sol_Wij,
_Wij, first_node, last_node - 1,
_n_gaps));
2432 if (lag_block_thermal_solve)
2438 LibmeshPetscCall(KSPCreate(PETSC_COMM_WORLD, &ksploc));
2440 LibmeshPetscCall(KSPGetPC(ksploc, &pc));
2441 LibmeshPetscCall(PCSetType(pc, PCJACOBI));
2443 LibmeshPetscCall(KSPSetFromOptions(ksploc));
2446 LibmeshPetscCall(VecGetArray(sol, &xx));
2447 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
2449 auto iz_ind = iz - first_node;
2450 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
2457 " : Calculation of negative Enthalpy h_out = : ",
2462 _h_soln->set(node_out, h_out);
2465 LibmeshPetscCall(KSPDestroy(&ksploc));
2466 LibmeshPetscCall(VecDestroy(&sol));
2472 LibmeshPetscCall(VecCopy(loc_vecs[3], sol_h));
2473 PetscScalar * sol_h_array;
2474 LibmeshPetscCall(VecGetArray(sol_h, &sol_h_array));
2475 for (
unsigned int iz = first_node; iz < last_node + 1; iz++)
2477 auto iz_ind = iz - first_node;
2478 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
2481 auto h_out = sol_h_array[iz_ind *
_n_channels + i_ch];
2485 " : Calculation of negative Enthalpy h_out = : ",
2490 _h_soln->set(node_out, h_out);
2493 LibmeshPetscCall(VecDestroy(&sol_h));
2499 LibmeshPetscCall(populateSolutionChan<SolutionHandle>(
2504 LibmeshPetscCall(populateVectorFromHandle<SolutionHandle>(
2507 LibmeshPetscCall(VecAbs(
_prod));
2515 _console <<
"Solutions assigned to MOOSE variables." << std::endl;
2518 LibmeshPetscCall(VecDestroy(&x_nest));
2519 LibmeshPetscCall(VecDestroy(&sol_mdot));
2520 LibmeshPetscCall(VecDestroy(&sol_p));
2521 LibmeshPetscCall(VecDestroy(&sol_Wij));
2522 LibmeshPetscCall(VecDestroy(&sumWij_loc));
2524 _console <<
"Solutions destroyed." << std::endl;
2532 _console <<
"Executing subchannel solver\n";
2537 _console <<
"Solution initialized" << std::endl;
2539 unsigned int P_it = 0;
2540 unsigned int P_it_max;
2550 while ((P_error >
_P_tol && P_it < P_it_max))
2555 _console <<
"Reached maximum number of axial pressure iterations" << std::endl;
2558 _console <<
"Solving Outer Iteration : " << P_it << std::endl;
2559 auto P_L2norm_old_axial =
_P_soln->L2norm();
2560 for (
unsigned int iblock = 0; iblock <
_n_blocks; iblock++)
2564 Real T_block_error = 1.0;
2566 _console <<
"Solving Block: " << iblock <<
" From first level: " << first_level
2567 <<
" to last level: " << last_level << std::endl;
2573 _console <<
"Reached maximum number of temperature iterations for block: " << iblock
2577 auto T_L2norm_old_block =
_T_soln->L2norm();
2594 _console <<
"Done with main solve." << std::endl;
2603 _console <<
"Starting thermal solve." << std::endl;
2610 _console <<
"Done with thermal solve." << std::endl;
2615 _console <<
"Start updating thermophysical properties." << std::endl;
2624 _console <<
"Done updating thermophysical properties." << std::endl;
2628 _aux->solution().close();
2630 auto T_L2norm_new =
_T_soln->L2norm();
2632 std::abs((T_L2norm_new - T_L2norm_old_block) / (T_L2norm_old_block + 1E-14));
2633 _console <<
"T_block_error: " << T_block_error << std::endl;
2636 auto P_L2norm_new_axial =
_P_soln->L2norm();
2638 std::abs((P_L2norm_new_axial - P_L2norm_old_axial) / (P_L2norm_old_axial +
_P_out + 1E-14));
2639 _console <<
"P_error :" << P_error << std::endl;
2642 _console <<
"Iteration: " << P_it << std::endl;
2643 _console <<
"Maximum iterations: " << P_it_max << std::endl;
2648 _console <<
"Finished executing subchannel solver\n";
2653 _console <<
"Commencing calculation of Pin surface temperature \n";
2654 for (
unsigned int i_pin = 0; i_pin <
_n_pins; i_pin++)
2656 for (
unsigned int iz = 0; iz <
_n_cells + 1; ++iz)
2660 Real rod_counter = 0.0;
2665 auto mu = (*_mu_soln)(node);
2666 auto S = (*_S_flow_soln)(node);
2667 auto w_perim = (*_w_perim_soln)(node);
2668 auto Dh_i = 4.0 *
S / w_perim;
2669 auto Re = (((*_mdot_soln)(node) /
S) * Dh_i /
mu);
2672 auto Pr = (*_mu_soln)(node)*
cp /
k;
2674 auto hw = Nu *
k / Dh_i;
2676 mooseError(
"Dpin should not be null or negative when computing pin powers: ",
2679 (*_q_prime_soln)(pin_node) / ((*
_Dpin_soln)(pin_node)*M_PI * hw) + (*_T_soln)(node);
2682 if (rod_counter > 0)
2683 _Tpin_soln->set(pin_node, sumTemp / rod_counter);
2685 mooseError(
"Pin was not found for pin index: " + std::to_string(i_pin));
2693 _console <<
"Commencing calculation of duct surface temperature " << std::endl;
2695 for (Node * dn : duct_nodes)
2698 auto mu = (*_mu_soln)(node_chan);
2699 auto S = (*_S_flow_soln)(node_chan);
2700 auto w_perim = (*_w_perim_soln)(node_chan);
2701 auto Dh_i = 4.0 *
S / w_perim;
2702 auto Re = (((*_mdot_soln)(node_chan) /
S) * Dh_i /
mu);
2705 auto Pr = (*_mu_soln)(node_chan)*
cp /
k;
2707 auto hw = Nu *
k / Dh_i;
2713 _aux->solution().close();
2716 Real power_in = 0.0;
2717 Real power_out = 0.0;
2718 Real Total_surface_area = 0.0;
2719 Real Total_wetted_perimeter = 0.0;
2720 Real mass_flow_in = 0.0;
2721 Real mass_flow_out = 0.0;
2722 for (
unsigned int i_ch = 0; i_ch <
_n_channels; i_ch++)
2726 Total_surface_area += (*_S_flow_soln)(node_in);
2727 Total_wetted_perimeter += (*_w_perim_soln)(node_in);
2728 power_in += (*_mdot_soln)(node_in) * (*
_h_soln)(node_in);
2729 power_out += (*_mdot_soln)(node_out) * (*
_h_soln)(node_out);
2730 mass_flow_in += (*_mdot_soln)(node_in);
2731 mass_flow_out += (*_mdot_soln)(node_out);
2733 auto h_bulk_out = power_out / mass_flow_out;
2734 auto T_bulk_out =
_fp->T_from_p_h(
_P_out, h_bulk_out);
2736 Real bulk_Dh = 4.0 * Total_surface_area / Total_wetted_perimeter;
2738 Real bulk_Re = mass_flow_in * bulk_Dh / (inlet_mu * Total_surface_area);
2741 _console <<
" ======================================= " << std::endl;
2742 _console <<
" ======== Subchannel Print Outs ======== " << std::endl;
2743 _console <<
" ======================================= " << std::endl;
2744 _console <<
"Total flow area :" << Total_surface_area <<
" m^2" << std::endl;
2745 _console <<
"Assembly hydraulic diameter :" << bulk_Dh <<
" m" << std::endl;
2746 _console <<
"Assembly Re number :" << bulk_Re <<
" [-]" << std::endl;
2747 _console <<
"Bulk coolant temperature at outlet :" << T_bulk_out <<
" K" << std::endl;
2748 _console <<
"Power added to coolant is : " << power_out - power_in <<
" Watt" << std::endl;
2749 _console <<
"Mass flow rate in is : " << mass_flow_in <<
" kg/sec" << std::endl;
2750 _console <<
"Mass balance is : " << mass_flow_out - mass_flow_in <<
" kg/sec" << std::endl;
2751 _console <<
"User defined outlet pressure is : " <<
_P_out <<
" Pa" << std::endl;
2752 _console <<
" ======================================= " << std::endl;
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 const unsigned int & getNumOfChannels() const =0
Return the number of channels per layer.
std::unique_ptr< SolutionHandle > _Tduct_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.
virtual const Real & getPinDiameter() const
Return Pin diameter.
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.
virtual Real computeBeta(unsigned int i_gap, unsigned int iz)=0
Computes turbulent mixing coefficient.
const bool _monolithic_thermal_bool
Thermal monolithic bool.
std::unique_ptr< SolutionHandle > _q_prime_duct_soln
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
static const std::string DUCT_LINEAR_HEAT_RATE
duct linear heat rate
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 bool _duct_mesh_exist
Flag that informs if there is a pin mesh or not.
static InputParameters validParams()
Vec _cmc_Wij_channel_dummy
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)
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::string & name() const
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 flux added by the duct.
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_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.
processor_id_type n_processors() const
std::vector< Real > _z_grid
axial location of nodes
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
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
virtual const unsigned int & getNumOfPins() const =0
Return the number of pins.
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
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 const unsigned int & getNumOfAxialCells() const
Return the number of axial cells.
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 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 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.
const Real & _P_tol
Convergence tolerance for the pressure loop in external solve.
void mooseError(Args &&... args) const
virtual bool solverSystemConverged(const unsigned int) override
virtual const unsigned int & getNumOfGapsPerLayer() const =0
Return the number of gaps per layer.
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
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