Skip to content

Commit 188b3c3

Browse files
authored
[NB] refine adjacency matrix (#12298)
* [NB] start minimal tearing * [NB] update strong component after tearing method * [NB] new tearing utility - start Adjacency.Matrix.refine which refines solvabilty information - apply tearingFinalize on implicitely solved equations
1 parent a842deb commit 188b3c3

File tree

3 files changed

+90
-32
lines changed

3 files changed

+90
-32
lines changed

OMCompiler/Compiler/NBackEnd/Modules/3_Post/NBTearing.mo

Lines changed: 44 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ protected
4848
import Tearing = NBTearing;
4949

5050
// NF imports
51+
import ComponentRef = NFComponentRef;
5152
import NFFlatten.FunctionTree;
5253
import Variable = NFVariable;
5354

@@ -121,30 +122,29 @@ public
121122
bdae := match (systemType, bdae)
122123
local
123124
list<System.System> systems;
124-
VariablePointers variables;
125125
Pointer<Integer> eq_index;
126126

127-
case (NBSystem.SystemType.ODE, BackendDAE.MAIN(ode = systems, funcTree = funcTree, varData = BVariable.VAR_DATA_SIM(variables = variables), eqData = BEquation.EQ_DATA_SIM(uniqueIndex = eq_index)))
127+
case (NBSystem.SystemType.ODE, BackendDAE.MAIN(ode = systems, funcTree = funcTree, eqData = BEquation.EQ_DATA_SIM(uniqueIndex = eq_index)))
128128
algorithm
129-
(systems, funcTree) := tearingTraverser(systems, funcs, funcTree, variables, eq_index, systemType);
129+
(systems, funcTree) := tearingTraverser(systems, funcs, funcTree, eq_index, systemType);
130130
bdae.ode := systems;
131131
bdae.funcTree := funcTree;
132132
then bdae;
133133

134-
case (NBSystem.SystemType.INI, BackendDAE.MAIN(init = systems, funcTree = funcTree, varData = BVariable.VAR_DATA_SIM(variables = variables), eqData = BEquation.EQ_DATA_SIM(uniqueIndex = eq_index)))
134+
case (NBSystem.SystemType.INI, BackendDAE.MAIN(init = systems, funcTree = funcTree, eqData = BEquation.EQ_DATA_SIM(uniqueIndex = eq_index)))
135135
algorithm
136-
(systems, funcTree) := tearingTraverser(systems, funcs, funcTree, variables, eq_index, systemType);
136+
(systems, funcTree) := tearingTraverser(systems, funcs, funcTree, eq_index, systemType);
137137
bdae.init := systems;
138138
if Util.isSome(bdae.init_0) then
139-
(systems, funcTree) := tearingTraverser(Util.getOption(bdae.init_0), funcs, funcTree, variables, eq_index, systemType);
139+
(systems, funcTree) := tearingTraverser(Util.getOption(bdae.init_0), funcs, funcTree, eq_index, systemType);
140140
bdae.init_0 := SOME(systems);
141141
end if;
142142
bdae.funcTree := funcTree;
143143
then bdae;
144144

145-
case (NBSystem.SystemType.DAE, BackendDAE.MAIN(dae = SOME(systems), funcTree = funcTree, varData = BVariable.VAR_DATA_SIM(variables = variables), eqData = BEquation.EQ_DATA_SIM(uniqueIndex = eq_index)))
145+
case (NBSystem.SystemType.DAE, BackendDAE.MAIN(dae = SOME(systems), funcTree = funcTree, eqData = BEquation.EQ_DATA_SIM(uniqueIndex = eq_index)))
146146
algorithm
147-
(systems, funcTree) := tearingTraverser(systems, funcs, funcTree, variables, eq_index, systemType);
147+
(systems, funcTree) := tearingTraverser(systems, funcs, funcTree, eq_index, systemType);
148148
bdae.dae := SOME(systems);
149149
bdae.funcTree := funcTree;
150150
then bdae;
@@ -161,26 +161,36 @@ public
161161
protected
162162
// dummy adjacency matrix, dont need it for tearingNone()
163163
Adjacency.Matrix dummy = Adjacency.EMPTY(NBAdjacency.MatrixStrictness.FULL);
164+
list<Module.tearingInterface> funcs = {tearingNone, tearingFinalize};
165+
StrongComponent new_comp;
164166
algorithm
165167
(comp, dummy, funcTree, index) := match comp
166168
// create implicit equations
167-
case StrongComponent.SINGLE_COMPONENT()
168-
then tearingNone(StrongComponent.ALGEBRAIC_LOOP(
169-
idx = index,
170-
strict = singleImplicit(comp.var, comp.eqn),
171-
casual = NONE(),
172-
linear = false,
173-
mixed = false,
174-
status = NBSolve.Status.IMPLICIT), dummy, funcTree, index, VariablePointers.empty(), Pointer.create(0), systemType);
175-
176-
case StrongComponent.MULTI_COMPONENT()
177-
then tearingNone(StrongComponent.ALGEBRAIC_LOOP(
178-
idx = index,
179-
strict = singleImplicit(List.first(comp.vars), comp.eqn), // this is wrong! need to take all vars
180-
casual = NONE(),
181-
linear = false,
182-
mixed = false,
183-
status = NBSolve.Status.IMPLICIT), dummy, funcTree, index, VariablePointers.empty(), Pointer.create(0), systemType);
169+
case StrongComponent.SINGLE_COMPONENT() algorithm
170+
new_comp := StrongComponent.ALGEBRAIC_LOOP(
171+
idx = index,
172+
strict = singleImplicit(comp.var, comp.eqn),
173+
casual = NONE(),
174+
linear = false,
175+
mixed = false,
176+
status = NBSolve.Status.IMPLICIT);
177+
for func in funcs loop
178+
(new_comp, dummy, funcTree, index) := func(new_comp, dummy, funcTree, index, VariablePointers.empty(), EquationPointers.empty(), Pointer.create(0), systemType);
179+
end for;
180+
then (new_comp, dummy, funcTree, index);
181+
182+
case StrongComponent.MULTI_COMPONENT() algorithm
183+
new_comp := StrongComponent.ALGEBRAIC_LOOP(
184+
idx = index,
185+
strict = singleImplicit(List.first(comp.vars), comp.eqn), // this is wrong! need to take all vars
186+
casual = NONE(),
187+
linear = false,
188+
mixed = false,
189+
status = NBSolve.Status.IMPLICIT);
190+
for func in funcs loop
191+
(new_comp, dummy, funcTree, index) := func(new_comp, dummy, funcTree, index, VariablePointers.empty(), EquationPointers.empty(), Pointer.create(0), systemType);
192+
end for;
193+
then (new_comp, dummy, funcTree, index);
184194

185195
// do nothing otherwise
186196
else (comp, dummy, funcTree, index);
@@ -234,7 +244,6 @@ protected
234244
input list<Module.tearingInterface> funcs;
235245
output list<System.System> new_systems = {};
236246
input output FunctionTree funcTree;
237-
input VariablePointers variables;
238247
input Pointer<Integer> eq_index;
239248
input System.SystemType systemType;
240249
protected
@@ -251,7 +260,7 @@ protected
251260
// each module has a list of functions that need to be applied
252261
tmp := strongComponents[i];
253262
for func in funcs loop
254-
(tmp, full, funcTree, idx) := func(tmp, full, funcTree, idx, variables, eq_index, systemType);
263+
(tmp, full, funcTree, idx) := func(tmp, full, funcTree, idx, syst.unknowns, syst.equations, eq_index, systemType);
255264
end for;
256265
// only update if it changed
257266
if not referenceEq(tmp, strongComponents[i]) then
@@ -288,7 +297,6 @@ protected
288297
comps = listArray(residual_comps),
289298
funcTree = funcTree,
290299
name = System.System.systemTypeString(systemType) + tag + intString(index));
291-
292300
strict.jac := jacobian;
293301
comp.strict := strict;
294302
if Flags.isSet(Flags.TEARING_DUMP) then
@@ -346,8 +354,9 @@ protected
346354
Adjacency.Matrix adj;
347355
Matching matching;
348356
list<StrongComponent> inner_comps, residual_comps;
357+
UnorderedMap<ComponentRef, Integer> v, e;
349358
algorithm
350-
//print("######## minimal ########\n");
359+
print("######## minimal ########\n");
351360
(comp, index) := match comp
352361
case StrongComponent.ALGEBRAIC_LOOP(strict = strict) algorithm
353362

@@ -356,8 +365,12 @@ protected
356365
(cont_vars, disc_vars) := List.splitOnTrue(vars_lst, BVariable.isContinuous);
357366
(cont_eqns, disc_eqns) := List.splitOnTrue(eqns_lst, Equation.isContinuous);
358367

359-
//print(List.toString(disc_vars, function BVariable.pointerToString()) + "\n");
360-
//print(List.toString(disc_eqns, function Equation.pointerToString(str = "")) + "\n");
368+
print(List.toString(disc_vars, function BVariable.pointerToString(), "", "", "\n", "") + "\n");
369+
print(List.toString(disc_eqns, function Equation.pointerToString(str = ""), "", "", "\n", "") + "\n");
370+
v := UnorderedMap.subSet(variables.map, list(BVariable.getVarName(var) for var in disc_vars));
371+
e := UnorderedMap.subSet(equations.map, list(Equation.getEqnName(eqn) for eqn in disc_eqns));
372+
(full, funcTree) := Adjacency.Matrix.refine(full, funcTree, v, e, variables, equations);
373+
361374

362375
/*
363376

OMCompiler/Compiler/NBackEnd/Modules/NBModule.mo

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@ public
291291
input output FunctionTree funcTree "Function call bodies";
292292
input output Integer index "current unique loop index";
293293
input VariablePointers variables "all variables";
294+
input EquationPointers equations "all equations";
294295
input Pointer<Integer> eq_index "equation index";
295296
input System.SystemType systemType = NBSystem.SystemType.ODE "system type";
296297
end tearingInterface;

OMCompiler/Compiler/NBackEnd/Util/NBAdjacency.mo

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,13 +44,15 @@ protected
4444
import Dimension = NFDimension;
4545
import Expression = NFExpression;
4646
import FunctionTree = NFFlatten.FunctionTree;
47+
import SimplifyExp = NFSimplifyExp;
4748
import Subscript = NFSubscript;
4849
import Type = NFType;
4950
import Operator = NFOperator;
5051
import Variable = NFVariable;
5152

5253
// NB imports
5354
import Differentiate = NBDifferentiate;
55+
import NBDifferentiate.{DifferentiationArguments, DifferentiationType};
5456
import BEquation = NBEquation;
5557
import NBEquation.{Equation, EquationAttributes, EquationPointers, Iterator, IfEquationBody, WhenEquationBody, WhenStatement};
5658
import BVariable = NBVariable;
@@ -686,8 +688,9 @@ public
686688
end for;
687689
end if;
688690
then full;
691+
689692
else algorithm
690-
Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " expected types final, got type " + strictnessString(getStrictness(full)) + "."});
693+
Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " expected type full, got type " + strictnessString(getStrictness(full)) + "."});
691694
then fail();
692695
end match;
693696

@@ -696,6 +699,47 @@ public
696699
end if;
697700
end expandFull;
698701

702+
function refine
703+
"refines the solvability kind using differentiation
704+
Note: only updates the solvabilites of the variables and equations from the maps"
705+
input output Matrix full;
706+
input output FunctionTree funcTree;
707+
input UnorderedMap<ComponentRef, Integer> v "variables to refine";
708+
input UnorderedMap<ComponentRef, Integer> e "equations to refine";
709+
input VariablePointers vars "all variables";
710+
input EquationPointers eqns "all equations";
711+
algorithm
712+
full := match full
713+
local
714+
ComponentRef eqn, var;
715+
Integer eqn_idx, var_idx;
716+
DifferentiationArguments diffArgs;
717+
Pointer<Equation> eqn_ptr;
718+
Expression exp;
719+
720+
case FULL() algorithm
721+
for v_tpl in UnorderedMap.toList(v) loop
722+
(var, var_idx) := v_tpl;
723+
diffArgs := DifferentiationArguments.default(NBDifferentiate.DifferentiationType.SIMPLE, funcTree);
724+
diffArgs.diffCref := var;
725+
for e_tpl in UnorderedMap.toList(e) loop
726+
(eqn, eqn_idx) := e_tpl;
727+
eqn_ptr := EquationPointers.getEqnAt(eqns, eqn_idx);
728+
// get the residual expression, differentiate and simplify it
729+
exp := Equation.getResidualExp(Pointer.access(eqn_ptr));
730+
(exp, diffArgs) := Differentiate.differentiateExpressionDump(exp, diffArgs, getInstanceName());
731+
exp := SimplifyExp.simplifyDump(exp, true, getInstanceName());
732+
print("the partial derivative by " + ComponentRef.toString(var) + " of equation\n" + Equation.pointerToString(eqn_ptr) + "\nis: " + Expression.toString(exp) + "\n");
733+
end for;
734+
end for;
735+
then full;
736+
737+
else algorithm
738+
Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " expected type full, got type " + strictnessString(getStrictness(full)) + "."});
739+
then fail();
740+
end match;
741+
end refine;
742+
699743
function compress
700744
"use after equations have been removed"
701745
input output Matrix adj;

0 commit comments

Comments
 (0)