Solution transfer from one submesh to other

Dear fellows,
I am using the vector valued function space with element degree >1 . When I calculate the solution u on one submesh e.g. half_cube_mesh, then I want to transfer it to my next mesh which is quarter_cube_mesh.
It should be in such a way that the half cube zone of quarter_cube_mesh should have the same solution assigned as available in the half_cube_mesh and rest (1/3 rd) of the zone’s solution being zero.
Does anyone have a very simple idea to do it in fenics? Thank you!

from dolfin import *

class HalfDomain(SubDomain):
    def inside(self, x, on_boundary):
        return between(x[0], (0, 0.5))
class QuarterDomain(SubDomain):
    def inside(self, x, on_boundary):
        return between(x[0], (0, 0.75))

mesh_Complete = UnitCubeMesh(8,8,8);
mark_sub_domain = MeshFunction("size_t", mesh_Complete, mesh_Complete.topology().dim(), 0)

mark_sub_domain.set_all(0)
mark_domain = HalfDomain()
mark_domain.mark(mark_sub_domain, 1)
half_cube_mesh = SubMesh(mesh_Complete, mark_sub_domain, 1)

mark_sub_domain.set_all(0)
mark_domain = QuarterDomain()
mark_domain.mark(mark_sub_domain, 1)
quarter_cube_mesh = SubMesh(mesh_Complete, mark_sub_domain, 1)

V_half_cube  = VectorFunctionSpace(half_cube_mesh, "Lagrange", 2)
u_half_cube = Function(V_half_cube, name="u_half")

##############################################################################
# here solver performs the solution on the half cube and returns the solution vector u_half_cube #
##############################################################################

V_quarter_cube =  VectorFunctionSpace(quarter_cube_mesh, "Lagrange", 2)
u_quarter_cube = Function(V_quarter_cube, name="u_quarter")

########################################################
# now the u_half_cube has to be transferred to the u_quarter_cube #
# before starting the solver for quarter_cube_mesh #
#########################################################

Hi,

If you use the MeshView function (see here to see how to get the MeshView function [it seems that is also available in the master branch of dolfin]) you can do what you want.

Consider the following modified version of your code snippet:

import numpy as np
from dolfin import *

class HalfDomain(SubDomain):
    def inside(self, x, on_boundary):
        return between(x[0], (0, 0.5))
class QuarterDomain(SubDomain):
    def inside(self, x, on_boundary):
        return between(x[0], (0, 0.75))

mesh_Complete = UnitCubeMesh(8,8,8);
mark_sub_domain = MeshFunction("size_t", mesh_Complete, mesh_Complete.topology().dim(), 0)

mark_sub_domain.set_all(0)
mark_domain = HalfDomain()
mark_domain.mark(mark_sub_domain, 1)
half_cube_mesh = MeshView.create(mark_sub_domain, 1)

mark_sub_domain.set_all(0)
mark_domain = QuarterDomain()
mark_domain.mark(mark_sub_domain, 1)
quarter_cube_mesh = MeshView.create(mark_sub_domain, 1)

V_half_cube  = VectorFunctionSpace(half_cube_mesh, "Lagrange", 2)
u_half_cube = Function(V_half_cube, name="u_half")

##############################################################################
# here solver performs the solution on the half cube and returns the solution vector u_half_cube #
##############################################################################

V_quarter_cube =  VectorFunctionSpace(quarter_cube_mesh, "Lagrange", 2)
u_quarter_cube = Function(V_quarter_cube, name="u_quarter")

# Builds cells mapping between parent meshes
half = half_cube_mesh.topology().mapping()[mesh_Complete.id()].cell_map()
quarter = quarter_cube_mesh.topology().mapping()[mesh_Complete.id()].cell_map()

# Builds cells mapping betwen childs
map = [j for i, c in enumerate(half) for j, d in enumerate(quarter) if c==d]

# Get cell dofmaps
half_dofmap = V_half_cube.dofmap()
quarter_dofmap = V_quarter_cube.dofmap()

# Assign values to functions for testint
u_half_cube.vector()[:] = np.random.rand(u_half_cube.vector()[:].size, )

# Assing dofs to quarter
for c in cells(half_cube_mesh):
  u_quarter_cube.vector()[quarter_dofmap.cell_dofs(map[c.index()])] = u_half_cube.vector()[half_dofmap.cell_dofs(c.index())]

File('u_half.pvd') << u_half_cube
File('u_quarter.pvd') << u_quarter_cube

########################################################
# now the u_half_cube has to be transferred to the u_quarter_cube #
# before starting the solver for quarter_cube_mesh #
#########################################################

which results in

Thanks @hernan for your support!

Hello everyone,

I want to perform a thermal analysis of selective laser melting in which two layers represent the consecutive powder layers to be melting by the heat source(laser beam), as shown in the meshed domain.

The simulation requires the following:

  • In the beginning, the “Base + Layer 1” should be activated and the solution of temperature is obtained.

  • then “Layer 2” is activated and the solution is computed throughout the complete domain.

  • during the melting process, heat a source and different boundary conditions need to be applied on the top surface of Layer 1 and later on the top surface of Layer 2.

After reading in FEniCS discourse, I saw that this can be done by subdomains

I wonder if there exists a way to create the complete mesh and activate/deactivate the layers during the simulation process?

Hi @alixx . Yes it is possible in FEniCS by two different options:

  1. As you yourself mentioned, using the submesh to cut the domain where required from the complete mesh.
  2. Using the MeshView as @hernan used in the code snippet mentioned above.

However in both cases you need to specify part of domain you want to cut by marking if first.

Thank you so much @mashsquad777 . I will try this.