Skip to content

Commit

Permalink
add code generation for DAE mode
Browse files Browse the repository at this point in the history
  • Loading branch information
Willi Braun authored and OpenModelica-Hudson committed Apr 27, 2016
1 parent 75b496e commit b9640d0
Show file tree
Hide file tree
Showing 8 changed files with 148 additions and 5 deletions.
1 change: 1 addition & 0 deletions Compiler/SimCode/SimCodeMain.mo
Expand Up @@ -637,6 +637,7 @@ algorithm
(CodegenC.simulationFile_opt_header, "_13opt.h"),
(CodegenC.simulationFile_lnz, "_14lnz.c"),
(CodegenC.simulationFile_syn, "_15syn.c"),
(CodegenC.simulationFile_dae, "_16dae.c"),
(CodegenC.simulationHeaderFile, "_model.h")
} loop
(func,str) := f;
Expand Down
126 changes: 122 additions & 4 deletions Compiler/Template/CodegenC.tpl
Expand Up @@ -161,6 +161,9 @@ end translateModel;
extern void <%symbolName(modelNamePrefixStr,"read_input_fmu")%>(MODEL_DATA* modelData, SIMULATION_INFO* simulationData);
extern void <%symbolName(modelNamePrefixStr,"function_savePreSynchronous")%>(DATA *data, threadData_t *threadData);
extern int <%symbolName(modelNamePrefixStr,"inputNames")%>(DATA* data, char ** names);
extern int <%symbolName(modelNamePrefixStr,"evaluateDAEResiduals")%>(DATA *data, threadData_t *threadData);
extern int <%symbolName(modelNamePrefixStr,"setAlgebraicDAEVars")%>(DATA *data, threadData_t *threadData, double* algebraics);
extern int <%symbolName(modelNamePrefixStr,"getAlgebraicDAEVars")%>(DATA *data, threadData_t *threadData, double* algebraics);
<%\n%>
>>
end match
Expand Down Expand Up @@ -801,6 +804,35 @@ template simulationFile_lnz(SimCode simCode)
end match
end simulationFile_lnz;

template simulationFile_dae(SimCode simCode)
"Algebraic"
::=
match simCode
case SIMCODE(modelInfo=MODELINFO(vars=SIMVARS(__)), daeEquations=daeEquations) then
match modelInfo
case MODELINFO(vars=SIMVARS(__)) then
<<
/* DAE residuals */
<%simulationFileHeader(simCode)%>

#ifdef __cplusplus
extern "C" {
#endif
<%evaluateDAEResiduals(daeEquations, modelNamePrefix(simCode))%>
<%algebraicDAEVar(vars.algebraicDAEVars, modelNamePrefix(simCode))%>
#ifdef __cplusplus
}
#endif<%\n%>
>>
/* adrpo: leave a newline at the end of file to get rid of the warning */
end match
end match
end simulationFile_dae;

template simulationFile(SimCode simCode, String guid, Boolean isModelExchangeFMU)
"Generates code for main C file for simulation target."
::=
Expand Down Expand Up @@ -911,6 +943,9 @@ template simulationFile(SimCode simCode, String guid, Boolean isModelExchangeFMU
<%symbolName(modelNamePrefixStr,"functionODE")%>,
<%symbolName(modelNamePrefixStr,"functionAlgebraics")%>,
<%symbolName(modelNamePrefixStr,"functionDAE")%>,
<%symbolName(modelNamePrefixStr,"evaluateDAEResiduals")%>,
<%symbolName(modelNamePrefixStr,"setAlgebraicDAEVars")%>,
<%symbolName(modelNamePrefixStr,"getAlgebraicDAEVars")%>,
<%symbolName(modelNamePrefixStr,"input_function")%>,
<%symbolName(modelNamePrefixStr,"input_function_init")%>,
<%symbolName(modelNamePrefixStr,"input_function_updateStartValues")%>,
Expand Down Expand Up @@ -992,6 +1027,7 @@ template simulationFile(SimCode simCode, String guid, Boolean isModelExchangeFMU
data.modelData = &modelData;
data.simulationInfo = &simInfo;
measure_time_flag = <% if profileHtml() then "5" else if profileSome() then "1" else if profileAll() then "2" else "0" /* Would be good if this was not a global variable...*/ %>;
compiledInDAEMode = <% if Flags.getConfigBool(Flags.DAE_MODE) then '1' else '0' %>;
<%mainInit%>
<%mainTop(mainBody,"https://trac.openmodelica.org/OpenModelica/newticket")%>
Expand Down Expand Up @@ -1058,7 +1094,7 @@ template populateModelInfo(ModelInfo modelInfo, String fileNamePrefix, String gu
"Generates information for data.modelInfo struct."
::=
match modelInfo
case MODELINFO(varInfo=VARINFO(__)) then
case MODELINFO(varInfo=VARINFO(__),vars=SIMVARS(__)) then
<<
data->modelData->modelName = "<%dotPath(name)%>";
data->modelData->modelFilePrefix = "<%fileNamePrefix%>";
Expand Down Expand Up @@ -1139,11 +1175,15 @@ template populateModelInfo(ModelInfo modelInfo, String fileNamePrefix, String gu
data->modelData->nOptimizeConstraints = <%varInfo.numOptimizeConstraints%>;
data->modelData->nOptimizeFinalConstraints = <%varInfo.numOptimizeFinalConstraints%>;

data->modelData->nDelayExpressions = <%match delayed case DELAYED_EXPRESSIONS(__) then maxDelayedIndex%>;
data->modelData->nDelayExpressions = <%match delayed case
DELAYED_EXPRESSIONS(__) then maxDelayedIndex%>;

data->modelData->nClocks = <%nClocks%>;
data->modelData->nSubClocks = <%nSubClocks%>;

data->modelData->nResidualVars = <%listLength(vars.residualVars)%>;
data->modelData->nAlgebraicDAEVars = <%listLength(vars.algebraicDAEVars)%>;

>>
end match
end populateModelInfo;
Expand Down Expand Up @@ -1236,6 +1276,11 @@ template variableDefinitions(ModelInfo modelInfo, list<BackendDAE.TimeEvent> tim
globalDataVarDefine(var, "realVars", intAdd(intAdd(intMul(2, numStateVars),numAlgVars), intAdd(numDiscreteReal,numOptimizeConstraints)))
;separator="\n"%>

/* residual variables of DAE solution method */
<%vars.residualVars |> var =>
globalDataParDefine(var, "residualVars")
;separator="\n"%>

/* Algebraic Parameter */
<%vars.paramVars |> var =>
globalDataParDefine(var, "realParameter")
Expand Down Expand Up @@ -3744,6 +3789,79 @@ template functionAlgebraic(list<list<SimEqSystem>> algebraicEquations, String mo
>>
end functionAlgebraic;
template evaluateDAEResiduals(list<list<SimEqSystem>> resEquations, String modelNamePrefix)
"Generates function in simulation file."
::=
let &eqFuncs = buffer ""
let &nrfuncs = buffer ""
let &fncalls = buffer ""
let systems = if Flags.isSet(Flags.PARMODAUTO) then
(functionXXX_systems_arrayFormat(resEquations, "DAERes", &fncalls, &nrfuncs, &eqFuncs, modelNamePrefix))
else
(functionXXX_systems(resEquations, "DAERes", &fncalls, &eqFuncs, modelNamePrefix))
let eqns = (resEquations |> eqLst => (eqLst |> eq hasindex i0 =>
equation_(-1, eq, contextSimulationDiscrete, &eqFuncs, modelNamePrefix)
;separator="\n");separator="\n")
<<
/*residual equations*/
<%eqFuncs%>
<%systems%>
/* for residuals DAE variables */
int <%symbolName(modelNamePrefix,"evaluateDAEResiduals")%>(DATA *data, threadData_t *threadData)
{
TRACE_PUSH
data->simulationInfo->callStatistics.functionEvalDAE++;
<%if Flags.isSet(Flags.PARMODAUTO) then 'PM_functionDAERes(<%nrfuncs%>, data, threadData, functionDAERes_systems);'
else '<%fncalls%>' %>
<%symbolName(modelNamePrefix,"function_savePreSynchronous")%>(data, threadData);
TRACE_POP
return 0;
}
>>
end evaluateDAEResiduals;
template algebraicDAEVar(list<SimVar> algVars, String modelNamePrefix)
"Generates function in simulation file."
::=
let forwardVars = (algVars |> var hasindex i fromindex 0 =>
(match var
case SIMVAR(__) then
'<%cref(name)%> = algebraic[<%i%>];'
end match)
;separator="\n")
let getVars = (algVars |> var hasindex i fromindex 0 =>
(match var
case SIMVAR(__) then
'algebraic[<%i%>] = <%cref(name)%>;'
end match)
;separator="\n")
<<
/* forward algebraic variables */
int <%symbolName(modelNamePrefix,"setAlgebraicDAEVars")%>(DATA *data, threadData_t *threadData, double* algebraic)
{
TRACE_PUSH
<%forwardVars%>
TRACE_POP
return 0;
}
/* get algebraic variables */
int <%symbolName(modelNamePrefix,"getAlgebraicDAEVars")%>(DATA *data, threadData_t *threadData, double* algebraic)
{
TRACE_PUSH
<%getVars%>
TRACE_POP
return 0;
}
>>
end algebraicDAEVar;
template functionDAE(list<SimEqSystem> allEquationsPlusWhen, String modelNamePrefix)
"Generates function in simulation file.
This is a helper of template simulationFile."
Expand Down Expand Up @@ -5241,7 +5359,7 @@ case SIMCODE(modelInfo=MODELINFO(__), makefileParams=MAKEFILE_PARAMS(__), simula
CFILES=<%fileNamePrefix%>_functions.c <%fileNamePrefix%>_records.c \
<%fileNamePrefix%>_01exo.c <%fileNamePrefix%>_02nls.c <%fileNamePrefix%>_03lsy.c <%fileNamePrefix%>_04set.c <%fileNamePrefix%>_05evt.c <%fileNamePrefix%>_06inz.c <%fileNamePrefix%>_07dly.c \
<%fileNamePrefix%>_08bnd.c <%fileNamePrefix%>_09alg.c <%fileNamePrefix%>_10asr.c <%fileNamePrefix%>_11mix.c <%fileNamePrefix%>_12jac.c <%fileNamePrefix%>_13opt.c <%fileNamePrefix%>_14lnz.c \
<%fileNamePrefix%>_15syn.c
<%fileNamePrefix%>_15syn.c <%fileNamePrefix%>_16dae.c
OFILES=$(CFILES:.c=.obj)
GENERATEDFILES=$(MAINFILE) $(FILEPREFIX)_functions.h $(FILEPREFIX).makefile $(CFILES)

Expand Down Expand Up @@ -5292,7 +5410,7 @@ case SIMCODE(modelInfo=MODELINFO(__), makefileParams=MAKEFILE_PARAMS(__), simula
CFILES=<%fileNamePrefix%>_functions.c <%fileNamePrefix%>_records.c \
<%fileNamePrefix%>_01exo.c <%fileNamePrefix%>_02nls.c <%fileNamePrefix%>_03lsy.c <%fileNamePrefix%>_04set.c <%fileNamePrefix%>_05evt.c <%fileNamePrefix%>_06inz.c <%fileNamePrefix%>_07dly.c \
<%fileNamePrefix%>_08bnd.c <%fileNamePrefix%>_09alg.c <%fileNamePrefix%>_10asr.c <%fileNamePrefix%>_11mix.c <%fileNamePrefix%>_12jac.c <%fileNamePrefix%>_13opt.c <%fileNamePrefix%>_14lnz.c \
<%fileNamePrefix%>_15syn.c
<%fileNamePrefix%>_15syn.c <%fileNamePrefix%>_16dae.c
OFILES=$(CFILES:.c=.o)
GENERATEDFILES=$(MAINFILE) <%fileNamePrefix%>.makefile <%fileNamePrefix%>_literals.h <%fileNamePrefix%>_functions.h $(CFILES)

Expand Down
4 changes: 3 additions & 1 deletion Compiler/Template/CodegenFMU.tpl
Expand Up @@ -124,6 +124,8 @@ end translateModel;
let()= textFileConvertLines(simulationFile_lnz(simCode), '<%modelNamePrefix%>_14lnz.c')
// synchronous
let()= textFileConvertLines(simulationFile_syn(simCode), '<%modelNamePrefix%>_15syn.c')
// residuals
let()= textFileConvertLines(simulationFile_dae(simCode), '<%modelNamePrefix%>_16dae.c')
// main file
let()= textFileConvertLines(simulationFile(simCode,guid,true), '<%modelNamePrefix%>.c')
""
Expand Down Expand Up @@ -1075,7 +1077,7 @@ let common =
CFILES=<%fileNamePrefix%>.c <%fileNamePrefix%>_functions.c <%fileNamePrefix%>_records.c \
<%fileNamePrefix%>_01exo.c <%fileNamePrefix%>_02nls.c <%fileNamePrefix%>_03lsy.c <%fileNamePrefix%>_04set.c <%fileNamePrefix%>_05evt.c <%fileNamePrefix%>_06inz.c <%fileNamePrefix%>_07dly.c \
<%fileNamePrefix%>_08bnd.c <%fileNamePrefix%>_09alg.c <%fileNamePrefix%>_10asr.c <%fileNamePrefix%>_11mix.c <%fileNamePrefix%>_12jac.c <%fileNamePrefix%>_13opt.c <%fileNamePrefix%>_14lnz.c \
<%fileNamePrefix%>_15syn.c <%fileNamePrefix%>_init_fmu.c
<%fileNamePrefix%>_15syn.c <%fileNamePrefix%>_16dae.c <%fileNamePrefix%>_init_fmu.c
OFILES=$(CFILES:.c=.o)
GENERATEDFILES=$(MAINFILE) <%fileNamePrefix%>_FMU.makefile <%fileNamePrefix%>_literals.h <%fileNamePrefix%>_model.h <%fileNamePrefix%>_includes.h <%fileNamePrefix%>_functions.h <%fileNamePrefix%>_11mix.h <%fileNamePrefix%>_12jac.h <%fileNamePrefix%>_13opt.h <%fileNamePrefix%>_init_fmu.c <%fileNamePrefix%>_info.c $(CFILES) <%fileNamePrefix%>_FMU.libs

Expand Down
9 changes: 9 additions & 0 deletions SimulationRuntime/c/openmodelica_func.h
Expand Up @@ -107,6 +107,15 @@ int (*functionAlgebraics)(DATA *data, threadData_t*);
uses in EventHandle */
int (*functionDAE)(DATA *data, threadData_t*);

/* function to evaluate dynamic equations for DAE solver*/
int (*evaluateDAEResiduals)(DATA *data, threadData_t*);

/* function to set algebraic DAE Variable form solver*/
int (*setAlgebraicDAEVars)(DATA *data, threadData_t*, double *algebraics);

/* function to get algebraic DAE Variable form solver*/
int (*getAlgebraicDAEVars)(DATA *data, threadData_t*, double *algebraics);

/* functions for input and output */
int (*input_function)(DATA*, threadData_t*);
int (*input_function_init)(DATA*, threadData_t*);
Expand Down
3 changes: 3 additions & 0 deletions SimulationRuntime/c/simulation/solver/model_help.c
Expand Up @@ -950,6 +950,8 @@ void initializeDataStruc(DATA *data, threadData_t *threadData)
/* buffer for inputs and outputs values */
data->simulationInfo->inputVars = (modelica_real*) calloc(data->modelData->nInputVars, sizeof(modelica_real));
data->simulationInfo->outputVars = (modelica_real*) calloc(data->modelData->nOutputVars, sizeof(modelica_real));
/* buffer for residual values of DAE solver*/
data->simulationInfo->residualVars = (modelica_real*) calloc(data->modelData->nResidualVars, sizeof(modelica_real));

/* buffer for mixed systems */
data->simulationInfo->mixedSystemData = (MIXED_SYSTEM_DATA*) omc_alloc_interface.malloc_uncollectable(data->modelData->nMixedSystems*sizeof(MIXED_SYSTEM_DATA));
Expand Down Expand Up @@ -989,6 +991,7 @@ void initializeDataStruc(DATA *data, threadData_t *threadData)

/* initial call statistics */
data->simulationInfo->callStatistics.functionODE = 0;
data->simulationInfo->callStatistics.functionEvalDAE = 0;
data->simulationInfo->callStatistics.updateDiscreteSystem = 0;
data->simulationInfo->callStatistics.functionZeroCrossingsEquations = 0;
data->simulationInfo->callStatistics.functionZeroCrossings = 0;
Expand Down
4 changes: 4 additions & 0 deletions SimulationRuntime/c/simulation_data.h
Expand Up @@ -107,6 +107,7 @@ typedef struct CALL_STATISTICS
long updateDiscreteSystem;
long functionZeroCrossingsEquations;
long functionZeroCrossings;
long functionEvalDAE;
} CALL_STATISTICS;

typedef enum {ERROR_AT_TIME,NO_PROGRESS_START_POINT,NO_PROGRESS_FACTOR,IMPROPER_INPUT} equationSystemError;
Expand Down Expand Up @@ -474,6 +475,8 @@ typedef struct MODEL_DATA
long nAliasString;

long nJacobians;
long nResidualVars;
long nAlgebraicDAEVars;
}MODEL_DATA;

typedef struct CLOCK_DATA {
Expand Down Expand Up @@ -569,6 +572,7 @@ typedef struct SIMULATION_INFO
modelica_real* inputVars;
modelica_real* outputVars;
EXTERNAL_INPUT external_input;
modelica_real* residualVars; /* used by integrators in dae solver mode */

ANALYTIC_JACOBIAN* analyticJacobians;

Expand Down
5 changes: 5 additions & 0 deletions SimulationRuntime/c/util/simulation_options.c
Expand Up @@ -40,6 +40,7 @@ const char *FLAG_NAME[FLAG_MAX+1] = {
/* FLAG_CSV_OSTEP */ "csvOstep",
/* FLAG_DASSL_NO_RESTART */ "dasslnoRestart",
/* FLAG_DASSL_NO_ROOTFINDING */ "dasslnoRootFinding",
/* FLAG_DAE_MODE */ "daeMode",
/* FLAG_EMBEDDED_SERVER */ "embeddedServer",
/* FLAG_EMIT_PROTECTED */ "emit_protected",
/* FLAG_F */ "f",
Expand Down Expand Up @@ -107,6 +108,7 @@ const char *FLAG_DESC[FLAG_MAX+1] = {
/* FLAG_CSV_OSTEP */ "value specifies csv-files for debuge values for optimizer step",
/* FLAG_DASSL_NO_RESTART */ "flag deactivates the restart of dassl after an event is performed.",
/* FLAG_DASSL_NO_ROOTFINDING */ "flag deactivates the internal root finding procedure of dassl.",
/* FLAG_DAE_MODE */ "flag to let the integrator use daeResiduals",
/* FLAG_EMBEDDED_SERVER */ "enables an embedded server. Valid values: none, opc-da [broken], opc-ua [experimental], or the path to a shared object.",
/* FLAG_EMIT_PROTECTED */ "emits protected variables to the result-file",
/* FLAG_F */ "value specifies a new setup XML file to the generated simulation code",
Expand Down Expand Up @@ -183,6 +185,8 @@ const char *FLAG_DETAILED_DESC[FLAG_MAX+1] = {
" Deactivates the restart of dassl after an event is performed.",
/* FLAG_DASSL_NO_ROOTFINDING */
" Deactivates the internal root finding procedure of dassl.",
/* FLAG_DAE_MODE */
"flag to let the integrator use daeMode",
/* FLAG_EMBEDDED_SERVER */
" Enables an embedded server. Valid values:\n\n"
" * none - default, run without embedded server\n"
Expand Down Expand Up @@ -345,6 +349,7 @@ const int FLAG_TYPE[FLAG_MAX] = {
/* FLAG_CSV_OSTEP */ FLAG_TYPE_OPTION,
/* FLAG_DASSL_NO_RESTART */ FLAG_TYPE_FLAG,
/* FLAG_DASSL_NO_ROOTFINDING */ FLAG_TYPE_FLAG,
/* FLAG_DAE_SOLVING */ FLAG_TYPE_FLAG,
/* FLAG_EMBEDDED_SERVER */ FLAG_TYPE_OPTION,
/* FLAG_EMIT_PROTECTED */ FLAG_TYPE_FLAG,
/* FLAG_F */ FLAG_TYPE_OPTION,
Expand Down
1 change: 1 addition & 0 deletions SimulationRuntime/c/util/simulation_options.h
Expand Up @@ -48,6 +48,7 @@ enum _FLAG
FLAG_CSV_OSTEP,
FLAG_DASSL_NO_RESTART,
FLAG_DASSL_NO_ROOTFINDING,
FLAG_DAE_MODE,
FLAG_EMBEDDED_SERVER,
FLAG_EMIT_PROTECTED,
FLAG_F,
Expand Down

0 comments on commit b9640d0

Please sign in to comment.