Example #1
0
    def __init__(self,
                 fom,
                 RB=None,
                 product=None,
                 coercivity_estimator=None,
                 check_orthonormality=None,
                 check_tol=None):
        if not isinstance(fom.time_stepper, ImplicitEulerTimeStepper):
            raise NotImplementedError
        if fom.mass is not None and fom.mass.parametric and 't' in fom.mass.parameters:
            raise NotImplementedError
        super().__init__(fom,
                         RB,
                         product=product,
                         check_orthonormality=check_orthonormality,
                         check_tol=check_tol)
        self.coercivity_estimator = coercivity_estimator

        self.residual_reductor = ImplicitEulerResidualReductor(
            self.bases['RB'],
            fom.operator,
            fom.mass,
            fom.T / fom.time_stepper.nt,
            rhs=fom.rhs,
            product=product)

        self.initial_residual_reductor = ResidualReductor(
            self.bases['RB'],
            IdentityOperator(fom.solution_space),
            fom.initial_data,
            product=fom.l2_product,
            riesz_representatives=False)
Example #2
0
    def __init__(self,
                 fom,
                 RB=None,
                 product=None,
                 coercivity_estimator=None,
                 check_orthonormality=None,
                 check_tol=None):
        assert isinstance(fom.time_stepper, ImplicitEulerTimeStepper)
        super().__init__(fom,
                         RB,
                         product=product,
                         check_orthonormality=check_orthonormality,
                         check_tol=check_tol)
        self.coercivity_estimator = coercivity_estimator

        self.residual_reductor = ImplicitEulerResidualReductor(
            self.bases['RB'],
            fom.operator,
            fom.mass,
            fom.T / fom.time_stepper.nt,
            rhs=fom.rhs,
            product=product)

        self.initial_residual_reductor = ResidualReductor(
            self.bases['RB'],
            IdentityOperator(fom.solution_space),
            fom.initial_data,
            product=fom.l2_product,
            riesz_representatives=False)
Example #3
0
 def __init__(self, fom, RB=None, product=None, coercivity_estimator=None,
              check_orthonormality=None, check_tol=None):
     super().__init__(fom, RB, product=product, check_orthonormality=check_orthonormality,
                      check_tol=check_tol)
     self.coercivity_estimator = coercivity_estimator
     self.residual_reductor = ResidualReductor(self.bases['RB'], self.fom.operator, self.fom.rhs,
                                               product=product, riesz_representatives=True)
Example #4
0
 def __init__(self, d, RB=None, orthogonal_projection=('initial_data',), product=None,
              coercivity_estimator=None):
     super().__init__(d, RB,
                      orthogonal_projection=orthogonal_projection,
                      product=product)
     self.coercivity_estimator = coercivity_estimator
     self.residual_reductor = ResidualReductor(self.RB, self.d.operator, self.d.rhs,
                                               product=product)
Example #5
0
 def __init__(self, fom, RB=None, product=None, coercivity_estimator=None,
              check_orthonormality=None, check_tol=None):
     super().__init__(fom, RB, product=product, check_orthonormality=check_orthonormality,
                      check_tol=check_tol)
     self.coercivity_estimator = coercivity_estimator
     self.residual_reductor = ResidualReductor(self.bases['RB'], self.fom.operator, self.fom.rhs,
                                               product=product, riesz_representatives=True)
Example #6
0
    def __init__(self,
                 fom,
                 RB=None,
                 product=None,
                 coercivity_estimator=None,
                 check_orthonormality=None,
                 check_tol=None):
        assert fom.operator.linear and fom.rhs.linear
        assert isinstance(fom.operator, LincombOperator)
        assert all(not op.parametric for op in fom.operator.operators)
        if fom.rhs.parametric:
            assert isinstance(fom.rhs, LincombOperator)
            assert all(not op.parametric for op in fom.rhs.operators)

        super().__init__(fom,
                         RB,
                         product=product,
                         check_orthonormality=check_orthonormality,
                         check_tol=check_tol)
        self.coercivity_estimator = coercivity_estimator
        self.residual_reductor = ResidualReductor(self.bases['RB'],
                                                  self.fom.operator,
                                                  self.fom.rhs,
                                                  product=product)
        self.extends = None
Example #7
0
 def __init__(self, d, RB=None, orthogonal_projection=('initial_data',), product=None,
              coercivity_estimator=None):
     super().__init__(d, RB,
                      orthogonal_projection=orthogonal_projection,
                      product=product)
     self.coercivity_estimator = coercivity_estimator
     self.residual_reductor = ResidualReductor(self.RB, self.d.operator, self.d.rhs,
                                               product=product)
Example #8
0
    def __init__(self, d, RB=None, product=None, coercivity_estimator=None):
        assert isinstance(d.time_stepper, ImplicitEulerTimeStepper)
        super().__init__(d, RB, product=product)
        self.coercivity_estimator = coercivity_estimator

        self.residual_reductor = ImplicitEulerResidualReductor(
            self.RB,
            d.operator,
            d.mass,
            d.T / d.time_stepper.nt,
            functional=d.rhs,
            product=product)

        self.initial_residual_reductor = ResidualReductor(
            self.RB,
            IdentityOperator(d.solution_space),
            d.initial_data,
            product=d.l2_product)
Example #9
0
class CoerciveRBReductor(GenericRBReductor):
    """Reduced Basis reductor for |StationaryDiscretizations| with coercive linear operator.

    The only addition to :class:`~pymor.reductors.basic.GenericRBReductor` is an error
    estimator which evaluates the dual norm of the residual with respect to a given inner
    product. For the reduction of the residual we use
    :class:`~pymor.reductors.residual.ResidualReductor` for improved numerical stability
    [BEOR14]_.

    .. [BEOR14] A. Buhr, C. Engwer, M. Ohlberger, S. Rave, A Numerically Stable A
                Posteriori Error Estimator for Reduced Basis Approximations of Elliptic
                Equations, Proceedings of the 11th World Congress on Computational
                Mechanics, 2014.

    Parameters
    ----------
    d
        The |Discretization| which is to be reduced.
    RB
        |VectorArray| containing the reduced basis on which to project.
    orthogonal_projection
        List of keys in `d.operators` for which the corresponding |Operator|
        should be orthogonally projected (i.e. operators which map to vectors in
        contrast to bilinear forms which map to functionals).
    product
        Inner product for the projection of the |Operators| given by
        `orthogonal_projection` and for the computation of Riesz representatives
        of the residual. If `None`, the Euclidean product is used.
    coercivity_estimator
        `None` or a |Parameterfunctional| returning a lower bound for the coercivity
        constant of the given problem. Note that the computed error estimate is only
        guaranteed to be an upper bound for the error when an appropriate coercivity
        estimate is specified.
    """

    def __init__(self, d, RB=None, orthogonal_projection=('initial_data',), product=None,
                 coercivity_estimator=None):
        super().__init__(d, RB,
                         orthogonal_projection=orthogonal_projection,
                         product=product)
        self.coercivity_estimator = coercivity_estimator
        self.residual_reductor = ResidualReductor(self.RB, self.d.operator, self.d.rhs,
                                                  product=product)

    def _reduce(self):
        with self.logger.block('RB projection ...'):
            rd = super()._reduce()

        with self.logger.block('Assembling error estimator ...'):
            residual = self.residual_reductor.reduce()

            estimator = CoerciveRBEstimator(residual, tuple(self.residual_reductor.residual_range_dims),
                                            self.coercivity_estimator)
            rd = rd.with_(estimator=estimator)

        return rd
Example #10
0
class CoerciveRBReductor(GenericRBReductor):
    """Reduced Basis reductor for |StationaryDiscretizations| with coercive linear operator.

    The only addition to :class:`~pymor.reductors.basic.GenericRBReductor` is an error
    estimator which evaluates the dual norm of the residual with respect to a given inner
    product. For the reduction of the residual we use
    :class:`~pymor.reductors.residual.ResidualReductor` for improved numerical stability
    [BEOR14]_.

    .. [BEOR14] A. Buhr, C. Engwer, M. Ohlberger, S. Rave, A Numerically Stable A
                Posteriori Error Estimator for Reduced Basis Approximations of Elliptic
                Equations, Proceedings of the 11th World Congress on Computational
                Mechanics, 2014.

    Parameters
    ----------
    d
        The |Discretization| which is to be reduced.
    RB
        |VectorArray| containing the reduced basis on which to project.
    orthogonal_projection
        List of keys in `d.operators` for which the corresponding |Operator|
        should be orthogonally projected (i.e. operators which map to vectors in
        contrast to bilinear forms which map to functionals).
    product
        Inner product for the projection of the |Operators| given by
        `orthogonal_projection` and for the computation of Riesz representatives
        of the residual. If `None`, the Euclidean product is used.
    coercivity_estimator
        `None` or a |Parameterfunctional| returning a lower bound for the coercivity
        constant of the given problem. Note that the computed error estimate is only
        guaranteed to be an upper bound for the error when an appropriate coercivity
        estimate is specified.
    """

    def __init__(self, d, RB=None, orthogonal_projection=('initial_data',), product=None,
                 coercivity_estimator=None):
        super().__init__(d, RB,
                         orthogonal_projection=orthogonal_projection,
                         product=product)
        self.coercivity_estimator = coercivity_estimator
        self.residual_reductor = ResidualReductor(self.RB, self.d.operator, self.d.rhs,
                                                  product=product)

    def _reduce(self):
        with self.logger.block('RB projection ...'):
            rd = super()._reduce()

        with self.logger.block('Assembling error estimator ...'):
            residual = self.residual_reductor.reduce()

            estimator = CoerciveRBEstimator(residual, tuple(self.residual_reductor.residual_range_dims),
                                            self.coercivity_estimator)
            rd = rd.with_(estimator=estimator)

        return rd
Example #11
0
class CoerciveRBReductor(GenericRBReductor):
    """Reduced Basis reductor for |StationaryDiscretizations| with coercive linear operator.

    The only addition to :class:`~pymor.reductors.basic.GenericRBReductor` is an error
    estimator which evaluates the dual norm of the residual with respect to a given inner
    product. For the reduction of the residual we use
    :class:`~pymor.reductors.residual.ResidualReductor` for improved numerical stability
    [BEOR14]_.

    Parameters
    ----------
    d
        The |Discretization| which is to be reduced.
    RB
        |VectorArray| containing the reduced basis on which to project.
    basis_is_orthonormal
        If `RB` is specified, indicate whether or not the basis is orthonormal
        w.r.t. `product`.
    vector_ranged_operators
        List of keys in `d.operators` for which the corresponding |Operator|
        should be orthogonally projected (i.e. operators which map to vectors in
        contrast to bilinear forms which map to functionals).
    product
        Inner product for the orthonormalization of `RB`, the projection of the
        |Operators| given by `vector_ranged_operators` and for the computation of
        Riesz representatives of the residual. If `None`, the Euclidean product is used.
    coercivity_estimator
        `None` or a |Parameterfunctional| returning a lower bound for the coercivity
        constant of the given problem. Note that the computed error estimate is only
        guaranteed to be an upper bound for the error when an appropriate coercivity
        estimate is specified.
    """

    def __init__(self, d, RB=None, basis_is_orthonormal=None,
                 vector_ranged_operators=('initial_data',), product=None,
                 coercivity_estimator=None):
        super().__init__(d, RB,
                         basis_is_orthonormal=basis_is_orthonormal,
                         vector_ranged_operators=vector_ranged_operators,
                         product=product)
        self.coercivity_estimator = coercivity_estimator
        self.residual_reductor = ResidualReductor(self.RB, self.d.operator, self.d.rhs,
                                                  product=product, riesz_representatives=True)

    def _reduce(self):
        with self.logger.block('RB projection ...'):
            rd = super()._reduce()

        with self.logger.block('Assembling error estimator ...'):
            residual = self.residual_reductor.reduce()

            estimator = CoerciveRBEstimator(residual, tuple(self.residual_reductor.residual_range_dims),
                                            self.coercivity_estimator)
            rd = rd.with_(estimator=estimator)

        return rd
Example #12
0
 def __init__(self, d, RB=None, basis_is_orthonormal=None,
              vector_ranged_operators=('initial_data',), product=None,
              coercivity_estimator=None):
     super().__init__(d, RB,
                      basis_is_orthonormal=basis_is_orthonormal,
                      vector_ranged_operators=vector_ranged_operators,
                      product=product)
     self.coercivity_estimator = coercivity_estimator
     self.residual_reductor = ResidualReductor(self.RB, self.d.operator, self.d.rhs,
                                               product=product, riesz_representatives=True)
Example #13
0
class CoerciveRBReductor(StationaryRBReductor):
    """Reduced Basis reductor for |StationaryModels| with coercive linear operator.

    The only addition to :class:`~pymor.reductors.basic.StationaryRBReductor` is an error
    estimator which evaluates the dual norm of the residual with respect to a given inner
    product. For the reduction of the residual we use
    :class:`~pymor.reductors.residual.ResidualReductor` for improved numerical stability
    [BEOR14]_.

    Parameters
    ----------
    fom
        The |Model| which is to be reduced.
    RB
        |VectorArray| containing the reduced basis on which to project.
    product
        Inner product for the orthonormalization of `RB`, the projection of the
        |Operators| given by `vector_ranged_operators` and for the computation of
        Riesz representatives of the residual. If `None`, the Euclidean product is used.
    coercivity_estimator
        `None` or a |Parameterfunctional| returning a lower bound for the coercivity
        constant of the given problem. Note that the computed error estimate is only
        guaranteed to be an upper bound for the error when an appropriate coercivity
        estimate is specified.
    """
    def __init__(self,
                 fom,
                 RB=None,
                 product=None,
                 coercivity_estimator=None,
                 check_orthonormality=None,
                 check_tol=None):
        super().__init__(fom,
                         RB,
                         product=product,
                         check_orthonormality=check_orthonormality,
                         check_tol=check_tol)
        self.coercivity_estimator = coercivity_estimator
        self.residual_reductor = ResidualReductor(self.bases['RB'],
                                                  self.fom.operator,
                                                  self.fom.rhs,
                                                  product=product,
                                                  riesz_representatives=True)

    def assemble_estimator(self):
        residual = self.residual_reductor.reduce()
        estimator = CoerciveRBEstimator(
            residual, tuple(self.residual_reductor.residual_range_dims),
            self.coercivity_estimator)
        return estimator

    def assemble_estimator_for_subbasis(self, dims):
        return self._last_rom.estimator.restricted_to_subbasis(
            dims['RB'], m=self._last_rom)
Example #14
0
    def __init__(self, d, RB=None, orthogonal_projection=('initial_data',), product=None,
                 coercivity_estimator=None):
        assert d.linear
        assert isinstance(d.operator, LincombOperator)
        assert all(not op.parametric for op in d.operator.operators)
        if d.rhs.parametric:
            assert isinstance(d.rhs, LincombOperator)
            assert all(not op.parametric for op in d.rhs.operators)

        super().__init__(d, RB,
                         orthogonal_projection=orthogonal_projection,
                         product=product)
        self.coercivity_estimator = coercivity_estimator
        self.residual_reductor = ResidualReductor(self.RB, self.d.operator, self.d.rhs,
                                                  product=product)
        self.extends = None
Example #15
0
class CoerciveRBReductor(StationaryRBReductor):
    """Reduced Basis reductor for |StationaryModels| with coercive linear operator.

    The only addition to :class:`~pymor.reductors.basic.StationaryRBReductor` is an error
    estimator which evaluates the dual norm of the residual with respect to a given inner
    product. For the reduction of the residual we use
    :class:`~pymor.reductors.residual.ResidualReductor` for improved numerical stability
    [BEOR14]_.

    Parameters
    ----------
    fom
        The |Model| which is to be reduced.
    RB
        |VectorArray| containing the reduced basis on which to project.
    product
        Inner product for the orthonormalization of `RB`, the projection of the
        |Operators| given by `vector_ranged_operators` and for the computation of
        Riesz representatives of the residual. If `None`, the Euclidean product is used.
    coercivity_estimator
        `None` or a |Parameterfunctional| returning a lower bound for the coercivity
        constant of the given problem. Note that the computed error estimate is only
        guaranteed to be an upper bound for the error when an appropriate coercivity
        estimate is specified.
    """

    def __init__(self, fom, RB=None, product=None, coercivity_estimator=None,
                 check_orthonormality=None, check_tol=None):
        super().__init__(fom, RB, product=product, check_orthonormality=check_orthonormality,
                         check_tol=check_tol)
        self.coercivity_estimator = coercivity_estimator
        self.residual_reductor = ResidualReductor(self.bases['RB'], self.fom.operator, self.fom.rhs,
                                                  product=product, riesz_representatives=True)

    def assemble_estimator(self):
        residual = self.residual_reductor.reduce()
        estimator = CoerciveRBEstimator(residual, tuple(self.residual_reductor.residual_range_dims),
                                        self.coercivity_estimator)
        return estimator

    def assemble_estimator_for_subbasis(self, dims):
        return self._last_rom.estimator.restricted_to_subbasis(dims['RB'], m=self._last_rom)
Example #16
0
    def __init__(self, d, RB=None, product=None, coercivity_estimator=None):
        assert isinstance(d.time_stepper, ImplicitEulerTimeStepper)
        super().__init__(d, RB, product=product)
        self.coercivity_estimator = coercivity_estimator

        self.residual_reductor = ImplicitEulerResidualReductor(
            self.RB,
            d.operator,
            d.mass,
            d.T / d.time_stepper.nt,
            functional=d.rhs,
            product=product
        )

        self.initial_residual_reductor = ResidualReductor(
            self.RB,
            IdentityOperator(d.solution_space),
            d.initial_data,
            product=d.l2_product
        )
Example #17
0
    def __init__(self, d, RB=None, basis_is_orthonormal=None,
                 product=None, coercivity_estimator=None):
        assert isinstance(d.time_stepper, ImplicitEulerTimeStepper)
        super().__init__(d, RB, basis_is_orthonormal=basis_is_orthonormal, product=product)
        self.coercivity_estimator = coercivity_estimator

        self.residual_reductor = ImplicitEulerResidualReductor(
            self.RB,
            d.operator,
            d.mass,
            d.T / d.time_stepper.nt,
            rhs=d.rhs,
            product=product
        )

        self.initial_residual_reductor = ResidualReductor(
            self.RB,
            IdentityOperator(d.solution_space),
            d.initial_data,
            product=d.l2_product,
            riesz_representatives=False
        )
Example #18
0
    def __init__(self, fom, RB=None, product=None, coercivity_estimator=None,
                 check_orthonormality=None, check_tol=None):
        assert isinstance(fom.time_stepper, ImplicitEulerTimeStepper)
        super().__init__(fom, RB, product=product,
                         check_orthonormality=check_orthonormality, check_tol=check_tol)
        self.coercivity_estimator = coercivity_estimator

        self.residual_reductor = ImplicitEulerResidualReductor(
            self.bases['RB'],
            fom.operator,
            fom.mass,
            fom.T / fom.time_stepper.nt,
            rhs=fom.rhs,
            product=product
        )

        self.initial_residual_reductor = ResidualReductor(
            self.bases['RB'],
            IdentityOperator(fom.solution_space),
            fom.initial_data,
            product=fom.l2_product,
            riesz_representatives=False
        )
Example #19
0
class ParabolicRBReductor(InstationaryRBReductor):
    r"""Reduced Basis Reductor for parabolic equations.

    This reductor uses :class:`~pymor.reductors.basic.InstationaryRBReductor` for the actual
    RB-projection. The only addition is the assembly of an error estimator which
    bounds the discrete l2-in time / energy-in space error similar to [GP05]_, [HO08]_
    as follows:

    .. math::
        \left[ C_a^{-1}(\mu)\|e_N(\mu)\|^2 + \sum_{n=1}^{N} \Delta t\|e_n(\mu)\|^2_e \right]^{1/2}
            \leq \left[ C_a^{-1}(\mu)\Delta t \sum_{n=1}^{N}\|\mathcal{R}^n(u_n(\mu), \mu)\|^2_{e,-1}
                        + C_a^{-1}(\mu)\|e_0\|^2 \right]^{1/2}

    Here, :math:`\|\cdot\|` denotes the norm induced by the problem's mass matrix
    (e.g. the L^2-norm) and :math:`\|\cdot\|_e` is an arbitrary energy norm w.r.t.
    which the space operator :math:`A(\mu)` is coercive, and :math:`C_a(\mu)` is a
    lower bound for its coercivity constant. Finally, :math:`\mathcal{R}^n` denotes
    the implicit Euler timestepping residual for the (fixed) time step size :math:`\Delta t`,

    .. math::
        \mathcal{R}^n(u_n(\mu), \mu) :=
            f - M \frac{u_{n}(\mu) - u_{n-1}(\mu)}{\Delta t} - A(u_n(\mu), \mu),

    where :math:`M` denotes the mass operator and :math:`f` the source term.
    The dual norm of the residual is computed using the numerically stable projection
    from [BEOR14]_.

    Parameters
    ----------
    fom
        The |InstationaryModel| which is to be reduced.
    RB
        |VectorArray| containing the reduced basis on which to project.
    product
        The energy inner product |Operator| w.r.t. which the reduction error is
        estimated and `RB` is orthonormalized.
    coercivity_estimator
        `None` or a |Parameterfunctional| returning a lower bound :math:`C_a(\mu)`
        for the coercivity constant of `fom.operator` w.r.t. `product`.
    """
    def __init__(self, fom, RB=None, product=None, coercivity_estimator=None,
                 check_orthonormality=None, check_tol=None):
        assert isinstance(fom.time_stepper, ImplicitEulerTimeStepper)
        super().__init__(fom, RB, product=product,
                         check_orthonormality=check_orthonormality, check_tol=check_tol)
        self.coercivity_estimator = coercivity_estimator

        self.residual_reductor = ImplicitEulerResidualReductor(
            self.bases['RB'],
            fom.operator,
            fom.mass,
            fom.T / fom.time_stepper.nt,
            rhs=fom.rhs,
            product=product
        )

        self.initial_residual_reductor = ResidualReductor(
            self.bases['RB'],
            IdentityOperator(fom.solution_space),
            fom.initial_data,
            product=fom.l2_product,
            riesz_representatives=False
        )

    def assemble_estimator(self):
        residual = self.residual_reductor.reduce()
        initial_residual = self.initial_residual_reductor.reduce()

        estimator = ParabolicRBEstimator(residual, self.residual_reductor.residual_range_dims,
                                         initial_residual, self.initial_residual_reductor.residual_range_dims,
                                         self.coercivity_estimator)
        return estimator

    def assemble_estimator_for_subbasis(self, dims):
        return self._last_rom.estimator.restricted_to_subbasis(dims['RB'], m=self._last_rom)
Example #20
0
class ParabolicRBReductor(InstationaryRBReductor):
    r"""Reduced Basis Reductor for parabolic equations.

    This reductor uses :class:`~pymor.reductors.basic.InstationaryRBReductor` for the actual
    RB-projection. The only addition is the assembly of an error estimator which
    bounds the discrete l2-in time / energy-in space error similar to [GP05]_, [HO08]_
    as follows:

    .. math::
        \left[ C_a^{-1}(\mu)\|e_N(\mu)\|^2 + \sum_{n=1}^{N} \Delta t\|e_n(\mu)\|^2_e \right]^{1/2}
            \leq \left[ C_a^{-2}(\mu)\Delta t \sum_{n=1}^{N}\|\mathcal{R}^n(u_n(\mu), \mu)\|^2_{e,-1}
                        + C_a^{-1}(\mu)\|e_0\|^2 \right]^{1/2}

    Here, :math:`\|\cdot\|` denotes the norm induced by the problem's mass matrix
    (e.g. the L^2-norm) and :math:`\|\cdot\|_e` is an arbitrary energy norm w.r.t.
    which the space operator :math:`A(\mu)` is coercive, and :math:`C_a(\mu)` is a
    lower bound for its coercivity constant. Finally, :math:`\mathcal{R}^n` denotes
    the implicit Euler timestepping residual for the (fixed) time step size :math:`\Delta t`,

    .. math::
        \mathcal{R}^n(u_n(\mu), \mu) :=
            f - M \frac{u_{n}(\mu) - u_{n-1}(\mu)}{\Delta t} - A(u_n(\mu), \mu),

    where :math:`M` denotes the mass operator and :math:`f` the source term.
    The dual norm of the residual is computed using the numerically stable projection
    from [BEOR14]_.

    Parameters
    ----------
    fom
        The |InstationaryModel| which is to be reduced.
    RB
        |VectorArray| containing the reduced basis on which to project.
    product
        The energy inner product |Operator| w.r.t. which the reduction error is
        estimated and `RB` is orthonormalized.
    coercivity_estimator
        `None` or a |Parameterfunctional| returning a lower bound :math:`C_a(\mu)`
        for the coercivity constant of `fom.operator` w.r.t. `product`.
    """
    def __init__(self,
                 fom,
                 RB=None,
                 product=None,
                 coercivity_estimator=None,
                 check_orthonormality=None,
                 check_tol=None):
        if not isinstance(fom.time_stepper, ImplicitEulerTimeStepper):
            raise NotImplementedError
        if fom.mass is not None and fom.mass.parametric and 't' in fom.mass.parameters:
            raise NotImplementedError
        super().__init__(fom,
                         RB,
                         product=product,
                         check_orthonormality=check_orthonormality,
                         check_tol=check_tol)
        self.coercivity_estimator = coercivity_estimator

        self.residual_reductor = ImplicitEulerResidualReductor(
            self.bases['RB'],
            fom.operator,
            fom.mass,
            fom.T / fom.time_stepper.nt,
            rhs=fom.rhs,
            product=product)

        self.initial_residual_reductor = ResidualReductor(
            self.bases['RB'],
            IdentityOperator(fom.solution_space),
            fom.initial_data,
            product=fom.l2_product,
            riesz_representatives=False)

    def assemble_estimator(self):
        residual = self.residual_reductor.reduce()
        initial_residual = self.initial_residual_reductor.reduce()

        estimator = ParabolicRBEstimator(
            residual, self.residual_reductor.residual_range_dims,
            initial_residual,
            self.initial_residual_reductor.residual_range_dims,
            self.coercivity_estimator)
        return estimator

    def assemble_estimator_for_subbasis(self, dims):
        return self._last_rom.estimator.restricted_to_subbasis(
            dims['RB'], m=self._last_rom)
Example #21
0
class ParabolicRBReductor(GenericRBReductor):
    r"""Reduced Basis Reductor for parabolic equations.

    This reductor uses :class:`~pymor.reductors.basic.GenericRBReductor` for the actual
    RB-projection. The only addition is the assembly of an error estimator which
    bounds the discrete l2-in time / energy-in space error similar to [GP05]_, [HO08]_
    as follows:

    .. math::
        \left[ C_a^{-1}(\mu)\|e_N(\mu)\|^2 + \sum_{n=1}^{N} \Delta t\|e_n(\mu)\|^2_e \right]^{1/2}
            \leq \left[ C_a^{-1}(\mu)\Delta t \sum_{n=1}^{N}\|\mathcal{R}^n(u_n(\mu), \mu)\|^2_{e,-1}
                        + C_a^{-1}(\mu)\|e_0\|^2 \right]^{1/2}

    Here, :math:`\|\cdot\|` denotes the norm induced by the problem's mass matrix
    (e.g. the L^2-norm) and :math:`\|\cdot\|_e` is an arbitrary energy norm w.r.t.
    which the space operator :math:`A(\mu)` is coercive, and :math:`C_a(\mu)` is a
    lower bound for its coercivity constant. Finally, :math:`\mathcal{R}^n` denotes
    the implicit Euler timestepping residual for the (fixed) time step size :math:`\Delta t`,

    .. math::
        \mathcal{R}^n(u_n(\mu), \mu) :=
            f - M \frac{u_{n}(\mu) - u_{n-1}(\mu)}{\Delta t} - A(u_n(\mu), \mu),

    where :math:`M` denotes the mass operator and :math:`f` the source term.
    The dual norm of the residual is computed using the numerically stable projection
    from [BEOR14]_.

    .. warning::
        The reduced basis `RB` is required to be orthonormal w.r.t. the given
        energy product. If not, the projection of the initial values will be
        computed incorrectly.

    .. [GP05]   M. A. Grepl, A. T. Patera, A Posteriori Error Bounds For Reduced-Basis
                Approximations Of Parametrized Parabolic Partial Differential Equations,
                M2AN 39(1), 157-181, 2005.
    .. [HO08]   B. Haasdonk, M. Ohlberger, Reduced basis method for finite volume
                approximations of parametrized evolution equations,
                M2AN 42(2), 277-302, 2008.

    Parameters
    ----------
    d
        The |InstationaryDiscretization| which is to be reduced.
    RB
        |VectorArray| containing the reduced basis on which to project.
    product
        The energy inner product |Operator| w.r.t. the reduction error is estimated.
        RB must be to be orthonomrmal w.r.t. this product!
    coercivity_estimator
        `None` or a |Parameterfunctional| returning a lower bound :math:`C_a(\mu)`
        for the coercivity constant of `d.operator` w.r.t. `product`.
    """
    def __init__(self, d, RB=None, product=None, coercivity_estimator=None):
        assert isinstance(d.time_stepper, ImplicitEulerTimeStepper)
        super().__init__(d, RB, product=product)
        self.coercivity_estimator = coercivity_estimator

        self.residual_reductor = ImplicitEulerResidualReductor(
            self.RB,
            d.operator,
            d.mass,
            d.T / d.time_stepper.nt,
            functional=d.rhs,
            product=product
        )

        self.initial_residual_reductor = ResidualReductor(
            self.RB,
            IdentityOperator(d.solution_space),
            d.initial_data,
            product=d.l2_product
        )

    def _reduce(self):
        with self.logger.block('RB projection ...'):
            rd = super()._reduce()

        with self.logger.block('Assembling error estimator ...'):
            residual = self.residual_reductor.reduce()
            initial_residual = self.initial_residual_reductor.reduce()

            estimator = ParabolicRBEstimator(residual, self.residual_reductor.residual_range_dims,
                                             initial_residual, self.initial_residual_reductor.residual_range_dims,
                                             self.coercivity_estimator)
            rd = rd.with_(estimator=estimator)

        return rd
Example #22
0
class ParabolicRBReductor(GenericRBReductor):
    r"""Reduced Basis Reductor for parabolic equations.

    This reductor uses :class:`~pymor.reductors.basic.GenericRBReductor` for the actual
    RB-projection. The only addition is the assembly of an error estimator which
    bounds the discrete l2-in time / energy-in space error similar to [GP05]_, [HO08]_
    as follows:

    .. math::
        \left[ C_a^{-1}(\mu)\|e_N(\mu)\|^2 + \sum_{n=1}^{N} \Delta t\|e_n(\mu)\|^2_e \right]^{1/2}
            \leq \left[ C_a^{-1}(\mu)\Delta t \sum_{n=1}^{N}\|\mathcal{R}^n(u_n(\mu), \mu)\|^2_{e,-1}
                        + C_a^{-1}(\mu)\|e_0\|^2 \right]^{1/2}

    Here, :math:`\|\cdot\|` denotes the norm induced by the problem's mass matrix
    (e.g. the L^2-norm) and :math:`\|\cdot\|_e` is an arbitrary energy norm w.r.t.
    which the space operator :math:`A(\mu)` is coercive, and :math:`C_a(\mu)` is a
    lower bound for its coercivity constant. Finally, :math:`\mathcal{R}^n` denotes
    the implicit Euler timestepping residual for the (fixed) time step size :math:`\Delta t`,

    .. math::
        \mathcal{R}^n(u_n(\mu), \mu) :=
            f - M \frac{u_{n}(\mu) - u_{n-1}(\mu)}{\Delta t} - A(u_n(\mu), \mu),

    where :math:`M` denotes the mass operator and :math:`f` the source term.
    The dual norm of the residual is computed using the numerically stable projection
    from [BEOR14]_.

    .. warning::
        The reduced basis `RB` is required to be orthonormal w.r.t. the given
        energy product. If not, the projection of the initial values will be
        computed incorrectly.

    .. [GP05]   M. A. Grepl, A. T. Patera, A Posteriori Error Bounds For Reduced-Basis
                Approximations Of Parametrized Parabolic Partial Differential Equations,
                M2AN 39(1), 157-181, 2005.
    .. [HO08]   B. Haasdonk, M. Ohlberger, Reduced basis method for finite volume
                approximations of parametrized evolution equations,
                M2AN 42(2), 277-302, 2008.

    Parameters
    ----------
    discretization
        The |InstationaryDiscretization| which is to be reduced.
    RB
        |VectorArray| containing the reduced basis on which to project.
    product
        The energy inner product |Operator| w.r.t. the reduction error is estimated.
        RB must be to be orthonomrmal w.r.t. this product!
    coercivity_estimator
        `None` or a |Parameterfunctional| returning a lower bound :math:`C_a(\mu)`
        for the coercivity constant of `discretization.operator` w.r.t. `product`.
    """
    def __init__(self, d, RB=None, product=None, coercivity_estimator=None):
        assert isinstance(d.time_stepper, ImplicitEulerTimeStepper)
        super().__init__(d, RB, product=product)
        self.coercivity_estimator = coercivity_estimator

        self.residual_reductor = ImplicitEulerResidualReductor(
            self.RB,
            d.operator,
            d.mass,
            d.T / d.time_stepper.nt,
            functional=d.rhs,
            product=product)

        self.initial_residual_reductor = ResidualReductor(
            self.RB,
            IdentityOperator(d.solution_space),
            d.initial_data,
            product=d.l2_product)

    def _reduce(self):
        with self.logger.block('RB projection ...'):
            rd = super()._reduce()

        with self.logger.block('Assembling error estimator ...'):
            residual = self.residual_reductor.reduce()
            initial_residual = self.initial_residual_reductor.reduce()

            estimator = ParabolicRBEstimator(
                residual, self.residual_reductor.residual_range_dims,
                initial_residual,
                self.initial_residual_reductor.residual_range_dims,
                self.coercivity_estimator)
            rd = rd.with_(estimator=estimator)

        return rd
Example #23
0
class ParabolicRBReductor(GenericRBReductor):
    r"""Reduced Basis Reductor for parabolic equations.

    This reductor uses :class:`~pymor.reductors.basic.GenericRBReductor` for the actual
    RB-projection. The only addition is the assembly of an error estimator which
    bounds the discrete l2-in time / energy-in space error similar to [GP05]_, [HO08]_
    as follows:

    .. math::
        \left[ C_a^{-1}(\mu)\|e_N(\mu)\|^2 + \sum_{n=1}^{N} \Delta t\|e_n(\mu)\|^2_e \right]^{1/2}
            \leq \left[ C_a^{-1}(\mu)\Delta t \sum_{n=1}^{N}\|\mathcal{R}^n(u_n(\mu), \mu)\|^2_{e,-1}
                        + C_a^{-1}(\mu)\|e_0\|^2 \right]^{1/2}

    Here, :math:`\|\cdot\|` denotes the norm induced by the problem's mass matrix
    (e.g. the L^2-norm) and :math:`\|\cdot\|_e` is an arbitrary energy norm w.r.t.
    which the space operator :math:`A(\mu)` is coercive, and :math:`C_a(\mu)` is a
    lower bound for its coercivity constant. Finally, :math:`\mathcal{R}^n` denotes
    the implicit Euler timestepping residual for the (fixed) time step size :math:`\Delta t`,

    .. math::
        \mathcal{R}^n(u_n(\mu), \mu) :=
            f - M \frac{u_{n}(\mu) - u_{n-1}(\mu)}{\Delta t} - A(u_n(\mu), \mu),

    where :math:`M` denotes the mass operator and :math:`f` the source term.
    The dual norm of the residual is computed using the numerically stable projection
    from [BEOR14]_.

    Parameters
    ----------
    d
        The |InstationaryDiscretization| which is to be reduced.
    RB
        |VectorArray| containing the reduced basis on which to project.
    basis_is_orthonormal
        Indicate whether or not the basis is orthonormal w.r.t. `product`.
    product
        The energy inner product |Operator| w.r.t. which the reduction error is
        estimated and `RB` is orthonormalized.
    coercivity_estimator
        `None` or a |Parameterfunctional| returning a lower bound :math:`C_a(\mu)`
        for the coercivity constant of `d.operator` w.r.t. `product`.
    """
    def __init__(self, d, RB=None, basis_is_orthonormal=None,
                 product=None, coercivity_estimator=None):
        assert isinstance(d.time_stepper, ImplicitEulerTimeStepper)
        super().__init__(d, RB, basis_is_orthonormal=basis_is_orthonormal, product=product)
        self.coercivity_estimator = coercivity_estimator

        self.residual_reductor = ImplicitEulerResidualReductor(
            self.RB,
            d.operator,
            d.mass,
            d.T / d.time_stepper.nt,
            rhs=d.rhs,
            product=product
        )

        self.initial_residual_reductor = ResidualReductor(
            self.RB,
            IdentityOperator(d.solution_space),
            d.initial_data,
            product=d.l2_product,
            riesz_representatives=False
        )

    def _reduce(self):
        with self.logger.block('RB projection ...'):
            rd = super()._reduce()

        with self.logger.block('Assembling error estimator ...'):
            residual = self.residual_reductor.reduce()
            initial_residual = self.initial_residual_reductor.reduce()

            estimator = ParabolicRBEstimator(residual, self.residual_reductor.residual_range_dims,
                                             initial_residual, self.initial_residual_reductor.residual_range_dims,
                                             self.coercivity_estimator)
            rd = rd.with_(estimator=estimator)

        return rd