예제 #1
0
def test_leaks():
    function_ids.clear()

    yield

    gc.collect()

    # Clear some internal storage that is allowed to keep references
    clear_caches()
    manager = _manager()
    manager._cp.clear(clear_refs=True)
    manager._cp_memory.clear()
    tlm_values = list(manager._tlm.values())  # noqa: F841
    manager._tlm.clear()
    tlm_eqs_values = [
        list(eq_tlm_eqs.values()) for eq_tlm_eqs in manager._tlm_eqs.values()
    ]  # noqa: E501,F841
    manager._tlm_eqs.clear()
    manager.drop_references()

    gc.collect()
    gc.collect()

    refs = 0
    for F in function_ids.values():
        F = F()
        if F is not None and F.name() != "Coordinates":
            info(f"{F.name():s} referenced")
            refs += 1
    if refs == 0:
        info("No references")

    function_ids.clear()
    assert refs == 0
예제 #2
0
def test_EmptySolver(setup_test, test_leaks):
    class EmptySolver(Equation):
        def __init__(self):
            super().__init__([], [], nl_deps=[], ic=False, adj_ic=False)

        def forward_solve(self, X, deps=None):
            pass

    mesh = UnitIntervalMesh(100)
    X = SpatialCoordinate(mesh)
    space = FunctionSpace(mesh, "Lagrange", 1)

    def forward(F):
        EmptySolver().solve()

        F_norm_sq = Constant(name="F_norm_sq")
        NormSqSolver(F, F_norm_sq).solve()

        J = Functional(name="J")
        NormSqSolver(F_norm_sq, J.fn()).solve()
        return J

    F = Function(space, name="F")
    interpolate_expression(F, sin(pi * X[0]) * exp(X[0]))

    start_manager()
    J = forward(F)
    stop_manager()

    manager = _manager()
    manager.finalize()
    manager.info()
    assert len(manager._blocks) == 1
    assert len(manager._blocks[0]) == 3
    assert len(manager._blocks[0][0].X()) == 0

    J_val = J.value()
    with F.dat.vec_ro as F_v:
        J_ref = F_v.norm(norm_type=PETSc.NormType.NORM_2)**4
    assert abs(J_val - J_ref) < 1.0e-11

    dJ = compute_gradient(J, F)

    min_order = taylor_test(forward, F, J_val=J_val, dJ=dJ)
    assert min_order > 2.00

    ddJ = Hessian(forward)
    min_order = taylor_test(forward, F, J_val=J_val, ddJ=ddJ)
    assert min_order > 3.00

    min_order = taylor_test_tlm(forward, F, tlm_order=1)
    assert min_order > 2.00

    min_order = taylor_test_tlm_adjoint(forward, F, adjoint_order=1)
    assert min_order > 2.00

    min_order = taylor_test_tlm_adjoint(forward, F, adjoint_order=2)
    assert min_order > 2.00
예제 #3
0
def tlm(kappa, zeta):
    clear_caches()

    manager = _manager().new()
    manager.add_tlm(kappa, zeta)
    manager.start()
    J = forward(kappa, manager=manager)
    manager.stop()
    return J.tlm(kappa, zeta, manager=manager).value()
예제 #4
0
def forward(kappa, manager=None, output_filename=None):
    clear_caches()

    Psi_n = Function(space, name="Psi_n")
    Psi_np1 = Function(space, name="Psi_np1")

    eq = EquationSolver(inner(test, trial / dt) * dx +
                        inner(grad(test), kappa * grad(trial)) * dx == inner(
                            test, Psi_n / dt) * dx,
                        Psi_np1,
                        bc,
                        solver_parameters={
                            "ksp_type": "cg",
                            "pc_type": "sor",
                            "ksp_rtol": 1.0e-14,
                            "ksp_atol": 1.0e-16
                        })
    cycle = AssignmentSolver(Psi_np1, Psi_n)

    if output_filename is not None:
        f = File(output_filename, "compressed")

    AssignmentSolver(Psi_0, Psi_n).solve(manager=manager)
    if output_filename is not None:
        f.write(Psi_n, time=0.0)
    for n in range(N):
        eq.solve(manager=manager)
        if n < N - 1:
            cycle.solve(manager=manager)
            (_manager() if manager is None else manager).new_block()
        else:
            Psi_n = Psi_np1
            Psi_n.rename("Psi_n", "a Function")
            del Psi_np1
        if output_filename is not None:
            f.write(Psi_n, time=(n + 1) * float(dt))

    J = Functional(name="J")
    J.assign(inner(Psi_n, Psi_n) * dx, manager=manager)

    return J
예제 #5
0
    def forward(m, forward_run=False):
        class NewtonIterationSolver(Equation):
            def __init__(self, m, x0, x):
                super().__init__(x,
                                 deps=[x, x0, m],
                                 nl_deps=[x0, m],
                                 ic=False,
                                 adj_ic=False)

            def forward_solve(self, x, deps=None):
                _, x0, m = self.dependencies() if deps is None else deps
                function_set_values(
                    x, 0.5 *
                    (function_get_values(x0)**2 + function_get_values(m)) /
                    function_get_values(x0))

            def adjoint_jacobian_solve(self, adj_x, nl_deps, b):
                return b

            def adjoint_derivative_action(self, nl_deps, dep_index, adj_x):
                if dep_index == 1:
                    x0, m = nl_deps
                    F = function_new(x0)
                    function_set_values(
                        F, 0.5 * function_get_values(adj_x) *
                        (function_get_values(m) /
                         (function_get_values(x0)**2) - 1.0))
                    return F
                elif dep_index == 2:
                    x0, m = nl_deps
                    F = function_new(x0)
                    function_set_values(
                        F, -0.5 * function_get_values(adj_x) /
                        function_get_values(x0))
                    return F
                else:
                    raise EquationException("Unexpected dep_index")

        x0 = Constant(1.0, name="x0")
        x1 = Constant(0.0, name="x1")

        eq0 = NewtonIterationSolver(m, x0, x1)
        eq1 = AssignmentSolver(x1, x0)

        fp_eq = FixedPointSolver(
            [eq0, eq1],
            solver_parameters={
                "absolute_tolerance": 0.0,
                "relative_tolerance": 1.0e-14,
                "report": False
            })
        fp_eq.solve()

        if forward_run:
            manager = _manager()

            assert len(manager._to_drop_references) == 0
            for eq in [fp_eq, eq0, eq1]:
                assert not eq._references_dropped
                for dep in eq.dependencies():
                    assert not isinstance(dep, Replacement)
            del eq

            fp_eq = WeakAlias(fp_eq)

            assert len(manager._to_drop_references) == 1
            for eq in [fp_eq, eq0, eq1]:
                assert not eq._references_dropped
                for dep in eq.dependencies():
                    assert not isinstance(dep, Replacement)
            del eq

            manager.drop_references()

            assert len(manager._to_drop_references) == 0
            assert fp_eq._references_dropped
            for dep in fp_eq.dependencies():
                assert isinstance(dep, Replacement)
            for eq in [eq0, eq1]:
                assert not eq._references_dropped
                for dep in eq.dependencies():
                    assert not isinstance(dep, Replacement)
            del eq

        eq0.solve()
        eq1.solve()

        if forward_run:
            assert len(manager._to_drop_references) == 0
            for eq in [eq0, eq1]:
                assert not eq._references_dropped
                for dep in eq.dependencies():
                    assert not isinstance(dep, Replacement)
            del eq

            eq0 = WeakAlias(eq0)
            eq1 = WeakAlias(eq1)

            assert len(manager._to_drop_references) == 2
            for eq in [eq0, eq1]:
                assert not eq._references_dropped
                for dep in eq.dependencies():
                    assert not isinstance(dep, Replacement)
            del eq

            manager.drop_references()

            assert len(manager._to_drop_references) == 0
            for eq in [eq0, eq1]:
                assert eq._references_dropped
                for dep in eq.dependencies():
                    assert isinstance(dep, Replacement)
            del eq

        J = Functional(name="J")
        J.assign(x1)
        return J
예제 #6
0
    def forward(m, forward_run=False):
        class IdentityMatrix(Matrix):
            def __init__(self):
                super().__init__(nl_deps=[], ic=False, adj_ic=False)

            def forward_action(self, nl_deps, x, b, method="assign"):
                if method == "assign":
                    function_assign(b, x)
                else:
                    raise EquationException(f"Unexpected method '{method:s}'")

            def forward_solve(self, x, nl_deps, b):
                function_assign(x, b)

            def adjoint_solve(self, adj_x, nl_deps, b):
                return b

            def tangent_linear_rhs(self, M, dM, tlm_map, x):
                return None

        x = Constant(0.0, name="x")

        M = IdentityMatrix()
        b = NormSqRHS(m, M=M)
        linear_eq = LinearEquation([b, b], x, A=M)
        linear_eq.solve()

        if forward_run:
            manager = _manager()

            assert len(manager._to_drop_references) == 0
            assert not linear_eq._references_dropped
            assert not b._references_dropped
            assert not M._references_dropped
            for dep in linear_eq.dependencies():
                assert not isinstance(dep, Replacement)
            for dep in b.dependencies():
                assert not isinstance(dep, Replacement)

            linear_eq = WeakAlias(linear_eq)

            assert len(manager._to_drop_references) == 1
            assert not linear_eq._references_dropped
            assert not b._references_dropped
            assert not M._references_dropped
            for dep in linear_eq.dependencies():
                assert not isinstance(dep, Replacement)
            for dep in b.dependencies():
                assert not isinstance(dep, Replacement)

            manager.drop_references()

            assert len(manager._to_drop_references) == 0
            assert linear_eq._references_dropped
            assert not b._references_dropped
            assert not M._references_dropped
            for dep in linear_eq.dependencies():
                assert isinstance(dep, Replacement)
            for dep in b.dependencies():
                assert not isinstance(dep, Replacement)

        y = Constant(0.0, name="y")
        LinearEquation(b, y, A=M).solve()

        z = Constant(0.0, name="z")
        AxpySolver(x, 1.0, y, z).solve()

        if forward_run:
            manager.drop_references()

            assert len(manager._to_drop_references) == 0
            assert not b._references_dropped
            assert not M._references_dropped
            for dep in b.dependencies():
                assert not isinstance(dep, Replacement)

            M = WeakAlias(M)
            b = WeakAlias(b)

            assert len(manager._to_drop_references) == 1
            assert not b._references_dropped
            assert not M._references_dropped
            for dep in b.dependencies():
                assert not isinstance(dep, Replacement)

            manager.drop_references()

            assert len(manager._to_drop_references) == 0
            assert b._references_dropped
            assert M._references_dropped
            for dep in b.dependencies():
                assert isinstance(dep, Replacement)

        J = Functional(name="J")
        NormSqSolver(z, J.fn()).solve()
        return J