## dpglaplace_original.py # """ ---------------------------------------------------------- This is a FEniCS implementation of a DPG method for the Dirichlet problem Delta u = f on UnitSquare u = g on boundary, and is part of notes for graduate lectures introducing DPG methods. [Disclaimer: This file worked as of May 2013 with FEniCS version 1.2.0. It may not work in past or future versions!] ----------------------------------------Jay Gopalakrishnan """ degree=1 # trial space degree p m = 8 # m x m square mesh divided into triangles from dolfin import * # Expressions for u and f (for error and source computation) U = Expression("x[0]*(1-x[0])*x[1]*(1-x[1])") F = Expression("2*x[1]*(1-x[1])+2*x[0]*(1-x[0])") ## You can set other solutions by solely changing U and F above, e.g.: # U = Expression("exp(pow(x[0],2)+pow(x[1],2))*sin(x[0]+x[1])") # F = Expression("-2*exp(pow(x[0],2)+pow(x[1],2))*(sin(x[0]+x[1])*(1+2*(pow(x[0],2)+pow(x[1],2))) + 2*cos(x[0]+x[1])*(x[0]+x[1]))") msh = UnitSquareMesh(m,m) E = FunctionSpace(msh,"DG", degree+2) # error estimator e CG = FunctionSpace(msh,"CG", degree+1) # primal variable u Q = FunctionSpace(msh,"BDM",degree,restriction="facet") # interfacial flux q X = MixedFunctionSpace( [E,CG,Q] ) (e,u,q) = TrialFunctions(X) (y,z,r) = TestFunctions(X) n = FacetNormal(msh) # normal vectors # the Y-inner product yip = dot(grad(e),grad(y))*dx + e*y*dx # b( (u,q), y ) = (grad u, grad y) - b1 = dot( grad(u),grad(y) ) * dx \ - dot(q('+'),n('+')) * (y('+')-y('-')) * dS \ - dot(q,n)*y*ds # b( (z,r), e) b2 = dot( grad(e),grad(z) ) * dx \ - (e('+')-e('-')) * dot(r('+'),n('+')) * dS \ - e*dot(r,n)*ds a = yip + b1 + b2 # mixed form of DPG b = F*y*dx # rhs # Dirichlet boundary condition on al boundary bc = DirichletBC(X.sub(1), U, DomainBoundary()) # solve x = Function(X) solve( a==b, x, bcs=bc) e,u,q = x.split(deepcopy=True) # compute errors fmsh=refine(refine(msh)) er = errornorm(U,u,norm_type='H1',degree_rise=3,mesh=fmsh) print " Case of %d x %d mesh with degree %d:"% (m,m,degree) print " H1-norm of (u - uh) = %15.12f" % er print " Error estimator norm = %15.12f" % \ sqrt(assemble( (dot(grad(e),grad(e)) +e*e) * dx )) # compute the H1 projection of U (a std Galerkin solution) uu = TrialFunction(CG) vv = TestFunction(CG) aa = (dot(grad(uu),grad(vv) )+uu*vv) *dx bb = (F+U)*vv*dx bc = DirichletBC(CG, U, DomainBoundary()) pu = Function(CG) solve( aa==bb, pu, bcs=bc) erp = errornorm(U,pu,norm_type='H1',degree_rise=3,mesh=fmsh) print " Error in H1 Projection = %15.12f" % erp if abs(erp)>1.e-12: print " Error:Projection ratio = %15.12f" % (er/erp) print " H1-norm of (uh - proj) = %15.12f" % \ errornorm(u,pu,norm_type='H1',degree_rise=0) # Issues: # # If you put degree=2 then the H1 best approximation error comes # out LARGER than the error of a numerical solution in the same # space! This is mathematically impossible. Is FEniCS losing some # double-precision digits in some routine?