Exemple #1
0
def test_linear_pde():
    """Test Newton solver for a linear PDE"""
    # Create mesh and function space
    mesh = dolfinx.generation.UnitSquareMesh(MPI.COMM_WORLD, 12, 12)
    V = function.FunctionSpace(mesh, ("Lagrange", 1))
    u = function.Function(V)
    v = TestFunction(V)
    F = inner(10.0, v) * dx - inner(grad(u), grad(v)) * dx

    def boundary(x):
        """Define Dirichlet boundary (x = 0 or x = 1)."""
        return np.logical_or(x[0] < 1.0e-8, x[0] > 1.0 - 1.0e-8)

    u_bc = function.Function(V)
    u_bc.vector.set(1.0)
    u_bc.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                            mode=PETSc.ScatterMode.FORWARD)
    bc = fem.DirichletBC(u_bc, fem.locate_dofs_geometrical(V, boundary))

    # Create nonlinear problem
    problem = NonlinearPDEProblem(F, u, bc)

    # Create Newton solver and solve
    solver = dolfinx.cpp.nls.NewtonSolver(MPI.COMM_WORLD)
    n, converged = solver.solve(problem, u.vector)
    assert converged
    assert n == 1

    # Increment boundary condition and solve again
    u_bc.vector.set(2.0)
    u_bc.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                            mode=PETSc.ScatterMode.FORWARD)
    n, converged = solver.solve(problem, u.vector)
    assert converged
    assert n == 1
Exemple #2
0
def test_nonlinear_pde_snes():
    """Test Newton solver for a simple nonlinear PDE"""
    # Create mesh and function space
    mesh = dolfinx.generation.UnitSquareMesh(MPI.COMM_WORLD, 12, 15)
    V = function.FunctionSpace(mesh, ("Lagrange", 1))
    u = function.Function(V)
    v = TestFunction(V)
    F = inner(5.0, v) * dx - ufl.sqrt(u * u) * inner(
        grad(u), grad(v)) * dx - inner(u, v) * dx

    def boundary(x):
        """Define Dirichlet boundary (x = 0 or x = 1)."""
        return np.logical_or(x[0] < 1.0e-8, x[0] > 1.0 - 1.0e-8)

    u_bc = function.Function(V)
    u_bc.vector.set(1.0)
    u_bc.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                            mode=PETSc.ScatterMode.FORWARD)
    bc = fem.DirichletBC(u_bc, fem.locate_dofs_geometrical(V, boundary))

    # Create nonlinear problem
    problem = NonlinearPDE_SNESProblem(F, u, bc)

    u.vector.set(0.9)
    u.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                         mode=PETSc.ScatterMode.FORWARD)

    b = dolfinx.cpp.la.create_vector(V.dofmap.index_map)
    J = dolfinx.cpp.fem.create_matrix(problem.a_comp._cpp_object)

    # Create Newton solver and solve
    snes = PETSc.SNES().create()
    snes.setFunction(problem.F, b)
    snes.setJacobian(problem.J, J)

    snes.setTolerances(rtol=1.0e-9, max_it=10)
    snes.getKSP().setType("preonly")
    snes.getKSP().setTolerances(rtol=1.0e-9)

    snes.getKSP().getPC().setType("lu")
    snes.getKSP().getPC().setFactorSolverType("superlu_dist")

    snes.solve(None, u.vector)
    assert snes.getConvergedReason() > 0
    assert snes.getIterationNumber() < 6

    # Modify boundary condition and solve again
    u_bc.vector.set(0.5)
    u_bc.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                            mode=PETSc.ScatterMode.FORWARD)
    snes.solve(None, u.vector)
    assert snes.getConvergedReason() > 0
    assert snes.getIterationNumber() < 6
Exemple #3
0
def test_newton_solver_inheritance_override_methods():
    import functools
    called_methods = {}

    def check_is_called(method):
        @functools.wraps(method)
        def wrapper(*args, **kwargs):
            called_methods[method.__name__] = True
            return method(*args, **kwargs)

        return wrapper

    class CustomNewtonSolver(dolfinx.cpp.nls.NewtonSolver):
        def __init__(self, comm):
            super().__init__(comm)

        @check_is_called
        def update_solution(self, x, dx, relaxation, problem, it):
            return super().update_solution(x, dx, relaxation, problem, it)

        @check_is_called
        def converged(self, r, problem, it):
            return super().converged(r, problem, it)

    mesh = dolfinx.generation.UnitSquareMesh(MPI.COMM_WORLD, 12, 12)
    V = function.FunctionSpace(mesh, ("Lagrange", 1))
    u = function.Function(V)
    v = TestFunction(V)
    F = inner(10.0, v) * dx - inner(grad(u), grad(v)) * dx

    def boundary(x):
        """Define Dirichlet boundary (x = 0 or x = 1)."""
        return np.logical_or(x[0] < 1.0e-8, x[0] > 1.0 - 1.0e-8)

    u_bc = function.Function(V)
    bc = fem.DirichletBC(u_bc, fem.locate_dofs_geometrical(V, boundary))

    # Create nonlinear problem
    problem = NonlinearPDEProblem(F, u, bc)

    # Create Newton solver and solve
    solver = CustomNewtonSolver(MPI.COMM_WORLD)
    n, converged = solver.solve(problem, u.vector)

    assert called_methods[CustomNewtonSolver.converged.__name__]
    assert called_methods[CustomNewtonSolver.update_solution.__name__]
Exemple #4
0
def test_nonlinear_pde():
    """Test Newton solver for a simple nonlinear PDE"""
    # Create mesh and function space
    mesh = dolfinx.generation.UnitSquareMesh(MPI.COMM_WORLD, 12, 5)
    V = fem.FunctionSpace(mesh, ("Lagrange", 1))
    u = dolfinx.fem.Function(V)
    v = TestFunction(V)
    F = inner(5.0, v) * dx - ufl.sqrt(u * u) * inner(
        grad(u), grad(v)) * dx - inner(u, v) * dx

    def boundary(x):
        """Define Dirichlet boundary (x = 0 or x = 1)."""
        return np.logical_or(x[0] < 1.0e-8, x[0] > 1.0 - 1.0e-8)

    u_bc = fem.Function(V)
    with u_bc.vector.localForm() as u_local:
        u_local.set(1.0)
    bc = fem.DirichletBC(u_bc, fem.locate_dofs_geometrical(V, boundary))

    # Create nonlinear problem
    problem = NonlinearPDEProblem(F, u, bc)

    # Create Newton solver and solve
    with u.vector.localForm() as u_local:
        u_local.set(0.9)
    solver = dolfinx.cpp.nls.NewtonSolver(MPI.COMM_WORLD)
    solver.setF(problem.F, problem.vector())
    solver.setJ(problem.J, problem.matrix())
    solver.set_form(problem.form)
    n, converged = solver.solve(u.vector)
    assert converged
    assert n < 6

    # Modify boundary condition and solve again
    with u_bc.vector.localForm() as u_local:
        u_local.set(0.5)
    n, converged = solver.solve(u.vector)
    assert converged
    assert n < 6
Exemple #5
0
def test_nonlinear_pde():
    """Test Newton solver for a simple nonlinear PDE"""
    # Create mesh and function space
    mesh = dolfinx.generation.UnitSquareMesh(dolfinx.MPI.comm_world, 12, 5)
    V = function.FunctionSpace(mesh, ("Lagrange", 1))
    u = dolfinx.function.Function(V)
    v = TestFunction(V)
    F = inner(5.0, v) * dx - ufl.sqrt(u * u) * inner(
        grad(u), grad(v)) * dx - inner(u, v) * dx

    def boundary(x):
        """Define Dirichlet boundary (x = 0 or x = 1)."""
        return np.logical_or(x[0] < 1.0e-8, x[0] > 1.0 - 1.0e-8)

    u_bc = function.Function(V)
    u_bc.vector.set(1.0)
    u_bc.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                            mode=PETSc.ScatterMode.FORWARD)
    bc = fem.DirichletBC(u_bc, fem.locate_dofs_geometrical(V, boundary))

    # Create nonlinear problem
    problem = NonlinearPDEProblem(F, u, bc)

    # Create Newton solver and solve
    u.vector.set(0.9)
    u.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                         mode=PETSc.ScatterMode.FORWARD)
    solver = dolfinx.cpp.nls.NewtonSolver(dolfinx.MPI.comm_world)
    n, converged = solver.solve(problem, u.vector)
    assert converged
    assert n < 6

    # Modify boundary condition and solve again
    u_bc.vector.set(0.5)
    u_bc.vector.ghostUpdate(addv=PETSc.InsertMode.INSERT,
                            mode=PETSc.ScatterMode.FORWARD)
    n, converged = solver.solve(problem, u.vector)
    assert converged
    assert n < 6