Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
niklwors committed Oct 19, 2015
2 parents 308ffab + 0c1e4fb commit f4f5eb0
Show file tree
Hide file tree
Showing 14 changed files with 266 additions and 508 deletions.
2 changes: 1 addition & 1 deletion Compiler/FrontEnd/Expression.mo
Expand Up @@ -1559,7 +1559,7 @@ algorithm
case DAE.REAL_CLOCK(e)
then e;
case DAE.INTEGER_CLOCK(e, res)
then DAE.BINARY(e, DAE.DIV(DAE.T_REAL_DEFAULT), DAE.ICONST(res));
then DAE.BINARY(e, DAE.DIV(DAE.T_REAL_DEFAULT), DAE.RCONST(res));
else
then DAE.RCONST(0.0);
end match;
Expand Down
1 change: 1 addition & 0 deletions Compiler/SimCode/SimCode.mo
Expand Up @@ -123,6 +123,7 @@ uniontype SimCode
//*** a protected section *** not exported to SimCodeTV
HashTableCrILst.HashTable varToIndexMapping;
HashTableCrefToSimVar crefToSimVarHT "hidden from typeview - used by cref2simvar() for cref -> SIMVAR lookup available in templates.";
HashTable.HashTable crefToClockIndexHT "map variables to clock indices";
Option<BackendMapping> backendMapping;
//FMI 2.0 data for model structure
Option<FmiModelStructure> modelStructure;
Expand Down
59 changes: 59 additions & 0 deletions Compiler/SimCode/SimCodeUtil.mo
Expand Up @@ -186,6 +186,7 @@ protected
SimCode.HashTableCrefToSimVar crefToSimVarHT;
SimCode.MakefileParams makefileParams;
SimCode.ModelInfo modelInfo;
HashTable.HashTable crefToClockIndexHT;
array<Integer> systemIndexMap;
list<BackendDAE.EqSystem> clockedSysts, contSysts;
//list<BackendDAE.Equation> paramAsserts, remEqLst;
Expand Down Expand Up @@ -384,6 +385,8 @@ algorithm
//BaseHashTable.dumpHashTable(varToArrayIndexMapping);
//print("END MAPPING\n\n");

crefToClockIndexHT := List.fold(inBackendDAE.eqs, collectClockedVars, HashTable.emptyHashTable());

simCode := SimCode.SIMCODE(modelInfo,
{}, // Set by the traversal below...
recordDecls,
Expand Down Expand Up @@ -421,6 +424,7 @@ algorithm
varToArrayIndexMapping,
varToIndexMapping,
crefToSimVarHT,
crefToClockIndexHT,
SOME(backendMapping),
modelStruct);

Expand Down Expand Up @@ -616,6 +620,61 @@ algorithm
end for;
end createClockedSimPartitions;

public function collectClockedVars "author: rfranke
This function collects clocked variables along with their clockIndex"
input BackendDAE.EqSystem inEqSystem;
input HashTable.HashTable inHT;
output HashTable.HashTable outHT;
protected
Integer clockIndex;
algorithm
outHT := match inEqSystem
case BackendDAE.EQSYSTEM(partitionKind = BackendDAE.CLOCKED_PARTITION(subPartIdx=clockIndex)) equation
(outHT, _) = BackendVariable.traverseBackendDAEVars(inEqSystem.orderedVars, collectClockedVars1, (inHT, clockIndex));
then outHT;
else inHT;
end match;
end collectClockedVars;

protected function collectClockedVars1 "author: rfranke
Helper to collectClockedVars"
input BackendDAE.Var inVar;
input tuple<HashTable.HashTable, Integer> inTpl;
output BackendDAE.Var outVar;
output tuple<HashTable.HashTable, Integer> outTpl;
protected
HashTable.HashTable clkHT;
Integer clockIndex;
DAE.ComponentRef cref;
algorithm
(clkHT, clockIndex) := inTpl;
(outVar, outTpl) := match inVar
case BackendDAE.VAR(varName=cref) equation
clkHT = BaseHashTable.add((cref, clockIndex), clkHT);
clkHT = BaseHashTable.add((ComponentReference.crefPrefixPrevious(cref), clockIndex), clkHT);
then (inVar, (clkHT, clockIndex));
else (inVar, inTpl);
end match;
end collectClockedVars1;

public function getClockIndex "author: rfranke
Returns the index of the clock of a variable or zero non-clocked variables"
input SimCodeVar.SimVar simVar;
input SimCode.SimCode simCode;
output Option<Integer> clockIndex;
protected
DAE.ComponentRef cref;
HashTable.HashTable clkHT;
algorithm
cref := getSimVarCompRef(simVar);
clockIndex := match simCode
case SimCode.SIMCODE(crefToClockIndexHT=clkHT) then
if BaseHashTable.hasKey(cref, clkHT)
then SOME(BaseHashTable.get(cref, clkHT))
else NONE();
end match;
end getClockIndex;

protected function getSimVarCompRef
input SimCodeVar.SimVar inVar;
output DAE.ComponentRef outComp;
Expand Down
2 changes: 2 additions & 0 deletions Compiler/Template/CodegenCppCommon.tpl
Expand Up @@ -96,6 +96,7 @@ template crefStrForWriteOutput(ComponentRef cr)
case CREF_IDENT(__) then '<%ident%><%subscriptsStrForWriteOutput(subscriptLst)%>'
// Are these even needed? Function context should only have CREF_IDENT :)
case CREF_QUAL(ident = "$DER") then 'der(<%crefStrForWriteOutput(componentRef)%>)'
case CREF_QUAL(ident = "$CLKPRE") then 'previous(<%crefStrForWriteOutput(componentRef)%>)'
case CREF_QUAL(__) then '<%ident%><%subscriptsStrForWriteOutput(subscriptLst)%>.<%crefStrForWriteOutput(componentRef)%>'
else "CREF_NOT_IDENT_OR_QUAL"
end crefStrForWriteOutput;
Expand All @@ -120,6 +121,7 @@ template crefStr(ComponentRef cr)
case CREF_IDENT(__) then '<%ident%><%subscriptsStr(subscriptLst)%>'
// Are these even needed? Function context should only have CREF_IDENT :)
case CREF_QUAL(ident = "$DER") then 'der(<%crefStr(componentRef)%>)'
case CREF_QUAL(ident = "$CLKPRE") then 'previous(<%crefStr(componentRef)%>)'
case CREF_QUAL(__) then '<%ident%><%subscriptsStr(subscriptLst)%>.<%crefStr(componentRef)%>'
else "CREF_NOT_IDENT_OR_QUAL"
end crefStr;
Expand Down
47 changes: 23 additions & 24 deletions Compiler/Template/CodegenFMUCommon.tpl
Expand Up @@ -75,60 +75,60 @@ case MODELINFO(vars=SIMVARS(stateVars=stateVars)) then
<ModelVariables>
<%System.tmpTickReset(0)%>
<%vars.stateVars |> var =>
ScalarVariable(simCode, stateVars, var, FMUVersion)
ScalarVariable(var, simCode, stateVars, FMUVersion)
;separator="\n"%>
<%vars.derivativeVars |> var =>
ScalarVariable(simCode, stateVars, var, FMUVersion)
ScalarVariable(var, simCode, stateVars, FMUVersion)
;separator="\n"%>
<%vars.algVars |> var =>
ScalarVariable(simCode, stateVars, var, FMUVersion)
ScalarVariable(var, simCode, stateVars, FMUVersion)
;separator="\n"%>
<%vars.discreteAlgVars |> var =>
ScalarVariable(simCode, stateVars, var, FMUVersion)
ScalarVariable(var, simCode, stateVars, FMUVersion)
;separator="\n"%>
<%vars.paramVars |> var =>
ScalarVariable(simCode, stateVars, var, FMUVersion)
ScalarVariable(var, simCode, stateVars, FMUVersion)
;separator="\n"%>
<%vars.aliasVars |> var =>
ScalarVariable(simCode, stateVars, var, FMUVersion)
ScalarVariable(var, simCode, stateVars, FMUVersion)
;separator="\n"%>
<%System.tmpTickReset(0)%>
<%vars.intAlgVars |> var =>
ScalarVariable(simCode, stateVars, var, FMUVersion)
ScalarVariable(var, simCode, stateVars, FMUVersion)
;separator="\n"%>
<%vars.intParamVars |> var =>
ScalarVariable(simCode, stateVars, var, FMUVersion)
ScalarVariable(var, simCode, stateVars, FMUVersion)
;separator="\n"%>
<%vars.intAliasVars |> var =>
ScalarVariable(simCode, stateVars, var, FMUVersion)
ScalarVariable(var, simCode, stateVars, FMUVersion)
;separator="\n"%>
<%System.tmpTickReset(0)%>
<%vars.boolAlgVars |> var =>
ScalarVariable(simCode, stateVars, var, FMUVersion)
ScalarVariable(var, simCode, stateVars, FMUVersion)
;separator="\n"%>
<%vars.boolParamVars |> var =>
ScalarVariable(simCode, stateVars, var, FMUVersion)
ScalarVariable(var, simCode, stateVars, FMUVersion)
;separator="\n"%>
<%vars.boolAliasVars |> var =>
ScalarVariable(simCode, stateVars, var, FMUVersion)
ScalarVariable(var, simCode, stateVars, FMUVersion)
;separator="\n"%>
<%System.tmpTickReset(0)%>
<%vars.stringAlgVars |> var =>
ScalarVariable(simCode, stateVars, var, FMUVersion)
ScalarVariable(var, simCode, stateVars, FMUVersion)
;separator="\n"%>
<%vars.stringParamVars |> var =>
ScalarVariable(simCode, stateVars, var, FMUVersion)
ScalarVariable(var, simCode, stateVars, FMUVersion)
;separator="\n"%>
<%vars.stringAliasVars |> var =>
ScalarVariable(simCode, stateVars, var, FMUVersion)
ScalarVariable(var, simCode, stateVars, FMUVersion)
;separator="\n"%>
<%System.tmpTickReset(0)%>
<%externalFunctions(modelInfo)%>
</ModelVariables>
>>
end fmiModelVariables;

template ScalarVariable(SimCode simCode, list<SimVar> stateVars, SimVar simVar, String FMUVersion)
template ScalarVariable(SimVar simVar, SimCode simCode, list<SimVar> stateVars, String FMUVersion)
"Generates code for ScalarVariable file for FMU target."
::=
match simVar
Expand All @@ -138,16 +138,13 @@ case SIMVAR(__) then
else if stringEq(crefStr(name),"der($dummy)") then
<<>>
else if isFMIVersion20(FMUVersion) then
//if intGt(getVariableIndex(simVar), 0) then
<<
<!-- Index of variable = "<%getVariableIndex(simVar)%>" -->
<ScalarVariable
<%ScalarVariableAttribute2(simCode, simVar)%>>
<%ScalarVariableAttribute2(simVar, simCode)%>>
<%ScalarVariableType2(simVar, stateVars)%>
</ScalarVariable>
>>
//else let valueReference = '<%System.tmpTick()%>'
//<<>>
else
<<
<ScalarVariable
Expand Down Expand Up @@ -436,24 +433,26 @@ template FmiUnknownDependenciesKind(list<String> dependenciesKind)
>>
end FmiUnknownDependenciesKind;

template ScalarVariableAttribute2(SimCode simCode, SimVar simVar)
template ScalarVariableAttribute2(SimVar simVar, SimCode simCode)
"Generates code for ScalarVariable Attribute file for FMU 2.0 target."
::=
match simVar
case SIMVAR(__) then
let valueReference = '<%System.tmpTick()%>'
let description = if comment then 'description="<%Util.escapeModelicaStringToXmlString(comment)%>"'
let variability = getVariability2(varKind, type_)
let variability = if getClockIndex(simVar, simCode) then "discrete" else getVariability2(varKind, type_)
let clockIndex = getClockIndex(simVar, simCode)
let previous = match varKind case CLOCKED_STATE(__) then '<%getVariableIndex(cref2simvar(previousName, simCode))%>'
let caus = getCausality2(causality, varKind, isValueChangeable)
let initial = getInitialType2(variability, caus, initialValue)
let previous = match varKind case CLOCKED_STATE(__) then '<%getVariableIndex(cref2simvar(previousName, simCode))%>'
<<
name="<%System.stringReplace(crefStrNoUnderscore(name),"$", "_D_")%>"
valueReference="<%valueReference%>"
<%if boolNot(stringEq(previous, "")) then 'previous="'+previous+'"' %>
<%description%>
variability="<%variability%>"
causality="<%caus%>"
<%if boolNot(stringEq(clockIndex, "")) then 'clockIndex="'+clockIndex+'"' %>
<%if boolNot(stringEq(previous, "")) then 'previous="'+previous+'"' %>
<%if boolNot(stringEq(initial, "")) then 'initial="'+initial+'"' %>
>>
end ScalarVariableAttribute2;
Expand Down
2 changes: 2 additions & 0 deletions Compiler/Template/CodegenUtil.tpl
Expand Up @@ -95,6 +95,7 @@ template crefStr(ComponentRef cr)
case CREF_IDENT(__) then '<%System.unquoteIdentifier(ident)%><%subscriptsStr(subscriptLst)%>'
// Are these even needed? Function context should only have CREF_IDENT :)
case CREF_QUAL(ident = "$DER") then 'der(<%crefStr(componentRef)%>)'
case CREF_QUAL(ident = "$CLKPRE") then 'previous(<%crefStr(componentRef)%>)'
case CREF_QUAL(__) then '<%System.unquoteIdentifier(ident)%><%subscriptsStr(subscriptLst)%>._<%crefStr(componentRef)%>'
else "CREF_NOT_IDENT_OR_QUAL"
end crefStr;
Expand All @@ -106,6 +107,7 @@ template crefStrNoUnderscore(ComponentRef cr)
match cr
case CREF_IDENT(__) then '<%ident%><%subscriptsStr(subscriptLst)%>'
case CREF_QUAL(ident = "$DER") then 'der(<%crefStrNoUnderscore(componentRef)%>)'
case CREF_QUAL(ident = "$CLKPRE") then 'previous(<%crefStrNoUnderscore(componentRef)%>)'
case CREF_QUAL(__) then '<%ident%><%subscriptsStr(subscriptLst)%>.<%crefStrNoUnderscore(componentRef)%>'
else "CREF_NOT_IDENT_OR_QUAL"
end crefStrNoUnderscore;
Expand Down
6 changes: 6 additions & 0 deletions Compiler/Template/SimCodeTV.mo
Expand Up @@ -839,6 +839,12 @@ package SimCodeUtil
output list<SimCode.SubPartition> outSubPartitions;
end getSubPartitions;

function getClockIndex
input SimCodeVar.SimVar simVar;
input SimCode.SimCode simCode;
output Option<Integer> clockIndex;
end getClockIndex;

function computeDependencies
input list<SimCode.SimEqSystem> eqs;
input DAE.ComponentRef cref;
Expand Down
Expand Up @@ -288,6 +288,11 @@ void SystemDefaultImplementation::getClock(bool* z)
}
}

double *SystemDefaultImplementation::clockInterval()
{
return _clockInterval;
}

void SystemDefaultImplementation::getContinuousStates(double* z)
{
std::copy(__z ,__z + _dimContinuousStates, z);
Expand Down
Expand Up @@ -85,6 +85,9 @@ class BOOST_EXTENSION_SYSTEM_DECL SystemDefaultImplementation
/// Provide clocks
virtual void getClock(bool* z);

/// Provide clock intervals
virtual double *clockInterval();

/// Provide the right hand side
virtual void getRHS(double* f);

Expand Down
28 changes: 26 additions & 2 deletions SimulationRuntime/cpp/Include/FMU2/FMU2Interface.cpp
Expand Up @@ -238,6 +238,18 @@ extern "C"
CATCH_EXCEPTION(w);
}

fmi2Status fmi2GetInterval(fmi2Component c,
const fmi2Integer clockIndex[],
size_t nClockIndex, fmi2Real interval[])
{
FMU2Wrapper *w = reinterpret_cast<FMU2Wrapper*>(c);
LOG_CALL(w, "fmi2GetInterval(nClockIndex = %d)", nClockIndex);
try {
return w->getInterval(clockIndex, nClockIndex, interval);
}
CATCH_EXCEPTION(w);
}

fmi2Status fmi2SetReal(fmi2Component c,
const fmi2ValueReference vr[], size_t nvr,
const fmi2Real value[])
Expand Down Expand Up @@ -288,12 +300,24 @@ extern "C"

fmi2Status fmi2SetClock(fmi2Component c,
const fmi2Integer clockIndex[],
size_t nClockIndex)
size_t nClockIndex, const fmi2Boolean active[])
{
FMU2Wrapper *w = reinterpret_cast<FMU2Wrapper*>(c);
LOG_CALL(w, "fmi2SetClock(nClockIndex = %d)", nClockIndex);
try {
return w->setClock(clockIndex, nClockIndex);
return w->setClock(clockIndex, nClockIndex, active);
}
CATCH_EXCEPTION(w);
}

fmi2Status fmi2SetInterval(fmi2Component c,
const fmi2Integer clockIndex[],
size_t nClockIndex, const fmi2Real interval[])
{
FMU2Wrapper *w = reinterpret_cast<FMU2Wrapper*>(c);
LOG_CALL(w, "fmi2SetInterval(nClockIndex = %d)", nClockIndex);
try {
return w->setInterval(clockIndex, nClockIndex, interval);
}
CATCH_EXCEPTION(w);
}
Expand Down
25 changes: 23 additions & 2 deletions SimulationRuntime/cpp/Include/FMU2/FMU2Wrapper.cpp
Expand Up @@ -260,16 +260,27 @@ fmi2Status FMU2Wrapper::setString(const fmi2ValueReference vr[], size_t nvr,
}

fmi2Status FMU2Wrapper::setClock(const fmi2Integer clockIndex[],
size_t nClockIndex)
size_t nClockIndex, const fmi2Boolean active[])
{
for (int i = 0; i < nClockIndex; i++) {
_clock_buffer[clockIndex[i] - 1] = true;
_clock_buffer[clockIndex[i] - 1] = active[i];
_nclock_active ++;
}
_need_update = true;
return fmi2OK;
}

fmi2Status FMU2Wrapper::setInterval(const fmi2Integer clockIndex[],
size_t nClockIndex, const fmi2Real interval[])
{
double *clockInterval = _model->clockInterval();
for (int i = 0; i < nClockIndex; i++) {
clockInterval[clockIndex[i] - 1] = interval[i];
}
_need_update = true;
return fmi2OK;
}

fmi2Status FMU2Wrapper::getEventIndicators(fmi2Real eventIndicators[], size_t ni)
{
if (_need_update)
Expand Down Expand Up @@ -335,6 +346,16 @@ fmi2Status FMU2Wrapper::getClock(const fmi2Integer clockIndex[],
}
}

fmi2Status FMU2Wrapper::getInterval(const fmi2Integer clockIndex[],
size_t nClockIndex, fmi2Real interval[])
{
double *clockInterval = _model->clockInterval();
for (int i = 0; i < nClockIndex; i++) {
interval[i] = clockInterval[clockIndex[i] - 1];
}
return fmi2OK;
}

fmi2Status FMU2Wrapper::newDiscreteStates(fmi2EventInfo *eventInfo)
{
if (_need_update) {
Expand Down

0 comments on commit f4f5eb0

Please sign in to comment.