Skip to content
This repository was archived by the owner on May 18, 2019. It is now read-only.

Commit dc5dc2b

Browse files
Willi BraunOpenModelica-Hudson
authored andcommitted
fixes issues from ticket:4395
- added runtime option newtonMaxStepFactor, which adjustes the maximum step size of a newton step in kinsol. - used as: mxnewtstep = maxStepFactor * norm2(xScaling) - added a much better initial value for the maximum step size
1 parent b67fdd1 commit dc5dc2b

File tree

6 files changed

+34
-1
lines changed

6 files changed

+34
-1
lines changed

SimulationRuntime/c/simulation/simulation_runtime.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -862,6 +862,11 @@ int initRuntimeAndSimulation(int argc, char**argv, DATA *data, threadData_t *thr
862862
infoStreamPrint(LOG_STDOUT, 0, "Tolerance for accepting accuracy in Newton solver changed to %g", newtonFTol);
863863
}
864864

865+
if(omc_flag[FLAG_NEWTON_MAX_STEP_FACTOR]) {
866+
maxStepFactor = atof(omc_flagValue[FLAG_NEWTON_MAX_STEP_FACTOR]);
867+
infoStreamPrint(LOG_STDOUT, 0, "Maximum step size factor for a Newton step changed to %g", newtonFTol);
868+
}
869+
865870
if(omc_flag[FLAG_STEADY_STATE_TOL]) {
866871
steadyStateTol = atof(omc_flagValue[FLAG_STEADY_STATE_TOL]);
867872
infoStreamPrint(LOG_STDOUT, 0, "Tolerance for steady state detection changed to %g", steadyStateTol);

SimulationRuntime/c/simulation/solver/kinsolSolver.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ typedef struct NLS_KINSOL_DATA
102102
/* ### tolerances ### */
103103
double fnormtol; /* function tolerance */
104104
double scsteptol; /* step tolerance */
105+
double maxstepfactor; /* maximum newton step factor mxnewtstep = maxstepfactor * norm2(xScaling) */
105106

106107
/* ### work arrays ### */
107108
N_Vector initialGuess;
@@ -187,6 +188,8 @@ int nlsKinsolAllocate(int size, NONLINEAR_SYSTEM_DATA *nlsData, int linearSolver
187188
kinsolData->fnormtol = sqrt(newtonFTol); /* function tolerance */
188189
kinsolData->scsteptol = sqrt(newtonXTol); /* step tolerance */
189190

191+
kinsolData->maxstepfactor = maxStepFactor; /* step tolerance */
192+
190193
kinsolData->initialGuess = N_VNew_Serial(size);
191194
kinsolData->xScale = N_VNew_Serial(size);
192195
kinsolData->fScale = N_VNew_Serial(size);
@@ -652,6 +655,15 @@ void nlsKinsolInfoPrint(const char *module, const char *function, char *msg, voi
652655
}
653656
}
654657

658+
static
659+
void nlsKinsolSetMaxNewtonStep(NLS_KINSOL_DATA *kinsolData, double maxstepfactor)
660+
{
661+
/* set maximum step size */
662+
N_VConst(maxstepfactor, kinsolData->fTmp);
663+
KINSetMaxNewtonStep(kinsolData->kinsolMemory, N_VWL2Norm(kinsolData->xScale, kinsolData->fTmp));
664+
665+
}
666+
655667
static
656668
void nlsKinsolResetInitial(DATA* data, NLS_KINSOL_DATA *kinsolData, NONLINEAR_SYSTEM_DATA* nlsData, int mode)
657669
{
@@ -775,6 +787,7 @@ int nlsKinsolConfigPrint(NLS_KINSOL_DATA *kinsolData, NONLINEAR_SYSTEM_DATA *nls
775787
infoStreamPrint(LOG_NLS_V, 0, "KINSOL max iterations %d", 20*kinsolData->size);
776788
infoStreamPrint(LOG_NLS_V, 0, "KINSOL strategy %d", kinsolData->kinsolStrategy);
777789
infoStreamPrint(LOG_NLS_V, 0, "KINSOL current retry %d", kinsolData->retries);
790+
infoStreamPrint(LOG_NLS_V, 0, "KINSOL max step %g", (*(KINMem)kinsolData->kinsolMemory).kin_mxnstepin);
778791

779792
messageClose(LOG_NLS_V);
780793

@@ -805,13 +818,16 @@ int nlsKinsolErrorHandler(int errorCode, DATA *data, NONLINEAR_SYSTEM_DATA *nlsD
805818
break;
806819
/* just retry with new initial guess */
807820
case KIN_MXNEWT_5X_EXCEEDED:
808-
warningStreamPrint(LOG_NLS, 0, "initial guess was too far away from the solution. Try again.\n");
821+
warningStreamPrint(LOG_NLS, 0, "Newton step exceed the maximum step size several times. Try again after increasing maximum step size.\n");
822+
kinsolData->maxstepfactor *= 1e5;
823+
nlsKinsolSetMaxNewtonStep(kinsolData, kinsolData->maxstepfactor);
809824
return 1;
810825
break;
811826
/* just retry without line search */
812827
case KIN_LINESEARCH_NONCONV:
813828
warningStreamPrint(LOG_NLS, 0, "kinsols line search did not convergence. Try without.\n");
814829
kinsolData->kinsolStrategy = KIN_NONE;
830+
kinsolData->retries--;
815831
return 1;
816832
/* maybe happened because of an out-dated factorization, so just retry */
817833
case KIN_LSETUP_FAIL:
@@ -927,6 +943,9 @@ int nlsKinsolSolve(DATA *data, threadData_t *threadData, int sysNumber)
927943
/* set f scaling */
928944
nlsKinsolFScaling(data, kinsolData, nlsData, SCALING_JACOBIAN);
929945

946+
/* set maximum step size */
947+
nlsKinsolSetMaxNewtonStep(kinsolData, kinsolData->maxstepfactor);
948+
930949
/* */
931950
do{
932951
/* dump configuration */

SimulationRuntime/c/simulation/solver/model_help.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ double linearSparseSolverMaxDensity = 0.2;
5555
int linearSparseSolverMinSize = 4001;
5656
double nonlinearSparseSolverMaxDensity = 0.2;
5757
int nonlinearSparseSolverMinSize = 10001;
58+
double maxStepFactor = 1e12;
5859
double newtonXTol = 1e-12;
5960
double newtonFTol = 1e-12;
6061
double steadyStateTol = 1e-3;

SimulationRuntime/c/simulation/solver/model_help.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ extern double nonlinearSparseSolverMaxDensity;
8181
extern int nonlinearSparseSolverMinSize;
8282
extern double newtonXTol;
8383
extern double newtonFTol;
84+
extern double maxStepFactor;
8485
extern double steadyStateTol;
8586
extern const size_t SIZERINGBUFFER;
8687
extern int compiledInDAEMode;

SimulationRuntime/c/util/simulation_options.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ const char *FLAG_NAME[FLAG_MAX+1] = {
8585
/* FLAG_MAX_STEP_SIZE */ "maxStepSize",
8686
/* FLAG_MEASURETIMEPLOTFORMAT */ "measureTimePlotFormat",
8787
/* FLAG_NEWTON_FTOL */ "newtonFTol",
88+
/* FLAG_NEWTON_MAX_STEP_FACTOR */"newtonMaxStepFactor",
8889
/* FLAG_NEWTON_XTOL */ "newtonXTol",
8990
/* FLAG_NEWTON_STRATEGY */ "newton",
9091
/* FLAG_NLS */ "nls",
@@ -174,6 +175,7 @@ const char *FLAG_DESC[FLAG_MAX+1] = {
174175
/* FLAG_MAX_STEP_SIZE */ "value specifies maximum absolute step size for supported solver",
175176
/* FLAG_MEASURETIMEPLOTFORMAT */ "value specifies the output format of the measure time functionality",
176177
/* FLAG_NEWTON_FTOL */ "[double (default 1e-12)] tolerance respecting residuals for updating solution vector in Newton solver",
178+
/* FLAG_NEWTON_MAX_STEP_FACTOR */"[double (default 1e12)] maximum newton step factor mxnewtstep = maxStepFactor * norm2(xScaling). Used currently only by kinsol.",
177179
/* FLAG_NEWTON_XTOL */ "[double (default 1e-12)] tolerance respecting newton correction (delta_x) for updating solution vector in Newton solver",
178180
/* FLAG_NEWTON_STRATEGY */ "value specifies the damping strategy for the newton solver",
179181
/* FLAG_NLS */ "value specifies the nonlinear solver",
@@ -353,6 +355,9 @@ const char *FLAG_DETAILED_DESC[FLAG_MAX+1] = {
353355
" Tolerance respecting residuals for updating solution vector in Newton solver."
354356
" Solution is accepted if the (scaled) 2-norm of the residuals is smaller than the tolerance newtonFTol and the (scaled) newton correction (delta_x) is smaller than the tolerance newtonXTol."
355357
" The value is a Double with default value 1e-12.",
358+
/* FLAG_NEWTON_MAX_STEP_FACTOR */
359+
" Maximum newton step factor mxnewtstep = maxStepFactor * norm2(xScaling). "
360+
" Used currently only by kinsol.",
356361
/* FLAG_NEWTON_XTOL */
357362
" Tolerance respecting newton correction (delta_x) for updating solution vector in Newton solver."
358363
" Solution is accepted if the (scaled) 2-norm of the residuals is smaller than the tolerance newtonFTol and the (scaled) newton correction (delta_x) is smaller than the tolerance newtonXTol."
@@ -496,6 +501,7 @@ const int FLAG_TYPE[FLAG_MAX] = {
496501
/* FLAG_MAX_STEP_SIZE */ FLAG_TYPE_OPTION,
497502
/* FLAG_MEASURETIMEPLOTFORMAT */ FLAG_TYPE_OPTION,
498503
/* FLAG_NEWTON_FTOL */ FLAG_TYPE_OPTION,
504+
/* FLAG_NEWTON_MAX_STEP_FACTOR */FLAG_TYPE_OPTION,
499505
/* FLAG_NEWTON_XTOL */ FLAG_TYPE_OPTION,
500506
/* FLAG_NEWTON_STRATEGY */ FLAG_TYPE_OPTION,
501507
/* FLAG_NLS */ FLAG_TYPE_OPTION,

SimulationRuntime/c/util/simulation_options.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ enum _FLAG
9393
FLAG_MAX_STEP_SIZE,
9494
FLAG_MEASURETIMEPLOTFORMAT,
9595
FLAG_NEWTON_FTOL,
96+
FLAG_NEWTON_MAX_STEP_FACTOR,
9697
FLAG_NEWTON_XTOL,
9798
FLAG_NEWTON_STRATEGY,
9899
FLAG_NLS,

0 commit comments

Comments
 (0)