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)
Example #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]')
Example #3
0
    def _build_dual_models(self):
        assert self.primal_rom is not None
        assert self.RBPrimal is not None
        RBbasis = self.RBPrimal
        rhs_operators = list(
            self.fom.output_functional_dict['d_u_linear_part'].operators)
        rhs_coefficients = list(
            self.fom.output_functional_dict['d_u_linear_part'].coefficients)

        bilinear_part = self.fom.output_functional_dict['d_u_bilinear_part']

        for i in range(len(RBbasis)):
            u = RBbasis[i]
            if isinstance(bilinear_part, LincombOperator):
                for j, op in enumerate(bilinear_part.operators):
                    rhs_operators.append(VectorOperator(op.apply(u)))
                    rhs_coefficients.append(
                        ExpressionParameterFunctional(
                            'basis_coefficients[{}]'.format(i),
                            {'basis_coefficients': len(RBbasis)}) *
                        bilinear_part.coefficients[j])
            else:
                rhs_operators.append(
                    VectorOperator(bilinear_part.apply(u, None)))
                rhs_coefficients.append(1. * ExpressionParameterFunctional(
                    'basis_coefficients[{}]'.format(i),
                    {'basis_coefficients': len(RBbasis)}))

        dual_rhs_operator = LincombOperator(rhs_operators, rhs_coefficients)

        dual_intermediate_fom = self.fom.primal_model.with_(
            rhs=dual_rhs_operator)

        if self.reductor_type == 'simple_coercive':
            print('building simple coercive dual reductor...')
            dual_reductor = SimpleCoerciveRBReductor(
                dual_intermediate_fom,
                RB=self.RBDual,
                product=self.opt_product,
                coercivity_estimator=self.coercivity_estimator)
        elif self.reductor_type == 'non_assembled':
            print('building non assembled dual reductor...')
            dual_reductor = NonAssembledCoerciveRBReductor(
                dual_intermediate_fom,
                RB=self.RBDual,
                product=self.opt_product,
                coercivity_estimator=self.coercivity_estimator)
        else:
            print('building coercive dual reductor...')
            dual_reductor = CoerciveRBReductor(
                dual_intermediate_fom,
                RB=self.RBDual,
                product=self.opt_product,
                coercivity_estimator=self.coercivity_estimator)

        dual_rom = dual_reductor.reduce()
        return dual_intermediate_fom, dual_rom, dual_reductor
def init_grid_and_problem(config):
    logger = getLogger('senegal_proceedings_problem.senegal_proceedings_problem')
    logger.info('initializing grid and problem ... ')

    lower_left = [-1, -1]
    upper_right = [1, 1]
    inner_boundary_id = 18446744073709551573
    grid = make_grid(lower_left=lower_left,
                     upper_right=upper_right,
                     num_elements=config['num_coarse_grid_elements'],
                     num_refinements=config['num_grid_refinements'],
                     num_partitions=config['num_grid_subdomains'],
                     num_oversampling_layers=config['num_grid_oversampling_layers'],
                     inner_boundary_segment_index=inner_boundary_id)

    all_dirichlet_boundary_info = make_boundary_info(grid, {'type': 'xt.grid.boundaryinfo.alldirichlet'})

    def make_values(background, foreground):
        checkerboard_values = [[background]]*36
        for ii in (7, 25):
            checkerboard_values[ii] = [foreground]
        return checkerboard_values

    diffusion_functions = [make_checkerboard_function_1x1(grid, lower_left, upper_right,
                                                          [6, 6], make_values(1., 0.),
                                                          name='lambda_0'),
                           make_checkerboard_function_1x1(grid, lower_left, upper_right,
                                                          [6, 6], make_values(0., 1.),
                                                          name='lambda_1')]

    parameter_type = {'diffusion': (2,)}
    coefficients = [ExpressionParameterFunctional('1.1 + sin(diffusion[0])*diffusion[1]', parameter_type),
                    ExpressionParameterFunctional('1.1 + sin(diffusion[1])', parameter_type)]

    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 = make_checkerboard_function_1x1(grid, lower_left, upper_right, [6, 6], make_values(1.1, 1.1), name='lambda_bar')
    lambda_hat = make_checkerboard_function_1x1(grid, lower_left, upper_right, [6, 6], make_values(1.1, 1.1), 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': (0, 0),
            'mu_hat': (0, 0),
            'mu_min': (0, 0),
            'mu_max': (np.pi, np.pi),
            'parameter_range': (0, np.pi)}
Example #5
0
def test_identity_lincomb():
    space = NumpyVectorSpace(10)
    identity = IdentityOperator(space)
    ones = space.ones()
    idid = (identity + identity)
    idid_ = ExpressionParameterFunctional('2', {}) * identity
    assert almost_equal(ones * 2, idid.apply(ones))
    assert almost_equal(ones * 2, idid.apply_adjoint(ones))
    assert almost_equal(ones * 0.5, idid.apply_inverse(ones))
    assert almost_equal(ones * 0.5, idid.apply_inverse_adjoint(ones))
    assert almost_equal(ones * 0.5, idid_.apply_inverse(ones))
    assert almost_equal(ones * 0.5, idid_.apply_inverse_adjoint(ones))
Example #6
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.]
Example #7
0
def test_min_theta_parameter_functional_fails_for_wrong_input():
    thetas = (ExpressionParameterFunctional('2*mu[0]', {'mu': 1}),
              ConstantParameterFunctional(1), -1)
    mu_bar = -3
    alpha_mu_bar = 10
    with pytest.raises(AssertionError):
        theta = MinThetaParameterFunctional(thetas, mu_bar, alpha_mu_bar)
Example #8
0
def test_base_max_theta_parameter_functional():
    thetas = (ExpressionParameterFunctional('2*mu[0]', {'mu': 1},
                                            derivative_expressions={
                                                'mu': ['2']
                                            }), ConstantParameterFunctional(1))

    # theta prime can for example be the derivatives of all theta
    thetas_prime = tuple([theta.d_mu('mu', 0) for theta in thetas])

    mu_bar = -3
    gamma_mu_bar = 10
    theta = BaseMaxThetaParameterFunctional(thetas_prime, thetas, mu_bar,
                                            gamma_mu_bar)
    thetas = [
        ConstantParameterFunctional(t)
        if not isinstance(t, ParameterFunctional) else t for t in thetas
    ]
    thetas_prime = [
        ConstantParameterFunctional(t)
        if not isinstance(t, ParameterFunctional) else t for t in thetas_prime
    ]
    mu = theta.parameters.parse(1)
    mu_bar = theta.parameters.parse(mu_bar)
    expected_value = gamma_mu_bar * np.abs(
        np.max(
            np.array([t(mu) for t in thetas_prime]) /
            np.array([np.abs(t(mu_bar)) for t in thetas])))
    actual_value = theta.evaluate(mu)
    assert expected_value == actual_value
Example #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 = [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]')
Example #10
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)
Example #11
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
Example #12
0
def test_lincomb_adjoint():
    op = LincombOperator([NumpyMatrixOperator(np.eye(10)), NumpyMatrixOperator(np.eye(10))],
                         [1+3j, ExpressionParameterFunctional('c[0] + 3', {'c': 1})])
    mu = op.parameters.parse(1j)
    U = op.range.random()
    V = op.apply_adjoint(U, mu=mu)
    VV = op.H.apply(U, mu=mu)
    assert np.all(almost_equal(V, VV))
    VVV = op.apply(U, mu=mu).conj()
    assert np.all(almost_equal(V, VVV))
Example #13
0
def test_ExpressionParameterFunctional_for_2d_array():
    dict_of_d_mus_2d = {'mu': [['10', '20'], ['1', '2']], 'nu': 'cos(nu)'}

    epf2d = ExpressionParameterFunctional(
        '10 * mu[(0,0)] + 20 * mu[(0,1)] \
                                          + 1 * mu[(1,0)] + 2 *  mu[(1,1)] \
                                          + sin(nu)', {
            'mu': (2, 2),
            'nu': ()
        }, 'functional_with_derivative', dict_of_d_mus_2d)

    derivative_to_11_mu_index = epf2d.d_mu('mu', (0, 0))
    derivative_to_12_mu_index = epf2d.d_mu('mu', (0, 1))
    derivative_to_21_mu_index = epf2d.d_mu('mu', (1, 0))
    derivative_to_22_mu_index = epf2d.d_mu('mu', (1, 1))
    derivative_to_nu_index = epf2d.d_mu('nu')

    mu = {'mu': (1, 2, 3, 4), 'nu': 0}

    der_mu_11 = derivative_to_11_mu_index.evaluate(mu)
    der_mu_12 = derivative_to_12_mu_index.evaluate(mu)
    der_mu_21 = derivative_to_21_mu_index.evaluate(mu)
    der_mu_22 = derivative_to_22_mu_index.evaluate(mu)
    der_nu = derivative_to_nu_index.evaluate(mu)

    assert epf2d.evaluate(mu) == 1 * 10 + 2 * 20 + 3 * 1 + 4 * 2 + 0
    assert der_mu_11 == 10
    assert der_mu_12 == 20
    assert der_mu_21 == 1
    assert der_mu_22 == 2
    assert der_nu == 1
Example #14
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
Example #15
0
    def __init__(self, domain=RectDomain(), rhs=None, parameter_range=(0., 100.),
                 dirichlet_data=None, neumann_data=None):

        self.parameter_range = parameter_range  # needed for with_
        parameter_space = CubicParameterSpace({'k': ()}, *parameter_range)
        super().__init__(
            diffusion_functions=[ConstantFunction(1., dim_domain=domain.dim)],
            diffusion_functionals=[1.],
            reaction_functions=[ConstantFunction(1., dim_domain=domain.dim)],
            reaction_functionals=[ExpressionParameterFunctional('-k**2', {'k': ()})],
            domain=domain,
            rhs=rhs or ConstantFunction(1., dim_domain=domain.dim),
            parameter_space=parameter_space,
            dirichlet_data=dirichlet_data,
            neumann_data=neumann_data)
def test_min_theta_parameter_functional():
    thetas = (ExpressionParameterFunctional('2*mu', {'mu': ()}),
              ConstantParameterFunctional(1), 1)
    mu_bar = 3
    alpha_mu_bar = 10
    theta = MinThetaParameterFunctional(thetas, mu_bar, alpha_mu_bar)
    thetas = [
        ConstantParameterFunctional(t)
        if not isinstance(t, ParameterFunctional) else t for t in thetas
    ]
    mu = 1
    expected_value = alpha_mu_bar * np.min(
        np.array([t(mu)
                  for t in thetas]) / np.array([t(mu_bar) for t in thetas]))
    actual_value = theta.evaluate(mu)
    assert expected_value == actual_value
Example #17
0
def helmholtz_problem(domain=RectDomain(), rhs=None, parameter_range=(0., 100.),
                      dirichlet_data=None, neumann_data=None):
    """Helmholtz equation problem.

    This problem is to solve the Helmholtz equation ::

      - ∆ u(x, k) - k^2 u(x, k) = f(x, k)

    on a given domain.

    Parameters
    ----------
    domain
        A |DomainDescription| of the domain the problem is posed on.
    rhs
        The |Function| f(x, μ).
    parameter_range
        A tuple `(k_min, k_max)` describing the interval in which k is allowd to vary.
    dirichlet_data
        |Function| providing the Dirichlet boundary values.
    neumann_data
        |Function| providing the Neumann boundary values.
    """

    return StationaryProblem(

        domain=domain,

        rhs=rhs or ConstantFunction(1., dim_domain=domain.dim),

        dirichlet_data=dirichlet_data,

        neumann_data=neumann_data,

        diffusion=ConstantFunction(1., dim_domain=domain.dim),

        reaction=LincombFunction([ConstantFunction(1., dim_domain=domain.dim)],
                                 [ExpressionParameterFunctional('-k**2', {'k': ()})]),

        parameter_space=CubicParameterSpace({'k': ()}, *parameter_range),

        name='helmholtz_problem'

    )
Example #18
0
def test_max_theta_parameter_functional():
    thetas = (ExpressionParameterFunctional('2*mu[0]', {'mu': 1}),
              ConstantParameterFunctional(1), -1)
    mu_bar = -3
    gamma_mu_bar = 10
    theta = MaxThetaParameterFunctional(thetas, mu_bar, gamma_mu_bar)
    thetas = [
        ConstantParameterFunctional(t)
        if not isinstance(t, ParameterFunctional) else t for t in thetas
    ]
    mu = theta.parameters.parse(1)
    mu_bar = theta.parameters.parse(mu_bar)
    expected_value = gamma_mu_bar * np.abs(
        np.max(
            np.array([t(mu)
                      for t in thetas]) / np.array([t(mu_bar)
                                                    for t in thetas])))
    actual_value = theta.evaluate(mu)
    assert expected_value == actual_value
Example #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'])

    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]')
Example #20
0
def test_ExpressionParameterFunctional():
    dict_of_d_mus = {'mu': ['100', '2'], 'nu': 'cos(nu)'}

    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}

    derivative_to_first_mu_index = epf.d_mu('mu', 0)
    derivative_to_second_mu_index = epf.d_mu('mu', 1)
    derivative_to_nu_index = epf.d_mu('nu', ())

    der_mu_1 = derivative_to_first_mu_index.evaluate(mu)
    der_mu_2 = derivative_to_second_mu_index.evaluate(mu)
    der_nu = derivative_to_nu_index.evaluate(mu)

    assert epf.evaluate(mu) == 100 * 10 + 2 * 2 + 0
    assert der_mu_1 == 100
    assert der_mu_2 == 2
    assert der_nu == 1
Example #21
0
     burgers_problem_2d(),
     burgers_problem_2d(torus=False, initial_data_type='bump', parameter_range=(1.3, 1.5))]


picklable_elliptic_problems = \
    [StationaryProblem(domain=RectDomain(), rhs=ConstantFunction(dim_domain=2, value=1.)),
     helmholtz_problem()]


non_picklable_elliptic_problems = \
    [StationaryProblem(domain=RectDomain(),
                     rhs=ConstantFunction(dim_domain=2, value=21.),
                     diffusion=LincombFunction(
                         [GenericFunction(dim_domain=2, mapping=lambda X, p=p: X[..., 0]**p)
                          for p in range(5)],
                         [ExpressionParameterFunctional('max(mu["exp"], {})'.format(m), parameter_type={'exp': ()})
                          for m in range(5)]
                     ))]

elliptic_problems = picklable_thermalblock_problems + non_picklable_elliptic_problems


@pytest.fixture(params=elliptic_problems + thermalblock_problems +
                burgers_problems)
def analytical_problem(request):
    return request.param


@pytest.fixture(params=picklable_elliptic_problems +
                picklable_thermalblock_problems + burgers_problems)
def picklable_analytical_problem(request):
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
Example #23
0
     burgers_problem_2d(),
     burgers_problem_2d(torus=False, initial_data_type='bump', parameter_range=(1.3, 1.5))]


picklable_elliptic_problems = \
    [StationaryProblem(domain=RectDomain(), rhs=ConstantFunction(dim_domain=2, value=1.)),
     helmholtz_problem()]


non_picklable_elliptic_problems = \
    [StationaryProblem(domain=RectDomain(),
                     rhs=ConstantFunction(dim_domain=2, value=21.),
                     diffusion=LincombFunction(
                         [GenericFunction(dim_domain=2, mapping=lambda X, p=p: X[..., 0]**p)
                          for p in range(5)],
                         [ExpressionParameterFunctional(f'max(mu["exp"], {m})', parameter_type={'exp': ()})
                          for m in range(5)]
                     ))]

elliptic_problems = picklable_thermalblock_problems + non_picklable_elliptic_problems


@pytest.fixture(params=elliptic_problems + thermalblock_problems +
                burgers_problems)
def analytical_problem(request):
    return request.param


@pytest.fixture(params=picklable_elliptic_problems +
                picklable_thermalblock_problems + burgers_problems)
def picklable_analytical_problem(request):
def EXC_problem(input_dict=None,
                summed_quantities=None,
                outside_temperature=10,
                q_inverse=1.,
                parameters_in_q=False,
                parameter_scaling=False,
                relative_path='',
                data_path='../../EXC_data',
                coefficient_expressions=None):
    '''
    initialize EXC problem
    '''
    # The pixels of the pictures are 200 x 100
    bounding_box = [[0, 0], [2, 1]]

    # converting Bitmaps
    # Windows = Fenster
    f1 = BitmapFunction('{}{}/f1.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    f2 = BitmapFunction('{}{}/f2.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    f3 = BitmapFunction('{}{}/f3.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    f4 = BitmapFunction('{}{}/f4.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    f5 = BitmapFunction('{}{}/f5.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    f6 = BitmapFunction('{}{}/f6.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    f7 = BitmapFunction('{}{}/f7.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    f8 = BitmapFunction('{}{}/f8.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    f9 = BitmapFunction('{}{}/f9.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    f10 = BitmapFunction('{}{}/f10.png'.format(relative_path, data_path),
                         range=[1., 0.],
                         bounding_box=bounding_box)
    f11 = BitmapFunction('{}{}/f11.png'.format(relative_path, data_path),
                         range=[1., 0.],
                         bounding_box=bounding_box)
    f12 = BitmapFunction('{}{}/f12.png'.format(relative_path, data_path),
                         range=[1., 0.],
                         bounding_box=bounding_box)

    # Walls = Waende
    w1 = BitmapFunction('{}{}/w1.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    w2 = BitmapFunction('{}{}/w2.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    w3 = BitmapFunction('{}{}/w3.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    w4 = BitmapFunction('{}{}/w4.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    w5 = BitmapFunction('{}{}/w5.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    w6 = BitmapFunction('{}{}/w6.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    w7 = BitmapFunction('{}{}/w7.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    w8 = BitmapFunction('{}{}/w8.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    sw = BitmapFunction('{}{}/sw.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    aw = BitmapFunction('{}{}/aw.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)

    # Doors = Tueren
    t1 = BitmapFunction('{}{}/t1.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    t2 = BitmapFunction('{}{}/t2.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    t3 = BitmapFunction('{}{}/t3.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    t4 = BitmapFunction('{}{}/t4.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    t5 = BitmapFunction('{}{}/t5.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    t6 = BitmapFunction('{}{}/t6.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    t7 = BitmapFunction('{}{}/t7.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)

    # outer Doors = Aussentueren
    at1 = BitmapFunction('{}{}/at1.png'.format(relative_path, data_path),
                         range=[1., 0.],
                         bounding_box=bounding_box)
    at2 = BitmapFunction('{}{}/at2.png'.format(relative_path, data_path),
                         range=[1., 0.],
                         bounding_box=bounding_box)
    it = BitmapFunction('{}{}/it.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)

    #heaters
    h1 = BitmapFunction('{}{}/h1.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    h2 = BitmapFunction('{}{}/h2.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    h3 = BitmapFunction('{}{}/h3.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    h4 = BitmapFunction('{}{}/h4.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    h5 = BitmapFunction('{}{}/h5.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    h6 = BitmapFunction('{}{}/h6.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    h7 = BitmapFunction('{}{}/h7.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    h8 = BitmapFunction('{}{}/h8.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    h9 = BitmapFunction('{}{}/h9.png'.format(relative_path, data_path),
                        range=[1., 0.],
                        bounding_box=bounding_box)
    h10 = BitmapFunction('{}{}/h10.png'.format(relative_path, data_path),
                         range=[1., 0.],
                         bounding_box=bounding_box)
    h11 = BitmapFunction('{}{}/h11.png'.format(relative_path, data_path),
                         range=[1., 0.],
                         bounding_box=bounding_box)
    h12 = BitmapFunction('{}{}/h12.png'.format(relative_path, data_path),
                         range=[1., 0.],
                         bounding_box=bounding_box)

    if input_dict is None:
        parametric_quantities = {
            'walls': [4, 6],
            'windows': [],
            'doors': [6],
            'heaters': [1]
        }
        active_quantities = {
            'removed_walls': [],
            'open_windows': [12],
            'open_doors': [2, 7],
            'active_heaters': [3, 8, 12]
        }
        input_dict = set_input_dict(parametric_quantities,
                                    active_quantities,
                                    parameters_in_q=parameters_in_q)

    if summed_quantities is None:
        summed_quantities = {
            'walls': [],
            'windows': [],
            'doors': [],
            'heaters': []
        }

    # background
    if parameters_in_q:
        background = BitmapFunction('{}{}/background.png'.format(
            relative_path, data_path),
                                    range=[0., 1.],
                                    bounding_box=bounding_box)
    else:
        background = BitmapFunction('{}{}/full_diffusion.png'.format(
            relative_path, data_path),
                                    range=[0., 1.],
                                    bounding_box=bounding_box)

    if parameters_in_q:
        diffusion_functions = [
            background, w1, w2, w3, w4, w5, w6, w7, w8, sw, t1, t2, t3, t4, t5,
            t6, t7, it
        ]
        for key in summed_quantities.keys():
            if len(summed_quantities[key]) > 0:
                for li in summed_quantities[key]:
                    idx = 0
                    if isinstance(li, str):
                        if li == 'a':
                            start_idx = 0
                            idx = 1
                            if key == 'walls':
                                li_iterate = list(np.arange(2, 11))
                            if key == 'doors':
                                li_iterate = list(np.arange(2, 11))
                    else:
                        if key == 'walls':
                            start_idx = 0
                            idx = li[0] + start_idx
                        if key == 'doors':
                            start_idx = 9
                            idx = li[0] + start_idx
                        li_iterate = li[1:]
                    if idx != 0:
                        new_lincomb_functions = [diffusion_functions[idx]]
                        new_lincomb_coefficients = [1.]
                        for l in li_iterate:
                            new_lincomb_functions.append(
                                diffusion_functions[l + start_idx])
                            new_lincomb_coefficients.append(1.)
                            diffusion_functions[l +
                                                start_idx] = ConstantFunction(
                                                    0, 2)
                        diffusion_functions[idx] = LincombFunction(
                            new_lincomb_functions, new_lincomb_coefficients)

    else:
        diffusion_functions = [
            background, w1, w2, w3, w4, w5, w6, w7, w8, sw, aw, f1, f2, f3, f4,
            f5, f6, f7, f8, f9, f10, f11, f12, t1, t2, t3, t4, t5, t6, t7, at1,
            at2, it
        ]
        for key in summed_quantities.keys():
            if len(summed_quantities[key]) > 0:
                for li in summed_quantities[key]:
                    idx = 0
                    if isinstance(li, str):
                        if li == 'a':
                            start_idx = 0
                            idx = 1
                            if key == 'walls':
                                li_iterate = list(np.arange(2, 11))
                            if key == 'windows':
                                li_iterate = list(np.arange(2, 13))
                            if key == 'doors':
                                li_iterate = list(np.arange(2, 11))
                    else:
                        if key == 'walls':
                            start_idx = 0
                            idx = li[0] + start_idx
                        if key == 'windows':
                            start_idx = 10
                            idx = li[0] + start_idx
                        if key == 'doors':
                            start_idx = 22
                            idx = li[0] + start_idx
                        li_iterate = li[1:]
                    if idx != 0:
                        new_lincomb_functions = [diffusion_functions[idx]]
                        new_lincomb_coefficients = [1.]
                        for l in li_iterate:
                            new_lincomb_functions.append(
                                diffusion_functions[l + start_idx])
                            new_lincomb_coefficients.append(1.)
                            diffusion_functions[l +
                                                start_idx] = ConstantFunction(
                                                    0, 2)
                        diffusion_functions[idx] = LincombFunction(
                            new_lincomb_functions, new_lincomb_coefficients)

    heat_functions = [h1, h2, h3, h4, h5, h6, h7, h8, h9, h10, h11, h12]

    if len(summed_quantities['heaters']) > 0:
        for li in summed_quantities['heaters']:
            if isinstance(li, str):
                if li == 'a':
                    start_idx = -1
                    idx = 1
                    li_iterate = list(np.arange(2, 13))
            else:
                start_idx = -1
                idx = li[0] + start_idx
                li_iterate = li[1:]
            new_lincomb_functions = [heat_functions[idx]]
            new_lincomb_coefficients = [1.]
            for l in li_iterate:
                new_lincomb_functions.append(heat_functions[l + start_idx])
                new_lincomb_coefficients.append(1.)
                heat_functions[l + start_idx] = ConstantFunction(0, 2)
            heat_functions[idx] = LincombFunction(new_lincomb_functions,
                                                  new_lincomb_coefficients)

    scale_quotient = {}
    coefficients = {}
    parameter_type = {}
    parameter_ranges = {}
    parametric_quantities = {}
    for (key, tu) in input_dict.items():
        key_ranges = []
        key_coefficients = []
        scale_quotients = []
        parametric_quantities[key] = 0
        for et in tu:
            if isinstance(et, list):
                # Then we have a parametrized value
                if parameter_scaling:
                    scale_quotients.append(et[1])
                    key_ranges.append([et[0] / (et[1]), 1])
                else:
                    scale_quotients.append(1.)
                    key_ranges.append([et[0], et[1]])
                key_coefficients.append(None)
                parametric_quantities[key] += 1
            elif isinstance(et, Number):
                # Then, we have a deterministic value
                key_coefficients.append(et)
            else:
                print(
                    'wrong input given for key {}... converting to 1.'.format(
                        key))
                key_coefficients.append(1.)
        coefficients[key] = key_coefficients
        if len(scale_quotients) > 0:
            scale_quotient[key] = scale_quotients[
                0]  #ranges are the same for the same key
        if key_ranges != []:
            parameter_type[key] = (len(key_ranges), )
            parameter_ranges[key] = tuple(key_ranges[0])

    for (key, list_) in coefficients.items():
        it = 0
        for (i, l) in enumerate(list_):
            if l is None:
                if coefficient_expressions is not None:
                    if key == 'heaters':
                        add_exp = '{}[{}]'
                        add_exp_derivative = '1*'
                        add_exp_second_derivative = '0*'
                    else:
                        add_exp = coefficient_expressions['function']
                        add_exp_derivative = coefficient_expressions[
                            'derivative']
                        add_exp_second_derivative = coefficient_expressions[
                            'second_derivative']

                else:
                    add_exp = '{}[{}]'
                    add_exp_derivative = '1*'
                if parametric_quantities[key] == 1:
                    if coefficient_expressions is None:
                        derivative_expressions = {
                            key: '1*{}'.format(scale_quotient[key])
                        }
                        second_derivative_expressions = {key: {key: '0'}}
                    else:
                        derivative_expressions = {
                            key:
                            add_exp_derivative.format(key, it) +
                            '1*{}'.format(scale_quotient[key])
                        }
                        second_derivative_expressions = {
                            key: {
                                key:
                                add_exp_second_derivative.format(
                                    key, it, key, it) +
                                '1*{}'.format(scale_quotient[key])
                            }
                        }
                else:
                    expressions = np.empty((parametric_quantities[key], ),
                                           dtype='<U60')
                    second_expressions = np.empty(
                        (parametric_quantities[key], ), dtype=dict)
                    second_expression = np.empty(
                        (parametric_quantities[key], ), dtype='<U60')
                    for k in range(parametric_quantities[key]):
                        expressions[k] = '0'
                        second_expression[k] = '0'
                    for k in range(parametric_quantities[key]):
                        second_expressions[k] = {key: second_expression.copy()}
                    second_derivative_expressions = {key: second_expressions}
                    if coefficient_expressions is None:
                        expressions[it] = '1*{}'.format(scale_quotient[key])
                    else:
                        expressions[it] = add_exp_derivative.format(
                            key, it) + '1*{}'.format(scale_quotient[key])
                        second_derivative_expressions[key][it][key][
                            it] = add_exp_second_derivative.format(
                                key, it, key, it) + '1*{}'.format(
                                    scale_quotient[key])
                    derivative_expressions = {key: expressions}
                coefficients[key][i] = ExpressionParameterFunctional(
                    add_exp.format(key, it, key, it) +
                    '*{}'.format(scale_quotient[key]),
                    {key: parameter_type[key]},
                    derivative_expressions=derivative_expressions,
                    second_derivative_expressions=second_derivative_expressions
                )
                it += 1

    if parameters_in_q:
        q_inverse_coefficients = [
            coefficients['walls'].pop(-1), coefficients['doors'].pop(7),
            coefficients['doors'].pop(7)
        ]
    diffusion_coefficients = []
    heat_coefficients = []
    for (key, val) in coefficients.items():
        if (key == 'heaters'):
            heat_coefficients.extend(val)
        elif (key == 'windows'):
            if parameters_in_q:
                q_inverse_coefficients.extend(val)
            else:
                diffusion_coefficients.extend(val)
        else:
            diffusion_coefficients.extend(val)

    lincomb_diffusion = LincombFunction(diffusion_functions,
                                        diffusion_coefficients)
    lincomb_heat = LincombFunction(heat_functions, heat_coefficients)

    # parameter space
    parameter_space = CubicParameterSpace(parameter_type,
                                          ranges=parameter_ranges)

    #Define problem
    domain = RectDomain(bounding_box,
                        left='robin',
                        right='robin',
                        top='robin',
                        bottom='robin')

    u_out = ConstantFunction(outside_temperature, 2)

    if parameters_in_q:
        # extracting parameters for boundary
        q_inverse_functions = [
            aw, at1, at2, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12
        ]
        if len(summed_quantities['windows']) > 0:
            for li in summed_quantities['heaters']:
                if isinstance(li, str):
                    if li == 'a':
                        print(
                            'warning: I have summed all outside quantities together'
                        )
                        idx = 0
                        li_iterate = list(np.arange(2, 16))
                else:
                    start_idx = 2
                    idx = li[0] + start_idx
                    li_iterate = li[1:]
                new_lincomb_functions = [q_inverse_functions[idx]]
                new_lincomb_coefficients = [1.]
                for l in li_iterate:
                    new_lincomb_functions += [
                        q_inverse_functions[l + start_idx]
                    ]
                    new_lincomb_coefficients += [1.]
                    q_inverse_functions[l + start_idx] = ConstantFunction(0, 2)
                q_inverse_functions[idx] = LincombFunction(
                    new_lincomb_functions, new_lincomb_coefficients)

        q_inverse_function = LincombFunction(q_inverse_functions,
                                             q_inverse_coefficients)
        robin_data = (q_inverse_function, u_out)  # ( 1/q, u_out )
    else:
        robin_data = (ConstantFunction(q_inverse, 2), u_out)  # ( 1/q, u_out)

    problem = StationaryProblem(domain=domain,
                                diffusion=lincomb_diffusion,
                                rhs=lincomb_heat,
                                robin_data=robin_data,
                                parameter_space=parameter_space)

    return problem, scale_quotient
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)
Example #26
0
def main(args):

    args = parse_arguments(args)

    pool = new_parallel_pool(ipython_num_engines=args['--ipython-engines'], ipython_profile=args['--ipython-profile'])

    if args['--fenics']:
        fom, fom_summary = discretize_fenics(args['XBLOCKS'], args['YBLOCKS'], args['--grid'], args['--order'])
    else:
        fom, fom_summary = discretize_pymor(args['XBLOCKS'], args['YBLOCKS'], args['--grid'], args['--list-vector-array'])

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

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

    print('RB generation ...')

    # define estimator for coercivity constant
    from pymor.parameters.functionals import ExpressionParameterFunctional
    coercivity_estimator = ExpressionParameterFunctional('min(diffusion)', fom.parameter_type)

    # inner product for computation of Riesz representatives
    product = fom.h1_0_semi_product if args['--product'] == 'h1' else None

    if args['--reductor'] == 'residual_basis':
        from pymor.reductors.coercive import CoerciveRBReductor
        reductor = CoerciveRBReductor(fom, product=product, coercivity_estimator=coercivity_estimator,
                                      check_orthonormality=False)
    elif args['--reductor'] == 'traditional':
        from pymor.reductors.coercive import SimpleCoerciveRBReductor
        reductor = SimpleCoerciveRBReductor(fom, product=product, coercivity_estimator=coercivity_estimator,
                                            check_orthonormality=False)
    else:
        assert False  # this should never happen

    if args['--alg'] == 'naive':
        rom, red_summary = reduce_naive(fom=fom, reductor=reductor, basis_size=args['RBSIZE'])
    elif args['--alg'] == 'greedy':
        parallel = not (args['--fenics'] and args['--greedy-without-estimator'])  # cannot pickle FEniCS model
        rom, red_summary = reduce_greedy(fom=fom, reductor=reductor, snapshots_per_block=args['SNAPSHOTS'],
                                         extension_alg_name=args['--extension-alg'],
                                         max_extensions=args['RBSIZE'],
                                         use_estimator=not args['--greedy-without-estimator'],
                                         pool=pool if parallel else None)
    elif args['--alg'] == 'adaptive_greedy':
        parallel = not (args['--fenics'] and args['--greedy-without-estimator'])  # cannot pickle FEniCS model
        rom, red_summary = reduce_adaptive_greedy(fom=fom, reductor=reductor, validation_mus=args['SNAPSHOTS'],
                                                  extension_alg_name=args['--extension-alg'],
                                                  max_extensions=args['RBSIZE'],
                                                  use_estimator=not args['--greedy-without-estimator'],
                                                  rho=args['--adaptive-greedy-rho'],
                                                  gamma=args['--adaptive-greedy-gamma'],
                                                  theta=args['--adaptive-greedy-theta'],
                                                  pool=pool if parallel else None)
    elif args['--alg'] == 'pod':
        rom, red_summary = reduce_pod(fom=fom, reductor=reductor, snapshots_per_block=args['SNAPSHOTS'],
                                      basis_size=args['RBSIZE'])
    else:
        assert False  # this should never happen

    if args['--pickle']:
        print(f"\nWriting reduced model to file {args['--pickle']}_reduced ...")
        with open(args['--pickle'] + '_reduced', 'wb') as f:
            dump(rom, f)
        if not args['--fenics']:  # FEniCS data structures do not support serialization
            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, fom.l2_norm),
                                       condition=True,
                                       test_mus=args['--test'],
                                       basis_sizes=0 if args['--plot-error-sequence'] else 1,
                                       plot=args['--plot-error-sequence'],
                                       pool=None if args['--fenics'] else pool,  # cannot pickle FEniCS model
                                       random_seed=999)

    print('\n*** RESULTS ***\n')
    print(fom_summary)
    print(red_summary)
    print(results['summary'])
    sys.stdout.flush()

    if args['--plot-error-sequence']:
        import matplotlib.pyplot
        matplotlib.pyplot.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)

    return results
def set_input_dict(parametric_quantities,
                   active_quantities,
                   coefficient_expressions=None,
                   summed_quantities=None,
                   parameters_in_q=False,
                   ac=None,
                   owc=None,
                   iwc=None,
                   idc=None,
                   wc=None,
                   ht=None,
                   owc_c=None,
                   iwc_c=None,
                   idc_c=None,
                   wc_c=None,
                   ht_c=None):
    # ac means air conductivity
    # owc means outside wall and outside door conductivity
    # iwc means inside wall conductivity
    # idc means inside door conductivity
    # wc means window conductivity
    # ht means heat temperature

    # *_c stands for the constant value for the non parameterized case !
    # the need to be evaluated by the coefficient_expressions as well

    if coefficient_expressions is not None:
        assert 'function' in coefficient_expressions, 'You might have assigned summed_quantities to coefficient_expressions. Check the input arguments of this function!!!'
        add_exp = coefficient_expressions['function']
    else:
        print(
            'Warning: Check whether you have not used coefficient_expressions for the later experiment'
        )
        add_exp = '{}[{}]'

    epf = ExpressionParameterFunctional(add_exp.format('anything', ()),
                                        {'anything': ()})

    # Attention ! Parametric case has priority over active case !

    # please provide the owc,iwc,idc,wc and ht in a list or use default
    def_ac, def_owc, def_iwc, def_idc, def_wc, def_ht = set_default_conductivities(
        parameters_in_q)

    if ac is None:
        ac = def_ac
    if owc is None:
        owc = def_owc
    if iwc is None:
        iwc = def_iwc
    if idc is None:
        idc = def_idc
    if wc is None:
        wc = def_wc
    if ht is None:
        ht = def_ht

    if owc_c is None:
        owc_c = owc[0]
    if iwc_c is None:
        iwc_c = iwc[0]
    if idc_c is None:
        idc_c = idc[0]
    if wc_c is None:
        wc_c = wc[0]
    if ht_c is None:
        ht_c = ht[1]

    # apply epf to _c
    owc_c = epf(owc_c)
    iwc_c = epf(iwc_c)
    idc_c = epf(idc_c)
    wc_c = epf(wc_c)

    assert (isinstance(owc, list))
    assert (isinstance(iwc, list))
    assert (isinstance(idc, list))
    assert (isinstance(wc, list))
    assert (isinstance(ht, list))

    walls_tuple = ()
    windows_tuple = ()
    doors_tuple = ()
    heaters_tuple = ()

    walls_params = parametric_quantities['walls']
    windows_params = parametric_quantities['windows']
    doors_params = parametric_quantities['doors']
    heaters_params = parametric_quantities['heaters']

    active_quantities['walls'] = active_quantities['removed_walls']
    active_quantities['windows'] = active_quantities['open_windows']
    active_quantities['doors'] = active_quantities['open_doors']
    active_quantities['heaters'] = active_quantities['active_heaters']

    removed_walls = active_quantities['walls']  # removed walls
    open_windows = active_quantities['windows']  # open windows
    open_doors = active_quantities['doors']  # open_doors
    active_heaters = active_quantities['heaters']  # active heater

    if summed_quantities is not None:
        for key in ['walls', 'windows', 'doors', 'heaters']:
            if summed_quantities[key] == 'all':
                assert len(parametric_quantities[key]
                           ) == 1, 'only parameterize one quantity'
                assert len(active_quantities[key]
                           ) == 0, 'do not sum active quantities'
                continue
            for summand in summed_quantities[key]:
                assert isinstance(summand, list)
                assert len(summand) > 1, 'you must at least sum two quantities'
                for i in range(1, len(summand)):
                    assert summand[i] not in parametric_quantities[
                        key], 'do not sum parametric quantities'
                    assert summand[i] not in active_quantities[
                        key], 'do not sum active quantities'

    for i in range(1, 11):
        if i in walls_params:
            if i == 10:  # outside wall
                assert isinstance(owc, list) and len(
                    owc
                ) == 2, 'WRONG INPUT: owc has to be a list of the parametric range'
                walls_tuple += (owc, )
            else:
                assert isinstance(iwc, list) and len(
                    iwc
                ) == 2, 'WRONG INPUT: iwc has to be a list of the parametric range'
                walls_tuple += (iwc, )
        elif i in removed_walls:
            walls_tuple += (ac, )
        else:
            if i == 10:
                walls_tuple += (owc_c, )
            else:
                walls_tuple += (iwc_c, )
        if i in doors_params:
            assert isinstance(idc, list) and len(
                idc
            ) == 2, 'WRONG INPUT: idc has to be a list of the parametric range'
            doors_tuple += (idc, )
        elif i in open_doors:
            doors_tuple += (ac, )
        else:
            if i in [8, 9]:
                doors_tuple += (owc_c, )
            else:
                doors_tuple += (idc_c, )

    for i in range(1, 13):
        if i in windows_params:
            assert isinstance(wc, list) and len(
                wc
            ) == 2, 'WRONG INPUT: wc has to be a list of the parametric range'
            windows_tuple += (wc, )
        elif i in open_windows:
            assert isinstance(wc, list) and len(
                wc
            ) == 2, 'WRONG INPUT: wc has to be a list where the first entry corresponds to open window'
            windows_tuple += (ac, )
        else:
            windows_tuple += (wc_c, )
        if i in heaters_params:
            assert isinstance(ht, list) and len(
                ht
            ) == 2, 'WRONG INPUT: ht has to be a list of the parametric range'
            heaters_tuple += (ht, )
        elif i in active_heaters:
            heaters_tuple += (ht_c, )
        else:
            heaters_tuple += (0, )

    assert (len(walls_tuple) == 10)
    assert (len(windows_tuple) == 12)
    assert (len(doors_tuple) == 10)
    assert (len(heaters_tuple) == 12)

    input_dict = {
        'air': (ac, ),
        'walls': walls_tuple,  # must be 10 
        'windows': windows_tuple,  # must be 12
        'doors': doors_tuple,  # must be 10
        'heaters': heaters_tuple
    }  # must be 12

    return input_dict
Example #28
0
     burgers_problem_2d(),
     burgers_problem_2d(torus=False, initial_data_type='bump', parameter_range=(1.3, 1.5))]


picklable_elliptic_problems = \
    [StationaryProblem(domain=RectDomain(), rhs=ConstantFunction(dim_domain=2, value=1.)),
     helmholtz_problem()]


non_picklable_elliptic_problems = \
    [StationaryProblem(domain=RectDomain(),
                     rhs=ConstantFunction(dim_domain=2, value=21.),
                     diffusion=LincombFunction(
                         [GenericFunction(dim_domain=2, mapping=lambda X, p=p: X[..., 0]**p)
                          for p in range(5)],
                         [ExpressionParameterFunctional(f'max(mu["exp"], {m})', parameters={'exp': 1})
                          for m in range(5)]
                     ))]


elliptic_problems = picklable_thermalblock_problems + non_picklable_elliptic_problems


@pytest.fixture(params=elliptic_problems + thermalblock_problems + burgers_problems)
def analytical_problem(request):
    return request.param


@pytest.fixture(params=picklable_elliptic_problems + picklable_thermalblock_problems + burgers_problems)
def picklable_analytical_problem(request):
    return request.param
Example #29
0
def discretize_instationary_from_disk(parameter_file,
                                      T=None,
                                      steps=None,
                                      u0=None,
                                      time_stepper=None):
    """Load a linear affinely decomposed |InstationaryModel| from file.

    Similarly to :func:`discretize_stationary_from_disk`, the model is
    specified via an `ini.`-file of the following form ::

        [system-matrices]
        L_1.mat: l_1(μ_1,...,μ_n)
        L_2.mat: l_2(μ_1,...,μ_n)
        ...

        [rhs-vectors]
        F_1.mat: f_1(μ_1,...,μ_n)
        F_2.mat: f_2(μ_1,...,μ_n)
        ...

        [mass-matrix]
        D.mat

        [initial-solution]
        u0: u0.mat

        [parameter]
        μ_1: a_1,b_1
        ...
        μ_n: a_n,b_n

        [products]
        Prod1: P_1.mat
        Prod2: P_2.mat
        ...

        [time]
        T: final time
        steps: number of time steps


    Parameters
    ----------
    parameter_file
        Path to the '.ini' parameter file.
    T
        End-time of desired solution. If `None`, the value specified in the
        parameter file is used.
    steps
        Number of time steps to. If `None`, the value specified in the
        parameter file is used.
    u0
        Initial solution. If `None` the initial solution is obtained
        from parameter file.
    time_stepper
        The desired :class:`time stepper <pymor.algorithms.timestepping.TimeStepper>`
        to use. If `None`, implicit Euler time stepping is used.

    Returns
    -------
    m
        The |InstationaryModel| that has been generated.
    """
    assert ".ini" == parameter_file[-4:], "Given file is not an .ini file"
    assert os.path.isfile(parameter_file)
    base_path = os.path.dirname(parameter_file)

    # Get input from parameter file
    config = configparser.ConfigParser()
    config.optionxform = str
    config.read(parameter_file)

    # Assert that all needed entries given
    assert 'system-matrices' in config.sections()
    assert 'mass-matrix' in config.sections()
    assert 'rhs-vectors' in config.sections()
    assert 'parameter' in config.sections()

    system_mat = config.items('system-matrices')
    mass_mat = config.items('mass-matrix')
    rhs_vec = config.items('rhs-vectors')
    parameter = config.items('parameter')

    # Dict of parameters types and ranges
    parameter_type = {}
    parameter_range = {}

    # get parameters
    for i in range(len(parameter)):
        parameter_name = parameter[i][0]
        parameter_list = tuple(
            float(j) for j in parameter[i][1].replace(" ", "").split(','))
        parameter_range[parameter_name] = parameter_list
        # Assume scalar parameter dependence
        parameter_type[parameter_name] = 0

    # Create parameter space
    parameter_space = CubicParameterSpace(parameter_type=parameter_type,
                                          ranges=parameter_range)

    # Assemble operators
    system_operators, system_functionals = [], []

    # get parameter functionals and system matrices
    for i in range(len(system_mat)):
        path = os.path.join(base_path, system_mat[i][0])
        expr = system_mat[i][1]
        parameter_functional = ExpressionParameterFunctional(
            expr, parameter_type=parameter_type)
        system_operators.append(
            NumpyMatrixOperator.from_file(path,
                                          source_id='STATE',
                                          range_id='STATE'))
        system_functionals.append(parameter_functional)

    system_lincombOperator = LincombOperator(system_operators,
                                             coefficients=system_functionals)

    # get rhs vectors
    rhs_operators, rhs_functionals = [], []

    for i in range(len(rhs_vec)):
        path = os.path.join(base_path, rhs_vec[i][0])
        expr = rhs_vec[i][1]
        parameter_functional = ExpressionParameterFunctional(
            expr, parameter_type=parameter_type)
        op = NumpyMatrixOperator.from_file(path, range_id='STATE')
        assert isinstance(op.matrix, np.ndarray)
        op = op.with_(matrix=op.matrix.reshape((-1, 1)))
        rhs_operators.append(op)
        rhs_functionals.append(parameter_functional)

    rhs_lincombOperator = LincombOperator(rhs_operators,
                                          coefficients=rhs_functionals)

    # get mass matrix
    path = os.path.join(base_path, mass_mat[0][1])
    mass_operator = NumpyMatrixOperator.from_file(path,
                                                  source_id='STATE',
                                                  range_id='STATE')

    # Obtain initial solution if not given
    if u0 is None:
        u_0 = config.items('initial-solution')
        path = os.path.join(base_path, u_0[0][1])
        op = NumpyMatrixOperator.from_file(path, range_id='STATE')
        assert isinstance(op.matrix, np.ndarray)
        u0 = op.with_(matrix=op.matrix.reshape((-1, 1)))

    # get products if given
    if 'products' in config.sections():
        product = config.items('products')
        products = {}
        for i in range(len(product)):
            product_name = product[i][0]
            product_path = os.path.join(base_path, product[i][1])
            products[product_name] = NumpyMatrixOperator.from_file(
                product_path, source_id='STATE', range_id='STATE')
    else:
        products = None

    # Further specifications
    if 'time' in config.sections():
        if T is None:
            assert 'T' in config.options('time')
            T = float(config.get('time', 'T'))
        if steps is None:
            assert 'steps' in config.options('time')
            steps = int(config.get('time', 'steps'))

    # Use implicit euler time stepper if no time-stepper given
    if time_stepper is None:
        time_stepper = ImplicitEulerTimeStepper(steps)
    else:
        time_stepper = time_stepper(steps)

    # Create and return instationary model
    return InstationaryModel(operator=system_lincombOperator,
                             rhs=rhs_lincombOperator,
                             parameter_space=parameter_space,
                             initial_data=u0,
                             T=T,
                             time_stepper=time_stepper,
                             mass=mass_operator,
                             products=products)
Example #30
0
def discretize_stationary_from_disk(parameter_file):
    """Load a linear affinely decomposed |StationaryModel| from file.

    The model is defined via an `.ini`-style file as follows ::

        [system-matrices]
        L_1.mat: l_1(μ_1,...,μ_n)
        L_2.mat: l_2(μ_1,...,μ_n)
        ...

        [rhs-vectors]
        F_1.mat: f_1(μ_1,...,μ_n)
        F_2.mat: f_2(μ_1,...,μ_n)
        ...

        [parameter]
        μ_1: a_1,b_1
        ...
        μ_n: a_n,b_n

        [products]
        Prod1: P_1.mat
        Prod2: P_2.mat
        ...

    Here, `L_1.mat`, `L_2.mat`, ..., `F_1.mat`, `F_2.mat`, ... are files
    containing matrices `L_1`, `L_2`, ... and vectors `F_1.mat`, `F_2.mat`, ...
    which correspond to the affine components of the operator and right-hand
    side.  The respective coefficient functionals, are given via the
    string expressions `l_1(...)`, `l_2(...)`, ..., `f_1(...)` in the
    (scalar-valued) |Parameter| components `w_1`, ..., `w_n`. The allowed lower
    and upper bounds `a_i, b_i` for the component `μ_i` are specified in the
    `[parameters]` section. The resulting operator and right-hand side are
    then of the form ::

        L(μ) = l_1(μ)*L_1 + l_2(μ)*L_2+ ...
        F(μ) = f_1(μ)*F_1 + f_2(μ)*L_2+ ...

    In the `[products]` section, an optional list of inner products `Prod1`, `Prod2`, ..
    with corresponding matrices `P_1.mat`, `P_2.mat` can be specified.

    Example::

        [system-matrices]
        matrix1.mat: 1.
        matrix2.mat: 1. - theta**2

        [rhs-vectors]
        rhs.mat: 1.

        [parameter]
        theta: 0, 0.5

        [products]
        h1: h1.mat
        l2: mass.mat


    Parameters
    ----------
    parameter_file
        Path to the parameter file.

    Returns
    -------
    m
        The |StationaryModel| that has been generated.
    """
    assert ".ini" == parameter_file[
        -4:], f'Given file is not an .ini file: {parameter_file}'
    assert os.path.isfile(parameter_file)
    base_path = os.path.dirname(parameter_file)

    # Get input from parameter file
    config = configparser.ConfigParser()
    config.optionxform = str
    config.read(parameter_file)

    # Assert that all needed entries given
    assert 'system-matrices' in config.sections()
    assert 'rhs-vectors' in config.sections()
    assert 'parameter' in config.sections()

    system_mat = config.items('system-matrices')
    rhs_vec = config.items('rhs-vectors')
    parameter = config.items('parameter')

    # Dict of parameters types and ranges
    parameter_type = {}
    parameter_range = {}

    # get parameters
    for i in range(len(parameter)):
        parameter_name = parameter[i][0]
        parameter_list = tuple(
            float(j) for j in parameter[i][1].replace(" ", "").split(','))
        parameter_range[parameter_name] = parameter_list
        # Assume scalar parameter dependence
        parameter_type[parameter_name] = 0

    # Create parameter space
    parameter_space = CubicParameterSpace(parameter_type=parameter_type,
                                          ranges=parameter_range)

    # Assemble operators
    system_operators, system_functionals = [], []

    # get parameter functionals and system matrices
    for i in range(len(system_mat)):
        path = os.path.join(base_path, system_mat[i][0])
        expr = system_mat[i][1]
        parameter_functional = ExpressionParameterFunctional(
            expr, parameter_type=parameter_type)
        system_operators.append(
            NumpyMatrixOperator.from_file(path,
                                          source_id='STATE',
                                          range_id='STATE'))
        system_functionals.append(parameter_functional)

    system_lincombOperator = LincombOperator(system_operators,
                                             coefficients=system_functionals)

    # get rhs vectors
    rhs_operators, rhs_functionals = [], []

    for i in range(len(rhs_vec)):
        path = os.path.join(base_path, rhs_vec[i][0])
        expr = rhs_vec[i][1]
        parameter_functional = ExpressionParameterFunctional(
            expr, parameter_type=parameter_type)
        op = NumpyMatrixOperator.from_file(path, range_id='STATE')
        assert isinstance(op.matrix, np.ndarray)
        op = op.with_(matrix=op.matrix.reshape((-1, 1)))
        rhs_operators.append(op)
        rhs_functionals.append(parameter_functional)

    rhs_lincombOperator = LincombOperator(rhs_operators,
                                          coefficients=rhs_functionals)

    # get products if given
    if 'products' in config.sections():
        product = config.items('products')
        products = {}
        for i in range(len(product)):
            product_name = product[i][0]
            product_path = os.path.join(base_path, product[i][1])
            products[product_name] = NumpyMatrixOperator.from_file(
                product_path, source_id='STATE', range_id='STATE')
    else:
        products = None

    # Create and return stationary model
    return StationaryModel(operator=system_lincombOperator,
                           rhs=rhs_lincombOperator,
                           parameter_space=parameter_space,
                           products=products)