Skip to content

Commit

Permalink
adjust code generation for daeMode
Browse files Browse the repository at this point in the history
  • Loading branch information
Willi Braun authored and OpenModelica-Hudson committed May 25, 2016
1 parent 397dd82 commit 7ef8873
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 70 deletions.
211 changes: 178 additions & 33 deletions Compiler/Template/CodegenC.tpl
Expand Up @@ -161,9 +161,7 @@ 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);
extern int <%symbolName(modelNamePrefixStr,"initializeDAEmodeData")%>(DATA *data, DAEMODE_DATA*);
<%\n%>
>>
end match
Expand Down Expand Up @@ -804,32 +802,91 @@ template simulationFile_lnz(SimCode simCode)
end match
end simulationFile_lnz;

template defineSimVarArray(SimVar simVar, String arrayName)
"Generates a define statement for a parameter."
::=
match simVar
case SIMVAR(arrayCref=SOME(c),aliasvar=NOALIAS()) then
<<
/* <%crefStrNoUnderscore(c)%> */
#define <%cref(c)%> data->simulationInfo->daeModeData-><%arrayName%>[<%index%>]

/* <%crefStrNoUnderscore(name)%> */
#define <%cref(name)%> data->simulationInfo->daeModeData-><%arrayName%>[<%index%>]

>>
case SIMVAR(aliasvar=NOALIAS()) then
<<
/* <%crefStrNoUnderscore(name)%> */
#define <%cref(name)%> data->simulationInfo->daeModeData-><%arrayName%>[<%index%>]

>>
end match
end defineSimVarArray;

template simulationFile_dae_header(SimCode simCode)
"DAEmode header generation"
::=
match simCode
case simCode as SIMCODE(daeModeData=SOME(DAEMODEDATA(residualVars=residualVars))) then
<<
/* residual variable define for daeMode */
<%residualVars |> var =>
defineSimVarArray(var, "residualVars")
;separator="\n"%>
>>
/* adrpo: leave a newline at the end of file to get rid of the warning */
end match
end simulationFile_dae_header;

template simulationFile_dae(SimCode simCode)
"Algebraic"
"DAEmode equations generation"
::=
match simCode
case SIMCODE(modelInfo=MODELINFO(vars=SIMVARS(__)), daeModeDate=DAEMODEDATA(daeEquations=daeEquations)) then
match modelInfo
case MODELINFO(vars=SIMVARS(__)) then
<<
/* DAE residuals */
<%simulationFileHeader(simCode)%>
case SIMCODE(modelInfo=MODELINFO(vars=SIMVARS(__)),
daeModeData=SOME(DAEMODEDATA(daeEquations=daeEquations, sparsityPattern=sparsityPattern,
algebraicDAEVars=algebraicDAEVars, residualVars=residualVars))) then
let modelNamePrefixStr = modelNamePrefix(simCode)
let initDAEmode =
match sparsityPattern
case SOME((_, _, _, (sparse,_), colorList, maxColor, _)) then
'<%initializeDAEmodeData(listLength(residualVars), listLength(algebraicDAEVars), sparse, colorList, maxColor, modelNamePrefixStr)%>'
case NONE() then
'int <%symbolName(modelNamePrefixStr,"initializeDAEmodeData")%>(DATA *inData, DAEMODE_DATA* daeModeData){ return -1; }'
end match
<<
/* DAE residuals */
<%simulationFileHeader(simCode)%>
#include "<%fileNamePrefix%>_16dae.h"

#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
extern "C" {
#endif
<%evaluateDAEResiduals(daeEquations, modelNamePrefixStr)%>
<%evaluateDAEResiduals(daeEquations, modelNamePrefix(simCode))%>
<%algebraicDAEVar(algebraicDAEVars, modelNamePrefixStr)%>
<%algebraicDAEVar(vars.algebraicDAEVars, modelNamePrefix(simCode))%>
<%initDAEmode%>
#ifdef __cplusplus
}
#endif<%\n%>
>>
/* adrpo: leave a newline at the end of file to get rid of the warning */
end match
#ifdef __cplusplus
}
#endif<%\n%>
>>
/* adrpo: leave a newline at the end of file to get rid of the warning */
else
let modelNamePrefixStr = modelNamePrefix(simCode)
<<
/* DAE residuals is empty */
<%simulationFileHeader(simCode)%>
#ifdef __cplusplus
extern "C" {
#endif
int <%symbolName(modelNamePrefixStr,"initializeDAEmodeData")%>(DATA *inData, DAEMODE_DATA* daeModeData){ return -1; }
#ifdef __cplusplus
}
#endif<%\n%>
>>
end match
end simulationFile_dae;

Expand Down Expand Up @@ -940,12 +997,10 @@ template simulationFile(SimCode simCode, String guid, Boolean isModelExchangeFMU
<%symbolName(modelNamePrefixStr,"initialLinearSystem")%>,
<%symbolName(modelNamePrefixStr,"initialMixedSystem")%>,
<%symbolName(modelNamePrefixStr,"initializeStateSets")%>,
<%symbolName(modelNamePrefixStr,"initializeDAEmodeData")%>,
<%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 @@ -1181,9 +1236,6 @@ template populateModelInfo(ModelInfo modelInfo, String fileNamePrefix, String gu
data->modelData->nClocks = <%nClocks%>;
data->modelData->nSubClocks = <%nSubClocks%>;

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

data->modelData->nSensitivityVars = <%listLength(vars.sensitivityVars)%>;
data->modelData->nSensitivityParamVars = <%varInfo.numSensitivityParameters%>;
>>
Expand Down Expand Up @@ -1278,11 +1330,6 @@ template variableDefinitions(ModelInfo modelInfo, list<BackendDAE.TimeEvent> tim
globalDataVarDefine(var, "realVars")
;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 @@ -3760,7 +3807,7 @@ template evaluateDAEResiduals(list<list<SimEqSystem>> resEquations, String model
<%systems%>
/* for residuals DAE variables */
int <%symbolName(modelNamePrefix,"evaluateDAEResiduals")%>(DATA *data, threadData_t *threadData)
int <%symbolName(modelNamePrefix,"evaluateDAEResiduals")%>(DATA *data, threadData_t *threadData, double* residualVars)
{
TRACE_PUSH
data->simulationInfo->callStatistics.functionEvalDAE++;
Expand Down Expand Up @@ -3811,6 +3858,61 @@ template algebraicDAEVar(list<SimVar> algVars, String modelNamePrefix)
>>
end algebraicDAEVar;
template initializeDAEmodeData(Integer nResVars, Integer nAlgVars, list<tuple<Integer,list<Integer>>> sparsepattern, list<list<Integer>> colorList, Integer maxColor, String modelNamePrefix)
"Generates initialization function for daeMode."
::=
let sizeCols = listLength(sparsepattern)
let sizeNNZ = lengthListElements(unzipSecond(sparsepattern))
let colPtr = genSPCRSPtr(listLength(sparsepattern), sparsepattern, "colPtrIndex")
let rowIndex = genSPCRSRows(lengthListElements(unzipSecond(sparsepattern)), sparsepattern, "rowIndex")
let colorString = genSPColors(colorList, "daeModeData->sparsePattern->colorCols")
let maxColorStr = '<%maxColor%>'
<<
/* initialize the daeMode variables */
int <%symbolName(modelNamePrefix,"initializeDAEmodeData")%>(DATA *inData, DAEMODE_DATA* daeModeData)
{
TRACE_PUSH
DATA* data = ((DATA*)inData);
/* sparse patterns */
<%colPtr%>
<%rowIndex%>
int i = 0;
daeModeData->nResidualVars = <%nResVars%>;
daeModeData->nAlgebraicDAEVars = <%nAlgVars%>;
daeModeData->residualVars = (double*) malloc(sizeof(double)*<%nResVars%>);
/* set the function pointer */
daeModeData->evaluateDAEResiduals = <%symbolName(modelNamePrefix,"evaluateDAEResiduals")%>;
daeModeData->setAlgebraicDAEVars = <%symbolName(modelNamePrefix,"setAlgebraicDAEVars")%>;
daeModeData->getAlgebraicDAEVars = <%symbolName(modelNamePrefix,"getAlgebraicDAEVars")%>;
/* intialize sparse pattern */
daeModeData->sparsePattern = (SPARSE_PATTERN*) malloc(sizeof(SPARSE_PATTERN));
daeModeData->sparsePattern->leadindex = (unsigned int*) malloc((<%sizeCols%>+1)*sizeof(int));
daeModeData->sparsePattern->index = (unsigned int*) malloc(<%sizeNNZ%>*sizeof(int));
daeModeData->sparsePattern->numberOfNoneZeros = <%sizeNNZ%>;
daeModeData->sparsePattern->colorCols = (unsigned int*) malloc(<%sizeCols%>*sizeof(int));
daeModeData->sparsePattern->maxColors = <%maxColorStr%>;
/* write lead index of compressed sparse column */
memcpy(daeModeData->sparsePattern->leadindex, colPtrIndex, (1+<%sizeCols%>)*sizeof(int));
/* makek CRS compatible */
for(i=2;i<=<%sizeCols%>;++i)
daeModeData->sparsePattern->leadindex[i] += daeModeData->sparsePattern->leadindex[i-1];
/* call sparse index */
memcpy(daeModeData->sparsePattern->index, rowIndex, <%sizeNNZ%>*sizeof(int));
/* write color array */
<%colorString%>
TRACE_POP
return 0;
}
>>
end initializeDAEmodeData;
template functionDAE(list<SimEqSystem> allEquationsPlusWhen, String modelNamePrefix)
"Generates function in simulation file.
This is a helper of template simulationFile."
Expand Down Expand Up @@ -4459,6 +4561,49 @@ template functionJac(list<SimEqSystem> jacEquations, list<SimVar> tmpVars, Strin
>>
end functionJac;

// function for sparsity pattern generation
template genSPCRSPtr(Integer sizeColPtr, list<tuple<Integer,list<Integer>>> sparsepattern, String constArrayName)
"This template generates colPtr of the CRS format"
::=
let colPtrindex = (sparsepattern |> (i, indexes) =>
<<
<%listLength(indexes)%>
>>
;separator=",")
<<
const int <%constArrayName%>[1+<%sizeColPtr%>] = {0,<%colPtrindex%>};
>>
end genSPCRSPtr;

template genSPCRSRows(Integer nonZeroElems, list<tuple<Integer,list<Integer>>> sparsepattern, String constArrayName)
"This template generates row of the CRS format"
::=
let rowsIndex = ( sparsepattern |> (i, indexes) hasindex index0 =>
( indexes |> indexrow =>
<<
<%indexrow%>
>>
;separator=",")
;separator=",")
<<
const int <%constArrayName%>[<%nonZeroElems%>] = {<%rowsIndex%>};
>>
end genSPCRSRows;

template genSPColors(list<list<Integer>> colorList, String arrayName)
"This template generates row of the CRS format"
::=
let colorArray = (colorList |> (indexes) hasindex index0 =>
let colorCol = ( indexes |> i_index =>
<<<%arrayName%>[<%i_index%>] = <%intAdd(index0,1)%>;>>
;separator="\n")
'<%colorCol%>'
;separator="\n")
<<
<%colorArray%>
>>
end genSPColors;

template equation_arrayFormat(SimEqSystem eq, String name, Context context, Integer arrayIndex, Text &eqArray, Text &eqfuncs, String modelNamePrefix)
"Generates an equation.
This template should not be used for a SES_RESIDUAL.
Expand Down
8 changes: 5 additions & 3 deletions Compiler/Template/SimCodeTV.mo
Expand Up @@ -314,7 +314,7 @@ package SimCode
HashTableCrIListArray.HashTable varToArrayIndexMapping;
Option<FmiModelStructure> modelStructure;
PartitionData partitionData;
DaeModeDate daeModeDate;
Option<DaeModeData> daeModeData;
end SIMCODE;
end SimCode;

Expand Down Expand Up @@ -613,13 +613,15 @@ package SimCode
end VARINFO;
end VarInfo;

uniontype DaeModeDate
uniontype DaeModeData
"contains data that belongs to the dae mode"
record DAEMODEDATA
list<list<SimEqSystem>> daeEquations "daeModel residuals equations";
Option<JacobianMatrix> sparsityPattern "contains the sparsity pattern for the daeMode";
list<SimCodeVar.SimVar> residualVars; // variable used to calculate residuals of a DAE form, they are real
list<SimCodeVar.SimVar> algebraicDAEVars; // variable used to calculate residuals of a DAE form, they are real
end DAEMODEDATA;
end DaeModeDate;
end DaeModeData;

uniontype Function
record FUNCTION
Expand Down
17 changes: 8 additions & 9 deletions SimulationRuntime/c/openmodelica_func.h
Expand Up @@ -95,6 +95,14 @@ void (*initialMixedSystem)(int nMixedSystems, MIXED_SYSTEM_DATA *data);
*/
void (*initializeStateSets)(int nStateSets, STATE_SET_DATA* statesetData, DATA *data);

/*! \fn initializeDAEmodeData
*
* This function to initialize the daeMode data structure in Data
*
* \param [ref] [data]
*/
int (*initializeDAEmodeData)(DATA *data, DAEMODE_DATA* daeModeData);

/* functionODE contains those equations that are needed
* to calculate the dynamic part of the system */
int (*functionODE)(DATA *data, threadData_t*);
Expand All @@ -107,15 +115,6 @@ 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
18 changes: 9 additions & 9 deletions SimulationRuntime/c/simulation/solver/dassl.c
Expand Up @@ -141,7 +141,7 @@ int dassl_initial(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo,
{
dasslData->daeMode = 1;
dasslData->residualFunction = functionDAE_residual;
N = data->modelData->nStates + data->modelData->nAlgebraicDAEVars;
N = data->modelData->nStates + data->simulationInfo->daeModeData->nAlgebraicDAEVars;
NDAE = N;
}
else
Expand Down Expand Up @@ -546,7 +546,7 @@ int dassl_step(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo)
if (dasslData->daeMode)
{
memcpy(states, data->localData[0]->realVars, sizeof(double)*data->modelData->nStates);
data->callback->getAlgebraicDAEVars(data, threadData, states + data->modelData->nStates);
data->simulationInfo->daeModeData->getAlgebraicDAEVars(data, threadData, states + data->modelData->nStates);
memcpy(stateDer, data->localData[1]->realVars + data->modelData->nStates, sizeof(double)*data->modelData->nStates);
}
}
Expand Down Expand Up @@ -666,7 +666,7 @@ int dassl_step(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo)
if (dasslData->daeMode)
{
memcpy(data->localData[0]->realVars, states, sizeof(double)*data->modelData->nStates);
data->callback->setAlgebraicDAEVars(data, threadData, states + data->modelData->nStates);
data->simulationInfo->daeModeData->setAlgebraicDAEVars(data, threadData, states + data->modelData->nStates);
memcpy(data->localData[0]->realVars + data->modelData->nStates, stateDer, sizeof(double)*data->modelData->nStates);
}
else
Expand Down Expand Up @@ -878,7 +878,7 @@ int functionDAE_residual(double *t, double *y, double *yd, double* cj, double *d

memcpy(data->localData[0]->realVars, y, sizeof(double)*data->modelData->nStates);
memcpy(data->localData[0]->realVars + data->modelData->nStates, yd, sizeof(double)*data->modelData->nStates);
data->callback->setAlgebraicDAEVars(data, threadData, y + data->modelData->nStates);
data->simulationInfo->daeModeData->setAlgebraicDAEVars(data, threadData, y + data->modelData->nStates);

saveJumpState = threadData->currentErrorStage;
threadData->currentErrorStage = ERROR_INTEGRATOR;
Expand All @@ -893,14 +893,14 @@ int functionDAE_residual(double *t, double *y, double *yd, double* cj, double *d
data->callback->input_function(data, threadData);

/* eval residual vars */
data->callback->evaluateDAEResiduals(data, threadData);
data->simulationInfo->daeModeData->evaluateDAEResiduals(data, threadData);

/* get data->simulationInfo->residualVars */
for(i=0; i < data->modelData->nResidualVars; i++)
for(i=0; i < data->simulationInfo->daeModeData->nResidualVars; i++)
{
delta[i] = data->simulationInfo->residualVars[i];
delta[i] = data->simulationInfo->daeModeData->residualVars[i];
}
printVector(LOG_DASSL_STATES, "residual", delta, data->modelData->nResidualVars, *t);
printVector(LOG_DASSL_STATES, "residual", delta, data->simulationInfo->daeModeData->nResidualVars, *t);
success = 1;
#if !defined(OMC_EMCC)
MMC_CATCH_INTERNAL(simulationJumpBuffer)
Expand Down Expand Up @@ -948,7 +948,7 @@ int function_ZeroCrossingsDASSL(int *neqm, double *t, double *y, double *yp,
{
memcpy(data->localData[0]->realVars, y, sizeof(double)*data->modelData->nStates);
memcpy(data->localData[0]->realVars + data->modelData->nStates, yp, sizeof(double)*data->modelData->nStates);
data->callback->setAlgebraicDAEVars(data, threadData, y + data->modelData->nStates);
data->simulationInfo->daeModeData->setAlgebraicDAEVars(data, threadData, y + data->modelData->nStates);
}

/* read input vars */
Expand Down

0 comments on commit 7ef8873

Please sign in to comment.