Ich habe ein bisschen an der adaptiven Verfeinerung gearbeitet, um den Job zu erledigen (siehe den Code unten). Die Skalierung des Fehlerindikators mit der gesamten Maschengröße und der gesamten Variation der Maschenfunktion ist nicht perfekt, aber Sie können dies an Ihre Bedürfnisse anpassen. Die folgenden Bilder sind für Testfall Nr. 4. Die Anzahl der Zellen erhöht sich von 200 auf etwa 24.000, was zwar etwas übertrieben ist, aber das Ergebnis ist ziemlich gut. Das Netz zeigt, dass nur die relevanten Teile verfeinert wurden. Die Artefakte, die Sie immer noch sehen können, sind das, was die Elemente dritter Ordnung selbst nicht genau genug darstellen konnten.
from dolfin import *
from numpy import abs
def compute_error(expr, mesh):
DG = FunctionSpace(mesh, "DG", 0)
e = project(expr, DG)
err = abs(e.vector().array())
dofmap = DG.dofmap()
return err, dofmap
def refine_by_bool_array(mesh, to_mark, dofmap):
cell_markers = CellFunction("bool", mesh)
cell_markers.set_all(False)
n = 0
for cell in cells(mesh):
index = dofmap.cell_dofs(cell.index())[0]
if to_mark[index]:
cell_markers[cell] = True
n += 1
mesh = refine(mesh, cell_markers)
return mesh, n
def adapt_mesh(f, mesh, max_err=0.001, exp=0):
V = FunctionSpace(mesh, "CG", 1)
while True:
fi = interpolate(f, V)
v = CellVolume(mesh)
expr = v**exp * abs(f-fi)
err, dofmap = compute_error(expr, mesh)
to_mark = (err>max_err)
mesh, n = refine_by_bool_array(mesh, to_mark, dofmap)
if not n:
break
V = FunctionSpace(mesh, "CG", 1)
return fi, mesh
def show_testcase(i, p, N, fac, title1="", title2=""):
funcs = ["sin(60*(x[0]-0.5)*(x[1]-0.5))",
"sin(10*(x[0]-0.5)*(x[1]-0.5))",
"sin(10*(x[0]-0.5))*sin(pow(3*(x[1]-0.05),2))"]
mesh = UnitSquareMesh(N, N)
U = FunctionSpace(mesh, "CG", p)
f = interpolate(Expression(funcs[i]), U)
v0 = (1.0/N) ** 2;
exp = 1
#exp = 0
fac2 = (v0/100)**exp
max_err = fac * fac2
#print v0, fac, exp, fac2, max_err
g, mesh2 = adapt_mesh(f, mesh, max_err=max_err, exp=exp)
plot(mesh, title=title1 + " (mesh)")
plot(f, title=title1)
plot(mesh2, title=title2 + " (mesh)")
plot(g, title=title2)
interactive()
if __name__ == "__main__":
N = 10
fac = 0.01
show_testcase(0, 1, 10, fac, "degree 1 - orig", "degree 1 - refined (no change)")
show_testcase(0, 2, 10, fac, "degree 2 - orig", "degree 2 - refined")
show_testcase(0, 3, 10, fac, "degree 3 - orig", "degree 3 - refined")
show_testcase(0, 3, 10, 0.2*fac, "degree 3 - orig", "degree 3 - more refined")
show_testcase(1, 2, 10, fac, "smooth: degree 2 - orig", "smooth: degree 2 - refined")
show_testcase(1, 3, 10, fac, "smooth: degree 3 - orig", "smooth: degree 3 - refined")
show_testcase(2, 2, 10, fac, "bumps: degree 2 - orig", "bumps: degree 2 - refined")
show_testcase(2, 3, 10, fac, "bumps: degree 3 - orig", "bumps: degree 3 - refined")