Source code for pymor.reductors.sor_irka

# This file is part of the pyMOR project (http://www.pymor.org).
# Copyright 2013-2020 pyMOR developers and contributors. All rights reserved.
# License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

"""IRKA-type reductor for |SecondOrderModels|."""

from pymor.models.iosys import SecondOrderModel
from pymor.reductors.h2 import GenericIRKAReductor, IRKAReductor
from pymor.reductors.interpolation import SOBHIReductor


[docs]class SORIRKAReductor(GenericIRKAReductor): """SOR-IRKA reductor. Parameters ---------- fom The full-order |SecondOrderModel| to reduce. mu |Parameter values|. """ def __init__(self, fom, mu=None): assert isinstance(fom, SecondOrderModel) super().__init__(fom, mu=mu)
[docs] def reduce(self, rom0_params, tol=1e-4, maxit=100, num_prev=1, force_sigma_in_rhp=False, projection='orth', conv_crit='sigma', compute_errors=False, irka_options=None): r"""Reduce using SOR-IRKA. It uses IRKA as the intermediate reductor, to reduce from 2r to r poles. See Section 5.3.2 in [W12]_. Parameters ---------- rom0_params Can be: - order of the reduced model (a positive integer), - dict with `'sigma'`, `'b'`, `'c'` as keys mapping to initial interpolation points (a 1D |NumPy array|), right tangential directions (|VectorArray| from `fom.D.source`), and left tangential directions (|VectorArray| from `fom.D.range`), all of the same length (the order of the reduced model), - initial reduced-order model (|LTIModel|). If the order of reduced model is given, initial interpolation data is generated randomly. tol Tolerance for the convergence criterion. maxit Maximum number of iterations. num_prev Number of previous iterations to compare the current iteration to. Larger number can avoid occasional cyclic behavior of IRKA. force_sigma_in_rhp If `False`, new interpolation are reflections of the current reduced order model's poles. Otherwise, only the poles in the left half-plane are reflected. projection Projection method: - `'orth'`: projection matrices are orthogonalized with respect to the Euclidean inner product - `'biorth'`: projection matrices are biorthogolized with respect to the E product conv_crit Convergence criterion: - `'sigma'`: relative change in interpolation points - `'h2'`: relative :math:`\mathcal{H}_2` distance of reduced-order models compute_errors Should the relative :math:`\mathcal{H}_2`-errors of intermediate reduced order models be computed. .. warning:: Computing :math:`\mathcal{H}_2`-errors is expensive. Use this option only if necessary. irka_options Dict of options for IRKAReductor.reduce. Returns ------- rom Reduced-order |SecondOrderModel|. """ if not self.fom.cont_time: raise NotImplementedError self._clear_lists() sigma, b, c = self._rom0_params_to_sigma_b_c(rom0_params, force_sigma_in_rhp) self._store_sigma_b_c(sigma, b, c) self._check_common_args(tol, maxit, num_prev, conv_crit) assert projection in ('orth', 'biorth') assert irka_options is None or isinstance(irka_options, dict) if not irka_options: irka_options = {} self.logger.info('Starting SOR-IRKA') self._conv_data = (num_prev + 1) * [None] if conv_crit == 'sigma': self._conv_data[0] = sigma self._pg_reductor = SOBHIReductor(self.fom, mu=self.mu) for it in range(maxit): rom = self._pg_reductor.reduce(sigma, b, c, projection=projection) with self.logger.block('Intermediate reduction ...'): irka_reductor = IRKAReductor(rom.to_lti()) rom_r = irka_reductor.reduce(rom.order, **irka_options) sigma, b, c = self._rom_to_sigma_b_c(rom_r, force_sigma_in_rhp) self._store_sigma_b_c(sigma, b, c) self._update_conv_data(sigma, rom, conv_crit) self._compute_conv_crit(rom, conv_crit, it) self._compute_error(rom, it, compute_errors) if self.conv_crit[-1] < tol: break self.V = self._pg_reductor.V self.W = self._pg_reductor.W return rom