def test_LincombParameterFunctional():
    dict_of_d_mus = {'mu': ['200 * mu[0]', '2 * mu[0]'], 'nu': ['cos(nu[0])']}

    epf = ExpressionParameterFunctional('100 * mu[0]**2 + 2 * mu[1] * mu[0] + sin(nu[0])',
                                        {'mu': 2, 'nu': 1},
                                        'functional_with_derivative_and_second_derivative',
                                        dict_of_d_mus)
    pf = ProjectionParameterFunctional('mu', 2, 0)
    mu = Mu({'mu': [10,2], 'nu': [3]})

    zero = pf - pf 
    two_pf = pf + pf
    three_pf = pf + 2*pf
    pf_plus_one = pf + 1
    sum_ = epf + pf 
    pf_squared =  (pf + 2*epf) * (pf - 2*epf) + 4 * epf * epf  

    assert zero(mu) == 0
    assert two_pf(mu) == 2 * pf(mu)
    assert three_pf(mu) == 3 * pf(mu)
    assert pf_plus_one(mu) == pf(mu) + 1
    assert sum_(mu) == epf(mu) + pf(mu)
    assert pf_squared(mu) == pf(mu) * pf(mu)
    assert sum_.d_mu('mu', 0)(mu) == epf.d_mu('mu', 0)(mu) + pf.d_mu('mu', 0)(mu)
    assert sum_.d_mu('mu', 1)(mu) == epf.d_mu('mu', 1)(mu) + pf.d_mu('mu', 1)(mu)
    assert sum_.d_mu('nu', 0)(mu) == epf.d_mu('nu', 0)(mu) + pf.d_mu('nu', 0)(mu)
Beispiel #2
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'])

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

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

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

    robins = [None,
                (LincombFunction(
                [ExpressionFunction('x[..., 1]', 2, ()), ConstantFunction(1.,2)],
                [ProjectionParameterFunctional('mu', 0), ExpressionParameterFunctional('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=RectDomain(),
        rhs=rhs,
        diffusion=LincombFunction(
            [ExpressionFunction('1 - x[..., 0]', 2, ()), ExpressionFunction('x[..., 0]', 2, ())],
            [ProjectionParameterFunctional('mu', 0), ExpressionParameterFunctional('1', {})]
        ),
        dirichlet_data=dirichlet,
        neumann_data=neumann,
        robin_data=robin,
        parameter_space=CubicParameterSpace({'mu': 0}, 0.1, 1),
        name='2DProblem'
    )

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

    print('Solve ...')
    U = m.solution_space.empty()
    for mu in m.parameter_space.sample_uniformly(10):
        U.append(m.solve(mu))
    m.visualize(U, title='Solution for mu in [0.1, 1]')
def test_ProjectionParameterFunctional():
    pf = ProjectionParameterFunctional('mu', (2, ), (0, ))
    mu = {'mu': (10, 2)}

    derivative_to_first_index = pf.d_mu('mu', 0)
    derivative_to_second_index = pf.d_mu('mu', 1)

    der_mu_1 = derivative_to_first_index.evaluate(mu)
    der_mu_2 = derivative_to_second_index.evaluate(mu)

    assert pf.evaluate(mu) == 10
    assert der_mu_1 == 1
    assert der_mu_2 == 0
Beispiel #4
0
def test_ProjectionParameterFunctional():
    pf = ProjectionParameterFunctional('mu', 2, 0)
    mu = Mu({'mu': (10,2)})

    derivative_to_first_index = pf.d_mu('mu', 0)
    derivative_to_second_index = pf.d_mu('mu', 1)

    second_derivative_first_first = pf.d_mu('mu', 0).d_mu('mu', 0)
    second_derivative_first_second = pf.d_mu('mu', 0).d_mu('mu', 1)
    second_derivative_second_first = pf.d_mu('mu', 1).d_mu('mu', 0)
    second_derivative_second_second = pf.d_mu('mu', 1).d_mu('mu', 1)

    der_mu_1 = derivative_to_first_index.evaluate(mu)
    der_mu_2 = derivative_to_second_index.evaluate(mu)

    hes_mu_1_mu_1 = second_derivative_first_first.evaluate(mu)
    hes_mu_1_mu_2 = second_derivative_first_second.evaluate(mu)
    hes_mu_2_mu_1 = second_derivative_second_first.evaluate(mu)
    hes_mu_2_mu_2 = second_derivative_second_second.evaluate(mu)

    assert pf.evaluate(mu) == 10
    assert der_mu_1 == 1
    assert der_mu_2 == 0
    assert hes_mu_1_mu_1 == 0
    assert hes_mu_1_mu_2 == 0
    assert hes_mu_2_mu_1 == 0
    assert hes_mu_2_mu_2 == 0
def test_d_mu_of_LincombOperator():
    dict_of_d_mus = {'mu': ['100', '2'], 'nu': 'cos(nu)'}

    pf = ProjectionParameterFunctional('mu', (2, ), (0, ))
    epf = ExpressionParameterFunctional('100 * mu[0] + 2 * mu[1] + sin(nu)', {
        'mu': (2, ),
        'nu': ()
    }, 'functional_with_derivative', dict_of_d_mus)

    mu = {'mu': (10, 2), 'nu': 0}

    space = NumpyVectorSpace(1)
    zero_op = ZeroOperator(space, space)
    operators = [zero_op, zero_op, zero_op]
    coefficients = [1., pf, epf]

    operator = LincombOperator(operators, coefficients)

    op_sensitivity_to_first_mu = operator.d_mu('mu', 0)
    op_sensitivity_to_second_mu = operator.d_mu('mu', 1)
    op_sensitivity_to_nu = operator.d_mu('nu', ())

    eval_mu_1 = op_sensitivity_to_first_mu.evaluate_coefficients(mu)
    eval_mu_2 = op_sensitivity_to_second_mu.evaluate_coefficients(mu)
    eval_nu = op_sensitivity_to_nu.evaluate_coefficients(mu)

    assert operator.evaluate_coefficients(mu) == [1., 10, 1004.]
    assert eval_mu_1 == [0., 1., 100.]
    assert eval_mu_2 == [0., 0., 2.]
    assert eval_nu == [0., 0., 1.]
Beispiel #6
0
def discretize(n, nt, blocks):
    h = 1. / blocks
    ops = [WrappedDiffusionOperator.create(n, h * i, h * (i + 1)) for i in range(blocks)]
    pfs = [ProjectionParameterFunctional('diffusion_coefficients', blocks, i) for i in range(blocks)]
    operator = LincombOperator(ops, pfs)

    initial_data = operator.source.zeros()

    # use data property of WrappedVector to setup rhs
    # note that we cannot use the data property of ListVectorArray,
    # since ListVectorArray will always return a copy
    rhs_vec = operator.range.zeros()
    rhs_data = rhs_vec._list[0].to_numpy()
    rhs_data[:] = np.ones(len(rhs_data))
    rhs_data[0] = 0
    rhs_data[len(rhs_data) - 1] = 0
    rhs = VectorOperator(rhs_vec)

    # hack together a visualizer ...
    grid = OnedGrid(domain=(0, 1), num_intervals=n)
    visualizer = OnedVisualizer(grid)

    time_stepper = ExplicitEulerTimeStepper(nt)

    fom = InstationaryModel(T=1e-0, operator=operator, rhs=rhs, initial_data=initial_data,
                            time_stepper=time_stepper, num_values=20,
                            visualizer=visualizer, name='C++-Model')
    return fom
Beispiel #7
0
 def parameter_functional_factory(ix, iy):
     return ProjectionParameterFunctional(component_name='diffusion',
                                          component_shape=(num_blocks[1],
                                                           num_blocks[0]),
                                          index=(num_blocks[1] - iy - 1,
                                                 ix),
                                          name=f'diffusion_{ix}_{iy}')
Beispiel #8
0
def elliptic_oned_demo(args):
    args['PROBLEM-NUMBER'] = int(args['PROBLEM-NUMBER'])
    assert 0 <= args['PROBLEM-NUMBER'] <= 1, ValueError('Invalid problem number.')
    args['N'] = int(args['N'])

    rhss = [ExpressionFunction('ones(x.shape[:-1]) * 10', 1, ()),
            ExpressionFunction('(x - 0.5)**2 * 1000', 1, ())]
    rhs = rhss[args['PROBLEM-NUMBER']]

    d0 = ExpressionFunction('1 - x', 1, ())
    d1 = ExpressionFunction('x', 1, ())

    parameter_space = CubicParameterSpace({'diffusionl': 0}, 0.1, 1)
    f0 = ProjectionParameterFunctional('diffusionl', 0)
    f1 = ExpressionParameterFunctional('1', {})

    problem = StationaryProblem(
        domain=LineDomain(),
        rhs=rhs,
        diffusion=LincombFunction([d0, d1], [f0, f1]),
        dirichlet_data=ConstantFunction(value=0, dim_domain=1),
        name='1DProblem'
    )

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

    print('Solve ...')
    U = d.solution_space.empty()
    for mu in parameter_space.sample_uniformly(10):
        U.append(d.solve(mu))
    d.visualize(U, title='Solution for diffusionl in [0.1, 1]')
Beispiel #9
0
def elliptic_oned_demo(args):
    args['PROBLEM-NUMBER'] = int(args['PROBLEM-NUMBER'])
    assert 0 <= args['PROBLEM-NUMBER'] <= 1, ValueError('Invalid problem number.')
    args['N'] = int(args['N'])

    rhss = [GenericFunction(lambda X: np.ones(X.shape[:-1]) * 10, dim_domain=1),
            GenericFunction(lambda X: (X[..., 0] - 0.5) ** 2 * 1000, dim_domain=1)]
    rhs = rhss[args['PROBLEM-NUMBER']]

    d0 = GenericFunction(lambda X: 1 - X[..., 0], dim_domain=1)
    d1 = GenericFunction(lambda X: X[..., 0], dim_domain=1)

    parameter_space = CubicParameterSpace({'diffusionl': 0}, 0.1, 1)
    f0 = ProjectionParameterFunctional('diffusionl', 0)
    f1 = GenericParameterFunctional(lambda mu: 1, {})

    print('Solving on OnedGrid(({0},{0}))'.format(args['N']))

    print('Setup Problem ...')
    problem = EllipticProblem(domain=LineDomain(), rhs=rhs, diffusion_functions=(d0, d1),
                              diffusion_functionals=(f0, f1), dirichlet_data=ConstantFunction(value=0, dim_domain=1),
                              name='1DProblem')

    print('Discretize ...')
    discretizer = discretize_elliptic_fv if args['--fv'] else discretize_elliptic_cg
    discretization, _ = discretizer(problem, diameter=1 / args['N'])

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

    U = discretization.solution_space.empty()
    for mu in parameter_space.sample_uniformly(10):
        U.append(discretization.solve(mu))

    print('Plot ...')
    discretization.visualize(U, title='Solution for diffusionl in [0.1, 1]')
Beispiel #10
0
def test_expand():
    ops = [NumpyMatrixOperator(np.eye(1) * i) for i in range(8)]
    pfs = [ProjectionParameterFunctional('p', 9, i) for i in range(8)]
    prods = [o * p for o, p in zip(ops, pfs)]

    op = ((prods[0] + prods[1] + prods[2]) @ (prods[3] + prods[4] + prods[5])
          @ (prods[6] + prods[7]))

    eop = expand(op)

    assert isinstance(eop, LincombOperator)
    assert len(eop.operators) == 3 * 3 * 2
    assert all(
        isinstance(o, ConcatenationOperator) and len(o.operators) == 3
        for o in eop.operators)
    assert ({to_matrix(o)[0, 0]
             for o in eop.operators} == {
                 i0 * i1 * i2
                 for i0, i1, i2 in product([0, 1, 2], [3, 4, 5], [6, 7])
             })
    assert ({
        frozenset(p.index for p in pf.factors)
        for pf in eop.coefficients
    } == {
        frozenset([i0, i1, i2])
        for i0, i1, i2 in product([0, 1, 2], [3, 4, 5], [6, 7])
    })
Beispiel #11
0
def test_LincombParameterFunctional():
    dict_of_d_mus = {'mu': ['200 * mu[0]', '2 * mu[0]'], 'nu': ['cos(nu[0])']}

    epf = ExpressionParameterFunctional('100 * mu[0]**2 + 2 * mu[1] * mu[0] + sin(nu[0])',
                                        {'mu': 2, 'nu': 1},
                                        'functional_with_derivative_and_second_derivative',
                                        dict_of_d_mus)
    pf = ProjectionParameterFunctional('mu', 2, 0)
    mu = Mu({'mu': [10,2], 'nu': [3]})

    zero = pf - pf 
    two_pf = pf + pf
    two_pf_named = two_pf.with_(name='some_interesting_quantity')
    three_pf = pf + 2*pf
    three_pf_ = pf + two_pf
    three_pf_named = pf + two_pf_named
    pf_plus_one = pf + 1
    pf_plus_one_ = 1 + pf
    sum_ = epf + pf + 1 - 3
    pf_squared_ = pf * pf
    pf_squared_named = pf_squared_.with_(name='some_interesting_quantity')
    pf_times_pf_squared = pf * pf_squared_
    pf_times_pf_squared_named = pf * pf_squared_named
    pf_squared =  4 * epf * epf * 1 + (pf + 2*epf) * (pf - 2*epf)

    assert zero(mu) == 0
    assert two_pf(mu) == 2 * pf(mu)
    assert three_pf(mu) == 3 * pf(mu)
    assert three_pf_(mu) == 3 * pf(mu)
    assert pf_plus_one(mu) == pf(mu) + 1
    assert pf_plus_one_(mu) == pf(mu) + 1
    assert sum_(mu) == epf(mu) + pf(mu) + 1 - 3
    assert pf_squared_(mu) == pf(mu) * pf(mu)
    assert pf_squared(mu) == pf(mu) * pf(mu)
    assert pf_times_pf_squared(mu) == pf(mu) * pf(mu) * pf(mu)
    # derivatives are linear
    assert sum_.d_mu('mu', 0)(mu) == epf.d_mu('mu', 0)(mu) + pf.d_mu('mu', 0)(mu)
    assert sum_.d_mu('mu', 1)(mu) == epf.d_mu('mu', 1)(mu) + pf.d_mu('mu', 1)(mu)
    assert sum_.d_mu('nu', 0)(mu) == epf.d_mu('nu', 0)(mu) + pf.d_mu('nu', 0)(mu)
    # sums and products are not nested
    assert len(sum_.coefficients) == 4
    assert len(pf_squared.functionals[0].factors) == 4
    # named functions will not be merged and still be nested
    assert three_pf_named(mu) == three_pf_(mu)
    assert len(three_pf_named.coefficients) != len(three_pf_.coefficients)
    assert pf_times_pf_squared_named(mu) == pf_times_pf_squared(mu)
    assert len(pf_times_pf_squared_named.factors) != len(pf_times_pf_squared.factors)
Beispiel #12
0
def test_ProductParameterFunctional():
    # Projection ParameterFunctional
    pf = ProjectionParameterFunctional('mu', 2, 0)
    # Expression ParameterFunctional
    dict_of_d_mus = {'nu': ['2*nu']}
    dict_of_second_derivative = {'nu': [{'nu': ['2']}]}
    epf = ExpressionParameterFunctional('nu**2', {'nu': 1},
                                        'expression_functional',
                                        dict_of_d_mus, dict_of_second_derivative)
    mu = Mu({'mu': (10,2), 'nu': 3})

    productf = pf * epf * 2. * pf

    derivative_to_first_index = productf.d_mu('mu', 0)
    derivative_to_second_index = productf.d_mu('mu', 1)
    derivative_to_third_index = productf.d_mu('nu', 0)

    second_derivative_first_first = productf.d_mu('mu', 0).d_mu('mu', 0)
    second_derivative_first_second = productf.d_mu('mu', 0).d_mu('mu', 1)
    second_derivative_first_third = productf.d_mu('mu', 0).d_mu('nu', 0)
    second_derivative_second_first = productf.d_mu('mu', 1).d_mu('mu', 0)
    second_derivative_second_second = productf.d_mu('mu', 1).d_mu('mu', 1)
    second_derivative_second_third = productf.d_mu('mu', 1).d_mu('nu', 0)
    second_derivative_third_first = productf.d_mu('nu', 0).d_mu('mu', 0)
    second_derivative_third_second = productf.d_mu('nu', 0).d_mu('mu', 1)
    second_derivative_third_third = productf.d_mu('nu', 0).d_mu('nu', 0)

    der_mu_1 = derivative_to_first_index.evaluate(mu)
    der_mu_2 = derivative_to_second_index.evaluate(mu)
    der_nu_3 = derivative_to_third_index.evaluate(mu)

    hes_mu_1_mu_1 = second_derivative_first_first.evaluate(mu)
    hes_mu_1_mu_2 = second_derivative_first_second.evaluate(mu)
    hes_mu_1_nu_3 = second_derivative_first_third.evaluate(mu)
    hes_mu_2_mu_1 = second_derivative_second_first.evaluate(mu)
    hes_mu_2_mu_2 = second_derivative_second_second.evaluate(mu)
    hes_mu_2_nu_3 = second_derivative_second_third.evaluate(mu)
    hes_nu_3_mu_1 = second_derivative_third_first.evaluate(mu)
    hes_nu_3_mu_2 = second_derivative_third_second.evaluate(mu)
    hes_nu_3_nu_3 = second_derivative_third_third.evaluate(mu)

    # note that productf(mu,nu) = 2 * pf(mu)**2 * epf(nu)
    # and thus:
    #      d_mu productf(mu,nu) = 2 * 2 * pf(mu) * (d_mu pf)(mu) * epf(nu)
    #      d_nu productf(mu,nu) = 2 * pf(mu)**2 * (d_nu epf)(nu)
    # and so forth
    assert der_mu_1 == 2 * 2 * 10 * 1 * 9
    assert der_mu_2 == 0
    assert der_nu_3 == 2 * 10**2 * 6
    assert hes_mu_1_mu_1 == 2 * 2 * 9
    assert hes_mu_1_mu_2 == 0
    assert hes_mu_1_nu_3 == 2 * 2 * 10 * 1 * 6
    assert hes_mu_2_mu_1 == 0
    assert hes_mu_2_mu_2 == 0
    assert hes_mu_2_nu_3 == 0
    assert hes_nu_3_mu_1 == 2 * 2 * 10 * 1 * 6
    assert hes_nu_3_mu_2 == 0
    assert hes_nu_3_nu_3 == 2 * 10**2 * 2
Beispiel #13
0
def test_simple_ProductParameterFunctional():
    pf = ProjectionParameterFunctional('mu', 2, 0)
    mu = Mu({'mu': (10,2)})
    productf = pf * 2 * 3

    derivative_to_first_index = productf.d_mu('mu', 0)
    derivative_to_second_index = productf.d_mu('mu', 1)

    second_derivative_first_first = productf.d_mu('mu', 0).d_mu('mu', 0)
    second_derivative_first_second = productf.d_mu('mu', 0).d_mu('mu', 1)
    second_derivative_second_first = productf.d_mu('mu', 1).d_mu('mu', 0)
    second_derivative_second_second = productf.d_mu('mu', 1).d_mu('mu', 1)

    der_mu_1 = derivative_to_first_index.evaluate(mu)
    der_mu_2 = derivative_to_second_index.evaluate(mu)

    hes_mu_1_mu_1 = second_derivative_first_first.evaluate(mu)
    hes_mu_1_mu_2 = second_derivative_first_second.evaluate(mu)
    hes_mu_2_mu_1 = second_derivative_second_first.evaluate(mu)
    hes_mu_2_mu_2 = second_derivative_second_second.evaluate(mu)

    assert der_mu_1 == 2 * 3
    assert der_mu_2 == 0
    assert hes_mu_1_mu_1 == 0
    assert hes_mu_1_mu_2 == 0
    assert hes_mu_2_mu_1 == 0
    assert hes_mu_2_mu_2 == 0

    dict_of_d_mus = {'mu': ['2*mu']}

    dict_of_second_derivative = {'mu': [{'mu': ['2']}]}

    epf = ExpressionParameterFunctional('mu**2',
                                        {'mu': 1},
                                        'functional_with_derivative_and_second_derivative',
                                        dict_of_d_mus, dict_of_second_derivative)

    productf = epf * 2
    mu = Mu({'mu': 3})

    derivative_to_first_index = productf.d_mu('mu')

    second_derivative_first_first = productf.d_mu('mu').d_mu('mu')

    der_mu = derivative_to_first_index.evaluate(mu)

    hes_mu_mu = second_derivative_first_first.evaluate(mu)

    assert productf.evaluate(mu) == 2 * 3 ** 2
    assert der_mu == 2 * 2 * 3
    assert hes_mu_mu == 2 * 2
Beispiel #14
0
def test_output_d_mu():
    from pymordemos.linear_optimization import create_fom

    grid_intervals = 10
    training_samples = 3

    fom, mu_bar = create_fom(grid_intervals, vector_valued_output=True)
    easy_fom, _ = create_fom(grid_intervals, vector_valued_output=False)

    parameter_space = fom.parameters.space(0, np.pi)
    training_set = parameter_space.sample_uniformly(training_samples)

    #verifying that the adjoint and sensitivity gradients are the same and that solve_d_mu works
    for mu in training_set:
        gradient_with_adjoint_approach = fom.output_d_mu(mu, return_array=True, use_adjoint=True)
        gradient_with_sensitivities = fom.output_d_mu(mu, return_array=True, use_adjoint=False)
        assert np.allclose(gradient_with_adjoint_approach, gradient_with_sensitivities)
        u_d_mu = fom.solve_d_mu('diffusion', 1, mu=mu).to_numpy()
        u_d_mu_ = fom.compute(solution_d_mu=True, mu=mu)['solution_d_mu']['diffusion'][1].to_numpy()
        assert np.allclose(u_d_mu, u_d_mu_)

        # test the complex case
        complex_fom = easy_fom.with_(operator=easy_fom.operator.with_(
            operators=[op* (1+2j) for op in easy_fom.operator.operators]))
        complex_gradient_adjoint = complex_fom.output_d_mu(mu, return_array=True, use_adjoint=True)
        complex_gradient = complex_fom.output_d_mu(mu, return_array=True, use_adjoint=False)
        assert np.allclose(complex_gradient_adjoint, complex_gradient)

        complex_fom = easy_fom.with_(output_functional=easy_fom.output_functional.with_(
            operators=[op* (1+2j) for op in easy_fom.output_functional.operators]))
        complex_gradient_adjoint = complex_fom.output_d_mu(mu, return_array=True, use_adjoint=True)
        complex_gradient = complex_fom.output_d_mu(mu, return_array=True, use_adjoint=False)
        assert np.allclose(complex_gradient_adjoint, complex_gradient)

    # another fom to test the 3d case
    ops, coefs = fom.operator.operators, fom.operator.coefficients
    ops += (fom.operator.operators[1],)
    coefs += (ProjectionParameterFunctional('nu', 1, 0),)
    fom_ = fom.with_(operator=LincombOperator(ops, coefs))
    parameter_space = fom_.parameters.space(0, np.pi)
    training_set = parameter_space.sample_uniformly(training_samples)
    for mu in training_set:
        gradient_with_adjoint_approach = fom_.output_d_mu(mu, return_array=True, use_adjoint=True)
        gradient_with_sensitivities = fom_.output_d_mu(mu, return_array=True, use_adjoint=False)
        assert np.allclose(gradient_with_adjoint_approach, gradient_with_sensitivities)
Beispiel #15
0
def main(
    problem_number: int = Argument(
        ..., min=0, max=1, help='Selects the problem to solve [0 or 1].'),
    n: int = Argument(..., help='Grid interval count.'),
    fv: bool = Option(
        False,
        help='Use finite volume discretization instead of finite elements.'),
):
    """Solves the Poisson equation in 1D using pyMOR's builtin discreization toolkit."""

    rhss = [
        ExpressionFunction('ones(x.shape[:-1]) * 10', 1, ()),
        ExpressionFunction('(x - 0.5)**2 * 1000', 1, ())
    ]
    rhs = rhss[problem_number]

    d0 = ExpressionFunction('1 - x', 1, ())
    d1 = ExpressionFunction('x', 1, ())

    f0 = ProjectionParameterFunctional('diffusionl')
    f1 = 1.

    problem = StationaryProblem(domain=LineDomain(),
                                rhs=rhs,
                                diffusion=LincombFunction([d0, d1], [f0, f1]),
                                dirichlet_data=ConstantFunction(value=0,
                                                                dim_domain=1),
                                name='1DProblem')

    parameter_space = problem.parameters.space(0.1, 1)

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

    print('Solve ...')
    U = m.solution_space.empty()
    for mu in parameter_space.sample_uniformly(10):
        U.append(m.solve(mu))
    m.visualize(U, title='Solution for diffusionl in [0.1, 1]')
Beispiel #16
0
def discretize(n, nt, blocks):
    h = 1. / blocks
    ops = [
        WrappedDiffusionOperator.create(n, h * i, h * (i + 1))
        for i in range(blocks)
    ]
    pfs = [
        ProjectionParameterFunctional('diffusion_coefficients', (blocks, ),
                                      (i, )) for i in range(blocks)
    ]
    operator = LincombOperator(ops, pfs)

    initial_data = operator.source.zeros()

    # use data property of WrappedVector to setup rhs
    # note that we cannot use the data property of ListVectorArray,
    # since ListVectorArray will always return a copy
    rhs_vec = operator.range.zeros()
    rhs_data = rhs_vec._list[0].data
    rhs_data[:] = np.ones(len(rhs_data))
    rhs_data[0] = 0
    rhs_data[len(rhs_data) - 1] = 0
    rhs = VectorFunctional(rhs_vec)

    # hack together a visualizer ...
    grid = OnedGrid(domain=(0, 1), num_intervals=n)
    visualizer = Matplotlib1DVisualizer(grid)

    time_stepper = ExplicitEulerTimeStepper(nt)
    parameter_space = CubicParameterSpace(operator.parameter_type, 0.1, 1)

    d = InstationaryDiscretization(T=1e-0,
                                   operator=operator,
                                   rhs=rhs,
                                   initial_data=initial_data,
                                   time_stepper=time_stepper,
                                   num_values=20,
                                   parameter_space=parameter_space,
                                   visualizer=visualizer,
                                   name='C++-Discretization',
                                   cache_region=None)
    return d
Beispiel #17
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'])

    rhss = [
        ExpressionFunction('ones(x.shape[:-1]) * 10', 2, ()),
        ExpressionFunction('(x[..., 0] - 0.5)**2 * 1000', 2, ())
    ]
    rhs = rhss[args['PROBLEM-NUMBER']]

    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.1, 1),
        name='2DProblem')

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

    print('Solve ...')
    U = m.solution_space.empty()
    for mu in m.parameter_space.sample_uniformly(10):
        U.append(m.solve(mu))
    m.visualize(U, title='Solution for diffusionl in [0.1, 1]')
Beispiel #18
0
def text_problem(text='pyMOR', font_name=None):
    import numpy as np
    from PIL import Image, ImageDraw, ImageFont
    from tempfile import NamedTemporaryFile

    font_list = [font_name] if font_name else [
        'DejaVuSansMono.ttf', 'VeraMono.ttf', 'UbuntuMono-R.ttf', 'Arial.ttf'
    ]
    font = None
    for filename in font_list:
        try:
            font = ImageFont.truetype(
                filename, 64)  # load some font from file of given size
        except (OSError, IOError):
            pass
    if font is None:
        raise ValueError('Could not load TrueType font')

    size = font.getsize(text)  # compute width and height of rendered text
    size = (size[0] + 20, size[1] + 20
            )  # add a border of 10 pixels around the text

    def make_bitmap_function(
            char_num
    ):  # we need to genereate a BitmapFunction for each character
        img = Image.new('L',
                        size)  # create new Image object of given dimensions
        d = ImageDraw.Draw(img)  # create ImageDraw object for the given Image

        # in order to position the character correctly, we first draw all characters from the first
        # up to the wanted character
        d.text((10, 10), text[:char_num + 1], font=font, fill=255)

        # next we erase all previous character by drawing a black rectangle
        if char_num > 0:
            d.rectangle(
                ((0, 0), (font.getsize(text[:char_num])[0] + 10, size[1])),
                fill=0,
                outline=0)

        # open a new temporary file
        with NamedTemporaryFile(
                suffix='.png'
        ) as f:  # after leaving this 'with' block, the temporary
            # file is automatically deleted
            img.save(f, format='png')
            return BitmapFunction(f.name,
                                  bounding_box=[(0, 0), size],
                                  range=[0., 1.])

    # create BitmapFunctions for each character
    dfs = [make_bitmap_function(n) for n in range(len(text))]

    # create an indicator function for the background
    background = ConstantFunction(1., 2) - LincombFunction(
        dfs, np.ones(len(dfs)))

    # form the linear combination
    dfs = [background] + dfs
    coefficients = [1] + [
        ProjectionParameterFunctional('diffusion', (len(text), ), (i, ))
        for i in range(len(text))
    ]
    diffusion = LincombFunction(dfs, coefficients)

    return StationaryProblem(domain=RectDomain(dfs[1].bounding_box,
                                               bottom='neumann'),
                             neumann_data=ConstantFunction(-1., 2),
                             diffusion=diffusion,
                             parameter_space=CubicParameterSpace(
                                 diffusion.parameter_type, 0.1, 1.))
Beispiel #19
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]')
Beispiel #20
0
def misc_operator_with_arrays_and_products_factory(n):
    if n == 0:
        from pymor.operators.constructions import ComponentProjection
        _, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(100, 10, 4, 3, n)
        op = ComponentProjection(np.random.randint(0, 100, 10), U.space)
        return op, _, U, V, sp, rp
    elif n == 1:
        from pymor.operators.constructions import ComponentProjection
        _, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(100, 0, 4, 3, n)
        op = ComponentProjection([], U.space)
        return op, _, U, V, sp, rp
    elif n == 2:
        from pymor.operators.constructions import ComponentProjection
        _, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(100, 3, 4, 3, n)
        op = ComponentProjection([3, 3, 3], U.space)
        return op, _, U, V, sp, rp
    elif n == 3:
        from pymor.operators.constructions import AdjointOperator
        op, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(100, 20, 4, 3, n)
        op = AdjointOperator(op, with_apply_inverse=True)
        return op, _, V, U, rp, sp
    elif n == 4:
        from pymor.operators.constructions import AdjointOperator
        op, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(100, 20, 4, 3, n)
        op = AdjointOperator(op, with_apply_inverse=False)
        return op, _, V, U, rp, sp
    elif 5 <= n <= 7:
        from pymor.operators.constructions import SelectionOperator
        from pymor.parameters.functionals import ProjectionParameterFunctional
        op0, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(30, 30, 4, 3, n)
        op1 = NumpyMatrixOperator(np.random.random((30, 30)))
        op2 = NumpyMatrixOperator(np.random.random((30, 30)))
        op = SelectionOperator([op0, op1, op2], ProjectionParameterFunctional('x', ()), [0.3, 0.6])
        return op, op.parse_parameter((n-5)/2), V, U, rp, sp
    elif n == 8:
        from pymor.operators.block import BlockDiagonalOperator
        from pymor.vectorarrays.block import BlockVectorArray
        op0, _, U0, V0, sp0, rp0 = numpy_matrix_operator_with_arrays_and_products_factory(10, 10, 4, 3, n)
        op1, _, U1, V1, sp1, rp1 = numpy_matrix_operator_with_arrays_and_products_factory(20, 20, 4, 3, n+1)
        op2, _, U2, V2, sp2, rp2 = numpy_matrix_operator_with_arrays_and_products_factory(30, 30, 4, 3, n+2)
        op = BlockDiagonalOperator([op0, op1, op2])
        sp = BlockDiagonalOperator([sp0, sp1, sp2])
        rp = BlockDiagonalOperator([rp0, rp1, rp2])
        U = BlockVectorArray([U0, U1, U2])
        V = BlockVectorArray([V0, V1, V2])
        return op, _, U, V, sp, rp
    elif n == 9:
        from pymor.operators.block import BlockDiagonalOperator, BlockOperator
        from pymor.vectorarrays.block import BlockVectorArray
        op0, _, U0, V0, sp0, rp0 = numpy_matrix_operator_with_arrays_and_products_factory(10, 10, 4, 3, n)
        op1, _, U1, V1, sp1, rp1 = numpy_matrix_operator_with_arrays_and_products_factory(20, 20, 4, 3, n+1)
        op2, _, U2, V2, sp2, rp2 = numpy_matrix_operator_with_arrays_and_products_factory(20, 10, 4, 3, n+2)
        op = BlockOperator([[op0, op2],
                            [None, op1]])
        sp = BlockDiagonalOperator([sp0, sp1])
        rp = BlockDiagonalOperator([rp0, rp1])
        U = BlockVectorArray([U0, U1])
        V = BlockVectorArray([V0, V1])
        return op, None, U, V, sp, rp
    else:
        assert False
Beispiel #21
0
 def parameter_functional_factory(x, y):
     return ProjectionParameterFunctional(component_name='diffusion',
                                          component_shape=(yblocks, xblocks),
                                          index=(yblocks - y - 1, x),
                                          name=f'diffusion_{x}_{y}')
Beispiel #22
0
def test_d_mu_of_LincombOperator():
    dict_of_d_mus = {'mu': ['100', '2 * mu[0]'], 'nu': 'cos(nu)'}

    dict_of_second_derivative = {
        'mu': [{
            'mu': ['0', '2'],
            'nu': '0'
        }, {
            'mu': ['2', '0'],
            'nu': '0'
        }],
        'nu': {
            'mu': ['0', '0'],
            'nu': '-sin(nu)'
        }
    }

    pf = ProjectionParameterFunctional('mu', (2, ), (0, ))
    epf = ExpressionParameterFunctional(
        '100 * mu[0] + 2 * mu[1] * mu[0] + sin(nu)', {
            'mu': (2, ),
            'nu': ()
        }, 'functional_with_derivative', dict_of_d_mus,
        dict_of_second_derivative)

    mu = {'mu': (10, 2), 'nu': 0}

    space = NumpyVectorSpace(1)
    zero_op = ZeroOperator(space, space)
    operators = [zero_op, zero_op, zero_op]
    coefficients = [1., pf, epf]

    operator = LincombOperator(operators, coefficients)

    op_sensitivity_to_first_mu = operator.d_mu('mu', 0)
    op_sensitivity_to_second_mu = operator.d_mu('mu', 1)
    op_sensitivity_to_nu = operator.d_mu('nu', ())

    eval_mu_1 = op_sensitivity_to_first_mu.evaluate_coefficients(mu)
    eval_mu_2 = op_sensitivity_to_second_mu.evaluate_coefficients(mu)
    eval_nu = op_sensitivity_to_nu.evaluate_coefficients(mu)

    second_derivative_first_mu_first_mu = operator.d_mu('mu', 0).d_mu('mu', 0)
    second_derivative_first_mu_second_mu = operator.d_mu('mu', 0).d_mu('mu', 1)
    second_derivative_first_mu_nu = operator.d_mu('mu', 0).d_mu('nu')
    second_derivative_second_mu_first_mu = operator.d_mu('mu', 1).d_mu('mu', 0)
    second_derivative_second_mu_second_mu = operator.d_mu('mu',
                                                          1).d_mu('mu', 1)
    second_derivative_second_mu_nu = operator.d_mu('mu', 1).d_mu('nu')
    second_derivative_nu_first_mu = operator.d_mu('nu').d_mu('mu', 0)
    second_derivative_nu_second_mu = operator.d_mu('nu').d_mu('mu', 1)
    second_derivative_nu_nu = operator.d_mu('nu').d_mu('nu')

    hes_mu_1_mu_1 = second_derivative_first_mu_first_mu.evaluate_coefficients(
        mu)
    hes_mu_1_mu_2 = second_derivative_first_mu_second_mu.evaluate_coefficients(
        mu)
    hes_mu_1_nu = second_derivative_first_mu_nu.evaluate_coefficients(mu)
    hes_mu_2_mu_1 = second_derivative_second_mu_first_mu.evaluate_coefficients(
        mu)
    hes_mu_2_mu_2 = second_derivative_second_mu_second_mu.evaluate_coefficients(
        mu)
    hes_mu_2_nu = second_derivative_second_mu_nu.evaluate_coefficients(mu)
    hes_nu_mu_1 = second_derivative_nu_first_mu.evaluate_coefficients(mu)
    hes_nu_mu_2 = second_derivative_nu_second_mu.evaluate_coefficients(mu)
    hes_nu_nu = second_derivative_nu_nu.evaluate_coefficients(mu)

    assert operator.evaluate_coefficients(mu) == [1., 10, 1040.]
    assert eval_mu_1 == [0., 1., 100.]
    assert eval_mu_2 == [0., 0., 2. * 10]
    assert eval_nu == [0., 0., 1.]

    assert hes_mu_1_mu_1 == [0., 0., 0.]
    assert hes_mu_1_mu_2 == [0., 0., 2]
    assert hes_mu_1_nu == [0., 0., 0]
    assert hes_mu_2_mu_1 == [0., 0., 2]
    assert hes_mu_2_mu_2 == [0., 0., 0]
    assert hes_mu_2_nu == [0., 0., 0]
    assert hes_nu_mu_1 == [0., 0., 0]
    assert hes_nu_mu_2 == [0., 0., 0]
    assert hes_nu_nu == [0., 0., -0]
Beispiel #23
0
def misc_operator_with_arrays_and_products_factory(n):
    if n == 0:
        from pymor.operators.constructions import ComponentProjection
        _, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(
            100, 10, 4, 3, n)
        op = ComponentProjection(np.random.randint(0, 100, 10), U.space)
        return op, _, U, V, sp, rp
    elif n == 1:
        from pymor.operators.constructions import ComponentProjection
        _, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(
            100, 0, 4, 3, n)
        op = ComponentProjection([], U.space)
        return op, _, U, V, sp, rp
    elif n == 2:
        from pymor.operators.constructions import ComponentProjection
        _, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(
            100, 3, 4, 3, n)
        op = ComponentProjection([3, 3, 3], U.space)
        return op, _, U, V, sp, rp
    elif n == 3:
        from pymor.operators.constructions import AdjointOperator
        op, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(
            100, 20, 4, 3, n)
        op = AdjointOperator(op, with_apply_inverse=True)
        return op, _, V, U, rp, sp
    elif n == 4:
        from pymor.operators.constructions import AdjointOperator
        op, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(
            100, 20, 4, 3, n)
        op = AdjointOperator(op, with_apply_inverse=False)
        return op, _, V, U, rp, sp
    elif 5 <= n <= 7:
        from pymor.operators.constructions import SelectionOperator
        from pymor.parameters.functionals import ProjectionParameterFunctional
        op0, _, U, V, sp, rp = numpy_matrix_operator_with_arrays_and_products_factory(
            30, 30, 4, 3, n)
        op1 = NumpyMatrixOperator(np.random.random((30, 30)))
        op2 = NumpyMatrixOperator(np.random.random((30, 30)))
        op = SelectionOperator([op0, op1, op2],
                               ProjectionParameterFunctional('x'), [0.3, 0.6])
        return op, op.parameters.parse((n - 5) / 2), V, U, rp, sp
    elif n == 8:
        from pymor.operators.block import BlockDiagonalOperator
        op0, _, U0, V0, sp0, rp0 = numpy_matrix_operator_with_arrays_and_products_factory(
            10, 10, 4, 3, n)
        op1, _, U1, V1, sp1, rp1 = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 20, 4, 3, n + 1)
        op2, _, U2, V2, sp2, rp2 = numpy_matrix_operator_with_arrays_and_products_factory(
            30, 30, 4, 3, n + 2)
        op = BlockDiagonalOperator([op0, op1, op2])
        sp = BlockDiagonalOperator([sp0, sp1, sp2])
        rp = BlockDiagonalOperator([rp0, rp1, rp2])
        U = op.source.make_array([U0, U1, U2])
        V = op.range.make_array([V0, V1, V2])
        return op, _, U, V, sp, rp
    elif n == 9:
        from pymor.operators.block import BlockDiagonalOperator, BlockOperator
        from pymor.parameters.functionals import ProjectionParameterFunctional
        op0a, _, U0, V0, sp0, rp0 = numpy_matrix_operator_with_arrays_and_products_factory(
            10, 10, 4, 3, n)
        op0b, _, _, _, _, _ = numpy_matrix_operator_with_arrays_and_products_factory(
            10, 10, 4, 3, n)
        op0c, _, _, _, _, _ = numpy_matrix_operator_with_arrays_and_products_factory(
            10, 10, 4, 3, n)
        op1, _, U1, V1, sp1, rp1 = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 20, 4, 3, n + 1)
        op2a, _, _, _, _, _ = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 10, 4, 3, n + 2)
        op2b, _, _, _, _, _ = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 10, 4, 3, n + 2)
        op0 = (op0a * ProjectionParameterFunctional('p', 3, 0) +
               op0b * ProjectionParameterFunctional('p', 3, 1) +
               op0c * ProjectionParameterFunctional('p', 3, 1))
        op2 = (op2a * ProjectionParameterFunctional('p', 3, 0) +
               op2b * ProjectionParameterFunctional('q', 1))
        op = BlockOperator([[op0, op2], [None, op1]])
        mu = op.parameters.parse({'p': [1, 2, 3], 'q': 4})
        sp = BlockDiagonalOperator([sp0, sp1])
        rp = BlockDiagonalOperator([rp0, rp1])
        U = op.source.make_array([U0, U1])
        V = op.range.make_array([V0, V1])
        return op, mu, U, V, sp, rp
    elif n == 10:
        from pymor.operators.block import BlockDiagonalOperator, BlockColumnOperator
        from pymor.parameters.functionals import ProjectionParameterFunctional
        op0, _, U0, V0, sp0, rp0 = numpy_matrix_operator_with_arrays_and_products_factory(
            10, 10, 4, 3, n)
        op1, _, U1, V1, sp1, rp1 = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 20, 4, 3, n + 1)
        op2a, _, _, _, _, _ = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 10, 4, 3, n + 2)
        op2b, _, _, _, _, _ = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 10, 4, 3, n + 2)
        op2 = (op2a * ProjectionParameterFunctional('p', 3, 0) +
               op2b * ProjectionParameterFunctional('q', 1))
        op = BlockColumnOperator([op2, op1])
        mu = op.parameters.parse({'p': [1, 2, 3], 'q': 4})
        sp = sp1
        rp = BlockDiagonalOperator([rp0, rp1])
        U = U1
        V = op.range.make_array([V0, V1])
        return op, mu, U, V, sp, rp
    elif n == 11:
        from pymor.operators.block import BlockDiagonalOperator, BlockRowOperator
        from pymor.parameters.functionals import ProjectionParameterFunctional
        op0, _, U0, V0, sp0, rp0 = numpy_matrix_operator_with_arrays_and_products_factory(
            10, 10, 4, 3, n)
        op1, _, U1, V1, sp1, rp1 = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 20, 4, 3, n + 1)
        op2a, _, _, _, _, _ = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 10, 4, 3, n + 2)
        op2b, _, _, _, _, _ = numpy_matrix_operator_with_arrays_and_products_factory(
            20, 10, 4, 3, n + 2)
        op2 = (op2a * ProjectionParameterFunctional('p', 3, 0) +
               op2b * ProjectionParameterFunctional('q', 1))
        op = BlockRowOperator([op0, op2])
        mu = op.parameters.parse({'p': [1, 2, 3], 'q': 4})
        sp = BlockDiagonalOperator([sp0, sp1])
        rp = rp0
        U = op.source.make_array([U0, U1])
        V = V0
        return op, mu, U, V, sp, rp
    else:
        assert False
Beispiel #24
0
def main(
        n: int = Argument(100, help='Order of the FOM.'),
        r: int = Argument(10, help='Order of the ROMs.'),
):
    """Synthetic parametric demo.

    See the `MOR Wiki page <http://modelreduction.org/index.php/Synthetic_parametric_model>`_.
    """
    # Model
    # set coefficients
    a = -np.linspace(1e1, 1e3, n // 2)
    b = np.linspace(1e1, 1e3, n // 2)
    c = np.ones(n // 2)
    d = np.zeros(n // 2)

    # build 2x2 submatrices
    aa = np.empty(n)
    aa[::2] = a
    aa[1::2] = a
    bb = np.zeros(n)
    bb[::2] = b

    # set up system matrices
    Amu = sps.diags(aa, format='csc')
    A0 = sps.diags([bb, -bb], [1, -1], shape=(n, n), format='csc')
    B = np.zeros((n, 1))
    B[::2, 0] = 2
    C = np.empty((1, n))
    C[0, ::2] = c
    C[0, 1::2] = d

    # form operators
    A0 = NumpyMatrixOperator(A0)
    Amu = NumpyMatrixOperator(Amu)
    B = NumpyMatrixOperator(B)
    C = NumpyMatrixOperator(C)
    A = A0 + Amu * ProjectionParameterFunctional('mu')

    # form a model
    lti = LTIModel(A, B, C)

    mu_list = [1 / 50, 1 / 20, 1 / 10, 1 / 5, 1 / 2, 1]
    w = np.logspace(0.5, 3.5, 200)

    # System poles
    fig, ax = plt.subplots()
    for mu in mu_list:
        poles = lti.poles(mu=mu)
        ax.plot(poles.real, poles.imag, '.', label=fr'$\mu = {mu}$')
    ax.set_title('System poles')
    ax.legend()
    plt.show()

    # Magnitude plot
    fig, ax = plt.subplots()
    for mu in mu_list:
        lti.mag_plot(w, ax=ax, mu=mu, label=fr'$\mu = {mu}$')
    ax.legend()
    plt.show()

    # Hankel singular values
    fig, ax = plt.subplots()
    for mu in mu_list:
        hsv = lti.hsv(mu=mu)
        ax.semilogy(range(1, len(hsv) + 1), hsv, '.-', label=fr'$\mu = {mu}$')
    ax.set_title('Hankel singular values')
    ax.legend()
    plt.show()

    # System norms
    for mu in mu_list:
        print(f'mu = {mu}:')
        print(f'    H_2-norm of the full model:    {lti.h2_norm(mu=mu):e}')
        if config.HAVE_SLYCOT:
            print(
                f'    H_inf-norm of the full model:  {lti.hinf_norm(mu=mu):e}')
        print(f'    Hankel-norm of the full model: {lti.hankel_norm(mu=mu):e}')

    # Model order reduction
    run_mor_method_param(lti, r, w, mu_list, BTReductor, 'BT')
    run_mor_method_param(lti, r, w, mu_list, IRKAReductor, 'IRKA')
Beispiel #25
0
 def parameter_functional_factory(ix, iy):
     return ProjectionParameterFunctional('diffusion',
                                          size=num_blocks[0]*num_blocks[1],
                                          index=ix + iy*num_blocks[0],
                                          name=f'diffusion_{ix}_{iy}')
Beispiel #26
0
 def parameter_functional_factory(x, y):
     return ProjectionParameterFunctional(
         component_name='diffusion',
         component_shape=(num_blocks[1], num_blocks[0]),
         coordinates=(num_blocks[1] - y - 1, x),
         name='diffusion_{}_{}'.format(x, y))
Beispiel #27
0
 def parameter_functional_factory(x, y):
     return ProjectionParameterFunctional('diffusion',
                                          size=yblocks*xblocks,
                                          index=yblocks - y - 1 + x * yblocks,
                                          name=f'diffusion_{x}_{y}')
Beispiel #28
0
def init_grid_and_problem(config, mu_bar=(1, 1, 1, 1), mu_hat=(1, 1, 1, 1)):
    logger = getLogger('thermalblock_problem.thermalblock_problem')
    logger.info('initializing grid and problem ... ')

    lower_left = [-1, -1]
    upper_right = [1, 1]
    inner_boundary_id = 18446744073709551573
    grid = make_grid((lower_left, upper_right), config['num_subdomains'],
                     config['half_num_fine_elements_per_subdomain_and_dim'],
                     inner_boundary_id)
    all_dirichlet_boundary_info = make_boundary_info(
        grid, {'type': 'xt.grid.boundaryinfo.alldirichlet'})

    XBLOCKS = 2
    YBLOCKS = 2

    def diffusion_function_factory(ix, iy):
        values = [[0.]] * (YBLOCKS * XBLOCKS)
        values[ix + XBLOCKS * iy] = [1.]
        return make_checkerboard_function_1x1(grid_provider=grid,
                                              lower_left=lower_left,
                                              upper_right=upper_right,
                                              num_elements=[XBLOCKS, YBLOCKS],
                                              values=values,
                                              name='diffusion_{}_{}'.format(
                                                  ix, iy))

    diffusion_functions = [
        diffusion_function_factory(ix, iy)
        for ix, iy in product(range(XBLOCKS), range(YBLOCKS))
    ]

    parameter_type = {'diffusion': (YBLOCKS, XBLOCKS)}
    coefficients = [
        ProjectionParameterFunctional(component_name='diffusion',
                                      component_shape=(YBLOCKS, XBLOCKS),
                                      coordinates=(YBLOCKS - y - 1, x))
        for x in range(XBLOCKS) for y in range(YBLOCKS)
    ]

    kappa = make_constant_function_2x2(grid, [[1., 0.], [0., 1.]],
                                       name='kappa')
    f = make_expression_function_1x1(
        grid,
        'x',
        '0.5*pi*pi*cos(0.5*pi*x[0])*cos(0.5*pi*x[1])',
        order=2,
        name='f')
    lambda_bar_values = [[0.]] * (YBLOCKS * XBLOCKS)
    lambda_hat_values = [[0.]] * (YBLOCKS * XBLOCKS)
    counter = 0
    for ix in range(YBLOCKS):
        for iy in range(XBLOCKS):
            lambda_bar_values[ix + XBLOCKS * iy] = [
                coefficients[counter].evaluate(mu_bar)
            ]
            lambda_hat_values[ix + XBLOCKS * iy] = [
                coefficients[counter].evaluate(mu_hat)
            ]
            counter += 1
    lambda_bar = make_checkerboard_function_1x1(
        grid_provider=grid,
        lower_left=lower_left,
        upper_right=upper_right,
        num_elements=[XBLOCKS, YBLOCKS],
        values=lambda_bar_values,
        name='lambda_bar')
    lambda_hat = make_checkerboard_function_1x1(
        grid_provider=grid,
        lower_left=lower_left,
        upper_right=upper_right,
        num_elements=[XBLOCKS, YBLOCKS],
        values=lambda_hat_values,
        name='lambda_hat')

    return {
        'grid':
        grid,
        'boundary_info':
        all_dirichlet_boundary_info,
        'inner_boundary_id':
        inner_boundary_id,
        'lambda': {
            'functions': diffusion_functions,
            'coefficients': coefficients
        },
        'lambda_bar':
        lambda_bar,
        'lambda_hat':
        lambda_hat,
        'kappa':
        kappa,
        'f':
        f,
        'parameter_type':
        parameter_type,
        'mu_bar':
        mu_bar,
        'mu_hat':
        mu_hat,
        'mu_min': (min(0.1, b, h) for b, h in zip(mu_bar, mu_hat)),
        'mu_max': (max(1, b, h) for b, h in zip(mu_bar, mu_hat)),
        'parameter_range':
        (min((0.1, ) + mu_bar + mu_hat), max((1, ) + mu_bar + mu_hat))
    }
def Fin_problem(parameter_dimension=2):
    assert parameter_dimension == 2 or parameter_dimension == 6, 'This dimension is not available'
    if parameter_dimension == 2:
        functions = [
            ExpressionFunction(
                '(2.5 <= x[..., 0]) * (x[..., 0] <= 3.5) * (0 <= x[..., 1]) * (x[..., 1] <=4)* 1.',
                dim_domain=2,
                shape_range=()),
            ExpressionFunction(
                '(0 <= x[..., 0]) * (x[..., 0] < 2.5) * (0.75 <= x[..., 1]) * (x[..., 1] <= 1) *1. \
                                        + (3.5 < x[..., 0]) * (x[..., 0] <= 6) * (0.75 <= x[..., 1]) * (x[..., 1] <= 1)* 1. \
                                        + (0 <= x[..., 0]) * (x[..., 0] < 2.5) * (1.75 <= x[..., 1]) * (x[..., 1] <= 2) * 1. \
                                        + (3.5 < x[..., 0]) * (x[..., 0] <= 6) * (1.75 <= x[..., 1]) * (x[..., 1] <= 2) * 1. \
                                        + (0 <= x[..., 0]) * (x[..., 0] < 2.5) * (2.75 <= x[..., 1]) * (x[..., 1] <= 3) *1. \
                                        + (3.5 < x[..., 0]) * (x[..., 0] <= 6) * (2.75 <= x[..., 1]) * (x[..., 1] <= 3) * 1. \
                                        + (0 <= x[..., 0]) * (x[..., 0] < 2.5) * (3.75 <= x[..., 1]) * (x[..., 1] <= 4) *1. \
                                        + (3.5 < x[..., 0]) * (x[..., 0] <= 6) * (3.75 <= x[..., 1]) * (x[..., 1] <= 4) * 1.',
                dim_domain=2,
                shape_range=())
        ]
        coefficients = [1, ProjectionParameterFunctional('k', (), ())]
        diffusion = LincombFunction(functions, coefficients)
        parameter_ranges = {
            'biot': np.array([0.01, 1]),
            'k': np.array([0.1, 10])
        }
        parameter_type = {'biot': (), 'k': ()}
    elif parameter_dimension == 6:
        functions = [
            ExpressionFunction(
                '(2.5 <= x[..., 0]) * (x[..., 0] <= 3.5) * (0 <= x[..., 1]) * (x[..., 1] <= 4) * 1.',
                dim_domain=2,
                shape_range=()),
            ExpressionFunction(
                '(0 <= x[..., 0]) * (x[..., 0] < 2.5) * (0.75 <= x[..., 1]) * (x[..., 1] <= 1) * \
                                1. + (3.5 < x[..., 0]) * (x[..., 0] <= 6) * (0.75 <= x[..., 1]) * (x[..., 1] <=1) * 1.',
                dim_domain=2,
                shape_range=()),
            ExpressionFunction(
                '(0 <= x[..., 0]) * (x[..., 0] < 2.5) * (1.75 <= x[..., 1]) * (x[..., 1] <= 2) * 1. \
                                + (3.5 < x[..., 0]) * (x[..., 0] <= 6) * (1.75 <= x[..., 1]) * (x[..., 1] <= 2) * 1.',
                dim_domain=2,
                shape_range=()),
            ExpressionFunction(
                '(0 <= x[..., 0]) * (x[..., 0] < 2.5) * (2.75 <= x[..., 1]) * (x[..., 1] <= 3) *1. \
                                + (3.5 < x[..., 0]) * (x[..., 0] <= 6) * (2.75 <= x[..., 1]) * (x[..., 1] <= 3) * 1.',
                dim_domain=2,
                shape_range=()),
            ExpressionFunction(
                '(0 <= x[..., 0]) * (x[..., 0] < 2.5) * (3.75 <= x[..., 1]) * (x[..., 1] <= 4) *1. \
                                + (3.5 < x[..., 0]) * (x[..., 0] <= 6) * (3.75 <= x[..., 1]) * (x[..., 1] <= 4) * 1.',
                dim_domain=2,
                shape_range=())
        ]
        coefficients = [
            ProjectionParameterFunctional('k0', (), ()),
            ProjectionParameterFunctional('k1', (), ()),
            ProjectionParameterFunctional('k2', (), ()),
            ProjectionParameterFunctional('k3', (), ()),
            ProjectionParameterFunctional('k4', (), ())
        ]
        diffusion = LincombFunction(functions, coefficients)
        parameter_ranges = np.array([[0.01, 0.1, 0.1, 0.1, 0.1, 0.1],
                                     [1, 10, 10, 10, 10, 10]])
        parameter_ranges = {
            'biot': np.array([0.01, 1]),
            'k0': np.array([0.1, 10]),
            'k1': np.array([0.1, 10]),
            'k2': np.array([0.1, 10]),
            'k3': np.array([0.1, 10]),
            'k4': np.array([0.1, 10])
        }
        parameter_type = {
            'biot': (),
            'k0': (),
            'k1': (),
            'k2': (),
            'k3': (),
            'k4': ()
        }

    domain = RectDomain([[0, 0], [6, 4]])
    parameter_space = CubicParameterSpace(parameter_type,
                                          ranges=parameter_ranges)
    problem = StationaryProblem(
        domain=domain,
        diffusion=diffusion,
        rhs=ConstantFunction(0, 2),
        neumann_data=ConstantFunction(-1, 2),
        robin_data=(LincombFunction(
            [ConstantFunction(1, 2)],
            [ProjectionParameterFunctional('biot', (),
                                           ())]), ConstantFunction(0, 2)),
        parameter_space=parameter_space)
    return problem
B = np.zeros((n, 1))
B[::2, 0] = 2
C = np.empty((1, n))
C[0, ::2] = c
C[0, 1::2] = d

# In[ ]:

A0 = NumpyMatrixOperator(A0)
Amu = NumpyMatrixOperator(Amu)
B = NumpyMatrixOperator(B)
C = NumpyMatrixOperator(C)

# In[ ]:

A = A0 + Amu * ProjectionParameterFunctional('mu', ())

# In[ ]:

lti = LTIModel(A, B, C)

# # Magnitude plot

# In[ ]:

mu_list_short = [1 / 50, 1 / 20, 1 / 10, 1 / 5, 1 / 2, 1]

# In[ ]:

w = np.logspace(0.5, 3.5, 200)