Skip to content
This repository has been archived by the owner on May 18, 2019. It is now read-only.

Commit

Permalink
[DAEmode] reduce generated code for algebraic variables
Browse files Browse the repository at this point in the history
 - store algebraic variable indices in static array
 - move get/set AlgebricDAEVar functions to runtime

Belonging to [master]:
  - #2359
  • Loading branch information
Willi Braun authored and OpenModelica-Hudson committed Apr 12, 2018
1 parent f6ef4b2 commit 7a3a58f
Show file tree
Hide file tree
Showing 6 changed files with 84 additions and 76 deletions.
75 changes: 17 additions & 58 deletions Compiler/Template/CodegenC.tpl
Expand Up @@ -890,7 +890,7 @@ template simulationFile_dae(SimCode simCode)
let initDAEmode =
match sparsityPattern
case SOME(JAC_MATRIX(sparsity=sparse, coloredCols=colorList, maxColorCols=maxColor)) then
'<%initializeDAEmodeData(listLength(residualVars), listLength(algebraicVars), listLength(auxiliaryVars), sparse, colorList, maxColor, modelNamePrefixStr)%>'
'<%initializeDAEmodeData(listLength(residualVars), algebraicVars, listLength(auxiliaryVars), sparse, colorList, maxColor, modelNamePrefixStr)%>'
case NONE() then
'int <%symbolName(modelNamePrefixStr,"initializeDAEmodeData")%>(DATA *inData, DAEMODE_DATA* daeModeData){ return -1; }'
end match
Expand All @@ -905,8 +905,6 @@ template simulationFile_dae(SimCode simCode)
<%evaluateDAEResiduals(daeEquations, modelNamePrefixStr)%>
<%algebraicDAEVar(algebraicVars, modelNamePrefixStr)%>
<%initDAEmode%>
#ifdef __cplusplus
Expand Down Expand Up @@ -4053,73 +4051,33 @@ template evaluateDAEResiduals(list<list<SimEqSystem>> resEquations, String model
>>
end evaluateDAEResiduals;
template algebraicDAEVar(list<SimVar> algVars, String modelNamePrefix)
"Generates function in simulation file."
template genVarIndexes(list<SimVar> vars, String arrayName)
"This template generates array with indexes of given variables."
::=
let forwardVars = (algVars |> var hasindex i fromindex 0 =>
let size = listLength(vars)
let varIndexes = ( vars |> var =>
(match var
case SIMVAR(__) then
'<%cref(name)%> = algebraic[<%i%>];'
'<%crefToIndex(name)%>'
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")
let nominalVars = (algVars |> var hasindex i fromindex 0 =>
(match var
case SIMVAR(__) then
<<
algebraicNominal[<%i%>] = <%crefAttributes(name)%>.nominal;
infoStreamPrint(LOG_SOLVER, 0, "%ld. %s -> %g", ++i, <%crefVarInfo(name)%>.name, algebraicNominal[<%i%>]);
>>
end match)
;separator="\n")
;separator=",")
<<
/* algebraic nominal values */
OMC_DISABLE_OPT
int <%symbolName(modelNamePrefix,"getAlgebraicDAEVarNominals")%>(DATA *data, threadData_t *threadData, double* algebraicNominal)
{
TRACE_PUSH
long i = data->modelData->nStates;
<%nominalVars%>
TRACE_POP
return 0;
}
/* forward algebraic variables */
OMC_DISABLE_OPT
int <%symbolName(modelNamePrefix,"setAlgebraicDAEVars")%>(DATA *data, threadData_t *threadData, double* algebraic)
{
TRACE_PUSH
<%forwardVars%>
TRACE_POP
return 0;
}
/* get algebraic variables */
OMC_DISABLE_OPT
int <%symbolName(modelNamePrefix,"getAlgebraicDAEVars")%>(DATA *data, threadData_t *threadData, double* algebraic)
{
TRACE_PUSH
<%getVars%>
TRACE_POP
return 0;
}
const int <%arrayName%>[<%size%>] = {<%varIndexes%>};
>>
end algebraicDAEVar;
end genVarIndexes;
template initializeDAEmodeData(Integer nResVars, Integer nAlgVars, Integer nAuxVars, list<tuple<Integer,list<Integer>>> sparsepattern, list<list<Integer>> colorList, Integer maxColor, String modelNamePrefix)
template initializeDAEmodeData(Integer nResVars, list<SimVar> algVars, Integer nAuxVars, list<tuple<Integer,list<Integer>>> sparsepattern, list<list<Integer>> colorList, Integer maxColor, String modelNamePrefix)
"Generates initialization function for daeMode."
::=
let nAlgVars = listLength(algVars)
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%>'
let algIndexes = genVarIndexes(algVars, "algIndexes")
<<
/* initialize the daeMode variables */
OMC_DISABLE_OPT
Expand All @@ -4130,6 +4088,7 @@ template initializeDAEmodeData(Integer nResVars, Integer nAlgVars, Integer nAuxV
/* sparse patterns */
<%colPtr%>
<%rowIndex%>
<%algIndexes%>
int i = 0;
daeModeData->nResidualVars = <%nResVars%>;
Expand All @@ -4141,10 +4100,10 @@ template initializeDAEmodeData(Integer nResVars, Integer nAlgVars, Integer nAuxV
/* set the function pointer */
daeModeData->evaluateDAEResiduals = <%symbolName(modelNamePrefix,"evaluateDAEResiduals")%>;
daeModeData->setAlgebraicDAEVars = <%symbolName(modelNamePrefix,"setAlgebraicDAEVars")%>;
daeModeData->getAlgebraicDAEVars = <%symbolName(modelNamePrefix,"getAlgebraicDAEVars")%>;
daeModeData->getAlgebraicDAEVarNominals = <%symbolName(modelNamePrefix,"getAlgebraicDAEVarNominals")%>;
/* prepare algebraic indexes */
daeModeData->algIndexes = (int*) malloc(sizeof(int)*<%nAlgVars%>);
memcpy(daeModeData->algIndexes, algIndexes, <%nAlgVars%>*sizeof(int));
/* intialize sparse pattern */
daeModeData->sparsePattern = (SPARSE_PATTERN*) malloc(sizeof(SPARSE_PATTERN));
Expand Down
10 changes: 10 additions & 0 deletions Compiler/Template/CodegenCFunctions.tpl
Expand Up @@ -4134,6 +4134,16 @@ template crefToCStr(ComponentRef cr, Integer ix, Boolean isPre, Boolean isStart)
else "CREF_NOT_IDENT_OR_QUAL"
end crefToCStr;

template crefToIndex(ComponentRef cr)
"Helper function to cref."
::=
match cref2simvar(cr, getSimCode())
case SIMVAR(index=index)
then
'<%index%>'
else "CREF_NOT_FOUND"
end crefToIndex;

template crefToCStrDefine(ComponentRef cr)
"Helper function to cref."
::=
Expand Down
40 changes: 40 additions & 0 deletions SimulationRuntime/c/simulation/solver/dae_mode.c
Expand Up @@ -61,6 +61,46 @@ int evaluateDAEResiduals_wrapperEventUpdate(DATA* data, threadData_t* threadData
return retVal;
}

/*! \fn void getAlgebraicDAEVarNominals
*
* collects DAE mode algebraic nominal values from modelData
*/
void getAlgebraicDAEVarNominals(DATA* data, double *algebraicNominals)
{
int i;

DAEMODE_DATA* daeModeData = data->simulationInfo->daeModeData;
for(i=0; i < daeModeData->nAlgebraicDAEVars; i++){
algebraicNominals[i] = data->modelData->realVarsData[daeModeData->algIndexes[i]].attribute.nominal;
}
}

/*! \fn getAlgebraicVars
*
* function obtains algebraic variable values for DAEmode
*/
void getAlgebraicDAEVars(DATA *data, double* algebraic)
{
int i;
DAEMODE_DATA* daeModeData = data->simulationInfo->daeModeData;
for(i=0; i < daeModeData->nAlgebraicDAEVars; i++){
algebraic[i] = data->localData[0]->realVars[daeModeData->algIndexes[i]];
}
}

/*! \fn setAlgebraicVars
*
* function set algebraic variable values for DAEmode
*/
void setAlgebraicDAEVars(DATA *data, double* algebraic)
{
int i;
DAEMODE_DATA* daeModeData = data->simulationInfo->daeModeData;
for(i=0; i < daeModeData->nAlgebraicDAEVars; i++){
data->localData[0]->realVars[daeModeData->algIndexes[i]] = algebraic[i];
}
}

#ifdef __cplusplus
}
#endif
5 changes: 5 additions & 0 deletions SimulationRuntime/c/simulation/solver/dae_mode.h
Expand Up @@ -50,6 +50,11 @@ extern "C" {

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

void getAlgebraicDAEVarNominals(DATA*, double*);
void getAlgebraicDAEVars(DATA*, double*);
void setAlgebraicDAEVars(DATA*, double*);


#ifdef __cplusplus
}
#endif
Expand Down
20 changes: 10 additions & 10 deletions SimulationRuntime/c/simulation/solver/ida_solver.c
Expand Up @@ -174,7 +174,7 @@ ida_solver_initial(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo

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

idaData->y = N_VMake_Serial(idaData->N, idaData->states);
Expand Down Expand Up @@ -230,7 +230,7 @@ ida_solver_initial(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo
/* daeMode: set nominal values for algebraic variables */
if (idaData->daeMode)
{
data->simulationInfo->daeModeData->getAlgebraicDAEVarNominals(data, threadData, tmp + data->modelData->nStates);
getAlgebraicDAEVarNominals(data, tmp + data->modelData->nStates);
}
/* multiply by tolerance to obtain a relative tolerace */
for(i=0; i < idaData->N; ++i)
Expand Down Expand Up @@ -262,7 +262,7 @@ ida_solver_initial(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo
/* daeMode: set nominal values for algebraic variables */
if (idaData->daeMode)
{
data->simulationInfo->daeModeData->getAlgebraicDAEVarNominals(data, threadData, idaData->yScale + data->modelData->nStates);
getAlgebraicDAEVarNominals(data, idaData->yScale + data->modelData->nStates);
for(i=data->modelData->nStates; i < idaData->N; ++i)
{
idaData->ypScale[i] = 1.0;
Expand Down Expand Up @@ -702,12 +702,12 @@ ida_event_update(DATA* data, threadData_t *threadData)
data->simulationInfo->needToIterate = 0;

memcpy(idaData->states, data->localData[0]->realVars, sizeof(double)*data->modelData->nStates);
data->simulationInfo->daeModeData->getAlgebraicDAEVars(data, threadData, idaData->states + data->modelData->nStates);
getAlgebraicDAEVars(data, 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 */
evaluateDAEResiduals_wrapperEventUpdate(data, threadData);
data->simulationInfo->daeModeData->getAlgebraicDAEVars(data, threadData, idaData->states + data->modelData->nStates);
getAlgebraicDAEVars(data, idaData->states + data->modelData->nStates);

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

memcpy(data->localData[0]->realVars, idaData->states, sizeof(double)*data->modelData->nStates);
// and also algebraic vars
data->simulationInfo->daeModeData->setAlgebraicDAEVars(data, threadData, idaData->states + data->modelData->nStates);
setAlgebraicDAEVars(data, idaData->states + data->modelData->nStates);
memcpy(data->localData[0]->realVars + data->modelData->nStates, idaData->statesDer, sizeof(double)*data->modelData->nStates);

/* reset initial step size again to default */
Expand Down Expand Up @@ -809,7 +809,7 @@ ida_solver_step(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo)
{
memcpy(idaData->states, data->localData[0]->realVars, sizeof(double)*data->modelData->nStates);
/* and also algebraic vars */
data->simulationInfo->daeModeData->getAlgebraicDAEVars(data, threadData, idaData->states + data->modelData->nStates);
getAlgebraicDAEVars(data, idaData->states + data->modelData->nStates);
memcpy(idaData->statesDer, data->localData[0]->realVars + data->modelData->nStates, sizeof(double)*data->modelData->nStates);
}

Expand Down Expand Up @@ -1023,7 +1023,7 @@ ida_solver_step(DATA* data, threadData_t *threadData, SOLVER_INFO* solverInfo)
{
memcpy(data->localData[0]->realVars, idaData->states, sizeof(double)*data->modelData->nStates);
// and also algebraic vars
data->simulationInfo->daeModeData->setAlgebraicDAEVars(data, threadData, idaData->states + data->modelData->nStates);
setAlgebraicDAEVars(data, idaData->states + data->modelData->nStates);
memcpy(data->localData[0]->realVars + data->modelData->nStates, idaData->statesDer, sizeof(double)*data->modelData->nStates);
sData->timeValue = solverInfo->currentTime;
}
Expand Down Expand Up @@ -1164,7 +1164,7 @@ int residualFunctionIDA(double time, N_Vector yy, N_Vector yp, N_Vector res, voi
*/
memcpy(data->localData[0]->realVars, states, sizeof(double)*data->modelData->nStates);
memcpy(data->localData[0]->realVars + data->modelData->nStates, statesDer, sizeof(double)*data->modelData->nStates);
data->simulationInfo->daeModeData->setAlgebraicDAEVars(data, threadData, states + data->modelData->nStates);
setAlgebraicDAEVars(data, states + data->modelData->nStates);
}

/* debug */
Expand Down Expand Up @@ -1263,7 +1263,7 @@ int rootsFunctionIDA(double time, N_Vector yy, N_Vector yp, double *gout, void*
if (idaData->daeMode)
{
memcpy(data->localData[0]->realVars, states, sizeof(double)*data->modelData->nStates);
data->simulationInfo->daeModeData->setAlgebraicDAEVars(data, threadData, states + data->modelData->nStates);
setAlgebraicDAEVars(data, states + data->modelData->nStates);
memcpy(data->localData[0]->realVars + data->modelData->nStates, statesDer, sizeof(double)*data->modelData->nStates);
}

Expand Down
10 changes: 2 additions & 8 deletions SimulationRuntime/c/simulation_data.h
Expand Up @@ -437,14 +437,8 @@ typedef struct DAEMODE_DATA
/* function to evaluate dynamic equations for DAE solver*/
int (*evaluateDAEResiduals)(struct DATA*, threadData_t*, int);

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

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

/* function to get algebraic DAE nominal values*/
int (*getAlgebraicDAEVarNominals)(struct DATA*, threadData_t*, double*);
/* index of the algebraic DAE variable in original order */
int *algIndexes;

} DAEMODE_DATA;

Expand Down

0 comments on commit 7a3a58f

Please sign in to comment.