简体   繁体   English

在 Python、Fenics 中创建带有边界标记的网格

[英]Create a mesh with boundary markers in Python, Fenics

My aim is to create a mesh in Python and setting markers on some 1-dimensional subset.我的目标是在 Python 中创建一个网格并在一些一维子集上设置标记。

Up until now, I have always creates a set, for example a rectangle in gmsh, then put for example a circle in it.到目前为止,我总是创建一个集合,例如在 gmsh 中创建一个矩形,然后在其中放置一个圆圈。 Then gmsh puts a mesh on my structure and I can mark the boundary of the rectangle and of the circle as facets (as xdmf files).然后 gmsh 在我的结构上放置一个网格,我可以将矩形和圆形的边界标记为面(作为 xdmf 文件)。 I can then let Python read my mesh and boundary facets and using it, fe to solve PDEs.然后我可以让 Python 读取我的网格和边界面并使用它来求解 PDE。 What I want to do now is the following: I still want to have my rectangle with a mesh, but instead of defining the facet markes in gmsh, I want to define them using the image of a function.我现在想做的是:我仍然想让我的矩形有一个网格,但我不想在 gmsh 中定义小平面标记,而是想使用函数的图像来定义它们。

More precicely: Instead of creating a circle in gmsh, I want to consider, for example, the function更准确地说:我不想在 gmsh 中创建一个圆圈,而是考虑,例如,函数

f:(x,y) \mapsto (2x,3y)

Then I want to use然后我想用f(s^1)as my facet and mark it in my mesh.作为我的刻面并将其标记在我的网格中。

Is there a way to do this?有没有办法做到这一点? I feel kind of lost here.我觉得有点迷失在这里。

I am not sure if I understood everything in your question correctly, but here is some code that might help you.我不确定我是否正确理解了您问题中的所有内容,但这里有一些代码可能会对您有所帮助。 One thing I do not know is how to add element edges to physical groups in gmsh.我不知道的一件事是如何将元素边缘添加到 gmsh 中的物理组。 But maybe you can figure that out.但也许你能弄明白。

So here is the code:所以这是代码:

import gmsh
import numpy as np
    
def mapping(point):
    x = point[0]
    y = point[1]
    z = point[2]
    result = [2*x,3*y,z]
    return result

def inverseMapping(point):
    x = point[0]
    y = point[1]
    z = point[2]
    result = [(1/2)*x,(1/3)*y,z]
    return result

def getNodes():
    nodeTags, nodeCoord, _ = gmsh.model.mesh.getNodes()
    nodeCoord = np.reshape(nodeCoord,(len(nodeTags),3))
    return nodeTags, nodeCoord

def getEdgeNodeCoordinates():
    edgeTags, edgeNodes = gmsh.model.mesh.getAllEdges()
    edgeNodes = np.reshape(edgeNodes,(len(edgeTags),2))
    
    nodeTags, nodeCoord = getNodes()
    coord = []
    for i in range(0,len(edgeTags)):
        tagNode1 = edgeNodes[i][0]
        tagNode2 = edgeNodes[i][1]
        
        nodeIndex1 = list(nodeTags).index(tagNode1)
        nodeIndex2 = list(nodeTags).index(tagNode2)
        
        nodeCoord1 = nodeCoord[nodeIndex1]
        nodeCoord2 = nodeCoord[nodeIndex2]
        
        coord.append([nodeCoord1,nodeCoord2])
        
    return edgeTags, edgeNodes, nodeTags, coord
             
def getInverseNodeCoordinates(edgeNodeCoordinates):
    
    coord = []
    for edgeNodes in edgeNodeCoordinates:
        nodeCoord1 = edgeNodes[0]
        nodeCoord2 = edgeNodes[1]
        
        newCoord1 = inverseMapping(nodeCoord1)
        newCoord2 = inverseMapping(nodeCoord2)
        coord.append([newCoord1, newCoord2])
    return coord
        
def checkIntersection(edgeTags, edgeNodeCoordinates, inverseCoordinates):
    
    intersectingEdgeTags = []
    intersectingEdgeNodeCoord = []
    # 1 = inside, 0 = outside
    for i in range(0,len(inverseCoordinates)):
        pair = inverseCoordinates[i]
        coord1 = pair[0]
        coord2 = pair[1]
        
        e1 = 1 if np.linalg.norm(coord1) <= 1 else 0
        e2 = 1 if np.linalg.norm(coord2) <= 1 else 0
        
        s = e1 + e2 # s = 0 --> both nodes outside of manifold
                    # s = 1 --> one node inside and one node outside of manifold
                    # s = 2 --> both nodes inside of manifold
        
        if s == 1:
            intersectingEdgeTags.append(edgeTags[i])
            intersectingEdgeNodeCoord.append(edgeNodeCoordinates[i])
    return intersectingEdgeTags, intersectingEdgeNodeCoord    
        
def visualizeEdges(intersectingEdgeNodeCoord):
    
    for pair in intersectingEdgeNodeCoord:
        p1 = pair[0]
        p2 = pair[1]
        
        t1 = gmsh.model.occ.addPoint(p1[0],p1[1],p1[2])
        t2 = gmsh.model.occ.addPoint(p2[0],p2[1],p2[2])
        
        line = gmsh.model.occ.addLine(t1, t2)
        gmsh.model.occ.synchronize()
        gmsh.model.setColor([(1,line)], 255, 0, 0)
    gmsh.model.occ.synchronize()



gmsh.initialize()

# Create a rectangle which will be meshed later.
tag_vol_1 = gmsh.model.occ.addRectangle(-3, -4, 0, 6, 8)

# Sample the S1 manifold with n_points
S1_sampling_points = []
n_points = 100
maxAngle = 2*np.pi
angle = maxAngle/n_points
z = 0
for i in range(0,n_points):
    x = np.cos(i*angle)
    y = np.sin(i*angle)
    S1_sampling_points.append([x,y,z])

# Map the sampled S1 points to 2*x, 3*y, z.
# This is only for "visualization" via a spline.
mappedPoints = []
mappedPointTags = []
for point in S1_sampling_points:
    mappedPoint = mapping(point)
    tag = gmsh.model.occ.addPoint(mappedPoint[0], mappedPoint[1], mappedPoint[2])
    mappedPointTags.append(tag)

# Here the spline fitting is performed
# You will see it visualized when gmsh opens.
tagMappedS1 = gmsh.model.occ.addSpline(mappedPointTags + [mappedPointTags[0]]) # make the spline periodic by setting the last point equal to the first one
gmsh.model.occ.synchronize()

# Mesh the rectangle and tell gmsh to create edges which we can access.
gmsh.model.mesh.generate(2)
gmsh.model.mesh.createEdges() # You need to call this before using gmsh.model.mesh.getAllEdges()

# Get all these self-explanatory things
edgeTags, edgeNodes, nodeTags, edgeNodeCoordinates = getEdgeNodeCoordinates()

# Calculate the inverse-mapped coordinates of all nodes.
# With this we can just check if the transformed nodes are inside a circle of radius 1 or outside.
# If for every egde one node is inside, and the other node is outside the circle, then the edge is
# intersected by the mapped manifold f(S1) --> (2*x, 3*y, z). We then save the tag of such an edge.
inverseCoordinates = getInverseNodeCoordinates(edgeNodeCoordinates)
intersectingEdgeTags, intersectingEdgeNodeCoord = checkIntersection(edgeTags, edgeNodeCoordinates, inverseCoordinates)

# Here all intersecting edges are created within gmsh so you can see it.
# This is for visualization only. A lot of nodes with the same coordinates are created here twice.
visualizeEdges(intersectingEdgeNodeCoord)



gmsh.fltk.run()
gmsh.finalize()

And the result in gmsh looks like this: gmsh 中的结果如下所示: 在此处输入图像描述

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM