def test_HEP(setup_test, test_leaks):
    mesh = UnitIntervalMesh(20)
    space = FunctionSpace(mesh, "Lagrange", 1)
    test, trial = TestFunction(space), TrialFunction(space)

    M = assemble(inner(trial, test) * dx)

    def M_action(x):
        y = function_new(x)
        assemble(inner(x, test) * dx, tensor=function_vector(y))
        return function_get_values(y).conjugate()

    import slepc4py.SLEPc as SLEPc
    lam, V = eigendecompose(space,
                            M_action,
                            problem_type=SLEPc.EPS.ProblemType.HEP)

    assert (lam > 0.0).all()

    diff = Function(space)
    assert len(lam) == len(V)
    for lam_val, v in zip(lam, V):
        matrix_multiply(M, function_vector(v), tensor=function_vector(diff))
        function_axpy(diff, -lam_val, v)
        assert function_linf_norm(diff) < 1.0e-16
def test_NHEP(setup_test, test_leaks):
    mesh = UnitIntervalMesh(20)
    space = FunctionSpace(mesh, "Lagrange", 1)
    test, trial = TestFunction(space), TrialFunction(space)

    N = assemble(inner(trial.dx(0), test) * dx)

    def N_action(x):
        y = function_new(x)
        assemble(inner(x.dx(0), test) * dx, tensor=function_vector(y))
        return function_get_values(y).conjugate()

    lam, V = eigendecompose(space, N_action)

    assert abs(lam.real).max() < 1.0e-15

    diff = Function(space)
    if issubclass(PETSc.ScalarType, (complex, np.complexfloating)):
        assert len(lam) == len(V)
        for lam_val, v in zip(lam, V):
            matrix_multiply(N,
                            function_vector(v),
                            tensor=function_vector(diff))
            function_axpy(diff, -lam_val, v)
            assert function_linf_norm(diff) < 1.0e-14
    else:
        V_r, V_i = V
        assert len(lam) == len(V_r)
        assert len(lam) == len(V_i)
        for lam_val, v_r, v_i in zip(lam, V_r, V_i):
            matrix_multiply(N,
                            function_vector(v_r),
                            tensor=function_vector(diff))
            function_axpy(diff, -lam_val.real, v_r)
            function_axpy(diff, +lam_val.imag, v_i)
            assert function_linf_norm(diff) < 1.0e-15
            matrix_multiply(N,
                            function_vector(v_i),
                            tensor=function_vector(diff))
            function_axpy(diff, -lam_val.real, v_i)
            function_axpy(diff, -lam_val.imag, v_r)
            assert function_linf_norm(diff) < 1.0e-14
Esempio n. 3
0
def test_form_binding(setup_test, test_leaks, dim):
    from tlm_adjoint.firedrake.backend_code_generator_interface import \
        assemble as bind_assemble
    from tlm_adjoint.firedrake.equations import bind_form, unbind_form, \
        unbound_form

    mesh = UnitSquareMesh(30, 30)
    X = SpatialCoordinate(mesh)
    space = FunctionSpace(mesh, "Lagrange", 1)
    if dim > 1:
        space = FunctionSpace(
            mesh, MixedElement(*[space.ufl_element() for i in range(dim)]))
    test = TestFunction(space)

    def test_form(u, u_split, test):
        if dim == 1:
            # With FEniCS u.split() is empty for dim=1
            v = u
        else:
            v = as_vector(u_split)
        return inner(dot(u, v) * u, test) * dx

    def test_form_deps(u, u_split):
        if dim == 1:
            return [u]
        else:
            return [u] + list(u_split)

    u = Function(space)
    # With FEniCS u.split() creates new Coefficient objects
    u_split = u.split()
    form = test_form(u, u_split, test)
    for c in form.coefficients():
        assert not function_is_replacement(c)
    form = unbound_form(form, test_form_deps(u, u_split))
    for c in form.coefficients():
        assert function_is_replacement(c)
    del u, u_split

    for i in range(5):
        if dim == 1:
            u = project((i + 1) * sin(pi * X[0]) * cos(2 * pi * X[1]),
                        space,
                        solver_parameters=ls_parameters_cg)
        else:
            u = project((i + 1) * as_vector([
                sin((2 * j + 1) * pi * X[0]) * cos((2 * j + 2) * pi * X[1])
                for j in range(dim)
            ]),
                        space,
                        solver_parameters=ls_parameters_cg)
        u_split = u.split()
        assembled_form_ref = Function(space)
        assemble(test_form(u, u_split, test),
                 tensor=function_vector(assembled_form_ref))

        assert "_tlm_adjoint__bindings" not in form._cache
        bind_form(form, test_form_deps(u, u_split))
        assert "_tlm_adjoint__bindings" in form._cache
        assembled_form = Function(space)
        bind_assemble(form, tensor=function_vector(assembled_form))
        unbind_form(form)
        assert "_tlm_adjoint__bindings" not in form._cache

        error = function_copy(assembled_form_ref)
        function_axpy(error, -1.0, assembled_form)
        assert function_linf_norm(error) == 0.0
 def N_action(x):
     y = function_new(x)
     assemble(inner(x.dx(0), test) * dx, tensor=function_vector(y))
     return function_get_values(y).conjugate()
 def B_inv_action(x):
     y = function_new(x)
     assemble(eps * inner(ufl.conj(x), test) * dx,
              tensor=function_vector(y))
     return y
 def R_inv_action(x):
     y = function_new(x)
     assemble(inner(grad(ufl.conj(x)), grad(test)) * dx,
              tensor=function_vector(y))
     return y