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

Commit 815ffe0

Browse files
ptaeuberOpenModelica-Hudson
authored andcommitted
Make KINSOL compatible with adaptive homotopy
This workaround sets -homotopyOnFirstTry, so trying without homotopy first is not possible (for kinsol with adaptive homotopy). Belonging to [master]: - #2185 - OpenModelica/OpenModelica-testsuite#851
1 parent 6b6a486 commit 815ffe0

File tree

2 files changed

+45
-17
lines changed

2 files changed

+45
-17
lines changed

SimulationRuntime/c/simulation/solver/initialization/initialization.c

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,11 @@ static int symbolic_initialization(DATA *data, threadData_t *threadData)
189189
int homotopySupport = 0;
190190
int solveWithGlobalHomotopy;
191191
int adaptiveGlobal;
192+
int kinsol = 0;
193+
194+
#if !defined(OMC_MINIMAL_RUNTIME)
195+
kinsol = (data->simulationInfo->nlsMethod == NLS_KINSOL);
196+
#endif
192197

193198
#if !defined(OMC_NUM_NONLINEAR_SYSTEMS) || OMC_NUM_NONLINEAR_SYSTEMS>0
194199
for(i=0; i<mData->nNonLinearSystems; i++) {
@@ -227,12 +232,16 @@ static int symbolic_initialization(DATA *data, threadData_t *threadData)
227232
#ifndef OMC_EMCC
228233
MMC_TRY_INTERNAL(simulationJumpBuffer)
229234
#endif
230-
if (adaptiveGlobal)
231-
data->callback->useHomotopy = 1;
232-
data->simulationInfo->lambda = 1.0;
233-
infoStreamPrint(LOG_INIT, 0, "Try to solve the initialization problem without homotopy first.");
234-
data->callback->functionInitialEquations(data, threadData);
235-
solveWithGlobalHomotopy = 0;
235+
if (adaptiveGlobal && kinsol) {
236+
infoStreamPrint(LOG_INIT, 0, "Automatically set -homotopyOnFirstTry, because trying without homotopy first is not supported for the adaptive global approach in combination with KINSOL.");
237+
} else {
238+
if (adaptiveGlobal)
239+
data->callback->useHomotopy = 1;
240+
data->simulationInfo->lambda = 1.0;
241+
infoStreamPrint(LOG_INIT, 0, "Try to solve the initialization problem without homotopy first.");
242+
data->callback->functionInitialEquations(data, threadData);
243+
solveWithGlobalHomotopy = 0;
244+
}
236245

237246
/* catch */
238247
#ifndef OMC_EMCC
@@ -241,7 +250,8 @@ static int symbolic_initialization(DATA *data, threadData_t *threadData)
241250
if (adaptiveGlobal)
242251
data->callback->useHomotopy = 2;
243252
if(solveWithGlobalHomotopy) {
244-
warningStreamPrint(LOG_ASSERT, 0, "Failed to solve the initialization problem without homotopy method. If homotopy is available the homotopy method is used now.");
253+
if (!kinsol)
254+
warningStreamPrint(LOG_ASSERT, 0, "Failed to solve the initialization problem without homotopy method. If homotopy is available the homotopy method is used now.");
245255
omc_flag[FLAG_HOMOTOPY_ON_FIRST_TRY] = 1;
246256
setAllParamsToStart(data);
247257
setAllVarsToStart(data);

SimulationRuntime/c/simulation/solver/nonlinearSystem.c

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -448,10 +448,10 @@ int initializeNonlinearSystems(DATA *data, threadData_t *threadData)
448448
case NLS_KINSOL:
449449
solverData = (struct dataSolver*) malloc(sizeof(struct dataSolver));
450450
if (nonlinsys[i].homotopySupport && (data->callback->useHomotopy == 2 || data->callback->useHomotopy == 3)) {
451+
// Try without homotopy not supported for kinsol
451452
// nlsKinsolAllocate(size-1, &nonlinsys[i], data->simulationInfo->nlsLinearSolver);
452453
// solverData->ordinaryData = nonlinsys[i].solverData;
453-
// allocateHomotopyData(size-1, &(solverData->initHomotopyData));
454-
throwStreamPrint(threadData, "kinsol solver not compatible with adaptive homotopy approaches");
454+
allocateHomotopyData(size-1, &(solverData->initHomotopyData));
455455
} else {
456456
nlsKinsolAllocate(size, &nonlinsys[i], data->simulationInfo->nlsLinearSolver);
457457
solverData->ordinaryData = nonlinsys[i].solverData;
@@ -571,9 +571,10 @@ int freeNonlinearSystems(DATA *data, threadData_t *threadData)
571571
free(nonlinsys[i].solverData);
572572
break;
573573
case NLS_KINSOL:
574-
nlsKinsolFree(&((struct dataSolver*) nonlinsys[i].solverData)->ordinaryData);
575574
if (nonlinsys[i].homotopySupport && (data->callback->useHomotopy == 2 || data->callback->useHomotopy == 3)) {
576575
freeHomotopyData(&((struct dataSolver*) nonlinsys[i].solverData)->initHomotopyData);
576+
} else {
577+
nlsKinsolFree(&((struct dataSolver*) nonlinsys[i].solverData)->ordinaryData);
577578
}
578579
free(nonlinsys[i].solverData);
579580
break;
@@ -890,11 +891,17 @@ int solve_nonlinear_system(DATA *data, threadData_t *threadData, int sysNumber)
890891
int solveWithHomotopySolver = 0;
891892
int homotopyDeactivated = 0;
892893
int j;
894+
int nlsLs;
895+
int kinsol = 0;
893896
struct dataSolver *solverData;
894897
struct dataMixedSolver *mixedSolverData;
895898
char buffer[4096];
896899
FILE *pFile = NULL;
897900

901+
#if !defined(OMC_MINIMAL_RUNTIME)
902+
kinsol = (data->simulationInfo->nlsMethod == NLS_KINSOL);
903+
#endif
904+
898905
data->simulationInfo->currentNonlinearSystemIndex = sysNumber;
899906

900907
/* enable to avoid division by zero */
@@ -951,12 +958,16 @@ int solve_nonlinear_system(DATA *data, threadData_t *threadData, int sysNumber)
951958
/* If homotopy is deactivated in this place or flag homotopyOnFirstTry is not set,
952959
solve the system with the selected solver */
953960
if (homotopyDeactivated || !omc_flag[FLAG_HOMOTOPY_ON_FIRST_TRY]) {
954-
if (!homotopyDeactivated && !omc_flag[FLAG_HOMOTOPY_ON_FIRST_TRY])
955-
infoStreamPrint(LOG_INIT, 0, "Try to solve nonlinear initial system %d without homotopy first.", sysNumber);
961+
if (solveWithHomotopySolver && kinsol) {
962+
infoStreamPrint(LOG_INIT, 0, "Automatically set -homotopyOnFirstTry, because trying without homotopy first is not supported for the local global approach in combination with KINSOL.");
963+
} else {
964+
if (!homotopyDeactivated && !omc_flag[FLAG_HOMOTOPY_ON_FIRST_TRY])
965+
infoStreamPrint(LOG_INIT, 0, "Try to solve nonlinear initial system %d without homotopy first.", sysNumber);
956966

957-
data->simulationInfo->lambda = 1.0;
958-
/* SOLVE! */
959-
nonlinsys->solved = solveNLS(data, threadData, sysNumber);
967+
data->simulationInfo->lambda = 1.0;
968+
/* SOLVE! */
969+
nonlinsys->solved = solveNLS(data, threadData, sysNumber);
970+
}
960971
}
961972

962973
/* The following cases are only valid for initial systems with homotopy */
@@ -965,7 +976,7 @@ int solve_nonlinear_system(DATA *data, threadData_t *threadData, int sysNumber)
965976
/* If the adaptive local/global homotopy approach is activated and trying without homotopy failed or is not wanted,
966977
use the HOMOTOPY SOLVER */
967978
if (solveWithHomotopySolver && !nonlinsys->solved) {
968-
if (!omc_flag[FLAG_HOMOTOPY_ON_FIRST_TRY])
979+
if (!omc_flag[FLAG_HOMOTOPY_ON_FIRST_TRY] && !kinsol)
969980
warningStreamPrint(LOG_ASSERT, 0, "Failed to solve the initial system %d without homotopy method.", sysNumber);
970981
data->simulationInfo->lambda = 0.0;
971982
if (data->callback->useHomotopy == 3) {
@@ -974,7 +985,14 @@ int solve_nonlinear_system(DATA *data, threadData_t *threadData, int sysNumber)
974985
infoStreamPrint(LOG_INIT, 1, "homotopy process\n---------------------------");
975986
infoStreamPrint(LOG_INIT, 0, "solve lambda0-system");
976987
nonlinsys->homotopySupport = 0;
977-
nonlinsys->solved = solveNLS(data, threadData, sysNumber);
988+
if (!kinsol) {
989+
nonlinsys->solved = solveNLS(data, threadData, sysNumber);
990+
} else {
991+
nlsLs = data->simulationInfo->nlsLinearSolver;
992+
data->simulationInfo->nlsLinearSolver = NLS_LS_LAPACK;
993+
nonlinsys->solved = solveWithInitHomotopy(data, threadData, sysNumber);
994+
data->simulationInfo->nlsLinearSolver = nlsLs;
995+
}
978996
nonlinsys->homotopySupport = 1;
979997
infoStreamPrint(LOG_INIT, 0, "solving lambda0-system done with%s success\n---------------------------", nonlinsys->solved ? "" : " no");
980998
messageClose(LOG_INIT);

0 commit comments

Comments
 (0)