FeniCS: Trực quan hóa các yếu tố thứ tự cao


14

Tôi vừa mới bắt đầu loay hoay với FEniCS. Tôi đang giải quyết Poisson với các yếu tố bậc 3 và muốn trực quan hóa kết quả. Tuy nhiên, khi tôi sử dụng cốt truyện (u), trực quan hóa chỉ là một phép nội suy tuyến tính của các kết quả. Tôi nhận được điều tương tự khi tôi xuất ra VTK. Trong một mã khác mà tôi đang làm việc, tôi đã viết một đầu ra VTK sẽ lấy mẫu các phần tử bậc cao hơn để chúng thực sự trông có thứ tự cao hơn trong Paraview. Có bất cứ điều gì như thế này (hoặc tốt hơn) trong FEniCS không?

Câu trả lời:


12

Bạn có thể nội suy giải pháp lên một lưới mịn hơn và sau đó vẽ sơ đồ:

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

Lưu ý cách bạn có thể thấy đường viền của các tam giác P2 thô trong biểu đồ trên lưới mịn hơn.

Sơ đồ hàm P2 trên lưới thô

Đồ thị của hàm P2 được nội suy thành hàm P1 trên lưới mịn


8

Tôi đã làm việc một chút về sàng lọc thích ứng để thực hiện công việc (xem mã bên dưới). Tỷ lệ của chỉ báo lỗi với tổng kích thước mắt lưới và tổng biến thể của hàm lưới là không hoàn hảo, nhưng bạn có thể phù hợp với nhu cầu của mình. Những hình ảnh dưới đây là dành cho testcase # 4. Số lượng tế bào tăng từ 200 lên khoảng 24.000, có thể là một chút so với đầu, nhưng kết quả là khá tốt đẹp. Lưới cho thấy chỉ có các phần có liên quan đã được tinh chế. Các vật phẩm bạn vẫn có thể nhìn thấy, là những gì mà chính các phần tử thứ ba không thể thể hiện đủ chính xác.

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

Vẽ trên lưới chưa tinh chế Lưới chưa tinh chế Vẽ trên lưới tinh chế Lưới tinh chế thích ứng

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.