- Thank you received: 0
Set number of V-cycles in multigrid preconditioner
- JanWesterdiep
- Topic Author
- Offline
- Junior Member
Less
More
4 years 3 months ago - 4 years 3 months ago #3059
by JanWesterdiep
Set number of V-cycles in multigrid preconditioner was created 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?
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 3 months ago by JanWesterdiep.
Time to create page: 0.105 seconds