@@ -58,6 +58,14 @@ protected import System;
58
58
protected import CevalScript ;
59
59
60
60
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
+
61
69
public
62
70
function listLengthStr
63
71
input list< String > lst;
@@ -290,6 +298,13 @@ uniontype SimEqSystem
290
298
DAE . ComponentRef componentRef;
291
299
DAE . Exp exp;
292
300
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 ;
293
308
end SimEqSystem ;
294
309
295
310
uniontype SimWhenClause
@@ -1491,17 +1506,322 @@ algorithm
1491
1506
/* multiple equations that must be solved together (algebraic loop) */
1492
1507
case (dae, dlow, ass1, ass2, eqNum :: restEqNums)
1493
1508
equation
1494
- Error . addMessage( Error . INTERNAL_ERROR , { "createEquation failed: algebraic loops not implemented yet" } );
1509
+ equation_ = createOdeSystem( false , dlow, ass1, ass2, eqNum :: restEqNums );
1495
1510
then
1496
- SES_SIMPLE_ASSIGN ( DAE . WILD , DAE . ICONST ( 1 )) ;
1511
+ equation_ ;
1497
1512
case (_,_,_,_,_)
1498
- equation
1499
- Error . addMessage(Error . INTERNAL_ERROR , {"createEquation failed" });
1500
1513
then
1501
- SES_SIMPLE_ASSIGN ( DAE . WILD , DAE . ICONST ( 2 ) );
1514
+ SES_NOT_IMPLEMENTED ( "none of cases in createEquation succeeded" );
1502
1515
end matchcontinue;
1503
1516
end createEquation;
1504
1517
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
+
1505
1825
protected function createResidualEquations
1506
1826
input DAELow . DAELow dlow;
1507
1827
input Integer [:] ass1;
0 commit comments