Operation_IterativeLoopN.cpp (getdp-3.4.0-source.tgz) | : | Operation_IterativeLoopN.cpp (getdp-3.5.0-source.tgz) | ||
---|---|---|---|---|
// GetDP - Copyright (C) 1997-2021 P. Dular and C. Geuzaine, University of Liege | // GetDP - Copyright (C) 1997-2022 P. Dular and C. Geuzaine, University of Liege | |||
// | // | |||
// See the LICENSE.txt file for license information. Please report all | // See the LICENSE.txt file for license information. Please report all | |||
// issues on https://gitlab.onelab.info/getdp/getdp/issues. | // issues on https://gitlab.onelab.info/getdp/getdp/issues. | |||
// | // | |||
// Contributor(s): | // Contributor(s): | |||
// Michael Asam | // Michael Asam | |||
#include <stdio.h> | #include <stdio.h> | |||
#include "ProData.h" | #include "ProData.h" | |||
#include "DofData.h" | #include "DofData.h" | |||
#include "SolvingOperations.h" | #include "SolvingOperations.h" | |||
#include "SolvingAnalyse.h" | #include "SolvingAnalyse.h" | |||
#include "Message.h" | #include "Message.h" | |||
#include "Cal_Quantity.h" | #include "Cal_Quantity.h" | |||
extern struct CurrentData Current; | extern struct CurrentData Current; | |||
extern int Flag_IterativeLoopN; | extern int Flag_IterativeLoopN; | |||
extern int Flag_IterativeLoopConverged; | extern int Flag_IterativeLoopConverged; | |||
/* ------------------------------------------------------------------------ */ | /* ------------------------------------------------------------------------ */ | |||
/* C a l M a x E r r o r R a t i o */ | /* C a l M a x E r r o r R a t i o */ | |||
/* ------------------------------------------------------------------------ */ | /* ------------------------------------------------------------------------ */ | |||
double CalcMaxErrorRatio(Resolution *Resolution_P, | double CalcMaxErrorRatio(Resolution *Resolution_P, DofData *DofData_P0, | |||
DofData *DofData_P0, | List_T *ILsystems_L, List_T *LEPostOp_L, | |||
List_T *ILsystems_L, | List_T *xPrevious_L, List_T *PostOpSolutionPrevious_L) | |||
List_T *LEPostOp_L, | ||||
List_T *xPrevious_L, | ||||
List_T *PostOpSolutionPrevious_L) | ||||
{ | { | |||
DofData *DofData_P=NULL; | DofData *DofData_P = NULL; | |||
DefineSystem *DefineSystem_P; | DefineSystem *DefineSystem_P; | |||
IterativeLoopSystem ILsystem; | IterativeLoopSystem ILsystem; | |||
LoopErrorPostOperation ILPostOp; | LoopErrorPostOperation ILPostOp; | |||
PostOpSolutions *PostOpSolutions_P; | PostOpSolutions *PostOpSolutions_P; | |||
Solution *Solution_P; | Solution *Solution_P; | |||
gVector *xPrevious_P, *xCurrent_P; // new and last solut | gVector *xPrevious_P, *xCurrent_P; // new and last solution vector | |||
ion vector | gVector xError; // Local Truncation Error vector | |||
gVector xError; // Local Truncation E | int NbrSolutions, PostOpSolLength; | |||
rror vector | double ErrorRatio, MaxErrorRatio; | |||
int NbrSolutions, PostOpSolLength; | ||||
double ErrorRatio, MaxErrorRatio; | ||||
MaxErrorRatio = 0.; | MaxErrorRatio = 0.; | |||
// Loop through all given systems | // Loop through all given systems | |||
for(int i = 0; i < List_Nbr(ILsystems_L); i++){ | for(int i = 0; i < List_Nbr(ILsystems_L); i++) { | |||
List_Read(ILsystems_L, i, &ILsystem); | List_Read(ILsystems_L, i, &ILsystem); | |||
DofData_P = DofData_P0 + ILsystem.SystemIndex; | DofData_P = DofData_P0 + ILsystem.SystemIndex; | |||
DefineSystem_P = (DefineSystem*)List_Pointer(Resolution_P->DefineSystem, | DefineSystem_P = (DefineSystem *)List_Pointer(Resolution_P->DefineSystem, | |||
ILsystem.SystemIndex); | ILsystem.SystemIndex); | |||
xPrevious_P = (gVector*)List_Pointer(xPrevious_L, i); | xPrevious_P = (gVector *)List_Pointer(xPrevious_L, i); | |||
xCurrent_P = &DofData_P->CurrentSolution->x; | xCurrent_P = &DofData_P->CurrentSolution->x; | |||
LinAlg_CreateVector(&xError, &DofData_P->Solver, DofData_P->NbrDof); | LinAlg_CreateVector(&xError, &DofData_P->Solver, DofData_P->NbrDof); | |||
switch (ILsystem.NormOf) { | switch(ILsystem.NormOf) { | |||
case SOLUTION: | case SOLUTION: | |||
// Vector of errors: xError = xCurrent - xPrevious | // Vector of errors: xError = xCurrent - xPrevious | |||
LinAlg_CopyVector(xCurrent_P, &xError); | LinAlg_CopyVector(xCurrent_P, &xError); | |||
LinAlg_SubVectorVector(&xError, xPrevious_P, &xError); | LinAlg_SubVectorVector(&xError, xPrevious_P, &xError); | |||
Cal_SolutionErrorRatio(&xError, xCurrent_P, | Cal_SolutionErrorRatio(&xError, xCurrent_P, ILsystem.SystemILreltol, | |||
ILsystem.SystemILreltol, ILsystem.SystemILabstol, | ILsystem.SystemILabstol, ILsystem.NormType, | |||
ILsystem.NormType, &ErrorRatio); | &ErrorRatio); | |||
break; | break; | |||
case RECALCRESIDUAL: | case RECALCRESIDUAL: | |||
// Calculating the actual residual: xError = b(xn)-A(xn)*xn | // Calculating the actual residual: xError = b(xn)-A(xn)*xn | |||
// Works also for "Solve" but its computational expensive | // Works also for "Solve" but its computational expensive | |||
ReGenerate_System(DefineSystem_P, DofData_P, DofData_P0, 1); | ReGenerate_System(DefineSystem_P, DofData_P, DofData_P0, 1); | |||
LinAlg_ProdMatrixVector(&DofData_P->A, &DofData_P->CurrentSolution->x, & | LinAlg_ProdMatrixVector(&DofData_P->A, &DofData_P->CurrentSolution->x, | |||
xError); | &xError); | |||
LinAlg_SubVectorVector(&DofData_P->b, &xError, &xError); | LinAlg_SubVectorVector(&DofData_P->b, &xError, &xError); | |||
Cal_SolutionErrorRatio(&xError, &DofData_P->b, | Cal_SolutionErrorRatio(&xError, &DofData_P->b, ILsystem.SystemILreltol, | |||
ILsystem.SystemILreltol, ILsystem.SystemILabstol, | ILsystem.SystemILabstol, ILsystem.NormType, | |||
ILsystem.NormType, &ErrorRatio); | &ErrorRatio); | |||
break; | break; | |||
case RESIDUAL: | case RESIDUAL: | |||
// Or alternatively look at the old residual (from e.g. SolveJac) | // Or alternatively look at the old residual (from e.g. SolveJac) | |||
// -> More efficient but causes one extra iteration | // -> More efficient but causes one extra iteration | |||
Cal_SolutionErrorRatio(&DofData_P->res, &DofData_P->b, | Cal_SolutionErrorRatio(&DofData_P->res, &DofData_P->b, | |||
ILsystem.SystemILreltol, ILsystem.SystemILabstol, | ILsystem.SystemILreltol, ILsystem.SystemILabstol, | |||
ILsystem.NormType, &ErrorRatio); | ILsystem.NormType, &ErrorRatio); | |||
break; | break; | |||
default: | default: Message::Error("Unknown object for error norm"); break; | |||
Message::Error("Unknown object for error norm"); | ||||
break; | ||||
} | } | |||
LinAlg_DestroyVector(&xError); | LinAlg_DestroyVector(&xError); | |||
if (ErrorRatio != ErrorRatio) { // If ErrorRatio = NaN | if(ErrorRatio != ErrorRatio) { // If ErrorRatio = NaN | |||
MaxErrorRatio = ErrorRatio; | MaxErrorRatio = ErrorRatio; | |||
break; | break; | |||
} | } | |||
else if (ErrorRatio > MaxErrorRatio) | else if(ErrorRatio > MaxErrorRatio) | |||
MaxErrorRatio = ErrorRatio; | MaxErrorRatio = ErrorRatio; | |||
//Current.Residual = ErrorRatio; //kj+++ (should be commented here, Current. | if(Message::GetVerbosity() > 5) { | |||
ResidualN used instead and defined at the end of CalcMaxErrorRatio) | Message::Info( | |||
if (Message::GetVerbosity() > 5) { | "IterativeLoopN: %s of %s error ratio from system %s: %.3g", | |||
Message::Info("IterativeLoopN: %s of %s error ratio from system %s: %.3g" | ILsystem.NormTypeString, ILsystem.NormOfString, DefineSystem_P->Name, | |||
, | ErrorRatio); | |||
ILsystem.NormTypeString, ILsystem.NormOfString, DefineSystem_P->Name, | ||||
ErrorRatio); | ||||
} | } | |||
} | } | |||
// Loop through all specified PostOperations | // Loop through all specified PostOperations | |||
for(int i = 0; i < List_Nbr(LEPostOp_L); i++){ | for(int i = 0; i < List_Nbr(LEPostOp_L); i++) { | |||
List_Read(LEPostOp_L, i, &ILPostOp); | List_Read(LEPostOp_L, i, &ILPostOp); | |||
PostOpSolutions_P = (struct PostOpSolutions*) | PostOpSolutions_P = | |||
List_Pointer(Current.PostOpData_L, i); | (struct PostOpSolutions *)List_Pointer(Current.PostOpData_L, i); | |||
NbrSolutions = List_Nbr(PostOpSolutions_P->Solutions_L); | NbrSolutions = List_Nbr(PostOpSolutions_P->Solutions_L); | |||
Solution_P = (struct Solution*)List_Pointer(PostOpSolutions_P->Solutions_L, | Solution_P = (struct Solution *)List_Pointer(PostOpSolutions_P->Solutions_L, | |||
NbrSolutions-1); | NbrSolutions - 1); | |||
xPrevious_P = (gVector*)List_Pointer(PostOpSolutionPrevious_L, i); | xPrevious_P = (gVector *)List_Pointer(PostOpSolutionPrevious_L, i); | |||
xCurrent_P = &Solution_P->x; | xCurrent_P = &Solution_P->x; | |||
LinAlg_AssembleVector(&Solution_P->x); | LinAlg_AssembleVector(&Solution_P->x); | |||
LinAlg_GetVectorSize(xCurrent_P, &PostOpSolLength); | LinAlg_GetVectorSize(xCurrent_P, &PostOpSolLength); | |||
LinAlg_CreateVector(&xError, &DofData_P0->Solver, PostOpSolLength); | LinAlg_CreateVector(&xError, &DofData_P0->Solver, PostOpSolLength); | |||
// Vector of errors: xError = xCurrent - xPrevious | // Vector of errors: xError = xCurrent - xPrevious | |||
LinAlg_CopyVector(xCurrent_P, &xError); | LinAlg_CopyVector(xCurrent_P, &xError); | |||
LinAlg_SubVectorVector(&xError, xPrevious_P, &xError); | LinAlg_SubVectorVector(&xError, xPrevious_P, &xError); | |||
Cal_SolutionErrorRatio(&xError, xCurrent_P, | Cal_SolutionErrorRatio(&xError, xCurrent_P, ILPostOp.PostOperationReltol, | |||
ILPostOp.PostOperationReltol, ILPostOp.PostOperationA | ILPostOp.PostOperationAbstol, ILPostOp.NormType, | |||
bstol, | &ErrorRatio); | |||
ILPostOp.NormType, &ErrorRatio); | ||||
LinAlg_DestroyVector(&xError); | LinAlg_DestroyVector(&xError); | |||
if (ErrorRatio != ErrorRatio) { // If ErrorRatio = NaN | if(ErrorRatio != ErrorRatio) { // If ErrorRatio = NaN | |||
MaxErrorRatio = ErrorRatio; | MaxErrorRatio = ErrorRatio; | |||
break; | break; | |||
} | } | |||
else if (ErrorRatio > MaxErrorRatio) | else if(ErrorRatio > MaxErrorRatio) | |||
MaxErrorRatio = ErrorRatio; | MaxErrorRatio = ErrorRatio; | |||
if (Message::GetVerbosity() > 5) { | if(Message::GetVerbosity() > 5) { | |||
Message::Info("IterativeLoopN: %s error ratio from PostOperation %s: %.3g | Message::Info( | |||
", | "IterativeLoopN: %s error ratio from PostOperation %s: %.3g", | |||
ILPostOp.NormTypeString, ILPostOp.PostOperationName, | ILPostOp.NormTypeString, ILPostOp.PostOperationName, ErrorRatio); | |||
ErrorRatio); | ||||
} | } | |||
} | } | |||
Current.ResidualN = MaxErrorRatio ; //kj+++ Residual computed here for Iterat iveLoopN | Current.ResidualN = MaxErrorRatio; | |||
return MaxErrorRatio; | return MaxErrorRatio; | |||
} | } | |||
/* ------------------------------------------------------------------------ */ | /* ------------------------------------------------------------------------ */ | |||
/* O p e r a t i o n _ I t e r a t i v e L o o p N */ | /* O p e r a t i o n _ I t e r a t i v e L o o p N */ | |||
/* ------------------------------------------------------------------------ */ | /* ------------------------------------------------------------------------ */ | |||
void Operation_IterativeLoopN(Resolution *Resolution_P, | void Operation_IterativeLoopN(Resolution *Resolution_P, Operation *Operation_P, | |||
Operation *Operation_P, | DofData *DofData_P0, GeoData *GeoData_P0, | |||
DofData *DofData_P0, | Resolution *Resolution2_P, DofData *DofData2_P0, | |||
GeoData *GeoData_P0, | int *Flag_Break) | |||
Resolution *Resolution2_P, | ||||
DofData *DofData2_P0, | ||||
int *Flag_Break) | ||||
{ | { | |||
int NbrMaxIteration, RelaxationFactorIndex; | int NbrMaxIteration, RelaxationFactorIndex; | |||
int Num_Iteration, NbrPostOps, SavePostOpDataIndex, NbrSolutions; | int Num_Iteration, NbrPostOps, SavePostOpDataIndex, NbrSolutions; | |||
double Save_Iteration, MaxErrorRatio = 0.; | double Save_Iteration, MaxErrorRatio = 0.; | |||
List_T *ILsystems_L, *LEPostOp_L, *xPrevious_L; | List_T *ILsystems_L, *LEPostOp_L, *xPrevious_L; | |||
List_T *LEPostOpNames_L, *PostOpSolutionPrevious_L; | List_T *LEPostOpNames_L, *PostOpSolutionPrevious_L; | |||
List_T *SavePostOpData_L; | List_T *SavePostOpData_L; | |||
gVector *xPrevious_P, *PostOpResultPrevious_P; | gVector *xPrevious_P, *PostOpResultPrevious_P; | |||
Value Value; | Value Value; | |||
DofData *DofData_P=NULL; | DofData *DofData_P = NULL; | |||
IterativeLoopSystem ILsystem; | IterativeLoopSystem ILsystem; | |||
PostOpSolutions *PostOpSolutions_P; | PostOpSolutions *PostOpSolutions_P; | |||
Solution *Solution_P; | Solution *Solution_P; | |||
NbrMaxIteration = Operation_P->Case.IterativeLoop.NbrMaxIteration; | NbrMaxIteration = Operation_P->Case.IterativeLoop.NbrMaxIteration; | |||
RelaxationFactorIndex = Operation_P->Case.IterativeLoop.RelaxationFactorIndex | RelaxationFactorIndex = Operation_P->Case.IterativeLoop.RelaxationFactorIndex; | |||
; | ILsystems_L = Operation_P->Case.IterativeLoop.IterativeLoopSystems_L; | |||
ILsystems_L = Operation_P->Case.IterativeLoop.IterativeLoopSystems_ | LEPostOp_L = Operation_P->Case.IterativeLoop.IterativeLoopPOs_L; | |||
L; | ||||
LEPostOp_L = Operation_P->Case.IterativeLoop.IterativeLoopPOs_L; | if(ILsystems_L == NULL) | |||
ILsystems_L = List_Create(1, 1, sizeof(TimeLoopAdaptiveSystem)); | ||||
if (ILsystems_L == NULL) | if(LEPostOp_L == NULL) | |||
ILsystems_L = List_Create(1,1,sizeof(TimeLoopAdaptiveSystem)); | LEPostOp_L = List_Create(1, 1, sizeof(LoopErrorPostOperation)); | |||
if (LEPostOp_L == NULL) | ||||
LEPostOp_L = List_Create(1,1,sizeof(LoopErrorPostOperation)); | ||||
xPrevious_L = List_Create(4,4,sizeof(gVector)); | xPrevious_L = List_Create(4, 4, sizeof(gVector)); | |||
PostOpSolutionPrevious_L = List_Create(4,4,sizeof(gVector)); | PostOpSolutionPrevious_L = List_Create(4, 4, sizeof(gVector)); | |||
// Just some checks and initialization | // Just some checks and initialization | |||
// ----------------------------------- | // ----------------------------------- | |||
// Check if initial solutions for all specified systems are available | // Check if initial solutions for all specified systems are available | |||
for(int i = 0; i < List_Nbr(ILsystems_L); i++){ | for(int i = 0; i < List_Nbr(ILsystems_L); i++) { | |||
List_Read(ILsystems_L, i, &ILsystem); | List_Read(ILsystems_L, i, &ILsystem); | |||
DefineSystem *sys = (DefineSystem*)List_Pointer(Resolution_P->DefineSystem, | DefineSystem *sys = (DefineSystem *)List_Pointer(Resolution_P->DefineSystem, | |||
ILsystem.SystemIndex); | ILsystem.SystemIndex); | |||
DofData_P = DofData_P0 + ILsystem.SystemIndex; | DofData_P = DofData_P0 + ILsystem.SystemIndex; | |||
if(!List_Nbr(DofData_P->Solutions)) | if(!List_Nbr(DofData_P->Solutions)) | |||
Message::Error("No initial solution for system %s", sys->Name); | Message::Error("No initial solution for system %s", sys->Name); | |||
gVector xPrevious_S; | gVector xPrevious_S; | |||
LinAlg_CreateVector(&xPrevious_S, &DofData_P->Solver, DofData_P->NbrDof); | LinAlg_CreateVector(&xPrevious_S, &DofData_P->Solver, DofData_P->NbrDof); | |||
List_Add(xPrevious_L, &xPrevious_S); | List_Add(xPrevious_L, &xPrevious_S); | |||
} | } | |||
// Initializing stuff for PostOperations | // Initializing stuff for PostOperations | |||
SavePostOpData_L = Current.PostOpData_L; | SavePostOpData_L = Current.PostOpData_L; | |||
Current.PostOpData_L = NULL; | Current.PostOpData_L = NULL; | |||
SavePostOpDataIndex = Current.PostOpDataIndex; | SavePostOpDataIndex = Current.PostOpDataIndex; | |||
Current.PostOpDataIndex = -1; | Current.PostOpDataIndex = -1; | |||
NbrPostOps = List_Nbr(LEPostOp_L); | NbrPostOps = List_Nbr(LEPostOp_L); | |||
LEPostOpNames_L = List_Create(NbrPostOps,1,sizeof(char *)); | LEPostOpNames_L = List_Create(NbrPostOps, 1, sizeof(char *)); | |||
InitLEPostOperation(Resolution_P, DofData_P0, GeoData_P0, LEPostOp_L, | InitLEPostOperation(Resolution_P, DofData_P0, GeoData_P0, LEPostOp_L, | |||
LEPostOpNames_L, PostOpSolutionPrevious_L); | LEPostOpNames_L, PostOpSolutionPrevious_L); | |||
// Iterative loop | // Iterative loop | |||
// ---------------- | // ---------------- | |||
Save_Iteration = Current.Iteration ; | Save_Iteration = Current.Iteration; | |||
for (Num_Iteration = 1; Num_Iteration <= NbrMaxIteration; Num_Iteration++) { | ||||
for(Num_Iteration = 1; Num_Iteration <= NbrMaxIteration; Num_Iteration++) { | ||||
Flag_IterativeLoopN = 1; | Flag_IterativeLoopN = 1; | |||
if(Message::GetOnelabAction() == "stop" || Message::GetErrorCount()) break; | if(Message::GetOnelabAction() == "stop" || Message::GetErrorCount()) break; | |||
Current.Iteration = (double)Num_Iteration; | Current.Iteration = (double)Num_Iteration; | |||
Get_ValueOfExpressionByIndex(RelaxationFactorIndex, NULL, 0., 0., 0., &Value | Get_ValueOfExpressionByIndex(RelaxationFactorIndex, NULL, 0., 0., 0., | |||
); | &Value); | |||
Current.RelaxationFactor = Value.Val[0]; | Current.RelaxationFactor = Value.Val[0]; | |||
// Store the current solutions in xPrevious_L | // Store the current solutions in xPrevious_L | |||
for(int i = 0; i < List_Nbr(ILsystems_L); i++){ | for(int i = 0; i < List_Nbr(ILsystems_L); i++) { | |||
List_Read(ILsystems_L, i, &ILsystem); | List_Read(ILsystems_L, i, &ILsystem); | |||
DofData_P = DofData_P0 + ILsystem.SystemIndex; | DofData_P = DofData_P0 + ILsystem.SystemIndex; | |||
xPrevious_P = (gVector*)List_Pointer(xPrevious_L, i); | xPrevious_P = (gVector *)List_Pointer(xPrevious_L, i); | |||
LinAlg_CopyVector(&DofData_P->CurrentSolution->x, xPrevious_P); | LinAlg_CopyVector(&DofData_P->CurrentSolution->x, xPrevious_P); | |||
} | } | |||
// Store the current PostOperation results in PostOpSolutionPrevious_L | // Store the current PostOperation results in PostOpSolutionPrevious_L | |||
if (NbrPostOps != List_Nbr(Current.PostOpData_L)) | if(NbrPostOps != List_Nbr(Current.PostOpData_L)) | |||
Message::Error("Current.PostOpData_L list is not up to date"); | Message::Error("Current.PostOpData_L list is not up to date"); | |||
for(int i = 0; i < NbrPostOps; i++){ | for(int i = 0; i < NbrPostOps; i++) { | |||
PostOpSolutions_P = (struct PostOpSolutions*) | PostOpSolutions_P = | |||
List_Pointer(Current.PostOpData_L, i); | (struct PostOpSolutions *)List_Pointer(Current.PostOpData_L, i); | |||
NbrSolutions = List_Nbr(PostOpSolutions_P->Solutions_L); | NbrSolutions = List_Nbr(PostOpSolutions_P->Solutions_L); | |||
if (!NbrSolutions) | if(!NbrSolutions) | |||
Message::Error("No initial result for PostOperation %s", | Message::Error("No initial result for PostOperation %s", | |||
PostOpSolutions_P->PostOperation_P->Name); | PostOpSolutions_P->PostOperation_P->Name); | |||
Solution_P = (struct Solution*)List_Pointer(PostOpSolutions_P->Solutions_L | Solution_P = (struct Solution *)List_Pointer( | |||
, | PostOpSolutions_P->Solutions_L, NbrSolutions - 1); | |||
NbrSolutions-1); | PostOpResultPrevious_P = | |||
PostOpResultPrevious_P = (gVector*)List_Pointer(PostOpSolutionPrevious_L, | (gVector *)List_Pointer(PostOpSolutionPrevious_L, i); | |||
i); | ||||
LinAlg_AssembleVector(&Solution_P->x); | LinAlg_AssembleVector(&Solution_P->x); | |||
LinAlg_CopyVector(&Solution_P->x, PostOpResultPrevious_P); | LinAlg_CopyVector(&Solution_P->x, PostOpResultPrevious_P); | |||
} | } | |||
Message::Info("IterativeLoopN: Non linear iteration %d (Relaxation = %g)", | Message::Info("IterativeLoopN: Non linear iteration %d (Relaxation = %g)", | |||
(int)Current.Iteration, Current.RelaxationFactor) ; | (int)Current.Iteration, Current.RelaxationFactor); | |||
//NB: SolveJac OR SolveJacAdapt are called here | // NB: SolveJac OR SolveJacAdapt are called here | |||
Treatment_Operation(Resolution_P, Operation_P->Case.IterativeLoop.Operation, | Treatment_Operation(Resolution_P, Operation_P->Case.IterativeLoop.Operation, | |||
DofData_P0, GeoData_P0, Resolution2_P, DofData2_P0) ; | DofData_P0, GeoData_P0, Resolution2_P, DofData2_P0); | |||
if (Current.RelaxFac==0) | if(Current.RelaxFac == 0) | |||
// SolveJacAdapt has not been called | // SolveJacAdapt has not been called | |||
// ==> Copy the default RelaxationFactor in RelaxFac | // ==> Copy the default RelaxationFactor in RelaxFac | |||
Current.RelaxFac = Current.RelaxationFactor ; // +++ | Current.RelaxFac = Current.RelaxationFactor; // +++ | |||
if(*Flag_Break) { | if(*Flag_Break) { | |||
*Flag_Break = 0; | *Flag_Break = 0; | |||
Message::Info("Flag Break detected. Aborting IterativeLoop"); | Message::Info("Flag Break detected. Aborting IterativeLoop"); | |||
break; | break; | |||
} | } | |||
else if (Message::GetLastPETScError()) { | else if(Message::GetLastPETScError()) { | |||
Message::Warning("No valid solution found (PETSc-Error: %d)! " | Message::Warning("No valid solution found (PETSc-Error: %d)! " | |||
"Aborting IterativeLoopN", Message::GetLastPETScError()); | "Aborting IterativeLoopN", | |||
Message::GetLastPETScError()); | ||||
break; | break; | |||
} | } | |||
else if (NbrPostOps) // Execute the PostOperations if necessary | else if(NbrPostOps) // Execute the PostOperations if necessary | |||
Operation_PostOperation(Resolution_P, DofData_P0, GeoData_P0, LEPostOpName | Operation_PostOperation(Resolution_P, DofData_P0, GeoData_P0, | |||
s_L); | LEPostOpNames_L); | |||
// Check if converged | // Check if converged | |||
MaxErrorRatio = CalcMaxErrorRatio(Resolution_P,DofData_P0, ILsystems_L, LEPo | MaxErrorRatio = | |||
stOp_L, | CalcMaxErrorRatio(Resolution_P, DofData_P0, ILsystems_L, LEPostOp_L, | |||
xPrevious_L, PostOpSolutionPrevious_L); | xPrevious_L, PostOpSolutionPrevious_L); | |||
if (MaxErrorRatio != MaxErrorRatio) { // If ErrorRatio = NaN => There was no | if(MaxErrorRatio != | |||
valid solution! | MaxErrorRatio) { // If ErrorRatio = NaN => There was no valid solution! | |||
Flag_IterativeLoopConverged = 0; | Flag_IterativeLoopConverged = 0; | |||
break; | break; | |||
} | } | |||
Message::Info("IterativeLoopN: Largest error ratio: %.3g (after %d iteratio | Message::Info( | |||
n%s)", | "IterativeLoopN: Largest error ratio: %.3g (after %d iteration%s)", | |||
MaxErrorRatio, (int)Current.Iteration, | MaxErrorRatio, (int)Current.Iteration, | |||
((int)Current.Iteration == 1) ? "" : "s"); | ((int)Current.Iteration == 1) ? "" : "s"); | |||
if(Message::GetProgressMeterStep() > 0 && Message::GetProgressMeterStep() < | if(Message::GetProgressMeterStep() > 0 && | |||
100) | Message::GetProgressMeterStep() < 100) | |||
Message::AddOnelabNumberChoice(Message::GetOnelabClientName() + | Message::AddOnelabNumberChoice(Message::GetOnelabClientName() + | |||
"/IterativeLoop/ILmaxErrorRatio", | "/IterativeLoop/ILmaxErrorRatio", | |||
std::vector<double>(1, MaxErrorRatio)); | std::vector<double>(1, MaxErrorRatio)); | |||
//NB: MaxErrorRatio is what is used for IterativeLoopN stop criterion | // NB: MaxErrorRatio is what is used for IterativeLoopN stop criterion | |||
if (MaxErrorRatio < 1.) { | if(MaxErrorRatio < 1.) { | |||
Message::Info(3, "IterativeLoopN converged (%d iterations, error ratio %g) | Message::Info(3, | |||
", | "IterativeLoopN converged (%d iterations, error ratio %g)", | |||
(int)Current.Iteration, MaxErrorRatio); | (int)Current.Iteration, MaxErrorRatio); | |||
break; | break; | |||
} | } | |||
} | } | |||
if (Num_Iteration > NbrMaxIteration) { | if(Num_Iteration > NbrMaxIteration) { | |||
Num_Iteration = NbrMaxIteration; | Num_Iteration = NbrMaxIteration; | |||
Flag_IterativeLoopConverged = 0; | Flag_IterativeLoopConverged = 0; | |||
//Message::Info(3, "IterativeLoopN did NOT converge (%d iterations, error ra | Message::Warning( | |||
tio %g)", //kj+++ (warning is better) | "IterativeLoopN did NOT converge (%d iterations, error ratio %g)", | |||
Message::Warning("IterativeLoopN did NOT converge (%d iterations, error rati | (int)Current.Iteration, MaxErrorRatio); | |||
o %g)", | ||||
(int)Current.Iteration, MaxErrorRatio); | ||||
} | } | |||
Current.Iteration = Save_Iteration ; | Current.Iteration = Save_Iteration; | |||
Flag_IterativeLoopN = 0; | Flag_IterativeLoopN = 0; | |||
// Finally destroy vectors and delete Lists | // Finally destroy vectors and delete Lists | |||
// ---------------------------------------- | // ---------------------------------------- | |||
for(int i = 0; i < List_Nbr(ILsystems_L); i++) | for(int i = 0; i < List_Nbr(ILsystems_L); i++) | |||
LinAlg_DestroyVector((gVector*)List_Pointer(xPrevious_L, i)); | LinAlg_DestroyVector((gVector *)List_Pointer(xPrevious_L, i)); | |||
List_Delete(xPrevious_L); | List_Delete(xPrevious_L); | |||
ClearLEPostOperation(Resolution_P, DofData_P0, GeoData_P0, LEPostOp_L, | ClearLEPostOperation(Resolution_P, DofData_P0, GeoData_P0, LEPostOp_L, | |||
LEPostOpNames_L, PostOpSolutionPrevious_L, false); | LEPostOpNames_L, PostOpSolutionPrevious_L, false); | |||
Current.PostOpData_L = SavePostOpData_L; | Current.PostOpData_L = SavePostOpData_L; | |||
Current.PostOpDataIndex = SavePostOpDataIndex; | Current.PostOpDataIndex = SavePostOpDataIndex; | |||
} | } | |||
End of changes. 49 change blocks. | ||||
177 lines changed or deleted | 158 lines changed or added |