@@ -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" );
727742end NBSolve ;
0 commit comments