Skip to content

Commit

Permalink
- avoid divisions by zero in residual equations
Browse files Browse the repository at this point in the history
- add parameter equations to equationInfo, because they could also have nonlinear systems
- add listAppend to SimCodeTV, how it is posibble to append two list and store this list in a variable?
- fix tabs f2c.h
- improve test ParameterCycle, check results of var1 and var2

git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@13660 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
  • Loading branch information
Jens Frenkel committed Oct 26, 2012
1 parent bf072ed commit d322284
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 27 deletions.
99 changes: 78 additions & 21 deletions Compiler/BackEnd/SimCodeUtil.mo
Original file line number Diff line number Diff line change
Expand Up @@ -1913,7 +1913,8 @@ algorithm
allEquations = listAppend(allEquations,removedEquations);

// update indexNonLinear in SES_NONLINEAR and count
(allEquations, numberofEqns, numberofNonLinearSys) = indexNonLinSysandCountEqns(allEquations, 0, 0);
(parameterEquations, numberofEqns, numberofNonLinearSys) = indexNonLinSysandCountEqns(parameterEquations, 0, 0);
(allEquations, numberofEqns, numberofNonLinearSys) = indexNonLinSysandCountEqns(allEquations, numberofEqns, numberofNonLinearSys);
modelInfo = addNumEqnsandNonLinear(modelInfo, numberofEqns, numberofNonLinearSys);

// replace div operator with div operator with check of Division by zero
Expand Down Expand Up @@ -4180,6 +4181,43 @@ algorithm
end match;
end greateTempVars;

protected function moveDivToMul
input list<DAE.Exp> iExpLst;
input list<DAE.Exp> iExpLstAcc;
input list<DAE.Exp> iExpMuls;
output list<DAE.Exp> oExpLst;
output list<DAE.Exp> oExpMuls;
algorithm
(oExpLst,oExpMuls) := match(iExpLst,iExpLstAcc,iExpMuls)
local
DAE.Exp e,e1,e2,res;
list<DAE.Exp> rest,acc,elst,elst1;
case ({},_,_) then (iExpLstAcc,iExpMuls);
// a/b
case (DAE.BINARY(exp1=e1,operator=DAE.DIV(ty=_),exp2=e2)::rest,_,_)
equation
acc = List.map1(iExpLstAcc,Expression.expMul,e2);
rest = List.map1(rest,Expression.expMul,e2);
rest = ExpressionSimplify.simplifyList(rest,{});
(elst,elst1) = moveDivToMul(rest,e1::acc,e2::iExpMuls);
then
(elst,elst1);
case (DAE.BINARY(exp1=e1,operator=DAE.DIV_ARRAY_SCALAR(ty=_),exp2=e2)::rest,_,_)
equation
acc = List.map1(iExpLstAcc,Expression.expMul,e2);
rest = List.map1(rest,Expression.expMul,e2);
rest = ExpressionSimplify.simplifyList(rest,{});
(elst,elst1) = moveDivToMul(rest,e1::acc,e2::iExpMuls);
then
(elst,elst1);
case (e::rest,_,_)
equation
(elst,elst1) = moveDivToMul(rest,e::iExpLstAcc,iExpMuls);
then
(elst,elst1);
end match;
end moveDivToMul;

protected function createNonlinearResidualExp
"function createNonlinearResidualExp
autor Frenkel TUD 2012-10
Expand All @@ -4192,36 +4230,55 @@ algorithm
resExp := matchcontinue(iExp1,iExp2)
local
DAE.Exp e,e1,e2,res;
// a/b = c -> a-b*c
case (DAE.BINARY(exp1=e1,operator=DAE.DIV(ty=_),exp2=e2),_)
list<DAE.Exp> explst,explst1,mexplst;
DAE.Type ty;
case(_,_)
equation
res = Expression.expMul(e2,iExp2);
res = Expression.expSub(e1,res);
(res,_) = ExpressionSimplify.simplify(res);
true = Expression.isZero(iExp1);
then
res;
case (DAE.BINARY(exp1=e1,operator=DAE.DIV_ARRAY_SCALAR(ty=_),exp2=e2),_)
iExp2;
case(_,_)
equation
res = Expression.expMul(e2,iExp2);
res = Expression.expSub(e1,res);
(res,_) = ExpressionSimplify.simplify(res);
true = Expression.isZero(iExp2);
then
res;
// a = b/c -> a*c-b
case (_,DAE.BINARY(exp1=e1,operator=DAE.DIV(ty=_),exp2=e2))
iExp1;
case(_,_)
equation
res = Expression.expMul(iExp1,e2);
res = Expression.expSub(res,e1);
ty = Expression.typeof(iExp1);
true = Types.isIntegerOrRealOrSubTypeOfEither(ty);
// get terms
explst = Expression.terms(iExp1);
explst1 = Expression.terms(iExp2);
// get all divisors and multiply them to the other terms
(explst,mexplst) = moveDivToMul(explst,{},{});
e = Expression.makeProductLst(mexplst);
(e,_) = ExpressionSimplify.simplify(e);
explst1 = List.map1(explst1,Expression.expMul,e);
explst1 = ExpressionSimplify.simplifyList(explst1,{});
(explst1,mexplst) = moveDivToMul(explst1,{},{});
e = Expression.makeProductLst(mexplst);
(e,_) = ExpressionSimplify.simplify(e);
explst = List.map1(explst,Expression.expMul,e);
explst1 = List.map(explst1,Expression.negate);
explst = listAppend(explst,explst1);
res = Expression.makeSum(explst);
(res,_) = ExpressionSimplify.simplify(res);
then
res;
case(_,_)
equation
ty = Expression.typeof(iExp1);
true = Types.isBooleanOrSubTypeBoolean(ty);
res = DAE.LUNARY(DAE.NOT(ty),DAE.LBINARY(iExp1,DAE.EQUAL(ty),iExp2));
then
res;
case (_,DAE.BINARY(exp1=e1,operator=DAE.DIV_ARRAY_SCALAR(ty=_),exp2=e2))
case(_,_)
equation
res = Expression.expMul(iExp1,e2);
res = Expression.expSub(res,e1);
(res,_) = ExpressionSimplify.simplify(res);
ty = Expression.typeof(iExp1);
true = Types.isStringOrSubTypeString(ty);
res = DAE.LUNARY(DAE.NOT(ty),DAE.LBINARY(iExp1,DAE.EQUAL(ty),iExp2));
then
res;
res;
else
equation
res = Expression.expSub(iExp1,iExp2);
Expand Down
18 changes: 12 additions & 6 deletions Compiler/Template/CodegenC.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -146,15 +146,16 @@ template simulationFile(SimCode simCode, String guid)
<%functionInitializeDataStruc(modelInfo, fileNamePrefix, guid, allEquations, appendAllequations(jacobianMatrixes), delayedExps)%>
<%functionInitializeDataStruc2(modelInfo, allEquations, appendAllequations(jacobianMatrixes))%>
<%functionInitializeDataStruc2(modelInfo, allEquations, appendAllequations(jacobianMatrixes), parameterEquations)%>
<%functionCallExternalObjectConstructors(extObjInfo)%>
<%functionCallExternalObjectDestructors(extObjInfo)%>
<%functionExtraResiduals(parameterEquations)%>
<%functionExtraResiduals(allEquations)%>
<%functionInitialNonLinearSystems(allEquations)%>
<%functionInitialNonLinearSystems(parameterEquations,allEquations)%>
<%functionInput(modelInfo)%>
Expand Down Expand Up @@ -327,7 +328,7 @@ template functionSimProfDef(SimEqSystem eq, Integer value)
end match
end functionSimProfDef;

template functionInitializeDataStruc2(ModelInfo modelInfo, list<SimEqSystem> allEquations, list<SimEqSystem> symJacEquations)
template functionInitializeDataStruc2(ModelInfo modelInfo, list<SimEqSystem> allEquations, list<SimEqSystem> symJacEquations, list<SimEqSystem> parameterEquations)
"Generates function in simulation file."
::=
match modelInfo
Expand All @@ -337,11 +338,12 @@ template functionInitializeDataStruc2(ModelInfo modelInfo, list<SimEqSystem> all
*/
let &eqnsDefines = buffer ""
/*
let eqnsDefines = (allEquations |> eq hasindex i0 => functionSimProfDef(eq,i0); separator="";empty)
let allEqsPlusParamEqns = listAppend(parameterEquations,allEquations)
let eqnsDefines = (allEqsPlusParamEqns |> eq hasindex i0 => functionSimProfDef(eq,i0); separator="";empty)
<%equationInfo(allEquations)%>
*/
let &eqnsDefines = buffer ""
let eqnInfo = equationInfo(allEquations,&eqnsDefines,intAdd(varInfo.numEquations, listLength(symJacEquations)))
let eqnInfo = equationInfo(listAppend(parameterEquations,allEquations),&eqnsDefines,intAdd(varInfo.numEquations, listLength(symJacEquations)))
<<
/* Some empty lines, since emptyCount is not implemented in susan! */
<%eqnsDefines%>
Expand Down Expand Up @@ -474,11 +476,13 @@ template globalDataParDefine(SimVar simVar, String arrayName)
#define <%cref(c)%> data->simulationInfo.<%arrayName%>[<%index%>]
#define $P$ATTRIBUTE<%cref(name)%> data->modelData.<%arrayName%>Data[<%index%>].attribute
#define <%cref(name)%> data->simulationInfo.<%arrayName%>[<%index%>]
#define _<%cref(name)%>(i) <%cref(name)%>
#define <%cref(name)%>__varInfo data->modelData.<%arrayName%>Data[<%index%>].info
>>
case SIMVAR(aliasvar=NOALIAS()) then
<<
#define <%cref(name)%> data->simulationInfo.<%arrayName%>[<%index%>]
#define _<%cref(name)%>(i) <%cref(name)%>
#define $P$ATTRIBUTE<%cref(name)%> data->modelData.<%arrayName%>Data[<%index%>].attribute
#define <%cref(name)%>__varInfo data->modelData.<%arrayName%>Data[<%index%>].info
>>
Expand Down Expand Up @@ -876,14 +880,16 @@ template functionInitialResidual(list<SimEqSystem> residualEquations)
>>
end functionInitialResidual;

template functionInitialNonLinearSystems(list<SimEqSystem> allEquations)
template functionInitialNonLinearSystems(list<SimEqSystem> parameterEquations, list<SimEqSystem> allEquations)
"Generates functions in simulation file."
::=
let parambody = functionInitialNonLinearSystemsTemp(parameterEquations)
let body = functionInitialNonLinearSystemsTemp(allEquations)
<<
/* funtion initialize non-linear systems */
void initialNonLinearSystem(NONLINEAR_SYSTEM_DATA* nonLinearSystemData)
{
<%parambody%>
<%body%>
}
>>
Expand Down
7 changes: 7 additions & 0 deletions Compiler/Template/SimCodeTV.mo
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,13 @@ package builtin
output Boolean b;
end stringEq;

function listAppend
replaceable type TypeVar subtypeof Any;
input list<TypeVar> lst;
input list<TypeVar> lst1;
output list<TypeVar> result;
end listAppend;

end builtin;


Expand Down

0 comments on commit d322284

Please sign in to comment.