Exemplo n.º 1
0
 def __init__(self, args):
     self.args = args
     self.first = True
     self.problem = thermal_block_problem(num_blocks=(args['XBLOCKS'], args['YBLOCKS']),
                                          parameter_range=(PARAM_MIN, PARAM_MAX))
     self.m, pack = discretize_stationary_cg(self.problem, diameter=1. / args['--grid'])
     self.grid = pack['grid']
Exemplo n.º 2
0
def elliptic_gmsh_demo(args):
    args['ANGLE'] = float(args['ANGLE'])
    args['NUM_POINTS'] = int(args['NUM_POINTS'])
    args['CLSCALE'] = float(args['CLSCALE'])

    problem = StationaryProblem(
        domain=CircularSectorDomain(args['ANGLE'],
                                    radius=1,
                                    num_points=args['NUM_POINTS']),
        diffusion=ConstantFunction(1, dim_domain=2),
        rhs=ConstantFunction(np.array(0.), dim_domain=2, name='rhs'),
        dirichlet_data=ExpressionFunction('sin(polar(x)[1] * pi/angle)',
                                          2, (), {}, {'angle': args['ANGLE']},
                                          name='dirichlet'))

    print('Discretize ...')
    m, data = discretize_stationary_cg(analytical_problem=problem,
                                       diameter=args['CLSCALE'])
    grid = data['grid']
    print(grid)
    print()

    print('Solve ...')
    U = m.solve()

    solution = ExpressionFunction(
        '(lambda r, phi: r**(pi/angle) * sin(phi * pi/angle))(*polar(x))', 2,
        (), {}, {'angle': args['ANGLE']})
    U_ref = U.space.make_array(solution(grid.centers(2)))

    m.visualize((U, U_ref, U - U_ref),
                legend=('Solution', 'Analytical solution (circular boundary)',
                        'Error'),
                separate_colorbars=True)
Exemplo n.º 3
0
 def __init__(self, args):
     self.args = args
     self.first = True
     self.problem = thermal_block_problem(num_blocks=(args['XBLOCKS'], args['YBLOCKS']),
                                          parameter_range=(PARAM_MIN, PARAM_MAX))
     self.discretization, pack = discretize_stationary_cg(self.problem, diameter=1. / args['--grid'])
     self.grid = pack['grid']
Exemplo n.º 4
0
def elliptic_gmsh_demo(args):
    args['ANGLE'] = float(args['ANGLE'])
    args['NUM_POINTS'] = int(args['NUM_POINTS'])
    args['CLSCALE'] = float(args['CLSCALE'])

    problem = StationaryProblem(
        domain=CircularSectorDomain(args['ANGLE'], radius=1, num_points=args['NUM_POINTS']),
        diffusion=ConstantFunction(1, dim_domain=2),
        rhs=ConstantFunction(np.array(0.), dim_domain=2, name='rhs'),
        dirichlet_data=ExpressionFunction('sin(polar(x)[1] * pi/angle)', 2, (),
                                          {}, {'angle': args['ANGLE']}, name='dirichlet')
    )

    print('Discretize ...')
    m, data = discretize_stationary_cg(analytical_problem=problem, diameter=args['CLSCALE'])
    grid = data['grid']
    print(grid)
    print()

    print('Solve ...')
    U = m.solve()

    solution = ExpressionFunction('(lambda r, phi: r**(pi/angle) * sin(phi * pi/angle))(*polar(x))', 2, (),
                                  {}, {'angle': args['ANGLE']})
    U_ref = U.space.make_array(solution(grid.centers(2)))

    m.visualize((U, U_ref, U-U_ref),
                legend=('Solution', 'Analytical solution (circular boundary)', 'Error'),
                separate_colorbars=True)
Exemplo n.º 5
0
def test_visualize_patch(backend_gridtype):
    backend, gridtype = backend_gridtype
    domain = LineDomain() if gridtype is OnedGrid else RectDomain()
    dim = 1 if gridtype is OnedGrid else 2
    rhs = GenericFunction(lambda X: np.ones(X.shape[:-1]) * 10, dim)  # NOQA
    dirichlet = GenericFunction(lambda X: np.zeros(X.shape[:-1]), dim)  # NOQA
    diffusion = GenericFunction(lambda X: np.ones(X.shape[:-1]), dim)  # NOQA
    problem = StationaryProblem(domain=domain, rhs=rhs, dirichlet_data=dirichlet, diffusion=diffusion)
    grid, bi = discretize_domain_default(problem.domain, grid_type=gridtype)
    discretization, data = discretize_stationary_cg(analytical_problem=problem, grid=grid, boundary_info=bi)
    U = discretization.solve()
    try:
        visualize_patch(data['grid'], U=U, backend=backend)
    except PySideMissing as ie:
        pytest.xfail("PySide missing")
    finally:
        stop_gui_processes()
Exemplo n.º 6
0
def test_visualize_patch(backend_gridtype):
    backend, gridtype = backend_gridtype
    domain = LineDomain() if gridtype is OnedGrid else RectDomain()
    dim = 1 if gridtype is OnedGrid else 2
    rhs = GenericFunction(lambda X: np.ones(X.shape[:-1]) * 10, dim)  # NOQA
    dirichlet = GenericFunction(lambda X: np.zeros(X.shape[:-1]), dim)  # NOQA
    diffusion = GenericFunction(lambda X: np.ones(X.shape[:-1]), dim)  # NOQA
    problem = StationaryProblem(domain=domain, rhs=rhs, dirichlet_data=dirichlet, diffusion=diffusion)
    grid, bi = discretize_domain_default(problem.domain, grid_type=gridtype)
    d, data = discretize_stationary_cg(analytical_problem=problem, grid=grid, boundary_info=bi)
    U = d.solve()
    try:
        visualize_patch(data['grid'], U=U, backend=backend)
    except QtMissing as ie:
        pytest.xfail("Qt missing")
    finally:
        stop_gui_processes()
Exemplo n.º 7
0
def thermalblock_factory(xblocks, yblocks, diameter, seed):
    from pymor.analyticalproblems.thermalblock import thermal_block_problem
    from pymor.discretizers.cg import discretize_stationary_cg
    from pymor.functions.basic import GenericFunction
    from pymor.operators.cg import InterpolationOperator
    p = thermal_block_problem((xblocks, yblocks))
    d, d_data = discretize_stationary_cg(p, diameter)
    f = GenericFunction(lambda X, mu: X[..., 0]**mu['exp'] + X[..., 1],
                        dim_domain=2, parameter_type={'exp': ()})
    iop = InterpolationOperator(d_data['grid'], f)
    U = d.operator.source.empty()
    V = d.operator.range.empty()
    np.random.seed(seed)
    for exp in np.random.random(5):
        U.append(iop.as_vector(exp))
    for exp in np.random.random(6):
        V.append(iop.as_vector(exp))
    return d.operator, d.parameter_space.sample_randomly(1, seed=seed)[0], U, V, d.h1_product, d.l2_product
Exemplo n.º 8
0
def thermalblock_factory(xblocks, yblocks, diameter, seed):
    from pymor.analyticalproblems.thermalblock import thermal_block_problem
    from pymor.discretizers.cg import discretize_stationary_cg
    from pymor.functions.basic import GenericFunction
    from pymor.operators.cg import InterpolationOperator
    p = thermal_block_problem((xblocks, yblocks))
    m, m_data = discretize_stationary_cg(p, diameter)
    f = GenericFunction(lambda X, mu: X[..., 0]**mu['exp'] + X[..., 1],
                        dim_domain=2, parameter_type={'exp': ()})
    iop = InterpolationOperator(m_data['grid'], f)
    U = m.operator.source.empty()
    V = m.operator.range.empty()
    np.random.seed(seed)
    for exp in np.random.random(5):
        U.append(iop.as_vector(exp))
    for exp in np.random.random(6):
        V.append(iop.as_vector(exp))
    return m.operator, m.parameter_space.sample_randomly(1, seed=seed)[0], U, V, m.h1_product, m.l2_product
Exemplo n.º 9
0
def discretize_pymor(xblocks, yblocks, grid_num_intervals, use_list_vector_array):
    from pymor.analyticalproblems.thermalblock import thermal_block_problem
    from pymor.discretizers.cg import discretize_stationary_cg
    from pymor.playground.discretizers.numpylistvectorarray import convert_to_numpy_list_vector_array

    print('Discretize ...')
    # setup analytical problem
    problem = thermal_block_problem(num_blocks=(xblocks, yblocks))

    # discretize using continuous finite elements
    fom, _ = discretize_stationary_cg(problem, diameter=1. / grid_num_intervals)

    if use_list_vector_array:
        fom = convert_to_numpy_list_vector_array(fom)

    summary = f'''pyMOR model:
   number of blocks: {xblocks}x{yblocks}
   grid intervals:   {grid_num_intervals}
   ListVectorArray:  {use_list_vector_array}
'''

    return fom, summary
Exemplo n.º 10
0
def discretize_pymor(xblocks, yblocks, grid_num_intervals, use_list_vector_array):
    from pymor.analyticalproblems.thermalblock import thermal_block_problem
    from pymor.discretizers.cg import discretize_stationary_cg
    from pymor.playground.discretizers.numpylistvectorarray import convert_to_numpy_list_vector_array

    print('Discretize ...')
    # setup analytical problem
    problem = thermal_block_problem(num_blocks=(xblocks, yblocks))

    # discretize using continuous finite elements
    d, _ = discretize_stationary_cg(problem, diameter=1. / grid_num_intervals)

    if use_list_vector_array:
        d = convert_to_numpy_list_vector_array(d)

    summary = '''pyMOR discretization:
   number of blocks: {xblocks}x{yblocks}
   grid intervals:   {grid_num_intervals}
   ListVectorArray:  {use_list_vector_array}
'''.format(**locals())

    return d, summary
Exemplo n.º 11
0
# License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

from itertools import product

import pytest
from pkg_resources import resource_filename

from pymor.discretizers.cg import discretize_stationary_cg
from pymor.discretizers.fv import discretize_instationary_fv
from pymor.discretizers.disk import discretize_stationary_from_disk, discretize_instationary_from_disk
from pymortests.fixtures.analyticalproblem import (picklable_thermalblock_problems, non_picklable_thermalblock_problems,
                                                   burgers_problems)


picklable_discretizaion_generators = \
        [lambda p=p, d=d: discretize_stationary_cg(p, diameter=d)[0]
         for p, d in product(picklable_thermalblock_problems, [1./50., 1./100.])] + \
        [lambda p=p, d=d: discretize_instationary_fv(p, diameter=d, nt=100)[0]
         for p, d in product(burgers_problems, [1./10., 1./15.])] + \
        [lambda p=p: discretize_stationary_from_disk(parameter_file=p)
         for p in (resource_filename('pymortests', 'testdata/parameter_stationary.ini'),)] + \
        [lambda p=p: discretize_instationary_from_disk(parameter_file=p)
         for p in (resource_filename('pymortests', 'testdata/parameter_instationary.ini'),)]


non_picklable_discretization_generators = \
        [lambda p=p, d=d: discretize_stationary_cg(p, diameter=d)[0]
         for p, d in product(non_picklable_thermalblock_problems, [1./20., 1./30.])]


discretization_generators = picklable_discretizaion_generators + non_picklable_discretization_generators
Exemplo n.º 12
0
def thermalblock_demo(args):
    args['--grid'] = int(args['--grid'])
    args['RBSIZE'] = int(args['RBSIZE'])
    args['--test'] = int(args['--test'])
    args['--ipython-engines'] = int(args['--ipython-engines'])
    args['--extension-alg'] = args['--extension-alg'].lower()
    assert args['--extension-alg'] in {'trivial', 'gram_schmidt'}
    args['--product'] = args['--product'].lower()
    assert args['--product'] in {'trivial', 'h1'}
    args['--reductor'] = args['--reductor'].lower()
    assert args['--reductor'] in {'traditional', 'residual_basis'}
    args['--cache-region'] = args['--cache-region'].lower()
    args['--validation-mus'] = int(args['--validation-mus'])
    args['--rho'] = float(args['--rho'])
    args['--gamma'] = float(args['--gamma'])
    args['--theta'] = float(args['--theta'])

    problem = thermal_block_problem(num_blocks=(2, 2))
    functionals = [
        ExpressionParameterFunctional('diffusion[0]', {'diffusion': (2, )}),
        ExpressionParameterFunctional('diffusion[1]**2', {'diffusion': (2, )}),
        ExpressionParameterFunctional('diffusion[0]', {'diffusion': (2, )}),
        ExpressionParameterFunctional('diffusion[1]', {'diffusion': (2, )})
    ]
    problem = problem.with_(
        diffusion=problem.diffusion.with_(coefficients=functionals),
        parameter_space=CubicParameterSpace({'diffusion': (2, )}, 0.1, 1.))

    print('Discretize ...')
    fom, _ = discretize_stationary_cg(problem, diameter=1. / args['--grid'])

    if args['--list-vector-array']:
        from pymor.playground.discretizers.numpylistvectorarray import convert_to_numpy_list_vector_array
        fom = convert_to_numpy_list_vector_array(fom)

    if args['--cache-region'] != 'none':
        fom.enable_caching(args['--cache-region'])

    if args['--plot-solutions']:
        print('Showing some solutions')
        Us = ()
        legend = ()
        for mu in fom.parameter_space.sample_randomly(2):
            print(f"Solving for diffusion = \n{mu['diffusion']} ... ")
            sys.stdout.flush()
            Us = Us + (fom.solve(mu), )
            legend = legend + (str(mu['diffusion']), )
        fom.visualize(Us,
                      legend=legend,
                      title='Detailed Solutions for different parameters',
                      block=True)

    print('RB generation ...')

    product = fom.h1_0_semi_product if args['--product'] == 'h1' else None
    coercivity_estimator = ExpressionParameterFunctional(
        'min([diffusion[0], diffusion[1]**2])', fom.parameter_type)
    reductors = {
        'residual_basis':
        CoerciveRBReductor(fom,
                           product=product,
                           coercivity_estimator=coercivity_estimator),
        'traditional':
        SimpleCoerciveRBReductor(fom,
                                 product=product,
                                 coercivity_estimator=coercivity_estimator)
    }
    reductor = reductors[args['--reductor']]

    pool = new_parallel_pool(ipython_num_engines=args['--ipython-engines'],
                             ipython_profile=args['--ipython-profile'])
    greedy_data = rb_adaptive_greedy(
        fom,
        reductor,
        validation_mus=args['--validation-mus'],
        rho=args['--rho'],
        gamma=args['--gamma'],
        theta=args['--theta'],
        use_estimator=not args['--without-estimator'],
        error_norm=fom.h1_0_semi_norm,
        max_extensions=args['RBSIZE'],
        visualize=not args['--no-visualize-refinement'])

    rom = greedy_data['rom']

    if args['--pickle']:
        print(
            f"\nWriting reduced model to file {args['--pickle']}_reduced ...")
        with open(args['--pickle'] + '_reduced', 'wb') as f:
            dump(rom, f)
        print(
            f"Writing detailed model and reductor to file {args['--pickle']}_detailed ..."
        )
        with open(args['--pickle'] + '_detailed', 'wb') as f:
            dump((fom, reductor), f)

    print('\nSearching for maximum error on random snapshots ...')

    results = reduction_error_analysis(
        rom,
        fom=fom,
        reductor=reductor,
        estimator=True,
        error_norms=(fom.h1_0_semi_norm, ),
        condition=True,
        test_mus=args['--test'],
        basis_sizes=25 if args['--plot-error-sequence'] else 1,
        plot=True,
        pool=pool)

    real_rb_size = rom.solution_space.dim

    print('''
*** RESULTS ***

Problem:
   number of blocks:                   2x2
   h:                                  sqrt(2)/{args[--grid]}

Greedy basis generation:
   estimator disabled:                 {args[--without-estimator]}
   extension method:                   {args[--extension-alg]}
   product:                            {args[--product]}
   prescribed basis size:              {args[RBSIZE]}
   actual basis size:                  {real_rb_size}
   elapsed time:                       {greedy_data[time]}
'''.format(**locals()))
    print(results['summary'])

    sys.stdout.flush()

    if args['--plot-error-sequence']:
        from matplotlib import pyplot as plt
        plt.show(results['figure'])
    if args['--plot-err']:
        mumax = results['max_error_mus'][0, -1]
        U = fom.solve(mumax)
        URB = reductor.reconstruct(rom.solve(mumax))
        fom.visualize(
            (U, URB, U - URB),
            legend=('Detailed Solution', 'Reduced Solution', 'Error'),
            title='Maximum Error Solution',
            separate_colorbars=True,
            block=True)
Exemplo n.º 13
0
# License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

from itertools import product

import pytest
from pkg_resources import resource_filename

from pymor.discretizers.cg import discretize_stationary_cg
from pymor.discretizers.fv import discretize_instationary_fv
from pymor.discretizers.disk import discretize_stationary_from_disk, discretize_instationary_from_disk
from pymortests.fixtures.analyticalproblem import (picklable_thermalblock_problems, non_picklable_thermalblock_problems,
                                                   burgers_problems)


picklable_discretizaion_generators = \
        [lambda p=p, d=d: discretize_stationary_cg(p, diameter=d)[0]
         for p, d in product(picklable_thermalblock_problems, [1./50., 1./100.])] + \
        [lambda p=p, d=d: discretize_instationary_fv(p, diameter=d, nt=100)[0]
         for p, d in product(burgers_problems, [1./10., 1./15.])] + \
        [lambda p=p: discretize_stationary_from_disk(parameter_file=p)
         for p in (resource_filename('pymortests', 'testdata/parameter_stationary.ini'),)] + \
        [lambda p=p: discretize_instationary_from_disk(parameter_file=p)
         for p in (resource_filename('pymortests', 'testdata/parameter_instationary.ini'),)]


non_picklable_discretization_generators = \
        [lambda p=p, d=d: discretize_stationary_cg(p, diameter=d)[0]
         for p, d in product(non_picklable_thermalblock_problems, [1./20., 1./30.])]


discretization_generators = picklable_discretizaion_generators + non_picklable_discretization_generators
Exemplo n.º 14
0
def thermalblock_demo(args):
    args['--grid'] = int(args['--grid'])
    args['RBSIZE'] = int(args['RBSIZE'])
    args['--test'] = int(args['--test'])
    args['--ipython-engines'] = int(args['--ipython-engines'])
    args['--estimator-norm'] = args['--estimator-norm'].lower()
    assert args['--estimator-norm'] in {'trivial', 'h1'}
    args['--extension-alg'] = args['--extension-alg'].lower()
    assert args['--extension-alg'] in {'trivial', 'gram_schmidt', 'h1_gram_schmidt'}
    args['--reductor'] = args['--reductor'].lower()
    assert args['--reductor'] in {'traditional', 'residual_basis'}
    args['--cache-region'] = args['--cache-region'].lower()
    args['--validation-mus'] = int(args['--validation-mus'])
    args['--rho'] = float(args['--rho'])
    args['--gamma'] = float(args['--gamma'])
    args['--theta'] = float(args['--theta'])

    print('Solving on TriaGrid(({0},{0}))'.format(args['--grid']))

    print('Setup Problem ...')
    problem = thermal_block_problem(num_blocks=(2, 2))
    functionals = [ExpressionParameterFunctional('diffusion[0]', {'diffusion': (2,)}),
                   ExpressionParameterFunctional('diffusion[1]**2', {'diffusion': (2,)}),
                   ExpressionParameterFunctional('diffusion[0]', {'diffusion': (2,)}),
                   ExpressionParameterFunctional('diffusion[1]', {'diffusion': (2,)})]
    problem = StationaryProblem(domain=problem.domain,
                              diffusion=problem.diffusion.with_(coefficients=functionals),
                              rhs=problem.rhs,
                              parameter_space=CubicParameterSpace({'diffusion': (2,)}, 0.1, 1.))

    print('Discretize ...')
    discretization, _ = discretize_stationary_cg(problem, diameter=1. / args['--grid'])

    if args['--list-vector-array']:
        from pymor.playground.discretizers.numpylistvectorarray import convert_to_numpy_list_vector_array
        discretization = convert_to_numpy_list_vector_array(discretization)

    if args['--cache-region'] != 'none':
        discretization.enable_caching(args['--cache-region'])

    print('The parameter type is {}'.format(discretization.parameter_type))

    if args['--plot-solutions']:
        print('Showing some solutions')
        Us = ()
        legend = ()
        for mu in discretization.parameter_space.sample_randomly(2):
            print('Solving for diffusion = \n{} ... '.format(mu['diffusion']))
            sys.stdout.flush()
            Us = Us + (discretization.solve(mu),)
            legend = legend + (str(mu['diffusion']),)
        discretization.visualize(Us, legend=legend, title='Detailed Solutions for different parameters', block=True)

    print('RB generation ...')

    product = discretization.h1_0_semi_product if args['--estimator-norm'] == 'h1' else None
    coercivity_estimator=ExpressionParameterFunctional('min([diffusion[0], diffusion[1]**2])', discretization.parameter_type)
    reductors = {'residual_basis': partial(reduce_coercive, product=product,
                                   coercivity_estimator=coercivity_estimator),
                 'traditional': partial(reduce_coercive_simple, product=product,
                                        coercivity_estimator=coercivity_estimator)}
    reductor = reductors[args['--reductor']]
    extension_algorithms = {'trivial': trivial_basis_extension,
                            'gram_schmidt': gram_schmidt_basis_extension,
                            'h1_gram_schmidt': partial(gram_schmidt_basis_extension, product=discretization.h1_0_semi_product)}
    extension_algorithm = extension_algorithms[args['--extension-alg']]

    pool = new_parallel_pool(ipython_num_engines=args['--ipython-engines'], ipython_profile=args['--ipython-profile'])
    greedy_data = adaptive_greedy(discretization, reductor,
                                  validation_mus=args['--validation-mus'], rho=args['--rho'], gamma=args['--gamma'],
                                  theta=args['--theta'],
                                  use_estimator=not args['--without-estimator'], error_norm=discretization.h1_0_semi_norm,
                                  extension_algorithm=extension_algorithm, max_extensions=args['RBSIZE'],
                                  visualize=args['--visualize-refinement'])

    rb_discretization, reconstructor = greedy_data['reduced_discretization'], greedy_data['reconstructor']

    if args['--pickle']:
        print('\nWriting reduced discretization to file {} ...'.format(args['--pickle'] + '_reduced'))
        with open(args['--pickle'] + '_reduced', 'wb') as f:
            dump(rb_discretization, f)
        print('Writing detailed discretization and reconstructor to file {} ...'.format(args['--pickle'] + '_detailed'))
        with open(args['--pickle'] + '_detailed', 'wb') as f:
            dump((discretization, reconstructor), f)

    print('\nSearching for maximum error on random snapshots ...')

    results = reduction_error_analysis(rb_discretization,
                                       discretization=discretization,
                                       reconstructor=reconstructor,
                                       estimator=True,
                                       error_norms=(discretization.h1_0_semi_norm,),
                                       condition=True,
                                       test_mus=args['--test'],
                                       basis_sizes=25 if args['--plot-error-sequence'] else 1,
                                       plot=True,
                                       pool=pool)

    real_rb_size = rb_discretization.solution_space.dim

    print('''
*** RESULTS ***

Problem:
   number of blocks:                   2x2
   h:                                  sqrt(2)/{args[--grid]}

Greedy basis generation:
   estimator disabled:                 {args[--without-estimator]}
   estimator norm:                     {args[--estimator-norm]}
   extension method:                   {args[--extension-alg]}
   prescribed basis size:              {args[RBSIZE]}
   actual basis size:                  {real_rb_size}
   elapsed time:                       {greedy_data[time]}
'''.format(**locals()))
    print(results['summary'])

    sys.stdout.flush()

    if args['--plot-error-sequence']:
        from matplotlib import pyplot as plt
        plt.show(results['figure'])
    if args['--plot-err']:
        mumax = results['max_error_mus'][0, -1]
        U = discretization.solve(mumax)
        URB = reconstructor.reconstruct(rb_discretization.solve(mumax))
        discretization.visualize((U, URB, U - URB), legend=('Detailed Solution', 'Reduced Solution', 'Error'),
                                 title='Maximum Error Solution', separate_colorbars=True, block=True)
if __name__ == '__main__':
    argvs = sys.argv
    parser = OptionParser()
    parser.add_option("--dir", dest="dir", default="./")
    opt, argc = parser.parse_args(argvs)
    print(opt, argc)

    rhs = ExpressionFunction('(x[..., 0] - 0.5)**2 * 1000', 2, ())

    problem = StationaryProblem(
        domain=RectDomain(),
        rhs=rhs,
        diffusion=LincombFunction(
            [ExpressionFunction('1 - x[..., 0]', 2, ()),
             ExpressionFunction('x[..., 0]', 2, ())],
            [ProjectionParameterFunctional(
                'diffusionl', 0), ExpressionParameterFunctional('1', {})]
        ),
        parameter_space=CubicParameterSpace({'diffusionl': 0}, 0.01, 0.1),
        name='2DProblem'
    )

    args = {'N': 100, 'samples': 10}
    m, data = discretize_stationary_cg(problem, diameter=1. / args['N'])
    U = m.solution_space.empty()
    for mu in m.parameter_space.sample_uniformly(args['samples']):
        U.append(m.solve(mu))

    Us = U * 1.5
    plot = m.visualize((U, Us), title='Solution for diffusionl=0.5')