Пример #1
0
    def adjoint_derivative_action(self, nl_deps, dep_index, adj_x):
        eq_deps = self.dependencies()
        if dep_index < 0 or dep_index >= len(eq_deps):
            raise EquationException("dep_index out of bounds")
        elif dep_index == 0:
            return adj_x

        dep = eq_deps[dep_index]
        dF = ufl.conj(derivative(self._rhs, dep, argument=ufl.conj(adj_x)))
        dF = ufl.algorithms.expand_derivatives(dF)
        dF = eliminate_zeros(dF)
        dF = self._nonlinear_replace(dF, nl_deps)
        dF_val = evaluate_expr(dF)
        F = function_new(dep)
        if isinstance(dF_val, (int, np.integer,
                               float, np.floating,
                               complex, np.complexfloating)):
            dtype = function_dtype(F)
            function_set_values(
                F, np.full(function_local_size(F), dtype(dF_val), dtype=dtype))
        elif function_is_scalar(F):
            dtype = function_dtype(F)
            dF_val_local = np.array([dF_val.sum()], dtype=dtype)
            dF_val = np.full((1,), np.NAN, dtype=dtype)
            comm = function_comm(F)
            comm.Allreduce(dF_val_local, dF_val, op=MPI.SUM)
            dF_val = dF_val[0]
            function_assign(F, dF_val)
        else:
            assert function_local_size(F) == len(dF_val)
            function_set_values(F, dF_val)
        return (-1.0, F)
Пример #2
0
def test_automatic_simplification(self):
    cell = triangle
    element = FiniteElement("Lagrange", cell, 1)

    v = TestFunction(element)
    u = TrialFunction(element)

    assert inner(u, v) == u * conj(v)
    assert dot(u, v) == u * v
    assert outer(u, v) == conj(u) * v
def test_basic_interior_facet_assembly():

    ghost_mode = dolfin.cpp.mesh.GhostMode.none
    if (dolfin.MPI.size(dolfin.MPI.comm_world) > 1):
        ghost_mode = dolfin.cpp.mesh.GhostMode.shared_facet

    mesh = dolfin.RectangleMesh(
        dolfin.MPI.comm_world,
        [numpy.array([0.0, 0.0, 0.0]),
         numpy.array([1.0, 1.0, 0.0])], [5, 5],
        cell_type=dolfin.cpp.mesh.CellType.Type.triangle,
        ghost_mode=ghost_mode)

    V = dolfin.function.FunctionSpace(mesh, ("DG", 1))
    u, v = dolfin.TrialFunction(V), dolfin.TestFunction(V)

    a = ufl.inner(ufl.avg(u), ufl.avg(v)) * ufl.dS

    A = dolfin.fem.assemble_matrix(a)
    A.assemble()
    assert isinstance(A, PETSc.Mat)

    L = ufl.conj(ufl.avg(v)) * ufl.dS

    b = dolfin.fem.assemble_vector(L)
    b.assemble()
    assert isinstance(b, PETSc.Vec)
Пример #4
0
    def adjoint_derivative_action(self, nl_deps, dep_index, adj_x):
        # Derived from EquationSolver.derivative_action (see dolfin-adjoint
        # reference below). Code first added 2017-12-07.
        # Re-written 2018-01-28
        # Updated to adjoint only form 2018-01-29

        eq_deps = self.dependencies()
        if dep_index < 0 or dep_index >= len(eq_deps):
            raise EquationException("dep_index out of bounds")
        elif dep_index == 0:
            return adj_x

        dep = eq_deps[dep_index]
        dF = derivative(self._rhs, dep)
        dF = ufl.algorithms.expand_derivatives(dF)
        dF = eliminate_zeros(dF)
        if dF.empty():
            return None

        dF = self._nonlinear_replace(dF, nl_deps)
        if self._rank == 0:
            dF = ufl.Form([integral.reconstruct(integrand=ufl.conj(integral.integrand()))  # noqa: E501
                           for integral in dF.integrals()])  # dF = adjoint(dF)
            dF = assemble(
                dF, form_compiler_parameters=self._form_compiler_parameters)
            return (-function_scalar_value(adj_x), dF)
        else:
            assert self._rank == 1
            dF = assemble(
                ufl.action(adjoint(dF), coefficient=adj_x),
                form_compiler_parameters=self._form_compiler_parameters)
            return (-1.0, dF)
Пример #5
0
def test_mass_bilinear_form_2d(mode, expected_result):
    cell = ufl.triangle
    element = ufl.FiniteElement("Lagrange", cell, 1)
    u, v = ufl.TrialFunction(element), ufl.TestFunction(element)
    a = ufl.inner(u, v) * ufl.dx
    L = ufl.conj(v) * ufl.dx
    forms = [a, L]
    compiled_forms, module = ffc.codegeneration.jit.compile_forms(
        forms, parameters={'scalar_type': mode})

    for f, compiled_f in zip(forms, compiled_forms):
        assert compiled_f.rank == len(f.arguments())

    form0 = compiled_forms[0][0].create_cell_integral(-1)
    form1 = compiled_forms[1][0].create_cell_integral(-1)

    c_type, np_type = float_to_type(mode)
    A = np.zeros((3, 3), dtype=np_type)
    w = np.array([], dtype=np_type)
    ffi = cffi.FFI()
    coords = np.array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0], dtype=np.float64)
    form0.tabulate_tensor(
        ffi.cast('{type} *'.format(type=c_type), A.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), w.ctypes.data),
        ffi.cast('double *', coords.ctypes.data), 0)

    b = np.zeros(3, dtype=np_type)
    form1.tabulate_tensor(
        ffi.cast('{type} *'.format(type=c_type), b.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), w.ctypes.data),
        ffi.cast('double *', coords.ctypes.data), 0)

    assert np.allclose(A, expected_result)
    assert np.allclose(b, 1.0 / 6.0)
Пример #6
0
def test_compute_form_adjoint(self):
    cell = triangle
    element = FiniteElement('Lagrange', cell, 1)

    u = TrialFunction(element)
    v = TestFunction(element)

    a = inner(grad(u), grad(v)) * dx

    assert compute_form_adjoint(a) == conj(inner(grad(v), grad(u))) * dx
Пример #7
0
def test_remove_complex_nodes(self):
    cell = triangle
    element = FiniteElement("Lagrange", cell, 1)

    u = TrialFunction(element)
    v = TestFunction(element)
    f = Coefficient(element)

    a = conj(v)
    b = real(u)
    c = imag(f)
    d = conj(real(v))*imag(conj(u))

    assert remove_complex_nodes(a) == v
    assert remove_complex_nodes(b) == u
    with pytest.raises(ufl.log.UFLException):
        remove_complex_nodes(c)
    with pytest.raises(ufl.log.UFLException):
        remove_complex_nodes(d)
Пример #8
0
def test_conditional(mode, compile_args):
    cell = ufl.triangle
    element = ufl.FiniteElement("Lagrange", cell, 1)
    u, v = ufl.TrialFunction(element), ufl.TestFunction(element)
    x = ufl.SpatialCoordinate(cell)
    condition = ufl.Or(ufl.ge(ufl.real(x[0] + x[1]), 0.1),
                       ufl.ge(ufl.real(x[1] + x[1]**2), 0.1))
    c1 = ufl.conditional(condition, 2.0, 1.0)
    a = c1 * ufl.inner(ufl.grad(u), ufl.grad(v)) * ufl.dx

    x1x2 = ufl.real(x[0] + ufl.as_ufl(2) * x[1])
    c2 = ufl.conditional(ufl.ge(x1x2, 0), 6.0, 0.0)
    b = c2 * ufl.conj(v) * ufl.dx

    forms = [a, b]

    compiled_forms, module = ffcx.codegeneration.jit.compile_forms(
        forms,
        parameters={'scalar_type': mode},
        cffi_extra_compile_args=compile_args)

    form0 = compiled_forms[0][0].create_cell_integral(-1)
    form1 = compiled_forms[1][0].create_cell_integral(-1)

    ffi = cffi.FFI()
    c_type, np_type = float_to_type(mode)

    A1 = np.zeros((3, 3), dtype=np_type)
    w1 = np.array([1.0, 1.0, 1.0], dtype=np_type)
    c = np.array([], dtype=np.float64)

    coords = np.array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0], dtype=np.float64)

    form0.tabulate_tensor(
        ffi.cast('{type} *'.format(type=c_type), A1.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), w1.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), c.ctypes.data),
        ffi.cast('double *', coords.ctypes.data), ffi.NULL, ffi.NULL, 0)

    expected_result = np.array([[2, -1, -1], [-1, 1, 0], [-1, 0, 1]],
                               dtype=np_type)
    assert np.allclose(A1, expected_result)

    A2 = np.zeros(3, dtype=np_type)
    w2 = np.array([1.0, 1.0, 1.0], dtype=np_type)
    coords = np.array([0.0, 0.0, 1.0, 0.0, 0.0, 1.0], dtype=np.float64)

    form1.tabulate_tensor(
        ffi.cast('{type} *'.format(type=c_type), A2.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), w2.ctypes.data),
        ffi.cast('{type} *'.format(type=c_type), c.ctypes.data),
        ffi.cast('double *', coords.ctypes.data), ffi.NULL, ffi.NULL, 0)

    expected_result = np.ones(3, dtype=np_type)
    assert np.allclose(A2, expected_result)
Пример #9
0
def test_complex_degree_handling(self):
    cell = triangle
    element = FiniteElement("Lagrange", cell, 3)

    v = TestFunction(element)

    a = conj(v)
    b = imag(v)
    c = real(v)

    assert estimate_total_polynomial_degree(a) == 3
    assert estimate_total_polynomial_degree(b) == 3
    assert estimate_total_polynomial_degree(c) == 3
Пример #10
0
def _real_mangle(form):
    """If the form contains arguments in the Real function space, replace these with literal 1 before passing to tsfc."""

    a = form.arguments()
    reals = [x.ufl_element().family() == "Real" for x in a]
    if not any(reals):
        return form
    replacements = {}
    for arg, r in zip(a, reals):
        if r:
            replacements[arg] = 1
    # If only the test space is Real, we need to turn the trial function into a test function.
    if reals == [True, False]:
        replacements[a[1]] = conj(TestFunction(a[1].function_space()))
    return ufl.replace(form, replacements)
Пример #11
0
def test_apply_algebra_lowering_complex(self):
    cell = triangle
    element = FiniteElement("Lagrange", cell, 1)

    v = TestFunction(element)
    u = TrialFunction(element)

    gv = grad(v)
    gu = grad(u)

    a = dot(gu, gv)
    b = inner(gv, gu)
    c = outer(gu, gv)

    lowered_a = apply_algebra_lowering(a)
    lowered_b = apply_algebra_lowering(b)
    lowered_c = apply_algebra_lowering(c)
    lowered_a_index = lowered_a.index()
    lowered_b_index = lowered_b.index()
    lowered_c_indices = lowered_c.indices()

    assert lowered_a == gu[lowered_a_index] * gv[lowered_a_index]
    assert lowered_b == gv[lowered_b_index] * conj(gu[lowered_b_index])
    assert lowered_c == as_tensor(conj(gu[lowered_c_indices[0]]) * gv[lowered_c_indices[1]], (lowered_c_indices[0],) + (lowered_c_indices[1],))
Пример #12
0
def test_basic_interior_facet_assembly():
    mesh = create_rectangle(MPI.COMM_WORLD, [np.array([0.0, 0.0]), np.array([1.0, 1.0])],
                            [5, 5], cell_type=CellType.triangle,
                            ghost_mode=GhostMode.shared_facet)
    V = FunctionSpace(mesh, ("DG", 1))
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)
    a = ufl.inner(ufl.avg(u), ufl.avg(v)) * ufl.dS
    a = form(a)
    A = assemble_matrix(a)
    A.assemble()
    assert isinstance(A, PETSc.Mat)

    L = ufl.conj(ufl.avg(v)) * ufl.dS
    L = form(L)
    b = assemble_vector(L)
    b.assemble()
    assert isinstance(b, PETSc.Vec)
Пример #13
0
def test_basic_interior_facet_assembly():
    mesh = dolfinx.RectangleMesh(
        MPI.COMM_WORLD,
        [numpy.array([0.0, 0.0, 0.0]),
         numpy.array([1.0, 1.0, 0.0])], [5, 5],
        cell_type=dolfinx.cpp.mesh.CellType.triangle,
        ghost_mode=dolfinx.cpp.mesh.GhostMode.shared_facet)

    V = fem.FunctionSpace(mesh, ("DG", 1))
    u, v = ufl.TrialFunction(V), ufl.TestFunction(V)

    a = ufl.inner(ufl.avg(u), ufl.avg(v)) * ufl.dS

    A = dolfinx.fem.assemble_matrix(a)
    A.assemble()
    assert isinstance(A, PETSc.Mat)

    L = ufl.conj(ufl.avg(v)) * ufl.dS
    b = dolfinx.fem.assemble_vector(L)
    b.assemble()
    assert isinstance(b, PETSc.Vec)
Пример #14
0
 def B_inv_action(x):
     y = function_new(x)
     assemble(eps * inner(ufl.conj(x), test) * dx,
              tensor=function_vector(y))
     return y
Пример #15
0
 def R_inv_action(x):
     y = function_new(x)
     assemble(inner(grad(ufl.conj(x)), grad(test)) * dx,
              tensor=function_vector(y))
     return y
Пример #16
0
    def forward(y, x_0=None):
        if x_0 is None:
            x_0 = project(y,
                          space_1,
                          name="x_0",
                          solver_parameters=ls_parameters_cg)
        x = Function(space_1, name="x")

        class TestSolver(ProjectionSolver):
            def __init__(self,
                         y,
                         x,
                         form_compiler_parameters=None,
                         solver_parameters=None):
                if form_compiler_parameters is None:
                    form_compiler_parameters = {}
                if solver_parameters is None:
                    solver_parameters = {}

                assert is_function(y)
                super().__init__(
                    inner(y, TestFunction(x.function_space())) * dx,
                    x,
                    form_compiler_parameters=form_compiler_parameters,
                    solver_parameters=solver_parameters,
                    cache_jacobian=False,
                    cache_rhs_assembly=False)

            def forward_solve(self, x, deps=None):
                rhs = self._rhs
                if deps is not None:
                    rhs = self._replace(rhs, deps)
                J = assemble(
                    self._J,
                    form_compiler_parameters=self._form_compiler_parameters)
                b = assemble(
                    rhs,
                    form_compiler_parameters=self._form_compiler_parameters)
                solver = linear_solver(J, self._linear_solver_parameters)
                solver.solve(x, b)
                assert solver.ksp.getIterationNumber() == 0

            def adjoint_jacobian_solve(self, adj_x, nl_deps, b):
                assert adj_x is not None
                J = assemble(
                    self._J,
                    form_compiler_parameters=self._form_compiler_parameters)
                solver = linear_solver(J, self._linear_solver_parameters)
                solver.solve(adj_x, b)
                # test_adj_ic defined in test scope below
                assert not test_adj_ic or solver.ksp.getIterationNumber() == 0
                return adj_x

            def tangent_linear(self, M, dM, tlm_map):
                x, y = self.dependencies()
                tau_y = get_tangent_linear(y, M, dM, tlm_map)
                if tau_y is None:
                    return NullSolver(tlm_map[x])
                else:
                    return TestSolver(
                        tau_y,
                        tlm_map[x],
                        form_compiler_parameters=self.
                        _form_compiler_parameters,  # noqa: E501
                        solver_parameters=self._solver_parameters)

        AssignmentSolver(x_0, x).solve()
        TestSolver(y,
                   x,
                   solver_parameters={
                       "ksp_type": "cg",
                       "pc_type": "sor",
                       "ksp_rtol": 1.0e-10,
                       "ksp_atol": 1.0e-16,
                       "ksp_initial_guess_nonzero": True
                   }).solve()

        J = Functional(name="J")
        J.assign((dot(x, x)**2) * dx)
        J_val = J.value()

        # test_adj_ic defined in test scope below
        if test_adj_ic:
            adj_x_0 = Function(space_1, name="adj_x_0", static=True)
            solve(inner(trial_1, test_1) * dx == 4 *
                  dot(ufl.conj(dot(x, x) * x), ufl.conj(test_1)) * dx,
                  adj_x_0,
                  solver_parameters=ls_parameters_cg,
                  annotate=False,
                  tlm=False)
            NullSolver(x).solve()
            J_term = space_new(J.space())
            InnerProductSolver(x, adj_x_0, J_term).solve()
            J.addto(J_term)
        else:
            adj_x_0 = None

        # Active equation which requires no adjoint initial condition, but
        # for which one will be supplied
        z = Function(space_1, name="z")
        ProjectionSolver(zero * x, z,
                         solver_parameters=ls_parameters_cg).solve()
        J.addto(dot(z, z) * dx)

        assert abs(J.value() - J_val) == 0.0

        return x, adj_x_0, z, J