Skip to content

Commit

Permalink
Move checkForDiscreteChanges to simulation runtime
Browse files Browse the repository at this point in the history
We should not need to generate code for this function since all it does
is compare two vectors to each other to set a flag if a discrete value
changed.

Belonging to [master]:
  - OpenModelica/OMCompiler#1891
  - OpenModelica/OpenModelica-testsuite#738
  • Loading branch information
sjoelund authored and OpenModelica-Hudson committed Oct 12, 2017
1 parent 3a0af47 commit ebb0ea8
Show file tree
Hide file tree
Showing 14 changed files with 223 additions and 79 deletions.
19 changes: 19 additions & 0 deletions Compiler/SimCode/SimCodeUtil.mo
Expand Up @@ -13462,6 +13462,25 @@ algorithm
else t1>t2;
end simvarGraterThan;

public function sortCrefBasedOnSimCodeIndex
input output list<DAE.ComponentRef> crs;
input SimCode.SimCode simCode;
algorithm
crs := List.sort(crs, function crefSimCodeIndexGreaterThan(simCode=simCode));
end sortCrefBasedOnSimCodeIndex;

protected function crefSimCodeIndexGreaterThan
input DAE.ComponentRef cr1, cr2;
input SimCode.SimCode simCode;
output Boolean b;
protected
SimCodeVar.SimVar v1, v2;
algorithm
v1 := cref2simvar(cr1, simCode);
v2 := cref2simvar(cr2, simCode);
b := simvarGraterThan(v1, v2);
end crefSimCodeIndexGreaterThan;

public function lookupVR
input DAE.ComponentRef cr;
input SimCode.SimCode simCode;
Expand Down
44 changes: 7 additions & 37 deletions Compiler/Template/CodegenC.tpl
Expand Up @@ -152,7 +152,6 @@ end translateModel;
extern int <%symbolName(modelNamePrefixStr,"function_ZeroCrossingsEquations")%>(DATA *data, threadData_t *threadData);
extern int <%symbolName(modelNamePrefixStr,"function_ZeroCrossings")%>(DATA *data, threadData_t *threadData, double* gout);
extern int <%symbolName(modelNamePrefixStr,"function_updateRelations")%>(DATA *data, threadData_t *threadData, int evalZeroCross);
extern int <%symbolName(modelNamePrefixStr,"checkForDiscreteChanges")%>(DATA *data, threadData_t *threadData);
extern const char* <%symbolName(modelNamePrefixStr,"zeroCrossingDescription")%>(int i, int **out_EquationIndexes);
extern const char* <%symbolName(modelNamePrefixStr,"relationDescription")%>(int i);
extern void <%symbolName(modelNamePrefixStr,"function_initSample")%>(DATA *data, threadData_t *threadData);
Expand Down Expand Up @@ -582,8 +581,6 @@ template simulationFile_evt(SimCode simCode)
<%functionRelations(relations, modelNamePrefix(simCode))%>
<%functionCheckForDiscreteChanges(discreteModelVars, modelNamePrefix(simCode))%>
#if defined(__cplusplus)
}
#endif
Expand Down Expand Up @@ -1022,6 +1019,7 @@ template simulationFile(SimCode simCode, String guid, Boolean isModelExchangeFMU
<<
/* Main Simulation File */
<%simulationFileHeader(simCode.fileNamePrefix)%>
#include "simulation/solver/events.h"

<% if boolNot(isModelExchangeFMU) then
<<
Expand Down Expand Up @@ -1119,7 +1117,6 @@ template simulationFile(SimCode simCode, String guid, Boolean isModelExchangeFMU
<%symbolName(modelNamePrefixStr,"function_ZeroCrossingsEquations")%>,
<%symbolName(modelNamePrefixStr,"function_ZeroCrossings")%>,
<%symbolName(modelNamePrefixStr,"function_updateRelations")%>,
<%symbolName(modelNamePrefixStr,"checkForDiscreteChanges")%>,
<%symbolName(modelNamePrefixStr,"zeroCrossingDescription")%>,
<%symbolName(modelNamePrefixStr,"relationDescription")%>,
<%symbolName(modelNamePrefixStr,"function_initSample")%>,
Expand Down Expand Up @@ -4429,39 +4426,6 @@ template relationTpl(Integer index1, Exp relation, Context context, Text &varDec
>>
end relationTpl;
template functionCheckForDiscreteChanges(list<ComponentRef> discreteModelVars, String modelNamePrefix) "template functionCheckForDiscreteChanges
Generates function in simulation file.
This is a helper of template simulationFile."
::=
let changediscreteVars = (discreteModelVars |> var =>
match var
case CREF_QUAL(__)
case CREF_IDENT(__) then
<<
if(<%cref(var)%> != <%crefPre(var)%>)
{
infoStreamPrint(LOG_EVENTS_V, 0, "discrete var changed: %s from <%crefToPrintfArg(var)%> to <%crefToPrintfArg(var)%>", <%crefVarInfo(var)%>.name, <%crefPre(var)%>, <%cref(var)%>);
needToIterate = 1;
}
>>
;separator="\n")
<<
int <%symbolName(modelNamePrefix, "checkForDiscreteChanges")%>(DATA *data, threadData_t *threadData)
{
TRACE_PUSH
int needToIterate = 0;
infoStreamPrint(LOG_EVENTS_V, 1, "check for discrete changes at time=%.12g", data->localData[0]->timeValue);
<%changediscreteVars%>
if (ACTIVE_STREAM(LOG_EVENTS_V)) messageClose(LOG_EVENTS_V);
TRACE_POP
return needToIterate;
}
>>
end functionCheckForDiscreteChanges;
template crefToPrintfArg(ComponentRef cr)
::=
match crefType(cr)
Expand Down Expand Up @@ -4493,6 +4457,12 @@ template crefShortType(ComponentRef cr) "template crefType
end match
end crefShortType;
template crefIndexInArray(ComponentRef cr, SimCode simCode)
::=
match cref2simvar(cr, simCode)
case SIMVAR(__) then index
end crefIndexInArray;
template functionAssertsforCheck(list<SimEqSystem> algAndEqAssertsEquations, String modelNamePrefix) "template functionAssertsforCheck
Generates function in simulation file.
This is a helper of template simulationFile."
Expand Down
11 changes: 5 additions & 6 deletions Compiler/Template/CodegenFMU.tpl
Expand Up @@ -1106,23 +1106,22 @@ match platform
>>
else
<<
<%fileNamePrefix%>_FMU:
<%\t%>$(MAKE) CC="$(CC)" $(MAINOBJ) <%fileNamePrefix%>_functions.h <%fileNamePrefix%>_literals.h $(OFILES) $(RUNTIMEFILES) 2>&1 | tee make.log
<%fileNamePrefix%>_FMU: $(MAINOBJ) <%fileNamePrefix%>_functions.h <%fileNamePrefix%>_literals.h $(OFILES) $(RUNTIMEFILES)
<%\t%>mkdir -p ../binaries/$(FMIPLATFORM)
ifeq (@LIBTYPE_DYNAMIC@,1)
<%\t%>$(LD) -o <%modelNamePrefix%>$(DLLEXT) $(MAINOBJ) $(OFILES) $(RUNTIMEFILES) <%dirExtra%> <%libsPos1%> <%libsPos2%> $(LDFLAGS) 2>&1 | tee -a make.log
<%\t%>cp <%fileNamePrefix%>$(DLLEXT) <%fileNamePrefix%>_FMU.libs config.log make.log ../binaries/$(FMIPLATFORM)/
<%\t%>$(LD) -o <%modelNamePrefix%>$(DLLEXT) $(MAINOBJ) $(OFILES) $(RUNTIMEFILES) <%dirExtra%> <%libsPos1%> <%libsPos2%> $(LDFLAGS)
<%\t%>cp <%fileNamePrefix%>$(DLLEXT) <%fileNamePrefix%>_FMU.libs config.log ../binaries/$(FMIPLATFORM)/
endif
<%\t%>head -n20 Makefile > ../binaries/$(FMIPLATFORM)/config.summary
ifeq (@LIBTYPE_STATIC@,1)
<%\t%>rm -f <%modelNamePrefix%>.a
<%\t%>$(AR) -rsu <%modelNamePrefix%>.a $(MAINOBJ) $(OFILES) $(RUNTIMEFILES)
<%\t%>cp <%fileNamePrefix%>.a <%fileNamePrefix%>_FMU.libs config.log make.log ../binaries/$(FMIPLATFORM)/
<%\t%>cp <%fileNamePrefix%>.a <%fileNamePrefix%>_FMU.libs config.log ../binaries/$(FMIPLATFORM)/
endif
<%\t%>$(MAKE) distclean
<%\t%>cd .. && rm -f ../<%fileNamePrefix%>.fmu && zip -r ../<%fmuTargetName%>.fmu *
distclean: clean
<%\t%>rm -f Makefile config.status config.log make.log
<%\t%>rm -f Makefile config.status config.log
clean:
<%\t%>rm -f <%fileNamePrefix%>.def <%fileNamePrefix%>.o <%fileNamePrefix%>.a <%fileNamePrefix%>$(DLLEXT) $(MAINOBJ) $(OFILES) $(RUNTIMEFILES)
>>
Expand Down
6 changes: 6 additions & 0 deletions Compiler/Template/SimCodeTV.mo
Expand Up @@ -1027,6 +1027,12 @@ package SimCodeUtil
output list<SimCode.SimEqSystem> eqs;
end sortSimpleAssignmentBasedOnLhs;

function sortCrefBasedOnSimCodeIndex
input list<DAE.ComponentRef> inCrefs;
input SimCode.SimCode simCode;
output list<DAE.ComponentRef> crs;
end sortCrefBasedOnSimCodeIndex;

function lookupVR
input DAE.ComponentRef cr;
input SimCode.SimCode simCode;
Expand Down
1 change: 1 addition & 0 deletions SimulationRuntime/c/Makefile.common
Expand Up @@ -52,6 +52,7 @@ RUNTIMESIMRESULTS_HEADERS = ./simulation/results/simulation_result.h

RUNTIMESIMSOLVER_HEADERS = ./simulation/solver/delay.h \
./simulation/solver/epsilon.h \
./simulation/solver/fmi_events.h \
./simulation/solver/mixedSystem.h \
./simulation/solver/linearSystem.h \
./simulation/solver/linearSolverLapack.h \
Expand Down
4 changes: 2 additions & 2 deletions SimulationRuntime/c/Makefile.objs
Expand Up @@ -59,7 +59,7 @@ else
SOLVER_OBJS_MIXED_SYSTEMS=mixedSystem$(OBJ_EXT) mixedSearchSolver$(OBJ_EXT)
endif

SOLVER_OBJS_FMU=delay$(OBJ_EXT) $(SOLVER_OBJS_LINEAR_SYSTEMS) $(SOLVER_OBJS_MIXED_SYSTEMS) $(SOLVER_OBJS_NONLINEAR_SYSTEMS) omc_math$(OBJ_EXT) model_help$(OBJ_EXT) stateset$(OBJ_EXT) synchronous$(OBJ_EXT)
SOLVER_OBJS_FMU=delay$(OBJ_EXT) $(SOLVER_OBJS_LINEAR_SYSTEMS) $(SOLVER_OBJS_MIXED_SYSTEMS) $(SOLVER_OBJS_NONLINEAR_SYSTEMS) fmi_events$(OBJ_EXT) omc_math$(OBJ_EXT) model_help$(OBJ_EXT) stateset$(OBJ_EXT) synchronous$(OBJ_EXT)
ifeq ($(OMC_FMI_RUNTIME),)
SOLVER_OBJS_MINIMAL=$(SOLVER_OBJS_FMU) events$(OBJ_EXT) external_input$(OBJ_EXT) solver_main$(OBJ_EXT) real_time_sync$(OBJ_EXT) embedded_server$(OBJ_EXT)

Expand All @@ -71,7 +71,7 @@ SOLVER_OBJS=$(SOLVER_OBJS_MINIMAL) kinsolSolver$(OBJ_EXT) linearSolverKlu$(OBJ_E
else
SOLVER_OBJS=$(SOLVER_OBJS_MINIMAL)
endif
SOLVER_HFILES = dassl.h delay.h epsilon.h events.h external_input.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 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
8 changes: 0 additions & 8 deletions SimulationRuntime/c/openmodelica_func.h
Expand Up @@ -209,14 +209,6 @@ int (*function_ZeroCrossings)(DATA *data, threadData_t*, double* gout);
*/
int (*function_updateRelations)(DATA *data, threadData_t*, int evalZeroCross);

/*! \fn checkForDiscreteChanges
*
* This function checks if any discrete variable changed
*
* \param [ref] [data]
*/
int (*checkForDiscreteChanges)(DATA *data, threadData_t*);

/*! \var zeroCrossingDescription
*
* This variable contains a description string for zero crossing condition.
Expand Down
1 change: 1 addition & 0 deletions SimulationRuntime/c/simulation/solver/events.c
Expand Up @@ -527,6 +527,7 @@ void saveZeroCrossingsAfterEvent(DATA *data, threadData_t *threadData)
TRACE_POP
}


#ifdef __cplusplus
}
#endif
1 change: 1 addition & 0 deletions SimulationRuntime/c/simulation/solver/events.h
Expand Up @@ -37,6 +37,7 @@
#include "simulation_data.h"
#include "simulation/solver/solver_main.h"
#include "util/list.h"
#include "simulation/solver/fmi_events.h"

#ifdef __cplusplus
extern "C" {
Expand Down
112 changes: 112 additions & 0 deletions SimulationRuntime/c/simulation/solver/fmi_events.c
@@ -0,0 +1,112 @@
/*
* 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 "simulation/solver/fmi_events.h"

#ifdef __cplusplus
extern "C" {
#endif

int checkForDiscreteChanges(DATA *data, threadData_t *threadData)
{
TRACE_PUSH
MODEL_DATA *modelData = data->modelData;
long i=0, realStartIndex=modelData->nVariablesReal - modelData->nDiscreteReal, realStopIndex=modelData->nVariablesReal;

if (ACTIVE_STREAM(LOG_EVENTS_V)) {
/* We log all changed variables. This takes some extra time because we always iterate over all variables, and duplicates code */
int needToIterate = 0;
infoStreamPrint(LOG_EVENTS_V, 1, "check for discrete changes at time=%.12g", data->localData[0]->timeValue);

if ((!modelData->nDiscreteReal) && (!modelData->nVariablesInteger) && (!modelData->nVariablesBoolean) && (!modelData->nVariablesString)) {
return 0;
}
for (i=realStartIndex; i<realStopIndex; i++) {
modelica_real v1 = data->simulationInfo->realVarsPre[i];
modelica_real v2 = data->localData[0]->realVars[i];
if (v1 != v2) {
infoStreamPrint(LOG_EVENTS_V, 0, "discrete var changed: %s from %g to %g", modelData->realVarsData[i].info.name, v1, v2);
needToIterate = 1;
}
}
for (i=0; i<modelData->nVariablesInteger; i++) {
modelica_integer v1 = data->simulationInfo->integerVarsPre[i];
modelica_integer v2 = data->localData[0]->integerVars[i];
if (v1 != v2) {
infoStreamPrint(LOG_EVENTS_V, 0, "discrete var changed: %s from %ld to %ld", modelData->integerVarsData[i].info.name, (long) v1, (long) v2);
needToIterate = 1;
}
}
for (i=0; i<modelData->nVariablesBoolean; i++) {
modelica_boolean v1 = data->simulationInfo->booleanVarsPre[i];
modelica_boolean v2 = data->localData[0]->booleanVars[i];
if (v1 != v2) {
infoStreamPrint(LOG_EVENTS_V, 0, "discrete var changed: %s from %d to %d", modelData->booleanVarsData[i].info.name, v1, v2);
needToIterate = 1;
}
}
for (i=0; i<modelData->nVariablesString; i++) {
modelica_string v1 = data->simulationInfo->stringVarsPre[i];
modelica_string v2 = data->localData[0]->stringVars[i];
if (0 != strcmp(MMC_STRINGDATA(v1),MMC_STRINGDATA(v2))) {
infoStreamPrint(LOG_EVENTS_V, 0, "discrete var changed: %s from %s to %s", modelData->stringVarsData[i].info.name, v1, v2);
needToIterate = 1;
}
}
if (ACTIVE_STREAM(LOG_EVENTS_V)) messageClose(LOG_EVENTS_V);
return needToIterate;
} else {
/* Just check if variables changed */
if (0 != memcmp(data->simulationInfo->realVarsPre + realStartIndex, data->localData[0]->realVars + realStartIndex, modelData->nDiscreteReal*sizeof(modelica_real))) {
return 1;
}
if (0 != memcmp(data->simulationInfo->integerVarsPre, data->localData[0]->integerVars, modelData->nVariablesInteger*sizeof(modelica_integer))) {
return 1;
}
if (0 != memcmp(data->simulationInfo->booleanVarsPre, data->localData[0]->booleanVars, modelData->nVariablesBoolean*sizeof(modelica_boolean))) {
return 1;
}
for (i=0; i<modelData->nVariablesString; i++) {
modelica_string v1 = data->simulationInfo->stringVarsPre[i];
modelica_string v2 = data->localData[0]->stringVars[i];
if (0 != strcmp(MMC_STRINGDATA(v1),MMC_STRINGDATA(v2))) {
return 1;
}
}
return 0;
}


TRACE_POP
}

#ifdef __cplusplus
}
#endif
49 changes: 49 additions & 0 deletions SimulationRuntime/c/simulation/solver/fmi_events.h
@@ -0,0 +1,49 @@
/*
* This file is part of OpenModelica.
*
* Copyright (c) 1998-CurrentYear, 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.
*
*/

/*! \file events.h
*/

#ifndef _EVENTS_H_
#define _EVENTS_H_

#include "simulation_data.h"

#ifdef __cplusplus
extern "C" {
#endif

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

#ifdef __cplusplus
}
#endif

#endif
4 changes: 2 additions & 2 deletions SimulationRuntime/c/simulation/solver/model_help.c
Expand Up @@ -104,7 +104,7 @@ void updateDiscreteSystem(DATA *data, threadData_t *threadData)
debugStreamPrint(LOG_EVENTS_V, 0, "updated discrete System");

relationChanged = checkRelations(data);
discreteChanged = data->callback->checkForDiscreteChanges(data, threadData);
discreteChanged = checkForDiscreteChanges(data, threadData);
while(discreteChanged || data->simulationInfo->needToIterate || relationChanged)
{
if(data->simulationInfo->needToIterate) {
Expand All @@ -131,7 +131,7 @@ void updateDiscreteSystem(DATA *data, threadData_t *threadData)
}

relationChanged = checkRelations(data);
discreteChanged = data->callback->checkForDiscreteChanges(data, threadData);
discreteChanged = checkForDiscreteChanges(data, threadData);
}
storeRelations(data);

Expand Down

0 comments on commit ebb0ea8

Please sign in to comment.