FeniCS: Visualisierung von Elementen höherer Ordnung

14

Ich habe gerade angefangen, mit FEniCS herumzuspielen. Ich löse Poisson mit Elementen 3. Ordnung und möchte die Ergebnisse visualisieren. Wenn ich jedoch plot (u) verwende, ist die Visualisierung nur eine lineare Interpolation der Ergebnisse. Ich erhalte dasselbe, wenn ich auf VTK ausgebe. In einem anderen Code, mit dem ich arbeite, habe ich einen VTK-Outputer geschrieben, der Elemente höherer Ordnung aufwertet, sodass sie in Paraview tatsächlich eine höhere Ordnung haben. Gibt es so etwas (oder besseres) in FEniCS?

Truman Ellis
quelle

Antworten:

12

Sie können die Lösung auf ein feineres Netz interpolieren und dann plotten:

from dolfin import *

coarse_mesh = UnitSquareMesh(2, 2)
fine_mesh = refine(refine(refine(coarse_mesh)))

P2_coarse = FunctionSpace(coarse_mesh, "CG", 2)
P1_fine = FunctionSpace(fine_mesh, "CG", 1)

f = interpolate(Expression("sin(pi*x[0])*sin(pi*x[1])"), P2_coarse)
g = interpolate(f, P1_fine)

plot(f, title="Bad plot")
plot(g, title="Good plot")

interactive()

Beachten Sie, wie Sie den Umriss der groben P2-Dreiecke im Plot auf dem feineren Netz sehen können.

Diagramm der P2-Funktion auf grobem Netz

Diagramm der P2-Funktion interpoliert zu einer P1-Funktion auf einem feinen Netz

Anders Logg
quelle
8

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")

Zeichnung auf nicht raffiniertem Netz Raffiniertes Netz Handlung auf raffiniertem Netz Adaptiv veredeltes Mesh

Elmar Zander
quelle