Skip to content

Commit

Permalink
Adapted clock handling in cpp runtime
Browse files Browse the repository at this point in the history
- clocks are implemented with zero crossing functions instead of time events
  • Loading branch information
niklwors committed Jun 20, 2016
1 parent 3829472 commit ddf5050
Show file tree
Hide file tree
Showing 17 changed files with 177 additions and 82 deletions.
2 changes: 2 additions & 0 deletions Compiler/SimCode/SimCode.mo
Expand Up @@ -144,7 +144,9 @@ end ClockedPartition;

public uniontype SubPartition
record SUBPARTITION
Integer idx; //a unique index among all subpartitions
list<tuple<SimCodeVar.SimVar, Boolean /*previous*/>> vars;
list<SimEqSystem> previousAssignments; //equations to assign the $CLKPRE_* variables
list<SimEqSystem> equations;
list<SimEqSystem> removedEquations;
BackendDAE.SubClock subClock;
Expand Down
15 changes: 11 additions & 4 deletions Compiler/SimCode/SimCodeUtil.mo
Expand Up @@ -662,7 +662,7 @@ algorithm

prevClockedVars := {};
isPrevVar := arrayCreate(BackendVariable.varsSize(syst.orderedVars), false);

preEquations := {};
for cr in subPartition.prevVars loop
(_, varIxs) := BackendVariable.getVar(cr, syst.orderedVars);
for i in varIxs loop
Expand All @@ -679,13 +679,13 @@ algorithm
simVar.name := ComponentReference.crefPrefixPrevious(cr);
clockedVars := simVar::clockedVars;
simEq := SimCode.SES_SIMPLE_ASSIGN(ouniqueEqIndex, simVar.name, DAE.CREF(cr, simVar.type_), DAE.emptyElementSource);
equations := simEq::equations;
preEquations := simEq::preEquations;
ouniqueEqIndex := ouniqueEqIndex + 1;
end if;
end for;

//otempvars := listAppend(clockedVars, otempvars);
simSubPartition := SimCode.SUBPARTITION(prevClockedVars, equations, removedEquations, subPartition.clock, subPartition.holdEvents);
simSubPartition := SimCode.SUBPARTITION(subPartIdx,prevClockedVars, preEquations, equations, removedEquations, subPartition.clock, subPartition.holdEvents);

assert(isNone(simSubPartitions[subPartIdx]), "SimCodeUtil.translateClockedEquations failed");
arrayUpdate(simSubPartitions, subPartIdx, SOME(simSubPartition));
Expand Down Expand Up @@ -7818,7 +7818,7 @@ algorithm
simVars := List.map(subPart.vars,Util.tuple21);
arePrevious := List.map(subPart.vars,Util.tuple22);
simVarStrings := List.threadMap(List.map(simVars,simVarString), List.map(arePrevious,previousString),stringAppend);
str := "SubPartition Vars:\n"+UNDERLINE+"\n";
str := "SubPartition "+intString(subPart.idx)+"\nVars:\n"+UNDERLINE+"\n";
str := str + stringDelimitList(simVarStrings,"\n")+"\n";
str := str + "partition equations:\n"+UNDERLINE+"\n";
str := str + stringDelimitList(List.map(subPart.equations,simEqSystemString),"\n");
Expand Down Expand Up @@ -12876,5 +12876,12 @@ algorithm
end match;
end getInputIndex;

public function getSubPartitionIdx
input SimCode.SubPartition sub;
output Integer idx;
algorithm
idx := sub.idx;
end getSubPartitionIdx;

annotation(__OpenModelica_Interface="backend");
end SimCodeUtil;
4 changes: 2 additions & 2 deletions Compiler/Template/CodegenC.tpl
Expand Up @@ -372,8 +372,8 @@ template functionSystemsSynchronous(list<SubPartition> subPartitions, String mod
::=
let systs = subPartitions |> subPartition hasindex i =>
match subPartition
case SUBPARTITION(__) then
functionEquationsSynchronous(i, vars, listAppend(equations, removedEquations), modelNamePrefix)
case SUBPARTITION(equations=equations, previousAssignments=preveequations) then
functionEquationsSynchronous(i, vars, listAppend(listAppend(previousAssignments,equations), removedEquations), modelNamePrefix)
; separator = "\n"
let cases = subPartitions |> subPartition hasindex i =>
let name = 'functionEquationsSynchronous_system<%i%>'
Expand Down
126 changes: 98 additions & 28 deletions Compiler/Template/CodegenCpp.tpl
Expand Up @@ -3704,7 +3704,7 @@ match simCode
_dimZeroFunc = <%zeroCrossLength(simCode)%>;
_dimClock = <%listLength(getSubPartitions(clockedPartitions))%>;
// simplified treatment of clocks in model as time events
_dimTimeEvent = <%timeEventLength(simCode)%> + _dimClock;
_dimTimeEvent = <%timeEventLength(simCode)%> ;
//Number of residues
_event_handling= shared_ptr<EventHandling>(new EventHandling());
initializeAlgloopSolverVariables(); //if we do not initialize it here, we get a segfault in the destructor if initialization of Solver or OMFactory has failed
Expand Down Expand Up @@ -6829,7 +6829,7 @@ case SIMCODE(__) then
<<
<%equationFunctions(allEquations, simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace,contextSimulationDiscrete,stateDerVectorName,useFlatArrayNotation,boolNot(stringEq(getConfigString(PROFILING_LEVEL),"none")))%>

<%clockedFunctions(getSubPartitions(clockedPartitions), simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, contextSimulationDiscrete, stateDerVectorName, useFlatArrayNotation, boolNot(stringEq(getConfigString(PROFILING_LEVEL), "none")))%>
<%clockedFunctions(clockedPartitions, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, contextSimulationDiscrete, stateDerVectorName, useFlatArrayNotation, boolNot(stringEq(getConfigString(PROFILING_LEVEL), "none")))%>

<%createEvaluateAll(allEquations, simCode , &extraFuncs , &extraFuncsDecl, extraFuncsNamespace,contextOther, stateDerVectorName, useFlatArrayNotation, boolNot(stringEq(getConfigString(PROFILING_LEVEL),"none")))%>

Expand Down Expand Up @@ -7260,11 +7260,11 @@ template generateClockedFuncDecls(list<SubPartition> subPartitions, Text method)
let decls = (subPartitions |> subPartition hasindex i fromindex 1 =>
match subPartition case SUBPARTITION(__) then
<<
/// Clocked partition <%i%>
void evaluateClocked<%i%>(const UPDATETYPE command);
/// Clocked partition <%getSubPartitionIdx(subPartition)%>
void evaluateClocked<%getSubPartitionIdx(subPartition)%>(const UPDATETYPE command);
void evaluateClockedAssignPrevious<%getSubPartitionIdx(subPartition)%>(const UPDATETYPE command);


<%generateEquationMemberFuncDecls(listAppend(equations, removedEquations), method)%>
<%generateEquationMemberFuncDecls(listAppend(listAppend(previousAssignments,equations), removedEquations), method)%>
>>
; separator="\n")
'<%decls%>'
Expand Down Expand Up @@ -9815,8 +9815,13 @@ case SIMCODE(modelInfo = MODELINFO(__), modelStructure = fmims) then
<%preExp%>
_clockInterval[<%i%>] = <%interval%> * <%fnom%>.0 / <%fres%>.0;
_clockShift[<%i%>] = <%snom%>.0 / <%sres%>.0;
_clockTime[<%i%>] = _simTime + _clockShift[<%i%>] * _clockInterval[<%i%>];
_clockStart[<%i%>] = true;
_clockTime[<%i%>] = _simTime + _clockShift[<%i%>] * _clockInterval[<%i%>];
if( _clockShift[<%i%>]>0)
_clockCondition[<%i%>] = false;
else
_clockCondition[<%i%>] =true;
_clockStart[<%i%>] = true;

<%i%> ++;
>>
; separator="\n")
Expand Down Expand Up @@ -10510,9 +10515,11 @@ template generateTimeEvent(list<BackendDAE.TimeEvent> timeEvents, SimCode simCod
>>
else ''
;separator="\n\n")%>
// simplified treatment of clocks in model as time events
/* temporary deactivated: using state events for clocks
// simplified treatment of clocks in model as time events
for (int i = 0; i < _dimClock; i++)
time_events.push_back(std::make_pair(_clockShift[i] * _clockInterval[i], _clockInterval[i]));
*/
}
>>
end generateTimeEvent;
Expand Down Expand Up @@ -12449,13 +12456,24 @@ template handleSystemEvents(list<ZeroCrossing> zeroCrossings, SimCode simCode ,T
<<
bool <%lastIdentOfPath(modelInfo.name)%>Mixed::handleSystemEvents(bool* events)
{
_callType = IContinuous::DISCRETE;

bool restart = true;
bool state_vars_reinitialized = false;
bool clock_event_detected = false;

int iter = 0;
for(int i =0;i< _dimClock;i++)
{
if(events[_dimZeroFunc+i] )
{
if(_simTime +1e-9 > _clockTime[i])
_clockCondition[i]=true;
clock_event_detected = true;
evaluateAll();
}
}

if (clock_event_detected) return false;// no event iteration after clock tick handling
_callType = IContinuous::DISCRETE;
while(restart && !(iter++ > 100))
{
bool st_vars_reinit = false;
Expand Down Expand Up @@ -12502,7 +12520,14 @@ template giveZeroFunc1(list<ZeroCrossing> zeroCrossings,SimCode simCode ,Text& e
<%varDecls%>
<%prexp%>
<%zeroCrossingsCode%>
for(int i =0;i<_dimClock;i++)
{

if((_simTime>0.0) && (_simTime < _clockTime[i]))
f[i+_dimZeroFunc]= (_simTime - _clockTime[i])- 1e-9;
else
f[i+_dimZeroFunc]=1.0;
}

}
>>
Expand Down Expand Up @@ -12709,26 +12734,39 @@ template equationFunctions(list<SimEqSystem> allEquationsPlusWhen, SimCode simCo
>>
end equationFunctions;

template clockedFunctions(list<SubPartition> subPartitions, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Context context, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation, Boolean enableMeasureTime)
template clockedFunctions(list<ClockedPartition> clockedPartitions, SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Context context, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation, Boolean enableMeasureTime)
"Evaluate clocked synchronous equations"
::=
let className = lastIdentOfPathFromSimCode(simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace)


/*
let parts = subPartitions |> subPartition hasindex i fromindex 1 =>
match subPartition
case SUBPARTITION(__) then
clockedPartFunctions(i, vars, listAppend(equations, removedEquations), simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, contextSimulationDiscrete, stateDerVectorName, useFlatArrayNotation, enableMeasureTime)
clockedPartFunctions(i, vars, listAppend(equations, removedEquations), subPartition,simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, contextSimulationDiscrete, stateDerVectorName, useFlatArrayNotation, enableMeasureTime)
; separator = "\n"
*/
let parts =
(clockedPartitions |> partition hasindex i fromindex 1 =>
match partition
case CLOCKED_PARTITION(baseClock=clock) then

let subClocks = (subPartitions |> subPartition hasindex j fromindex 1 =>
match subPartition
case SUBPARTITION(idx=idx, subClock=SUBCLOCK(factor=RATIONAL(nom=fnom, denom=fres), shift=RATIONAL(nom=snom, denom=sres))) then
clockedPartFunctions(idx, previousAssignments, listAppend(equations, removedEquations), clock,subClock,simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, contextSimulationDiscrete, stateDerVectorName, useFlatArrayNotation, enableMeasureTime)
; separator="\n")
<<
<%subClocks%>
>>
; separator="\n")




let cases = subPartitions |> subPartition hasindex i fromindex 1 =>
let cases = getSubPartitions(clockedPartitions) |> subPartition hasindex i fromindex 1 =>
<<
case <%i%>:
evaluateClocked<%i%>(IContinuous::UNDEF_UPDATE);
case <%getSubPartitionIdx(subPartition)%>:
evaluateClocked<%getSubPartitionIdx(subPartition)%>(IContinuous::UNDEF_UPDATE);
break;
>>; separator = "\n"
<<
Expand All @@ -12748,13 +12786,31 @@ template clockedFunctions(list<SubPartition> subPartitions, SimCode simCode, Te
>>
end clockedFunctions;

template clockedPartFunctions(Integer i, list<tuple<SimCodeVar.SimVar, Boolean>> vars, list<SimEqSystem> equations,SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Context context, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation, Boolean enableMeasureTime)
template clockedPartFunctions(Integer i, list<SimEqSystem> previousAssignments, list<SimEqSystem> equations,DAE.ClockKind baseClock,BackendDAE.SubClock subClock,SimCode simCode, Text& extraFuncs, Text& extraFuncsDecl, Text extraFuncsNamespace, Context context, Text stateDerVectorName /*=__zDot*/, Boolean useFlatArrayNotation, Boolean enableMeasureTime)
"Evaluate functions that belong to a clocked partition"
::=
let className = lastIdentOfPathFromSimCode(simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace)
let funcs = equations |> eq =>
let &preExp = buffer "" /*BUFD*/
let &varDecls = buffer "" /*BUFD*/
let intvl = daeExp(getClockInterval(baseClock), contextOther, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl,extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
let idx = intAdd(i, -1)
let clockvals = match subClock
case SUBCLOCK(factor=RATIONAL(nom=fnom, denom=fres), shift=RATIONAL(nom=snom, denom=sres))
then
<<
_clockInterval[<%idx%>] = <%intvl%> * <%fnom%>.0 / <%fres%>.0;
_clockTime[<%idx%>] = _simTime +_clockInterval[<%idx%>] ;
>>

let funcs = listAppend(previousAssignments,equations) |> eq =>
equation_function_create_single_func(eq, context/*BUFC*/, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, "evaluate", "", stateDerVectorName, useFlatArrayNotation, enableMeasureTime, false, false, 'const int clockIndex = <%i%>;<%\n%>')
; separator="\n"

let funcNamePrev = 'evaluateClockedAssignPrevious<%i%>'
let funcCallsPrev = (List.partition(previousAssignments, 100) |> eqs hasindex i0 =>
createEvaluateWithSplit(i0, context, eqs, funcNamePrev, className, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace)
; separator="\n")

let funcName = 'evaluateClocked<%i%>'
let funcCalls = (List.partition(equations, 100) |> eqs hasindex i0 =>
createEvaluateWithSplit(i0, context, eqs, funcName, className, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace)
Expand All @@ -12765,14 +12821,20 @@ template clockedPartFunctions(Integer i, list<tuple<SimCodeVar.SimVar, Boolean>>

void <%className%>::<%funcName%>(const UPDATETYPE command)
{
if (_simTime > _clockTime[<%idx%>]) {

<%varDecls%>
<%preExp%>
if (_simTime > _clockTime[<%idx%>]) {
_clockStart[<%idx%>] = false;
}
<%funcCalls%>
if (_simTime > _clockTime[<%idx%>]) {
_clockInterval[<%idx%>] = _simTime - _clockTime[<%idx%>];
_clockTime[<%idx%>] = _simTime;
}
//evaluate clock partition equations
<%funcCalls%>

//compute new clock tick
<%clockvals%>

//assign the previous-vars since the step is completed
<%funcCallsPrev%>
}
>>
end clockedPartFunctions;
Expand Down Expand Up @@ -12805,13 +12867,21 @@ end createEvaluateAll;
template createTimeConditionTreatments(String numberOfTimeEvents)
::=
<<

/*temporary deactivated: treatment of clocks in model as state events
// treatment of clocks in model as time events
for (int i = <%numberOfTimeEvents%>; i < _dimTimeEvent; i++) {
if (_time_conditions[i]) {
evaluateClocked(i - <%numberOfTimeEvents%> + 1);
_time_conditions[i] = false; // reset clock after one evaluation

}
}
*/
for (int i = 0; i < _dimClock; i++)
{
if( _clockCondition[i])
{
evaluateClocked(i+1);
_clockCondition[i] = false;// reset clock after one evaluation
}
}
>>
Expand Down
2 changes: 1 addition & 1 deletion Compiler/Template/CodegenCppCommon.tpl
Expand Up @@ -1702,7 +1702,7 @@ template daeExpCall(Exp call, Context context, Text &preExp /*BUFP*/, Text &varD
'_clockInterval[clockIndex - 1]'

case CALL(path=IDENT(name="$_clkfire"), expLst={arg as ICONST(__)}) then
'_time_conditions[<%arg.integer%> - 1 + <%timeEventLength(simCode)%>] = (_simTime > _clockTime[<%arg.integer%> - 1])'
'_clockCondition[<%arg.integer%> - 1 + <%timeEventLength(simCode)%>] = (_simTime > _clockTime[<%arg.integer%> - 1])'

case CALL(path=IDENT(name="$getPart"), expLst={e1}) then
daeExp(e1, context, &preExp, &varDecls, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, stateDerVectorName, useFlatArrayNotation)
Expand Down
2 changes: 1 addition & 1 deletion Compiler/Template/CodegenCppHpcom.tpl
Expand Up @@ -754,7 +754,7 @@ template updateHpcom(list<SimEqSystem> allEquationsPlusWhen, SimCode simCode, Te

<%createEvaluateConditions(allEquations, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, contextOther, stateDerVectorName, useFlatArrayNotation)%>

<%clockedFunctions(getSubPartitions(clockedPartitions), simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, contextSimulationDiscrete, stateDerVectorName, useFlatArrayNotation, boolNot(stringEq(getConfigString(PROFILING_LEVEL), "none")))%>
<%clockedFunctions(clockedPartitions, simCode, &extraFuncs, &extraFuncsDecl, extraFuncsNamespace, contextSimulationDiscrete, stateDerVectorName, useFlatArrayNotation, boolNot(stringEq(getConfigString(PROFILING_LEVEL), "none")))%>

<%parCode%>

Expand Down
7 changes: 7 additions & 0 deletions Compiler/Template/SimCodeTV.mo
Expand Up @@ -337,7 +337,9 @@ package SimCode

uniontype SubPartition
record SUBPARTITION
Integer idx; //a unique index among all subpartitions
list<tuple<SimCodeVar.SimVar, Boolean>> vars;
list<SimEqSystem> previousAssignments;
list<SimEqSystem> equations;
list<SimEqSystem> removedEquations;
BackendDAE.SubClock subClock;
Expand Down Expand Up @@ -879,6 +881,11 @@ package SimCodeUtil
output list<SimCode.SubPartition> outSubPartitions;
end getSubPartitions;

function getSubPartitionIdx
input SimCode.SubPartition sub;
output Integer idx;
end getSubPartitionIdx;

function getClockIndex
input SimCodeVar.SimVar simVar;
input SimCode.SimCode simCode;
Expand Down
7 changes: 2 additions & 5 deletions SimulationRuntime/cpp/Core/SimController/Initialization.cpp
Expand Up @@ -22,9 +22,7 @@ void Initialization::initializeSystem()
shared_ptr<IContinuous> continous_system = dynamic_pointer_cast<IContinuous>(_system);
shared_ptr<IEvent> event_system = dynamic_pointer_cast<IEvent>(_system);
shared_ptr<IMixedSystem> mixed_system = dynamic_pointer_cast<IMixedSystem>(_system);
int dim = event_system->getDimZeroFunc();
bool* conditions0 = new bool[dim];
bool* conditions1 = new bool[dim];


_system->setInitial(true);
//Initialization of continous equations and bounded parameters
Expand Down Expand Up @@ -58,7 +56,6 @@ void Initialization::initializeSystem()
if(_solver->stateSelection())
cout << "Cannot initialize the dynamic state selection in an unique way." << std::endl;
}
delete[] conditions0;
delete[] conditions1;

}
/** @} */ // end of coreSimcontroller

0 comments on commit ddf5050

Please sign in to comment.