How to avoid large rigid translations?

Hi,

I am working on the following code which is very similar to Stokes problem here.. However, in here div(u) = 1. What I don’t understand is why the region has to go through such a large displacement and then grow. How can I exclude the rigid movement?

from dolfin import *

# Test for PETSc or Tpetra
if not has_linear_algebra_backend("PETSc") and not has_linear_algebra_backend("Tpetra"):
    info("DOLFIN has not been configured with Trilinos or PETSc. Exiting.")
    exit()

if not has_krylov_solver_preconditioner("amg"):
    info("Sorry, this demo is only available when DOLFIN is compiled with AMG "
         "preconditioner, Hypre or ML.")
    exit()

if has_krylov_solver_method("minres"):
    krylov_method = "minres"
elif has_krylov_solver_method("tfqmr"):
    krylov_method = "tfqmr"
else:
    info("Default linear algebra backend was not compiled with MINRES or TFQMR "
         "Krylov subspace method. Terminating.")
    exit()
meshlevel =10
degree = 1
dim = 2
mesh = UnitDiscMesh.create(MPI.comm_world, meshlevel, degree, dim)
###############################################################
# Build function space
P2 = VectorElement("Lagrange", mesh.ufl_cell(), 2)
P1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1)
TH = P2 * P1
W = FunctionSpace(mesh, TH)
Q = FunctionSpace(mesh,'P',2)
t=0.0
# Define variational problem
(u, p) = TrialFunctions(W)
(v, q) = TestFunctions(W)
f = Constant((0.0, 0.0))
a = inner(grad(u), grad(v))*dx+inner(grad(u).T, grad(v))*dx + div(v)*p*dx + q*div(u)*dx
L = inner(f, v)*dx+1*q*dx
b = inner(grad(u), grad(v))*dx + p*q*dx
A, bb = assemble_system(a, L, [])
P, btmp = assemble_system(b, L, [])
solver = KrylovSolver(krylov_method, "amg")

solver.set_operators(A, P)
U = Function(W)
ufile_pvd = File("test/mesh.pvd")
for n in range(4):

    solver.solve(U.vector(), bb)
    u, p = U.split()
    ALE.move(mesh,u)

    ufile_pvd<< (mesh,t)
    t+=0.1
    print(t,flush=True)

I tried to define a boundary condition at (0,0) to pin the displacement as follows:

def origin(x,on_boundary):
    return x[0] < DOLFIN_EPS and x[1] < DOLFIN_EPS
bc = DirichletBC(W.sub(0), Constant((0.0,0.0)), origin, 'pointwise')

But with this the code doesn’t converge. I really appreciate if you can help me fix this.

I figured it out. If you are interested here was the fix and was rather weird:

def origin(x,on_boundary):
    return abs(x[0]-0.0) < DOLFIN_EPS and abs(x[1] -0.0)< DOLFIN_EPS
bc = DirichletBC(W.sub(0), Constant((0.0,0.0)), origin, 'pointwise')