Skip to content

Commit

Permalink
[DAEmode] Avoid IDA for models without states
Browse files Browse the repository at this point in the history
 - when the model has no states and no residual equations
   the general simulation algorithm with event handling is used.
 - This fixes models like Modelica.Blocks.Examples.RealNetwork1 for
   the daeMode=new.

Belonging to [master]:
  - OpenModelica/OMCompiler#2295
  • Loading branch information
Willi Braun authored and OpenModelica-Hudson committed Mar 20, 2018
1 parent 1769e70 commit 77407e8
Show file tree
Hide file tree
Showing 7 changed files with 124 additions and 12 deletions.
3 changes: 2 additions & 1 deletion SimulationRuntime/c/Makefile.common
Expand Up @@ -75,7 +75,8 @@ RUNTIMESIMSOLVER_HEADERS = ./simulation/solver/delay.h \
./simulation/solver/events.h \
./simulation/solver/synchronous.h \
./simulation/solver/external_input.h\
./simulation/solver/solver_main.h
./simulation/solver/solver_main.h \
./simulation/solver/dae_mode.h

RUNTIMEMETA_HEADERS = ./meta/meta_modelica_builtin_boxptr.h \
./meta/meta_modelica_builtin_boxvar.h \
Expand Down
4 changes: 2 additions & 2 deletions SimulationRuntime/c/Makefile.objs
Expand Up @@ -67,11 +67,11 @@ else
SOLVER_OBJS_MINIMAL=$(SOLVER_OBJS_FMU)
endif
ifeq ($(OMC_MINIMAL_RUNTIME),)
SOLVER_OBJS=$(SOLVER_OBJS_MINIMAL) kinsolSolver$(OBJ_EXT) linearSolverKlu$(OBJ_EXT) linearSolverLis$(OBJ_EXT) linearSolverUmfpack$(OBJ_EXT) dassl$(OBJ_EXT) radau$(OBJ_EXT) sym_solver_ssc$(OBJ_EXT) nonlinearSolverNewton$(OBJ_EXT) newtonIteration$(OBJ_EXT) ida_solver$(OBJ_EXT) irksco$(OBJ_EXT)
SOLVER_OBJS=$(SOLVER_OBJS_MINIMAL) kinsolSolver$(OBJ_EXT) linearSolverKlu$(OBJ_EXT) linearSolverLis$(OBJ_EXT) linearSolverUmfpack$(OBJ_EXT) dassl$(OBJ_EXT) radau$(OBJ_EXT) sym_solver_ssc$(OBJ_EXT) nonlinearSolverNewton$(OBJ_EXT) newtonIteration$(OBJ_EXT) ida_solver$(OBJ_EXT) irksco$(OBJ_EXT) dae_mode$(OBJ_EXT)
else
SOLVER_OBJS=$(SOLVER_OBJS_MINIMAL)
endif
SOLVER_HFILES = dassl.h delay.h epsilon.h events.h external_input.h fmi_events.h ida_solver.h linearSystem.h mixedSystem.h model_help.h nonlinearSystem.h nonlinearValuesList.h radau.h sym_solver_ssc.h solver_main.h stateset.h
SOLVER_HFILES = dassl.h dae_mode.h delay.h epsilon.h events.h external_input.h fmi_events.h ida_solver.h linearSystem.h mixedSystem.h model_help.h nonlinearSystem.h nonlinearValuesList.h radau.h sym_solver_ssc.h solver_main.h stateset.h

INITIALIZATION_OBJS = initialization$(OBJ_EXT)
INITIALIZATION_HFILES = initialization.h
Expand Down
14 changes: 13 additions & 1 deletion SimulationRuntime/c/simulation/simulation_runtime.cpp
Expand Up @@ -84,6 +84,7 @@
#include "util/rtclock.h"
#include "omc_config.h"
#include "simulation/solver/initialization/initialization.h"
#include "simulation/solver/dae_mode.h"

#ifdef _OMC_QSS_LIB
#include "solver_qss/solver_qss.h"
Expand Down Expand Up @@ -644,8 +645,19 @@ static int callSolver(DATA* simData, threadData_t *threadData, string init_initM
/* if no states are present, then we can
* use euler method, since it does nothing.
*/
if (simData->modelData->nStates < 1 && solverID != S_OPTIMIZATION && solverID != S_SYM_SOLVER && !compiledInDAEMode) {
if ( (simData->modelData->nStates < 1 &&
solverID != S_OPTIMIZATION &&
solverID != S_SYM_SOLVER) ||
(compiledInDAEMode && (simData->simulationInfo->daeModeData->nResidualVars +
simData->simulationInfo->daeModeData->nAlgebraicDAEVars < 1))
)
{
solverID = S_EULER;
if (compiledInDAEMode == 3)
{
simData->callback->functionDAE = evaluateDAEResiduals_wrapperEventUpdate;
simData->callback->function_ZeroCrossingsEquations = simData->simulationInfo->daeModeData->evaluateDAEResiduals;
}
}

if(S_UNKNOWN == solverID) {
Expand Down
54 changes: 54 additions & 0 deletions SimulationRuntime/c/simulation/solver/dae_mode.c
@@ -0,0 +1,54 @@
/*
* This file is part of OpenModelica.
*
* Copyright (c) 1998-2018, Open Source Modelica Consortium (OSMC),
* c/o Linköpings universitet, Department of Computer and Information Science,
* SE-58183 Linköping, Sweden.
*
* All rights reserved.
*
* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THE BSD NEW LICENSE OR THE
* GPL VERSION 3 LICENSE OR THE OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2.
* ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
* RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3,
* ACCORDING TO RECIPIENTS CHOICE.
*
* The OpenModelica software and the OSMC (Open Source Modelica Consortium)
* Public License (OSMC-PL) are obtained from OSMC, either from the above
* address, from the URLs: http://www.openmodelica.org or
* http://www.ida.liu.se/projects/OpenModelica, and in the OpenModelica
* distribution. GNU version 3 is obtained from:
* http://www.gnu.org/copyleft/gpl.html. The New BSD License is obtained from:
* http://www.opensource.org/licenses/BSD-3-Clause.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, EXCEPT AS
* EXPRESSLY SET FORTH IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE
* CONDITIONS OF OSMC-PL.
*
*/

#include "dae_mode.h"

#ifdef __cplusplus
extern "C" {
#endif

/*! \fn void evaluateDAEResiduals_wrapperEventUpdate
*
* wrapper function of the main evaluation function for DAE mode
*/
int evaluateDAEResiduals_wrapperEventUpdate(DATA* data, threadData_t* threadData)
{
int retVal;

data->simulationInfo->discreteCall = 1;
retVal = data->simulationInfo->daeModeData->evaluateDAEResiduals(data, threadData);
data->simulationInfo->discreteCall = 0;

return retVal;
}

#ifdef __cplusplus
}
#endif
46 changes: 46 additions & 0 deletions SimulationRuntime/c/simulation/solver/dae_mode.h
@@ -0,0 +1,46 @@
/*
* This file is part of OpenModelica.
*
* Copyright (c) 1998-2018, Open Source Modelica Consortium (OSMC),
* c/o Linköpings universitet, Department of Computer and Information Science,
* SE-58183 Linköping, Sweden.
*
* All rights reserved.
*
* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THE BSD NEW LICENSE OR THE
* GPL VERSION 3 LICENSE OR THE OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2.
* ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
* RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3,
* ACCORDING TO RECIPIENTS CHOICE.
*
* The OpenModelica software and the OSMC (Open Source Modelica Consortium)
* Public License (OSMC-PL) are obtained from OSMC, either from the above
* address, from the URLs: http://www.openmodelica.org or
* http://www.ida.liu.se/projects/OpenModelica, and in the OpenModelica
* distribution. GNU version 3 is obtained from:
* http://www.gnu.org/copyleft/gpl.html. The New BSD License is obtained from:
* http://www.opensource.org/licenses/BSD-3-Clause.
*
* This program is distributed WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, EXCEPT AS
* EXPRESSLY SET FORTH IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE
* CONDITIONS OF OSMC-PL.
*
*/

#ifndef DAE_MODE_H
#define DAE_MODE_H

#include "simulation_data.h"

#ifdef __cplusplus
extern "C" {
#endif

int evaluateDAEResiduals_wrapperEventUpdate(DATA* data, threadData_t* threadData);

#ifdef __cplusplus
}
#endif

#endif
11 changes: 3 additions & 8 deletions SimulationRuntime/c/simulation/solver/ida_solver.c
Expand Up @@ -52,6 +52,7 @@
#include "simulation/solver/omc_math.h"
#include "simulation/solver/ida_solver.h"
#include "simulation/solver/dassl.h"
#include "simulation/solver/dae_mode.h"

#ifdef WITH_SUNDIALS

Expand Down Expand Up @@ -703,17 +704,14 @@ ida_event_update(DATA* data, threadData_t *threadData)
if (initializedSolver){

data->simulationInfo->needToIterate = 0;
/* get new values from data -> TODO: update all discrete */
data->simulationInfo->discreteCall = 1;

memcpy(idaData->states, data->localData[0]->realVars, sizeof(double)*data->modelData->nStates);
data->simulationInfo->daeModeData->getAlgebraicDAEVars(data, threadData, idaData->states + data->modelData->nStates);
memcpy(idaData->statesDer, data->localData[0]->realVars + data->modelData->nStates, sizeof(double)*data->modelData->nStates);

/* update inner algebraic get new values from data */
idaData->residualFunction(data->localData[0]->timeValue, idaData->y, idaData->yp, idaData->newdelta, idaData);
evaluateDAEResiduals_wrapperEventUpdate(data, threadData);
data->simulationInfo->daeModeData->getAlgebraicDAEVars(data, threadData, idaData->states + data->modelData->nStates);
data->simulationInfo->discreteCall = 0;

infoStreamPrint(LOG_SOLVER, 0, "##IDA## do event update at %.15g", data->localData[0]->timeValue);
flag = IDAReInit(idaData->ida_mem,
Expand Down Expand Up @@ -756,9 +754,7 @@ ida_event_update(DATA* data, threadData_t *threadData)
IDAGetConsistentIC(idaData->ida_mem, idaData->y, idaData->yp);

/* update inner algebraic variables */
data->simulationInfo->discreteCall = 1;
idaData->residualFunction(data->localData[0]->timeValue, idaData->y, idaData->yp, idaData->newdelta, idaData);
data->simulationInfo->discreteCall = 0;
evaluateDAEResiduals_wrapperEventUpdate(data, threadData);

memcpy(data->localData[0]->realVars, idaData->states, sizeof(double)*data->modelData->nStates);
// and also algebraic vars
Expand Down Expand Up @@ -1034,7 +1030,6 @@ ida_solver_step(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo)
data->simulationInfo->daeModeData->setAlgebraicDAEVars(data, threadData, idaData->states + data->modelData->nStates);
memcpy(data->localData[0]->realVars + data->modelData->nStates, idaData->statesDer, sizeof(double)*data->modelData->nStates);
sData->timeValue = solverInfo->currentTime;
idaData->residualFunction(sData->timeValue, idaData->y , idaData->yp, idaData->newdelta, idaData);
}

/* sensitivity mode */
Expand Down
4 changes: 4 additions & 0 deletions SimulationRuntime/c/simulation/solver/perform_simulation.c
Expand Up @@ -76,6 +76,10 @@ static void prefixedName_updateContinuousSystem(DATA *data, threadData_t *thread
{
data->callback->functionAlgebraics(data, threadData);
}
else if (compiledInDAEMode == 3)
{
data->simulationInfo->daeModeData->evaluateDAEResiduals(data, threadData);
}
}
else /* ode mode */
{
Expand Down

0 comments on commit 77407e8

Please sign in to comment.