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

Commit 0e6d68f

Browse files
Willi BraunOpenModelica-Hudson
authored andcommitted
nonlinear homotopy solver with lapack
- added -nls-LS option with options [lapack|totalpivot] - make lapack as default, since it's faster - in the next step klu will added
1 parent 08ea75e commit 0e6d68f

5 files changed

Lines changed: 144 additions & 5 deletions

File tree

SimulationRuntime/c/simulation/simulation_runtime.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,28 @@ static int getNewtonStrategy()
301301
return NEWTON_NONE;
302302
}
303303

304+
static int getNlsLSSolver()
305+
{
306+
int i;
307+
const char *cflags = omc_flagValue[FLAG_NLS_LS];
308+
const string *method = cflags ? new string(cflags) : NULL;
309+
310+
if(!method)
311+
return NLS_LS_LAPACK; /* default method */
312+
313+
for(i=1; i<NLS_LS_MAX; ++i)
314+
if(*method == NLS_LS_METHOD[i])
315+
return i;
316+
317+
warningStreamPrint(LOG_STDOUT, 1, "unrecognized option -nls=%s, current options are:", method->c_str());
318+
for(i=1; i<NLS_LS_MAX; ++i)
319+
warningStreamPrint(LOG_STDOUT, 0, "%-18s [%s]", NLS_LS_METHOD[i], NLS_LS_METHOD_DESC[i]);
320+
messageClose(LOG_STDOUT);
321+
throwStreamPrint(NULL,"see last warning");
322+
323+
return NLS_LS_UNKNOWN;
324+
}
325+
304326
static double getFlagReal(enum _FLAG flag, double res)
305327
{
306328
const char *flagStr = omc_flagValue[flag];
@@ -792,6 +814,7 @@ int initRuntimeAndSimulation(int argc, char**argv, DATA *data, threadData_t *thr
792814
data->simulationInfo->lssMethod = getlinearSparseSolverMethod();
793815
data->simulationInfo->newtonStrategy = getNewtonStrategy();
794816
data->simulationInfo->nlsCsvInfomation = omc_flag[FLAG_NLS_INFO];
817+
data->simulationInfo->nlsLinearSolver = getNlsLSSolver();
795818

796819
if(omc_flag[FLAG_LSS_MAX_DENSITY]) {
797820
linearSparseSolverMaxDensity = atof(omc_flagValue[FLAG_LSS_MAX_DENSITY]);

SimulationRuntime/c/simulation/solver/nonlinearSolverHomotopy.c

Lines changed: 85 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,16 @@
4949
#include "nonlinearSolverHomotopy.h"
5050
#include "nonlinearSolverHybrd.h"
5151

52+
#ifdef __cplusplus
53+
extern "C" {
54+
#endif
55+
56+
extern int dgesv_(int *n, int *nrhs, doublereal *a, int *lda, int *ipiv, doublereal *b, int *ldb, int *info);
57+
58+
#ifdef __cplusplus
59+
}
60+
#endif
61+
5262
/*! \typedef DATA_HOMOTOPY
5363
* define memory structure for nonlinear system solver
5464
* \author bbachmann
@@ -953,6 +963,7 @@ static int wrapper_fvec_homotopy_fixpoint_der(DATA_HOMOTOPY* solverData, double*
953963
return 0;
954964
}
955965

966+
956967
/*! \fn getIndicesOfPivotElement for calculating pivot element
957968
*
958969
* \author bbachmann
@@ -976,6 +987,7 @@ static int wrapper_fvec_homotopy_fixpoint_der(DATA_HOMOTOPY* solverData, double*
976987
}
977988
}
978989

990+
979991
/*! \fn solveSystemWithTotalPivotSearch for solution of overdetermined linear system
980992
* used for the homotopy solver, for calculating the direction
981993
* used for the newton solver, for calculating the Newton step
@@ -994,6 +1006,7 @@ int solveSystemWithTotalPivotSearch(int n, double* x, double* A, int* indRow, in
9941006
double *res;
9951007

9961008
debugMatrixDouble(LOG_NLS_JAC,"Linear System Matrix [Jac res]:",A, n, m);
1009+
debugVectorDouble(LOG_NLS_JAC,"vector b:", A+n*n, n);
9971010

9981011
/* assume full rank of matrix [n x (n+1)] */
9991012
*rank = n;
@@ -1077,20 +1090,85 @@ int solveSystemWithTotalPivotSearch(int n, double* x, double* A, int* indRow, in
10771090
*pos=indCol[n];
10781091
}
10791092

1093+
return 0;
1094+
}
1095+
1096+
1097+
/*! \fn linearSolverWrapper
1098+
*/
1099+
int linearSolverWrapper(int n, double* x, double* A, int* indRow, int* indCol, int *pos, int *rank, int method)
1100+
{
1101+
/* First try to use lapack and if it fails then
1102+
* use solveSystemWithTotalPivotSearch */
1103+
int returnValue = -1;
1104+
int solverinfo;
1105+
int nrhs = 1;
1106+
int lda = n;
1107+
1108+
debugMatrixDouble(LOG_NLS_JAC,"Linear System Matrix [Jac res]:", A, n, n+1);
1109+
debugVectorDouble(LOG_NLS_JAC,"vector b:", x, n);
1110+
1111+
switch(method){
1112+
case (1): /* NLS_LS_TOTALPIVOT */
1113+
1114+
solverinfo = solveSystemWithTotalPivotSearch(n, x, A, indRow, indCol, pos, rank);
1115+
/* in case of failing */
1116+
if (solverinfo != 0)
1117+
{
1118+
/* debug information */
1119+
debugString(LOG_NLS_V, "Linear total pivot solver failed!!!");
1120+
debugString(LOG_NLS_V, "******************************************************");
1121+
}
1122+
else
1123+
{
1124+
returnValue = 0;
1125+
}
1126+
break;
1127+
case 2: /* NLS_LS_LAPACK */
1128+
/* Solve system with lapack */
1129+
dgesv_((int*) &n,
1130+
(int*) &nrhs,
1131+
A,
1132+
(int*) &lda,
1133+
indRow,
1134+
x,
1135+
(int*) &n,
1136+
&solverinfo);
1137+
1138+
debugMatrixDouble(LOG_NLS_JAC,"Linear system matrix [Jac res] after decomposition:", A, n, n+1);
1139+
/* in case of failing */
1140+
if (solverinfo != 0)
1141+
{
1142+
/* debug information */
1143+
debugString(LOG_NLS_V, "Linear lapack solver failed!!!");
1144+
debugString(LOG_NLS_V, "******************************************************");
1145+
}
1146+
else
1147+
{
1148+
vecScalarMult(n, x, -1, x);
1149+
returnValue = 0;
1150+
}
1151+
break;
1152+
default:
1153+
warningStreamPrint(LOG_STDOUT, 0, "Non-Linear solver try to run with a unknown linear solver.");
1154+
}
1155+
10801156
/* Debugging error of linear system */
10811157
if(ACTIVE_STREAM(LOG_NLS_JAC))
10821158
{
1083-
res = (double*) calloc(n,sizeof(double));
1084-
debugVectorDouble(LOG_NLS_JAC,"solution:", x, m);
1085-
matVecMult(n, m, A, x, res);
1159+
double* res = (double*) calloc(n,sizeof(double));
1160+
debugVectorDouble(LOG_NLS_JAC,"solution:", x, n);
1161+
matVecMult(n, n, A, x, res);
10861162
debugVectorDouble(LOG_NLS_JAC,"test solution:", res, n);
10871163
debugDouble(LOG_NLS_JAC,"error of linear system = ", vec2Norm(n, res));
10881164
free(res);
10891165
messageClose(LOG_NLS_JAC);
10901166
}
10911167

1092-
return 0;
1168+
return returnValue;
10931169
}
1170+
1171+
10941172
/*! \fn solve system with damped Newton-Raphson
10951173
*
10961174
* \author bbachmann
@@ -1114,6 +1192,7 @@ static int newtonAlgorithm(DATA_HOMOTOPY* solverData, double* x)
11141192
int assert = 1;
11151193
threadData_t *threadData = solverData->threadData;
11161194
NONLINEAR_SYSTEM_DATA* nonlinsys = &(solverData->data->simulationInfo->nonlinearSystemData[solverData->data->simulationInfo->currentNonlinearSystemIndex]);
1195+
int linearSolverMethod = solverData->data->simulationInfo->nlsLinearSolver;
11171196

11181197
/* debug information */
11191198
debugString(LOG_NLS_V, "******************************************************");
@@ -1135,7 +1214,7 @@ static int newtonAlgorithm(DATA_HOMOTOPY* solverData, double* x)
11351214
debugInt(LOG_NLS_V, "Iteration:", numberOfIterations);
11361215

11371216
/* solve jacobian and function value (both stored in hJac, last column is fvec), side effects: jacobian matrix is changed */
1138-
if ((numberOfIterations>1) && (solveSystemWithTotalPivotSearch(solverData->n, solverData->dy0, solverData->fJac, solverData->indRow, solverData->indCol, &pos, &rank) != 0))
1217+
if ((numberOfIterations>1) && linearSolverWrapper(solverData->n, solverData->dy0, solverData->fJac, solverData->indRow, solverData->indCol, &pos, &rank, linearSolverMethod) != 0)
11391218
{
11401219
/* report solver abortion */
11411220
solverData->info=-1;
@@ -1392,6 +1471,7 @@ static int newtonAlgorithm(DATA_HOMOTOPY* solverData, double* x)
13921471
matVecMultAbsBB(solverData->n, solverData->fJac, solverData->ones, solverData->resScaling);
13931472
debugVectorDouble(LOG_NLS_JAC, "residuum scaling:", solverData->resScaling, solverData->n);
13941473
scaleMatrixRows(solverData->n, solverData->m, solverData->fJac);
1474+
vecCopy(n, solverData->fJac + n*n, solverData->dy0);
13951475
}
13961476
return 0;
13971477
}

SimulationRuntime/c/simulation_data.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,6 +547,7 @@ typedef struct SIMULATION_INFO
547547
int nlsMethod; /* nonlinear solver */
548548
int newtonStrategy; /* newton damping strategy solver */
549549
int nlsCsvInfomation; /* = 1 csv files with detailed nonlinear solver process are generated */
550+
int nlsLinearSolver; /* nls linear solver setting =1 totalpivot, =2 lapack, =3=klu */
550551

551552
/* current context evaluation, set by dassl and used for extrapolation
552553
* of next non-linear guess */

SimulationRuntime/c/util/simulation_options.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ const char *FLAG_NAME[FLAG_MAX+1] = {
8383
/* FLAG_NEWTON_STRATEGY */ "newton",
8484
/* FLAG_NLS */ "nls",
8585
/* FLAG_NLS_INFO */ "nlsInfo",
86+
/* FLAG_NLS_LS */ "nlsLS",
8687
/* FLAG_NOEMIT */ "noemit",
8788
/* FLAG_NOEQUIDISTANT_GRID */ "noEquidistantTimeGrid",
8889
/* FLAG_NOEQUIDISTANT_OUT_FREQ*/ "noEquidistantOutputFrequency",
@@ -161,6 +162,7 @@ const char *FLAG_DESC[FLAG_MAX+1] = {
161162
/* FLAG_NEWTON_STRATEGY */ "value specifies the damping strategy for the newton solver",
162163
/* FLAG_NLS */ "value specifies the nonlinear solver",
163164
/* FLAG_NLS_INFO */ "outputs detailed information about solving process of non-linear systems into csv files.",
165+
/* FLAG_NLS_LS */ "value specifies the linear solver used by the non-linear solver\m nlsLS=[totalpivot|lapack|klu]",
164166
/* FLAG_NOEMIT */ "do not emit any results to the result file",
165167
/* FLAG_NOEQUIDISTANT_GRID */ "stores results not in equidistant time grid as given by stepSize or numberOfIntervals, instead the variable step size of dassl is used.",
166168
/* FLAG_NOEQUIDISTANT_OUT_FREQ*/ "value controls the output frequency in noEquidistantTimeGrid mode",
@@ -328,6 +330,8 @@ const char *FLAG_DETAILED_DESC[FLAG_MAX+1] = {
328330
" * mixed",
329331
/* FLAG_NLS_INFO */
330332
" Outputs detailed information about solving process of non-linear systems into csv files.",
333+
/* FLAG_NLS_LS */
334+
"value specifies the linear solver used by the non-linear solver\m nlsLS=[totalpivot|lapack|klu]",
331335
/* FLAG_NOEMIT */
332336
" Do not emit any results to the result file.",
333337
/* FLAG_NOEQUIDISTANT_GRID */
@@ -443,6 +447,7 @@ const int FLAG_TYPE[FLAG_MAX] = {
443447
/* FLAG_NEWTON_STRATEGY */ FLAG_TYPE_OPTION,
444448
/* FLAG_NLS */ FLAG_TYPE_OPTION,
445449
/* FLAG_NLS_INFO */ FLAG_TYPE_FLAG,
450+
/* FLAG_NLS_LS */ FLAG_TYPE_OPTION,
446451
/* FLAG_NOEMIT */ FLAG_TYPE_FLAG,
447452
/* FLAG_NOEQUIDISTANT_GRID*/ FLAG_TYPE_FLAG,
448453
/* FLAG_NOEQUIDISTANT_OUT_FREQ*/ FLAG_TYPE_OPTION,
@@ -676,3 +681,22 @@ const char *IDA_LS_METHOD_DESC[IDA_LS_MAX+1] = {
676681

677682
"IDA_LS_MAX"
678683
};
684+
685+
const char *NLS_LS_METHOD[NLS_LS_MAX+1] = {
686+
"unknown",
687+
688+
"totalpivot",
689+
"lapack",
690+
691+
"NLS_LS_MAX"
692+
};
693+
694+
const char *NLS_LS_METHOD_DESC[NLS_LS_MAX+1] = {
695+
"unknown",
696+
697+
"internal total pivot implementation. Solve in some case even under-determined systems.",
698+
"use external lapack implementation.",
699+
700+
"NLS_LS_MAX"
701+
};
702+

SimulationRuntime/c/util/simulation_options.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ enum _FLAG
9191
FLAG_NEWTON_STRATEGY,
9292
FLAG_NLS,
9393
FLAG_NLS_INFO,
94+
FLAG_NLS_LS,
9495
FLAG_NOEMIT,
9596
FLAG_NOEQUIDISTANT_GRID,
9697
FLAG_NOEQUIDISTANT_OUT_FREQ,
@@ -271,8 +272,18 @@ enum IDA_LS
271272
extern const char *IDA_LS_METHOD[IDA_LS_MAX+1];
272273
extern const char *IDA_LS_METHOD_DESC[IDA_LS_MAX+1];
273274

275+
enum NLS_LS
276+
{
277+
NLS_LS_UNKNOWN = 0,
278+
279+
NLS_LS_TOTALPIVOT,
280+
NLS_LS_LAPACK,
274281

282+
NLS_LS_MAX
283+
};
275284

285+
extern const char *NLS_LS_METHOD[NLS_LS_MAX+1];
286+
extern const char *NLS_LS_METHOD_DESC[NLS_LS_MAX+1];
276287

277288

278289
#if defined(__cplusplus)

0 commit comments

Comments
 (0)