@@ -417,8 +417,6 @@ void CNEMOEulerSolver::SetMax_Eigenvalue(CGeometry *geometry, CConfig *config) {
417417void CNEMOEulerSolver::Centered_Residual (CGeometry *geometry, CSolver **solver_container, CNumerics **numerics_container,
418418 CConfig *config, unsigned short iMesh, unsigned short iRKStep) {
419419 unsigned long iEdge, iPoint, jPoint;
420- unsigned short iVar, jVar;
421- bool err;
422420
423421 CNumerics* numerics = numerics_container[CONV_TERM];
424422
@@ -452,17 +450,8 @@ void CNEMOEulerSolver::Centered_Residual(CGeometry *geometry, CSolver **solver_c
452450 /* --- Compute residuals, and Jacobians ---*/
453451 auto residual = numerics->ComputeResidual (config);
454452
455- /* --- Check for NaNs before applying the residual to the linear system ---*/
456- err = false ;
457- for (iVar = 0 ; iVar < nVar; iVar++)
458- if (residual[iVar] != residual[iVar])
459- err = true ;
460- if (implicit)
461- for (iVar = 0 ; iVar < nVar; iVar++)
462- for (jVar = 0 ; jVar < nVar; jVar++)
463- if ((residual.jacobian_i [iVar][jVar] != residual.jacobian_i [iVar][jVar]) ||
464- (residual.jacobian_j [iVar][jVar] != residual.jacobian_j [iVar][jVar]))
465- err = true ;
453+ /* --- Check residuals/Jacobians --*/
454+ bool err = CNumerics::CheckResidualNaNs (implicit, nVar, residual);
466455
467456 /* --- Update the residual and Jacobian ---*/
468457 if (!err) {
@@ -614,15 +603,7 @@ void CNEMOEulerSolver::Upwind_Residual(CGeometry *geometry, CSolver **solver_con
614603 auto residual = numerics->ComputeResidual (config);
615604
616605 /* --- Check for NaNs before applying the residual to the linear system ---*/
617- bool err = false ;
618- for (iVar = 0 ; iVar < nVar; iVar++)
619- if (residual[iVar] != residual[iVar]) err = true ;
620- if (implicit)
621- for (auto iVar = 0u ; iVar < nVar; iVar++)
622- for (auto jVar = 0u ; jVar < nVar; jVar++)
623- if ((residual.jacobian_i [iVar][jVar] != residual.jacobian_i [iVar][jVar]) ||
624- (residual.jacobian_j [iVar][jVar] != residual.jacobian_j [iVar][jVar]) )
625- err = true ;
606+ bool err = CNumerics::CheckResidualNaNs (implicit, nVar, residual);
626607
627608 /* --- Update the residual and Jacobian ---*/
628609 if (!err) {
@@ -761,7 +742,7 @@ bool CNEMOEulerSolver::CheckNonPhys(const su2double *V) const {
761742
762743void CNEMOEulerSolver::Source_Residual (CGeometry *geometry, CSolver **solver_container, CNumerics **numerics_container, CConfig *config, unsigned short iMesh) {
763744
764- unsigned short iVar, jVar ;
745+ unsigned short iVar;
765746 unsigned long iPoint;
766747
767748 /* --- Assign booleans ---*/
@@ -817,13 +798,7 @@ void CNEMOEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_con
817798 auto residual = numerics->ComputeChemistry (config);
818799
819800 /* --- Check for errors before applying source to the linear system ---*/
820- err = false ;
821- for (iVar = 0 ; iVar < nVar; iVar++)
822- if (residual[iVar] != residual[iVar]) err = true ;
823- if (implicit)
824- for (iVar = 0 ; iVar < nVar; iVar++)
825- for (jVar = 0 ; jVar < nVar; jVar++)
826- if (residual.jacobian_i [iVar][jVar] != residual.jacobian_i [iVar][jVar]) err = true ;
801+ err = CNumerics::CheckResidualNaNs (implicit, nVar, residual);
827802
828803 /* --- Apply the chemical sources to the linear system ---*/
829804 if (!err) {
@@ -842,13 +817,7 @@ void CNEMOEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_con
842817 auto residual = numerics->ComputeVibRelaxation (config);
843818
844819 /* --- Check for errors before applying source to the linear system ---*/
845- err = false ;
846- for (iVar = 0 ; iVar < nVar; iVar++)
847- if (residual[iVar] != residual[iVar]) err = true ;
848- if (implicit)
849- for (iVar = 0 ; iVar < nVar; iVar++)
850- for (jVar = 0 ; jVar < nVar; jVar++)
851- if (residual.jacobian_i [iVar][jVar] != residual.jacobian_i [iVar][jVar]) err = true ;
820+ err = CNumerics::CheckResidualNaNs (implicit, nVar, residual);
852821
853822 /* --- Apply the vibrational relaxation terms to the linear system ---*/
854823 if (!err) {
@@ -896,13 +865,7 @@ void CNEMOEulerSolver::Source_Residual(CGeometry *geometry, CSolver **solver_con
896865 auto residual = numerics->ComputeAxisymmetric (config);
897866
898867 /* --- Check for errors before applying source to the linear system ---*/
899- err = false ;
900- for (iVar = 0 ; iVar < nVar; iVar++)
901- if (residual[iVar] != residual[iVar]) err = true ;
902- if (implicit)
903- for (iVar = 0 ; iVar < nVar; iVar++)
904- for (jVar = 0 ; jVar < nVar; jVar++)
905- if (residual.jacobian_i [iVar][jVar] != residual.jacobian_i [iVar][jVar]) err = true ;
868+ err = CNumerics::CheckResidualNaNs (implicit, nVar, residual);
906869
907870 /* --- Apply the update to the linear system ---*/
908871 if (!err) {
@@ -965,6 +928,60 @@ void CNEMOEulerSolver::CompleteImplicitIteration(CGeometry *geometry, CSolver**,
965928 CompleteImplicitIteration_impl<true >(geometry, config);
966929}
967930
931+ void CNEMOEulerSolver::ComputeUnderRelaxationFactor (const CConfig *config) {
932+
933+ /* Loop over the solution update given by relaxing the linear
934+ system for this nonlinear iteration. */
935+
936+ const su2double allowableRatio = 0.2 ;
937+
938+ SU2_OMP_FOR_STAT (omp_chunk_size)
939+ for (unsigned long iPoint = 0 ; iPoint < nPointDomain; iPoint++) {
940+ su2double localUnderRelaxation = 1.0 ;
941+
942+ su2double num = 0.0 ;
943+ su2double denom = 0.0 ;
944+
945+ for (unsigned short iVar = 0 ; iVar < nVar; iVar++) {
946+ /* We impose a limit on the maximum percentage that the
947+ density (sum of all species) and energy can change over a nonlinear iteration. */
948+
949+ const unsigned long index = iPoint * nVar + iVar;
950+ if (iVar < config->GetnSpecies ()) {
951+ num += fabs (LinSysSol[index]);
952+ denom += fabs (nodes->GetSolution (iPoint, iVar));
953+
954+ /* --- If final density/species, compute Under-relaxation ---*/
955+ if (iVar == (config ->GetnSpecies ()-1 )){
956+ su2double ratio = (num/(denom+EPS));
957+ if (ratio > allowableRatio) {
958+ localUnderRelaxation = min (allowableRatio / ratio, localUnderRelaxation);
959+ }
960+ }
961+
962+ /* --- Energy ---*/
963+ if (iVar == (nVar-2 )){
964+ su2double ratio = fabs (LinSysSol[index]) / (fabs (nodes->GetSolution (iPoint, iVar)) + EPS);
965+ if (ratio > allowableRatio) {
966+ localUnderRelaxation = min (allowableRatio / ratio, localUnderRelaxation);
967+ }
968+ }
969+ }
970+ }
971+
972+ /* Threshold the relaxation factor in the event that there is
973+ a very small value. This helps avoid catastrophic crashes due
974+ to non-realizable states by canceling the update. */
975+
976+ if (localUnderRelaxation < 1e-10 ) localUnderRelaxation = 0.0 ;
977+
978+ /* Store the under-relaxation factor for this point. */
979+
980+ nodes->SetUnderRelaxation (iPoint, localUnderRelaxation);
981+ }
982+ END_SU2_OMP_FOR
983+ }
984+
968985void CNEMOEulerSolver::SetNondimensionalization (CConfig *config, unsigned short iMesh) {
969986
970987 su2double
@@ -2327,7 +2344,7 @@ SU2_MPI::Error("BC_SUPERSONIC_INLET: Not operational in NEMO.", CURRENT_FUNCTION
23272344//
23282345// /*--- Jacobian contribution for implicit integration ---*/
23292346// //if (implicit)
2330- // // Jacobian.AddBlock2Daig (iPoint, residual.jacobian_i);
2347+ // // Jacobian.AddBlock2Diag (iPoint, residual.jacobian_i);
23312348//
23322349// /*--- Viscous contribution ---*/
23332350// if (viscous) {
@@ -2352,7 +2369,7 @@ SU2_MPI::Error("BC_SUPERSONIC_INLET: Not operational in NEMO.", CURRENT_FUNCTION
23522369//
23532370// /*--- Jacobian contribution for implicit integration ---*/
23542371// //if (implicit)
2355- // // Jacobian.SubtractBlock (iPoint, residual.jacobian_i );
2372+ // // Jacobian.SubtractBlock2Diag (iPoint, residual.Jacobian_i );
23562373// }
23572374//
23582375// }
0 commit comments