From 52c8c2ced097295c0501f30eac0bd103d0d471fa Mon Sep 17 00:00:00 2001 From: kabdelhak <38032125+kabdelhak@users.noreply.github.com> Date: Wed, 19 Jan 2022 00:59:58 +0100 Subject: [PATCH] [BE] fix ASSC pivoting (#8436) * [BE] fix ASSC pivoting - remove dividing pivot row by pivot element > it would need an update of rhs - refers to ticket #8381 * [BE] fix ASSC row update - also update all elements in the row that do not appear in the pivot row - fixes ticket #8373 --- .../Compiler/BackEnd/SymbolicJacobian.mo | 21 ++++++++++++++++--- .../modelica/indexreduction/ASSC.mos | 2 +- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/OMCompiler/Compiler/BackEnd/SymbolicJacobian.mo b/OMCompiler/Compiler/BackEnd/SymbolicJacobian.mo index 2319dd6337b..87e68185178 100644 --- a/OMCompiler/Compiler/BackEnd/SymbolicJacobian.mo +++ b/OMCompiler/Compiler/BackEnd/SymbolicJacobian.mo @@ -4327,13 +4327,16 @@ uniontype LinearJacobian jump over all manipulations, nothing to do */ (col_index, piv_value) := getPivot(linJac.rows[i]); - updatePivotRow(linJac.rows[i], piv_value); + + //updatePivotRow(linJac.rows[i], piv_value); + // ToDo: updating the pivot row would also need an update for the rhs! + for j in i+1:arrayLength(linJac.rows) loop row_value := getElementValue(linJac.rows[j], col_index); if not realEq(row_value, 0.0) then // set row to processed and perform pivot step linJac.eq_marks[j] := true; - solveRow(linJac.rows[i], linJac.rows[j], 1.0, row_value); + solveRow(linJac.rows[i], linJac.rows[j], piv_value, row_value); //perform multiplication inside? use simplification of multiplication afterwards? linJac.rhs[j] := DAE.BINARY( DAE.BINARY(linJac.rhs[j], DAE.MUL(DAE.T_REAL_DEFAULT), DAE.RCONST(piv_value)), // row_rhs * piv_elem @@ -4359,6 +4362,7 @@ uniontype LinearJacobian Integer idx; Real val, diag_val; algorithm + // update all elements that are in the pivot row for idx in UnorderedMap.keyList(pivot_row) loop _ := match (UnorderedMap.get(idx, row), UnorderedMap.get(idx, pivot_row)) @@ -4383,11 +4387,22 @@ uniontype LinearJacobian then (); end match; end for; + + // update all row elements that are not in pivot row + for idx in UnorderedMap.keyList(row) loop + _ := match (UnorderedMap.get(idx, row), UnorderedMap.get(idx, pivot_row)) + case (SOME(val), NONE()) algorithm + val := val * piv_value; + UnorderedMap.add(idx, val, row); + then (); + else (); + end match; + end for; end solveRow; public function updatePivotRow "author: kabdelhak FHB 03-2021 - updates the pivot row by deviding everything by its pivot value" + updates the pivot row by dividing everything by its pivot value" input LinearJacobianRow pivot_row; input Real piv_value; protected diff --git a/testsuite/simulation/modelica/indexreduction/ASSC.mos b/testsuite/simulation/modelica/indexreduction/ASSC.mos index 8eebef3b343..bf4e6c759af 100644 --- a/testsuite/simulation/modelica/indexreduction/ASSC.mos +++ b/testsuite/simulation/modelica/indexreduction/ASSC.mos @@ -27,7 +27,7 @@ simulate(ASSC); getErrorString(); // LinearJacobian sparsity pattern: Solved (initial: false) // ###################################################### // (scal_idx|arr_idx|changed) [var_index, value] || RHS_EXPRESSION -// (3|3|false): [2|1.0] [3|1.0] || RHS: 10.0 - (x + c) +// (3|3|false): [2|2.0] [3|2.0] || RHS: 10.0 - (x + c) // (5|5|true): EMPTY ROW || RHS: -10.0 + x + c - 2.0 * c // // [ASSC] The equation: a + b + c = 0.0