Skip to content

Commit e581e16

Browse files
author
Rickard Lindberg
committed
- Added dummy SimEqArray record for debugging purposes
- Extract array equations - Generate DAE.Exp.ARRAY - Added listLengthExp function git-svn-id: https://openmodelica.org/svn/OpenModelica/trunk@4655 f25d12d1-65f4-0310-ae8a-bbce733d8d8e
1 parent 43823ef commit e581e16

File tree

5 files changed

+15188
-14496
lines changed

5 files changed

+15188
-14496
lines changed

Compiler/SimCode.mo

Lines changed: 325 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ protected import System;
5858
protected import CevalScript;
5959

6060

61+
public
62+
function listLengthExp
63+
input list<DAE.Exp> lst;
64+
output Integer len;
65+
algorithm
66+
len := listLength(lst);
67+
end listLengthExp;
68+
6169
public
6270
function listLengthStr
6371
input list<String> lst;
@@ -290,6 +298,13 @@ uniontype SimEqSystem
290298
DAE.ComponentRef componentRef;
291299
DAE.Exp exp;
292300
end SES_SIMPLE_ASSIGN;
301+
record SES_ARRAY_CALL_ASSIGN
302+
DAE.ComponentRef componentRef;
303+
DAE.Exp exp;
304+
end SES_ARRAY_CALL_ASSIGN;
305+
record SES_NOT_IMPLEMENTED
306+
String msg;
307+
end SES_NOT_IMPLEMENTED;
293308
end SimEqSystem;
294309

295310
uniontype SimWhenClause
@@ -1491,17 +1506,322 @@ algorithm
14911506
/* multiple equations that must be solved together (algebraic loop) */
14921507
case (dae, dlow, ass1, ass2, eqNum :: restEqNums)
14931508
equation
1494-
Error.addMessage(Error.INTERNAL_ERROR, {"createEquation failed: algebraic loops not implemented yet"});
1509+
equation_ = createOdeSystem(false, dlow, ass1, ass2, eqNum :: restEqNums);
14951510
then
1496-
SES_SIMPLE_ASSIGN(DAE.WILD, DAE.ICONST(1));
1511+
equation_;
14971512
case (_,_,_,_,_)
1498-
equation
1499-
Error.addMessage(Error.INTERNAL_ERROR, {"createEquation failed"});
15001513
then
1501-
SES_SIMPLE_ASSIGN(DAE.WILD, DAE.ICONST(2));
1514+
SES_NOT_IMPLEMENTED("none of cases in createEquation succeeded");
15021515
end matchcontinue;
15031516
end createEquation;
15041517

1518+
public function createOdeSystem
1519+
input Boolean genDiscrete "if true generate discrete equations";
1520+
input DAELow.DAELow inDAELow1;
1521+
input Integer[:] inIntegerArray2;
1522+
input Integer[:] inIntegerArray3;
1523+
input list<Integer> inIntegerLst4;
1524+
output SimEqSystem equation_;
1525+
algorithm
1526+
equation_ :=
1527+
matchcontinue (genDiscrete,inDAELow1,inIntegerArray2,inIntegerArray3,inIntegerLst4)
1528+
local
1529+
String rettp,fn;
1530+
list<DAELow.Equation> eqn_lst,cont_eqn,disc_eqn;
1531+
list<DAELow.Var> var_lst,cont_var,disc_var,var_lst_1,cont_var1;
1532+
DAELow.Variables vars_1,vars,knvars,exvars;
1533+
DAELow.EquationArray eqns_1,eqns,se,ie;
1534+
DAELow.DAELow cont_subsystem_dae,daelow,subsystem_dae,dlow;
1535+
list<Integer>[:] m,m_1,mt_1;
1536+
Option<list<tuple<Integer, Integer, DAELow.Equation>>> jac;
1537+
DAELow.JacobianType jac_tp;
1538+
String s;
1539+
Codegen.CFunction s2,s1,s0,s2_1,s3,s4,cfn;
1540+
Integer cg_id_1,cg_id,cg_id3,cg_id1,cg_id2,cg_id4,cg_id5;
1541+
list<CFunction> f1,extra_funcs1;
1542+
DAELow.MultiDimEquation[:] ae;
1543+
Algorithm.Algorithm[:] al;
1544+
DAELow.EventInfo ev;
1545+
Integer[:] ass1,ass2;
1546+
list<Integer> block_;
1547+
DAELow.ExternalObjectClasses eoc;
1548+
list<String> retrec,arg,locvars,init,locvars,stmts,cleanups,stmts_1,stmts_2;
1549+
Integer numValues;
1550+
/* mixed system of equations, continuous part only */
1551+
case (false,(daelow as DAELow.DAELOW(vars,knvars,exvars,eqns,se,ie,ae,al, ev,eoc)),ass1,ass2,block_)
1552+
equation
1553+
(eqn_lst,var_lst) = Util.listMap32(block_, getEquationAndSolvedVar, eqns, vars, ass2);
1554+
true = isMixedSystem(var_lst,eqn_lst);
1555+
(cont_eqn,cont_var,disc_eqn,disc_var) = splitMixedEquations(eqn_lst, var_lst);
1556+
// States are solved for der(x) not x.
1557+
cont_var1 = Util.listMap(cont_var, transformXToXd);
1558+
vars_1 = DAELow.listVar(cont_var1);
1559+
eqns_1 = DAELow.listEquation(cont_eqn);
1560+
cont_subsystem_dae = DAELow.DAELOW(vars_1,knvars,exvars,eqns_1,se,ie,ae,al,ev,eoc);
1561+
m = DAELow.incidenceMatrix(cont_subsystem_dae);
1562+
m_1 = DAELow.absIncidenceMatrix(m);
1563+
mt_1 = DAELow.transposeMatrix(m_1);
1564+
// calculate jacobian. If constant, linear system of equations. Otherwise nonlinear
1565+
jac = DAELow.calculateJacobian(vars_1, eqns_1, ae, m_1, mt_1,true);
1566+
jac_tp = DAELow.analyzeJacobian(cont_subsystem_dae, jac);
1567+
equation_ = createOdeSystem2(false, false, cont_subsystem_dae, jac, jac_tp);
1568+
then
1569+
equation_;
1570+
/* mixed system of equations, both continous and discrete eqns*/
1571+
case (true,(dlow as DAELow.DAELOW(vars,knvars,exvars,eqns,se,ie,ae,al, ev,eoc)),ass1,ass2,block_)
1572+
equation
1573+
(eqn_lst,var_lst) = Util.listMap32(block_, getEquationAndSolvedVar, eqns, vars, ass2);
1574+
true = isMixedSystem(var_lst,eqn_lst);
1575+
(cont_eqn,cont_var,disc_eqn,disc_var) = splitMixedEquations(eqn_lst, var_lst);
1576+
// States are solved for der(x) not x.
1577+
cont_var1 = Util.listMap(cont_var, transformXToXd);
1578+
vars_1 = DAELow.listVar(cont_var1);
1579+
eqns_1 = DAELow.listEquation(cont_eqn);
1580+
cont_subsystem_dae = DAELow.DAELOW(vars_1,knvars,exvars,eqns_1,se,ie,ae,al,ev,eoc);
1581+
m = DAELow.incidenceMatrix(cont_subsystem_dae);
1582+
m_1 = DAELow.absIncidenceMatrix(m);
1583+
mt_1 = DAELow.transposeMatrix(m_1);
1584+
// calculate jacobian. If constant, linear system of equations.
1585+
// Otherwise nonlinear
1586+
jac = DAELow.calculateJacobian(vars_1, eqns_1, ae, m_1, mt_1,true);
1587+
jac_tp = DAELow.analyzeJacobian(cont_subsystem_dae, jac);
1588+
// (s0,cg_id1,numValues) = generateMixedHeader(cont_eqn, cont_var, disc_eqn, disc_var, cg_id);
1589+
// (Codegen.CFUNCTION(rettp,fn,retrec,arg,locvars,init,stmts,cleanups),cg_id2,extra_funcs1) = generateOdeSystem2(true/*mixed system*/,true,cont_subsystem_dae, jac, jac_tp, cg_id1);
1590+
// stmts_1 = Util.listFlatten({{"{"},locvars,stmts,{"}"}}) "initialization of e.g. matrices for linsys must be done in each
1591+
// iteration, create new scope and put them first." ;
1592+
// s2_1 = Codegen.CFUNCTION(rettp,fn,retrec,arg,{},init,stmts_1,cleanups);
1593+
// (s4,cg_id3) = generateMixedFooter(cont_eqn, cont_var, disc_eqn, disc_var, cg_id2);
1594+
// (s3,cg_id4,_) = generateMixedSystemDiscretePartCheck(disc_eqn, disc_var, cg_id3,numValues);
1595+
// (s1,cg_id5,_) = generateMixedSystemStoreDiscrete(disc_var, 0, cg_id4);
1596+
// cfn = Codegen.cMergeFns({s0,s1,s2_1,s3,s4});
1597+
then
1598+
SES_NOT_IMPLEMENTED("mixed system not implemented");
1599+
/* continuous system of equations */
1600+
case (genDiscrete,(daelow as DAELow.DAELOW(vars,knvars,exvars,eqns,se,ie,ae,al,ev,eoc)),ass1,ass2,block_)
1601+
equation
1602+
// extract the variables and equations of the block.
1603+
(eqn_lst,var_lst) = Util.listMap32(block_, getEquationAndSolvedVar, eqns, vars, ass2);
1604+
// States are solved for der(x) not x.
1605+
var_lst_1 = Util.listMap(var_lst, transformXToXd);
1606+
vars_1 = DAELow.listVar(var_lst_1);
1607+
eqns_1 = DAELow.listEquation(eqn_lst);
1608+
subsystem_dae = DAELow.DAELOW(vars_1,knvars,exvars,eqns_1,se,ie,ae,al,ev,eoc);
1609+
m = DAELow.incidenceMatrix(subsystem_dae);
1610+
m_1 = DAELow.absIncidenceMatrix(m);
1611+
mt_1 = DAELow.transposeMatrix(m_1);
1612+
// calculate jacobian. If constant, linear system of equations. Otherwise nonlinear
1613+
jac = DAELow.calculateJacobian(vars_1, eqns_1, ae, m_1, mt_1,false);
1614+
jac_tp = DAELow.analyzeJacobian(subsystem_dae, jac);
1615+
equation_ = createOdeSystem2(false, genDiscrete, subsystem_dae, jac, jac_tp);
1616+
then
1617+
equation_;
1618+
case (_,_,_,_,_)
1619+
equation
1620+
Error.addMessage(Error.INTERNAL_ERROR, {"createOdeSystem failed"});
1621+
then
1622+
fail();
1623+
end matchcontinue;
1624+
end createOdeSystem;
1625+
1626+
public function createOdeSystem2
1627+
input Boolean mixedEvent "true if generating the mixed system event code";
1628+
input Boolean genDiscrete;
1629+
input DAELow.DAELow inDAELow;
1630+
input Option<list<tuple<Integer, Integer, DAELow.Equation>>> inTplIntegerIntegerDAELowEquationLstOption;
1631+
input DAELow.JacobianType inJacobianType;
1632+
output SimEqSystem equation_;
1633+
algorithm
1634+
equation_ :=
1635+
matchcontinue (mixedEvent,genDiscrete,inDAELow,inTplIntegerIntegerDAELowEquationLstOption,inJacobianType)
1636+
local
1637+
Codegen.CFunction s1,s2,s3,s4,s5,s;
1638+
Integer cg_id_1,cg_id,eqn_size,unique_id,cg_id1,cg_id2,cg_id3,cg_id4,cg_id5;
1639+
list<CFunction> f1;
1640+
DAELow.DAELow dae,d;
1641+
Option<list<tuple<Integer, Integer, DAELow.Equation>>> jac;
1642+
DAELow.JacobianType jac_tp;
1643+
DAELow.Variables v,kv;
1644+
DAELow.EquationArray eqn;
1645+
list<DAELow.Equation> eqn_lst;
1646+
list<DAELow.Var> var_lst;
1647+
list<DAE.ComponentRef> crefs;
1648+
DAELow.MultiDimEquation[:] ae;
1649+
Boolean genDiscrete;
1650+
/* A single array equation */
1651+
case (mixedEvent,_,dae,jac,jac_tp)
1652+
equation
1653+
singleArrayEquation(dae); // fails if not single array eq
1654+
equation_ = createSingleArrayEqnCode(dae, jac);
1655+
then
1656+
equation_;
1657+
// /* A single algorithm section for several variables. */
1658+
//case (mixedEvent,genDiscrete,dae,jac,jac_tp)
1659+
// equation
1660+
// singleAlgorithmSection(dae);
1661+
// (s1,cg_id_1,f1) = generateSingleAlgorithmCode(genDiscrete, dae, jac, cg_id);
1662+
// then
1663+
// (s1,cg_id_1,f1);
1664+
1665+
// /* constant jacobians. Linear system of equations (A x = b) where
1666+
// A and b are constants. TODO: implement symbolic gaussian elimination here. Currently uses dgesv as
1667+
// for next case */
1668+
//case (mixedEvent,genDiscrete,(d as DAELow.DAELOW(orderedVars = v,knownVars = kv,orderedEqs = eqn)),SOME(jac),DAELow.JAC_CONSTANT())
1669+
// local list<tuple<Integer, Integer, DAELow.Equation>> jac;
1670+
// equation
1671+
// eqn_size = DAELow.equationSize(eqn);
1672+
// (s1,cg_id_1,f1) = generateOdeSystem2(mixedEvent,genDiscrete,d, SOME(jac), DAELow.JAC_TIME_VARYING(), cg_id) "NOTE: Not impl. yet, use time_varying..." ;
1673+
// then
1674+
// (s1,cg_id_1,f1);
1675+
1676+
// /* Time varying jacobian. Linear system of equations that needs to
1677+
// be solved during runtime. */
1678+
//case (mixedEvent,_,(d as DAELow.DAELOW(orderedVars = v,knownVars = kv,orderedEqs = eqn)),SOME(jac),DAELow.JAC_TIME_VARYING())
1679+
// local list<tuple<Integer, Integer, DAELow.Equation>> jac;
1680+
// equation
1681+
// //print("linearSystem of equations:");
1682+
// //DAELow.dump(d);
1683+
// //print("Jacobian:");print(DAELow.dumpJacobianStr(SOME(jac)));print("\n");
1684+
// eqn_size = DAELow.equationSize(eqn);
1685+
// unique_id = tick();
1686+
// (s1,cg_id1) = generateOdeSystem2Declaration(mixedEvent,eqn_size, unique_id, cg_id);
1687+
// (s2,cg_id2) = generateOdeSystem2PopulateAb(mixedEvent,jac, v, eqn, unique_id, cg_id1);
1688+
// (s3,cg_id3) = generateOdeSystem2SolveCall(mixedEvent,eqn_size, unique_id, cg_id2);
1689+
// (s4,cg_id4) = generateOdeSystem2CollectResults(mixedEvent,v, unique_id, cg_id3);
1690+
// s = Codegen.cMergeFns({s1,s2,s3,s4});
1691+
// then
1692+
// (s,cg_id4,{});
1693+
//case (mixedEvent,_,DAELow.DAELOW(orderedVars = v,knownVars = kv,orderedEqs = eqn,arrayEqs=ae),SOME(jac),DAELow.JAC_NONLINEAR()) /* Time varying nonlinear jacobian. Non-linear system of equations */
1694+
// local list<tuple<Integer, Integer, DAELow.Equation>> jac;
1695+
// equation
1696+
1697+
// eqn_lst = DAELow.equationList(eqn);
1698+
// var_lst = DAELow.varList(v);
1699+
// crefs = Util.listMap(var_lst, DAELow.varCrefPrefixStates);// get varnames and prefix $der for states.
1700+
// (s1,cg_id_1,f1) = generateOdeSystem2NonlinearResiduals(mixedEvent,crefs, eqn_lst,ae, cg_id);
1701+
// then
1702+
// (s1,cg_id_1,f1);
1703+
//case (mixedEvent,_,DAELow.DAELOW(orderedVars = v,knownVars = kv,orderedEqs = eqn,arrayEqs=ae),NONE,DAELow.JAC_NO_ANALYTIC()) /* no analythic jacobian available. Generate non-linear system */
1704+
// equation
1705+
// eqn_lst = DAELow.equationList(eqn);
1706+
// var_lst = DAELow.varList(v);
1707+
// crefs = Util.listMap(var_lst, DAELow.varCrefPrefixStates); // get varnames and prefix $der for states.
1708+
// (s1,cg_id_1,f1) = generateOdeSystem2NonlinearResiduals(mixedEvent,crefs, eqn_lst, ae, cg_id);
1709+
// then
1710+
// (s1,cg_id_1,f1);
1711+
case (_,_,_,_,_)
1712+
equation
1713+
Error.addMessage(Error.INTERNAL_ERROR, {"createOdeSystem2 failed"});
1714+
then
1715+
SES_NOT_IMPLEMENTED("some case in createOdeSystem2 not implemented");
1716+
end matchcontinue;
1717+
end createOdeSystem2;
1718+
1719+
public function createSingleArrayEqnCode
1720+
input DAELow.DAELow inDAELow;
1721+
input Option<list<tuple<Integer, Integer, DAELow.Equation>>> inTplIntegerIntegerDAELowEquationLstOption;
1722+
output SimEqSystem equation_;
1723+
algorithm
1724+
equation_ :=
1725+
matchcontinue (inDAELow,inTplIntegerIntegerDAELowEquationLstOption)
1726+
local
1727+
Integer indx,cg_id_1,cg_id;
1728+
list<Integer> ds;
1729+
DAE.Exp e1,e2;
1730+
DAE.ComponentRef cr,origname,cr_1;
1731+
Codegen.CFunction s1;
1732+
list<CFunction> f1;
1733+
DAELow.Variables vars,knvars;
1734+
DAELow.EquationArray eqns,se,ie;
1735+
DAELow.MultiDimEquation[:] ae;
1736+
Algorithm.Algorithm[:] al;
1737+
DAELow.EventInfo ev;
1738+
Option<list<tuple<Integer, Integer, DAELow.Equation>>> jac;
1739+
case (DAELow.DAELOW(orderedVars = vars,
1740+
knownVars = knvars,
1741+
orderedEqs = eqns,
1742+
removedEqs = se,
1743+
initialEqs = ie,
1744+
arrayEqs = ae,
1745+
algorithms = al,
1746+
eventInfo = ev),jac) /* eqn code cg var_id extra functions */
1747+
local String cr_1_str;
1748+
equation
1749+
(DAELow.ARRAY_EQUATION(indx,_) :: _) = DAELow.equationList(eqns);
1750+
DAELow.MULTIDIM_EQUATION(ds,e1,e2) = ae[indx + 1];
1751+
((DAELow.VAR(cr,_,_,_,_,_,_,_,origname,_,_,_,_,_) :: _)) = DAELow.varList(vars);
1752+
// We need to strip subs from origname since they are removed in cr.
1753+
cr_1 = Exp.crefStripLastSubs(origname);
1754+
// Since we use origname we need to replace '.' with '$P' manually.
1755+
cr_1_str = Util.modelicaStringToCStr(Exp.printComponentRefStr(cr_1),true); // stringAppend("$",Util.modelicaStringToCStr(Exp.printComponentRefStr(cr_1),true));
1756+
cr_1 = DAE.CREF_IDENT(cr_1_str,DAE.ET_OTHER(),{});
1757+
(e1,e2) = solveTrivialArrayEquation(cr_1,e1,e2);
1758+
equation_ = createSingleArrayEqnCode2(cr_1, cr_1, e1, e2);
1759+
then
1760+
equation_;
1761+
case (_,_)
1762+
equation
1763+
Error.addMessage(Error.INTERNAL_ERROR,{"array equations currently only supported on form v = functioncall(...)"});
1764+
then
1765+
fail();
1766+
end matchcontinue;
1767+
end createSingleArrayEqnCode;
1768+
1769+
// TODO: are the cases really correct?
1770+
public function createSingleArrayEqnCode2
1771+
input DAE.ComponentRef inComponentRef1;
1772+
input DAE.ComponentRef inComponentRef2;
1773+
input DAE.Exp inExp3;
1774+
input DAE.Exp inExp4;
1775+
output SimEqSystem equation_;
1776+
algorithm
1777+
equation_ :=
1778+
matchcontinue (inComponentRef1,inComponentRef2,inExp3,inExp4)
1779+
local
1780+
String s1,s2,stmt,s3,s4,s;
1781+
Codegen.CFunction cfunc,func_1;
1782+
Integer cg_id_1,cg_id;
1783+
DAE.ComponentRef cr,eltcr,cr2;
1784+
DAE.Exp e1,e2;
1785+
case (cr,eltcr,(e1 as DAE.CREF(componentRef = cr2)),e2)
1786+
equation
1787+
true = Exp.crefEqual(cr, cr2);
1788+
s1 = Exp.printComponentRefStr(eltcr);
1789+
//(cfunc,s2,cg_id_1) = Codegen.generateExpression(e2, cg_id, Codegen.simContext);
1790+
//stmt = Util.stringAppendList({"copy_real_array_data_mem(&",s2,", &",s1,");"});
1791+
then
1792+
SES_ARRAY_CALL_ASSIGN(eltcr, e2);
1793+
case (cr,eltcr,e1,(e2 as DAE.CREF(componentRef = cr2)))
1794+
equation
1795+
true = Exp.crefEqual(cr, cr2);
1796+
s1 = Exp.printComponentRefStr(eltcr);
1797+
//(cfunc,s2,cg_id_1) = Codegen.generateExpression(e1, cg_id, Codegen.simContext);
1798+
//stmt = Util.stringAppendList({"copy_real_array_data_mem(&",s1,", &",s2,");"});
1799+
then
1800+
SES_ARRAY_CALL_ASSIGN(eltcr, e1);
1801+
case (cr,eltcr,e1,e2) /* e2 is array of crefs, {v{1},v{2},...v{n}} */
1802+
equation
1803+
cr2 = getVectorizedCrefFromExp(e2);
1804+
s1 = Exp.printComponentRefStr(eltcr);
1805+
//(cfunc,s2,cg_id_1) = Codegen.generateExpression(e1, cg_id, Codegen.simContext);
1806+
//stmt = Util.stringAppendList({"copy_real_array_data_mem(&",s1,", &",s2,");"});
1807+
then
1808+
SES_ARRAY_CALL_ASSIGN(cr2, e1);
1809+
case (cr,eltcr,e1,e2) /* e1 is array of crefs, {v{1},v{2},...v{n}} */
1810+
equation
1811+
cr2 = getVectorizedCrefFromExp(e1);
1812+
s1 = Exp.printComponentRefStr(eltcr);
1813+
//(cfunc,s2,cg_id_1) = Codegen.generateExpression(e2, cg_id, Codegen.simContext);
1814+
//stmt = Util.stringAppendList({"copy_real_array_data_mem(&",s2,", &",s1,");"});
1815+
then
1816+
SES_ARRAY_CALL_ASSIGN(cr2, e2);
1817+
case (_,_,_,_)
1818+
equation
1819+
Error.addMessage(Error.INTERNAL_ERROR, {"createSingleArrayEqnCode2 failed"});
1820+
then
1821+
fail();
1822+
end matchcontinue;
1823+
end createSingleArrayEqnCode2;
1824+
15051825
protected function createResidualEquations
15061826
input DAELow.DAELow dlow;
15071827
input Integer[:] ass1;

0 commit comments

Comments
 (0)