Skip to content

Commit

Permalink
- prepare qss solver development (using euler method as place holder)
Browse files Browse the repository at this point in the history
git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@24856 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
lochel committed Mar 2, 2015
1 parent 7c3bb78 commit 00c28f7
Show file tree
Hide file tree
Showing 5 changed files with 211 additions and 3 deletions.
4 changes: 4 additions & 0 deletions Compiler/Template/CodegenC.tpl
Expand Up @@ -596,6 +596,9 @@ template simulationFile(SimCode simCode, String guid)
#define prefixedName_performSimulation <%symbolName(modelNamePrefixStr,"performSimulation")%>
#include <simulation/solver/perform_simulation.c>

#define prefixedName_performQSSSimulation <%symbolName(modelNamePrefixStr,"performQSSSimulation")%>
#include <simulation/solver/perform_qss_simulation.c>

/* dummy VARINFO and FILEINFO */
const FILE_INFO dummyFILE_INFO = omc_dummyFileInfo;
const VAR_INFO dummyVAR_INFO = omc_dummyVarInfo;
Expand Down Expand Up @@ -655,6 +658,7 @@ template simulationFile(SimCode simCode, String guid)
struct OpenModelicaGeneratedFunctionCallbacks <%symbolName(modelNamePrefixStr,"callback")%> = {
(int (*)(DATA *, void *)) <%symbolName(modelNamePrefixStr,"performSimulation")%>,
(int (*)(DATA *, void *)) <%symbolName(modelNamePrefixStr,"performQSSSimulation")%>,
<%symbolName(modelNamePrefixStr,"callExternalObjectConstructors")%>,
<%symbolName(modelNamePrefixStr,"callExternalObjectDestructors")%>,
<%symbolName(modelNamePrefixStr,"initialNonLinearSystem")%>,
Expand Down
3 changes: 2 additions & 1 deletion SimulationRuntime/c/Makefile.common
Expand Up @@ -51,7 +51,8 @@ RUNTIMESIMSOLVER_HEADERS = ./simulation/solver/delay.h \
./simulation/solver/model_help.h \
./simulation/solver/nonlinearSystem.h \
./simulation/solver/stateset.h \
./simulation/solver/perform_simulation.c \
./simulation/solver/perform_simulation.c \
./simulation/solver/perform_qss_simulation.c \
./simulation/solver/dassl.h \
./simulation/solver/events.h \
./simulation/solver/external_input.h\
Expand Down
1 change: 1 addition & 0 deletions SimulationRuntime/c/openmodelica_func.h
Expand Up @@ -55,6 +55,7 @@ extern "C" {

struct OpenModelicaGeneratedFunctionCallbacks {
int (*performSimulation)(DATA* data, void* solverInfo);
int (*performQSSSimulation)(DATA* data, void* solverInfo);
/* Function for calling external object constructors */
void (*callExternalObjectConstructors)(DATA *data);
/* Function for calling external object deconstructors */
Expand Down
184 changes: 184 additions & 0 deletions SimulationRuntime/c/simulation/solver/perform_qss_simulation.c
@@ -0,0 +1,184 @@
/*
* This file is part of OpenModelica.
*
* Copyright (c) 1998-2014, 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 "solver_main.h"

#include "simulation/simulation_runtime.h"
#include "simulation/results/simulation_result.h"
#include "openmodelica_func.h"

#include "util/omc_error.h"
#include "simulation/options.h"

static int qss_step(DATA* data, SOLVER_INFO* solverInfo)
{
TRACE_PUSH

int i;
SIMULATION_DATA *sData = (SIMULATION_DATA*)data->localData[0];
SIMULATION_DATA *sDataOld = (SIMULATION_DATA*)data->localData[1];
modelica_real* stateDer = sDataOld->realVars + data->modelData.nStates;
SIMULATION_INFO *simInfo = &(data->simulationInfo);

infoStreamPrint(LOG_SOLVER, 1, "call solver from %g to %g (stepSize: %.15g)", solverInfo->currentTime, solverInfo->currentTime + solverInfo->currentStepSize, solverInfo->currentStepSize);

/* calculate states */
/* TODO: use QSS solver instead of euler method */
solverInfo->currentTime = sDataOld->timeValue + solverInfo->currentStepSize;
for(i = 0; i < data->modelData.nStates; i++)
{
sData->realVars[i] = sDataOld->realVars[i] + stateDer[i] * solverInfo->currentStepSize;
}
sData->timeValue = solverInfo->currentTime;
solverInfo->laststep = solverInfo->currentTime;

/* update continous system */
externalInputUpdate(data);
data->callback->input_function(data);
data->callback->functionODE(data);
data->callback->functionAlgebraics(data);
data->callback->output_function(data);
data->callback->function_storeDelayed(data);

messageClose(LOG_SOLVER);

TRACE_POP
return 0;
}

/*! \fn performQSSSimulation(DATA* data, SOLVER_INFO* solverInfo)
*
* \param [ref] [data]
* \param [ref] [solverInfo]
*
* This function performs the simulation controlled by solverInfo.
*/
int prefixedName_performQSSSimulation(DATA* data, SOLVER_INFO* solverInfo)
{
TRACE_PUSH

SIMULATION_INFO *simInfo = &(data->simulationInfo);
unsigned int currStepNo = 0;
int retValIntegrator = 0;
int retValue = 0;

solverInfo->currentTime = simInfo->startTime;

warningStreamPrint(LOG_STDOUT, 0, "This QSS method is under development and should not be used yet.");

/***** Start main simulation loop *****/
while(solverInfo->currentTime < simInfo->stopTime)
{
int success = 0;
threadData->currentErrorStage = ERROR_SIMULATION;
omc_alloc_interface.collect_a_little();

#if !defined(OMC_EMCC)
/* try */
MMC_TRY_INTERNAL(simulationJumpBuffer)
{
#endif

#ifdef USE_DEBUG_TRACE
if(useStream[LOG_TRACE])
printf("TRACE: push loop step=%u, time=%.12g\n", currStepNo, solverInfo->currentTime);
#endif

rotateRingBuffer(data->simulationData, 1, (void**) data->localData);

currStepNo++;
solverInfo->currentStepSize = (double)(currStepNo*(simInfo->stopTime-simInfo->startTime))/(simInfo->numSteps) + simInfo->startTime - solverInfo->currentTime;

if(0 != strcmp("ia", MMC_STRINGDATA(data->simulationInfo.outputFormat)))
{
communicateStatus("Running", (solverInfo->currentTime-simInfo->startTime)/(simInfo->stopTime-simInfo->startTime));
}

retValIntegrator = qss_step(data, solverInfo);

sim_result.emit(&sim_result, data);

/* check if terminate()=true */
if(terminationTerminate)
{
printInfo(stdout, TermInfo);
fputc('\n', stdout);
infoStreamPrint(LOG_STDOUT, 0, "Simulation call terminate() at time %f\nMessage : %s", data->localData[0]->timeValue, TermMsg);
simInfo->stopTime = solverInfo->currentTime;
}

/* terminate for some cases:
* - integrator fails
* - non-linear system failed to solve
* - assert was called
*/
if(retValIntegrator)
{
retValue = -1 + retValIntegrator;
infoStreamPrint(LOG_STDOUT, 0, "model terminate | Integrator failed. | Simulation terminated at time %g", solverInfo->currentTime);
break;
}
else if(check_nonlinear_solutions(data, 0))
{
retValue = -2;
infoStreamPrint(LOG_STDOUT, 0, "model terminate | non-linear system solver failed. | Simulation terminated at time %g", solverInfo->currentTime);
break;
}
else if(check_linear_solutions(data, 0))
{
retValue = -3;
infoStreamPrint(LOG_STDOUT, 0, "model terminate | linear system solver failed. | Simulation terminated at time %g", solverInfo->currentTime);
break;
}
else if(check_mixed_solutions(data, 0))
{
retValue = -4;
infoStreamPrint(LOG_STDOUT, 0, "model terminate | mixed system solver failed. | Simulation terminated at time %g", solverInfo->currentTime);
break;
}
success = 1;
#if !defined(OMC_EMCC)
}
/* catch */
MMC_CATCH_INTERNAL(simulationJumpBuffer)
#endif
if (!success)
{
retValue = -1;
infoStreamPrint(LOG_STDOUT, 0, "model terminate | Simulation terminated by an assert at time: %g", data->localData[0]->timeValue);
break;
}

TRACE_POP /* pop loop */
}

TRACE_POP
return retValue;
}
22 changes: 20 additions & 2 deletions SimulationRuntime/c/simulation/solver/solver_main.c
Expand Up @@ -173,7 +173,8 @@ int initializeSolverData(DATA* data, SOLVER_INFO* solverInfo)
/* set tolerance for ZeroCrossings */
setZCtol(fmin(simInfo->stepSize, simInfo->tolerance));

switch (solverInfo->solverMethod) {
switch (solverInfo->solverMethod)
{
case S_EULER: break;
case S_RUNGEKUTTA:
{
Expand All @@ -187,6 +188,7 @@ int initializeSolverData(DATA* data, SOLVER_INFO* solverInfo)
solverInfo->solverData = rungeData;
break;
}
case S_QSS: break;
#if !defined(OMC_MINIMAL_RUNTIME)
case S_DASSL:
{
Expand Down Expand Up @@ -624,7 +626,23 @@ int solver_main(DATA* data, const char* init_initMethod, const char* init_file,
overwriteOldSimulationData(data);
finishSimulation(data, &solverInfo, outputVariablesAtEnd);
}
/* starts the simulation main loop */
/* starts the simulation main loop - special solvers */
else if(S_QSS == solverInfo.solverMethod)
{
sim_result.emit(&sim_result,data);

/* overwrite the whole ring-buffer with initialized values */
overwriteOldSimulationData(data);

infoStreamPrint(LOG_SOLVER, 0, "Start numerical integration (startTime: %g, stopTime: %g)", simInfo->startTime, simInfo->stopTime);
retVal = data->callback->performQSSSimulation(data, &solverInfo);
omc_alloc_interface.collect_a_little();

/* terminate the simulation */
finishSimulation(data, &solverInfo, outputVariablesAtEnd);
omc_alloc_interface.collect_a_little();
}
/* starts the simulation main loop - standard solver interface */
else
{
if(solverInfo.solverMethod != S_OPTIMIZATION)
Expand Down

0 comments on commit 00c28f7

Please sign in to comment.