From 498d3a8436741399f7340411d037665cc9126460 Mon Sep 17 00:00:00 2001 From: Gertjan van Zwieten Date: Tue, 22 Oct 2024 10:21:13 +0200 Subject: [PATCH] Generalize System.optimize to nonsymmetric problems This patch lifts the restriction that System.optimize only applies to symmetric problems, as none of the internal logic actually requires it. --- nutils/solver.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/nutils/solver.py b/nutils/solver.py index 9b494b140..d3b915078 100644 --- a/nutils/solver.py +++ b/nutils/solver.py @@ -429,16 +429,15 @@ def optimize(self, *, droptol: Optional[float], arguments: Dict[str, numpy.ndarr participate in the optimization problem. ''' - log.info(f'optimizing for argument {self._trial_info} with drop tolerance {droptol:.0e}') + log.info(f'{"optimizing" if self.is_symmetric else "solving"} for argument {self._trial_info} with drop tolerance {droptol:.0e}') if not self.is_linear: raise ValueError('system is not linear') - if not self.is_symmetric: - raise ValueError('system is not symmetric') x, iscons, arguments = self.prepare_solution_vector(arguments, constrain) jac, res, val = self.assemble(arguments) mycons = iscons | ~jac.rowsupp(droptol) dx = -jac.solve(res, constrain=mycons, **_copy_with_defaults(linargs, symmetric=self.is_symmetric)) - log.info(f'optimal value: {val+.5*(res@dx):.1e}') # val(x + dx) = val(x) + res(x) dx + .5 dx jac dx + if self.is_symmetric: + log.info(f'optimal value: {val+.5*(res@dx):.1e}') # val(x + dx) = val(x) + res(x) dx + .5 dx jac dx x += dx for trial, i, j in zip(self.trials, self.__trial_offsets, self.__trial_offsets[1:]): log.info(f'constrained {(~mycons[i:j]).sum()} degrees of freedom of u')