Solves the momentum equations using dual-time Picard iteration with Jameson RK smoothing.
Local to this translation unit.
749{
750 (void)ibm;
751 (void)fsi;
752
755
756
757 const PetscInt ti = simCtx->
step;
758 const PetscReal dt = simCtx->
dt;
759
760
762 const PetscReal alfa[] = {0.25, 1.0/3.0, 0.5, 1.0};
763 Vec *pRhs;
764
765
766 PetscBool force_restart = PETSC_FALSE;
767
768
770 const PetscReal tol_abs_delta = simCtx->
mom_atol;
771 const PetscReal tol_rtol_delta = simCtx->
mom_rtol;
772
773
774 PetscErrorCode ierr;
775 PetscMPIInt rank;
776 PetscInt istage, pseudo_iter;
777 PetscInt accepted_iter = 0, rejected_iter = 0, recovery_streak = 0;
778 PetscReal ts, te, cput;
779
780
781 PetscReal global_norm_delta = 10.0;
782 PetscReal global_rel_delta = 1.0;
783 PetscReal global_norm_resid = 1.0;
784 PetscReal global_rel_resid = 1.0;
785 PetscReal smoothed_trial_ratio = 1.0;
786
787
788
789
790
791
792
793
794 PetscReal lambda_max = 0.0;
795
796
797
798
799
801
802
803
804 PetscReal resid_ref = 0.0;
805 PetscReal dtau_min, dtau_max;
806
807
808 PetscReal *delta_sol_norm_init, *delta_sol_norm_prev, *delta_sol_norm_curr, *delta_sol_rel_curr;
809 PetscReal *resid_norm_init, *resid_norm_prev, *resid_norm_curr, *resid_rel_curr;
810 PetscReal *pseudo_dtau;
811 PetscReal *trial_ratio_log;
812 PetscReal last_accepted_resid;
813
814 PetscFunctionBeginUser;
816 ierr = MPI_Comm_rank(PETSC_COMM_WORLD, &rank); CHKERRQ(ierr);
818
819
820 ierr = PetscMalloc2(block_number, &delta_sol_norm_init, block_number, &delta_sol_norm_prev); CHKERRQ(ierr);
821 ierr = PetscMalloc2(block_number, &delta_sol_norm_curr, block_number, &delta_sol_rel_curr); CHKERRQ(ierr);
822 ierr = PetscMalloc2(block_number, &resid_norm_init, block_number, &resid_norm_prev); CHKERRQ(ierr);
823 ierr = PetscMalloc2(block_number, &resid_norm_curr, block_number, &pseudo_dtau); CHKERRQ(ierr);
824 ierr = PetscMalloc1(block_number, &resid_rel_curr); CHKERRQ(ierr);
825 ierr = PetscMalloc1(block_number, &trial_ratio_log); CHKERRQ(ierr);
826 ierr = PetscMalloc1(block_number, &pRhs); CHKERRQ(ierr);
827 last_accepted_resid = 0.0;
828
829 ierr = PetscTime(&ts); CHKERRQ(ierr);
830
831
832
833 if (block_number > 1) {
834
835 }
836
837 for (PetscInt bi = 0; bi < block_number; bi++) {
839
840
841
842
843 ierr = VecDuplicate(user[bi].Ucont, &user[bi].Rhs); CHKERRQ(ierr);
844 ierr = VecDuplicate(user[bi].Rhs, &pRhs[bi]); CHKERRQ(ierr);
845 ierr = VecDuplicate(user[bi].Ucont, &user[bi].dUcont); CHKERRQ(ierr);
846 ierr = VecDuplicate(user[bi].Ucont, &user[bi].pUcont); CHKERRQ(ierr);
847
848
849 ierr = VecCopy(user[bi].Ucont, user[bi].pUcont); CHKERRQ(ierr);
850
851
853
854
855 ierr = VecCopy(user[bi].Rhs, pRhs[bi]); CHKERRQ(ierr);
856
857
858 ierr = VecNorm(user[bi].Rhs, NORM_INFINITY, &resid_norm_init[bi]); CHKERRQ(ierr);
859
860
861
862 {
863 PetscReal ucont_inf;
864 ierr = VecNorm(user[bi].Ucont, NORM_INFINITY, &ucont_inf); CHKERRQ(ierr);
866 }
867
868
869 resid_norm_prev[bi] = resid_norm_init[bi];
870 delta_sol_norm_prev[bi] = 1000.0;
871
872
873 LOG_ALLOW(
GLOBAL,
LOG_INFO,
" Block %d | Max RHS = %.6f | initial pseudo-CFL = %.4f .\n", bi, resid_norm_init[bi], cfl);
874 }
875
876
877
878
879
880
881
882
883
884
888
889
890 for (PetscInt bi = 0; bi < block_number; bi++) {
891 pseudo_dtau[bi] = cfl / lambda_max;
892 }
893
894
895
896
897
898 {
899 PetscBool shadow = PETSC_FALSE;
900 ierr = PetscOptionsGetBool(NULL, NULL, "-mom_stability_shadow", &shadow, NULL); CHKERRQ(ierr);
901 if (shadow) {
906
907
909 "Momentum scale [shadow]: legacy_dtau=%.4e new_dtau=%.4e ratio=%.4f limiter=%s | "
910 "lambda_legacy=%.4e lambda_new=%.4e (B=%.4e C=%.4e D=%.4e) | "
911 "lt=%.4e lc=%.4e lv=%.4e | cell=(%d,%d,%d) blk=%d class=%d onesided=%d\n",
912 cfl / lambda_max, cfl / rep.
lambda, rep.
lambda / lambda_max, lim,
916 }
917 }
918
920 "Dual-time solver: lambda_max=%.4e [1/s] resid_ref=%.4e dtau_init=%.4e dtau range [%.4e, %.4e] "
921 "CFL range [%.4f, %.4f] rejection_threshold=%.3f (EMA alpha=%.2f) "
922 "growth=%.3f reduction=%.3f max_accepted=%d.\n",
923 lambda_max, resid_ref, cfl / lambda_max, dtau_min, dtau_max,
928 max_pseudo_steps);
929
930
931 pseudo_iter = 0;
932 PetscBool residual_convergence_enabled =
934 PetscBool converged = PETSC_FALSE;
935 PetscBool last_trial_nonfinite = PETSC_FALSE;
936
937
938 const PetscInt max_total_attempts = max_pseudo_steps * 3;
939 while (!converged && accepted_iter < max_pseudo_steps && pseudo_iter < max_total_attempts)
940 {
941 pseudo_iter++;
942 force_restart = PETSC_FALSE;
943
944
945 for (PetscInt bi = 0; bi < block_number; bi++) {
946 ierr = VecCopy(user[bi].pUcont, user[bi].Ucont); CHKERRQ(ierr);
947 ierr = VecCopy(pRhs[bi], user[bi].Rhs); CHKERRQ(ierr);
951 }
952
953 for (PetscInt bi = 0; bi < block_number; bi++) {
954
955
956 for (istage = 0; istage < 4; istage++) {
957
959
960
961
962
963 ierr = VecWAXPY(user[bi].Ucont,
964 pseudo_dtau[bi] * alfa[istage],
965 user[bi].Rhs,
966 user[bi].pUcont); CHKERRQ(ierr);
967
968
971
973
974
976
977 }
978
979
980
981
982
983
984 ierr = VecWAXPY(user[bi].dUcont, -1.0, user[bi].pUcont, user[bi].Ucont); CHKERRQ(ierr);
985
986
987 ierr = VecNorm(user[bi].dUcont, NORM_INFINITY, &delta_sol_norm_curr[bi]); CHKERRQ(ierr);
988 ierr = VecNorm(user[bi].Rhs, NORM_INFINITY, &resid_norm_curr[bi]); CHKERRQ(ierr);
989
990
991 if (pseudo_iter == 1) {
992 delta_sol_norm_init[bi] = delta_sol_norm_curr[bi];
993 delta_sol_rel_curr[bi] = 1.0;
994 resid_rel_curr[bi] = 1.0;
995
996 } else {
997 if (delta_sol_norm_init[bi] > 1.0e-10)
998 delta_sol_rel_curr[bi] = delta_sol_norm_curr[bi] / delta_sol_norm_init[bi];
999 else
1000 delta_sol_rel_curr[bi] = 0.0;
1001
1002 if(resid_norm_init[bi] > 1.0e-10)
1003 resid_rel_curr[bi] = resid_norm_curr[bi] / resid_norm_init[bi];
1004 else
1005 resid_rel_curr[bi] = 0.0;
1006 }
1007
1008
1009 {
1010 const PetscReal resid_floor_log = 1.0e-30;
1011 if (resid_norm_prev[bi] > resid_floor_log)
1012 trial_ratio_log[bi] = resid_norm_curr[bi] / resid_norm_prev[bi];
1013 else if (resid_norm_curr[bi] <= resid_floor_log)
1014 trial_ratio_log[bi] = 0.0;
1015 else
1016 trial_ratio_log[bi] = PETSC_MAX_REAL;
1017 }
1018 }
1019
1020
1021 global_norm_delta = -1.0e20;
1022 global_rel_delta = -1.0e20;
1023 global_norm_resid = -1.0e20;
1024 global_rel_resid = -1.0e20;
1025
1026 for (PetscInt bi = 0; bi < block_number; bi++) {
1027 global_norm_delta = PetscMax(delta_sol_norm_curr[bi], global_norm_delta);
1028 global_rel_delta = PetscMax(delta_sol_rel_curr[bi], global_rel_delta);
1029 global_norm_resid = PetscMax(resid_norm_curr[bi], global_norm_resid);
1030 global_rel_resid = PetscMax(resid_rel_curr[bi], global_rel_resid);
1031 }
1032 ierr = PetscTime(&te); CHKERRQ(ierr);
1033 cput = te - ts;
1035 pseudo_iter, global_norm_delta, global_rel_delta, global_rel_resid, cput);
1036
1037
1038 const PetscReal resid_floor = 1.0e-30;
1039 PetscReal global_trial_ratio = 0.0;
1040 PetscBool global_nonfinite = PETSC_FALSE;
1041 for (PetscInt bi = 0; bi < block_number; bi++) {
1042 PetscReal ratio;
1043 if (resid_norm_prev[bi] > resid_floor) {
1044 ratio = resid_norm_curr[bi] / resid_norm_prev[bi];
1045 } else if (resid_norm_curr[bi] <= resid_floor) {
1046 ratio = 0.0;
1047 } else {
1048 ratio = PETSC_MAX_REAL;
1049 }
1050 global_trial_ratio = PetscMax(global_trial_ratio, ratio);
1051 global_nonfinite = (PetscBool)(global_nonfinite ||
1052 PetscIsInfOrNanReal(delta_sol_norm_curr[bi]) ||
1053 PetscIsInfOrNanReal(resid_norm_curr[bi]) ||
1054 PetscIsInfOrNanReal(ratio));
1055 }
1056
1057 PetscReal reduced_trial_ratio;
1058 PetscMPIInt local_nonfinite = global_nonfinite ? 1 : 0;
1059 PetscMPIInt reduced_nonfinite = 0;
1060 ierr = MPI_Allreduce(&global_trial_ratio, &reduced_trial_ratio, 1, MPIU_REAL, MPI_MAX, PETSC_COMM_WORLD); CHKERRQ(ierr);
1061 ierr = MPI_Allreduce(&local_nonfinite, &reduced_nonfinite, 1, MPI_INT, MPI_LOR, PETSC_COMM_WORLD); CHKERRQ(ierr);
1062 global_trial_ratio = reduced_trial_ratio;
1063 global_nonfinite = reduced_nonfinite ? PETSC_TRUE : PETSC_FALSE;
1064 last_trial_nonfinite = global_nonfinite;
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078 PetscReal trial_smoothed = smoothed_trial_ratio;
1079 if (!global_nonfinite) {
1082 }
1084 " [k=%d] raw_ratio=%.4e smoothed_ratio=%.4e (threshold=%.3f) | "
1085 "|R_prev|=%.6e | |R_curr|=%.6e | CFL=%.6f\n",
1086 pseudo_iter, global_trial_ratio, trial_smoothed,
1088 resid_norm_prev[0], resid_norm_curr[0], pseudo_dtau[0]);
1089
1091
1092 force_restart = global_nonfinite;
1093 } else {
1094 force_restart = (PetscBool)(global_nonfinite ||
1096 }
1097
1098 if (force_restart) {
1099
1100
1101
1102 PetscReal old_dtau = pseudo_dtau[0];
1104
1105
1108 rejected_iter++;
1109 recovery_streak = 0;
1110 for (PetscInt bi = 0; bi < block_number; bi++) {
1111 ierr = VecCopy(user[bi].pUcont, user[bi].Ucont); CHKERRQ(ierr);
1112 ierr = VecCopy(pRhs[bi], user[bi].Rhs); CHKERRQ(ierr);
1116 pseudo_dtau[bi] = next_dtau;
1117 }
1119 " Trial %d REJECTED (raw_ratio=%.4e, smoothed=%.4e, nonfinite=%d); "
1120 "dtau %.4e -> %.4e (cfl_eff %.4f -> %.4f)%s\n",
1121 pseudo_iter, global_trial_ratio, trial_smoothed, (int)global_nonfinite,
1122 old_dtau, next_dtau, old_dtau * lambda_max, next_dtau * lambda_max,
1123 (old_dtau == next_dtau) ? " [AT FLOOR — no dtau reduction]" : "");
1124
1125 if (!rank) {
1126 for (PetscInt bi = 0; bi < block_number; bi++) {
1127 FILE *f;
1128 char filen[PETSC_MAX_PATH_LEN + 128];
1129 ierr = PetscSNPrintf(filen, sizeof(filen),
1130 "%s/Momentum_Solver_DualTime_Picard_Jameson_RK_History_Block_%1d.log",
1131 simCtx->
log_dir, bi); CHKERRQ(ierr);
1133 f = fopen(filen, "w");
1134 else
1135 f = fopen(filen, "a");
1137 PetscFPrintf(PETSC_COMM_WORLD, f,
"# Continuation from step %" PetscInt_FMT
"\n", simCtx->
StartStep);
1138
1139 PetscFPrintf(PETSC_COMM_WORLD, f,
1140 "Step: %d | PseudoIter(k): %d | dtau: %.6e | cfl_eff: %.4f | |dUk|: %le | "
1141 "|dUk|/|dU0|: %le | |Rk|: %le | |Rk|/|R0|: %le | "
1142 "trial_ratio: %le | smoothed_ratio: %le | status: rejected | "
1143 "dtau_after: %.6e | cfl_eff_after: %.4f\n",
1144 (int)ti, (int)pseudo_iter, old_dtau, old_dtau * lambda_max,
1145 delta_sol_norm_curr[bi], delta_sol_rel_curr[bi],
1146 resid_norm_curr[bi], resid_rel_curr[bi],
1147 trial_ratio_log[bi], trial_smoothed,
1148 next_dtau, next_dtau * lambda_max);
1149 fclose(f);
1150 }
1151 }
1152 if (old_dtau <= dtau_min) {
1153 if (global_nonfinite) {
1154 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_CONV_FAILED,
1155 "Momentum solver produced a non-finite trial at minimum pseudo-CFL.");
1156 }
1157
1158
1160 " Trial %d REJECTED (ratio=%.4e) at minimum dtau (%.4e, cfl_eff=%.4f) "
1161 "with no further reduction possible; breaking retry loop.\n",
1162 pseudo_iter, global_trial_ratio, old_dtau, old_dtau * lambda_max);
1163 break;
1164 }
1165 continue;
1166 }
1167
1168 accepted_iter++;
1169 smoothed_trial_ratio = trial_smoothed;
1170 last_trial_nonfinite = PETSC_FALSE;
1171 last_accepted_resid = resid_norm_curr[0];
1172 for (PetscInt bi = 0; bi < block_number; bi++) {
1173 ierr = VecCopy(user[bi].Ucont, user[bi].pUcont); CHKERRQ(ierr);
1174 ierr = VecCopy(user[bi].Rhs, pRhs[bi]); CHKERRQ(ierr);
1175 resid_norm_prev[bi] = resid_norm_curr[bi];
1176 delta_sol_norm_prev[bi] = delta_sol_norm_curr[bi];
1177 }
1178
1179
1180
1181
1182 PetscReal old_dtau = pseudo_dtau[0];
1183 PetscReal next_dtau = old_dtau;
1184 if (global_trial_ratio < 0.90) {
1185
1187 recovery_streak = 0;
1188 } else if (global_trial_ratio <= 1.0) {
1189
1190 recovery_streak++;
1191 if (recovery_streak >= 3) {
1193 recovery_streak = 0;
1194 }
1195 } else {
1196
1198 recovery_streak = 0;
1199 }
1200
1201
1202
1204 next_dtau = PetscMin(next_dtau, dtau_max);
1205 next_dtau = PetscMin(next_dtau, cfl_cap / lambda_max);
1206 next_dtau = PetscMax(next_dtau, dtau_min);
1207 for (PetscInt bi = 0; bi < block_number; bi++) pseudo_dtau[bi] = next_dtau;
1208
1210 " Trial %d ACCEPTED (raw_ratio=%.4e, smoothed=%.4e); |dU|=%.6e | "
1211 "dtau %.4e -> %.4e (cfl_eff %.4f -> %.4f)\n",
1212 pseudo_iter, global_trial_ratio, trial_smoothed, global_norm_delta,
1213 old_dtau, next_dtau, old_dtau * lambda_max, next_dtau * lambda_max);
1214
1215
1216 if (!rank) {
1217 for (PetscInt bi = 0; bi < block_number; bi++) {
1218 FILE *f;
1219 char filen[PETSC_MAX_PATH_LEN + 128];
1220 ierr = PetscSNPrintf(filen, sizeof(filen),
1221 "%s/Momentum_Solver_DualTime_Picard_Jameson_RK_History_Block_%1d.log",
1222 simCtx->
log_dir, bi); CHKERRQ(ierr);
1224 f = fopen(filen, "w");
1225 else
1226 f = fopen(filen, "a");
1228 PetscFPrintf(PETSC_COMM_WORLD, f,
"# Continuation from step %" PetscInt_FMT
"\n", simCtx->
StartStep);
1229
1230 PetscFPrintf(PETSC_COMM_WORLD, f,
1231 "Step: %d | PseudoIter(k): %d | dtau: %.6e | cfl_eff: %.4f | |dUk|: %le | "
1232 "|dUk|/|dU0|: %le | |Rk|: %le | |Rk|/|R0|: %le | "
1233 "trial_ratio: %le | smoothed_ratio: %le | status: accepted | "
1234 "dtau_after: %.6e | cfl_eff_after: %.4f\n",
1235 (int)ti, (int)pseudo_iter, old_dtau, old_dtau * lambda_max,
1236 delta_sol_norm_curr[bi], delta_sol_rel_curr[bi],
1237 resid_norm_curr[bi], resid_rel_curr[bi],
1238 trial_ratio_log[bi], trial_smoothed,
1239 next_dtau, next_dtau * lambda_max);
1240 fclose(f);
1241 }
1242 }
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277 if (residual_convergence_enabled) {
1278 const PetscBool residual_abs_pass = (PetscBool)(
1280 global_norm_resid <= simCtx->mom_resid_atol * resid_ref);
1281 const PetscBool residual_rel_pass = (PetscBool)(
1282 simCtx->
mom_resid_rtol > 0.0 && global_rel_resid <= simCtx->mom_resid_rtol);
1283 const PetscBool update_pass = (PetscBool)(
1284 tol_rtol_delta <= 0.0 || global_rel_delta <= tol_rtol_delta);
1285 converged = (PetscBool)(residual_abs_pass || (residual_rel_pass && update_pass));
1286 } else {
1287 converged = (PetscBool)(global_norm_delta <= tol_abs_delta &&
1288 global_rel_delta <= tol_rtol_delta);
1289 }
1290
1291 if (block_number > 1) {
1292
1293 }
1294 }
1295
1296 if (last_trial_nonfinite) {
1297 SETERRQ(PETSC_COMM_WORLD, PETSC_ERR_CONV_FAILED,
1298 "Momentum solver exhausted its attempt limit while recovering from a non-finite trial.");
1299 }
1300
1301
1302
1303
1304
1305 PetscReal next_dtau_start = pseudo_dtau[0];
1306 PetscReal next_cfl_warmstart = next_dtau_start * lambda_max;
1307
1308 if (!rank) {
1310 " Step %d finished: dtau=%.4e cfl_eff=%.4f lambda_max=%.4e [1/s]. "
1311 "Next step warm-starts at cfl=%.4f.\n",
1312 simCtx->
step, next_dtau_start, next_cfl_warmstart, lambda_max, next_cfl_warmstart);
1313 }
1314
1315
1318
1319
1320
1321
1322 if (accepted_iter == 0) {
1323 for (PetscInt bi = 0; bi < block_number; bi++) {
1324 ierr = VecCopy(user[bi].pUcont, user[bi].Ucont); CHKERRQ(ierr);
1325 ierr = VecCopy(pRhs[bi], user[bi].Rhs); CHKERRQ(ierr);
1326 }
1327 }
1328 for (PetscInt bi = 0; bi < block_number; bi++) {
1332 }
1333
1335 if (!converged) {
1336 PetscPrintf(PETSC_COMM_WORLD,
1337 "[WARNING] Momentum solver step %d: reached %d total attempts (%d accepted, %d rejected) "
1338 "without convergence; continuing from last accepted finite state.\n",
1339 (int)ti, pseudo_iter, accepted_iter, rejected_iter);
1340 }
1341 if (accepted_iter == 0) {
1342 PetscPrintf(PETSC_COMM_WORLD,
1343 "[WARNING] Momentum solver step %d: no pseudo-time trials were accepted; "
1344 "retaining physical-step entry state.\n", (int)ti);
1345 }
1347 "Momentum solver finished: %d attempts (%d accepted, %d rejected) of %d max accepted / %d hard cap, "
1348 "converged=%s, last accepted |R|=%.6e, last accepted |dU|=%.6e, "
1349 "next_dtau=%.4e (cfl=%.4f).\n",
1350 pseudo_iter, accepted_iter, rejected_iter, max_pseudo_steps, max_total_attempts,
1351 converged ? "yes" : "no",
1352 (accepted_iter > 0) ? last_accepted_resid : resid_norm_init[0],
1353 (accepted_iter > 0) ? delta_sol_norm_prev[0] : 0.0,
1354 next_dtau_start, next_cfl_warmstart);
1355
1356
1357 for (PetscInt bi = 0; bi < block_number; bi++) {
1358 ierr = VecDestroy(&user[bi].Rhs); CHKERRQ(ierr);
1359 ierr = VecDestroy(&user[bi].dUcont); CHKERRQ(ierr);
1360 ierr = VecDestroy(&user[bi].pUcont); CHKERRQ(ierr);
1361 ierr = VecDestroy(&pRhs[bi]); CHKERRQ(ierr);
1362 }
1363 ierr = PetscFree(pRhs); CHKERRQ(ierr);
1364
1365 ierr = PetscFree2(delta_sol_norm_init, delta_sol_norm_prev);CHKERRQ(ierr);
1366 ierr = PetscFree2(delta_sol_norm_curr, delta_sol_rel_curr);CHKERRQ(ierr);
1367 ierr = PetscFree2(resid_norm_init, resid_norm_prev);CHKERRQ(ierr);
1368 ierr = PetscFree2(resid_norm_curr, pseudo_dtau); CHKERRQ(ierr);
1369 ierr = PetscFree(resid_rel_curr); CHKERRQ(ierr);
1370 ierr = PetscFree(trial_ratio_log); CHKERRQ(ierr);
1371
1373 PetscFunctionReturn(0);
1374}
@ LOG_TRACE
Very fine-grained tracing information for in-depth debugging.
@ LOG_WARNING
Non-critical issues that warrant attention.
#define MOM_CFL_CAP_SAFETY
static PetscErrorCode ComputeGlobalSpectralRadiusEstimate(UserCtx *user, PetscInt block_number, PetscReal dt, PetscReal *lambda_max_out)
Compute a conservative global pseudo-time spectral radius estimate.
PetscErrorCode ComputeTotalResidual(UserCtx *user)
Shared implementation of ComputeTotalResidual().
PetscErrorCode ComputeMomentumStabilityEstimate(UserCtx *user, PetscInt block_number, PetscReal dt, MomStabCandidate candidate, MomStabilityReport *rep)
Practical conservative momentum pseudo-time stability estimate (shadow).
#define MOM_CFL_CAP_RELAX
Diagnostic report produced by ComputeMomentumStabilityEstimate().
PetscReal mom_last_lambda_max
PetscReal pseudo_cfl_reduction_factor
PetscBool mom_last_converged
PetscBool no_pseudo_cfl_backtrack
char log_dir[PETSC_MAX_PATH_LEN]
PetscReal mom_dt_jameson_residual_norm_noise_allowance_factor
PetscReal pseudo_cfl_growth_factor
PetscInt mom_max_pseudo_steps
PetscReal mom_ratio_ema_alpha