This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

How to interpolate function (rank 0) into vector function space (rank 1)

0 votes

Problem

Hi guys, I'm stuck.
I'm new in FEniCS and unfortunately I have no idea how to solve this error message on my code. May anybody please help me?

Error message

Error: Unable to interpolate function into function space.
Reason: Rank of function (0) does not match rank of function space (1).
Where: This error was encountered inside FunctionSpace.cpp.
Process: 0

DOLFIN version: 2016.1.0
Git changeset: f4e22e59622b42182d16059f0212ddb1c6aa8712

Code

from dolfin import *

parameters["form_compiler"]["cpp_optimize"] = True
params={"optimize":True, "eliminate_zeros":True,
"precompute_basis_const":True, "precompute_ip_const":True}

! /usr/bin/env python

-- coding: utf-8 --

T = 2.0
num_steps = 50
dt = T / num_steps

Define geometry and mesh

p = Point(0.0, 0.0, 0.0)
q = Point(2.0, 1.0, 1.0)
mesh = BoxMesh(p, q, 12, 8, 8)

Define boundaries

class Side(SubDomain):
def init(self, dim, val):
SubDomain.init(self)
self.dim = dim
self.val = val
def inside(self, x, on_boundary):
return near(x[self.dim], self.val) and on_boundary
boundaries = FacetFunction("size_t", mesh)
boundaries.set_all(0)
left, right, bottom, top = 1, 2, 3, 4
Side(0, p[0]).mark(boundaries, left)
Side(0, q[0]).mark(boundaries, right)
Side(1, p[1]).mark(boundaries, bottom)
Side(1, q[1]).mark(boundaries, top)

Surface integral element

ds = Measure('ds', domain=mesh, subdomain_data=boundaries)

Define function space

V_u = VectorFunctionSpace(mesh, "Lagrange", 1)

Define functions

u = TrialFunction(V_u)
delta_u = TestFunction(V_u)

Define initial value

t = 0
u_0 = Expression("1 + x[0]x[0] + 3.0x[1]x[1] + 1.2t", degree=2, t=0)
u_n = interpolate(u_0, V_u)

Volume force and prescribed tractions

b = Constant((0.0, 0.0, 0.0))
t_p = Constant((0.0, 0.0, 0.0))

Dirichlet boundary conditions

bcs = [DirichletBC(V_u, Constant((0.0, 0.0, 0.0)), boundaries, left),
DirichletBC(V_u, Constant((0.0, 0.0, 0.0)), boundaries, right)]

Material parameters

E = 10.0
nu = 0.3
mu = E/(2.0(1.0 + nu))
lmbda = E
nu/((1.0 + nu)(1.0 - 2.0nu))
roh = 3.5
v_0 = 0.0

Stress tensor (linear isotropic elasticity)

def sigma(u):
return lmbdatr(sym(grad(u)))Identity(3) + 2.0musym(grad(u))

Weak form a==l

a = dtdtinner(grad(delta_u), sigma(u))dx + rohinner(delta_u, u)dx
l = dt
dtinner(b, delta_u)dx + dtdtinner(t_p, delta_u)ds(top) + rohinner(delta_u, u_n)dx + dtrohinner(delta_u, v_0)dx

Time-stepping

u = Function(V_u)
t = 0
for n in range(num_steps):
t += dt
solve(a == l, u, bcs)
u_n.assign(u)

Create .pvd-file

File("mechanicaldynamic_displacement.pvd", "compressed") << u

asked Jan 12, 2017 by Ulla FEniCS Novice (210 points)

1 Answer

0 votes
 
Best answer

Hi, you defined V_n as a space of vector valued functions while in

u_0 = Expression("1 + x[0]x[0] + 3.0x[1]x[1] + 1.2t", degree=2, t=0)
u_n = interpolate(u_0, V_u)

your are trying to interpolate scalar u_0 to it. One solution is thus to make u_0 a vector valued expression, e.g.

u_0 = Expression(('x[0]', 'x[1]', 'x[2]'), degree=1)
answered Jan 13, 2017 by MiroK FEniCS Expert (80,920 points)
selected Jan 16, 2017 by Ulla

Hi MiroK,

thanks a lot for your quick answer!!
It works now.

...