# This file is part of the pyMOR project (http://www.pymor.org).
# Copyright Holders: Felix Albrecht, Rene Milk, Stephan Rave
# License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

from __future__ import absolute_import, division, print_function

from pymor.core.cache import CacheableInterface, cached
from pymor.core.interfaces import abstractmethod
from pymor.parameters import Parametric
from pymor.tools import Named


class DiscretizationInterface(CacheableInterface, Parametric, Named):
    '''Describes a discretization.

    Note that we do not make any distinction between detailed and reduced
    discretizations at this point.

    Attributes
    ----------
    dim_solution
        Dimension of the `VectorArrays` returned by solve.
    type_solution
        Type of the `VectorArrays` returned by solve.
    linear
        True if the discretization describes a linear Problem.
    operators
        Dictionary of all operators contained in this discretization. The idea is
        that this attribute will be common to all discretizations such that it can
        be used for introspection. Compare the implementation of `reduce_generic_rb`.
    functionals
        Same as operators but for functionals.
    vector_operators
        Same as operators but for operators representing vectors, linear operators
        with `dim_source == 1`.

    Optional Methods:

        def estimate(self, U, mu=None):
            Estimate the error of the discrete solution U to the parameter mu against
            the real solution. (For a reduced discretization, the 'real' solution will
            in genereal be the solution of a detailed discretization.)

        def visualize(self, U):
            Visualize a solution given by the VectorArray U.
    '''

    dim_solution = None
    type_solution = None
    linear = False
    operators = dict()
    functionals = dict()
    vector_operators = dict()
    with_arguments = frozenset({'operators', 'functionals', 'vector_operators'})

    @abstractmethod
    def _solve(self, mu=None):
        '''Perform the actual solving.'''
        pass

    @cached
    def solve(self, mu=None):
        '''Solve for a parameter `mu`.

        The result is cached by default.
        '''
        return self._solve(mu)

@@ -1372,16 +1372,130 @@
 e == 1%60.
+%0A    products%0A        Same as operators but for scalar product operators associated to the%0A        discretization.
 %0A%0A    Op
@@ -2040,24 +2040,46 @@
 rs = dict()%0A
+    products = dict()%0A
     with_arg
@@ -2143,16 +2143,26 @@
 perators
+, products
 '%7D)%0A%0A   

add 'products' to DiscretizationInterface