Using method of manufactured solutions to verify my code for Darcy flow though a unit square

Hi Everyone,

I am stuck trying to verify my code for implementing Darcy’s flow though a unit square.

The 2 equations for this flow are: u_bar = -K * grad p and div (u_bar) = 0;

Given: K = max(0.10, exp(-pow(10y-1.0sin(10*x)-5.0, 2)) * I. Where I is an identity matrix, u_bar represents velocity, p represents pressure and the flow uses pressure boundary conditions with p = 1 at x = 0 and p = 0 at x = 1.

Now using the method of manufactured solutions, I selected the analytical expression for pressure to be p = 1 - x^2.

I have tried to solve it on FEniCS with no success. Please see the code below and let me know where I got it wrong and what I should add to make it run successfully:

from fenics import *
import numpy as np
from ufl import nabla_div

Creating mesh and defining function space

mesh = UnitSquareMesh(24, 24)
V = FunctionSpace(mesh, ‘P’, 1)

Defining Exact Solution for Pressure Distribution

p_e = Expression(‘1 - x[0]*x[0]’, degree=2)

Defining Dirichlet boundary

p_L = Constant(1.0)

def boundary_L(x, on_boundary):
return on_boundary and near(x[0], 0)

bc_L = DirichletBC(V, p_L, boundary_L)

p_R = Constant(0.0)

def boundary_R(x, on_boundary):
return on_boundary and near(x[0], 1)

bc_R = DirichletBC(V, p_R, boundary_R)

bcs = [bc_L, bc_R]

Defining variational problem

p = TrialFunction(V)
v = TestFunction(V)
d = 2
I = Identity(d)
M = Expression(‘fmax(0.10, exp(-pow(10x[1]-1.0sin(10*x[0])-5.0, 2)))’, degree=2)
K = M * I
a = dot(K * grad p , grad(v))dx
f1 = Expression(’(-2
x[0], 0)’, degree=1)
f = nabla_div(-K * interpolate(f1, V))
L = inner(f, v)*dx

Computing solutions

p = Function(V)
solve(a == L, p, bcs)

p_e_f = interpolate(p_e, V)
diff_p = Function(V)
diff_p.vector()[:] = p.vector() - p_e_f.vector()

Saving Solution in VTK format

file = File(‘Pressure_Gradient.pvd’)
file << p
File(‘diff_p.pvd’) << diff_p

The error message is:
Shapes do not match: and .
Traceback (most recent call last):
File “Numerical_Exact.py”, line 43, in
L = inner(f, v)*dx
File “/usr/lib/python3/dist-packages/ufl/operators.py”, line 144, in inner
return Inner(a, b)
File “/usr/lib/python3/dist-packages/ufl/tensoralgebra.py”, line 161, in new
error(“Shapes do not match: %s and %s.” % (ufl_err_str(a), ufl_err_str(b)))
File “/usr/lib/python3/dist-packages/ufl/log.py”, line 172, in error
raise self._exception_type(self._format_raw(*message))
ufl.log.UFLException: Shapes do not match: NablaDiv id=140429426823800> and <Argument id=140429427152376.

You are defining f_1 wrongly; for vector valued expression you need to specify a tuple
of strings that are the components. While the expression compiles it ends up being scalar valued, c.f. it can be interpolated in V. Consider

x, y = SpatialCoordinate(mesh)
f1 = as_vector((-2*x, 0))
f = nabla_div(-K * f1)

Hi MiroK,

Thank you for the response. I tried your suggestion but it returned the error below:

Calling FFC just-in-time (JIT) compiler, this may take some time.
Cannot determine geometric dimension from expression.
Traceback (most recent call last):
File “Numerical_Exact.py”, line 52, in
solve(a == L, p, bcs)
File “/usr/lib/python3/dist-packages/dolfin/fem/solving.py”, line 220, in solve
_solve_varproblem(*args, **kwargs)
File “/usr/lib/python3/dist-packages/dolfin/fem/solving.py”, line 242, in _solve_varproblem
form_compiler_parameters=form_compiler_parameters)
File “/usr/lib/python3/dist-packages/dolfin/fem/problem.py”, line 55, in init
L = Form(L, form_compiler_parameters=form_compiler_parameters)
File “/usr/lib/python3/dist-packages/dolfin/fem/form.py”, line 45, in init
mpi_comm=mesh.mpi_comm())
File “/usr/lib/python3/dist-packages/dolfin/jit/jit.py”, line 47, in mpi_jit
return local_jit(*args, **kwargs)
File “/usr/lib/python3/dist-packages/dolfin/jit/jit.py”, line 97, in ffc_jit
return ffc.jit(ufl_form, parameters=p)
File “/usr/lib/python3/dist-packages/ffc/jitcompiler.py”, line 217, in jit
module = jit_build(ufl_object, module_name, parameters)
File “/usr/lib/python3/dist-packages/ffc/jitcompiler.py”, line 133, in jit_build
generate=jit_generate)
File “/usr/lib/python3/dist-packages/dijitso/jit.py”, line 165, in jit
header, source, dependencies = generate(jitable, name, signature, params[“generator”])
File “/usr/lib/python3/dist-packages/ffc/jitcompiler.py”, line 66, in jit_generate
prefix=module_name, parameters=parameters, jit=True)
File “/usr/lib/python3/dist-packages/ffc/compiler.py”, line 143, in compile_form
prefix, parameters, jit)
File “/usr/lib/python3/dist-packages/ffc/compiler.py”, line 185, in compile_ufl_objects
analysis = analyze_ufl_objects(ufl_objects, kind, parameters)
File “/usr/lib/python3/dist-packages/ffc/analysis.py”, line 90, in analyze_ufl_objects
for form in forms)
File “/usr/lib/python3/dist-packages/ffc/analysis.py”, line 90, in
for form in forms)
File “/usr/lib/python3/dist-packages/ffc/analysis.py”, line 174, in _analyze_form
do_apply_restrictions=True)
File “/usr/lib/python3/dist-packages/ufl/algorithms/compute_form_data.py”, line 260, in compute_form_data
form = apply_derivatives(form)
File “/usr/lib/python3/dist-packages/ufl/algorithms/apply_derivatives.py”, line 1074, in apply_derivatives
return map_integrand_dags(rules, expression)
File “/usr/lib/python3/dist-packages/ufl/algorithms/map_integrands.py”, line 58, in map_integrand_dags
form, only_integral_type)
File “/usr/lib/python3/dist-packages/ufl/algorithms/map_integrands.py”, line 39, in map_integrands
for itg in form.integrals()]
File “/usr/lib/python3/dist-packages/ufl/algorithms/map_integrands.py”, line 39, in
for itg in form.integrals()]
File “/usr/lib/python3/dist-packages/ufl/algorithms/map_integrands.py”, line 46, in map_integrands
return itg.reconstruct(function(itg.integrand()))
File “/usr/lib/python3/dist-packages/ufl/algorithms/map_integrands.py”, line 57, in
return map_integrands(lambda expr: map_expr_dag(function, expr, compress),
File “/usr/lib/python3/dist-packages/ufl/corealg/map_dag.py”, line 37, in map_expr_dag
result, = map_expr_dags(function, [expression], compress=compress)
File “/usr/lib/python3/dist-packages/ufl/corealg/map_dag.py”, line 86, in map_expr_dags
r = handlers[v.ufl_typecode](v, *[vcache[u] for u in v.ufl_operands])
File “/usr/lib/python3/dist-packages/ufl/algorithms/apply_derivatives.py”, line 1027, in grad
return map_expr_dag(rules, f)
File “/usr/lib/python3/dist-packages/ufl/corealg/map_dag.py”, line 37, in map_expr_dag
result, = map_expr_dags(function, [expression], compress=compress)
File “/usr/lib/python3/dist-packages/ufl/corealg/map_dag.py”, line 84, in map_expr_dags
r = handlersv.ufl_typecode
File “/usr/lib/python3/dist-packages/ufl/algorithms/apply_derivatives.py”, line 522, in coefficient
return Grad(o)
File “/usr/lib/python3/dist-packages/ufl/differentiation.py”, line 147, in init
self._dim = find_geometric_dimension(f)
File “/usr/lib/python3/dist-packages/ufl/domain.py”, line 380, in find_geometric_dimension
error(“Cannot determine geometric dimension from expression.”)
File “/usr/lib/python3/dist-packages/ufl/log.py”, line 172, in error
raise self._exception_type(self._format_raw(*message))
ufl.log.UFLException: Cannot determine geometric dimension from expression.

Please post a formatted code which resulted in the error.

Ok, see the code below:

from fenics import *
import numpy as np
from ufl import nabla_div

# Creating mesh and defining function space
mesh = UnitSquareMesh(4, 4)
V = FunctionSpace(mesh, 'P', 1)

# Defining Exact Solution for Pressure Distribution
p_e = Expression('1 - x[0]*x[0]', degree=2)

# Defining Dirichlet boundary
p_L = Constant(1.0)

def boundary_L(x, on_boundary):
    return on_boundary and near(x[0], 0)

bc_L = DirichletBC(V, p_L, boundary_L)

p_R = Constant(0.0)

def boundary_R(x, on_boundary):
    return on_boundary and near(x[0], 1)

bc_R = DirichletBC(V, p_R, boundary_R)

bcs = [bc_L, bc_R]

# Defining variational problem
p = TrialFunction(V)
v = TestFunction(V)
d = 2
I = Identity(d)
M = Expression('fmax(0.10, exp(-pow(10.0*x[1]-1.0*sin(10*x[0])-5.0, 2)))', degree=2)
K = M*I
a = dot(K*grad(p), grad(v))*dx
x, y = SpatialCoordinate(mesh)
f1 = as_vector((-2*x, 0))
f = nabla_div(-K * f1)
L = inner(f, v)*dx

# Computing solutions
p = Function(V)
solve(a == L, p, bcs)

p_e_f = interpolate(p_e, V)
diff_p = Function(V)
diff_p.vector()[:] = p.vector() - p_e_f.vector()

# Saving Solution in VTK format
file = File('Pressure_Gradient.pvd')
file << p
File('diff_p.pvd') << diff_p

You need to provide element or similar to M expression for the geometric dimension of nabla_div(K*f1) to be determined. An alternative is to define M using UFL

from ufl import nabla_div, max_value

d = 2
I = Identity(d)
x, y = SpatialCoordinate(mesh)

M = max_value(Constant(0.10),
              exp(-(10.0*y-1.0*sin(10*x)-5.0)**2))

K = M*I
a = dot(K*grad(p), grad(v))*dx
f1 = as_vector((-2*x, 0))
f = nabla_div(dot(K, f1))

Hi MiroK,

I applied the suggestions you offered and it worked. Thank you so much. Your help is much appreciated.