Unable to update step-wise mesh deformation

Hello everyone,

I’m writting a script to perform a step-wise boundary deformation in a specific domain. The geometry change will be later combined to proceed with a FSI implementation. I need to move a marked boundary in a specific manner, However it seems that the mesh only moves on the first time step. Here is a minimum working example:

# Create mesh    
channel = Rectangle(Point(0,0), Point(2, 1))

mesh = generate_mesh(channel, 20)

# Create boundaries
class Left(SubDomain):

    def inside(self, x, on_boundary):

        return near(x[0], 0.0) and on_boundary

class Bottom(SubDomain):

    def inside(self, x, on_boundary):

        return near(x[1], 0.0) and on_boundary

class Top(SubDomain): 

    def inside(self, x, on_boundary):

        return near(x[1], H) and on_boundary


left = Left()
bottom = Bottom()
top = Top()

# Subdomain marker

mf = MeshFunction("size_t", mesh, 2)
mf.set_all(0)
left.mark(mf, 1)
bottom.mark(mf,2)
top.mark(mf, 3)

# Extract boundary mesh

bmesh = BoundaryMesh(mesh, "exterior", True)

t = 0.0

for i in range(5):
     t += 0.1

     for x in bmesh.coordinates():
`        # update values of the boundary nodes`
         if left.inside(x, True):
            x[0] += 0.05 # Moving left boundary to the right. 
            x[1] += 0.0 

     ALE.move(mesh, bmesh)

I am still learning my ways with mesh deformation, so the way I’m moving a specific boundary is also something I could use some help (in the MWE i update the left boundary, but the nodes shared with top and bottom boundaries dont move. I hard-coded a checking and overcame the problem, but there might be a simpler way of doing so).

Do I need to update something after moving the mesh with ALE in each time-step?
Thanks in advance.

The reason it only updates position in the first time step is that, once you move the boundary nodes to the right, they no longer satisfy the geometrical condition for left.inside, and are therefore not moved in subsequent steps. I modified your MWE to create a quick example using vertex markers that does what it looks like this code is trying to do:

from dolfin import *
from mshr import *
from matplotlib import pyplot as plt

# Create mesh
H = 1
channel = Rectangle(Point(0,0), Point(2, H))
mesh = generate_mesh(channel, 8)

# Create boundaries
class Left(SubDomain):

    # Note that, if you want to mark the boundary mesh, nodes from
    # the boundary of the original mesh are interior nodes of the
    # boundary mesh, so they are no longer on_boundary.
    def inside(self, x, on_boundary):
        return near(x[0], 0.0) #and on_boundary

left = Left()

# Extract boundary mesh
bmesh = BoundaryMesh(mesh, "exterior", True)

# Mark boundary mesh; pass 0 as last argument to
# define a function on vertices, i.e., mesh entities
# of topological dimension 0.  
bmf = MeshFunction("size_t", bmesh, 0)
bmf.set_all(0)
left.mark(bmf, 1)

t = 0.0
for i in range(5):
     t += 0.1
     # Vertex markers follow the mesh.
     for i in range(bmesh.num_vertices()):
         if(bmf[i] == 1):
             bmesh.coordinates()[i,0] += 0.05
     ALE.move(mesh, bmesh)
     plot(mesh)
     plt.show()

(Of course mesh elements immediately start to invert if you move only the boundary, although that is a separate concern.)

3 Likes