def reduce(self, r, projection='bfsr'): """Reduce using SOBTfv. Parameters ---------- r Order of the reduced model. projection Projection method used: - `'sr'`: square root method - `'bfsr'`: balancing-free square root method (default, since it avoids scaling by singular values and orthogonalizes the projection matrices, which might make it more accurate than the square root method) - `'biorth'`: like the balancing-free square root method, except it biorthogonalizes the projection matrices Returns ------- rom Reduced-order |SecondOrderModel|. """ assert 0 < r < self.fom.order assert projection in ('sr', 'bfsr', 'biorth') # compute all necessary Gramian factors pcf = self.fom.gramian('pc_lrcf', mu=self.mu) pof = self.fom.gramian('po_lrcf', mu=self.mu) if r > min(len(pcf), len(pof)): raise ValueError( 'r needs to be smaller than the sizes of Gramian factors.') # find necessary SVDs _, sp, Vp = spla.svd(pof.inner(pcf), lapack_driver='gesvd') # compute projection matrices self.V = pcf.lincomb(Vp[:r]) if projection == 'sr': alpha = 1 / np.sqrt(sp[:r]) self.V.scal(alpha) elif projection == 'bfsr': self.V = gram_schmidt(self.V, atol=0, rtol=0) elif projection == 'biorth': self.V = gram_schmidt(self.V, product=self.fom.M, atol=0, rtol=0) self.W = self.V # find the reduced model if self.fom.parametric: fom_mu = self.fom.with_(**{ op: getattr(self.fom, op).assemble(mu=self.mu) for op in ['M', 'E', 'K', 'B', 'Cp', 'Cv'] }, parameter_space=None) else: fom_mu = self.fom self._pg_reductor = SOLTIPGReductor(fom_mu, self.W, self.V, projection == 'biorth') rom = self._pg_reductor.reduce() return rom
def reduce(self, r, projection='bfsr'): """Reduce using GenericSOBTpv. Parameters ---------- r Order of the reduced model. projection Projection method used: - `'sr'`: square root method - `'bfsr'`: balancing-free square root method (default, since it avoids scaling by singular values and orthogonalizes the projection matrices, which might make it more accurate than the square root method) - `'biorth'`: like the balancing-free square root method, except it biorthogonalizes the projection matrices Returns ------- rom Reduced-order |SecondOrderModel|. """ assert 0 < r < self.fom.order assert projection in ('sr', 'bfsr', 'biorth') # compute all necessary Gramian factors gramians = self._gramians() if r > min(len(g) for g in gramians): raise ValueError( 'r needs to be smaller than the sizes of Gramian factors.') # compute projection matrices self.V, self.W, singular_values = self._projection_matrices_and_singular_values( r, gramians) if projection == 'sr': alpha = 1 / np.sqrt(singular_values[:r]) self.V.scal(alpha) self.W.scal(alpha) elif projection == 'bfsr': self.V = gram_schmidt(self.V, atol=0, rtol=0) self.W = gram_schmidt(self.W, atol=0, rtol=0) elif projection == 'biorth': self.V, self.W = gram_schmidt_biorth(self.V, self.W, product=self.fom.M) # find the reduced model if self.fom.parametric: fom_mu = self.fom.with_(**{ op: getattr(self.fom, op).assemble(mu=self.mu) for op in ['M', 'E', 'K', 'B', 'Cp', 'Cv'] }, parameter_space=None) else: fom_mu = self.fom self._pg_reductor = SOLTIPGReductor(fom_mu, self.W, self.V, projection == 'biorth') rom = self._pg_reductor.reduce() return rom
def reduce(self, r, projection='bfsr'): """Reduce using SOBTfv. Parameters ---------- r Order of the reduced model. projection Projection method used: - `'sr'`: square root method - `'bfsr'`: balancing-free square root method (default, since it avoids scaling by singular values and orthogonalizes the projection matrices, which might make it more accurate than the square root method) - `'biorth'`: like the balancing-free square root method, except it biorthogonalizes the projection matrices Returns ------- rom Reduced system. """ assert 0 < r < self.fom.order assert projection in ('sr', 'bfsr', 'biorth') # compute all necessary Gramian factors pcf = self.fom.gramian('pc_lrcf') pof = self.fom.gramian('po_lrcf') if r > min(len(pcf), len(pof)): raise ValueError( 'r needs to be smaller than the sizes of Gramian factors.') # find necessary SVDs _, sp, Vp = spla.svd(pof.inner(pcf)) # compute projection matrices and find the reduced model self.V = pcf.lincomb(Vp[:r]) if projection == 'sr': alpha = 1 / np.sqrt(sp[:r]) self.V.scal(alpha) self.bases_are_biorthonormal = False elif projection == 'bfsr': self.V = gram_schmidt(self.V, atol=0, rtol=0) self.bases_are_biorthonormal = False elif projection == 'biorth': self.V = gram_schmidt(self.V, product=self.fom.M, atol=0, rtol=0) self.bases_are_biorthonormal = True self.W = self.V self.pg_reductor = SOLTIPGReductor(self.fom, self.W, self.V, projection == 'biorth') rom = self.pg_reductor.reduce() return rom