Set number of V-cycles in multigrid preconditioner

1 year 2 months ago - 1 year 2 months ago #3059 by JanWesterdiep

I am trying to use your multigrid preconditioner and set its number of V-cycles. When taking the following page as a starting point:
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:

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:

In the constructor of the `MGPreconditioner` class, it calls this method,
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?
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,
    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
        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)
    if precond == 'multigrid':
        c = MultiGridPreconditioner(a, cycle=5)
        c = Preconditioner(a, precond)

    steps = []

    for l in range(levels):
        if l > 0:

        with TaskManager():

            # Conjugate gradient solver
            inv = CGSolver(a.mat, c.mat, maxsteps=1000)

            # Solve steps depend on condense
            if condense:
       += a.harmonic_extension_trans * f.vec

   = inv * f.vec

            if condense:
       += a.harmonic_extension * gfu.vec
       += a.inner_solve * f.vec
        steps.append((fes.ndof, inv.GetSteps()))
        if fes.ndof < 15000:
    return steps

    SolveProblem(levels=5, precond="multigrid"),
    SolveProblem(levels=5, precond="multigrid", cycle=5)

Please Log in or Create an account to join the conversation.

© 2019 Netgen/NGSolve