Exemplo n.º 1
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.º 2
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.º 3
0
 def __init__(self, xblocks, yblocks, snapshots, rbsize, grid, product):
     self.snapshots, self.rbsize, self.product = snapshots, rbsize, product
     self.xblocks, self.yblocks = xblocks, yblocks
     self.first = True
     self.problem = thermal_block_problem(num_blocks=(xblocks, yblocks),
                                          parameter_range=(PARAM_MIN,
                                                           PARAM_MAX))
     self.m, pack = discretize_stationary_cg(self.problem,
                                             diameter=1. / grid)
     self.grid = pack['grid']
Exemplo n.º 4
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)
    m, data = discretize_stationary_cg(analytical_problem=problem, grid=grid, boundary_info=bi)
    U = m.solve()
    try:
        visualize_patch(data['grid'], U=U, backend=backend)
    except QtMissing as ie:
        pytest.xfail("Qt missing")
    finally:
        stop_gui_processes()
Exemplo n.º 5
0
def thermalblock_factory(xblocks, yblocks, diameter, seed):
    from pymor.analyticalproblems.thermalblock import thermal_block_problem
    from pymor.discretizers.builtin import discretize_stationary_cg
    from pymor.functions.basic import GenericFunction
    from pymor.discretizers.builtin.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.º 6
0
def main(
    angle: float = Argument(..., help='The angle of the circular sector.'),
    num_points: int = Argument(
        ...,
        help='The number of points that form the arc of the circular sector.'),
    clscale: float = Argument(..., help='Mesh element size scaling factor.'),
):
    """Solves the Poisson equation in 2D on a circular sector domain of radius 1
    using an unstructured mesh.

    Note that Gmsh (http://geuz.org/gmsh/) is required for meshing.
    """

    problem = StationaryProblem(
        domain=CircularSectorDomain(angle, radius=1, num_points=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': angle},
                                          name='dirichlet'))

    print('Discretize ...')
    m, data = discretize_stationary_cg(analytical_problem=problem,
                                       diameter=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': 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.º 7
0
def discretize_pymor(xblocks, yblocks, grid_num_intervals, use_list_vector_array):
    from pymor.analyticalproblems.thermalblock import thermal_block_problem
    from pymor.discretizers.builtin 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.º 8
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), )

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

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

    if args['--cache-region'] != 'none':
        # building a cache_id is only needed for persistent CacheRegions
        cache_id = f"pymordemos.thermalblock_adaptive {args['--grid']}"
        fom.enable_caching(args['--cache-region'], cache_id)

    if args['--plot-solutions']:
        print('Showing some solutions')
        Us = ()
        legend = ()
        for mu in problem.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.parameters)
    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,
        problem.parameter_space,
        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=problem.parameter_space.sample_randomly(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.º 9
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.builtin import discretize_stationary_cg, 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_model_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_model_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.])]

model_generators = picklable_model_generators + non_picklable_model_generators
Exemplo n.º 10
0
def elliptic2_demo(args):
    args['PROBLEM-NUMBER'] = int(args['PROBLEM-NUMBER'])
    assert 0 <= args['PROBLEM-NUMBER'] <= 1, ValueError('Invalid problem number.')
    args['N'] = int(args['N'])
    norm = args['NORM']
    norm = float(norm) if not norm.lower() in ('h1', 'l2') else norm.lower()

    rhss = [ExpressionFunction('ones(x.shape[:-1]) * 10', 2, ()),
              LincombFunction(
              [ExpressionFunction('ones(x.shape[:-1]) * 10', 2, ()), ConstantFunction(1.,2)],
              [ProjectionParameterFunctional('mu'), 0.1])]

    dirichlets = [ExpressionFunction('zeros(x.shape[:-1])', 2, ()),
                  LincombFunction(
                  [ExpressionFunction('2 * x[..., 0]', 2, ()), ConstantFunction(1.,2)],
                  [ProjectionParameterFunctional('mu'), 0.5])]

    neumanns = [None,
                  LincombFunction(
                  [ExpressionFunction('1 - x[..., 1]', 2, ()), ConstantFunction(1.,2)],
                  [ProjectionParameterFunctional('mu'), 0.5**2])]

    robins = [None,
                (LincombFunction(
                [ExpressionFunction('x[..., 1]', 2, ()), ConstantFunction(1.,2)],
                [ProjectionParameterFunctional('mu'), 1]),
                 ConstantFunction(1.,2))]

    domains = [RectDomain(),
               RectDomain(right='neumann', top='dirichlet', bottom='robin')]

    rhs = rhss[args['PROBLEM-NUMBER']]
    dirichlet = dirichlets[args['PROBLEM-NUMBER']]
    neumann = neumanns[args['PROBLEM-NUMBER']]
    domain = domains[args['PROBLEM-NUMBER']]
    robin = robins[args['PROBLEM-NUMBER']]
    
    problem = StationaryProblem(
        domain=domain,
        rhs=rhs,
        diffusion=LincombFunction(
            [ExpressionFunction('1 - x[..., 0]', 2, ()), ExpressionFunction('x[..., 0]', 2, ())],
            [ProjectionParameterFunctional('mu'), 1]
        ),
        dirichlet_data=dirichlet,
        neumann_data=neumann,
        robin_data=robin,
        parameter_ranges=(0.1, 1),
        name='2DProblem'
    )

    if isinstance(norm, float) and not args['--fv']:
        # use a random parameter to construct an energy product
        mu_bar = problem.parameters.parse(norm)
    else:
        mu_bar = None

    print('Discretize ...')
    if args['--fv']:
        m, data = discretize_stationary_fv(problem, diameter=1. / args['N'])
    else:
        m, data = discretize_stationary_cg(problem, diameter=1. / args['N'], mu_energy_product=mu_bar)
    print(data['grid'])
    print()

    print('Solve ...')
    U = m.solution_space.empty()
    for mu in problem.parameter_space.sample_uniformly(10):
        U.append(m.solve(mu))
    if mu_bar is not None:
        # use the given energy product
        norm_squared = U[-1].norm(m.products['energy'])[0]
        print('Energy norm of the last snapshot: ', np.sqrt(norm_squared))
    if not args['--fv']:
        if args['NORM'] == 'h1':
            norm_squared = U[-1].norm(m.products['h1_0_semi'])[0]
            print('H^1_0 semi norm of the last snapshot: ', np.sqrt(norm_squared))
        if args['NORM'] == 'l2':
            norm_squared = U[-1].norm(m.products['l2_0'])[0]
            print('L^2_0 norm of the last snapshot: ', np.sqrt(norm_squared))
    m.visualize(U, title='Solution for mu in [0.1, 1]')
def discretize_quadratic_pdeopt_stationary_cg(problem,
                                              diameter=np.sqrt(2) / 100.,
                                              weights=None,
                                              parameter_scales=None,
                                              domain_of_interest=None,
                                              desired_temperature=None,
                                              mu_for_u_d=None,
                                              mu_for_tikhonov=False,
                                              parameters_in_q=True,
                                              product='h1_l2_boundary',
                                              solver_options=None,
                                              use_corrected_functional=True,
                                              use_corrected_gradient=False,
                                              adjoint_approach=False):
    if use_corrected_functional:
        print('I am using the corrected functional!!')
    else:
        print('I am using the OLD functional!!')
    if use_corrected_gradient:
        print('I am using the corrected gradient!!')
    else:
        if adjoint_approach:
            print(
                'I am using the adjoint approach for computing the gradient!!')
        print('I am using the OLD gradient!!')

    mu_bar = _construct_mu_bar(problem)
    print(mu_bar)
    primal_fom, data = discretize_stationary_cg(problem,
                                                diameter=diameter,
                                                grid_type=RectGrid,
                                                energy_product=mu_bar)

    #Preassemble non parametric parts: simplify, put the constant part in only one function

    simplified_operators = [
        ZeroOperator(primal_fom.solution_space, primal_fom.solution_space)
    ]
    simplified_coefficients = [1]
    to_pre_assemble = ZeroOperator(primal_fom.solution_space,
                                   primal_fom.solution_space)

    if isinstance(primal_fom.operator, LincombOperator):
        for (i, coef) in enumerate(primal_fom.operator.coefficients):
            if isinstance(coef, Parametric):
                simplified_coefficients.append(coef)
                simplified_operators.append(primal_fom.operator.operators[i])
            else:
                to_pre_assemble += coef * primal_fom.operator.operators[i]
    else:
        to_pre_assemble += primal_fom.operator

    simplified_operators[0] += to_pre_assemble
    simplified_operators[0] = simplified_operators[0].assemble()

    lincomb_operator = LincombOperator(
        simplified_operators,
        simplified_coefficients,
        solver_options=primal_fom.operator.solver_options)

    simplified_rhs = [
        ZeroOperator(primal_fom.solution_space, NumpyVectorSpace(1))
    ]
    simplified_rhs_coefficients = [1]
    to_pre_assemble = ZeroOperator(primal_fom.solution_space,
                                   NumpyVectorSpace(1))

    if isinstance(primal_fom.rhs, LincombOperator):
        for (i, coef) in enumerate(primal_fom.rhs.coefficients):
            if isinstance(coef, Parametric):
                simplified_rhs_coefficients.append(coef)
                simplified_rhs.append(primal_fom.rhs.operators[i])
            else:
                to_pre_assemble += coef * primal_fom.rhs.operators[i]
    else:
        to_pre_assemble += primal_fom.rhs

    simplified_rhs[0] += to_pre_assemble
    simplified_rhs[0] = simplified_rhs[0].assemble()
    lincomb_rhs = LincombOperator(simplified_rhs, simplified_rhs_coefficients)

    primal_fom = primal_fom.with_(operator=lincomb_operator, rhs=lincomb_rhs)

    grid = data['grid']
    d = grid.dim

    # prepare data functions
    if desired_temperature is not None:
        u_desired = ConstantFunction(desired_temperature, d)
    if domain_of_interest is None:
        domain_of_interest = ConstantFunction(1., d)
    if mu_for_u_d is not None:
        domain_of_interest = ConstantFunction(1., d)
        modifified_mu = mu_for_u_d.copy()
        for key in mu_for_u_d.keys():
            if len(mu_for_u_d[key]) == 0:
                modifified_mu.pop(key)
        u_d = primal_fom.solve(modifified_mu)
    else:
        assert desired_temperature is not None
        u_d = InterpolationOperator(grid, u_desired).as_vector()

    if grid.reference_element is square:
        L2_OP = L2ProductQ1
    else:
        L2_OP = L2ProductP1

    Restricted_L2_OP = L2_OP(grid,
                             data['boundary_info'],
                             dirichlet_clear_rows=False,
                             coefficient_function=domain_of_interest)

    l2_u_d_squared = Restricted_L2_OP.apply2(u_d, u_d)[0][0]
    constant_part = 0.5 * l2_u_d_squared

    # assemble output functional
    from pdeopt.theta import build_output_coefficient
    if weights is not None:
        weight_for_J = weights.pop('state')
    else:
        weight_for_J = 1.
    if isinstance(weight_for_J, dict):
        assert len(
            weight_for_J
        ) == 4, 'you need to give all derivatives including second order'
        state_functional = ExpressionParameterFunctional(
            weight_for_J['function'],
            weight_for_J['parameter_type'],
            derivative_expressions=weight_for_J['derivative'],
            second_derivative_expressions=weight_for_J['second_derivatives'])
    elif isinstance(weight_for_J, float) or isinstance(weight_for_J, int):
        state_functional = ConstantParameterFunctional(weight_for_J)
    else:
        assert 0, 'state weight needs to be an integer or a dict with derivatives'

    if mu_for_tikhonov:
        if mu_for_u_d is not None:
            mu_for_tikhonov = mu_for_u_d
        else:
            assert isinstance(mu_for_tikhonov, dict)
        output_coefficient = build_output_coefficient(
            primal_fom.parameter_type, weights, mu_for_tikhonov,
            parameter_scales, state_functional, constant_part)
    else:
        output_coefficient = build_output_coefficient(
            primal_fom.parameter_type, weights, None, parameter_scales,
            state_functional, constant_part)

    output_functional = {}

    output_functional['output_coefficient'] = output_coefficient
    output_functional['linear_part'] = LincombOperator(
        [VectorOperator(Restricted_L2_OP.apply(u_d))],
        [-state_functional])  # j(.)
    output_functional['bilinear_part'] = LincombOperator(
        [Restricted_L2_OP], [0.5 * state_functional])  # k(.,.)
    output_functional['d_u_linear_part'] = LincombOperator(
        [VectorOperator(Restricted_L2_OP.apply(u_d))],
        [-state_functional])  # j(.)
    output_functional['d_u_bilinear_part'] = LincombOperator(
        [Restricted_L2_OP], [state_functional])  # 2k(.,.)

    l2_boundary_product = RobinBoundaryOperator(
        grid,
        data['boundary_info'],
        robin_data=(ConstantFunction(1, 2), ConstantFunction(1, 2)),
        name='l2_boundary_product')

    # choose product
    if product == 'h1_l2_boundary':
        opt_product = primal_fom.h1_semi_product + l2_boundary_product  # h1_semi + l2_boundary
    elif product == 'fixed_energy':
        opt_product = primal_fom.energy_product  # energy w.r.t. mu_bar (see above)
    else:
        assert 0, 'product: {} is not nown'.format(product)
    print('my product is {}'.format(product))

    primal_fom = primal_fom.with_(
        products=dict(opt=opt_product,
                      l2_boundary=l2_boundary_product,
                      **primal_fom.products))
    pde_opt_fom = QuadraticPdeoptStationaryModel(
        primal_fom,
        output_functional,
        opt_product=opt_product,
        use_corrected_functional=use_corrected_functional,
        use_corrected_gradient=use_corrected_gradient)
    return pde_opt_fom, data, mu_bar
def discretize_fin_pdeopt_stationary_cg(problem,
                                        grid,
                                        boundary_info,
                                        mu_for_u_d,
                                        product='h1_l2_boundary',
                                        use_corrected_functional=True,
                                        use_corrected_gradient=False,
                                        add_constant_term=False):
    if use_corrected_functional:
        print('I am using the corrected functional!!')
    else:
        print('I am using the OLD functional!!')
    if use_corrected_gradient:
        print('I am using the corrected gradient!!')
    else:
        print('I am using the OLD gradient!!')
    mu_bar = _construct_mu_bar(problem)
    print(mu_bar)
    primal_fom, data = discretize_stationary_cg(problem,
                                                grid=grid,
                                                boundary_info=boundary_info,
                                                energy_product=mu_bar)

    u_d = primal_fom.solve(mu_for_u_d)

    Boundary_Functional = primal_fom.rhs.operators[1]
    T_root_d = Boundary_Functional.apply_adjoint(u_d)
    T_root_d_squared = T_root_d.to_numpy()[0][0]**2

    # assemble output functional
    from pdeopt.theta import build_output_coefficient
    weights = {}
    mu_for_tikhonov = {}
    parameter_scales = {}
    for key, item in mu_for_u_d.items():
        if isinstance(item, list):
            weights[key] = 1. / item[0]**2
        else:
            weights[key] = 1. / item**2
        mu_for_tikhonov[key] = mu_for_u_d[key]
        parameter_scales[key] = 1.
    if add_constant_term:
        state_functional = ConstantParameterFunctional(1.)
        output_coefficient = build_output_coefficient(
            primal_fom.parameter_type,
            weights,
            mu_for_tikhonov,
            parameter_scales,
            state_functional=state_functional,
            constant_part=0.5 * T_root_d_squared)
    else:
        output_coefficient = build_output_coefficient(
            primal_fom.parameter_type, weights, mu_for_tikhonov,
            parameter_scales)

    output_functional = {}

    class Boundary_squared_half(ImmutableObject):
        def __init__(self, source, range):
            self.__auto_init(locals())
            self.linear = False

        def apply2(self, u, v, mu=None):
            return Boundary_Functional.apply_adjoint(u).to_numpy(
            ) * Boundary_Functional.apply_adjoint(v).to_numpy() * 0.5

    class Boundary_squared(ImmutableObject):
        def __init__(self, source, range):
            self.__auto_init(locals())
            self.linear = False

        def apply2(self, u, v, mu=None):
            return Boundary_Functional.apply_adjoint(u).to_numpy(
            ) * Boundary_Functional.apply_adjoint(v).to_numpy()

        def apply(self, u, mu=None):
            b = (Boundary_Functional.apply_adjoint(u).to_numpy()[0][0] *
                 Boundary_Functional).as_vector()
            return b

    source_ = Boundary_Functional.source
    range_ = Boundary_Functional.range
    output_functional['output_coefficient'] = output_coefficient
    output_functional[
        'linear_part'] = -1 * Boundary_Functional * T_root_d.to_numpy()[0][
            0]  # j(.)
    output_functional['bilinear_part'] = Boundary_squared_half(
        range_, range_)  # k(.,.)
    output_functional[
        'd_u_linear_part'] = -1 * Boundary_Functional * T_root_d.to_numpy()[0][
            0]  # j(.)
    output_functional['d_u_bilinear_part'] = Boundary_squared(
        range_, range_)  # 2k(.,.)

    # choose product
    l2_boundary_product = RobinBoundaryOperator(
        grid,
        data['boundary_info'],
        robin_data=(ConstantFunction(1, 2), ConstantFunction(1, 2)),
        name='l2_boundary_product')
    # choose product
    if product == 'h1_l2_boundary':
        opt_product = primal_fom.h1_semi_product + l2_boundary_product  # h1_semi + l2_boundary
    elif product == 'fixed_energy':
        opt_product = primal_fom.energy_product  # energy w.r.t. mu_bar (see above)
    else:
        assert 0, 'product: {} is not known'.format(product)
    print('my product is {}'.format(product))

    primal_fom = primal_fom.with_(
        products=dict(opt=opt_product,
                      l2_boundary=l2_boundary_product,
                      **primal_fom.products))
    pde_opt_fom = QuadraticPdeoptStationaryModel(
        primal_fom,
        output_functional,
        opt_product=opt_product,
        fin_model=True,
        use_corrected_functional=use_corrected_functional,
        use_corrected_gradient=use_corrected_gradient)
    return pde_opt_fom, data, mu_bar
Exemplo n.º 13
0
def main(
    problem_number: int = Argument(..., min=0, max=1, help='Selects the problem to solve [0 or 1].'),
    n: int = Argument(..., help='Triangle count per direction'),
    norm: str = Argument(
        ...,
        help="h1: compute the h1-norm of the last snapshot.\n\n"
             "l2: compute the l2-norm of the last snapshot.\n\n"
             "k: compute the energy norm of the last snapshot, where the energy-product"
             "is constructed with a parameter {'mu': k}."
    ),

    fv: bool = Option(False, help='Use finite volume discretization instead of finite elements.'),
):
    """Solves the Poisson equation in 2D using pyMOR's builtin discreization toolkit."""
    norm = float(norm) if not norm.lower() in ('h1', 'l2') else norm.lower()

    rhss = [ExpressionFunction('ones(x.shape[:-1]) * 10', 2, ()),
            LincombFunction(
                [ExpressionFunction('ones(x.shape[:-1]) * 10', 2, ()), ConstantFunction(1., 2)],
                [ProjectionParameterFunctional('mu'), 0.1])]

    dirichlets = [ExpressionFunction('zeros(x.shape[:-1])', 2, ()),
                  LincombFunction(
                  [ExpressionFunction('2 * x[..., 0]', 2, ()), ConstantFunction(1., 2)],
                  [ProjectionParameterFunctional('mu'), 0.5])]

    neumanns = [None,
                LincombFunction(
                    [ExpressionFunction('1 - x[..., 1]', 2, ()), ConstantFunction(1., 2)],
                    [ProjectionParameterFunctional('mu'), 0.5**2])]

    robins = [None,
              (LincombFunction(
                  [ExpressionFunction('x[..., 1]', 2, ()), ConstantFunction(1., 2)],
                  [ProjectionParameterFunctional('mu'), 1]), ConstantFunction(1., 2))]

    domains = [RectDomain(),
               RectDomain(right='neumann', top='dirichlet', bottom='robin')]

    rhs = rhss[problem_number]
    dirichlet = dirichlets[problem_number]
    neumann = neumanns[problem_number]
    domain = domains[problem_number]
    robin = robins[problem_number]

    problem = StationaryProblem(
        domain=domain,
        rhs=rhs,
        diffusion=LincombFunction(
            [ExpressionFunction('1 - x[..., 0]', 2, ()), ExpressionFunction('x[..., 0]', 2, ())],
            [ProjectionParameterFunctional('mu'), 1]
        ),
        dirichlet_data=dirichlet,
        neumann_data=neumann,
        robin_data=robin,
        parameter_ranges=(0.1, 1),
        name='2DProblem'
    )

    if isinstance(norm, float) and not fv:
        # use a random parameter to construct an energy product
        mu_bar = problem.parameters.parse(norm)
    else:
        mu_bar = None

    print('Discretize ...')
    if fv:
        m, data = discretize_stationary_fv(problem, diameter=1. / n)
    else:
        m, data = discretize_stationary_cg(problem, diameter=1. / n, mu_energy_product=mu_bar)
    print(data['grid'])
    print()

    print('Solve ...')
    U = m.solution_space.empty()
    for mu in problem.parameter_space.sample_uniformly(10):
        U.append(m.solve(mu))
    if mu_bar is not None:
        # use the given energy product
        norm_squared = U[-1].norm(m.products['energy'])[0]
        print('Energy norm of the last snapshot: ', np.sqrt(norm_squared))
    if not fv:
        if norm == 'h1':
            norm_squared = U[-1].norm(m.products['h1_0_semi'])[0]
            print('H^1_0 semi norm of the last snapshot: ', np.sqrt(norm_squared))
        if norm == 'l2':
            norm_squared = U[-1].norm(m.products['l2_0'])[0]
            print('L^2_0 norm of the last snapshot: ', np.sqrt(norm_squared))
    m.visualize(U, title='Solution for mu in [0.1, 1]')
Exemplo n.º 14
0
def main(
    rbsize: int = Argument(..., help='Size of the reduced basis.'),

    cache_region: Choices('none memory disk persistent') = Option(
        'none',
        help='Name of cache region to use for caching solution snapshots.'
    ),
    error_estimator: bool = Option(True, help='Use error estimator for basis generation.'),
    gamma: float = Option(0.2, help='Weight factor for age penalty term in refinement indicators.'),
    grid: int = Option(100, help='Use grid with 2*NI*NI elements.'),
    ipython_engines: int = Option(
        0,
        help='If positive, the number of IPython cluster engines to use for parallel greedy search. '
             'If zero, no parallelization is performed.'
    ),
    ipython_profile: str = Option(None, help='IPython profile to use for parallelization.'),
    list_vector_array: bool = Option(
        False,
        help='Solve using ListVectorArray[NumpyVector] instead of NumpyVectorArray.'
    ),
    pickle: str = Option(
        None,
        help='Pickle reduced discretization, as well as reductor and high-dimensional model to files with this prefix.'
    ),
    plot_err: bool = Option(False, help='Plot error.'),
    plot_solutions: bool = Option(False, help='Plot some example solutions.'),
    plot_error_sequence: bool = Option(False, help='Plot reduction error vs. basis size.'),
    product: Choices('euclidean h1') = Option(
        'h1',
        help='Product  w.r.t. which to orthonormalize and calculate Riesz representatives.'
    ),
    reductor: Choices('traditional residual_basis') = Option(
        'residual_basis',
        help='Reductor (error estimator) to choose (traditional, residual_basis).'
    ),
    rho: float = Option(1.1, help='Maximum allowed ratio between error on validation set and on training set.'),
    test: int = Option(10, help='Use COUNT snapshots for stochastic error estimation.'),
    theta: float = Option(0., help='Ratio of elements to refine.'),
    validation_mus: int = Option(0, help='Size of validation set.'),
    visualize_refinement: bool = Option(True, help='Visualize the training set refinement indicators.'),
):
    """Modified thermalblock demo using adaptive greedy basis generation algorithm."""

    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),
    )

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

    if list_vector_array:
        from pymor.discretizers.builtin.list import convert_to_numpy_list_vector_array
        fom = convert_to_numpy_list_vector_array(fom)

    if cache_region != 'none':
        # building a cache_id is only needed for persistent CacheRegions
        cache_id = f"pymordemos.thermalblock_adaptive {grid}"
        fom.enable_caching(cache_region.value, cache_id)

    if plot_solutions:
        print('Showing some solutions')
        Us = ()
        legend = ()
        for mu in problem.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_op = fom.h1_0_semi_product if product == 'h1' else None
    coercivity_estimator = ExpressionParameterFunctional('min([diffusion[0], diffusion[1]**2])',
                                                         fom.parameters)
    reductors = {'residual_basis': CoerciveRBReductor(fom, product=product_op,
                                                      coercivity_estimator=coercivity_estimator),
                 'traditional': SimpleCoerciveRBReductor(fom, product=product_op,
                                                         coercivity_estimator=coercivity_estimator)}
    reductor = reductors[reductor]

    pool = new_parallel_pool(ipython_num_engines=ipython_engines, ipython_profile=ipython_profile)
    greedy_data = rb_adaptive_greedy(
        fom, reductor, problem.parameter_space,
        validation_mus=validation_mus,
        rho=rho,
        gamma=gamma,
        theta=theta,
        use_error_estimator=error_estimator,
        error_norm=fom.h1_0_semi_norm,
        max_extensions=rbsize,
        visualize=visualize_refinement
    )

    rom = greedy_data['rom']

    if pickle:
        print(f"\nWriting reduced model to file {pickle}_reduced ...")
        with open(pickle + '_reduced', 'wb') as f:
            dump(rom, f)
        print(f"Writing detailed model and reductor to file {pickle}_detailed ...")
        with open(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,
                                       error_estimator=True,
                                       error_norms=(fom.h1_0_semi_norm,),
                                       condition=True,
                                       test_mus=problem.parameter_space.sample_randomly(test),
                                       basis_sizes=25 if 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)/{grid}

Greedy basis generation:
   error estimator enalbed:            {error_estimator}
   product:                            {product}
   prescribed basis size:              {rbsize}
   actual basis size:                  {real_rb_size}
   elapsed time:                       {greedy_data[time]}
'''.format(**locals()))
    print(results['summary'])

    sys.stdout.flush()

    if plot_error_sequence:
        from matplotlib import pyplot as plt
        plt.show()
    if 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)