Mataplotlib of demo_biharmonic.py

HI all. I run demo_biharmonic.py but I didn’t get the same image as they given in biharmonic_u.png . What I got is below. I open it in paraview by using command paraview biharmonic.pvd but didn’t get the result. Also the L2 error goes increasing as I fine the mesh.The code is given below.On taking mesh = UnitSquareMesh(2,2) I got 0.284522 and on taking mesh = UnitSquareMesh(4,4) I got 0.401958. Our error must decrease with finer refinement but it increases as we do the mesh finer. Kindly help me regarding the same. Thanku.
Figure_1

# Biharmonic equation
# ===================
# 
# This demo is implemented in a single Python file,
# :download:`demo_biharmonic.py`, which contains both the variational
# forms and the solver.
# 
# This demo illustrates how to:
# 
# * Solve a linear partial differential equation
# * Use a discontinuous Galerkin method
# * Solve a fourth-order differential equation
# 
# The solution for :math:`u` in this demo will look as follows:
# 
# .. image:: biharmonic_u.png
#     :scale: 75 %
# 
# 
# Equation and problem definition
# -------------------------------
# 
# The biharmonic equation is a fourth-order elliptic equation. On the
# domain :math:`\Omega \subset \mathbb{R}^{d}`, :math:`1 \le d \le 3`,
# it reads
# 
# .. math::
#    \nabla^{4} u = f \quad {\rm in} \ \Omega,
# 
# where :math:`\nabla^{4} \equiv \nabla^{2} \nabla^{2}` is the
# biharmonic operator and :math:`f` is a prescribed source term. To
# formulate a complete boundary value problem, the biharmonic equation
# must be complemented by suitable boundary conditions.
# 
# Multiplying the biharmonic equation by a test function and integrating
# by parts twice leads to a problem second-order derivatives, which
# would requires :math:`H^{2}` conforming (roughly :math:`C^{1}`
# continuous) basis functions.  To solve the biharmonic equation using
# Lagrange finite element basis functions, the biharmonic equation can
# be split into two second-order equations (see the Mixed Poisson demo
# for a mixed method for the Poisson equation), or a variational
# formulation can be constructed that imposes weak continuity of normal
# derivatives between finite element cells.  The demo uses a
# discontinuous Galerkin approach to impose continuity of the normal
# derivative weakly.
# 
# Consider a triangulation :math:`\mathcal{T}` of the domain
# :math:`\Omega`, where the set of interior facets is denoted by
# :math:`\mathcal{E}_h^{\rm int}`.  Functions evaluated on opposite
# sides of a facet are indicated by the subscripts ':math:`+`' and
# ':math:`-`'.  Using the standard continuous Lagrange finite element
# space
# 
# .. math::
#     V = \left\{v \in H^{1}_{0}(\Omega)\,:\, v \in P_{k}(K) \ \forall \ K \in \mathcal{T} \right\}
# 
# and considering the boundary conditions
# 
# .. math::
#    u            &= 0 \quad {\rm on} \ \partial\Omega \\
#    \nabla^{2} u &= 0 \quad {\rm on} \ \partial\Omega
# 
# a weak formulation of the biharmonic problem reads: find :math:`u \in
# V` such that
# 
# .. math::
#   a(u,v)=L(v) \quad \forall \ v \in V,
# 
# where the bilinear form is
# 
# 
# .. math::
#    a(u, v) = \sum_{K \in \mathcal{T}} \int_{K} \nabla^{2} u \nabla^{2} v \, {\rm d}x \
#   +\sum_{E \in \mathcal{E}_h^{\rm int}}\left(\int_{E} \frac{\alpha}{h_E} [\!\![ \nabla u ]\!\!] [\!\![ \nabla v ]\!\!] \, {\rm d}s
#   - \int_{E} \left<\nabla^{2} u \right>[\!\![ \nabla v ]\!\!]  \, {\rm d}s
#   - \int_{E} [\!\![ \nabla u ]\!\!]  \left<\nabla^{2} v \right>  \, {\rm d}s\right)
# 
# and the linear form is
# 
# .. math::
#   L(v) = \int_{\Omega} fv \, {\rm d}x
# 
# Furthermore, :math:`\left< u \right> = \frac{1}{2} (u_{+} + u_{-})`,
# :math:`[\!\![ w ]\!\!]  = w_{+} \cdot n_{+} + w_{-} \cdot n_{-}`,
# :math:`\alpha \ge 0` is a penalty parameter and :math:`h_E` is a
# measure of the cell size.
# 
# The input parameters for this demo are defined as follows:
# 
# * :math:`\Omega = [0,1] \times [0,1]` (a unit square)
# * :math:`\alpha = 8.0` (penalty parameter)
# * :math:`f = 4.0 \pi^4\sin(\pi x)\sin(\pi y)` (source term)
# 
# 
# Implementation
# --------------
# 
# This demo is implemented in the :download:`demo_biharmonic.py` file.
# 
# First, the necessary modules are imported::

import matplotlib.pyplot as plt
from dolfin import *

# Next, some parameters for the form compiler are set::

# Optimization options for the form compiler
parameters["form_compiler"]["cpp_optimize"] = True
parameters["form_compiler"]["optimize"] = True

# A mesh is created, and a quadratic finite element function space::

# Make mesh ghosted for evaluation of DG terms
parameters["ghost_mode"] = "shared_facet"

# Create mesh and define function space
mesh = UnitSquareMesh(4,4)
V = FunctionSpace(mesh, "CG", 2)

# A subclass of :py:class:`SubDomain <dolfin.cpp.SubDomain>`,
# ``DirichletBoundary`` is created for later defining the boundary of
# the domain::

# Define Dirichlet boundary
class DirichletBoundary(SubDomain):
    def inside(self, x, on_boundary):
        return on_boundary

# A subclass of :py:class:`Expression
# <dolfin.functions.expression.Expression>`, ``Source`` is created for
# the source term :math:`f`::

class Source(UserExpression):
    def eval(self, values, x):
        values[0] = 4.0*pi**4*sin(pi*x[0])*sin(pi*x[1])

# The Dirichlet boundary condition is created::

# Define boundary condition
u0 = Constant(0.0)
bc = DirichletBC(V, u0, DirichletBoundary())

# On the finite element space ``V``, trial and test functions are
# created::

# Define trial and test functions
u = TrialFunction(V)
v = TestFunction(V)

# A function for the cell size :math:`h` is created, as is a function
# for the average size of cells that share a facet (``h_avg``).  The UFL
# syntax ``('+')`` and ``('-')`` restricts a function to the ``('+')``
# and ``('-')`` sides of a facet, respectively. The unit outward normal
# to cell boundaries (``n``) is created, as is the source term ``f`` and
# the penalty parameter ``alpha``. The penalty parameters is made a
# :py:class:`Constant <dolfin.functions.constant.Constant>` so that it
# can be changed without needing to regenerate code. ::

# Define normal component, mesh size and right-hand side
h = CellDiameter(mesh)
h_avg = (h('+') + h('-'))/2.0
n = FacetNormal(mesh)
f = Source(degree=2)

# Penalty parameter
alpha = Constant(8.0)

# The bilinear and linear forms are defined::

# Define bilinear form
a = inner(div(grad(u)), div(grad(v)))*dx \
  - inner(avg(div(grad(u))), jump(grad(v), n))*dS \
  - inner(jump(grad(u), n), avg(div(grad(v))))*dS \
  + alpha/h_avg*inner(jump(grad(u),n), jump(grad(v),n))*dS

# Define linear form
L = f*v*dx

# A :py:class:`Function <dolfin.functions.function.Function>` is created
# to store the solution and the variational problem is solved::

# Solve variational problem
u = Function(V)
solve(a == L, u, bc)

error_L2 = errornorm(u0, u, 'L2')
print('error_L2  =', error_L2)

# The computed solution is written to a file in VTK format and plotted to
# the screen. ::

# Save solution to file
file = File("biharmonic.pvd")
file << u

# Plot solution
plot(u)
plt.show()

What you are checking is the L^2 norm of the solution, not the L^2 norm of the error. errornorm here is comparing u with u0, where the latter is Constant(0.0). In this case, the exact solution is \sin(\pi x_0)\sin(\pi x_1), so you can check the error as follows:

#error_L2 = errornorm(u0, u, 'L2')
x = SpatialCoordinate(mesh)
u_ex = sin(pi*x[0])*sin(pi*x[1])
error_L2 = sqrt(assemble(((u-u_ex)**2)*dx))
print('error_L2  =', error_L2)

which converges as expected. If you want to use errornorm, you could also define the exact solution as an Expression, e.g.,

u0 = Expression('sin(pi*x[0])*sin(pi*x[1])',degree=3)
error_L2 = errornorm(u0, u, 'L2')
print('error_L2  =', error_L2)

which may be more robust to floating point precision issues, although, anecdotally, I’ve never run into problems checking convergence by just using assemble on the definition of the error.

Thanks for your time. I want to know that why I didn’t get the same image as they given in demo_biharmonic. Kindly help me regarding the same.