fipy

Can we find out which mesh a point belongs to in FiPy by searching with the coordinate?


I have two meshes defined in FiPY as follows:

gmsh_mesh = fp.Gmsh2D("ProcessSim_CMOS_Step1.msh")

from fipy.meshes.mesh2D import Mesh2D

def extract_mesh(mesh, mask):
    cellFaceIDs = mesh.cellFaceIDs[..., mask]
    faceIDs = numerix.unique(cellFaceIDs.flatten())
    facemap = numerix.zeros(mesh.faceVertexIDs.shape[1], dtype=int)
    facemap[faceIDs] = faceIDs.argsort()
    
    faceVertexIDs = mesh.faceVertexIDs[..., faceIDs]
    vertIDs = numerix.unique(faceVertexIDs.flatten())
    vertmap = numerix.zeros(mesh.vertexCoords.shape[1], dtype=int)
    vertmap[vertIDs] = vertIDs.argsort()

    return Mesh2D(mesh.vertexCoords[..., vertIDs],
                  vertmap[faceVertexIDs],
                  facemap[cellFaceIDs])

oxideMesh = extract_mesh(mesh=gmsh_mesh, mask=gmsh_mesh.physicalCells["Oxide"])
siliconMesh = extract_mesh(mesh=gmsh_mesh, mask=gmsh_mesh.physicalCells["Silicon"])

So while doing process simulation, say etching, the user wants to selectively etch the specified material. To assign different etch rate to different points, I want to find whether a coordinate <x, y, 0.0> belongs to oxideMesh or siliconMesh. Is there a way to do this?


Solution

  • FiPy doesn't provide any capability like this and isn't likely to. If your meshes were simply connected and convex, then you could use scipy.spatial.tsearch with the mesh vertices. Unfortunately, based on your previous questions, this approach won't work for you.

    Many years ago, I did some work with semiconductor heterostructures, where I needed to account for different domain geometries built up during successive lithographic and electrodeposition steps. I used the Shapely package to define abstract geometrical domains and then converted those domains to a FiPy mesh with Gmsh. Shapely can be used to check point containment, even when the domains are concave or disconnected. The specifics were a bit different from what you're doing, but I believe it's still applicable.

    This gist illustrates building multiple complex domains, checking point containment in them, and then generating a single FiPy mesh from them (which was my use-case; you could generate separate meshes from separate domains).

    Shapely geometry of pn junction FiPy meshing of Shapely geometry

    In [5]:
    pt = Point((-5e-7, 3.99e-7))
    ntype.contains(pt), ptype.contains(pt)
    Out[5]:
    (True, False)
    In [6]:
    pt = Point((-5e-7, 4e-7))
    ntype.contains(pt), ptype.contains(pt)
    Out[6]:
    (False, False)
    In [7]:
    pt = Point((-5e-7, 4.01e-7))
    ntype.contains(pt), ptype.contains(pt)
    Out[7]:
    (False, True)
    In [8]:
    pt = Point((-5e-7, 4.0e-7))
    ntype.touches(pt), ptype.touches(pt)
    Out[8]:
    (True, True)