Hi, the first problem with your code is that the vector b
is zero (check print b.norm("l2")
once the vector is assembled). This is probably because the conditions for facets to be marked as one or two are never met. You can see that even after you have marked the boundary_parts
, all the facet values are still zero. I will let you figure this out and move to the more serious problem of your code. The system as you assemble it is singular. The matrix has 6 zero eigenvalues and any solution is only determined up to the 3 translations and 3 rotations that are the eigenvectors of the zero eigenvalues. To fix this lack of
uniqueness consider
from mshr import Sphere, generate_mesh
from dolfin import *
# Radius of outer and inner sphere
oradius, iradius = 5., 1.
tol = 1e-3
#Material parameters
nu = 0.3
mu = 1.0
Young = 2.*mu*(1.+nu)
lmbda = 2.*mu*nu/(1.-2.*nu)
# Geometry
outer_sphere = Sphere(Point(0., 0., 0.), oradius)
inner_sphere = Sphere(Point(0., 0., 0.), iradius)
g3d = outer_sphere - inner_sphere
mesh = generate_mesh(g3d, 8)
#Function Space
VV = VectorFunctionSpace(mesh, "Lagrange", 1, 3) # displacement space
Q = VectorFunctionSpace(mesh, 'R', 0, 6)
W = MixedFunctionSpace([VV, Q])
u, p = TrialFunctions(W)
v, q = TestFunctions(W)
eps_u = sym(grad(u))
eps_v = sym(grad(v))
sig_u = lmbda*tr(eps_u)*Identity(3) + 2.*mu*eps_u
t = Constant((1, 1, 1))
# Nullspace of rigid motions
# Translation
Z_transl = [Constant((1, 0, 0)), Constant((0, 1, 0)), Constant((0, 0, 1))]
# Rotations
Z_rot = [Expression(('0', 'x[2]', '-x[1]')),
Expression(('-x[2]', '0', 'x[0]')),
Expression(('x[1]', '-x[0]', '0'))]
# All
Z = Z_transl + Z_rot
a = inner(sig_u, eps_v)*dx\
-sum(p[i]*inner(v, Z[i])*dx for i in range(len(Z)))\
-sum(q[i]*inner(u, Z[i])*dx for i in range(len(Z)))
L = inner(t, v)*ds
w_h = Function(W)
A, b = assemble_system(a, L)
print b.norm('l2')
solve(A, w_h.vector(), b, 'lu')
uh, ph = w_h.split(deepcopy=True)
plot(uh, mode = "displacement", interactive=True, wire_frame=True, axes=True,rescale=False,scalarbar=True)
Here 6 Lagrange multipliers are introduced to enforce orthogonality of the unique solution with respect to the given nullspace (Z
) formed by the rigid motions. If you do not like the multiplier approach you can pass the nullspace as 6 $l^2$-orthogonal vectors to the Krylov method, see here for how this is done for singular Poisson problem. Let me know if you have troubles making it work. Also, please tag the question with singular elasticity tag.