How to apply strain field from one mesh to another?

Hello,

I am trying to apply the strain field from a previous mesh to a new mesh. I am currently trying:

du = TrialFunction(rand_V)
u_ = project(eps(u), rand_V)

where u is the Function of my previous VectorFunctionSpace, eps() is the function to calculate the strain, and rand_V is my new VectorFunctionSpace. Both meshes are the same domain, with the difference being that my previous one contained some subdomains. The error I am getting is that the shapes are different:

Shapes do not match: and .

I do not understand why the shapes would be different/how to fix it. Thanks in advance!

Please make a reproducible example

This is the initial problem:

def TopBoundary(x, on_boundary):
        return on_boundary and near(x[1],10) and x[0]<7.5 and x[0]>2.5

def BottomBoundary(x, on_boundary):
     return on_boundary and near(x[1], 0)
    
class Subdomain1(SubDomain):
    r = 2
    center = (6, 6)
    def inside(self, x, on_boundary):
        return (x[0] - self.center[0]) ** 2 + (x[1] - self.center[1]) ** 2 <= self.r ** 2


class Subdomain2(SubDomain):
    r = 1
    center = (3, 2)
    def inside(self, x, on_boundary):
        return (x[0] - self.center[0]) ** 2 + (x[1] - self.center[1]) ** 2 <= self.r ** 2
    
class Subdomain3(SubDomain):
    r = 0.5
    center = (8, 3)
    def inside(self, x, on_boundary):
        return (x[0] - self.center[0]) ** 2 + (x[1] - self.center[1]) ** 2 <= self.r ** 2

domain = Rectangle(Point(0, 0), Point(10, 10))
subdomain = Subdomain1()
subdomain2 = Subdomain2()
subdomain3 = Subdomain3()


mesh = generate_mesh(domain, 64)
subdomains = MeshFunction("size_t", mesh, mesh.topology().dim())
subdomains.set_all(1)
subdomain.mark(subdomains, 0)
subdomain2.mark(subdomains, 0)
subdomain3.mark(subdomains, 0)

V0 = FunctionSpace(mesh, "DG", 0)
k = Function(V0)


square_G = 1e4 
circle_G = 1e3
G_vals = [circle_G, square_G]

# Create the function space for the material function
# material_space = FunctionSpace(mesh, "DG", 0)
# material = Function(material_space)  # Material function
for cell in (cells(mesh)):
    subdomain_no = subdomains[cell.index()]
    k.vector()[cell.index()] = G_vals[subdomain_no]



nu = 0.3

mu = k
lmbda = 2*k*nu/(1-2*nu)

def eps(v):
     return sym(grad(v))

def sigma(v):
    return lmbda*tr(sym(grad(v)))*Identity(2) + 2.0*mu*sym(grad(v))

V = VectorFunctionSpace(mesh, 'CG', 1)



# Define subdomain markers and integration measure
boundaries = MeshFunction("size_t", mesh, mesh.topology().dim() - 1)
AutoSubDomain(TopBoundary).mark(boundaries, 1)
ds = Measure('ds', domain=mesh, subdomain_data=boundaries, subdomain_id=True)

# Define boundary condition
bc2 = DirichletBC(V, Constant((0, 0)), BottomBoundary)

du = TrialFunction(V)
u_ = TestFunction(V)
a = inner(sigma(du), sym(grad(u_)))*dx
l = dot(Constant((0, -500)), u_)*ds(1)

# Solve the problem with the boundary condition
u = Function(V, name="Displacement")
solve(a==l, u, bc2)

I now want to apply the strain field from that Function to a new mesh:

rand_mesh = generate_mesh(domain, 64)
rand_V0 = FunctionSpace(rand_mesh, "DG", 0)
rand_k = Function(rand_V0)

new_square_G = 1e5  # Young's modulus
new_circle_G = 1e2
new_G_vals = [new_circle_G, new_square_G]

# code for random initialization
for cell in (cells(rand_mesh)):
    subdomain_no = random.randint(0, 1)
    rand_k.vector()[cell.index()] = new_G_vals[subdomain_no]


rand_V = VectorFunctionSpace(rand_mesh, 'CG', 1)
rand_boundaries = MeshFunction("size_t", rand_mesh, rand_mesh.topology().dim() - 1)
AutoSubDomain(TopBoundary).mark(rand_boundaries, 1)
rand_ds = Measure('ds', domain=rand_mesh, subdomain_data=rand_boundaries, subdomain_id=True)

# Define boundary condition
rand_bc2 = DirichletBC(rand_V, Constant((0, 0)), BottomBoundary)

du = TrialFunction(rand_V)
u_ = project(eps(u), rand_V)
a = inner(sigma(du), u_)*dx
l = dot(Constant((0, -500)), u_)*rand_ds(1)

Please include all import statements and state what version of legacy dolfin you are running.

Sorry,

here are my import statements:

from fenics import *
from mshr import *
import numpy as np
import matplotlib.pyplot as plt
from dolfin import *
import random

The version of dolfin I am running is 2019.2.0.dev0

eps(u) is a tensor, so you need to use a TensorFunctionSpace, not

I’m not really sure what you try to do at the end of your code:

The following runs nicely:

rand_V = TensorFunctionSpace(rand_mesh, 'CG', 1)
rand_boundaries = MeshFunction(
    "size_t", rand_mesh, rand_mesh.topology().dim() - 1)
AutoSubDomain(TopBoundary).mark(rand_boundaries, 1)
rand_ds = Measure('ds', domain=rand_mesh,
                  subdomain_data=rand_boundaries, subdomain_id=1)

# Define boundary condition
rand_bc2 = DirichletBC(rand_V, Constant(((0, 0), (0, 0))), BottomBoundary)
u_ = project(eps(u), rand_V)