Skip to content

Commit be5a25d

Browse files
authored
[NB] correctly fix arrays of size 1 (#11888)
- instead of removing them, keep them as is and update the solving process - ToDo: if multiple instances occur in the equation, chose the most fitting one
1 parent 13e5671 commit be5a25d

File tree

2 files changed

+35
-46
lines changed

2 files changed

+35
-46
lines changed

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

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -142,8 +142,6 @@ public
142142
ComponentRef name;
143143
list<Pointer<Equation>> sliced_eqns;
144144
algorithm
145-
// remove size one array subscripts for solving
146-
system := System.mapExp(system, BackendUtil.removeSizeOneArraySubscriptsExp);
147145
if Util.isSome(system.strongComponents) then
148146
for comp in Util.getOption(system.strongComponents) loop
149147
if UnorderedMap.contains(comp, duplicate_map) then
@@ -196,7 +194,6 @@ public
196194
SlicingStatus slicing_status;
197195
list<Integer> sizes, eqn_indices;
198196
UnorderedMap<ComponentRef, Expression> replacements;
199-
list<ComponentRef> slices_lst;
200197
Integer index;
201198
list<Equation> entwined_eqns = {};
202199
list<Pointer<Equation>> rest, sliced_eqns = {};
@@ -255,17 +252,7 @@ public
255252
// array equation solved for the a sliced variable.
256253
// get all slices of the variable ocurring in the equation and select the slice that fits the indices
257254
eqn := Pointer.access(Slice.getT(eqn_slice));
258-
slices_lst := Equation.collectCrefs(eqn, function Slice.getSliceCandidates(name = BVariable.getVarName(Slice.getT(var_slice))));
259-
260-
if listLength(slices_lst) == 1 then
261-
var_cref := List.first(slices_lst);
262-
solve_status := Status.UNPROCESSED;
263-
else
264-
// todo: choose best slice of list if more than one.
265-
// only fail for listLength == 0
266-
solve_status := Status.UNSOLVABLE;
267-
break;
268-
end if;
255+
(var_cref, solve_status) := getVarSlice(BVariable.getVarName(Slice.getT(var_slice)), eqn);
269256

270257
if solve_status < Status.UNSOLVABLE then
271258
(eqn, funcTree, solve_status, implicit_index, _) := solveEquation(eqn, var_cref, funcTree, systemType, implicit_index, slicing_map);
@@ -513,17 +500,26 @@ public
513500
output Status status;
514501
output Boolean invertRelation "If the equation represents a relation, this tells if the sign should be inverted";
515502
protected
503+
Type ty;
504+
ComponentRef fixed_cref;
516505
Expression residual, derivative;
517506
Differentiate.DifferentiationArguments diffArgs;
518507
Operator divOp, uminOp;
519-
Type ty;
520508
algorithm
521-
(eqn, status, invertRelation) := solveSimple(eqn, cref);
509+
// fix crefs where the array is of size one
510+
fixed_cref := ComponentRef.stripSubscriptsAll(cref);
511+
ty := ComponentRef.getSubscriptedType(fixed_cref, true);
512+
if Type.isArray(ty) and Type.sizeOf(ty) == 1 then
513+
fixed_cref := getVarSlice(fixed_cref, eqn);
514+
else
515+
fixed_cref := cref;
516+
end if;
517+
(eqn, status, invertRelation) := solveSimple(eqn, fixed_cref);
522518
// if the equation does not have a simple structure try to solve with other strategies
523519
if status == Status.UNPROCESSED then
524520
residual := Equation.getResidualExp(eqn);
525521
diffArgs := Differentiate.DIFFERENTIATION_ARGUMENTS(
526-
diffCref = cref,
522+
diffCref = fixed_cref,
527523
new_vars = {},
528524
jacobianHT = NONE(),
529525
diffType = NBDifferentiate.DifferentiationType.SIMPLE,
@@ -536,17 +532,17 @@ public
536532
if Expression.isZero(derivative) then
537533
invertRelation := false;
538534
status := Status.UNSOLVABLE;
539-
elseif not Expression.containsCref(derivative, cref) then
535+
elseif not Expression.containsCref(derivative, fixed_cref) then
540536
// If eqn is linear in cref:
541-
(eqn, funcTree) := solveLinear(eqn, residual, derivative, diffArgs, cref, funcTree);
537+
(eqn, funcTree) := solveLinear(eqn, residual, derivative, diffArgs, fixed_cref, funcTree);
542538
// If the derivative is negative, invert possible inequality sign
543539
invertRelation := Expression.isNegative(derivative);
544540
status := Status.EXPLICIT;
545541
else
546542
// If eqn is non-linear in cref
547543
if Flags.isSet(Flags.FAILTRACE) then
548544
Error.addMessage(Error.INTERNAL_ERROR,{getInstanceName() + " failed to solve Cref: "
549-
+ ComponentRef.toString(cref) + " in equation:\n" + Equation.toString(eqn)});
545+
+ ComponentRef.toString(fixed_cref) + " in equation:\n" + Equation.toString(eqn)});
550546
end if;
551547
invertRelation := false;
552548
status := Status.IMPLICIT;
@@ -723,5 +719,24 @@ protected
723719
end if;
724720
end tupleSolvable;
725721

722+
function getVarSlice
723+
input output ComponentRef var_cref;
724+
input Equation eqn;
725+
output Status solve_status;
726+
protected
727+
list<ComponentRef> slices_lst;
728+
algorithm
729+
slices_lst := Equation.collectCrefs(eqn, function Slice.getSliceCandidates(name = var_cref));
730+
731+
if listLength(slices_lst) == 1 then
732+
var_cref := List.first(slices_lst);
733+
solve_status := Status.UNPROCESSED;
734+
else
735+
// todo: choose best slice of list if more than one.
736+
// only fail for listLength == 0
737+
solve_status := Status.UNSOLVABLE;
738+
end if;
739+
end getVarSlice;
740+
726741
annotation(__OpenModelica_Interface="backend");
727742
end NBSolve;

OMCompiler/Compiler/NBackEnd/Util/NBBackendUtil.mo

Lines changed: 0 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -257,31 +257,5 @@ public
257257
end if;
258258
end isContinuousFold;
259259

260-
function removeSizeOneArraySubscriptsExp
261-
input output Expression exp;
262-
algorithm
263-
exp := match exp
264-
case Expression.CREF() algorithm
265-
exp.cref := removeSizeOneArraySubscriptsCref(exp.cref);
266-
then exp;
267-
else exp;
268-
end match;
269-
end removeSizeOneArraySubscriptsExp;
270-
271-
function removeSizeOneArraySubscriptsCref
272-
input output ComponentRef cref;
273-
algorithm
274-
cref := match cref
275-
case ComponentRef.CREF() algorithm
276-
if Type.isArray(cref.ty) and Type.sizeOf(cref.ty) == 1 then
277-
cref.subscripts := {};
278-
end if;
279-
cref.restCref := removeSizeOneArraySubscriptsCref(cref.restCref);
280-
then cref;
281-
282-
else cref;
283-
end match;
284-
end removeSizeOneArraySubscriptsCref;
285-
286260
annotation(__OpenModelica_Interface="backend");
287261
end NBBackendUtil;

0 commit comments

Comments
 (0)