Save Solution as variable

As I said previously, project u_platte[0] into the collapsed subspace (W.sub(0).collapse()).

This was my second guess, but then i get the again the following error:

Exception: codim != 0 or 1 - Not (yet) implemented

from this code

W0 = W.sub(0).collapse()
bc_function = project(as_vector((0,0,u_Platte[0])),W0, solver_type="mumps")

my next guesses would either be to change the version of my dolfin installation, but i am quite hestitant to do this, or work on the functionspaces. For the plate i use:

X = FiniteElement('CG', submesh.ufl_cell(), 2)
Y = FiniteElement('CG', submesh.ufl_cell(), 2)
Z = X * Y
S = FunctionSpace(submesh, Z)

but for the fluid:

P2 = VectorElement("Lagrange", mesh.ufl_cell(), 2)
P1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1)
TH = P2 * P1
W = FunctionSpace(mesh, TH)

Instead of trying to use a projection, could you try to phrase your problem as a coupled problem, and solve it with the mixed dimensional framework I linked to above?

I think this should be possible.

My Professor actually tried to do that, but it turned out, that such a formulation doesn’t work very well

Then I’d suggest using the 2019.1.0 version of fenics, Where the projection didn’t raise any error.

Okay, i will try that. I hate to ask you so much, but how do i degrade my version? I couldn’t find any good ressources on that topic.

Depends on how you installed dolfin

Easiest way of changing versions is by using docker.
docker run -ti -p 127.0.0.1:8000:8000 -v $(pwd):/home/fenics/shared -w /home/fenics/shared quay.io/fenicsproject/stable:2019.1.0

I installed it over my Ubuntu terminal as instructed on the fenics main website

Then its Harder to downgrade directly. I would suggest using docker.

Would another approach maybe possible? My overall frist guess was to save the values of the solution of plate u_platte[0] as an two dimensional array and reintroduce the raw values over the top of the cube mesh. Can something like this be done? I imagine this could eliminate the issues that the dimensions of the functionspaces are different

It can be done, it would be equivalent of an interpolation. To do this safely you Need to match the dofs on the 2D mesh with those on the 3D mesh.

Do you know any ressources to do this correctly? It does sound promissing.

I would suggest starting by collapsing your sub-space down to the component level,
i.e. W.sub(0).sub(0), then use the built in interpolation:

from dolfin import *

N = 10
mesh = UnitSquareMesh(N, N)
V = FunctionSpace(mesh, "CG", 1)
u = project(Expression("x[0]*x[1]", degree=1), V)

mesh3D = UnitCubeMesh(N, N, N)
V3 = FunctionSpace(mesh3D, "CG", 1)
u3 = interpolate(u, V3)
File("u3.pvd") << u3

then use FunctionAssigner (https://bitbucket.org/fenics-project/dolfin/raw/ec57db53f2b13f1768214829e8b4f80fc32205cf/python/demo/undocumented/sub-function-assignment/demo_sub-function-assignment.py) to assign the function to the appropriate space (W.sub(0).collapse) and assign the boundary condition.

Hi tried my best to use your hints to solve my problem. I got to the point where i build a transferspace to match the finite elements to the submesh, in this space i projected the plate, now i want to interpolate from transferspace to the regular functionspace i use for the fluid:

from dolfin import *
import matplotlib.pyplot as plt
parameters['allow_extrapolation'] = True
height = 1.0
width = 1.0
length = 1.0
mesh = BoxMesh(Point(0.0, 0.0, 0.0), Point(length,width,height), 12, 12, 12)
#plot(mesh)
#%%
marker = MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0)
for f in facets(mesh):
    marker[f] = height - DOLFIN_EPS < f.midpoint().z() < height + DOLFIN_EPS

## Create submesh ##
submesh = MeshView.create(marker, 1)
#plot(submesh)
X = FiniteElement('CG', submesh.ufl_cell(), 2)
Y = FiniteElement('CG', submesh.ufl_cell(), 2)
Z = X * Y
S = FunctionSpace(submesh, Z)

u_Platte = Function(S)

P2 = VectorElement("Lagrange", mesh.ufl_cell(), 2)
P1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1)
TH = P2 * P1
W = FunctionSpace(mesh, TH)
def Top(x, on_boundary): return x[2] > height - DOLFIN_EPS
def Container(x, on_boundary): 
    return x[0] > length - DOLFIN_EPS or x[0] < DOLFIN_EPS or x[1] > width - DOLFIN_EPS or x[1] < DOLFIN_EPS 

P2_1 = VectorElement("Lagrange", submesh.ufl_cell(), 2)
P1_1 = FiniteElement("Lagrange", submesh.ufl_cell(), 1)
TH_1 = P2_1 * P1_1
transferspace = FunctionSpace(submesh, TH_1)
transferfunction = project(u_Platte.sub(0),transferspace.sub(0).sub(0).collapse())

This works so far, how ever i get an error, when i add the following code

BoundaryFunction = interpolate(transferfunction, W.sub(0).sub(0).collapse())

(u, p) = TrialFunctions(W)
(v, q) = TestFunctions(W)
f = Constant((0.0, 0.0, 0.0))
a = inner(grad(u), grad(v))*dx + div(v)*p*dx + q*div(u)*dx
L = inner(f, v)*dx

# Form for use in constructing preconditioner matrix
b = inner(grad(u), grad(v))*dx + p*q*dx

# Assemble system
A, bb = assemble_system(a, L, bcs)
# Assemble preconditioner system
P, btmp = assemble_system(b, L, bcs)

# Create Krylov solver and AMG preconditioner
solver = KrylovSolver(krylov_method, "amg")

# Associate operator (A) and preconditioner matrix (P)
solver.set_operators(A, P)

# Solve
U = Function(W)
solver.solve(U.vector(), bb)

the errormessage reads following:

*** -------------------------------------------------------------------------
*** DOLFIN encountered an error. If you are not able to resolve this issue
*** using the information listed below, you can ask for help at
***
***     fenics-support@googlegroups.com
***
*** Remember to include the error message listed below and, if possible,
*** include a *minimal* running example to reproduce the error.
***
*** -------------------------------------------------------------------------
*** Error:   Unable to match boundary condition to function space.
*** Reason:  Function space on axis 0 does not contain BC space.
*** Where:   This error was encountered inside SystemAssembler.cpp.
*** Process: 0
*** 
*** DOLFIN version: 2019.2.0.dev0
*** Git changeset:  unknown
*** -------------------------------------------------------------------------

Again, you keep excluding code required to run your problem. This time, you have excluded bcs Which is the actual cause of error.

Oh, i am sorry.

from dolfin import *
import matplotlib.pyplot as plt
parameters['allow_extrapolation'] = True
height = 1.0
width = 1.0
length = 1.0
mesh = BoxMesh(Point(0.0, 0.0, 0.0), Point(length,width,height), 12, 12, 12)

marker = MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0)
for f in facets(mesh):
    marker[f] = height - DOLFIN_EPS < f.midpoint().z() < height + DOLFIN_EPS

## Create submesh ##
submesh = MeshView.create(marker, 1)
#plot(submesh)
X = FiniteElement('CG', submesh.ufl_cell(), 2)
Y = FiniteElement('CG', submesh.ufl_cell(), 2)
Z = X * Y
S = FunctionSpace(submesh, Z)

u_Platte = Function(S)

P2 = VectorElement("Lagrange", mesh.ufl_cell(), 2)
P1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1)
TH = P2 * P1
W = FunctionSpace(mesh, TH)
def Top(x, on_boundary): return x[2] > height - DOLFIN_EPS
def Container(x, on_boundary): 
    return x[0] > length - DOLFIN_EPS or x[0] < DOLFIN_EPS or x[1] > width - DOLFIN_EPS or x[1] < DOLFIN_EPS 


noslip = Constant((0.0, 0.0, 0.0))
bcContainer = DirichletBC(W.sub(0), noslip, Container)
P2_1 = VectorElement("Lagrange", submesh.ufl_cell(), 2)
P1_1 = FiniteElement("Lagrange", submesh.ufl_cell(), 1)
TH_1 = P2_1 * P1_1
transferspace = FunctionSpace(submesh, TH_1)
transferfunction = project(u_Platte.sub(0),transferspace.sub(0).sub(0).collapse())

BoundaryFunction = interpolate(transferfunction, W.sub(0).sub(0).collapse())
bcTop = DirichletBC(W.sub(0).collapse(), as_vector((0.0, 0.0, BoundaryFunction)),Top)
bcs = [bcContainer, bcTop]

(u, p) = TrialFunctions(W)
(v, q) = TestFunctions(W)
f = Constant((0.0, 0.0, 0.0))
a = inner(grad(u), grad(v))*dx + div(v)*p*dx + q*div(u)*dx
L = inner(f, v)*dx

# Form for use in constructing preconditioner matrix
b = inner(grad(u), grad(v))*dx + p*q*dx

# Assemble system
A, bb = assemble_system(a, L, bcs)
# Assemble preconditioner system
P, btmp = assemble_system(b, L, bcs)

# Create Krylov solver and AMG preconditioner
krylov_method = "minres"
solver = KrylovSolver(krylov_method, "amg")

# Associate operator (A) and preconditioner matrix (P)
solver.set_operators(A, P)

# Solve
U = Function(W)
solver.solve(U.vector(), bb)

This code reproduces the following error message:

RuntimeError: 

*** -------------------------------------------------------------------------
*** DOLFIN encountered an error. If you are not able to resolve this issue
*** using the information listed below, you can ask for help at
***
***     fenics-support@googlegroups.com
***
*** Remember to include the error message listed below and, if possible,
*** include a *minimal* running example to reproduce the error.
***
*** -------------------------------------------------------------------------
*** Error:   Unable to match boundary condition to function space.
*** Reason:  Function space on axis 0 does not contain BC space.
*** Where:   This error was encountered inside SystemAssembler.cpp.
*** Process: 0
*** 
*** DOLFIN version: 2019.2.0.dev0
*** Git changeset:  unknown
*** -------------------------------------------------------------------------

You should not collapse the function space in the Dirichlet BC

Collapsing it, was actually a consideration made by DOLFIN. Without collapsing it, i get the following error:

*** -------------------------------------------------------------------------
*** Error:   Unable to create function.
*** Reason:  Cannot be created from subspace. Consider collapsing the function space.
*** Where:   This error was encountered inside Function.cpp.
*** Process: 0
*** 
*** DOLFIN version: 2019.2.0.dev0
*** Git changeset:  unknown
*** -------------------------------------------------------------------------

As I said in a previous post, you should use FunctionAssigner to assign the function from W.sub(0).sub(2) to W.sub(0) such that it can be used in Dirichlet condition

Hi, is there any further documentation of the FunctionAssigner?
I was able to project the initial function to the space w.sub(0).sub(2) but still struggle withe following steps and the example doesn’t give much away on how to initialize the functionassigner.

from dolfin import *
import matplotlib.pyplot as plt
parameters['allow_extrapolation'] = True
height = 1.0
width = 1.0
length = 1.0
mesh = BoxMesh(Point(0.0, 0.0, 0.0), Point(length,width,height), 12, 12, 12)

marker = MeshFunction("size_t", mesh, mesh.topology().dim() - 1, 0)
for f in facets(mesh):
    marker[f] = height - DOLFIN_EPS < f.midpoint().z() < height + DOLFIN_EPS

## Create submesh ##
submesh = MeshView.create(marker, 1)
#plot(submesh)
X = FiniteElement('CG', submesh.ufl_cell(), 2)
Y = FiniteElement('CG', submesh.ufl_cell(), 2)
Z = X * Y
S = FunctionSpace(submesh, Z)

u_Platte = Function(S)

P2 = VectorElement("Lagrange", mesh.ufl_cell(), 2)
P1 = FiniteElement("Lagrange", mesh.ufl_cell(), 1)
TH = P2 * P1
W = FunctionSpace(mesh, TH)
def Top(x, on_boundary): return x[2] > height - DOLFIN_EPS
def Container(x, on_boundary): 
    return x[0] > length - DOLFIN_EPS or x[0] < DOLFIN_EPS or x[1] > width - DOLFIN_EPS or x[1] < DOLFIN_EPS 


noslip = Constant((0.0, 0.0, 0.0))
bcContainer = DirichletBC(W.sub(0), noslip, Container)
S0 = S.sub(0).collapse()
u_0 = project(u_Platte.sub(0), S0)

u_top = interpolate(u_0, W.sub(0).sub(2).collapse())
#next line produces error
assigner = FunctionAssigner(W.sub(0), W.sub(0).sub(2))

with the following error:

*** -------------------------------------------------------------------------
*** DOLFIN encountered an error. If you are not able to resolve this issue
*** using the information listed below, you can ask for help at
***
***     fenics-support@googlegroups.com
***
*** Remember to include the error message listed below and, if possible,
*** include a *minimal* running example to reproduce the error.
***
*** -------------------------------------------------------------------------
*** Error:   Unable to create function assigner.
*** Reason:  The assigning and receiving FunctionSpaces have incompatible number of entity dofs for entity 0 and space no: 0.
*** Where:   This error was encountered inside FunctionAssigner.cpp.
*** Process: 0
*** 
*** DOLFIN version: 2019.2.0.dev0
*** Git changeset:  unknown
*** -------------------------------------------------------------------------