""" ---------------------------------------------------------- DPG methods come with a built-in error estimator. This FEniCS implementation shows how to use that estimator in an adaptive algorithm to solve Delta u = f on UnitSquare u = 0 on boundary, where f is peaked at a boundary point (so that near it, we expect the exact solution to require finer mesh points for its resolution). This file is part of a few graduate lectures introducing DPG methods. It is heavily based on the undocumented FEniCS demo at share/dolfin/demo/undocumented/adaptive-poisson/python/demo_adaptive-poisson.py which shows a way to implement adaptivity for the standard FEM. We have substituted the FEM by DPG, and omitted the original demo's error estimator calculation (since one of the DPG solution components is an error estimator). [Disclaimer: This file worked as of May 2013 with FEniCS version 1.2.0, but it may not work on past or future versions!] ----------------------------------------Jay Gopalakrishnan """ from dolfin import * if not has_cgal(): # does not work without CGAL print "DOLFIN must be compiled with CGAL to run this demo." exit(0) TOL = 1e-4 # error tolerance for stopping adaptive iterations REFINE_RATIO = 0.50 # refine 50 % of the cells in each iteration MAX_ITER = 20 # maximal number of iterations # create initial mesh msh = UnitSquareMesh(2,2) # set rhs f, no expression for exact solution known source_str = "exp(-100.0*(pow(x[0], 2) + pow(x[1], 2)))" ufile = File("out/dpgsol.pvd") # adaptive algorithm for level in xrange(MAX_ITER): # define the lowest order DPG method ER = FunctionSpace(msh,"DG",2) # DPG error estimator CG = FunctionSpace(msh,"CG",1) # linear solution u Q = FunctionSpace(msh,"RT",1,restriction="facet") # constant fluxes q X = MixedFunctionSpace( [ER,CG,Q] ) (e,u,q) = TrialFunctions(X) (y,z,r) = TestFunctions(X) n = FacetNormal(msh) # 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 f = Expression(source_str) b = f*y*dx # solve x = Function(X) bc = DirichletBC(X.sub(1), Constant(0.0), DomainBoundary()) solve( a==b, x, bcs=bc) e,u,q = x.split() # compute error indicators from the DPG mixed variable e PC = FunctionSpace(msh,"DG", 0) c = TestFunction(PC) # p.w constant fn g = assemble((dot(grad(e),grad(e))+e*e)*c*dx) g = g.array() # element-wise norms of e E = sqrt( assemble((dot(grad(e),grad(e))+e*e)*dx)) print "Level %d: Estimated error E = %g (TOL = %g)"%\ (level, E, TOL) # Check convergence if E < TOL: print "Success, solution converged after %d iterations"% level break # Mark cells for refinement cell_markers = MeshFunction("bool", msh, msh.topology().dim()) g0 = sorted(g, reverse=True)[int(len(g)*REFINE_RATIO)] for c in cells(msh): cell_markers[c] = g[c.index()] > g0 # Refine mesh msh = refine(msh, cell_markers) # Plot mesh plot(u,wireframe=True,scalarbar=False) ufile << u # Hold plot interactive()