FeniCS: Yüksek dereceli elemanları görselleştirme


14

FEniCS ile uğraşmaya yeni başladım. Poisson'u 3. dereceden elemanlarla çözüyorum ve sonuçları görselleştirmek istiyorum. Ancak, çizim (u) kullandığımda, görselleştirme sadece sonuçların doğrusal enterpolasyonudur. VTK'ya çıkış yaptığımda da aynı şeyi alıyorum. Birlikte çalıştığım başka bir kodda, aslında Paraview'de daha yüksek sıraya bakmaları için daha yüksek dereceli öğeleri örnekleyen bir VTK çıktısı yazdım. FEniCS'de böyle (veya daha iyisi) bir şey var mı?

Yanıtlar:


12

Çözeltiyi daha ince bir ağ üzerine enterpole edebilir ve daha sonra çizebilirsiniz:

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

İnce ağ üzerindeki çizimde kaba P2 üçgenlerinin ana hatlarını nasıl görebileceğinize dikkat edin.

Kaba ağda P2 fonksiyonunun çizimi

İnce bir ağ üzerindeki P1 fonksiyonuna enterpolasyonlu P2 fonksiyonunun çizimi


8

Ben iş yapmak için uyarlanabilir arıtma üzerinde biraz çalışıyorum (aşağıdaki koda bakınız). Hata göstergesinin toplam ağ boyutu ve ağ işlevinin toplam varyasyonu ile ölçeklendirilmesi mükemmel değildir, ancak ihtiyaçlarınıza göre ayarlayabilirsiniz. Aşağıdaki resimler 4 numaralı test çantası içindir. Hücre sayısı 200'den 24.000'e yükselir, bu da tepenin biraz üzerinde olabilir, ancak sonuç oldukça güzeldir. Ağ, sadece ilgili bölümlerin rafine edildiğini gösterir. Hala görebileceğiniz eserler, üçüncü dereceden elementlerin yeterince doğru bir şekilde temsil edemedikleri şeydir.

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

Rafine edilmemiş file üzerine çizim Rafine edilmemiş örgü Rafine örgü üzerine çizim Uyarlanmış rafine ağ

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.