This is a read only copy of the old FEniCS QA forum. Please visit the new QA forum to ask questions

Measuring the distance to boundary defined by CellFunction

0 votes

Hello

So I am implementing the Fluid-Structure interaction validation benchmark from Turek, where I solve the equations of FSI on a tube with an elastic flag behind a tube --> Turek Paper
In order to experiment with some different extrapolation operators of the solid deformation into the fluid, I need to calculate the distance from an interior node in the fluid to the solid flag.
This is further to be used in a basic poisson equation on the form

$$ \nabla \cdot (\gamma \nabla u) = 0$$

where $\gamma$ is some diffusion parameter based on this distance

Øyvind Evju answered here, how to calculate the distance from a node to the outer boundary, which comes close to what I need. However, my boundary is defined by CellFunctions

Bar_area = AutoSubDomain(lambda x: (0.19 <= x[1] <= 0.21) and 0.24<= x[0] <= 0.6) 
domains = CellFunction("size_t", mesh)
domains.set_all(1)
Bar_area.mark(domains, 2) #Overwrites structure domain
dx = Measure("dx", subdomain_data = domains)
plot(domains,interactive = True)
dx_f = dx(1, subdomain_data = domains)
dx_s = dx(2, subdomain_data = domains)

and using this approach leaves me with

Distance boundary

What I want is to extend this method to let me measure the distance from an internal node in the fluid to the closest point on the solid flag.

Link to my mesh

Happy Easter

Andreas

asked Apr 14, 2017 by Andreas Slyngstad FEniCS Novice (170 points)

1 Answer

0 votes
 
Best answer

Hi, the following is a modification of Øyvind's answer

from dolfin import *
import numpy as np

# Setup
mesh = RectangleMesh(Point(-1, -1), Point(1, 1), 128, 128)
cell_domains = CellFunction('size_t', mesh, 0)

solid = '&&'.join(['((0.25 - TOL < x[0]) && (x[0] < 0.75 + TOL))', 
                   '((0.4 - TOL < x[1])  && (x[1] < 0.75 + TOL))'])
solid = CompiledSubDomain(solid, TOL=DOLFIN_EPS)
# Init so that solid point distance to solid is 0
distance_f = VertexFunction('double', mesh, 1)
solid.mark(distance_f, 0)
# Fluid vertices
fluid_vertex_ids = np.where(distance_f.array() > 0.5)[0]
# Represent solid as its own mesh for distance queries
solid.mark(cell_domains, 1)
solid_mesh = SubMesh(mesh, cell_domains, 1)
tree = solid_mesh.bounding_box_tree()
# Fill
for vertex_id in fluid_vertex_ids:
    vertex = Vertex(mesh, vertex_id)
    _, dist = tree.compute_closest_entity(vertex.point())
    distance_f[vertex] = dist
# Let's also build representation as a CG1 function
V = FunctionSpace(mesh, 'CG', 1)
f = Function(V)
transform = dof_to_vertex_map(V)
data = distance_f.array()[transform]
f.vector().set_local(data)
f.vector().apply('insert')

plot(f)
interactive() 
answered Apr 15, 2017 by MiroK FEniCS Expert (80,920 points)
selected Apr 15, 2017 by Andreas Slyngstad

Thank you so mutch MiroK !

Just what I needed :D

Andreas

...