Using Constant or float for scalar constant

Dear all,
In fenics, we can use Constant for a scalar constant, for example f=Constant(-6.0), and alternatively we can use float for a scalar constant, for example f=-6.0. I wonder what’s the difference between these two usages? Below is the Poisson problem code from fenics tutorial. I changed the f = Constant(-6.0) to f = -6.0, and the result didn’t change. So what’s the meaning of using Constant for a scalar constant? We can just simply use float type for a scalar constant, like this: f = -6.0.
My second question is are the Constant((0, 1)) and as_vector([0, 1]) the same?

I appreciate any help. Thank you very much in advance.

from __future__ import print_function
from fenics import *
import matplotlib.pyplot as plt

# Create mesh and define function space
mesh = UnitSquareMesh(8, 8)
V = FunctionSpace(mesh, 'P', 1)

# Define boundary condition
u_D = Expression('1 + x[0]*x[0] + 2*x[1]*x[1]', degree=2)

def boundary(x, on_boundary):
    return on_boundary

bc = DirichletBC(V, u_D, boundary)

# Define variational problem
u = TrialFunction(V)
v = TestFunction(V)

#test Constant and float
# f = Constant(-6.0)
f = -6.0

a = dot(grad(u), grad(v))*dx
L = f*v*dx

# Compute solution
u = Function(V)
solve(a == L, u, bc)

# Plot solution and mesh
plot(u)
plot(mesh)

# Save solution to file in VTK format
vtkfile = File('poisson/solution.pvd')
vtkfile << u

# Compute error in L2 norm
error_L2 = errornorm(u_D, u, 'L2')

# Compute maximum error at vertices
vertex_values_u_D = u_D.compute_vertex_values(mesh)
vertex_values_u = u.compute_vertex_values(mesh)
import numpy as np
error_max = np.max(np.abs(vertex_values_u_D - vertex_values_u))

# Print errors
print('error_L2  =', error_L2)
print('error_max =', error_max)

# Hold plot
plt.show()

You could, but if one day you decide that your f must change to -6.1, the form compiler will recompile the form from scratch. By using Constant you are informing the form compiler that the value of f is a constant (regardless of its actual value), and you’ll be allowed to change it in future without triggering a recompilation.

1 Like

I understand now. Thank you for your reply. Besides, I wonder if Constant((0, 1)) and as_vector([0, 1]) the same. :slightly_smiling_face:

They are not

>>> import ufl
>>> ufl.as_vector([0, 1])
ListTensor(Zero((), (), ()), IntValue(1))

Got it. Thank you. But if we want to define a constant vector (0, 1) in fenics, which one is better?

I’d say Constant, especially if you plan to change those entries in the future.

1 Like