Assigning one VectorFunctionSpace to multiple submeshes

My geometry has four submeshes and looks like

I need to solve a hyperelasticity problem on the outer 3 meshes and a fluid mechanics problem on the innermost mesh.

I extracted the four submeshes with the following commands:

mesh1 = SubMesh(mesh,cf,8)
mesh2 = SubMesh(mesh,cf,5)
mesh3 = SubMesh(mesh,cf,6)
mesh4 = SubMesh(mesh,cf,7)

I want to introduce a single VectorFunctionSpace on meshes 2, 3, and 4 and another VectorFunctionSpace on mesh 5. I do not want to club the outer meshes into a single mesh since they have different material properties. But VectorFunctionSpace takes only one mesh as an argument. How can I assign a single VectorFunctionSpace to multiple submeshes?

Another way I thought of doing this is to introduce a VectorFunctionSpace, V, on the whole mesh, introduce the variable of interest, u=Function(V), assign value 0 to u on the innermost mesh when solving the hyperelasticity problem on the outer 3 meshes. But I am having trouble with the assignment. The following set of commands

class expr(UserExpression):
    def __init__(self, mesh, marker,f1, **kwargs):
        super(expr, self).__init__(kwargs)   
        self.mesh = mesh
        self.marker = marker
        self.f1 = f1
    def eval_cell(self, value, x, ufc_cell):
        cell = Cell(self.mesh, ufc_cell.index)
        if self.marker[cell] == 8: # The innermost mesh is tagged 8
            value[0] = 0
        else:
            value[0] = self.f1(x)

    def value_shape(self):
        return ()

new_u = expr(mesh, cf, u, degree = 0)
new_u1 = project(new_u, V)

produces the error:

ValueError: setting an array element with a sequence. How to overcome this error?

I personally create my SubMeshes like this:

def extract_SubMesh(mesh, mf_2d, indices):
    """
    extracts the submesh (meshView-object) with the indices in indices out of the mesh
    Input:
        - mesh: mesh of the system
        - mf_2d: MeshFunction with the indices of the submeshes saved
        - indices: indices of the submesh to be created

    Output:
        - MeshView object of the submesh with the indices in indices
    """
    subdomains = MeshFunction("size_t", mesh, mesh.topology().dim(), 0) # create MeshFunction in order to create the subMesh
    for k in indices:
        subdomains.array()[mf_2d.array()==k] = 1
    extracted_SubMesh_return = MeshView.create(subdomains, 1)

I don’t quite remember where, but somewhere I’ve read, that you should use MeshView.create(…) for SubMeshes. However I forgot the reason why.
The code above however works for me :slight_smile:

Hope this is what you were looking for!

1 Like

@Emanuel_Gebauer , Thanks for the suggestion. Although the suggested code works, I have a question:

What is the difference between MeshView.create() and SubMesh(). For example, are the following two codes same, i.e., Does MeshView.create() remesh the compiled subdomains? If it remeshes, then for my problem it will not work. I need the vertices on boundary 1 to be aligned.

(a)

combined_subdomains = MeshFunction("size_t", mesh, mesh.topology().dim(), 0)
combined_subdomains.array()[cf.array()==5] = 1  # cf is the cell marker
combined_subdomains.array()[cf.array()==6] = 1
combined_subdomains.array()[cf.array()==7] = 1
combined_submesh = SubMesh(mesh,combined_subdomains, 1)

(b) ```
combined_subdomains = MeshFunction(“size_t”, mesh, mesh.topology().dim(), 0)
combined_subdomains.array()[cf.array()==5] = 1 # cf is the cell marker
combined_subdomains.array()[cf.array()==6] = 1
combined_subdomains.array()[cf.array()==7] = 1
combined_submesh = MeshView.create(combined_subdomains, 1)

SubMesh does not work in parallel, while MeshView works in parallel. Also, mesh-view works for mixed dimensional assembly.

Neither MeshView or SubMesh remeshes the sub-domains.

2 Likes