Processing math: 100%

Facet spaces and hybrid methods

Mixed methods for second order problems lead to saddle point problems, and indefinite matrices. By hybridization one obtains a positive definite system again. It's structure is similar to the non-conforming P1 method, but hybridization works for any order. See text-book by Brezzi and Fortin.

One skips the normal-continuity of the H(div) variable, and reinforces it by a Lagrange parameter. This leads to the following discrete system:

Find σ,u,ˆuΣh×Vh×Fh:

λ1στ+TTdivτu+FF[τn]ˆu=0τΣdivσv=fvvVh[σn]ˆv=ΓngˆvˆvFh

where Σh is an discontinuous H(div) finite element space, Vh a sub-space of L2, and Fh consists of polynomials on every edge.

In [1]:
from netgen.geom2d import unit_square
from ngsolve import *
import netgen.gui
%gui tk
mesh = Mesh(unit_square.GenerateMesh(maxh=0.2))

same example as in 'mixed':

In [2]:
source = sin(3.14*x)
ud = CoefficientFunction(5)
g = CoefficientFunction([y*(1-y) if bc=="left" else 0 for bc in mesh.GetBoundaries()])
lam = 10

define spaces:

  • The discontinuous flag generates an element-wise H(Div)-space
  • FacetFESpace lives only on facets (i.e. faces in 3D, edges in 2D, points in 1D)

Boundary conditions are now posed for the facet-space

In [3]:
order = 3
V = HDiv(mesh, order=order, flags = { "discontinuous" : True })
Q = L2(mesh, order=order-1)
F = FacetFESpace(mesh, order=order, dirichlet="bottom")
X = FESpace([V,Q,F])

Assemble forms. The jump-term is rewritten as FF[σn]v=TTσnv

In [4]:
sigma,u,uhat = X.TrialFunction()
tau,v,vhat = X.TestFunction()

a = BilinearForm(X)
a += SymbolicBFI(1/lam * sigma*tau + div(sigma)*v + div(tau)*u)
n = specialcf.normal(mesh.dim)
a += SymbolicBFI(sigma*n*vhat+tau*n*uhat, element_boundary=True)
a.Assemble()

f = LinearForm(X)
f += SymbolicLFI(-source*v)
f += SymbolicLFI(g*vhat, BND)
f.Assemble()

Solve system. Leave everything to the sparse direct solver.

In [5]:
gfu = GridFunction(X)
inv = a.mat.Inverse(freedofs=X.FreeDofs())
gfu.vec.data = inv * f.vec
In [6]:
Draw (gfu.components[0], mesh, "sigma")
Draw (gfu.components[1], mesh, "u")
In [7]: