Say I want two sub domains and a different function to be interpolated in each of these. I want the functions to be solved in the same manner as one of my previous questions "interpolating vector function from python code to fenics". Basically, I want to extract the dofs of each sub domain and compute the expressions in python code, then I want to port these back into the global domain. have attached a code that is as short as I can make it where I try to solve this using submesh. The code is giving the wrong result when compared to hand calculations, and this seems to be something with the dof structure in each submesh that I'm doing wrong. Any method around this or simpler approach is greatly appreciated.
Regards
Daniel
from dolfin import *
import scitools.std as sc
# Constants
L = 1
H = 2
l = 2
m = 4
ys = 1
# Domains
mesh = RectangleMesh(0,0,L,H,l,m)
class Bottom(SubDomain):
def inside(self, x, on_boundary):
return (between(x[1], (0,ys)))
class Top(SubDomain):
def inside(self, x, on_boundary):
return (between(x[1], (ys,H)))
bottommesh = Bottom()
topmesh = Top()
cf = CellFunction("size_t", mesh)
cf.set_all(0)
bottommesh.mark(cf,0)
topmesh.mark(cf,1)
bottom = SubMesh(mesh, bottommesh)
top = SubMesh(mesh, topmesh)
# Functionspaces
V = VectorFunctionSpace(mesh, "CG", 1)
Vs = VectorFunctionSpace(bottom, "CG", 1)
Vf = VectorFunctionSpace(top, "CG", 1)
def extract_nodes(mesh, V):
"""
Extract x and y coordinates of mesh and
align with dof structure
"""
dim = V.dim()
N = mesh.geometry().dim()
coor = V.dofmap().tabulate_all_coordinates(mesh).reshape(dim,N)
xdof = V.sub(0).dofmap().dofs()
ydof = V.sub(1).dofmap().dofs()
x = coor[:,0]
y = coor[:,1]
# x and y values of the vector components
xx, xy = x[xdof], y[xdof]
yx, yy = x[ydof], y[ydof]
return xx, xy, yx, yy, xdof, ydof
def func1(mesh, V):
"""
Function to be solved in bottom layer
"""
xx, xy, yx, yy,xdof, ydof = extract_nodes(mesh, V)
fx = 0*xx
fy = sc.cos(yy)
return fx, fy, xdof, ydof
def func2(mesh, V):
"""
Expression to be solved in top layer
"""
xx, xy, yx, yy, xdof, ydof = extract_nodes(mesh, V)
fx = 0*xx
fy = sc.sin(yy)
return fx, fy, xdof, ydof
u = Function(V)
us = Function(V)
# Get function values and dofs from each sub domain
fx1, fy1, xdof1, ydof1 = func1(bottom, Vs)
fx2, fy2, xdof2, ydof2 = func2(top, Vf)
# Set function values into vector
u.vector()[xdof1] = fx1
u.vector()[ydof1] = fy1
u.vector()[xdof2] = fx2
u.vector()[ydof2] = fy2
us.assign(interpolate(u,V))
plot(us, interactive=True)