Embedded Trefftz-DG: Advection

In this section we finally consider an example that is typically not related to Trefftz method: A scalar linear transport problem, the advection equation. It reads as

\[\begin{split}\newcommand{\Th}{{\mathcal{T}_h}} \newcommand{\Fh}{\mathcal{F}_h} \newcommand{\dom}{\Omega} \newcommand{\jump}[1]{[\![ #1 ]\!]} \newcommand{\tjump}[1]{[\![{#1} ]\!]_\tau} \newcommand{\avg}[1]{\{\!\!\{#1\}\!\!\}} \newcommand{\nx}{n_\mathbf{x}} \newcommand{\Vhp}{V^p(\Th)} \newcommand{\bT}{\mathbf{T}} \newcommand{\bW}{\mathbf{W}} \newcommand{\bw}{\mathbf{w}} \newcommand{\bl}{\mathbf{l}} \newcommand{\bM}{\mathbf{M}} \newcommand{\bL}{\mathbf{L}} \newcommand{\bA}{\mathbf{A}} \newcommand{\bU}{\mathbf{U}} \newcommand{\bV}{\mathbf{V}} \newcommand{\calL}{\mathcal{L}} \newcommand{\bu}{\mathbf{u}} \newcommand{\IT}{\mathbb{T}} \newcommand{\calG}{\mathcal{G}} \newcommand{\be}{\mathbf{e}} \newcommand{\bx}{{\mathbf x}} \newcommand{\inner}[1]{\langle #1 \rangle} \newcommand{\bb}{\mathbf{b}} \begin{align*} \bb\cdot\nabla u &= f\quad \text{ in } \Omega,\\ u &= u_D \quad \text{ on } \partial \Omega_{\text{in}} :=\{\bx\in\partial \Omega\mid \bb\cdot\nx < 0\}. \end{align*}\end{split}\]

for a given velocity field \(\bb\) which we assume to be divergence-free.

As underlying DG discretization we choose the standard Upwind DG formulation which reads as

\[\begin{split}\begin{align} a_h(u,v) &= \sum_{K\in\Th} \Big\{ \int_K - u ~ \bb\cdot \nabla v\ dV +\int_{\partial K\setminus {\partial \Omega}{\text{in}} } \bb\cdot\nx\hat{u} v~ dS \Big\} \\ \ell(v) &= \sum_{K\in\Th} \int_K f v\ dV - \int_{{\partial \Omega}{\text{in}}} \bb \cdot \nx u_D v~ dS \end{align}\end{split}\]
[1]:
from ngsolve import *
from ngstrefftz import *
from netgen.occ import *
[2]:
b = CF((-sin(y),cos(x)))
exact = sin(3*x)*sin(3*y)
rhs = b*CF((exact.Diff(x),exact.Diff(y)))

mesh = Mesh(unit_square.GenerateMesh(maxh=0.1))
fes = L2(mesh, order=4,  dgjumps=True)
u,v = fes.TnT()
[3]:
bndc=exact
n = specialcf.normal(mesh.dim)
h = specialcf.mesh_size

jump_u = (u-u.Other())*n
jump_v = (v-v.Other())*n

a = BilinearForm(fes,symmetric=False)
a += - u * b * grad(v) * dx
a += b*n*IfPos(b*n,u,u.Other())*v*dx(element_boundary=True)

f = LinearForm(fes)
f += rhs*v * dx \
     - b*n*IfPos(b*n,0,bndc)*v * ds(skeleton=True)
with TaskManager():
    a.Assemble()
    f.Assemble()

[4]:
eps = 10**-8
op = b*grad(u) * grad(v)[0]*dx
lop = rhs*grad(v)[0]*dx

with TaskManager():
    PP,uf = TrefftzEmbedding(op,fes,lop,eps)
PPT = PP.CreateTranspose()
with TaskManager():
    TA = PPT@a.mat@PP
    Tgfu = TA.Inverse()*(PPT*(f.vec-a.mat*uf))
    gfu = GridFunction(fes)
    gfu.vec.data = PP*Tgfu + uf
error = sqrt(Integrate((gfu-exact)**2, mesh))
print("svdt error : {:13.8e}".format(error))
svdt error : 1.51628610e-07
[5]:
from ngsolve.webgui import Draw
Draw(gfu)
[5]:
BaseWebGuiScene