Extract parts of the boundary

Thank you for viewing my question.
I am confused when using BoundaryMesh.

from fenics import *
from mshr   import *
import matplotlib.pyplot as plt

domain = Box(Point(0,0,0),Point(10,10,10))
sphere = Sphere(Point(5, 5, 5),3)
domain = domain - sphere
mesh   = generate_mesh(domain,32)
exterior = BoundaryMesh(mesh, 'exterior')
interior = BoundaryMesh(mesh, 'interior')
File('exterior.pvd') << exterior
File('interior.pvd') << interior

exterior contains surfaces of sphere and box and interior contains nothing.

Here is my question:

  • What is the meaning of the second parameter in BoundaryMesh?
  • How to output the surfaces of the sphere and box in mesh separately?

If you run with multiple processes, you will see that ‘interior’ returns the boundaries between processor subdomains. (So, on one process, it is empty.)

To extract the sphere and box separately, you can do something like the following:

from fenics import *
from mshr   import *
import matplotlib.pyplot as plt

domain = Box(Point(0,0,0),Point(10,10,10))
sphere = Sphere(Point(5, 5, 5),3)
domain = domain - sphere
mesh   = generate_mesh(domain,32)
exterior = BoundaryMesh(mesh, 'exterior')

from numpy import array
from numpy.linalg import norm
def inSphere(x):
    v = x - array([5,5,5])
    return norm(v)<3+1e2*DOLFIN_EPS
class SphereDomain(SubDomain):
    def inside(self,x,on_boundary):
        return inSphere(x)
class BoxDomain(SubDomain):
    def inside(self,x,on_boundary):
        return not inSphere(x)
    
File('sphere.pvd') << SubMesh(exterior,SphereDomain())
File('box.pvd') << SubMesh(exterior,BoxDomain())

Thank you, very much!

Howerver, I have an another question. exterior consists of triangles which are called cells. Submesh also consists of cells. Here is my question: how to judge a cell is inside a subdomain? Every vertex of the cell should be inside the subdomain? or, so long as the midpoint is inside the subdomain?

From looking at the source code, it appears that cells are marked by SubDomains based on whether all vertices and (optionally) the midpoint are contained in the sub-domain (depending on the value of the argument check_midpoint). See the apply_markers method of the SubDomain class, implemented here:

https://bitbucket.org/fenics-project/dolfin/src/master/dolfin/mesh/SubDomain.cpp

The SubMesh class constructor calls SubDomain::mark without passing check_midpoint, so it defaults to true. See

https://bitbucket.org/fenics-project/dolfin/src/master/dolfin/mesh/SubMesh.cpp