Set number of V-cycles in multigrid preconditioner

More
4 years 4 months ago - 4 years 4 months ago #3059 by JanWesterdiep
Hey!

I am trying to use your multigrid preconditioner and set its number of V-cycles. When taking the following page as a starting point:
ngsolve.org/docu/nightly/i-tutorials/uni.../preconditioner.html
I see how I can build a multigrid preconditioner object.

In this file in the C++ code, I can see how this object is constructed:
github.com/NGSolve/ngsolve/blob/bef34e5a...ython_comp.cpp#L2474

Moreover, it shows me the existence of a `MultiGridPreconditioner` object in Python, which is the `MGPreconditioner` class in C++. This class has a `ngmg::MultigridPreconditioner` pointer which drives the multigrid, and *this* class has a method "SetCycle" that sounds to me like the right method:
github.com/NGSolve/ngsolve/blob/3e0c9cac...tigrid/mgpre.cpp#L50

In the constructor of the `MGPreconditioner` class, it calls this method,
github.com/NGSolve/ngsolve/blob/29f288b8...conditioner.cpp#L388
which indicates to me that when I create the preconditioner from Python using `MultiGridPreconditioner(A, cycle=N)`, it should set the cycles. However, no matter how I change the N, the preconditioner does not seem to improve. See the following code. Am I missing something? Is perhaps `cycle` not the number of V-cycles?
Code:
import matplotlib.pyplot as plt import netgen.gui from netgen.csg import unit_cube from netgen.geom2d import unit_square from ngsolve import * def SolveProblem(h=0.5, p=1, levels=1, condense=False, precond="local", cycle=5): """ Solve Poisson problem on l refinement levels. h: coarse mesh size p: polynomial degree l: number of refinement levels condense: if true, perform static condensations precond: name of a built-in preconditioner cycle: (non-working) number of cycles of the multigrid preconditioner OUTPUT: List of tuples of ndofs and iterations """ mesh = Mesh(unit_square.GenerateMesh(maxh=h)) fes = H1(mesh, order=p, dirichlet="bottom|left") u, v = fes.TnT() a = BilinearForm(fes, eliminate_internal=condense) a += grad(u) * grad(v) * dx f = LinearForm(fes) f += v * dx gfu = GridFunction(fes) Draw(gfu) if precond == 'multigrid': c = MultiGridPreconditioner(a, cycle=5) else: c = Preconditioner(a, precond) steps = [] for l in range(levels): if l > 0: mesh.Refine() fes.Update() gfu.Update() with TaskManager(): a.Assemble() f.Assemble() # Conjugate gradient solver inv = CGSolver(a.mat, c.mat, maxsteps=1000) # Solve steps depend on condense if condense: f.vec.data += a.harmonic_extension_trans * f.vec gfu.vec.data = inv * f.vec if condense: gfu.vec.data += a.harmonic_extension * gfu.vec gfu.vec.data += a.inner_solve * f.vec steps.append((fes.ndof, inv.GetSteps())) if fes.ndof < 15000: Redraw() return steps print([ SolveProblem(levels=5, precond="multigrid"), SolveProblem(levels=5, precond="multigrid", cycle=5) ])
Last edit: 4 years 4 months ago by JanWesterdiep.
Time to create page: 0.094 seconds