Skip to content

Commit 76dc250

Browse files
ptaeuberOpenModelica-Hudson
authored andcommitted
Match more nonlinear equations first while tearing
1 parent b95b469 commit 76dc250

1 file changed

Lines changed: 93 additions & 13 deletions

File tree

Compiler/BackEnd/Tearing.mo

Lines changed: 93 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,7 +1695,7 @@ author: ptaeuber FHB 2013-2016"
16951695
output Boolean outRunMatching;
16961696
protected
16971697
Integer size, tornsize;
1698-
array<Integer> ass1, ass2, mapIncRowEqn;
1698+
array<Integer> ass1, ass2, mapIncRowEqn, eqnNonlinPoints;
16991699
array<list<Integer>> mapEqnIncRow;
17001700
list<Integer> OutTVars, residual, residual_coll, order, unsolvables, discreteVars, tSel_always, tSel_prefer, tSel_avoid,tSel_never;
17011701
BackendDAE.InnerEquations innerEquations;
@@ -1773,17 +1773,22 @@ algorithm
17731773

17741774
// Determine unsolvable vars to consider solvability
17751775
unsolvables := getUnsolvableVars(size,meT);
1776+
1777+
// Determine a weight for the nonlinearity of each equation
1778+
eqnNonlinPoints := arrayCreate(size, -1);
1779+
getEquationNonlinearityPoints(eqnNonlinPoints, me, size);
17761780
if debug then execStat("Tearing.CellierTearing -> 2"); end if;
17771781

17781782
if Flags.isSet(Flags.TEARING_DUMP) or Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
17791783
print("\nAdjacencyMatrixEnhanced:\n");
17801784
BackendDump.dumpAdjacencyMatrixEnhanced(me);
17811785
print("\nAdjacencyMatrixTransposedEnhanced:\n");
17821786
BackendDump.dumpAdjacencyMatrixTEnhanced(meT);
1787+
print("\neqLinPoints:\n" + stringDelimitList(List.map(arrayList(eqnNonlinPoints),intString),",") + "\n\n");
17831788
end if;
17841789

17851790
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
1786-
print("\n\nmapEqnIncRow:"); //+ stringDelimitList(List.map(List.flatten(arrayList(mapEqnIncRow)),intString),",") + "\n\n");
1791+
print("mapEqnIncRow:"); //+ stringDelimitList(List.map(List.flatten(arrayList(mapEqnIncRow)),intString),",") + "\n\n");
17871792
BackendDump.dumpIncidenceMatrix(mapEqnIncRow);
17881793
print("\nmapIncRowEqn:\n" + stringDelimitList(List.map(arrayList(mapIncRowEqn),intString),",") + "\n\n");
17891794
print("\n\nUNSOLVABLES:\n" + stringDelimitList(List.map(unsolvables,intString),",") + "\n\n");
@@ -1811,7 +1816,7 @@ algorithm
18111816
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
18121817
print("\n" + BORDER + "\nBEGINNING of CellierTearing2\n\n");
18131818
end if;
1814-
(OutTVars, order) := CellierTearing2(false,m,mt,me,meT,ass1,ass2,unsolvables,{},discreteVars,tSel_always,tSel_prefer,tSel_avoid,tSel_never,order,mapEqnIncRow,mapIncRowEqn);
1819+
(OutTVars, order) := CellierTearing2(false,m,mt,me,meT,ass1,ass2,unsolvables,{},discreteVars,tSel_always,tSel_prefer,tSel_avoid,tSel_never,order,mapEqnIncRow,mapIncRowEqn,eqnNonlinPoints);
18151820
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
18161821
print("\nEND of CellierTearing2\n" + BORDER + "\n\n");
18171822
end if;
@@ -1879,10 +1884,11 @@ algorithm
18791884
BackendDump.dumpAdjacencyMatrixEnhanced(me);
18801885
print("\nAdjacencyMatrixTransposedEnhanced:\n");
18811886
BackendDump.dumpAdjacencyMatrixTEnhanced(meT);
1887+
print("\neqLinPoints:\n" + stringDelimitList(List.map(arrayList(eqnNonlinPoints),intString),",") + "\n\n");
18821888
end if;
18831889

18841890
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
1885-
print("\n\nmapEqnIncRow:"); //+ stringDelimitList(List.map(List.flatten(arrayList(mapEqnIncRow)),intString),",") + "\n\n");
1891+
print("mapEqnIncRow:"); //+ stringDelimitList(List.map(List.flatten(arrayList(mapEqnIncRow)),intString),",") + "\n\n");
18861892
BackendDump.dumpIncidenceMatrix(mapEqnIncRow);
18871893
print("\nmapIncRowEqn:\n" + stringDelimitList(List.map(arrayList(mapIncRowEqn),intString),",") + "\n\n");
18881894
print("\n\nUNSOLVABLES:\n" + stringDelimitList(List.map(unsolvables,intString),",") + "\n\n");
@@ -1897,7 +1903,7 @@ algorithm
18971903
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
18981904
print("\n" + BORDER + "\nBEGINNING of CellierTearing2\n\n");
18991905
end if;
1900-
(OutTVars, order) := CellierTearing2(false,m,mt,me,meT,ass1,ass2,unsolvables,{},discreteVars,tSel_always,tSel_prefer,tSel_avoid,tSel_never,order,mapEqnIncRow,mapIncRowEqn);
1906+
(OutTVars, order) := CellierTearing2(false,m,mt,me,meT,ass1,ass2,unsolvables,{},discreteVars,tSel_always,tSel_prefer,tSel_avoid,tSel_never,order,mapEqnIncRow,mapIncRowEqn,eqnNonlinPoints);
19011907
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
19021908
print("\nEND of CellierTearing2\n" + BORDER + "\n\n");
19031909
end if;
@@ -2053,6 +2059,48 @@ algorithm
20532059
end findDiscrete;
20542060

20552061

2062+
protected function getEquationNonlinearityPoints
2063+
"Function returns an array with an integer assessment of the nonlinearity
2064+
author: ptaeuber"
2065+
input output array<Integer> eqnNonlinPoints;
2066+
input BackendDAE.AdjacencyMatrixEnhanced me;
2067+
input Integer size;
2068+
protected
2069+
BackendDAE.AdjacencyMatrixElementEnhanced row;
2070+
Integer sum;
2071+
algorithm
2072+
for i in 1:size loop
2073+
row := me[i];
2074+
sum := 0;
2075+
for entry in row loop
2076+
sum := sum + nonlinearityWeight(entry);
2077+
end for;
2078+
eqnNonlinPoints[i] := sum;
2079+
end for;
2080+
end getEquationNonlinearityPoints;
2081+
2082+
2083+
protected function nonlinearityWeight
2084+
"Function returns a weight for specific solvability
2085+
author: ptaeuber"
2086+
input BackendDAE.AdjacencyMatrixElementEnhancedEntry entry;
2087+
output Integer weight;
2088+
algorithm
2089+
weight := match(entry)
2090+
case(_, BackendDAE.SOLVABILITY_SOLVED(), _) then 0;
2091+
case(_, BackendDAE.SOLVABILITY_CONSTONE(), _) then 2;
2092+
case(_, BackendDAE.SOLVABILITY_CONST(), _) then 5;
2093+
case(_, BackendDAE.SOLVABILITY_PARAMETER(b=true), _) then 10;
2094+
case(_, BackendDAE.SOLVABILITY_PARAMETER(b=false), _) then 20;
2095+
case(_, BackendDAE.SOLVABILITY_LINEAR(b=true), _) then 20;
2096+
case(_, BackendDAE.SOLVABILITY_LINEAR(b=false), _) then 50;
2097+
case(_, BackendDAE.SOLVABILITY_NONLINEAR(), _) then 50;
2098+
case(_, BackendDAE.SOLVABILITY_UNSOLVABLE(), _) then 100;
2099+
else 0;
2100+
end match;
2101+
end nonlinearityWeight;
2102+
2103+
20562104
protected function CellierTearing2 " function to call tearing heuristic and matching algorithm
20572105
author: ptaeuber FHB 2013-2015"
20582106
input Boolean inCausal;
@@ -2064,6 +2112,7 @@ protected function CellierTearing2 " function to call tearing heuristic and matc
20642112
input list<Integer> Unsolvables,tvarsIn,discreteVars,tSel_always,tSel_prefer,tSel_avoid,tSel_never,orderIn;
20652113
input array<list<Integer>> mapEqnIncRow;
20662114
input array<Integer> mapIncRowEqn;
2115+
input array<Integer> eqnNonlinPoints;
20672116
output list<Integer> OutTVars;
20682117
output list<Integer> orderOut;
20692118
protected
@@ -2117,7 +2166,7 @@ algorithm
21172166
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
21182167
print("\n" + BORDER + "\nBEGINNING of TarjanMatching\n\n");
21192168
end if;
2120-
(order,causal) = TarjanMatching(mIn,mtIn,meIn,meTIn,ass1In,ass2In,orderIn,{},mapEqnIncRow,mapIncRowEqn);
2169+
(order,causal) = TarjanMatching(mIn,mtIn,meIn,meTIn,ass1In,ass2In,orderIn,{},mapEqnIncRow,mapIncRowEqn,eqnNonlinPoints);
21212170
if debug then execStat("Tearing.CellierTearing2 - 1.2"); end if;
21222171
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
21232172
print("\nEND of TarjanMatching\n" + BORDER + "\n\n");
@@ -2138,7 +2187,7 @@ algorithm
21382187

21392188
if debug then execStat("Tearing.CellierTearing2 - 1 done"); end if;
21402189
// repeat until system is causal
2141-
(tvars, order) = CellierTearing2(causal,mIn,mtIn,meIn,meTIn,ass1In,ass2In,unsolvables,tvars,discreteVars,tSel_always,tSel_prefer,tSel_avoid,tSel_never,order,mapEqnIncRow,mapIncRowEqn);
2190+
(tvars, order) = CellierTearing2(causal,mIn,mtIn,meIn,meTIn,ass1In,ass2In,unsolvables,tvars,discreteVars,tSel_always,tSel_prefer,tSel_avoid,tSel_never,order,mapEqnIncRow,mapIncRowEqn,eqnNonlinPoints);
21422191

21432192
then
21442193
(tvars,order);
@@ -2179,7 +2228,7 @@ algorithm
21792228
tvars = listAppend(tvars,tvarsIn);
21802229

21812230
// assign vars to eqs until complete or partially causalisation(and restart algorithm)
2182-
(order,causal) = TarjanMatching(mIn,mtIn,meIn,meTIn,ass1In,ass2In,orderIn,{},mapEqnIncRow,mapIncRowEqn);
2231+
(order,causal) = TarjanMatching(mIn,mtIn,meIn,meTIn,ass1In,ass2In,orderIn,{},mapEqnIncRow,mapIncRowEqn,eqnNonlinPoints);
21832232
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
21842233
print("\nEND of TarjanMatching\n" + BORDER + "\n\n");
21852234
print("\n" + BORDER + "\n* TARJAN RESULTS:\n* ass1: " + stringDelimitList(List.map(arrayList(ass1In),intString),",")+"\n");
@@ -2198,7 +2247,7 @@ algorithm
21982247

21992248
if debug then execStat("Tearing.CellierTearing2 - 2"); end if;
22002249
// repeat until system is causal
2201-
(tvars, order) = CellierTearing2(causal,mIn,mtIn,meIn,meTIn,ass1In,ass2In,unsolvables,tvars,discreteVars,{},tSel_prefer,tSel_avoid,tSel_never,order,mapEqnIncRow,mapIncRowEqn);
2250+
(tvars, order) = CellierTearing2(causal,mIn,mtIn,meIn,meTIn,ass1In,ass2In,unsolvables,tvars,discreteVars,{},tSel_prefer,tSel_avoid,tSel_never,order,mapEqnIncRow,mapIncRowEqn,eqnNonlinPoints);
22022251

22032252
then
22042253
(tvars, order);
@@ -3231,6 +3280,7 @@ protected function TarjanMatching "Modified matching algorithm according to Tarj
32313280
input list<Integer> eqQueueIn;
32323281
input array<list<Integer>> mapEqnIncRow;
32333282
input array<Integer> mapIncRowEqn;
3283+
input array<Integer> eqnNonlinPoints;
32343284
output list<Integer> orderOut;
32353285
output Boolean causal;
32363286
protected
@@ -3243,7 +3293,7 @@ algorithm
32433293
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
32443294
print("\nTarjanAssignment:\n");
32453295
end if;
3246-
(eqQueue,order,assignable) := TarjanAssignment(eqQueue,mIn,mtIn,meIn,metIn,ass1In,ass2In,order,mapEqnIncRow,mapIncRowEqn);
3296+
(eqQueue,order,assignable) := TarjanAssignment(eqQueue,mIn,mtIn,meIn,metIn,ass1In,ass2In,order,mapEqnIncRow,mapIncRowEqn,eqnNonlinPoints);
32473297
end while;
32483298
if debug then execStat("Tearing.TarjanMatching iters done"); end if;
32493299

@@ -3276,6 +3326,7 @@ author: ptaeuber FHB 2013-2015"
32763326
input list<Integer> orderIn;
32773327
input array<list<Integer>> mapEqnIncRow;
32783328
input array<Integer> mapIncRowEqn;
3329+
input array<Integer> eqnNonlinPoints;
32793330
output list<Integer> eqQueueOut;
32803331
output list<Integer> orderOut = orderIn;
32813332
output Boolean assignable = false;
@@ -3308,7 +3359,7 @@ algorithm
33083359

33093360
// Get the next solvable equation from the equation queue
33103361
try
3311-
(eqQueueOut,eq_coll,eqns,vars) := getNextSolvableEqn(eqQueueOut,mIn,meIn,ass1In,mapEqnIncRow);
3362+
(eqQueueOut,eq_coll,eqns,vars) := getNextSolvableEqn(eqQueueOut,mIn,meIn,ass1In,mapEqnIncRow,mapIncRowEqn,eqnNonlinPoints);
33123363
orderOut := eq_coll::orderOut;
33133364
assignable := true;
33143365
else
@@ -3450,6 +3501,8 @@ protected function getNextSolvableEqn " finds equation that can be matched with
34503501
input BackendDAE.AdjacencyMatrixEnhanced me;
34513502
input array<Integer> ass1;
34523503
input array<list<Integer>> mapEqnIncRow;
3504+
input array<Integer> mapIncRowEqn;
3505+
input array<Integer> eqnNonlinPoints;
34533506
output list<Integer> eqQueueOut = eqQueueIn;
34543507
output Integer eqOut;
34553508
output list<Integer> eqnsOut;
@@ -3458,7 +3511,11 @@ protected
34583511
Boolean solvable = false;
34593512
algorithm
34603513
while not listEmpty(eqQueueOut) loop
3461-
eqOut::eqQueueOut := eqQueueOut;
3514+
eqOut := getMostNonlinearEquation(eqnNonlinPoints, eqQueueOut, mapEqnIncRow, mapIncRowEqn);
3515+
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
3516+
print("Most nonlinear equation: " + intString(eqOut) + "\n");
3517+
end if;
3518+
eqQueueOut := List.deleteMember(eqQueueOut, eqOut);
34623519
(solvable, eqnsOut, varsOut) := eqnSolvableCheck(eqOut, mapEqnIncRow, ass1, m, me);
34633520
if solvable then break; end if;
34643521
end while;
@@ -3588,6 +3645,29 @@ algorithm
35883645
end maxListInt;
35893646

35903647

3648+
protected function getMostNonlinearEquation
3649+
"Function to find maximum Integers in a selection of inArray and outputs the first index.
3650+
author: ptaeuber"
3651+
input array<Integer> inArray;
3652+
input list<Integer> inList;
3653+
input array<list<Integer>> mapEqnIncRow;
3654+
input array<Integer> mapIncRowEqn;
3655+
output Integer index=1;
3656+
protected
3657+
Integer maxi;
3658+
algorithm
3659+
maxi := max(inArray[listHead(mapEqnIncRow[i])] for i in inList);
3660+
3661+
for i in inList loop
3662+
index := listHead(mapEqnIncRow[i]);
3663+
if inArray[index] == maxi then
3664+
index := mapIncRowEqn[index];
3665+
return;
3666+
end if;
3667+
end for;
3668+
end getMostNonlinearEquation;
3669+
3670+
35913671
protected function selectFromList_rev" selects Ints from inList by indexes given in selList
35923672
author: Waurich TUD 2012-11"
35933673
input List<Integer> inList,selList;
@@ -4677,7 +4757,7 @@ algorithm
46774757
end if;
46784758
while not listEmpty(causEq) loop
46794759
try
4680-
(_,e,e_exp,vars) := getNextSolvableEqn(causEq,m,me,ass1,mapEqnIncRow);
4760+
(_,e,e_exp,vars) := getNextSolvableEqn(causEq,m,me,ass1,mapEqnIncRow,mapIncRowEqn,ass1);
46814761
else
46824762
if Flags.isSet(Flags.TEARING_DUMPVERBOSE) then
46834763
print("\nMatching failed, choose different tearing set!\n\n\n");

0 commit comments

Comments
 (0)