예제 #1
0
파일: sobt.py 프로젝트: tobiasleibner/pymor
class SOBTfvReductor(BasicObject):
    """Free-velocity Second-Order Balanced Truncation reductor.

    See [MS96]_.

    Parameters
    ----------
    fom
        The full-order |SecondOrderModel| to reduce.
    mu
        |Parameter values|.
    """
    def __init__(self, fom, mu=None):
        assert isinstance(fom, SecondOrderModel)
        if not isinstance(mu, Mu):
            mu = fom.parameters.parse(mu)
        assert fom.parameters.assert_compatible(mu)
        self.fom = fom
        self.mu = mu
        self.V = None
        self.W = None
        self._pg_reductor = None

    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':
            gram_schmidt(self.V, atol=0, rtol=0, copy=False)
        elif projection == 'biorth':
            gram_schmidt(self.V,
                         product=self.fom.M,
                         atol=0,
                         rtol=0,
                         copy=False)
        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']
                })
        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 reconstruct(self, u):
        """Reconstruct high-dimensional vector from reduced vector `u`."""
        return self._pg_reductor.reconstruct(u)
예제 #2
0
파일: sobt.py 프로젝트: tobiasleibner/pymor
class GenericSOBTpvReductor(BasicObject):
    """Generic Second-Order Balanced Truncation position/velocity reductor.

    See [RS08]_.

    Parameters
    ----------
    fom
        The full-order |SecondOrderModel| to reduce.
    mu
        |Parameter values|.
    """
    def __init__(self, fom, mu=None):
        assert isinstance(fom, SecondOrderModel)
        if not isinstance(mu, Mu):
            mu = fom.parameters.parse(mu)
        assert fom.parameters.assert_compatible(mu)
        self.fom = fom
        self.mu = mu
        self.V = None
        self.W = None
        self._pg_reductor = None

    def _gramians(self):
        """Return Gramians."""
        raise NotImplementedError

    def _projection_matrices_and_singular_values(self, r, gramians):
        """Return projection matrices and singular values."""
        raise NotImplementedError

    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':
            gram_schmidt(self.V, atol=0, rtol=0, copy=False)
            gram_schmidt(self.W, atol=0, rtol=0, copy=False)
        elif projection == 'biorth':
            gram_schmidt_biorth(self.V, self.W, product=self.fom.M, copy=False)

        # 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']
                })
        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 reconstruct(self, u):
        """Reconstruct high-dimensional vector from reduced vector `u`."""
        return self._pg_reductor.reconstruct(u)
예제 #3
0
파일: sobt.py 프로젝트: deneick/pymor
class SOBTfvReductor(BasicInterface):
    """Free-velocity Second-Order Balanced Truncation reductor.

    See [MS96]_.

    Parameters
    ----------
    fom
        The full-order |SecondOrderModel| to reduce.
    """
    def __init__(self, fom):
        assert isinstance(fom, SecondOrderModel)
        self.fom = fom
        self._pg_reductor = None
        self.V = None
        self.W = None

    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')
        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
        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
        self._pg_reductor = SOLTIPGReductor(self.fom, self.W, self.V,
                                            projection == 'biorth')
        rom = self._pg_reductor.reduce()
        return rom

    def reconstruct(self, u):
        """Reconstruct high-dimensional vector from reduced vector `u`."""
        return self._pg_reductor.reconstruct(u)
예제 #4
0
파일: sobt.py 프로젝트: prklVIP/pymor
class GenericSOBTpvReductor(BasicInterface):
    """Generic Second-Order Balanced Truncation position/velocity reductor.

    See [RS08]_.

    Parameters
    ----------
    fom
        The system which is to be reduced.
    """
    def __init__(self, fom):
        assert isinstance(fom, SecondOrderModel)
        self.fom = fom
        self.V = None
        self.W = None

    def _gramians(self):
        """Returns gramians."""
        raise NotImplementedError

    def _projection_matrices_and_singular_values(self, r, gramians):
        """Returns projection matrices and singular values."""
        raise NotImplementedError

    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 system.
        """
        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 and find the reduced model
        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)

        self.pg_reductor = SOLTIPGReductor(self.fom, self.W, self.V,
                                           projection == 'biorth')

        rom = self.pg_reductor.reduce()

        return rom

    def reconstruct(self, u):
        """Reconstruct high-dimensional vector from reduced vector `u`."""
        self.pg_reductor.reconstruct(u)
예제 #5
0
파일: sobt.py 프로젝트: pymor/pymor
class SOBTfvReductor(BasicInterface):
    """Free-velocity Second-Order Balanced Truncation reductor.

    See [MS96]_.

    Parameters
    ----------
    fom
        The full-order |SecondOrderModel| to reduce.
    """
    def __init__(self, fom):
        assert isinstance(fom, SecondOrderModel)
        self.fom = fom
        self._pg_reductor = None
        self.V = None
        self.W = None

    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')
        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
        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
        self._pg_reductor = SOLTIPGReductor(self.fom, self.W, self.V, projection == 'biorth')
        rom = self._pg_reductor.reduce()
        return rom

    def reconstruct(self, u):
        """Reconstruct high-dimensional vector from reduced vector `u`."""
        return self._pg_reductor.reconstruct(u)
예제 #6
0
파일: sobt.py 프로젝트: pymor/pymor
class GenericSOBTpvReductor(BasicInterface):
    """Generic Second-Order Balanced Truncation position/velocity reductor.

    See [RS08]_.

    Parameters
    ----------
    fom
        The full-order |SecondOrderModel| to reduce.
    """
    def __init__(self, fom):
        assert isinstance(fom, SecondOrderModel)
        self.fom = fom
        self.V = None
        self.W = None
        self._pg_reductor = None

    def _gramians(self):
        """Return Gramians."""
        raise NotImplementedError

    def _projection_matrices_and_singular_values(self, r, gramians):
        """Return projection matrices and singular values."""
        raise NotImplementedError

    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
        self._pg_reductor = SOLTIPGReductor(self.fom, self.W, self.V, projection == 'biorth')
        rom = self._pg_reductor.reduce()
        return rom

    def reconstruct(self, u):
        """Reconstruct high-dimensional vector from reduced vector `u`."""
        return self._pg_reductor.reconstruct(u)