L2 norm of Poisson equation with u as vector function

Dear Sir/Mam,
when i am trying to find out L2 norm of the error, the error increases as finer the mesh. for example, when ‘mesh = UnitSquareMesh(4,4)’ error_L2 = 0.0956198463430736, when ‘mesh = UnitSquareMesh(16,16)’ error_L2 = 0.1695765431464665.

when we are going to finer and finer mesh , the error should decreases, and the order of convergence should 2. But here error increases.

Kindly clarify the issues .
waiting for positive response!

the code is given below

from future import print_function
from fenics import *
mesh = UnitSquareMesh(8,8 )
V = VectorFunctionSpace(mesh, ‘P’, 1)
u_D = Expression(('1 + x[0]*x[0]+x[1]*x[1] ', ‘1 + x[1]x[0] + 2x[1]’), degree=2)
bc=DirichletBC(V,u_D,“on_boundary &&
(x[0] < DOLFIN_EPS | x[1] < DOLFIN_EPS |
(x[0] > 0.5 - DOLFIN_EPS && x[1] > 0.5 - DOLFIN_EPS))”)
bcu=[bc]

Define variational problem

u = TrialFunction(V)
v = TestFunction(V)
f = Constant((-5,0))
#F = inner(grad(u),grad(v))*dx-inner(f,v)*dx
a=inner(grad(u),grad(v))*dx
b=inner(f,v)*dx
#g = inner(f,v)*dx
u=Function(V)
#f=Function(V)
solve(a==b, u, bcu)
error_L2 = errornorm(u_D, u, ‘L2’)
print(‘error_L2 =’, error_L2)

Dear @Debendra,
Please format your code using 3x` encapsulation, such that it keeps the appropriate formatting of the code.

1 Like

Dear @dokken,

kindly see the code.

from __future__ import print_function
from fenics import *
mesh = UnitSquareMesh(16,16)
V = VectorFunctionSpace(mesh, 'P', 1)
u_D = Expression(('1 + x[0]*x[0]+x[1]*x[1] ', '1 + x[1]*x[0] + 2*x[1]'), degree=2)
bc=DirichletBC(V,u_D, "on_boundary && \
                        (x[0] < DOLFIN_EPS | x[1] < DOLFIN_EPS | \
                        (x[0] > 0.5 - DOLFIN_EPS && x[1] > 0.5 - DOLFIN_EPS))")        
bcu=[bc]
# Define variational problem
u = TrialFunction(V)
v = TestFunction(V)
f = Constant((-5,0))
#F = inner(grad(u),grad(v))*dx-inner(f,v)*dx
a=inner(grad(u),grad(v))*dx
b=inner(f,v)*dx
#g = inner(f,v)*dx
u=Function(V)
#f=Function(V)
solve(a==b, u, bcu)
error_L2 = errornorm(u_D, u, 'L2')
print('error_L2 =', error_L2)

There are two issues with your code:

  1. You apply the Dirichlet condition on a subset of the boundary.

If you do this, you need to apply the corresponding Neumann condition on the remaining boundary.

  1. Your source funciton is wrong, it should be f = Constant((-4, 0)).

If you fix these two things, you obtain:

from fenics import *

def poisson(N):
    mesh = UnitSquareMesh(N, N)
    V = VectorFunctionSpace(mesh, 'P', 1)
    u_D = Expression(('1 + x[0]*x[0]+x[1]*x[1] ', '1 + x[1]*x[0] + 2*x[1]'), degree=2)
    bc=DirichletBC(V,u_D, "on_boundary")        
    bcu=[bc]
    # Define variational problem
    u = TrialFunction(V)
    v = TestFunction(V)
    f = Constant((-4,0))
    a=inner(grad(u),grad(v))*dx
    b=inner(f,v)*dx
    u=Function(V)

    solve(a==b, u, bcu)
    error_L2 = errornorm(u_D, u, 'L2')
    return error_L2

for N in [8, 16, 32]:
    print("{0:d} error_L2 ={1:.2e}".format(N, poisson(N)))

and the output:

8 error_L2 =5.71e-03
16 error_L2 =1.43e-03
32 error_L2 =3.57e-04
1 Like

Dear @dokken ,
I want to apply dirichlet condition on whole Boundary.
will it work for

V = VectorFunctionSpace(mesh, 'P', 2)
def poisson(N):
    mesh = UnitSquareMesh(N, N)
    V = VectorFunctionSpace(mesh, 'P', 2)
    u_D = Expression(('1 + x[0]*x[0]+x[1]*x[1] ', '1 + x[1]*x[0] + 2*x[1]'), degree=2)
    bc=DirichletBC(V,u_D, "on_boundary")        
    bcu=[bc]
    # Define variational problem
    u = TrialFunction(V)
    v = TestFunction(V)
    f = Constant((-4,0))
    a=inner(grad(u),grad(v))*dx
    b=inner(f,v)*dx
    u=Function(V)

    solve(a==b, u, bcu)
    error_L2 = errornorm(u_D, u, 'L2')
    return error_L2
for N in [2, 4, 8 ]:
    print("{0:d} error_L2 ={1:.2e}".format(N, poisson(N)))
2 error_L2 =2.60e-15
4 error_L2 =2.29e-15
8 error_L2 =2.55e-15

still the error is not decreasing. I am using python.
Thanks ,
Debendra

This is because you have changed your function space to a space containing the solution, and therefore your error is of machine precision (1e-15).

1 Like

Dear @dokken ,

What should be the necessary changes for finding out the L2 order of convergence to the above problem?

Thanks,
Debendra

Your analytical solution (1 + x^2 + y^2, 1 + y x + 2 y)^\top is exactly representable by a second order (or higher) polynomial approximation. So as @dokken states, your error is machine precision.

If you want to examine convergence rates for higher order polynomials, you need to design a solution which is not exactly representable by a (Lagrange) polynomial approximation.

1 Like

Thanks
for the suggestion.

Dear @dokken ,

Could you Please tell me , How to plot 3d- diagram of u_1 and u_2 ,
where , u=(u_1, u_2) in paraview. Similarly for u_D1, u_D2, where u_D= Expression((‘u_D1’, ‘u_D1’), degree=2) in paraview.
It is possible to plot 3d diagram of u when it is a scalar problem, Issues are having when u as a solution of vector problem.

    from __future__ import print_function
    from fenics import *
    import numpy as np

    mesh = UnitSquareMesh(8, 8)
    V = VectorFunctionSpace(mesh, 'P', 2)
    u_D = Expression(('1 + x[0]*x[0]+x[1]*x[1] ', '1 + x[1]*x[0] + 2*x[1]'), degree=2)
    bc=DirichletBC(V,u_D, "on_boundary")        
    bcu=[bc]
    # Define variational problem
    u = TrialFunction(V)
    v = TestFunction(V)
    f = Constant((-4,0))
    a=inner(grad(u),grad(v))*dx
    b=inner(f,v)*dx
    u=Function(V)

    solve(a==b, u, bcu)
    (u_1,u_2)=u.split(True)
    u_1file_pvd=File("u_1.pvd")
    u_1file_pvd << u_1

What do you imply when you are saying a 3D diagram?

To plot an expression you need to project it into an appropriate function space, and save the result as pvd.

Dear @dokken ,
From the previous problem u is vector function not a scalar function , when u is a scalar function , i can save as .pvd, then it is possible to plot its 3d-figure in paraview, when u is vector function containing two components say u1 and u2 as u=(u1,u2) then it is not possible to plot it’s 3d-figure.
I have to plot u1 and u2 separately. How is it possible?

As you are not specifying what kind of 3D plot (i.e. what filters do you want to use, I cannot really help you any further.
Simply running:

from fenics import *
import numpy as np

mesh = UnitSquareMesh(8, 8)
V = VectorFunctionSpace(mesh, 'P', 2)
u_D = Expression(('1 + x[0]*x[0]+x[1]*x[1] ', '1 + x[1]*x[0] + 2*x[1]'), degree=2)
bc=DirichletBC(V,u_D, "on_boundary")        
bcu=[bc]
# Define variational problem
u = TrialFunction(V)
v = TestFunction(V)
f = Constant((-4,0))
a=inner(grad(u),grad(v))*dx
b=inner(f,v)*dx
u=Function(V)

solve(a==b, u, bcu)
File("u.pvd") << u

you can select each component in Paraview as shown in:


Dear @dokken,

    from __future__ import print_function
    from fenics import *
    import numpy as np

    mesh = UnitSquareMesh(8, 8)
    V = VectorFunctionSpace(mesh, 'P', 2)
    u_D = Expression(('1 + x[0]*x[0]+x[1]*x[1] ', '1 + x[1]*x[0] + 2*x[1]'), degree=2)
    bc=DirichletBC(V,u_D, "on_boundary")        
    bcu=[bc]
    # Define variational problem
    u = TrialFunction(V)
    v = TestFunction(V)
    f = Constant((-4,0))
    a=inner(grad(u),grad(v))*dx
    b=inner(f,v)*dx
    u=Function(V)

    solve(a==b, u, bcu)
    File("sol.pvd")<< u

i am using Filters - Alphabetical - Wrap by vector to show the 3D instead of 2D.
But it is not showing .

when click on 3D botton followed by Filters - Alphabetical - Wrap by vector ,
it is not showing the figure.

Warp by vector and warp by scalar are two very different functions.
Warp by scalar warps a function from 2D to 3D. Warp by vector warps a function from 2D to 2D (as seen in your figures). You need to carefully think about how you would like to warp your vector function, as it does not make sense to warp it into 3D.

Dear @dokken ,
Please see this for one component u1 , u=(u1, u2)

    from __future__ import print_function
    from fenics import *
    import numpy as np

    mesh = UnitSquareMesh(8, 8)
    V = VectorFunctionSpace(mesh, 'P', 2)
    u_D = Expression(('1 + x[0]*x[0]+x[1]*x[1] ', '1 + x[1]*x[0] + 2*x[1]'), degree=2)
    bc=DirichletBC(V,u_D, "on_boundary")        
    bcu=[bc]
    # Define variational problem
    u = TrialFunction(V)
    v = TestFunction(V)
    f = Constant((-4,0))
    a=inner(grad(u),grad(v))*dx
    b=inner(f,v)*dx
    u=Function(V)

    solve(a==b, u, bcu)
    File("sol.pvd")<< u
    (u1, u2)=u.split(True)
    File("soln.pvd")<< u1
    


And for plotting u_D, in in paraview.

ue=interpolate(u_D, V)
File("ue.pvd") << ue

But such a plot for a vector function does not make sense (at it has both an x and a y component) How do you want to warp the vector?

If you want to warp the domain by the magnitude of the vector, you can do it by choosing
Filters->Calculator and insert
sqrt(f_8.f_8) (if f_8 is the name of the vector field (this can be looked up in the Vectors part of the calculator). Press apply and use the Warp by scalar filter on the result.