Skip to content

Nonlinear Poisson tutorial #60

Closed
Closed
@bhaveshshrimali

Description

@bhaveshshrimali

Hi @jorgensd,

Although a pretty minor detail, but isn't scatter_forward repeated in the Nonlinear poisson tutorial at the end? NewtonSolver.solve() automatically applies scatter_forward to the solution, as I can see here?

On another note, do you feel that adding an example on, say, implementing the Newton's method by hand would add value to tutorial? This could be illustrative in use cases where one needs to implement their own nonlinear solve? Something like this for the nonlinear poisson

from ufl import TrialFunction, derivative
Jac = derivative(F, uh, TrialFunction(V))

bilinear_form = fem.form(Jac)
linear_form = fem.form(-F)

du = fem.Function(V, name="incr_u")

bilinf = fem.assemble.create_matrix(bilinear_form)
linf = fem.assemble.create_vector(linear_form)

# zero the entries
bilinf.zeroEntries()

fem.assemble_matrix(bilinf, bilinear_form, bcs=bcs)
bilinf.assemble()

with linf.localForm() as loc:
    loc.set(0.)

fem.assemble_vector(linf, linear_form)

fem.apply_lifting(linf, [bilinear_form], [bcs])
linf.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES, mode=PETSc.ScatterMode.REVERSE)
fem.set_bc(linf, bcs)

res_0 = linf.norm()
res = res_0
print(f"Initial residual norm: {res_0}")
solver = PETSc.KSP().create(mesh.comm)
solver.setType(PETSc.KSP.Type.PREONLY)
solver.getPC().setType(PETSc.PC.Type.LU)
solver.setOperators(bilinf)
solver.solve(linf, du.vector)
du.x.scatter_forward()
uh.vector.axpy(1.0, du.vector)
iters = 0
maxIter = 30

while res/res_0 > 1.e-8 and iters < maxIter:

    
    bilinf.zeroEntries()
    fem.assemble_matrix(bilinf, bilinear_form, bcs=bcs_hom)
    bilinf.assemble()

    with linf.localForm() as loc:
        loc.set(0.)

    fem.assemble_vector(linf, linear_form)
    fem.apply_lifting(linf, [bilinear_form], [bcs_hom])
    linf.ghostUpdate(addv=PETSc.InsertMode.ADD_VALUES, mode=PETSc.ScatterMode.REVERSE)
    fem.set_bc(linf, bcs_hom)
    solver.setOperators(bilinf)
    solver.solve(linf, du.vector)
    du.x.scatter_forward()
    uh.vector.axpy(1.0, du.vector)
    res = linf.norm()
    print(f"norm: {res}")
    iters += 1

instead of the call to NewtonSolver.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions