Skip to content

Commit

Permalink
Support array equation with der(v) on left hand side
Browse files Browse the repository at this point in the history
See e.g. import of FMU in
testsuite/openmodelica/cppruntime/fmu/modelExchange/2.0/DIC_FMU2_CPP.mos:
  der(fmi_x) = DIC_me_FMU.fmi2Functions.fmi2GetDerivatives(fmi2me, 2, flowStatesInputs)

Belonging to [master]:
  - OpenModelica/OMCompiler#2658
  • Loading branch information
rfranke authored and OpenModelica-Hudson committed Sep 16, 2018
1 parent 18752c9 commit 049ab69
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 15 deletions.
4 changes: 2 additions & 2 deletions Compiler/BackEnd/BackendDAETransform.mo
Expand Up @@ -865,7 +865,7 @@ algorithm
(exp1::exps) := Expression.flattenArrayExpToList(e);
(cr1, call1) := match exp1
case DAE.CREF(componentRef=cr1) then (cr1, "");
case DAE.CALL(path=Absyn.IDENT(name="previous"), expLst={DAE.CREF(componentRef=cr1)}) then (cr1, "previous");
case DAE.CALL(path=Absyn.IDENT(name=call1), expLst={DAE.CREF(componentRef=cr1)}) then (cr1, call1);
else fail();
end match;
if call1 <> "" and Config.simCodeTarget() <> "Cpp" or call1 == "pre" then
Expand All @@ -886,7 +886,7 @@ algorithm
//DAE.CREF(componentRef=cr2) := exp;
(cr2, call2) := match exp
case DAE.CREF(componentRef=cr2) then (cr2, "");
case DAE.CALL(path=Absyn.IDENT(name="previous"), expLst={DAE.CREF(componentRef=cr2)}) then (cr2, "previous");
case DAE.CALL(path=Absyn.IDENT(name=call2), expLst={DAE.CREF(componentRef=cr2)}) then (cr2, call2);
else fail();
end match;
true := ndim==listLength(ComponentReference.crefLastSubs(cr2));
Expand Down
29 changes: 16 additions & 13 deletions Compiler/SimCode/SimCodeUtil.mo
Expand Up @@ -5444,11 +5444,21 @@ protected function createSingleArrayEqnCode
output list<SimCode.SimEqSystem> noDiscequations;
output Integer ouniqueEqIndex;
output list<SimCodeVar.SimVar> otempvars;
protected
BackendDAE.Equation inEquation;
algorithm
(equations_, noDiscequations, ouniqueEqIndex, otempvars) := matchcontinue(genDiscrete, inEquations, inVars, iuniqueEqIndex, itempvars, iextra)
// first replace der() to match them as cref $DER. below
inEquation := match listHead(inEquations)
case inEquation as BackendDAE.ARRAY_EQUATION(_)
algorithm
inEquation.left := Expression.replaceDerOpInExp(inEquation.left);
inEquation.right := Expression.replaceDerOpInExp(inEquation.right);
then inEquation;
end match;
(equations_, noDiscequations, ouniqueEqIndex, otempvars) := matchcontinue(genDiscrete, inEquation, inVars, iuniqueEqIndex, itempvars, iextra)
local
list<Integer> ds;
DAE.Exp e1, e2, e1_1, e2_1, lhse, rhse;
DAE.Exp e1, e2, lhse, rhse;
list<DAE.Exp> ea1, ea2, expLst, expLstTmp;
list<BackendDAE.Equation> re;
list<BackendDAE.Var> vars;
Expand Down Expand Up @@ -5482,14 +5492,11 @@ algorithm
// {z1,z2,..} = rhsexp -> solved for {z1,z2,..}
// => tmp = rhsexp;
// z1 = tmp[1]; z2 = tmp[2] ....
case (_, (BackendDAE.ARRAY_EQUATION(dimSize=ds, left=e1, right=e2, source=source, attr=eqAttr))::{}, _, _, _, _)
case (_, (BackendDAE.ARRAY_EQUATION(dimSize=ds, left=e1, right=e2, source=source, attr=eqAttr)), _, _, _, _)
guard Expression.isMatrix(e1) or Expression.isArray(e1)
equation
// Flattne multi-dimensional ARRAY{ARRAY} expressions
expLst = Expression.flattenArrayExpToList(e1);
// Replace the der() operators
expLst = List.map(expLst, Expression.replaceDerOpInExp);
e2_1 = Expression.replaceDerOpInExp(e2);
// create the lhs tmp var
ty = Expression.typeof(e1);
(basety,dims) = Types.flattenArrayType(ty);
Expand All @@ -5506,16 +5513,14 @@ algorithm
exptl = List.threadTuple(expLst, expLstTmp);
(eqSystlst, uniqueEqIndex) = List.map2Fold(exptl, makeSES_SIMPLE_ASSIGN, source, eqAttr, iuniqueEqIndex);
// Create the array equation with the tmp var as lhs
eqSystlst = SimCode.SES_ARRAY_CALL_ASSIGN(uniqueEqIndex, lhse, e2_1, source, eqAttr)::eqSystlst;
eqSystlst = SimCode.SES_ARRAY_CALL_ASSIGN(uniqueEqIndex, lhse, e2, source, eqAttr)::eqSystlst;
then (eqSystlst, eqSystlst, uniqueEqIndex+1, tempvars);

// An array equation
// cref = rhsexp
case (_, (BackendDAE.ARRAY_EQUATION(left=lhse as DAE.CREF(cr_1, _), right=e2, source=source, attr=eqAttr))::_, BackendDAE.VAR(varName=cr)::_, _, _, _)
case (_, (BackendDAE.ARRAY_EQUATION(left=e1 as DAE.CREF(cr_1, _), right=e2, source=source, attr=eqAttr)), BackendDAE.VAR(varName=cr)::_, _, _, _)
guard ComponentReference.crefEqual(cr_1, ComponentReference.crefStripLastSubs(cr))
equation
e1 = Expression.replaceDerOpInExp(lhse);
e2 = Expression.replaceDerOpInExp(e2);
(e1, _) = BackendDAEUtil.collateArrExp(e1, NONE());
(e2, _) = BackendDAEUtil.collateArrExp(e2, NONE());
(e1, e2) = solveTrivialArrayEquation(cr_1, e1, e2);
Expand All @@ -5525,11 +5530,9 @@ algorithm

// An array equation
// lhsexp = cref
case (_, (BackendDAE.ARRAY_EQUATION(left=e1, right=rhse as DAE.CREF(cr_1, _), source=source, attr=eqAttr))::_, BackendDAE.VAR(varName=cr)::_, _, _, _)
case (_, (BackendDAE.ARRAY_EQUATION(left=e1, right=e2 as DAE.CREF(cr_1, _), source=source, attr=eqAttr)), BackendDAE.VAR(varName=cr)::_, _, _, _)
guard ComponentReference.crefEqual(cr_1, ComponentReference.crefStripLastSubs(cr))
equation
e1 = Expression.replaceDerOpInExp(e1);
e2 = Expression.replaceDerOpInExp(rhse);
(e1, _) = BackendDAEUtil.collateArrExp(e1, NONE());
(e2, _) = BackendDAEUtil.collateArrExp(e2, NONE());
(e2, e1) = solveTrivialArrayEquation(cr_1, e2, e1);
Expand Down

0 comments on commit 049ab69

Please sign in to comment.