2. Hybridization#
2.1. Poisson equation#
from ngsolve import *
from ngsolve.webgui import Draw
mesh = Mesh(unit_square.GenerateMesh(maxh=0.2))
order = 2
Sigma = HDiv(mesh, order=order)
V = L2(mesh, order=order-1)
Vhat = FacetFESpace(mesh, order=order, dirichlet=".*")
X = PrivateSpace(Sigma) * V * Vhat
(sigma, u, uhat), (tau, v, vhat) = X.TnT()
print ("ndof.Sigma=", Sigma.ndof)
print ("Discont(Sigma).ndof=", Discontinuous(Sigma).ndof)
print ("Privat(Sigma).ndof=", PrivateSpace(Sigma).ndof)
print ("V.ndof=", V.ndof, "Vhat.ndof=", Vhat.ndof)
print ("X.ndof = ", X.ndof)
ndof.Sigma= 435
Discont(Sigma).ndof= 648
Privat(Sigma).ndof= 0
V.ndof= 162 Vhat.ndof= 273
X.ndof = 435
PrivateSpace .. have elements, but don’t assign global dofs
will be condensed out in assembling
Find \(\sigma \in BDM_k^{dc}\), \(u \in P^{k-1}\), \(\hat u \in P^k({\mathcal E})\):
\[\begin{split}
\begin{array}{ccccll}
(\sigma, \tau) & + & (\operatorname{div} \tau, u) + ([\sigma n], \hat u)_{\mathcal E} & = & 0 & \forall \, \tau \\
(\operatorname{div} \sigma, v) + ([\tau n], \hat v)_{\mathcal E}
& & & = & (f,v) & \forall \, (v, \hat v)
\end{array}
\end{split}\]
n = specialcf.normal(mesh.dim)
def Div(sigma, v, vhat): return div(sigma)*v*dx - sigma*n * vhat*dx(element_boundary=True)
source = x
lhs = sigma*tau*dx + Div(sigma,v,vhat) + Div(tau, u,uhat)
rhs = source*v*dx
gf = Solve(lhs==rhs)
_, gfu, gfuhat = gf.components
print ("ndof gf =", len(gf.vec))
Draw (gfu);
ndof gf = 435
2.2. Reconstruct the flux#
Xp1 = Discontinuous(Sigma)*V
(sigmap1, up1), (taup1, vp1) = Xp1.TnT()
lhs = sigmap1*taup1*dx + div(sigmap1)*vp1*dx + div(taup1)*up1*dx
rhs = source*vp1*dx + taup1*n * gfuhat*dx(element_boundary=True)
gfpsigma,_ = Solve(lhs==rhs).components
Draw (gfpsigma[0], mesh);
Setup and solve a new problem for the flux, only if we need the flux.
Alternative:
Keep the flux in the product space, local condensation, and reconstruct algebraically by harmonic extension
Setup reconstruction operator
2.3. Postprocessing for the scalar#
obtain better scalar by solving
\[
\min_{u_p \atop \int_T u_p = \int_T u} \| \nabla u_p - \sigma \|^2
\]
Xp = L2(mesh,order=order+1) * L2(mesh,order=0)
(up,umean),(vp,vmean) = Xp.TnT()
lhs = grad(up)*grad(vp)*dx + up*vmean*dx + vp*umean*dx
rhs = gfpsigma*grad(vp)*dx + gfu*vmean*dx
gfp,_ = Solve(lhs==rhs).components
Draw (gfp);