CFDMSH - Python Module For Meshing of Airfoil
CFDMSH - Python Module For Meshing of Airfoil
++++++++++
+ CFDMSH +
++++++++++
Python Library for CFD Meshing with Salome Platform
http://www.vzlu.cz/en/results-transfer/software-r/free-software-download
Author: Tougeron W. (tougeron@vzlu.cz)
Last Modification: 18.06.2013
Licence: GNU General Public License
"""
version="2.2.33"
import
import
import
import
salome, salome.geom.geomtools
geompy, GEOM
smesh, SMESH
time
return subShapeList
def CheckObjectExistence(name,moduleName='GEOM'):
# Make this function recursive
if isinstance(name,list):
objectList=[]
for subObject in name:
objectList.append(CheckObjectExistence(subObject,moduleN
ame))
return objectList
#else:
# Get the component
geometryComponent=salome.myStudy.FindComponent(moduleName)
## Get the existing names
nameList=GetSubShapeNames(geometryComponent)
## Check the object existence
if name==None:
return None
elif name in nameList:
return True
else:
return False
#-
def GetNextNameIndex(name,moduleName='GEOM'):
# Get the component
geometryComponent=salome.myStudy.FindComponent(moduleName)
## Get the existing names
nameList=GetSubShapeNames(geometryComponent)
## Get the existing indexes
existingIndexes=[]
for existingName in nameList:
if existingName.find(name)!=-1:
nameEnding=existingName.split(name)[1]
try:
index=int(nameEnding)
existingIndexes.append(index)
except:
pass
else:
name+='_'
index=GetNextNameIndex(name)
name+=index
if father==None:
id=geompy.addToStudy(object,name)
else:
id=geompy.addToStudyInFather(father,object,name)
if display==True:
gg=salome.ImportComponentGUI("GEOM")
gg.createAndDisplayGO(id)
else:
if salome.sg.hasDesktop():
salome.sg.updateObjBrowser(1)
def GetObject(object,componentName='GEOM'):
if isinstance(object,list):
objectList=[]
return object
def GetSubShapes(shape):
if isinstance(shape,list):
returnList=[]
for subShape in shape:
returnList.append(GetSubShapes(subShape))
return returnList
else:
shapeVertexes=geompy.SubShapeAll(shape,geompy.ShapeType["VERTEX"
])
shapeEdges=geompy.SubShapeAll(shape,geompy.ShapeType["EDGE"])
shapeFaces=geompy.SubShapeAll(shape,geompy.ShapeType["FACE"])
shapeSolids=geompy.SubShapeAll(shape,geompy.ShapeType["SOLID"])
return [shapeVertexes,shapeEdges,shapeFaces,shapeSolids,shape]
def PrintDefinedFunctions():
print """
Defined Functions:
> Geometry Module:
+ Measurement:
- GeometricalEquality()
+ Basic Geometry Tools:
* 1D:
- ExtendSpline()
- FuseSplines()
- MakeMiddleSpline()
- RebuildSpline()
- SplitEdge()
* 2D:
- FuseCoplanarFaces()
- RebuildFace()
- RemoveFaceExtraEdges()
+ Viscous Layer Generation:
* 2D:
- MakeEdgeOffset()
- ExtendViscousLayer()
- CloseViscousLayer()
- PropagateViscousLayerIntersection()
* 3D:
- MakeTipViscousLayer()
- ExtendTipViscousLayer()
- CloseTipViscousLayer()
- MakeLinkingSolids()
- GetBoundaryFaces()
+ Group Management:
- GetTriEdgeFaces()
- CopyGeometricalGroups()
- ExportGeometricalGroups()
- ImportGeometricalGroups()
> Mesh Module:
+ Viscous Layer Meshing:
- ViscousLayerScaleFactor()
+ Mesh Export:
- ExportAmshFile()
+ Mesh Management:
- ExportMeshConfiguration()
- ImportMeshConfiguration()
> Multi-module Functions:
- RotateFlapGenerateAndExportMeshInAmshFormat()
"""
def PrintVersion():
print "Version:"
print version
#### - ####
#### Here are cfdmsh functions ####
def GeometricalEquality(shape1,shape2,tol=1e-7):
"""
Compares the shapes of two geometrical objects.
Argument(s):
Name
Description
Type
Default Value
shape1 First geometrical object. / Its name in the study tree.
Any geometrical object / String
shape2 Second geometrical object. / Its name in the study tree.
Any geometrical object / String
tol
Maximum difference allowed between all the shape parameters.
Float 1e-7
Returned Value(s):
dim Value
Type
Boolean
"""
Number Name
1
-
isEqual=False
# Get the input shape(s)
shapes=GetObject([shape1,shape2],'GEOM')
#if "error" in [shape1,shape2]:
return
else:
# Check the centers of mass
centersOfMass=[
geompy.MakeCDG(shapes[0]),
geompy.MakeCDG(shapes[1])
]
distance=geompy.MinDistance(centersOfMass[1],centersOfMass[0])
#if distance<=tol:# If they are equals...
# Check the basic properties
basicProperties=[
geompy.BasicProperties(shapes[0]),
geompy.BasicProperties(shapes[1])
]
for i in range(len(basicProperties[0])):
difference=abs(basicProperties[1][i]-basicProper
ties[0][i])
if difference>tol:
break
def ExtendSpline(edge,vertex,pos="auto",np=10,add=True,infa=False,dim=1):
"""
Extends an Edge to a Vertex position.
Argument(s):
Name
Description
Type
Default Value
edge
Curve to extend. / Its name in the study tree. Edge / String
vertex Vertex to reach. / Its name in the study tree. Vertex / String
pos
If equals "before" or "after", the edge is extended from it star
t or its end respectivly (according to its orientation). If equals "auto", the f
unction decides
np
add
infa
dim
itself.
See the
See the
See the
See the
String
documentation.
documentation.
documentation.
documentation.
"auto"
Integer
Boolean
Boolean
Integer
10
True
False
1
Returned Value(s):
dim Value
Type
Number Name
0
Compound of Vertexes
1
"ExtendedSpline (Vertexes)"
1
Edge
1
"ExtendedSpline"
"""
if dim>1:
return
else:
# Get the input shape(s)
[edge,vertex]=GetObject([edge,vertex],'GEOM')
father=None
if infa==True:
father=edge
## Check the input shape existence
if "error" in [edge,vertex]:
return
#else:
# Get the sub-shapes
[edge,vertex]=GetSubShapes([edge,vertex])
## Check the position
if pos not in ["auto","before","after"]:
pos="auto"
## Get the pos of the user vertex
if pos=="auto":
vertexDistances=[
geompy.MinDistance(vertex[-1],edge[0][0]),
geompy.MinDistance(vertex[-1],edge[0][1])
]
pos="after"
if vertexDistances[0] < vertexDistances[1]:
pos="before"
else:
# Create the extended spline
extendedSpline=geompy.MakeInterpol(splineVertexe
s,False,False)
## Add and return the resulting shape(s)
if add==True:
AddToStudy(extendedSpline,"ExtendedSplin
e",father)
return extendedSpline
#-
def FuseSplines(edge1,edge2,np=10,add=True,dim=1):
"""
Fuses two Edges.
tring
tring
Argument(s):
Name
Description
Type
Default Value
edge1 First spline to fuse. / Its name in the study tree.
edge2 Second spline to fuse. / Its name in the study tree.
np
See the documentation. Integer
10
add
See the documentation. Boolean
True
dim
See the documentation. Integer
1
Returned Value(s):
dim Value
Type
Number Name
0
Compound of Vertexes
1
1
Edge
1
"FusedSpline"
Edge / S
Edge / S
"FusedSpline (Vertexes)"
Conditions of Use:
For better results, if coincident, both splines has to be as tangential
as possible.
"""
if dim>1:
return
else:
# Get the input shape(s)
edges=GetObject([edge1,edge2],'GEOM')
## Check the input shape existence
if "error" in [edge1,edge2]:
return
#else:
# Extract the edge vertexes
#### Here the extremum vertexes are created on curve
#### and not exploded to be sure the vertex order
#### respects the edge orientation
edgeVertexes=[
geompy.MakeVertexOnCurve(edges[0],0),
geompy.MakeVertexOnCurve(edges[0],1),
geompy.MakeVertexOnCurve(edges[1],0),
geompy.MakeVertexOnCurve(edges[1],1)
]
###### Determine the edge directions
minDistances=[
geompy.MinDistance(edgeVertexes[0],edges[1]),
geompy.MinDistance(edgeVertexes[1],edges[1]),
geompy.MinDistance(edges[0],edgeVertexes[2]),
geompy.MinDistance(edges[0],edgeVertexes[3])
]
reverseEdges=[False,False]
if minDistances[0] < minDistances[1]:
reverseEdges[0]=True
if minDistances[2] > minDistances[3]:
reverseEdges[1]=True
## Split edge1
fusedSplineVertexes=[]
for parameter in [n/float(np) for n in range(np)]:
if reverseEdges[0] == True:
parameter=1-parameter
edge1Vertex=geompy.MakeVertexOnCurve(edges[0],pa
rameter)
fusedSplineVertexes.append(edge1Vertex)
## Split edge2
for parameter in [n/float(np) for n in range(np+1)]:
if reverseEdges[1] == True:
parameter=1-parameter
edge2Vertex=geompy.MakeVertexOnCurve(edges[1],pa
rameter)
fusedSplineVertexes.append(edge2Vertex)
#if dim==0:# If the output dimension is 0...
# Create the vertex compound
fusedSplineVertexCompound=geompy.MakeCompound(fu
sedSplineVertexes)
## Add and return the resulting shape(s)
if add==True:
AddToStudy(fusedSplineVertexCompound,"Fu
sedSpline (Vertexes)")
return fusedSplineVertexCompound
#else:
# Create the fused edge
fusedSpline=geompy.MakeInterpol(fusedSplineVerte
xes,False,False)
#-
def MakeMiddleSpline(edge1,edge2,np=10,add=True,dim=1):
"""
Creates a middle spline of two Edges.
Argument(s):
Name
Description
Type
Default Value
edge1 First of the two edges between which build the middle edge. / It
s name in the study tree.
Edge / String edge2 Second of the two edges between which build the middle edge. / I
ts name in the study tree.
Edge / String np
See the documentation. Integer
10
add
See the documentation. Boolean
True
dim
See the documentation. Integer
1
Returned Value(s):
dim Value
Type
Number Name
0
Compound of Vertexes
1
"MiddleSpline (Vertexes)"
1
Edge
1
"MiddleSpline"
"""
if dim>1:
return
else:
# Get the input shape(s)
edges=GetObject([edge1,edge2],'GEOM')
## Check the input shape existence
if "error" in [edge1,edge2]:
return
#else:
# Get the sub-shapes
edges=GetSubShapes(edges)
## Get the offset edge sense
linkingEdges=[
geompy.MakeEdge(edges[0][0][0],edges[1][0][0]),
geompy.MakeEdge(edges[0][0][0],edges[1][0][1])
]
linkingEdgeLengths=[
geompy.BasicProperties(linkingEdges[0])[0],
geompy.BasicProperties(linkingEdges[1])[0]
]
reverseParameter=False
if linkingEdgeLengths[0]>linkingEdgeLengths[1]:
reverseParameter=True
## Create the points
edgeVertexes=[[],[]]
for parameter in [float(i)/(np-1) for i in range(np)]:
edgeVertexes[0].append(geompy.MakeVertexOnCurve(
edges[0][-1],parameter))
if reverseParameter==True:
parameter=1.0-parameter
edgeVertexes[1].append(geompy.MakeVertexOnCurve(
edges[1][-1],parameter))
## Get the middle spline vertexes
nbVertexes=len(edgeVertexes[0])
middleVertexes=[]
for i in range(nbVertexes):
spline=geompy.MakeEdge(edgeVertexes[0][i],edgeVe
rtexes[1][i])
middleVertexes.append(geompy.MakeVertexOnCurve(s
pline,0.5))
def RebuildSpline(edge,np=10,add=True,infa=False,dim=1):
"""
Rebuilds an Edge with a certain number of Vertexes.
tring
Argument(s):
Name
Description
Type
edge
The edge to rebuild. /
np
See the documentation.
add
See the documentation.
infa
See the documentation.
dim
See the documentation.
Default Value
Its name in the study tree.
Integer
Boolean
Boolean
Integer
10
True
False
1
Edge / S
Returned Value(s):
dim Value
Type
Number Name
0
Compound of Vertexes
1
1
Edge
1
"FusedSpline"
"""
"FusedSpline (Vertexes)"
if dim>1:
return
else:
# Make this function recursive
if isinstance(edge,list):
returnList=[]
for subObject in edge:
returnList.append(RebuildSpline(subObject,np,add
,infa,dim))
return returnList
#else:
# Get the input shape(s)
edge=GetObject(edge,'GEOM')
father=None
if infa==True:
father=edge
## Check the input shape existence
if "error" in [edge]:
return
#else:
# Create the points
points=[]
def SplitEdge(edge,np=10,add=True,infa=False,dim=1):
"""
Edge / String
np
add
infa
dim
See
See
See
See
the
the
the
the
documentation.
documentation.
documentation.
documentation.
Integer
Boolean
Boolean
Integer
Returned Value(s):
dim Value
Type
Number Name
0
Compound of Vertexes
1
1
Edge
1
"SplitEdge"
"""
10
True
False
1
"SplitEdge (Vertexes)"
if dim>1:
return
else:
# Make this function recursive
if isinstance(edge,list):
returnList=[]
for subObject in edge:
returnList.append(SplitEdge(subObject,np,add,inf
a,dim))
return returnList
#else:
# Get the input shape(s)
edge=GetObject(edge,'GEOM')
father=None
if infa==True:
father=edge
## Check the input shape existence
if "error" in [edge]:
return
#else:
# Create the points
points=[]
for parameter in [float(i)/(np-1) for i in range
(np)]:
points.append(geompy.MakeVertexOnCurve(e
dge,parameter))
#if dim==0:# If the output dimension is 0...
# Create the vertex compound
pointCompound=geompy.MakeCompound(points
)
## Add and return the resulting shape(s)
if add==True:
AddToStudy(pointCompound,"SplitE
dge (Vertexes)",father)
return pointCompound
#else:
# Partition the edge
partition=geompy.MakePartition([edge],po
ints)
## Explode the partition in edges
edges=geompy.SubShapeAll(partition,geomp
y.ShapeType["EDGE"])
## Create the wire
wire=geompy.MakeWire(edges)
## Add and return the resulting shape(s)
if add==True:
AddToStudy(wire,"SplitEdge",fath
er)
return wire
#-
def FuseCoplanarFaces(face1,face2,add=True):
"""
Completely fuses two coplanar Faces.
tring
tring
Argument(s):
Name
Description
Type
Default Value
face1 First face to fuse. / Its name in the study tree.
face2 Second face to fuse. / Its name in the study tree.
add
See the documentation. Boolean
True
Returned Value(s):
dim Value
Type
Face
1
"""
Number Name
"FusedFace"
Face / S
Face / S
fusedFace=geompy.MakeTranslationVectorDistance(fusedFace,normal,
-cuttingPlanePosition)
## Add and return the resulting shape(s)
if add==True:
AddToStudy(fusedFace,"FusedFace")
return fusedFace
#-
def RebuildFace(face,np=30,rel=False,switch=False,tol=1e-7,add=True,infa=False,d
im=2):
"""
Rebuilds a Face using its extrapolated iso-lines.
Argument(s):
Name
Description
Type
Default Value
face
The face to rebuild. / Its name in the study tree.
Face / S
tring np
See here.
Integer
20
rel
If equals True, the function try to relimit the rebuild face usi
ng the source face edges.
Boolean
False
switch If equals True, the iso-curves are switched from iso-u to iso-v.
Boolean
False
tol
See here.
Float 1e-7
add
See here.
Boolean
True
infa
See here.
Boolean
False
dim
See here.
Integer
2
Returned Value(s):
dim Value
Type
Number Name
1
Compound of Edges
1
2
Edge
1
"RebuiltFace"
"RebuiltFace (Edges)"
"""
if dim==0 or dim==3:
return
else:
# Make this function recursive
if isinstance(face,list):
returnList=[]
for subObject in face:
returnList.append(RebuildFace(subObject,np,switc
h,add,infa,dim))
return returnList
#else:
# Get the input shape(s)
face=GetObject(face,'GEOM')
father=None
if infa==True:
father=face
## Check the input shape existence
if "error" in [face]:
return
#else:
# Get the sub-shapes
face=GetSubShapes(face)
## Create the iso curves
isoCurves=[]
for i in [n/float(np) for n in range(np+1)]:
isoCurveVertexes=[]
for j in [n/float(np) for n in range(np+
1)]:
if switch==True:
newIsoCurveVertex=geompy
.MakeVertexOnSurface(face[-1],j,i)
else:
newIsoCurveVertex=geompy
.MakeVertexOnSurface(face[-1],i,j)
isoCurveVertexes.append(newIsoCu
rveVertex)
newIsoCurve=geompy.MakeInterpol(isoCurve
Vertexes)
isoCurves.append(newIsoCurve)
## Put them into a compound
isoCurveCompound=geompy.MakeCompound(isoCurves)
#if dim==1:# If the output dimension is 1...
# Add and return the resulting shape(s)
if add==True:
AddToStudy(isoCurveCompound,"Reb
uiltFace (Edges)",father)
return isoCurveCompound
#else:
# Create the filling from this compound
filling=geompy.MakeFilling(isoCurveCompo
und,theMinDeg = 10,theMaxDeg = 20,theTol2D=1e-5,theTol3D=1e-5)
## Relimitate the filling
rebuildFace=filling
if rel==True:
projectedEdges=[]
for edge in face[1]:
try:
projectedEdge=ge
ompy.MakeProjection(edge,filling)
projectedEdges.a
ppend(projectedEdge)
except:
pass
if len(projectedEdges)>0:
fillingPartition=geompy.
MakePartition([filling],projectedEdges)
fillingPartitionFaces=ge
ompy.SubShapeAll(fillingPartition,geompy.ShapeType["FACE"])
for fillingPartitionFace
in fillingPartitionFaces:
fillingPartition
FaceVertexes=geompy.SubShapeAll(fillingPartitionFace,geompy.ShapeType["VERTEX"])
match=True
for fillingParti
tionFaceVertex in fillingPartitionFaceVertexes:
projecte
dEdgeCompound=geompy.MakeCompound(projectedEdges)
minDista
nce=geompy.MinDistance(fillingPartitionFaceVertex,projectedEdgeCompound)
if minDi
stance>tol:
match=False
if match==True:
rebuildF
ace=fillingPartitionFace
break
AddToStudy(rebuildFace,"RebuiltF
ace",father)
return filling
#-
def RemoveFaceExtraEdges(face,tol=1e-7,add=True,infa=False):
"""
Does the same as the geompy.RemoveExtraEdges function of Salome (Repair
> Remove Extra Edges) but applies on a Face instead of on a Solid.
Argument(s):
Name
Description
Type
face
Face from which remove
Face / String tol
See the documentation.
add
See the documentation.
infa
See the documentation.
Returned Value(s):
dim Value
Type
Face
1
"""
Default Value
extra edges. / Its name in the study tree
Float 1e-7
Boolean
Boolean
True
False
Number Name
"FaceWithoutExtraEdges"
if match==True:
fixedFace=explodedFace
break
def MakeEdgeOffset(edge,dist,pos=[0,1],face=None,plane=None,np=50,tol=1e-7,rev=F
alse,add=True,infa=False,dim=1):
"""
Creates an offset of an Edge.
Argument(s):
Name
Description
Type
Default Value
edge
Source curve. / Its name in the study tree.
Edge / String
dist
Offset distance. Must be an array to create a variable offset.
Float / Array of Floats
pos
Positions on the source edge (0 < pos < 1). Only necessary if th
e dist argument is an array.
Array of Floats
[0,1]
face
See the documentation. Face / String None
plane See the documentation. If the input edge is straight, the defaul
t plane is the OXY plane.
Face / String None
np
See the documentation. Integer
50
tol
See the documentation. Float 1e-7
rev
See the documentation. Boolean
False
add
See the documentation. Boolean
True
infa
See the documentation. Boolean
False
dim
See the documentation. Integer
1
Returned Value(s):
dim Value
Type
Number Name
0
Compound of Vertexes
1
1
Compound of Edges
1
"Offset (Vertexes)"
"Offset"
Conditions of Use:
The input edge has to be open.
In addition, if the input edge is straight, it is also necessary to set
the face or the plane argument so as the function knows the offset direction
"""
if dim>1:
return
else:
# Make this function recursive
if isinstance(edge,list):
returnList=[]
for subObject in edge:
returnList.append(MakeEdgeOffset(subObject,dist,
pos,face,plane,np,rev,add,infa,dim))
return returnList
#else:
# Get the input shape(s)
[edge,face,plane]=GetObject([edge,face,plane],'GEOM')
father=None
if infa==True:
father=edge
## Check the input shape existence
if "error" in [edge,face,plane]:
return
#else:
# Get the sub-shapes
edge=GetSubShapes(edge)
#offsetEdges=[]
if face==None:# If no face is given by the user.
..
if plane==None:# And if no plane is give
n by the user...
# Close the input edge
closingEdge=geompy.MakeEdge(edge
[0][0],edge[0][1])
closedContour=geompy.MakeWire([e
dge[-1],closingEdge])
#if abs(geompy.BasicProperties(cl
osingEdge)[0]-geompy.BasicProperties(edge[-1])[0])<tol:# If the input wire is st
raight...
# Use the OXY plane
plane=geompy.MakeFaceHW(
10, 10, 1)
#else:
# Get the wire plane
plane=geompy.MakeFace(cl
osedContour,True)
#-
if isinstance(dist,list):
#### Here the numpy function int
erp() was replaced by code doing the same thing.
#offsetDistance=numpy.interp(par
ameter,pos,dist)
for i in range(len(pos)-1):
if parameter>=pos[i] and
parameter<pos[i+1]:
slope=(dist[i+1]
-dist[i])/(pos[i+1]-pos[i])
offsetDistance=d
ist[i]+(parameter-pos[i])*slope
if parameter==pos[-1]:
offsetDistance=dist[-1]
####else:
offsetDistance=dist
if rev == True:
offsetDistance*=-1.0
offsetVertex=geompy.MakeTranslationVecto
rDistance(vertex,normal,offsetDistance)
offsetVertexes.append(offsetVertex)
#if dim==0:# If the output dimension is 0...
# Create the vertex compound
offsetVertexCompound=geompy.MakeCompound
(offsetVertexes)
## Add and return the resulting shape(s)
if add==True:
AddToStudy(offsetVertexCompound,
"EdgeOffset (Vertexes)",father)
return offsetVertexCompound
#else:
# Create the offset spline
offsetSpline=geompy.MakeInterpol(offsetV
ertexes)
offsetEdges.append(offsetSpline)
## Create the intermediate edges
offsetVertexes=geompy.SubShapeAll(offset
Spline,geompy.ShapeType["VERTEX"])
intermediateEdge=geompy.MakeEdge(geompy.
MakeVertexOnCurve(edge[-1],0),offsetVertexes[0])
#intermediateEdge=geompy.MakeEdge(edge[0
][0],offsetVertexes[0])
offsetEdges.append(intermediateEdge)
intermediateEdge=geompy.MakeEdge(geompy.
MakeVertexOnCurve(edge[-1],1),offsetVertexes[1])
#intermediateEdge=geompy.MakeEdge(edge[0
][1],offsetVertexes[1])
offsetEdges.append(intermediateEdge)
## Put the intermediate edges into a comp
ound
offsetEdges=geompy.MakeCompound(offsetEd
ges)
## Add and return the resulting shape(s)
if add==True:
AddToStudy(offsetEdges,"EdgeOffs
et",father)
return offsetEdges
#-
def ExtendViscousLayer(wire,dist,face=None,plane=None,scale=1,ratio=1,style='smo
oth',coef=0.5,tol=1e-7,rev=False,add=True,infa=False):
"""
Extends a 2D trailing edge viscous layer.
Argument(s):
Name
Description
Type
Default Value
wire
Source wire. / Its name in the study tree.
Wire / String
dist
Length of the extension.
Float face
See the documentation. Face / String None
plane See the documentation. If the input edge is straight, the defaul
t plane is the OXY plane.
Face / String None
scale Scale coefficient applied on the source middle edge before being
"projected" on the end wire. Float 1
ratio Ratio between the ending wire length and the source wire length.
Float 1
style See the documentation. String "smooth"
coef
Coefficient of curvature of the edges (0 < coef < 1). Float
0.5
tol
See the documentation. Float 1e-7
rev
See the documentation. Boolean
False
add
See the documentation. Boolean
True
infa
See the documentation. Boolean
False
Returned Value(s):
dim Value
Type
Number Name
Compound of Edges
1
"ViscousLayerExtension"
Conditions of Use:
The input wire has to contain two or three connected edges.
In addition, if the input wire is straight, it is also necessary to set
the face or the plane argument so as the function knows the extension direction
"""
# Make this function recursive
if isinstance(wire,list):
returnList=[]
for subObject in wire:
returnList.append(ExtendViscousLayer(subObject,dist,face
,plane,scale,ratio,style,coef,rev,add,infa))
return returnList
#else:
# Get the input shape(s)
[wire,face,plane]=GetObject([wire,face,plane],'GEOM')
father=None
if infa==True:
father=wire
## Check the input shape existence
if "error" in [wire,face,plane]:
return
#else:
# Get the sub-shapes
wire=GetSubShapes(wire)
## Sort vertexes
extremumVertexes=[]
insideVertexes=[]
for wireVertex in wire[0]:
nbContacts=0
for wireEdge in wire[1]:
minDistance=geompy.MinDistance(wireEdge,
wireVertex)
if minDistance==0:
nbContacts+=1
if nbContacts==2:
insideVertexes.append(wireVertex)
else:
extremumVertexes.append(wireVertex)
plane=geompy.MakeFaceHW(10, 10,
1)
#else:
# Get the wire plane
plane=geompy.MakeFace(closedCont
our,True)
#-
scaledEndEdgeFirstVertex=geompy.MakeTranslationV
ectorDistance(endEdgeMiddleVertex,endEdge,-endEdgeLength/2)
scaledEndEdgeLastVertex=geompy.MakeTranslationVe
ctorDistance(endEdgeMiddleVertex,endEdge,endEdgeLength/2)
endEdge=geompy.MakeEdge(scaledEndEdgeFirstVertex
,scaledEndEdgeLastVertex)
## Create the inside extension edges
extensionEdges=[]
insideEndEdgeVertexes=[]
for i in range(edgeNumber-1):
extremumEdgeLength=geompy.MinDistance(insideVert
exes[i],extremumVertexes[i])
endRatio=extremumEdgeLength/wireLength
if i==1:
endRatio=1.0-endRatio
insideEndEdgeVertex=geompy.MakeVertexOnCurve(end
Edge,endRatio)
insideEndEdgeVertexes.append(insideEndEdgeVertex
)
insideExtensionEdge=geompy.MakeEdge(insideVertex
es[i],insideEndEdgeVertex)
if style=='smooth':
insideExtensionEdgeMiddleVertex=geompy.M
akeVertexOnCurve(insideExtensionEdge,0.5)
TranslatedInsideExtensionEdgeMiddleVerte
x=geompy.MakeTranslationVectorDistance(insideExtensionEdgeMiddleVertex,extension
Direction,dist/2*coef)
insideExtensionEdge=geompy.MakeInterpol(
[insideVertexes[i],TranslatedInsideExtensionEdgeMiddleVertex,insideEndEdgeVertex
])
extensionEdges.append(insideExtensionEdge)
## Create extremum extension edges
endEdgeVertexes=geompy.SubShapeAll(endEdge,geompy.ShapeT
ype["VERTEX"])
for i in range(2):
extremumExtensionEdge=geompy.MakeEdge(endEdgeVer
texes[i],extremumVertexes[i])
if style=='smooth':
extremumExtensionEdgeMiddleVertex=geompy
.MakeVertexOnCurve(extremumExtensionEdge,0.5)
TranslatedExtremumExtensionEdgeMiddleVer
tex=geompy.MakeTranslationVectorDistance(extremumExtensionEdgeMiddleVertex,exten
sionDirection,dist/2*coef)
extremumExtensionEdge=geompy.MakeInterpo
l([endEdgeVertexes[i],TranslatedExtremumExtensionEdgeMiddleVertex,extremumVertex
es[i]])
extensionEdges.append(extremumExtensionEdge)
## Partition end edge
endEdgePartition=geompy.MakePartition([endEdge],insideEn
dEdgeVertexes)
endEdges=geompy.SubShapeAll(endEdgePartition,geompy.Shap
eType["EDGE"])
extensionEdges+=endEdges
## Put the resulting shapes into a compound
extensionEdges=geompy.MakeCompound(extensionEdges)
## Add and return the resulting shape(s)
if add==True:
AddToStudy(extensionEdges,"ViscousLayerExtension
",father)
return extensionEdges
#-
def CloseViscousLayer(wire,dist='auto',face=None,plane=None,style='smooth',tol=1
e-7,rev=False,add=True,infa=False):
"""
Closes a 2D viscous layer.
Argument(s):
Name
Description
Type
Default Value
wire
Source wire. / Its name in the study tree.
Wire / String
dist
Length of the extension. If equls "auto", the length is automati
cally calculated by the function.
Float / String "auto"
face
See the documentation. Face / String None
plane See the documentation. If the input edge is straight, the defaul
t plane is the OXY plane.
Face / String None
style See the documentation. String "smooth"
tol
See the documentation. Float 1e-7
rev
See the documentation. Boolean
False
add
See the documentation. Boolean
True
infa
See the documentation. Boolean
False
Returned Value(s):
dim Value
Type
Number Name
Compound of Edges
1
"ViscousLayerClosing"
Conditions of Use: ^
The input wire has to contain two or three connected edges.
In this case, the smooth style can only be used if the wire is straight.
Finally, if the input wire is straight, it is also necessary to set the face or
the plane argument so as the function knows the closing direction.
"""
# Make this function recursive
if isinstance(wire,list):
returnList=[]
for subObject in wire:
returnList.append(CloseViscousLayer(subObject,dist,face,
plane,style,tol,rev,add,infa))
return returnList
#else:
# Get the input shape(s)
[wire,face,plane]=GetObject([wire,face,plane],'GEOM')
father=None
if infa==True:
father=wire
#-
if nbContacts==2:
insideVertexes.append(wireVertex)
else:
outsideVertexes.append(wireVertex)
closingEdge=geompy.MakeEdge(outsideVertexes[0],o
utsideVertexes[1])
closedContour=geompy.MakeWire([wire[-1],closingE
dge])
#if plane==None:# And if no plane is given by the
user...
if abs(geompy.BasicProperties(closingEdg
e)[0]-geompy.BasicProperties(wire[-1])[0])<tol:# If the input wire is straight..
.
# Use the OXY plane
plane=geompy.MakeFaceHW(10, 10,
1)
#else:
# Get the wire plane
plane=geompy.MakeFace(closedCont
our,True)
#-
if nbContacts==1:
externalEdges.append(edge)
externalEdgeInsideVertex=None
externalEdgeOutideVertex=None
for externalEdgeVertex in externalEdgeVertexes:
minDistance=geompy.MinDistance(externalE
dgeVertex,insideVertexCompound)
if minDistance==0:
externalEdgeInsideVertex=externa
lEdgeVertex
else:
externalEdgeOutideVertex=externa
lEdgeVertex
closingClosingEdge=geompy.MakeEdge(translatedIns
ideVertexes[0],translatedInsideVertexes[1])
outputEdges.append(closingClosingEdge)
#if len(wire[1])==2:# If there are two edges in the input
wire...
# Create the output edge compound
outputEdgeCompound=geompy.MakeCompound(outputEdg
es)
## Glue the edges
gluedOutputEdgeCompound=geompy.MakeGlueEdges(out
putEdgeCompound,tol)
## Explode the glued compound
outputEdges=geompy.SubShapeAll(gluedOutputEdgeCo
mpound,geompy.ShapeType["EDGE"])
## Put the intermediate edges into a compound
outputEdges=geompy.MakeCompound(outputEdges)
## Add and return the resulting shape(s)
if add==True:
AddToStudy(outputEdges,"ViscousLayerClosing",fat
her)
return outputEdges
#-
def PropagateViscousLayerIntersection(compound,dir="auto",tol=1e-6,add=True,infa
=False):
"""
Propagates the intersection into two intersecting viscous layers.
Argument(s):
Name
Description
Type
Default Value
compound
Source compound of edges. / Its name in the study tree.
Compound of Edges / String
dir
Equals 'x', 'y' or 'z' to impose the approximate direction of th
e propagation, 'auto' to let the function decide by itself. (Used to sort inters
ection vertexes.)
String "auto"
tol
See the documentation. Float 1e-6
add
See the documentation. Boolean
True
infa
See the documentation. Boolean
False
Returned Value(s):
dim Value
Type
Number Name
Compound of Edges
1
"IntersectionPropagation"
Conditions of Use:
The source compound has to be planar and must contain only 'parallel' ed
ges (in the 'blocking' sense) of the two viscous layers.
"""
# Make this function recursive
if isinstance(compound,list):
returnList=[]
for subObject in compound:
returnList.append(PropagateViscousLayerIntersection(subO
bject,dir,tol,add,infa))
return returnList
#else:
# Get the input shape(s)
compound=GetObject(compound,'GEOM')
father=None
if infa==True:
father=compound
## Check the input shape existence
if "error" in [compound]:
return
#-
else:
# Get the sub-shapes
compound=GetSubShapes(compound)
## Get the intersection vertexes
partition=geompy.MakePartition([compound[-1]],Limit=geom
py.ShapeType["VERTEX"])
partitionVertexes=geompy.SubShapeAll(partition,geompy.Sh
apeType["VERTEX"])
intersectionVertexes=[]
for partitionVertex in partitionVertexes:
isIntersectionVertex=True
for compoundVertex in compound[0]:
distance=geompy.MinDistance(partitionVer
tex,compoundVertex)
if distance==0:
isIntersectionVertex=False
if isIntersectionVertex==True:
intersectionVertexes.append(partitionVer
tex)
vertexIndex+=1
nextVertex=restingVertexes[nextVertexInd
ex]
reorderProjectedVertexes.append(nextVert
ex)
del restingVertexes[nextVertexIndex]
## Create intermediate edges
for reorderedVertexIndex in range(nbProjectedVer
texes-1):
firstIntermediateEdgeVertex=reorderProje
ctedVertexes[reorderedVertexIndex]
secondIntermediateEdgeVertex=reorderProj
ectedVertexes[reorderedVertexIndex+1]
distance=geompy.MinDistance(firstInterme
diateEdgeVertex,secondIntermediateEdgeVertex)
if distance > tol:
intermediateEdge=geompy.MakeEdge
(firstIntermediateEdgeVertex,secondIntermediateEdgeVertex)
intermediateEdges.append(interme
diateEdge)
return partition
#-
def MakeTipViscousLayer(foilEdge,offsetEdge,dist,face=None,style='smooth',np=200
,tol=1e-4,byParam=False,rev=False,add=True,infa=False,dim=3):
"""
Creates a tip viscous layer volume following a foil edge.
Argument(s):
Name
Description
Type
Default Value
foilEdge
Edge describing the foil. / Its name in the study tree.
Edge / String offsetEdge
Edge describing the upside boundary of the viscous layer
in the foil plane. / Its name in the study tree.
Edge / String dist
Offset distance normal to the wing tip.
Float face
See the documentation. Face / String None
style See the documentation. String "smooth"
np
See the documentation. Integer
200
tol
See the documentation. Float 1e-4
byParam
Defines if the function has to create two points at the
same position on the foil edge and on the offset edge respectively by using a sa
me distance from the edge beginning (True) or the same parameter on the edge (Fa
lse). In few cases, switch this parameter can give better results.
Boolean
False
rev
See the documentation. Boolean
False
add
See the documentation. Boolean
True
infa
See the documentation. Boolean
False
dim
See the documentation. Integer
3
Returned Value(s):
dim Value
Type
Number Name
1
Compound of Edge
2
"TipViscousLayer (Edges)"
2
Compound of Faces
1
"TipViscousLayer (Faces)"
3
Solid 1
"TipViscousLayer"
Conditions of Use:
The input edges has to be open.
"""
if dim==0:
return
else:
# Get the input shape(s)
[foilEdge,offsetEdge,face]=GetObject([foilEdge,offsetEdge,face],
'GEOM')
father=None
if infa==True:
father=foilEdge
#fillingEdges3D=[]
fillingEdges2D=[]
boundaryFaces=[]
if rev==True:
dist*=-1.0
for parameter in [1-n/float(np-1) for n in range(np)]:#
For each position on the foil edge...
# Create the vertexes
if byParam==True:
foilEdgeVertex=geompy.MakeVertexOnCurve(
foilEdge[-1],parameter)
else:
foilEdgeVertex=geompy.MakeVertexOnCurveB
yLength(foilEdge[-1],parameter*foilEdgeLength,foilEdge[0][0])
if reverseLength==True:
parameter=1.0-parameter
if byParam==True:
offsetEdgeVertex=geompy.MakeVertexOnCurv
e(offsetEdge[-1],parameter)
else:
offsetEdgeVertex=geompy.MakeVertexOnCurv
eByLength(offsetEdge[-1],parameter*offsetEdgeLength,offsetEdge[0][0])
translatedVertex=geompy.MakeTranslationVectorDis
tance(foilEdgeVertex,normalVector,dist)
## Create the 2D filling edge
fillingEdge2D=geompy.MakeEdge(foilEdgeVertex,off
setEdgeVertex)
fillingEdges2D.append(fillingEdge2D)
## Create the 3D filling edge
if style=='straight':
fillingEdge3D=geompy.MakeEdge(offsetEdge
Vertex,translatedVertex)
fillingEdges3D.append(fillingEdge3D)
elif style=='smooth':
fillingEdge3D=geompy.MakeArcOfEllipse(fo
ilEdgeVertex,offsetEdgeVertex,translatedVertex)
fillingEdges3D.append(fillingEdge3D)
#if parameter==0 or parameter==1:# If it is the f
irst or the last position...
# Create the boundary face
thirdEdge=geompy.MakeEdge(foilEdgeVertex
,translatedVertex)
boundaryFaces.append(geompy.MakeFaceWire
s([fillingEdge3D,fillingEdge2D,thirdEdge],True))
## Put the filling edges into compounds
fillingEdgeCompound2D=geompy.MakeCompound(fillingEdges2D
)
fillingEdgeCompound3D=geompy.MakeCompound(fillingEdges3D
)
## Add and return the resulting shape(s)
if dim==1:
if add==True:
AddToStudy(fillingEdgeCompound2D,"TipVis
cousLayer (Edges)",father)
AddToStudy(fillingEdgeCompound3D,"TipVis
cousLayer (Edges)",father)
return [fillingEdgeCompound2D,fillingEdgeCompoun
d3D]
#-
else:
# Create the fillings
filling2D=geompy.MakeFilling(fillingEdgeCompound
2D,theTol2D=1e-5,theTol3D=1e-5,theMethod=GEOM.FOM_AutoCorrect)
filling3D=geompy.MakeFilling(fillingEdgeCompound
3D,theTol2D=1e-5,theTol3D=1e-5,theMethod=GEOM.FOM_AutoCorrect)
## Extrude the foil edge
foilEdgeExtension=geompy.MakePrismVecH(foilEdge[
-1],normalVector,dist)
## Create the compound from faces
faceCompound=geompy.MakeCompound([filling2D,fill
ing3D,foilEdgeExtension,boundaryFaces[0],boundaryFaces[1]])
## Add and return the resulting shape(s)
if dim==2:
if add==True:
AddToStudy(faceCompound,"TipVisc
ousLayer (Faces)",father)
return faceCompound
#else:
# Glue the edges
gluingTolerance=tol
while True:
freeBoundaries=geompy.GetFreeBou
ndary(faceCompound)[1]
if len(freeBoundaries)==0:
break
faceCompound=geompy.MakeGlueEdge
s(faceCompound,gluingTolerance)
gluingTolerance*=2
## Create the shell form the compound
shell=geompy.MakeShell([faceCompound])
## Create the solid from the shell
solid=geompy.MakeSolid([shell])
## Add and return the resulting shape(s)
if add==True:
AddToStudy(solid,"TipViscousLaye
r",father)
return solid
#-
def ExtendTipViscousLayer(shell,compound,np=10,tol=1e-7,add=True,infa=False,dim=
3):
"""
Extends a tip viscous layer.
Argument(s):
Name
Description
Type
Default Value
shell Shell to extend. / Its name in the study tree. Shell / String
compound
Compound containing the guiding edges, like one built th
anks to the ExtendViscousLayer function. / Its name in the study tree. Compound
of Edges / String
np
See the documentation. Integer
10
tol
See the documentation. Float 1e-7
add
See the documentation. Boolean
True
infa
See the documentation. Boolean
False
dim
See the documentation. Integer
3
Returned Value(s):
dim Value
Type
Number Name
1
Compound of Edges
5/8
"TipViscousLayerExtension (Edges
Compound of Faces
2/3
"TipViscousLayerExtension (Faces
Compound of Solids
"TipViscousLayerExtension"
)"
)"
Conditions of Use:
The input shell has to contain 2 faces having the shape of triangles or
ellipse quarters and an optional middle face being a quadrangle. The edge compou
nd has to have all the caracteristics of a compound build with the ExtendViscous
Layer function.
"""
if dim==0:
return
else:
# Get the input shape(s)
[shell,compound]=GetObject([shell,compound],'GEOM')
father=None
if infa==True:
father=shell
## Check the input shape existence
if "error" in [shell,compound]:
return
#else:
# Get the sub-geometries
[shell,compound]=GetSubShapes([shell,compound])
## Keep edges touching the input shell
edges=[]
for edge in compound[1]:
minDistance=geompy.MinDistance(edge,shell[-1])
if minDistance<=tol:
edges.append(edge)
#-
# Sort edges
insideEdges=[]
outsideEdges=[]
for edge in edges:
edgeVertexes=geompy.SubShapeAll(edge,geompy.Shap
eType["VERTEX"])
for edgeVertex in edgeVertexes:
minDistance=geompy.MinDistance(edgeVerte
x,shell[-1])
if minDistance<=tol:
nbContacts=0
for face in shell[2]:
minDistance=geompy.MinDi
stance(edgeVertex,face)
if minDistance<=tol:
nbContacts+=1
if nbContacts==1:
outsideEdges.append(edge
)
else:
insideEdges.append(edge)
break
adjacentEdges=[]
for shellEdge in shellEdges:
minDistance=geompy.MinDistance(shellEdge
,insideEdge)
if minDistance<=tol:
adjacentEdges.append(shellEdge)
insideVertex=insideEdgeVertex
break
## Translate the inside edge
missingOutsideEdge=geompy.MakeTranslationTwoPoin
ts(insideEdge,insideVertex,outsideVertex)
missingOutsideEdges.append(missingOutsideEdge)
### Add the missing outside edges to the edge list
pathEdges=edges+missingOutsideEdges
## Create the fillings
fillings=[]
fillingEdgeCompounds=[]
i=0
for shellEdge in shellEdges:# For each edge of the face
compound...
# Get the edge style
shellEdgeLength=geompy.BasicProperties(shellEdge
)[0]
shellEdgeVertexes=geompy.SubShapeAll(shellEdge,g
eompy.ShapeType["VERTEX"])
rebuiltStraightEdge=geompy.MakeEdge(shellEdgeVer
texes[0],shellEdgeVertexes[1])
rebuiltStraightEdgeLength=geompy.BasicProperties
(rebuiltStraightEdge)[0]
if abs(shellEdgeLength-rebuiltStraightEdgeLength
)<=tol:
style='straight'
else:
style='smooth'
nsideEdge,shellEdgeAdjacentEdgeCompound)
if minDistance<=tol:
centerEdge=insideEdge
break
if nbContacts==2:
faceFillings.append(fill
ing)
def CloseTipViscousLayer(shell,compound,np=20,tol=1e-7,add=True,infa=False,dim=3
):
"""
Close a tip viscous layer.
Argument(s):
Name
Description
Type
Default Value
shell Shell to extend. / Its name in the study tree. Shell / String
compound
y tree.
np
tol
add
infa
dim
Returned Value(s):
dim Value
Type
Number
1
Compound of Edges
2
Compound of Faces
3
Compound of Solids
Name
4/6
2/3
1
"TipViscousLayerClosing (Edges)"
"TipViscousLayerClosing (Faces)"
"TipViscousLayerClosing"
Conditions of Use:
The input shell has to contain 2 faces having the shape of triangles or
ellipse quarters and an optional middle face being a quadrangle. The edge compou
nd has to have all the caracteristics of a compound build with the CloseViscousL
ayer function.
"""
if dim==0:
return
else:
shapesToReturn=[]
# Get the input shape(s)
[shell,compound]=GetObject([shell,compound],'GEOM')
father=None
if infa==True:
father=shell
## Check the input shape existence
if "error" in [shell,compound]:
return
#else:
# Get the sub-shapes
[shell,compound]=GetSubShapes([shell,compound])
## Get the start edges
startEdges=[]
for shellEdge in shell[1]:# For each edge in the face co
mpound...
shellEdgeVertexes=geompy.SubShapeAll(shellEdge,g
eompy.ShapeType["VERTEX"])
# Get the number of adjacent face
nbAdjacentFaces=0
for face in shell[2]:
nbContacts=0
for shellEdgeVertex in shellEdgeVertexes
:
minDistance=geompy.MinDistance(s
hellEdgeVertex,face)
if minDistance<=tol:
nbContacts+=1
if nbContacts==2:
nbAdjacentFaces+=1
if nbContacts==2:
adjacentFace=face
break
#-
fillingEdge2D=geompy.MakeEdge(centerVert
ex,vertex)
fillingEdges3D.append(fillingEdge3D)
fillingEdges2D.append(fillingEdge2D)
#if parameter==0:
# Create the start face
startFaceWire=geompy.MakeWire([c
enterEdge,fillingEdge2D,fillingEdge3D])
startFace=geompy.MakeFace(startF
aceWire,True)
#if parameter==1:
# Create the end face
endFaceWire=geompy.MakeWire([cen
terEdge,fillingEdge2D,fillingEdge3D])
endFace=geompy.MakeFace(endFaceW
ire,True)
#-
OM_AutoCorrect)
## Remove the extra edges
filling2D=RemoveFaceExtraEdges(filling2D
,add=False)
filling3D=RemoveFaceExtraEdges(filling3D
,add=False)
## Create the filling compound
fillingShell=geompy.MakeShell([startFace
,endFace,filling2D,filling3D])
#if dim==2:
shapesToReturn.append(fillingShe
ll)
else:
# Sew the shell
sewingTolerance=tol
while True:
freeBoundaries=geompy.Ge
tFreeBoundary(fillingShell)[1]
if len(freeBoundaries)==
0:
break
fillingShell=geompy.Make
Sewing(fillingShell,sewingTolerance)
sewingTolerance*=2
## Create the solid
solids.append(geompy.MakeSolid([
fillingShell]))
#-
if nbContacts>=2:
nbAdjacentStartEdges+=1
if nbAdjacentStartEdges==0:
insideFaces.append(face)
insideFaceEdgeVertexes=geompy.SubShapeAl
l(insideFaceEdge,geompy.ShapeType["VERTEX"])
for insideFaceEdgeVertex in insideFaceEd
geVertexes:
minDistance=geompy.MinDistance(i
nsideFaceEdgeVertex,compound[-1])
if minDistance<=tol:
nbContacts+=1
if nbContacts==2:
centerEdge=insideFaceEdge
## Get the first path edge
minDistance=geompy.MinDistance(insideFac
eEdge,compound[-1])
if minDistance>tol:
pathEdges.append(insideFaceEdge)
## Get the second path edge
for edge in compound[1]:
minDistance=geompy.MinDistance(edge,shel
l[-1])
if minDistance>tol:
pathEdges.append(edge)
firstVertex0=geompy.SubShapeAll(centerEdge,geomp
y.ShapeType["VERTEX"])[0]
firstVertex1=geompy.SubShapeAll(pathEdges[0],geo
mpy.ShapeType["VERTEX"])[0]
lastVertex1=geompy.SubShapeAll(pathEdges[0],geom
py.ShapeType["VERTEX"])[1]
firstVertex1AdjacentEdge=None
for edge in compound[1]:
minDistance=geompy.MinDistance(edge,firs
tVertex0)
if minDistance<=tol:
firstVertex1AdjacentEdge=edge
break
pathEdgeVertexes=geompy.SubShapeAll(pathEdges[1]
,geompy.ShapeType["VERTEX"])
firstVertex2=None
lastVertex2=None
for pathEdgeVertex in pathEdgeVertexes:
minDistance=geompy.MinDistance(pathEdgeV
ertex,firstVertex1AdjacentEdge)
if minDistance<=tol:
firstVertex2=pathEdgeVertex
else:
lastVertex2=pathEdgeVertex
1],lastVertex2)
#for parameter in [n/float(np-1) for n in range(n
p)]:
# Create the vertexes
vertex0=geompy.MakeVertexOnCurveByLength
(centerEdge,parameter*length0,firstVertex0)
vertex1=geompy.MakeVertexOnCurveByLength
(pathEdges[0],parameter*length1,firstVertex1)
vertex2=geompy.MakeVertexOnCurveByLength
(pathEdges[1],parameter*length2,firstVertex2)
## Create the filling edges 3D
if style=='straight':
fillingEdge3D=geompy.MakeEdge(ve
rtex1,vertex2)
elif style=='smooth':
fillingEdge3D=geompy.MakeArcOfEl
lipse(vertex0,vertex1,vertex2)
fillingEdges3D.append(fillingEdge3D)
## Create the filling edges 2D
fillingEdge2D=geompy.MakeEdge(vertex0,ve
rtex2)
fillingEdges2D.append(fillingEdge2D)
#if parameter==0:
# Create the start face
startFaceWire=geompy.MakeWire([s
tartFaceEdge1,startFaceEdge2,fillingEdge3D])
startFace=geompy.MakeFace(startF
aceWire,True)
#if parameter==1:
# Create the end face
endFaceWire=geompy.MakeWire([end
FaceEdge1,endFaceEdge2,fillingEdge3D])
endFace=geompy.MakeFace(endFaceW
ire,True)
#-
sewingTolerance=tol
while True:
freeBoundaries=geompy.Ge
tFreeBoundary(fillingShell)[1]
if len(freeBoundaries)==
0:
break
fillingShell=geompy.Make
Sewing(fillingShell,sewingTolerance)
sewingTolerance*=2
## Create the solid
solids.append(geompy.MakeSolid([
fillingShell]))
#-
#if dim==1:
if add==True:
AddToStudy(shapesToReturn,"TipViscousLay
erClosing (Edges)",father)
return shapesToReturn
elif dim==2:
if add==True:
AddToStudy(shapesToReturn,"TipViscousLay
erClosing (Faces)",father)
return shapesToReturn
else:
# Put the solids into a compound
solids=geompy.MakeCompound(solids)
def MakeLinkingSolids(faceCompound1,edgeCompound,faceCompound2,tol=1e-7,add=True
,dim=3):
"""Creates solids linking two sets of faces.
Argument(s):
Name
Description
Type
Default Value
faceCompound1 Compound of source faces. / Its name in the study tree.
Compound of Faces / String
edgeCompound
Compound of edges linking all vertexes of source and tar
get compound of faces. / Its name in the study tree.
Compound of Edges / Stri
ng
faceCompound2 Compound of target faces. / Its name in the study tree.
Compound of Faces / String
tol
See the documentation. Float 1e-7
add
See the documentation. Boolean
True
dim
See the documentation. Integer
3
Returned Value(s):
dim Value
Type
Number Name
2
Compound of Faces
n
3
Compound of Solids
1
"LinkingSolids (Faces)"
"LinkingSolids"
Conditions of Use:
All the vertexes of the input face compounds have to be linked together
with one of the edges of the edge compound.
"""
#def Function(compound='Compound_1',tol=1e-7,add=True):
if dim<2:
return
else:
shapesToReturn=[]
#### Here is the code to sort sub-shapes when putting everything
into one compound.
#### But since this operation can be very long, in this version
the user has to
#### give the source and target faces as well as the linking edg
es
#### in separated compounds.
## Get the source shapes
#if isinstance(compound,str):
#compoundName=compound
#compound=salome.myStudy.FindObjectByName(compoundName,"
GEOM")[0].GetObject()
#### Get the sub-shapes
#faces=geompy.SubShapeAll(compound,geompy.ShapeType["FACE"])
#edges=geompy.SubShapeAll(compound,geompy.ShapeType["EDGE"])
#### Sort the faces
#adjacentFaceCompounds=[]
#nbFaces=len(faces)
#while(nbFaces>0):# While there are triangles not assigned to a
group of adjacent triangles...
#adjacentFaces=[]
## Put one of the faces in a compound
#adjacentFaceCompound=geompy.MakeCompound([faces[0]])
###faceToDeleteIndexes=[]
#for i in range(nbFaces):# For each of the faces...
## Get the distance with the compound
#minDistance=geompy.MinDistance(faces[i],adjacen
tFaceCompound)
###if minDistance<=tol:# If the face is adjacent t
o the compound...
## Put this face in the compound and in
the list
#adjacentFaceCompound=geompy.MakeCompoun
d([adjacentFaceCompound,faces[i]])
#adjacentFaces.append(faces[i])
#### Save the index of this face
#faceToDeleteIndexes.append(i)
###i+=1
## Add the adjacent faces to the list
#adjacentFaceCompounds.append(adjacentFaceCompound)
#### Delete from the face list the faces which were put in
to the adjacent list
#i=0
#for faceToDeleteIndex in faceToDeleteIndexes:
#del faces[faceToDeleteIndex-i]
#i+=1
###nbFaces=len(faces)
#### Get linking edges
#linkingEdges=[]
#for edge in edges:
#minDistance1=geompy.MinDistance(edge,adjacentFaceCompou
nds[0])
#minDistance2=geompy.MinDistance(edge,adjacentFaceCompou
nds[1])
#if minDistance1<=tol and minDistance2<=tol:
#linkingEdges.append(edge)
[faceCompound1,edgeCompound,faceCompound2]=GetObject([faceCompou
nd1,edgeCompound,faceCompound2],'GEOM')
## Check the input shape existence
if "error" in [faceCompound1,edgeCompound,faceCompound2]:
return
#else:
# Get the sub-shapes
[faceCompound1,edgeCompound,faceCompound2]=GetSubShapes(
[faceCompound1,edgeCompound,faceCompound2])
###### Create the solids
solids=[]
for face1 in faceCompound1[2]:# For each face of the fac
e compound 1...
# Get the linking edges
face1LinkingEdges=[]
for edge in edgeCompound[1]:
minDistance=geompy.MinDistance(edge,face
1)
if minDistance<=tol:
face1LinkingEdges.append(edge)
if nbContact==nbFace1LinkingEdges:
face1TargetFace=face2
break
nbContact=0
for face1EdgeLinkingEdge in face
1EdgeLinkingEdges:
minDistance=geompy.MinDi
stance(face1EdgeLinkingEdge,face1TargetFaceEdge)
if minDistance<=tol:
nbContact+=1
if nbContact==2:
face1EdgeTargetEdge=face
1TargetFaceEdge
while True:
freeBoundaries=geompy.GetFreeBou
ndary(face1Shell)[1]
if len(freeBoundaries)==0:
break
face1Shell=geompy.MakeGlueEdges(
face1Shell,sewingTolerance)
sewingTolerance*=2
## Create the solid
face1Shell=geompy.MakeShell([face1Shell]
)
face1Solid=geompy.MakeSolid([face1Shell]
)
solids.append(face1Solid)
#-
#if dim==2:
if add==True:
AddToStudy(shapesToReturn,"LinkingSolids
(Faces)")
return shapesToReturn
else:
# Put the solids into a compound
solids=geompy.MakeCompound(solids)
## Add and return the resulting shape(s)
if add==True:
AddToStudy(solids,"LinkingSolids")
return solids
#-
def GetBoundaryFaces(compound,add=True):
#def GetBoundaryFaces(compound,tol=1e-7,add=True):
"""
Get the boundary faces of a solid compound and put them in a group.
Argument(s):
Name
Description
Type
compound
Source compound
Compound of Solids / String
add
See the documentation.
Default Value
of solids. / Its name in the study tree.
Boolean
True
Returned Value(s):
dim Value
Type
Number Name
Group of Faces 1
"BoundaryFaces"
"""
# Make this function recursive
if isinstance(compound,list):
returnList=[]
for subObject in compound:
returnList.append(GetBoundaryFaces(compound,tol,add))
return returnList
#else:
# Get the input shape(s)
compound=GetObject(compound,'GEOM')
## Check the input shape existence
if "error" in [compound]:
return
#else:
# Get the sub-shapes
compound=GetSubShapes(compound)
## Get the boundary face IDs
boundaryFaceIDs=geompy.GetFreeFacesIDs(compound[-1])
## Create the boundary face group
boundaryFaceGroup=geompy.CreateGroup(compound[-1],geompy
.ShapeType["FACE"])
#for face in compound[2]:# For each face of the compound.
..
# Get the face ID
faceID=geompy.GetSubShapeID(compound[-1],face)
## Put the face in the group
if faceID in boundaryFaceIDs:
geompy.AddObject(boundaryFaceGroup,faceI
D)
## Add and return the resulting shape(s)
if add==True:
AddToStudy(boundaryFaceGroup,"BoundaryFaces",fat
her=compound[-1])
return boundaryFaceGroup
### Get the boundaryFaces
#boundaryFaces=[]
#for face in faces:# For each face of the compound...
#faceVertexes=geompy.SubShapeAll(face,geompy.Sha
peType["VERTEX"])
#nbFaceVertexes=len(faceVertexes)
#faceVertexCompound=geompy.MakeCompound(faceVert
exes)
#nbSolidContact=0
## Get the number of adjacent solids
#for solid in solids:
#solidVertexes=geompy.SubShapeAll(solid,
geompy.ShapeType["VERTEX"])
#nbVertexContact=0
#for solidVertex in solidVertexes:
#minDistance=geompy.MinDistance(
solidVertex,faceVertexCompound)
#if minDistance<=tol:
#nbVertexContact+=1
#if nbVertexContact==nbFaceVertexes:
#nbSolidContact+=1
##-
def GetTriEdgeFaces(shape,tol=1e-7,add=True):
"""
Get all the surfaces having three edges and put them in separated groups
.
ee.
Argument(s):
Name
Description
Type
Default Value
shape Shape in which looking for triangles. / Its name in the study tr
Any geometrical object / String
tol
See the documentation. Float 1e-7
add
See the documentation. Boolean
True
Returned Value(s):
dim Value
Type
Number Name
Group of Faces n
"TriEdgeFace"
"""
# Make this function recursive
if isinstance(shape,list):
returnList=[]
for subObject in shape:
returnList.append(GetTriEdgeFaces(shape,tol,disp))
return returnList
#else:
# Get the input shape(s)
shape=GetObject(shape,'GEOM')
## Check the input shape existence
if "error" in [shape]:
return
#else:
# Get the sub-shapes
shape=GetSubShapes(shape)
## Get the triangles
shapeTriangles=[]
for shapeFace in shape[2]:
shapeFaceDescription=geompy.WhatIs(shapeFace)
if "EDGE : 3" in shapeFaceDescription:
shapeTriangles.append(shapeFace)
.MakeCompound([adjacentTriangleCompound,shapeTriangles[i]])
#adjacentTriangles.append(shapeT
riangles[i])
#### Save the index of this triang
le
#triangleToDeleteIndexes.append(
i)
###i+=1
## Add the adjacent triangles to the list
#adjacentTriangleLists.append(adjacentTriangles)
#### Delete from the triangle list the triangles w
hich were put into the adjacent list
#i=0
#for triangleToDeleteIndex in triangleToDeleteIn
dexes:
#del shapeTriangles[triangleToDeleteInde
x-i]
#i+=1
###nbShapeTriangles=len(shapeTriangles)
#### Create groups
#i=0
#gg=salome.ImportComponentGUI("GEOM")
#for adjacentTriangles in adjacentTriangleLists:# For ea
ch list of adjacent triangles...
## Create a group
#newGroup=geompy.CreateGroup(shape[-1],geompy.Sh
apeType["FACE"])
return shapeTriangleGroups
#-
def CopyGeometricalGroups(shape1,shape2,only=None,ignore=None,type=None,tol=1e-7
,add=True):
"""
Copies groups from a geometrical object to another according to the shap
e of group elements.
Argument(s):
Name
Description
Type
Default Value
shape1 Source geometrical object. / Its name in the study tree.
Any geometrical object / String
shape2 Target geometrical object. / Its name in the study tree.
Any geometrical object / String
only
List of names of groups to copy, excluding the others. Array of
Strings
None
ignore List of names of groups to ignore.
Array of Strings
None
type
Type of groups to copy. Can equal "vertex", "edge", "face" or "s
olid". Array of Strings
None
tol
See the documentation. Float 1e-7
add
See the documentation. Boolean
True
Returned Value(s):
dim Value
Type
Group n
Number Name
The name of the source group
Conditions of Use:
The groups inside the source shape must have each one a different name.
"""
if add==True:
gg=salome.ImportComponentGUI("GEOM")
# Get the input shape(s)
[shape1,shape2]=GetObject([shape1,shape2],'GEOM')
## Check the input shape existence
if "error" in [shape1,shape2]:
return
#else:
# Get the list of the IDs of all the shapes visible in the study
tree
visibleIDs=GetSubShapeNames(salome.myStudy.FindComponent('GEOM')
,output='ID')
## Get the shape 1 groups
groups1=geompy.GetGroups(shape1)
visibleGroups1=[]
for group1 in groups1:
group1ID=salome.ObjectToID(group1)
if group1ID in visibleIDs:
visibleGroups1.append(group1)
sortedShapeGroups1.append(visibleGroup1)
visibleGroups1=sortedShapeGroups1
sortedShapeGroups1=[]
if ignore!=None:
for visibleGroup1 in visibleGroups1:
visibleGroupsName1=visibleGroup1.GetName()
if visibleGroupsName1 not in ignore:
sortedShapeGroups1.append(visibleGroup1)
visibleGroups1=sortedShapeGroups1
sortedShapeGroups1=[]
if type!=None:
for visibleGroup1 in visibleGroups1:
visibleGroupType1=str(visibleGroup1.GetMaxShapeT
ype())
if visibleGroupType1==type.upper():
sortedShapeGroups1.append(visibleGroup1)
visibleGroups1=sortedShapeGroups1
## Get the shape 2 groups
groups2=geompy.GetGroups(shape2)
visibleGroups2=[]
for group2 in groups2:
group2ID=salome.ObjectToID(group2)
if group2ID in visibleIDs:
visibleGroups2.append(group2)
#shape2MatchedSubShapes=geompy.GetSharedShapes(shape2,gr
oup1,geompy.ShapeType[group1Type])
## Add the group to the list
newGroups2.append(newGroup2)
## Add the group to the study
if add==True:
try:
id=geompy.addToStudyInFather(shape2,newG
roup2,visibleGroup1Name)
gg.createAndDisplayGO(id)
if salome.sg.hasDesktop():
salome.sg.updateObjBrowser(1)
except:
pass
def ExportGeometricalGroups(shape,file='groups',only=None,ignore=None,type=None,
):
"""
Exports into a file groups of a geometrical object in the form of sets o
f subshape Ids.
Argument(s):
Name
Description
Type
Default Value
shape Source geometrical object. / Its name in the study tree.
Any geometrical object / String
-
file
Name of the file to write.
String "groups"
only
List of names of groups to export, excluding the others.
Array of Strings
None
ignore List of names of groups to ignore.
Array of Strings
None
type
Type of groups to export. Can equal "vertex", "edge", "face" or
"solid".
Array of Strings
None
"""
# Get the input shape(s)
shape=GetObject(shape,'GEOM')
## Check the input shape existence
if "error" in [shape]:
return
#else:
# Get the list of the IDs of all the shapes visible in the study
tree
visibleIDs=GetSubShapeNames(salome.myStudy.FindComponent('GEOM')
,output='ID')
## Open the group file
groupFile=open(file,"w")
## Get the groups
shapeGroups=geompy.GetGroups(shape)
visibleShapeGroups=[]
for shapeGroup in shapeGroups:
shapeGroupID=salome.ObjectToID(shapeGroup)
if shapeGroupID in visibleIDs:
visibleShapeGroups.append(shapeGroup)
#shapeGroups=geompy.GetGroups(shape)
#-
visibleShapeGroups=sortedShapeGroups
sortedShapeGroups=[]
if ignore!=None:
for visibleGroup in visibleShapeGroups:
visibleShapeGroupsName=visibleGroup.GetName()
if visibleShapeGroupsName not in ignore:
sortedShapeGroups.append(visibleGroup)
visibleShapeGroups=sortedShapeGroups
sortedShapeGroups=[]
if type!=None:
for visibleGroup in visibleShapeGroups:
visibleGroupType=str(visibleGroup.GetMaxShapeTyp
e())
if visibleGroupType==type.upper():
sortedShapeGroups.append(visibleGroup)
visibleShapeGroups=sortedShapeGroups
## Write the group file
for visibleShapeGroup in visibleShapeGroups:
def ImportGeometricalGroups(shape,file='groups',only=None,ignore=None,type=None,
add=True):
"""
Imports from a file created with the ExportGeometricalGroups function in
to a geometrical object groups in the form of sets of subshape IDs.
Argument(s):
Name
Description
Type
Default Value
shape Target geometrical object. / Its name in the study tree.
Any geometrical object / String
file
Name of the file to read.
String "groups"
only
List of names of groups to import, excluding the others.
Array of Strings
None
ignore List of names of groups to ignore.
Array of Strings
None
type
Type of groups to import. Can equal "vertex", "edge", "face" or
"solid".
Array of Strings
None
add
See the documentation. Boolean
True
Returned Value(s):
dim Value
Type
Group n
"""
Number Name
The name of the group in the file
if add==True:
gg=salome.ImportComponentGUI("GEOM")
# Get the input shape(s)
shape=GetObject(shape,'GEOM')
## Check the input shape existence
if "error" in [shape]:
return
#else:
# Get the list of the IDs of all the shapes visible in the study
tree
visibleIDs=GetSubShapeNames(salome.myStudy.FindComponent('GEOM')
,output='ID')
## Get the already existing groups
#oldGroups=geompy.GetGroups(shape)
oldGroups=geompy.GetGroups(shape)
visibleOldGroups=[]
for oldGroup in oldGroups:
oldGroupID=salome.ObjectToID(oldGroup)
if oldGroupID in visibleIDs:
visibleOldGroups.append(oldGroup)
if i==0:
groupName=line
## Get the group type and create or get the group
if i==1:
groupType=int(line)
############
############
############
passGroup=False
if only!=None and groupName not in only:
passGroup=True
if ignore!=None and groupName in ignore:
passGroup=True
if type!=None and groupType!=geompy.ShapeType[ty
pe.upper()]:
passGroup=True
############
############
############
if passGroup==False:
if groupName in visibleOldGroupNames:# I
f the group already exists...
# Get the already existing group
j=0
for visibleOldGroupName in visib
leOldGroupNames:
if groupName==visibleOld
GroupName:
try:
salome.g
eom.geomtools.GeomStudyTools().deleteShape(salome.ObjectToID(visibleOldGroups[j]
))
except:
pass
break
j+=1
## Create the new group
newGroup=geompy.CreateGroup(shape,groupT
ype)
#-
##- Get the IDs and add them to the new group
if i==2:
if passGroup==False:
shapeIDs=line.split()
for shapeID in shapeIDs:
geompy.AddObject(newGroup,int(sh
apeID))
if add==True:
id=geompy.addToStudyInFather(sha
pe,newGroup,groupName)
gg.createAndDisplayGO(id)
if salome.sg.hasDesktop():
salome.sg.updateObjBrows
er(1)
#i+=1
if i==3:
i=0
def ViscousLayerScaleFactor(viscousLayerThickness,wallThickness,ratio=1.2):
"""
Calculates and prints the parameters to use with the Number of Segment h
ypothesis according to a desired viscous layer thickness, a wall thickness and a
ratio between each cell.
Argument(s):
Name
Description
Type
Default Value
viscousLayerThickness Viscous layer thickness.
Float
wallThickness Desired thicknessName of the first layer.
Float
ratio
"""
Float
1.2
tring
Argument(s):
Name
Description
Type
Default Value
mesh
The mesh to export. / Its name in the study tree.
"Mesh_1"
file
Name without extension of the amsh file to write.
Mesh / S
String
"Edge"
rt).
help
Activates the generation of a helpFile (slows down the mesh expo
Boolean
False
Conditions of Use:
The mesh has to be computed and to contain groups describing the desired
boundary conditions (inlet, outlet, wall, farfield, etc.).
Warning: In the case the mesh is the result of a mesh fusion, the nodes
and then the elements of the meshes to fuse have to be reordered before the fusi
on, else Edge can detect a Max dev. of accum. surface vector superior to its all
owed tolerance during the preprocessor command execution.
"""
# Get the mesh name
if isinstance(mesh,str):
meshName=mesh
else:
meshName="Unnammed_mesh"
else:
for s in range(nbSpaces):
file.write(" ")
if type(element)==type('string'):
file.write("%s"%(element))
elif type(element)==type(1.0):
file.write("%.16f"%(element))
elif type(element)==type(1):
file.write("%i"%(element))
if (n+1)%nbColumns==0 or n==len(table)-1:
file.write("\n")
n+=1
def powerOfTen(figure):
figure*=1.0
n=0
if figure!=0:
if abs(figure)<1:
while abs(figure)<1:
figure*=10
n-=1
if abs(figure)>=10:
while abs(figure)>=10:
figure/=10
n+=1
return figure,n
if "<SMESH._objref_SMESH_Mesh " in str(mesh):
mesh=smesh.Mesh(mesh)
# Renumber elements and nodes
mesh.RenumberNodes()
mesh.RenumberElements()
## Get nodes number and IDs
nbNodesInMesh=mesh.NbNodes()
nodeIDsInMesh=mesh.GetNodesId()
## Get edges IDs
edgeIDsInMesh=mesh.GetElementsByType(SMESH.EDGE)
nbEdgesInMesh=mesh.NbEdges()
## Get faces IDs
faceIDsInMesh=mesh.GetElementsByType(SMESH.FACE)
nbFacesInMesh=mesh.NbFaces()
nbTrianglesInMesh=mesh.NbTriangles()
nbQuadranglesInMesh=mesh.NbQuadrangles()
## Get volumes IDs
nbVolumesInMesh=mesh.NbVolumes()
nbTetrahedronsInMesh=mesh.NbTetras()
nbPyramidsInMesh=mesh.NbPyramids()
nbPrismsInMesh=mesh.NbPrisms()
nbHexahedronsInMesh=mesh.NbHexas()
volumeIDsInMesh=mesh.GetElementsByType(SMESH.VOLUME)
## Get mesh dimension
if nbVolumesInMesh != 0:
meshDimension=3
nbElementsInDomain=nbVolumesInMesh
else:
meshDimension=2
nbElementsInDomain=nbFacesInMesh
## Get groups
nbGroups=mesh.NbGroups()
groupNames=mesh.GetGroupNames()
groups=mesh.GetGroups()
## Get group types
groupTypes=[]
for group in groups:
groupType=str(group.GetType())
groupTypes.append(groupType)
## Open the amsh file
date=time.asctime(time.localtime())
amshFile=open("%s.amsh"%(file),"w")
amshFile.write("unstr_grid_data N 0 0 2\n")
amshFile.write("
title L 1 1 0\n")
amshFile.write("
'%s exported from Salome on %s'\n"%(
meshName,date))
## Open the help file
if help==True:
meshFile=open("%s.help"%(file),"w")
meshFile.write("%s\n"%(date))
meshFile.write("'%s'
'%s'\n"%(meshName,file))
meshFile.write("NODES EDGES TRIA
QUAD
TETRA
PYRA
PRISM
HEXA\n")
meshFile.write("%i
%i
%i
%i
%i
%i
%i
%i\n"%(nbNodesInMesh,nbEdgesInMesh,nbTrianglesInMesh,nbQuadrangl
esInMesh,nbTetrahedronsInMesh,nbPyramidsInMesh,nbPrismsInMesh,nbHexahedronsInMes
h))
for n in range(nbGroups):
meshFile.write("'%s'
"%(mesh.GetGroupNames()[
n]))
meshFile.write("\n")
meshFile.write("NODES\nID
## Get the region ffa dimension
regionFfaDimension=2+nbGroups
if meshDimension==2:
if nbTrianglesInMesh>0:
regionFfaDimension+=1
Z\n")
if nbQuadranglesInMesh>0:
regionFfaDimension+=1
elif meshDimension==3:
if nbTetrahedronsInMesh>0:
regionFfaDimension+=1
if nbPyramidsInMesh>0:
regionFfaDimension+=1
if nbPrismsInMesh>0:
regionFfaDimension+=1
if nbHexahedronsInMesh>0:
regionFfaDimension+=1
amshFile.write("
amshFile.write("
amshFile.write("
amshFile.write("
sion,nbNodesInMesh))
region N 0 0 %i\n"%(regionFfaDimension))
region_name L 1 1 0\n")
'volume_elements'\n")
coordinates DF %i %i 0\n"%(meshDimen
for n in range(meshDimension):
nodeCoordinate=mesh.GetNodeXYZ(nodeID)[n]
[nodeFloatCoordinate,nodeCoordinatePowerOfTen]=p
owerOfTen(nodeCoordinate)
nodeCoordinate="%.16fE%i"%(nodeFloatCoordinate,n
odeCoordinatePowerOfTen)
nodeCoordinates[n].append(nodeCoordinate)
figures=[]
for n in range(meshDimension):
figures+=nodeCoordinates[n]
WriteInColumns(amshFile,figures,meshDimension,18)
## Get the group element definition
print "Writing definition of group elements... (%s groups)"%(nbG
roups)
if help==True:
meshFile.write("GROUPS\n")
for group in groups:# For each group of the mesh
groupName=group.GetName()
elementIDsInGroup=group.GetListOfID()
triangleIDsInGroup=[]
quadrangleIDsInGroup=[]
edgesIDsInGroup=[]
for elementIDInGroup in elementIDsInGroup:
nbNodesInElement=mesh.GetElemNbNodes(elementIDIn
Group)
if meshDimension==3:
if nbNodesInElement==3:
triangleIDsInGroup.append(elemen
tIDInGroup)
if nbNodesInElement==4:
quadrangleIDsInGroup.append(elem
entIDInGroup)
elif meshDimension==2:
edgesIDsInGroup.append(elementIDInGroup)
nbTypesInGroup=0
typesInGroups=0 # -1 = edges ; +1 = triangles ; +2 = qua
drangles
nbTrianglesInGroup=len(triangleIDsInGroup)
nbQuadranglesInGroup=len(quadrangleIDsInGroup)
nbEdgesInGroup=len(edgesIDsInGroup)
if nbTrianglesInGroup>0:
typesInGroups+=1
nbTypesInGroup+=1
if nbQuadranglesInGroup>0:
typesInGroups+=2
nbTypesInGroup+=1
if nbEdgesInGroup>0:
typesInGroups-=1
nbTypesInGroup+=1
amshFile.write("
boundary N 0 0 %i\n"%(nbType
amshFile.write("
boundary_name L 1 1 0\
amshFile.write("
'%s'\n"%(groupNa
sInGroup+1))
n")
me))
if help==True:
meshFile.write("'%s'\n"%(groupName))
for n in range(nbTypesInGroup):
amshFile.write("
belem_group N
0 0 2\n")
amshFile.write("
em_type L 1 1 0\n")
bound_el
if typesInGroups==-1: # edges
if help==True:
meshFile.write("EDGES\n")
elementIDsInGroup=edgesIDsInGroup
nbElementsInGroup=nbEdgesInGroup
nbNodesInElements=2
elementsType='bar2'
elif typesInGroups==2: # quadrangles
if help==True:
meshFile.write("QUAD\n")
elementIDsInGroup=quadrangleIDsInGroup
nbElementsInGroup=nbQuadranglesInGroup
nbNodesInElements=4
elementsType='quad4'
elif typesInGroups==1 or typesInGroups==3: # tri
angles
if help==True:
meshFile.write("TRIA\n")
elementIDsInGroup=triangleIDsInGroup
nbElementsInGroup=nbTrianglesInGroup
nbNodesInElements=3
typesInGroups-=1
elementsType='tria3'
if help==True:
meshFile.write("N
NODE2
ID
NODE1
...\n")
N=1
amshFile.write("
'%
s'\n"%(elementsType))
amshFile.write("
em_nodes IF %i %i 0\n"%(nbNodesInElements,nbElementsInGroup))
bound_el
nodeIDs=[]
for n in range(nbNodesInElements):
nodeIDs.append([])
for elementID in elementIDsInGroup:
if help==True:
meshFile.write("%i
%i
"%(N,elementID))
N+=1
for n in range(nbNodesInElements):
if help==True:
meshFile.write("%i
"%(mesh.GetElemNodes(elementID)[n]))
nodeIDs[n].append(mesh.GetElemNo
des(elementID)[n])
if help==True:
meshFile.write("\n")
figures=[]
for n in range(nbNodesInElements):
figures+=nodeIDs[n]
WriteInColumns(amshFile,figures,nbNodesInElement
s,30)
## Write the domain element definitions
print "Writing definition of domain elements... (%s elements)"%(
nbElementsInDomain)
if help==True:
meshFile.write("DOMAIN CELLS\n")
triangleIDsInDomain=[]
quadrangleIDsInDomain=[]
tetrahedronIDsInDomain=[]
pyramidIDsInDomain=[]
prismIDsInDomain=[]
hexahedronIDsInDomain=[]
if meshDimension==2:
elementIDsInDomain=faceIDsInMesh
elif meshDimension==3:
elementIDsInDomain=volumeIDsInMesh
for elementIDInDomain in elementIDsInDomain:
nbNodesInElement=mesh.GetElemNbNodes(elementIDInDomain)
if meshDimension==2:
if nbNodesInElement==3:
triangleIDsInDomain.append(elementIDInDo
main)
if nbNodesInElement==4:
quadrangleIDsInDomain.append(elementIDIn
Domain)
elif meshDimension==3:
if nbNodesInElement==4:
tetrahedronIDsInDomain.append(elementIDI
nDomain)
if nbNodesInElement==5:
pyramidIDsInDomain.append(elementIDInDom
ain)
if nbNodesInElement==6:
prismIDsInDomain.append(elementIDInDomai
n)
if nbNodesInElement==8:
hexahedronIDsInDomain.append(elementIDIn
Domain)
nbTypesInDomain=0
typesInDomain=0 # -2 = quadrangles ; -1 = triangles ; +1 = tetra
hedrons ; +2 = pyramids ; +4 = prisms ; +8 = hexahedrons
nbTrianglesInDomain=len(triangleIDsInDomain)
nbQuandranglesInDomain=len(quadrangleIDsInDomain)
nbTetrahedronsInDomain=len(tetrahedronIDsInDomain)
nbPyramidsInDomain=len(pyramidIDsInDomain)
nbPrismsInDomain=len(prismIDsInDomain)
nbHexahedronsInDomain=len(hexahedronIDsInDomain)
if nbTrianglesInDomain>0:
typesInDomain-=1
nbTypesInDomain+=1
if nbQuandranglesInDomain>0:
typesInDomain-=2
nbTypesInDomain+=1
if nbTetrahedronsInDomain>0:
typesInDomain+=1
nbTypesInDomain+=1
if nbPyramidsInDomain>0:
typesInDomain+=2
nbTypesInDomain+=1
if nbPrismsInDomain>0:
typesInDomain+=4
nbTypesInDomain+=1
if nbHexahedronsInDomain>0:
typesInDomain+=8
nbTypesInDomain+=1
typesForQuadrangles=[-3,-2]
typesForTriangles=[-3,-1]
typesForTetrahedrons=[1,3,5,7,9,11,13,15]
typesForPyramids=[2,3,6,7,10,11,14,15]
typesForPrisms=[4,5,6,7,12,13,14,15]
typesForHexahedrons=[8,9,10,11,12,13,14,15]
for n in range(nbTypesInDomain):
amshFile.write("
amshFile.write("
element_group N 0 0 2\n")
element_type L 1 1 0\n
")
if typesInDomain in typesForQuadrangles:
if help==True:
meshFile.write("QUAD\n")
elementIDsInDomain=quadrangleIDsInDomain
nbElementsInDomain=nbQuandranglesInDomain
nbNodesInElements=4
typesInDomain+=2
elementsType='quad4'
elif typesInDomain in typesForTriangles:
if help==True:
meshFile.write("TRIA\n")
elementIDsInDomain=triangleIDsInDomain
nbElementsInDomain=nbTrianglesInDomain
nbNodesInElements=3
typesInDomain+=1
elementsType='tria3'
elif typesInDomain in typesForHexahedrons:
if help==True:
meshFile.write("HEXA\n")
elementIDsInDomain=hexahedronIDsInDomain
nbElementsInDomain=nbHexahedronsInDomain
nbNodesInElements=8
typesInDomain-=8
elementsType='hexa8'
ID
NODE1
NODE2
amshFile.write("
'%s'\n"%(element
sType))
amshFile.write("
0\n"%(nbNodesInElements,nbElementsInDomain))
element_nodes IF %i %i
nodeIDs=[]
for n in range(nbNodesInElements):
nodeIDs.append([])
for elementID in elementIDsInDomain:
if help==True:
meshFile.write("%i
%i
"%(N,ele
mentID))
N+=1
for n in range(nbNodesInElements):
if help==True:
meshFile.write("%i
"%(mesh.
GetElemNodes(elementID)[n]))
nodeIDs[n].append(mesh.GetElemNodes(elem
entID)[n])
if help==True:
meshFile.write("\n")
figures=[]
for n in range(nbNodesInElements):
figures+=nodeIDs[n]
if meshDimension==3:
# reorder node IDs
reorderedFigures=[]
splitFigures=[]
reorderedSplitFigures=[]
for n in range(nbNodesInElements):
splitFigures.append([])
reorderedSplitFigures.append([])
f=0
n=0
for figure in figures:
splitFigures[n].append(figure)
f+=1
if f==nbElementsInDomain:
n+=1
f=0
if elementsType=='hexa8' or elementsType=='penta
6':
for n in range(nbNodesInElements/2):
reorderedSplitFigures[n]=splitFi
gures[nbNodesInElements/2+n]
reorderedSplitFigures[nbNodesInE
lements/2+n]=splitFigures[n]
for n in range(nbNodesInElements):
reorderedFigures+=reorderedSplit
Figures[n]
figures=reorderedFigures
elif elementsType=='tetra4' or elementsType=='pe
nta5':
for n in range(nbNodesInElements-1):
reorderedFigures+=splitFigures[n
bNodesInElements-2-n]
figures=reorderedFigures+splitFigures[nb
NodesInElements-1]
WriteInColumns(amshFile,figures,nbNodesInElements,24)
## Close the files
amshFile.close()
if help==True:
meshFile.close()
#-
def ExportMeshConfiguration(mesh='Mesh_1',file='mesh'):
"""
Export into a file the nam of algorithms, hypotheses and groups associat
ed to a mesh and its submeshes.
Argument(s):
Name
Description
Type
Default Value
mesh
The source mesh. / Its name in the study tree. Mesh / String
"Mesh_1"
file
Name of the file to write.
String "mesh"
Conditions of Use:
All the hypotheses and algorithms used by the mesh and its sub-meshes mu
st have a different name. Also, the names of all the mesh groups have to be the
same as the names of their associated geometrical groups.
"""
meshShape=mesh.GetShape()
meshShapeName=meshShape.GetName()
## Get the shape hypotheses
shapeHypotheses=mesh.GetHypothesisList(meshShape)
## Check if hypotheses are associated to the mesh shape
nbShapeHypotheses=len(shapeHypotheses)
#if nbShapeHypotheses > 0:# If so...
# Write the shape flag
hypothesisFile.write("SHAPE:\n")
#for shapeHypothesis in shapeHypotheses:# For each shape
hypothesis...
# Get the hypothesis name
shapeHypothesisName=smesh.GetName(shapeHypothesi
s)
## Write the hypothesis
hypothesisFile.write("%s\n"%(shapeHypothesisName
))
#-
def ImportMeshConfiguration(mesh='Mesh_1',file='mesh'):
"""
Imports into a mesh algorithms, hypotheses and group names rom a file c
reated with the ExportMeshConfiguration function.
Argument(s):
Name
Description
Type
Default Value
mesh
The target mesh. / Its name in the study tree. Mesh / String
"Mesh_1"
file
Name of the file to read.
String "mesh"
Conditions of Use:
All the hypotheses and algorithms present in the file has to be also pre
sent in the study. Also, there must be, in the geometrical object associated to
the target mesh, groups having the same name as the groups present in the file.
"""
# Get the input mesh
mesh=GetObject(mesh,'SMESH')
## Check the input shape existence
if "error" in [mesh]:
return
#else:
if "<SMESH._objref_SMESH_Mesh " in str(mesh):
mesh=smesh.Mesh(mesh)
# Get the mesh shape
meshShape=mesh.GetShape()
## Get the mesh groups
shapeGroups=geompy.GetGroups(meshShape)
shapeGroupNames=[group.GetName() for group in shapeGroups]
nbShapeGroups=len(shapeGroups)
## Open the hypothesis file
hypothesisFile=open(file,"r")
## Read the file
for line in hypothesisFile:# For each line in the hypothesis fil
e...
isASubMeshLine=(line.find("SUBMESH:")==0)
isAShapeLine=(line.find("SHAPE:")==0)
isAGroupLine=(line.find("GROUPS:")==0)
geometry=None
if isAShapeLine==True:# If it is a "shape" line...
group=None
elif isASubMeshLine==True:# If it is a "submesh" line...
# Get the group name
groupName=line[8:-1]
## Get the group
for i in range(nbShapeGroups):# For all groups i
n the shape...
if groupName==shapeGroupNames[i]:# Compa
re their name with the one from the file...
group=shapeGroups[i]# If matched
, extract the group in the shape group list
break
def RotateFlapGenerateAndExportMeshInAmshFormat(angles,groupFile="groups",meshFi
le="mesh",domain="domain",fixedEdges="fixedEdges",rotatingFace="rotatingFace",ro
tatingEdges="rotatingEdges",flapAxis="flapAxis",keepMesh=True,help=False):
"""
Rotates a flap, generates a mesh and exports it into a .amsh file readab
le with Edge.
Argument(s):
Name
Description
Type
Default Value
angles List of flap angles to compute Array of Floats
groupFile
Name of the group file to import in the final partitions
String "groups"
meshFile
Name of the mesh file to import in the meshes. String
"mesh"
domain Face describing the domain before cutting the flap face / Its na
me in the study tree. Face / String "domain"
fixedEdges
Compound of edges which won't move with the flap / Its n
ame in the study tree. Compound of Edges / String
"fixedEdges"
rotatingFace
Face describing the flap / Its name in the study tree.
Face / String "rotatingFace"
rotatingEdges Compound of edges which move with the flap / Its name in
the study tree.
Compound of Edges / String
"rotatingEdges"
flapAxis
Axis of the flap rotation / Its name in the study tree.
Vector / Edge / String "flapAxis"
keepMesh
If equals True, the mesh are not cleared after each mesh
export.
Boolean
True
help
This argument is passed to the ExportAmshFile function.
Boolean
False
Conditions of Use:
To use this function, the group file and mesh file have to be previously
generated manually and the hypotheses to be used in the mesh have to be present
in the study.
"""
pi=3.141592654
# Get the input shape(s)
[domain,fixedEdges,rotatingFace,rotatingEdges,flapAxis]=GetObject([domai
n,fixedEdges,rotatingFace,rotatingEdges,flapAxis],'GEOM')
## Check the input shape existence
if "error" in [domain,fixedEdges,rotatingFace,rotatingEdges,flapAxis]:
return
#else:
for angle in angles:# For each rotation angle...
# Convert angle from degrees to radians
angleInRadians=angle*pi/180
## Rotate the flap
rotatedFlapFace=geompy.MakeRotation(rotatingFace,flapAxi
s,angleInRadians)
rotatedFlapEdges=geompy.MakeRotation(rotatingEdges,flapA
xis,angleInRadians)
## Cut and partition the domain
cutDomain=geompy.MakeCut(domain,rotatedFlapFace)
partition=geompy.MakePartition([cutDomain],[rotatedFlapE
dges,fixedEdges],Limit=geompy.ShapeType["FACE"])
## Import the geometrical groups
partitionName="Partition_"+str(angle)+"deg"
geompy.addToStudy(partition,partitionName)
ImportGeometricalGroups(partitionName,groupFile,add=Fals
e)
## Create the mesh
meshName="Mesh_"+str(angle)+"deg"
mesh=smesh.Mesh(partition,meshName)
## Import the mesh configuration
ImportMeshConfiguration(mesh,meshFile)
## Compute the mesh
mesh.Compute()
## Export the mesh
ExportAmshFile(mesh,meshName,help)
#if keepMesh==False:
mesh.Clear()
#### - ####
# Activate acronyms
pdf=PrintDefinedFunctions
pv=PrintVersion
ge=GeometricalEquality
es=ExtendSpline
fs=FuseSplines
mms=MakeMiddleSpline
rs=RebuildSpline
se=SplitEdge
fcf=FuseCoplanarFaces
rf=RebuildFace
rfee=RemoveFaceExtraEdges
meo=MakeEdgeOffset
evl=ExtendViscousLayer
cvl=CloseViscousLayer
pvli=PropagateViscousLayerIntersection
mtvl=MakeTipViscousLayer
etvl=ExtendTipViscousLayer
ctvl=CloseTipViscousLayer
mls=MakeLinkingSolids
gbf=GetBoundaryFaces
gtef=GetTriEdgeFaces
cgg=CopyGeometricalGroups
egg=ExportGeometricalGroups
igg=ImportGeometricalGroups
vlsf=ViscousLayerScaleFactor
eaf=ExportAmshFile
emc=ExportMeshConfiguration
imc=ImportMeshConfiguration
rfgaemiaf=RotateFlapGenerateAndExportMeshInAmshFormat
## Make this script more compatible with cfdmsh 1.0.0
MakeVariableOffset=MakeEdgeOffset
#print "Welcome in cfdmsh!"
pdf()
pv()