Skip to content

Commit

Permalink
+ Fixed handling of complex residual equations. We expand all complex…
Browse files Browse the repository at this point in the history
… residuals to simple

  residuals now.
  • Loading branch information
mahge authored and OpenModelica-Hudson committed Nov 4, 2015
1 parent 0311246 commit 291f55d
Show file tree
Hide file tree
Showing 3 changed files with 186 additions and 16 deletions.
89 changes: 86 additions & 3 deletions Compiler/FrontEnd/ComponentReference.mo
Expand Up @@ -1652,8 +1652,81 @@ algorithm
DAE.CREF_QUAL(componentRef = outCref) := inCref;
end crefRest;

public function crefTypeFull2
"Helper function to crefTypeFull."
input DAE.ComponentRef inCref;
output DAE.Type outType;
output list<DAE.Dimension> outDims;
algorithm
(outType, outDims) := match(inCref)
local
DAE.ComponentRef cr;
DAE.Type ty, basety;
list<DAE.Dimension> dims, restdims;
list<DAE.Subscript> subs;

case DAE.CREF_IDENT(identType = ty, subscriptLst = subs)
equation
(ty,dims) = Types.flattenArrayType(ty);
dims = List.stripN(dims,listLength(subs));
then (ty,dims);

case DAE.CREF_QUAL(identType = ty, subscriptLst = subs, componentRef = cr)
equation
(ty,dims) = Types.flattenArrayType(ty);
dims = List.stripN(dims,listLength(subs));

(basety, restdims) = crefTypeFull2(cr);
dims = listAppend(dims, restdims);
then (basety, dims);

else
equation
true = Flags.isSet(Flags.FAILTRACE);
Debug.trace("ComponentReference.crefTypeFull2 failed on cref: ");
Debug.traceln(printComponentRefStr(inCref));
then
fail();
end match;
end crefTypeFull2;

public function crefTypeFull
"mahge:
This function gives the type of a cref.
This is done by considering how many dimensions and subscripts
the cref has. It also takes in to consideration where the subscripts
are loacated in a qualifed cref. e.g. consider :
record R
Real [4]
end R;

R a[3][2];

if we have a cref a[1][1].b[1] --> Real
a[1].b --> Real[2][4]
a.b[1] --> Real[3][2]
a[1][1].b --> Real[4]
a[1].b[1] --> Real[2]

"
input DAE.ComponentRef inCref;
output DAE.Type outType;
protected
DAE.Type ty;
list<DAE.Dimension> dims;
algorithm
(ty,dims) := crefTypeFull2(inCref);
if listEmpty(dims) then
outType := ty;
else
outType := DAE.T_ARRAY(ty, dims, Types.getTypeSource(ty));
end if;
end crefTypeFull;

public function crefType
"Function for extracting the type of the first identifier of a cref."
" ***deprecated. Use crefTypeFull unless you really specifically want the type of the first cref.
Function for extracting the type of the first identifier of a cref.
"
input DAE.ComponentRef inCref;
output DAE.Type outType;
algorithm
Expand All @@ -1675,7 +1748,12 @@ algorithm
end match;
end crefType;

public function crefLastType "returns the 'last' type of a cref.
public function crefLastType
" ***deprecated.
mahge: Use crefTypeFull unless you really specifically want the type of the last cref.
Remember the type of a cref is not the same as the type of the last cref!!.

returns the 'last' type of a cref.
For instance, for the cref 'a.b' it returns the type in identifier 'b'
adrpo:
NOTE THAT THIS WILL BE AN ARRAY TYPE IF THE LAST CREF IS AN ARRAY TYPE
Expand Down Expand Up @@ -1787,7 +1865,12 @@ algorithm
end match;
end crefFirstCref;

public function crefTypeConsiderSubs "Function: crefTypeConsiderSubs
public function crefTypeConsiderSubs
" ***deprecated.
mahge: use crefTypeFull(). This is not what you want. We need to consider not just the last subs but all subs.
We can have slices.

Function: crefTypeConsiderSubs
Author: PA
Function for extracting the type out of a componentReference and consider the influence of the last subscript list.
For exampel. If the last cref type is Real[3,3] and the last subscript list is {Expression.INDEX(1)}, the type becomes Real[3], i.e
Expand Down
61 changes: 60 additions & 1 deletion Compiler/FrontEnd/Expression.mo
Expand Up @@ -3242,7 +3242,25 @@ algorithm
end match;
end makeCrefExp;

public function crefExp "

public function crefToExp
" mahge:
creates a DAE.Exp from a cref by exrtacting the type from the types of the cref (if qualified) and
considering the dimensions and subscripts that exist in the cref.
"
input DAE.ComponentRef cr;
output DAE.Exp cref;
algorithm
cref := DAE.CREF(cr,ComponentReference.crefTypeFull(cr));
end crefToExp;




public function crefExp
" ***deprecated.
mahge: use crefToExp(). This is not correct. We need to consider more than just the last subs.

Author: BZ, 2008-08
generate an DAE.CREF(ComponentRef, Type) from a ComponenRef, make array type correct from subs"
input DAE.ComponentRef cr;
Expand Down Expand Up @@ -11832,6 +11850,47 @@ algorithm
outExp := makePureBuiltinCall("vector",{exp},tp);
end makeVectorCall;


public function expandExpression
" mahge:
Expands a given expression to a list of expression. this means flattening any records in the
expression and vectorizing arrays.

Currently can only handle crefs and array expressions. Maybe we need to handle binary operations at least.

Right now this is used in generating simple residual equations from complex ones in SimCode.
"

input DAE.Exp inExp;
output list<DAE.Exp> outExps;
algorithm
(outExps) := match (inExp)
local
DAE.ComponentRef cr;
list<DAE.ComponentRef> crlst;
list<DAE.Exp> expl;
String msg;

case (DAE.CREF(cr,_))
algorithm
crlst := ComponentReference.expandCref(cr,true);
outExps := List.map(crlst, crefToExp);
then outExps;

case DAE.ARRAY(_,_,expl)
algorithm
expl := List.mapFlat(expl,expandExpression);
then expl;

else
algorithm
msg := "- Expression.expandExpression failed for " + ExpressionDump.printExpStr(inExp);
Error.addMessage(Error.INTERNAL_ERROR, {msg});
then
fail();
end match;
end expandExpression;

public function extendArrExp "author: Frenkel TUD 2010-07
alternative name: vectorizeExp"
input DAE.Exp inExp;
Expand Down
52 changes: 40 additions & 12 deletions Compiler/SimCode/SimCodeUtil.mo
Expand Up @@ -2187,15 +2187,22 @@ algorithm
// tmp = f()
ident = Absyn.pathStringUnquoteReplaceDot(path, "_");
cr = ComponentReference.makeCrefIdent("$TMP_" + ident + intString(iuniqueEqIndex), tp, {});
e1_1 = Expression.crefExp(cr);
e1_1 = Expression.crefToExp(cr);
stms = DAE.STMT_ASSIGN(tp, e1_1, e2_1, source);
simeqn = SimCode.SES_ALGORITHM(iuniqueEqIndex, {stms});
uniqueEqIndex = iuniqueEqIndex + 1;

// Record()-tmp = 0
e1lst = List.map1(varLst, Expression.generateCrefsExpFromExpVar, cr);
/* Expand the tmp record and any arrays */
e1lst = Expression.expandExpression(e1_1);
/* Expand the varLst. Each var might be an array or record. */
e2lst = List.mapFlat(e2lst, Expression.expandExpression);
/* pair each of the expanded expressions to coressponding one*/
exptl = List.threadTuple(e1lst, e2lst);
/* Create residual equations for each pair*/
(eqSystlst, uniqueEqIndex) = List.map1Fold(exptl, makeSES_RESIDUAL1, source, uniqueEqIndex);
eqSystlst = simeqn::eqSystlst;

tempvars = createTempVars(varLst, cr, itempvars);
then (eqSystlst, uniqueEqIndex, tempvars);

Expand Down Expand Up @@ -2334,9 +2341,11 @@ algorithm
otempvars := match(varLst)
local
list<DAE.Var> rest;
list<SimCodeVar.SimVar> ttmpvars;
DAE.Ident name;
DAE.Type ty;
DAE.ComponentRef cr;
DAE.ComponentRef cr, arraycref;
list<DAE.ComponentRef> crlst;
SimCodeVar.SimVar var;

case {}
Expand All @@ -2346,15 +2355,34 @@ algorithm
cr = ComponentReference.crefPrependIdent(inCrefPrefix, name, {}, ty);
then createTempVars(rest, cr, itempvars);

case DAE.TYPES_VAR(name=name, ty=ty)::rest equation
cr = ComponentReference.crefPrependIdent(inCrefPrefix, name, {}, ty);
if Expression.isArrayType(ComponentReference.crefLastType(cr)) then
ty = DAEUtil.expTypeElementType(ComponentReference.crefLastType(cr));
else
ty = ComponentReference.crefLastType(cr);
end if;
var = SimCodeVar.SIMVAR(cr, BackendDAE.VARIABLE(), "", "", "", 0, NONE(), NONE(), NONE(), NONE(), false, ty, false, NONE(), SimCodeVar.NOALIAS(), DAE.emptyElementSource, SimCodeVar.NONECAUS(), NONE(), {}, false, true);
then createTempVars(rest, inCrefPrefix, var::itempvars);
case DAE.TYPES_VAR(name=name, ty=ty)::rest
algorithm
/* Prepend the tmp ident.*/
cr := ComponentReference.crefPrependIdent(inCrefPrefix, name, {}, ty);
/* Expand the resulting cref.*/
cr::crlst := ComponentReference.expandCref(cr, true /*the way it is now we won't get records here. but if we do somehow expand them*/);

/* Create SimVars from the list of expanded crefs.*/

/* Mark the first element as an arrayCref i.e. we have 'SOME(arraycref)' since this is how the C template
detects first elements of arrays to generate VARNAME_indexed(..) macros for accessing the array
with variable indexes.*/
arraycref := ComponentReference.crefStripSubs(cr);
ty := ComponentReference.crefTypeFull(cr);
var := SimCodeVar.SIMVAR(cr, BackendDAE.VARIABLE(), "", "", "", 0, NONE(), NONE(), NONE(), NONE(), false,
ty, false, SOME(arraycref), SimCodeVar.NOALIAS(), DAE.emptyElementSource, SimCodeVar.NONECAUS(), NONE(), {}, false, true);

/* The rest don't need to be marked i.e. we have 'NONE()'. Just create simvars. */
ttmpvars := {var};
for cr in crlst loop
ty := ComponentReference.crefTypeFull(cr);
var := SimCodeVar.SIMVAR(cr, BackendDAE.VARIABLE(), "", "", "", 0, NONE(), NONE(), NONE(), NONE(), false, ty, false, NONE(), SimCodeVar.NOALIAS(), DAE.emptyElementSource, SimCodeVar.NONECAUS(), NONE(), {}, false, true);
ttmpvars := var::ttmpvars;
end for;
ttmpvars := listReverse(ttmpvars);
ttmpvars := listAppend(itempvars,ttmpvars);
then createTempVars(rest, inCrefPrefix, ttmpvars);

end match;
end createTempVars;

Expand Down

0 comments on commit 291f55d

Please sign in to comment.