Skip to content

Commit d322284

Browse files
author
Jens Frenkel
committed
- avoid divisions by zero in residual equations
- 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
1 parent bf072ed commit d322284

File tree

3 files changed

+97
-27
lines changed

3 files changed

+97
-27
lines changed

Compiler/BackEnd/SimCodeUtil.mo

Lines changed: 78 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1913,7 +1913,8 @@ algorithm
19131913
allEquations = listAppend(allEquations,removedEquations);
19141914

19151915
// update indexNonLinear in SES_NONLINEAR and count
1916-
(allEquations, numberofEqns, numberofNonLinearSys) = indexNonLinSysandCountEqns(allEquations, 0, 0);
1916+
(parameterEquations, numberofEqns, numberofNonLinearSys) = indexNonLinSysandCountEqns(parameterEquations, 0, 0);
1917+
(allEquations, numberofEqns, numberofNonLinearSys) = indexNonLinSysandCountEqns(allEquations, numberofEqns, numberofNonLinearSys);
19171918
modelInfo = addNumEqnsandNonLinear(modelInfo, numberofEqns, numberofNonLinearSys);
19181919

19191920
// replace div operator with div operator with check of Division by zero
@@ -4180,6 +4181,43 @@ algorithm
41804181
end match;
41814182
end greateTempVars;
41824183

4184+
protected function moveDivToMul
4185+
input list<DAE.Exp> iExpLst;
4186+
input list<DAE.Exp> iExpLstAcc;
4187+
input list<DAE.Exp> iExpMuls;
4188+
output list<DAE.Exp> oExpLst;
4189+
output list<DAE.Exp> oExpMuls;
4190+
algorithm
4191+
(oExpLst,oExpMuls) := match(iExpLst,iExpLstAcc,iExpMuls)
4192+
local
4193+
DAE.Exp e,e1,e2,res;
4194+
list<DAE.Exp> rest,acc,elst,elst1;
4195+
case ({},_,_) then (iExpLstAcc,iExpMuls);
4196+
// a/b
4197+
case (DAE.BINARY(exp1=e1,operator=DAE.DIV(ty=_),exp2=e2)::rest,_,_)
4198+
equation
4199+
acc = List.map1(iExpLstAcc,Expression.expMul,e2);
4200+
rest = List.map1(rest,Expression.expMul,e2);
4201+
rest = ExpressionSimplify.simplifyList(rest,{});
4202+
(elst,elst1) = moveDivToMul(rest,e1::acc,e2::iExpMuls);
4203+
then
4204+
(elst,elst1);
4205+
case (DAE.BINARY(exp1=e1,operator=DAE.DIV_ARRAY_SCALAR(ty=_),exp2=e2)::rest,_,_)
4206+
equation
4207+
acc = List.map1(iExpLstAcc,Expression.expMul,e2);
4208+
rest = List.map1(rest,Expression.expMul,e2);
4209+
rest = ExpressionSimplify.simplifyList(rest,{});
4210+
(elst,elst1) = moveDivToMul(rest,e1::acc,e2::iExpMuls);
4211+
then
4212+
(elst,elst1);
4213+
case (e::rest,_,_)
4214+
equation
4215+
(elst,elst1) = moveDivToMul(rest,e::iExpLstAcc,iExpMuls);
4216+
then
4217+
(elst,elst1);
4218+
end match;
4219+
end moveDivToMul;
4220+
41834221
protected function createNonlinearResidualExp
41844222
"function createNonlinearResidualExp
41854223
autor Frenkel TUD 2012-10
@@ -4192,36 +4230,55 @@ algorithm
41924230
resExp := matchcontinue(iExp1,iExp2)
41934231
local
41944232
DAE.Exp e,e1,e2,res;
4195-
// a/b = c -> a-b*c
4196-
case (DAE.BINARY(exp1=e1,operator=DAE.DIV(ty=_),exp2=e2),_)
4233+
list<DAE.Exp> explst,explst1,mexplst;
4234+
DAE.Type ty;
4235+
case(_,_)
41974236
equation
4198-
res = Expression.expMul(e2,iExp2);
4199-
res = Expression.expSub(e1,res);
4200-
(res,_) = ExpressionSimplify.simplify(res);
4237+
true = Expression.isZero(iExp1);
42014238
then
4202-
res;
4203-
case (DAE.BINARY(exp1=e1,operator=DAE.DIV_ARRAY_SCALAR(ty=_),exp2=e2),_)
4239+
iExp2;
4240+
case(_,_)
42044241
equation
4205-
res = Expression.expMul(e2,iExp2);
4206-
res = Expression.expSub(e1,res);
4207-
(res,_) = ExpressionSimplify.simplify(res);
4242+
true = Expression.isZero(iExp2);
42084243
then
4209-
res;
4210-
// a = b/c -> a*c-b
4211-
case (_,DAE.BINARY(exp1=e1,operator=DAE.DIV(ty=_),exp2=e2))
4244+
iExp1;
4245+
case(_,_)
42124246
equation
4213-
res = Expression.expMul(iExp1,e2);
4214-
res = Expression.expSub(res,e1);
4247+
ty = Expression.typeof(iExp1);
4248+
true = Types.isIntegerOrRealOrSubTypeOfEither(ty);
4249+
// get terms
4250+
explst = Expression.terms(iExp1);
4251+
explst1 = Expression.terms(iExp2);
4252+
// get all divisors and multiply them to the other terms
4253+
(explst,mexplst) = moveDivToMul(explst,{},{});
4254+
e = Expression.makeProductLst(mexplst);
4255+
(e,_) = ExpressionSimplify.simplify(e);
4256+
explst1 = List.map1(explst1,Expression.expMul,e);
4257+
explst1 = ExpressionSimplify.simplifyList(explst1,{});
4258+
(explst1,mexplst) = moveDivToMul(explst1,{},{});
4259+
e = Expression.makeProductLst(mexplst);
4260+
(e,_) = ExpressionSimplify.simplify(e);
4261+
explst = List.map1(explst,Expression.expMul,e);
4262+
explst1 = List.map(explst1,Expression.negate);
4263+
explst = listAppend(explst,explst1);
4264+
res = Expression.makeSum(explst);
42154265
(res,_) = ExpressionSimplify.simplify(res);
4266+
then
4267+
res;
4268+
case(_,_)
4269+
equation
4270+
ty = Expression.typeof(iExp1);
4271+
true = Types.isBooleanOrSubTypeBoolean(ty);
4272+
res = DAE.LUNARY(DAE.NOT(ty),DAE.LBINARY(iExp1,DAE.EQUAL(ty),iExp2));
42164273
then
42174274
res;
4218-
case (_,DAE.BINARY(exp1=e1,operator=DAE.DIV_ARRAY_SCALAR(ty=_),exp2=e2))
4275+
case(_,_)
42194276
equation
4220-
res = Expression.expMul(iExp1,e2);
4221-
res = Expression.expSub(res,e1);
4222-
(res,_) = ExpressionSimplify.simplify(res);
4277+
ty = Expression.typeof(iExp1);
4278+
true = Types.isStringOrSubTypeString(ty);
4279+
res = DAE.LUNARY(DAE.NOT(ty),DAE.LBINARY(iExp1,DAE.EQUAL(ty),iExp2));
42234280
then
4224-
res;
4281+
res;
42254282
else
42264283
equation
42274284
res = Expression.expSub(iExp1,iExp2);

Compiler/Template/CodegenC.tpl

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -146,15 +146,16 @@ template simulationFile(SimCode simCode, String guid)
146146
147147
<%functionInitializeDataStruc(modelInfo, fileNamePrefix, guid, allEquations, appendAllequations(jacobianMatrixes), delayedExps)%>
148148
149-
<%functionInitializeDataStruc2(modelInfo, allEquations, appendAllequations(jacobianMatrixes))%>
149+
<%functionInitializeDataStruc2(modelInfo, allEquations, appendAllequations(jacobianMatrixes), parameterEquations)%>
150150
151151
<%functionCallExternalObjectConstructors(extObjInfo)%>
152152
153153
<%functionCallExternalObjectDestructors(extObjInfo)%>
154154
155+
<%functionExtraResiduals(parameterEquations)%>
155156
<%functionExtraResiduals(allEquations)%>
156157
157-
<%functionInitialNonLinearSystems(allEquations)%>
158+
<%functionInitialNonLinearSystems(parameterEquations,allEquations)%>
158159
159160
<%functionInput(modelInfo)%>
160161
@@ -327,7 +328,7 @@ template functionSimProfDef(SimEqSystem eq, Integer value)
327328
end match
328329
end functionSimProfDef;
329330

330-
template functionInitializeDataStruc2(ModelInfo modelInfo, list<SimEqSystem> allEquations, list<SimEqSystem> symJacEquations)
331+
template functionInitializeDataStruc2(ModelInfo modelInfo, list<SimEqSystem> allEquations, list<SimEqSystem> symJacEquations, list<SimEqSystem> parameterEquations)
331332
"Generates function in simulation file."
332333
::=
333334
match modelInfo
@@ -337,11 +338,12 @@ template functionInitializeDataStruc2(ModelInfo modelInfo, list<SimEqSystem> all
337338
*/
338339
let &eqnsDefines = buffer ""
339340
/*
340-
let eqnsDefines = (allEquations |> eq hasindex i0 => functionSimProfDef(eq,i0); separator="";empty)
341+
let allEqsPlusParamEqns = listAppend(parameterEquations,allEquations)
342+
let eqnsDefines = (allEqsPlusParamEqns |> eq hasindex i0 => functionSimProfDef(eq,i0); separator="";empty)
341343
<%equationInfo(allEquations)%>
342344
*/
343345
let &eqnsDefines = buffer ""
344-
let eqnInfo = equationInfo(allEquations,&eqnsDefines,intAdd(varInfo.numEquations, listLength(symJacEquations)))
346+
let eqnInfo = equationInfo(listAppend(parameterEquations,allEquations),&eqnsDefines,intAdd(varInfo.numEquations, listLength(symJacEquations)))
345347
<<
346348
/* Some empty lines, since emptyCount is not implemented in susan! */
347349
<%eqnsDefines%>
@@ -474,11 +476,13 @@ template globalDataParDefine(SimVar simVar, String arrayName)
474476
#define <%cref(c)%> data->simulationInfo.<%arrayName%>[<%index%>]
475477
#define $P$ATTRIBUTE<%cref(name)%> data->modelData.<%arrayName%>Data[<%index%>].attribute
476478
#define <%cref(name)%> data->simulationInfo.<%arrayName%>[<%index%>]
479+
#define _<%cref(name)%>(i) <%cref(name)%>
477480
#define <%cref(name)%>__varInfo data->modelData.<%arrayName%>Data[<%index%>].info
478481
>>
479482
case SIMVAR(aliasvar=NOALIAS()) then
480483
<<
481484
#define <%cref(name)%> data->simulationInfo.<%arrayName%>[<%index%>]
485+
#define _<%cref(name)%>(i) <%cref(name)%>
482486
#define $P$ATTRIBUTE<%cref(name)%> data->modelData.<%arrayName%>Data[<%index%>].attribute
483487
#define <%cref(name)%>__varInfo data->modelData.<%arrayName%>Data[<%index%>].info
484488
>>
@@ -876,14 +880,16 @@ template functionInitialResidual(list<SimEqSystem> residualEquations)
876880
>>
877881
end functionInitialResidual;
878882

879-
template functionInitialNonLinearSystems(list<SimEqSystem> allEquations)
883+
template functionInitialNonLinearSystems(list<SimEqSystem> parameterEquations, list<SimEqSystem> allEquations)
880884
"Generates functions in simulation file."
881885
::=
886+
let parambody = functionInitialNonLinearSystemsTemp(parameterEquations)
882887
let body = functionInitialNonLinearSystemsTemp(allEquations)
883888
<<
884889
/* funtion initialize non-linear systems */
885890
void initialNonLinearSystem(NONLINEAR_SYSTEM_DATA* nonLinearSystemData)
886891
{
892+
<%parambody%>
887893
<%body%>
888894
}
889895
>>

Compiler/Template/SimCodeTV.mo

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,13 @@ package builtin
9292
output Boolean b;
9393
end stringEq;
9494

95+
function listAppend
96+
replaceable type TypeVar subtypeof Any;
97+
input list<TypeVar> lst;
98+
input list<TypeVar> lst1;
99+
output list<TypeVar> result;
100+
end listAppend;
101+
95102
end builtin;
96103

97104

0 commit comments

Comments
 (0)