Adaptive mesh refinement with MPI (UPDATED)
- sigmunh
- Topic Author
- New Member
Less
More
2 years 2 hours ago - 2 years 43 minutes ago #4556
by sigmunh
Adaptive mesh refinement with MPI (UPDATED) was created by sigmunh
Im trying to convert the example for
adaptive mesh refinement
[1] to working with MPI, but im getting a segmentation fault when im calling the function
mesh.Refine()
What is the correct way to do this? Do i need to 'collect' the mesh from the different cores, and run mesh.Refine() only on the rank=0 core (corresponding to that the mesh is distributed between the workers in the beginning)?
1: When run on two or more cores (mpirun -np 2 python3 adaptive.py), it creases with an segfault when the code reaches the line mesh.Refine().
[1] docu.ngsolve.org/v6.2.1808/whetting_the_appetite/adaptive.html
CODE
mesh.Refine()
What is the correct way to do this? Do i need to 'collect' the mesh from the different cores, and run mesh.Refine() only on the rank=0 core (corresponding to that the mesh is distributed between the workers in the beginning)?
1: When run on two or more cores (mpirun -np 2 python3 adaptive.py), it creases with an segfault when the code reaches the line mesh.Refine().
[1] docu.ngsolve.org/v6.2.1808/whetting_the_appetite/adaptive.html
CODE
Code:
from ngsolve import *
import ngsolve as ng
from netgen.geom2d import SplineGeometry
from ngsolve.krylovspace import CGSolver
from mpi4py import MPI
comm = MPI.COMM_WORLD
# point numbers 0, 1, ... 11
# sub-domain numbers (1), (2), (3)
#
#
# 7-------------6
# | |
# | (2) |
# | |
# 3------4-------------5------2
# | |
# | 11 |
# | / \ |
# | 10 (3) 9 |
# | \ / (1) |
# | 8 |
# | |
# 0---------------------------1
#
def make_geometry():
geometry = SplineGeometry()
# point coordinates ...
pnts = [ (0,0), (1,0), (1,0.6), (0,0.6), \
(0.2,0.6), (0.8,0.6), (0.8,0.8), (0.2,0.8), \
(0.5,0.15), (0.65,0.3), (0.5,0.45), (0.35,0.3) ]
pnums = [geometry.AppendPoint(*p) for p in pnts]
# start-point, end-point, boundary-condition, domain on left side, domain on right side:
lines = [ (0,1,1,1,0), (1,2,2,1,0), (2,5,2,1,0), (5,4,2,1,2), (4,3,2,1,0), (3,0,2,1,0), \
(5,6,2,2,0), (6,7,2,2,0), (7,4,2,2,0), \
(8,9,2,3,1), (9,10,2,3,1), (10,11,2,3,1), (11,8,2,3,1) ]
for p1,p2,bc,left,right in lines:
geometry.Append( ["line", pnums[p1], pnums[p2]], bc=bc, leftdomain=left, rightdomain=right)
return geometry
if comm.size > 1:
if comm.rank == 0:
mesh = make_geometry().GenerateMesh(maxh=0.2)
mesh = ng.Mesh(mesh.Distribute(comm))
else:
mesh = ng.Mesh(netgen.meshing.Mesh.Receive(comm))
else:
mesh = ng.Mesh(make_geometry().GenerateMesh(maxh=0.2))
vtk = ng.VTKOutput(
ma=mesh,
coefs=,
names=,
filename=f"mesh-rank-{comm.rank}",
subdivision=0)
vtk.Do()
fes = H1(mesh, order=3, dirichlet=[1])
u = fes.TrialFunction()
v = fes.TestFunction()
# one heat conductivity coefficient per sub-domain
lam = CoefficientFunction([1, 1000, 10])
# a = BilinearForm(fes, symmetric=False)
# a += SymbolicBFI(lam*grad(u)*grad(v))
a = BilinearForm(lam*grad(u)*grad(v) * dx)
pre = ng.Preconditioner(a, "local")
# a.Assemble()
# heat-source in sub-domain 3
f = LinearForm(fes)
f += SymbolicLFI(CoefficientFunction([0, 0, 1])*v)
# c = Preconditioner(a, type="multigrid", inverse = "sparsecholesky")
gfu = GridFunction(fes)
# Draw(gfu)
# finite element space and gridfunction to represent
# the heatflux:
space_flux = HDiv(mesh, order=2)
gf_flux = GridFunction(space_flux, "flux")
def SolveBVP(i):
fes.Update()
gfu.Update()
a.Assemble()
f.Assemble()
inv = CGSolver(a.mat, pre.mat, printrates=comm.rank == 0, maxiter=200, tol=1e-8)
gfu.vec.data = inv * f.vec
vtk = ng.VTKOutput(
ma=mesh,
coefs=[gfu],
names=["Temperature (K)"],
filename=f"results-{i}",
subdivision=0)
vtk.Do()
# Redraw(blocking=True)
l =
def CalcError():
space_flux.Update()
gf_flux.Update()
flux = lam * grad(gfu)
# interpolate finite element flux into H(div) space:
gf_flux.Set(flux)
# Gradient-recovery error estimator
err = 1/lam*(flux-gf_flux)*(flux-gf_flux)
elerr = Integrate (err, mesh, VOL, element_wise=True)
if len(elerr) == 0:
maxerr = 0
else:
maxerr = max(elerr)
maxerr = comm.allreduce(maxerr, MPI.MAX)
comm.Barrier()
l.append ( (fes.ndof, sqrt(sum(elerr)) ))
i = 0
i_nr = 0
for el in mesh.Elements():
i_nr += 1
if elerr[el.nr] > 0.25*maxerr:
i += 1
mesh.SetRefinementFlag(el, elerr[el.nr] > 0.25*maxerr)
print("# ", i, "number of elements refined. total=", i_nr)
with TaskManager():
i = 0
while fes.ndof < 100000:
print(i)
i += 1
if i == 20:
break
SolveBVP(i)
CalcError()
print("before", comm.rank)
mesh.Refine()
print("after", comm.rank)
print()
print("# num elements after refinement =", len(list(mesh.Elements())))
vtk = ng.VTKOutput(
ma=mesh,
coefs=,
names=,
filename=f"mesh-{i}",
subdivision=0)
vtk.Do()
import matplotlib.pyplot as plt
plt.yscale('log')
plt.xscale('log')
plt.xlabel("ndof")
plt.ylabel("H1 error-estimate")
ndof,err = zip(*l)
plt.plot(ndof,err, "-*")
plt.ion()
plt.savefig("hei.pdf")
Last edit: 2 years 43 minutes ago by sigmunh.
Time to create page: 0.107 seconds