FiPy:如何在两个网格之间的界面处找到节点(顶点)
FiPy: How to find node (vertex) at interface between two mesh
我已经通过 Gmsh 在 FiPy 中定义了两个网格,并且想在两个网格之间的界面上找到节点。有没有办法在 FiPy 中做到这一点?
siliconGeometry = '''
SetFactory("OpenCASCADE");
//set node spacing
ns = 1e-1;
ns2 = 1e-2;
x1 = 0;
y1 = 0;
x2 = 1;
y2 = 0.5;
Point(1) = {x1, y1, 0, ns};
Point(2) = {x2, y1, 0, ns};
Point(3) = {x2, y2, 0, ns2};
Point(4) = {x1, y2, 0, ns2};
Line(1) = {1, 2};
Line(2) = {2, 3};
Line(3) = {3, 4};
Line(4) = {4, 1};
Curve Loop(1) = {1, 2, 3, 4};
Plane Surface(1) = {1};
Physical Surface("Silicon") = {1};
'''
oxideGeometry = '''
SetFactory("OpenCASCADE");
//set node spacing
ns = 1e-1;
ns2 = 1e-2;
x1 = 0;
y1 = 0.5;
x2 = 1;
y2 = 1;
Point(5) = {x1, y1, 0, ns2};
Point(6) = {x2, y1, 0, ns2};
Point(7) = {x2, y2, 0, ns};
Point(8) = {x1, y2, 0, ns};
Line(5) = {5, 6};
Line(6) = {6, 7};
Line(7) = {7, 8};
Line(8) = {8, 5};
Curve Loop(2) = {5, 6, 7, 8};
Plane Surface(2) = {2};
Physical Surface("Oxide") = {2};
m0 = Gmsh2D(siliconGeometry)
m1 = Gmsh2D(oxideGeometry)
我想获取网格 m0
和 m1
之间界面处的所有节点(或线)。
FiPy 有一个函数叫做 nearest
它获取两个向量的最接近值。因此,要从 m0
和 m1
中获取重叠的 ID,请使用
from fipy import Gmsh2D
from fipy.tools.numerix import nearest
import numpy as np
siliconGeometry = '''
...
'''
oxideGeometry = '''
...
'''
m0 = Gmsh2D(siliconGeometry)
m1 = Gmsh2D(oxideGeometry)
near_ids = nearest(m0.vertexCoords, m1.vertexCoords)
mask = np.all(np.isclose(m0.vertexCoords[:, near_ids], m1.vertexCoords), axis=0)
m1_close_ids = np.arange(len(m1.vertexCoords[0]))[mask]
m0_close_ids = near_ids[mask]
for i in range(len(m0_close_ids)):
m0_id = m0_close_ids[i]
m1_id = m1_close_ids[i]
print()
print(f'm0: {m0_id}, {m0.vertexCoords[:, m0_id]}')
print(f'm1: {m1_id}, {m1.vertexCoords[:, m1_id]}')
我们使用 nearest
为 m0
获取 near_ids
,然后使用 np.isclose
检查节点是否关闭。然后使用 mask
我们可以在两个网格之间构造相应的关闭 ID。
请注意,使用 Scipy 的 KDTree 查找最接近的值可能要快得多。然而,对于这个小问题,这并不重要,但对于一个非常大的网格,我认为这很重要。事实上,FiPy 真的应该在内部使用它(目前不是)。
此外,这里的另一个调整是你知道上下脸重叠,所以你可以简单地要求 m0.facesTop
和 m1.facesBottom
面具将问题减少到重叠的面,但这依赖于网格的先验知识。
感谢@wd15。这是我所做的:
m0 = Gmsh2D(siliconGeometry)
m1 = Gmsh2D(oxideGeometry)
m0_faces = m0.exteriorFaces
m0_vertices = numerix.unique(m0.faceVertexIDs[..., m0_faces].flatten()) m0_vertexCoords = m0.vertexCoords[..., m0_vertices ]
m1_faces = m1.exteriorFaces
m1_vertices = numerix.unique(m1.faceVertexIDs[..., m1_faces].flatten()) m1_vertexCoords = m1.vertexCoords[..., m0_vertices ]
surfVertexID = numerix.nearest(m0_vertexCoords , m1_vertexCoords)
我已经通过 Gmsh 在 FiPy 中定义了两个网格,并且想在两个网格之间的界面上找到节点。有没有办法在 FiPy 中做到这一点?
siliconGeometry = '''
SetFactory("OpenCASCADE");
//set node spacing
ns = 1e-1;
ns2 = 1e-2;
x1 = 0;
y1 = 0;
x2 = 1;
y2 = 0.5;
Point(1) = {x1, y1, 0, ns};
Point(2) = {x2, y1, 0, ns};
Point(3) = {x2, y2, 0, ns2};
Point(4) = {x1, y2, 0, ns2};
Line(1) = {1, 2};
Line(2) = {2, 3};
Line(3) = {3, 4};
Line(4) = {4, 1};
Curve Loop(1) = {1, 2, 3, 4};
Plane Surface(1) = {1};
Physical Surface("Silicon") = {1};
'''
oxideGeometry = '''
SetFactory("OpenCASCADE");
//set node spacing
ns = 1e-1;
ns2 = 1e-2;
x1 = 0;
y1 = 0.5;
x2 = 1;
y2 = 1;
Point(5) = {x1, y1, 0, ns2};
Point(6) = {x2, y1, 0, ns2};
Point(7) = {x2, y2, 0, ns};
Point(8) = {x1, y2, 0, ns};
Line(5) = {5, 6};
Line(6) = {6, 7};
Line(7) = {7, 8};
Line(8) = {8, 5};
Curve Loop(2) = {5, 6, 7, 8};
Plane Surface(2) = {2};
Physical Surface("Oxide") = {2};
m0 = Gmsh2D(siliconGeometry)
m1 = Gmsh2D(oxideGeometry)
我想获取网格 m0
和 m1
之间界面处的所有节点(或线)。
FiPy 有一个函数叫做 nearest
它获取两个向量的最接近值。因此,要从 m0
和 m1
中获取重叠的 ID,请使用
from fipy import Gmsh2D
from fipy.tools.numerix import nearest
import numpy as np
siliconGeometry = '''
...
'''
oxideGeometry = '''
...
'''
m0 = Gmsh2D(siliconGeometry)
m1 = Gmsh2D(oxideGeometry)
near_ids = nearest(m0.vertexCoords, m1.vertexCoords)
mask = np.all(np.isclose(m0.vertexCoords[:, near_ids], m1.vertexCoords), axis=0)
m1_close_ids = np.arange(len(m1.vertexCoords[0]))[mask]
m0_close_ids = near_ids[mask]
for i in range(len(m0_close_ids)):
m0_id = m0_close_ids[i]
m1_id = m1_close_ids[i]
print()
print(f'm0: {m0_id}, {m0.vertexCoords[:, m0_id]}')
print(f'm1: {m1_id}, {m1.vertexCoords[:, m1_id]}')
我们使用 nearest
为 m0
获取 near_ids
,然后使用 np.isclose
检查节点是否关闭。然后使用 mask
我们可以在两个网格之间构造相应的关闭 ID。
请注意,使用 Scipy 的 KDTree 查找最接近的值可能要快得多。然而,对于这个小问题,这并不重要,但对于一个非常大的网格,我认为这很重要。事实上,FiPy 真的应该在内部使用它(目前不是)。
此外,这里的另一个调整是你知道上下脸重叠,所以你可以简单地要求 m0.facesTop
和 m1.facesBottom
面具将问题减少到重叠的面,但这依赖于网格的先验知识。
感谢@wd15。这是我所做的:
m0 = Gmsh2D(siliconGeometry)
m1 = Gmsh2D(oxideGeometry)
m0_faces = m0.exteriorFaces
m0_vertices = numerix.unique(m0.faceVertexIDs[..., m0_faces].flatten()) m0_vertexCoords = m0.vertexCoords[..., m0_vertices ]
m1_faces = m1.exteriorFaces
m1_vertices = numerix.unique(m1.faceVertexIDs[..., m1_faces].flatten()) m1_vertexCoords = m1.vertexCoords[..., m0_vertices ]
surfVertexID = numerix.nearest(m0_vertexCoords , m1_vertexCoords)