FeniCS: визуализация элементов высокого порядка


14

Я только начал возиться с FEniCS. Я решаю Пуассона с элементами 3-го порядка и хотел бы визуализировать результаты. Однако, когда я использую plot (u), визуализация - это просто линейная интерполяция результатов. Я получаю то же самое, когда выхожу на ВТК. В другом коде, с которым я работаю, я написал выводчик VTK, который будет повышать частоту элементов более высокого порядка, чтобы они действительно выглядели более высоким порядком в Paraview. Есть ли что-то подобное (или лучше) в FEniCS?

Ответы:


12

Вы можете интерполировать решение на более мелкую сетку и затем построить ее:

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

Обратите внимание, как вы видите контур грубых треугольников P2 на графике на более мелкой сетке.

График функции P2 на грубой сетке

График функции P2, интерполированный к функции P1 на тонкой сетке


8

Я немного работал над адаптивным уточнением, чтобы выполнить работу (см. Код ниже). Масштабирование индикатора ошибки с общим размером сетки и общим изменением функции сетки не является идеальным, но вы можете приспособить это к вашим потребностям. Изображения ниже для теста № 4. Количество ячеек увеличивается с 200 до примерно 24 000, что может быть немного выше, но результат довольно приятный. Сетка показывает, что только соответствующие части были уточнены. Все еще можно увидеть артефакты, которые сами элементы третьего порядка не могли представить достаточно точно.

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

Участок на неочищенной сетке Неопределенная сетка Участок на изысканной сетке Адаптивно изысканная сетка

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.