Hi
I made some changes. It is working smoothly now, but the result is not what I expect. Could someone please check what I am doing wrong?
from ngsolve import *
from netgen.geom2d import SplineGeometry
from ngsolve.webgui import Draw
from netgen.occ import *
from netgen.webgui import Draw as DrawGeo
shape = Rectangle(2,2).Face().Move((-1,-1,0))
shape.edges.Min(X).name="left"
shape.edges.Max(X).name="right"
shape.edges.Min(Y).name="bottom"
shape.edges.Max(Y).name="top"
time = 0.0
dt = 0.1
mesh = Mesh(OCCGeometry(shape, dim=2).GenerateMesh(maxh=0.25))
fes_old = H1(mesh, order=3, dirichlet="bottom|right|left|top")
gfu_main = GridFunction(fes_old)
new_mesh = Mesh(mesh.ngmesh.Copy())
fes = H1(new_mesh, order=3, dirichlet="bottom|right|left|top", autoupdate=True)
u,v = fes.TnT()
gfu = GridFunction(fes, autoupdate=True)
gfu.Set((1-y*y)*x)
def Solve(gfu, fes, u, v):
b = CoefficientFunction((2*y*(1-x*x),-2*x*(1-y*y)))
gaussp = exp(-6*((x+0.5)*(x+0.5)+y*y))-exp(-6*((x-0.5)*(x-0.5)+y*y))
a = BilinearForm(fes, symmetric=False)
a += 0.01*grad(u)*grad(v)*dx + b*grad(u)*v*dx
a.Assemble()
m = BilinearForm(fes, symmetric=False)
m += u*v*dx
m.Assemble()
mstar = m.mat.CreateMatrix()
mstar.AsVector().data = m.mat.AsVector() + dt * a.mat.AsVector()
invmstar = mstar.Inverse(freedofs=fes.FreeDofs())
f = LinearForm(fes)
f += gaussp*v*dx
f.Assemble()
res = dt * f.vec - dt * a.mat * gfu.vec
gfu.vec.data = invmstar * res
return gfu
def Solve2(gfu, fes, u, v):
b = CoefficientFunction((2*y*(1-x*x),-2*x*(1-y*y)))
gaussp = exp(-6*((x+0.5)*(x+0.5)+y*y))-exp(-6*((x-0.5)*(x-0.5)+y*y))
a = BilinearForm(fes, symmetric=False)
a += 0.01*grad(u)*grad(v)*dx + b*grad(u)*v*dx
a.Assemble()
m = BilinearForm(fes, symmetric=False)
m += u*v*dx
m.Assemble()
mstar = m.mat.CreateMatrix()
mstar.AsVector().data = m.mat.AsVector() + dt * a.mat.AsVector()
invmstar = mstar.Inverse(freedofs=fes.FreeDofs())
f = LinearForm(fes)
f += gaussp*v*dx
f.Assemble()
res = dt * f.vec - dt * a.mat * gfu.vec
gfu.vec.data += invmstar * res
return gfu
def CalcError(gfu, new_mesh):
flux = 0.01*grad(gfu)
# interpolate finite element flux into H(div) space:
gf_flux.Set (flux)
# Gradient-recovery error estimator
err = 1/0.01*(flux-gf_flux)*(flux-gf_flux)
elerr = Integrate (err, new_mesh, VOL, element_wise=True)
maxerr = max(elerr)
#print ("maxerr = ", maxerr)
for el in new_mesh.Elements():
new_mesh.SetRefinementFlag(el, elerr[el.nr] > 0.25*maxerr)
time = 0; tend = 2; cnt = 0; nsamples = 10; sample_int = int(floor(tend / dt / nsamples)+1)
gfut = GridFunction(gfu_main.space,multidim=0)
gfut.AddMultiDimComponent(gfu.vec)
while time < tend - 0.5 * dt:
space_flux = HDiv(new_mesh, order=2, autoupdate=True)
gf_flux = GridFunction(space_flux, "flux", autoupdate=True)
with TaskManager():
while fes.ndof < 100000:
Solve(gfu, fes, u, v)
CalcError(gfu, new_mesh)
new_mesh.Refine()
gfu_main.Set(Solve2(gfu, fes, u, v))
print("\r",time,end="")
new_mesh = Mesh(mesh.ngmesh.Copy())
fes = H1(new_mesh, order=3, dirichlet="bottom|right|left|top", autoupdate=True)
gfu = GridFunction(fes, autoupdate=True)
gfu.Set(gfu_main)
if cnt % sample_int == 0:
gfut.AddMultiDimComponent(gfu_main.vec)
u,v = fes.TnT()
cnt += 1; time = cnt * dt
Draw(gfut, mesh, interpolate_multidim=True, animate=True)
heat3.ipynb (6.1 KB)