-
Notifications
You must be signed in to change notification settings - Fork 0
/
functions.py
209 lines (207 loc) · 7.47 KB
/
functions.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
import numpy as np
from mesh_to_sdf import mesh_to_sdf
import sys
import trimesh
import warnings
#
# Function to read the geometry data from CaNS
#
def readGrid(filenamei,iskip,r0,non_uniform_grid):
'''
This function reads the grid generated by CaNS.
Originally written by Pedro Costa.
INPUT
filenamei: [string] Input name of the file
iskip: [3x1 array] that has data skip information for the written array
r0: [3x1 array] that defines the origin of the domain
non_uniform_grid: [Boolean] Is the grid non-uniform?
RETURNS
xp, yp, zp: Grid location for the scalar
xu, yv, zw: Grid location for the face values
'''
#
# setting up some parameters
#
precision = 'float64' # precision of float
#
# read geometry file
#
geofile = filenamei + "geometry.out"
geo = np.loadtxt(geofile, comments = "!", max_rows = 2)
ng = geo[0,:].astype('int')
l = geo[1,:]
dl = l/(1.*ng)
#
# read and generate grid
#
xp = np.arange(r0[0]+dl[0]/2.,r0[0]+l[0],dl[0]) # centered x grid
yp = np.arange(r0[1]+dl[1]/2.,r0[1]+l[1],dl[1]) # centered y grid
zp = np.arange(r0[2]+dl[2]/2.,r0[2]+l[2],dl[2]) # centered z grid
xu = xp + dl[0]/2. # staggered x grid
yv = yp + dl[1]/2. # staggered y grid
zw = zp + dl[2]/2. # staggered z grid
if(non_uniform_grid):
gridfile=filenamei + "grid.bin"
f = open(gridfile,'rb')
grid_z = np.fromfile(f,dtype=precision)
f.close()
grid_z = np.reshape(grid_z,(ng[2],4),order='F')
zp = r0[2] + np.transpose(grid_z[:,2]) # centered z grid
zw = r0[2] + np.transpose(grid_z[:,3]) # staggered z grid
#
# reshape grid
#
xp = xp[0:ng[0]:iskip[0]]
yp = yp[0:ng[1]:iskip[1]]
zp = zp[0:ng[2]:iskip[2]]
xu = xu[0:ng[0]:iskip[0]]
yv = yv[0:ng[1]:iskip[1]]
zw = zw[0:ng[2]:iskip[2]]
return xp, yp, zp, xu, yv, zw
#
# Load Dopamine grid
#
def loaddopaminegrid(infile):
'''
This function loads the grid information supplied by the user
INPUT
infile: [string] Name and location of the input file
OUTPUT
x,y,z: [numpy arrays] X, Y, and Z face locations
xm,ym,zm: [numpy arrays] Xm, Ym, and Zm cell-center locations
'''
x = np.loadtxt(infile,max_rows=1)
y = np.loadtxt(infile,skiprows=1,max_rows=1)
z = np.loadtxt(infile,skiprows=2,max_rows=1)
xm = np.loadtxt(infile,skiprows=3,max_rows=1)
ym = np.loadtxt(infile,skiprows=4,max_rows=1)
zm = np.loadtxt(infile,skiprows=5,max_rows=1)
return x,y,z,xm,ym,zm
#
# Function definition for computing the signed-distance field
#
def computeSDF(meshObj,xin,yin,zin,nSamples):
'''
This function computes the SDF for the entire grid
INPUT
meshObj: [mesh object] Mesh object of the stl/obj file
xin: [numpy array] x array corresponding to the streamwise coordinate
yin: [numpy array] y array corresponding to the spanwise coordinate
zin: [numpy array] z array corresponding to the vertical coordinate
nSamples: [float .or. integer] Number of sample points used in the scan method
OUTPUT
sdf: [float64] Signed distance field
'''
#
# Compute the signed-distance field
#
dummy = np.vstack(np.meshgrid(xin,yin,zin,indexing='ij')).reshape(3,-1).T
sdf = mesh_to_sdf(meshObj,dummy,surface_point_method='sample', sign_method='normal', bounding_radius=None, scan_count=100, scan_resolution=100, sample_point_count=nSamples, normal_sample_count=11)
return sdf
#
# Function to convert the numpy array to CaNS compatible binary files
#
# This file has the functions to convert arrays from numpy to CaNS compatible binary
def n2carray(filein,N,fileout):
'''
This function converts the filein to binary array that is CaNS compatible
INPUT
filein: [string] Location and name of the numpy array
N: [3 x 1 numpy array] Number of grid points in x,y, and z
RETURNS
fileout: [string] Location and name of the output binary array that is CaNS compatible
'''
#
# Load the file
#
data = np.load(filein)
data = np.reshape(data,N) # First reshape using row major array
data = np.asfortranarray(data) # Cast as column major array
data = data.flatten(order='F') # Flatten it to make FORTRAN binary compatible
print("%s has size %d"%(filein,sys.getsizeof(data)))
#
# Write file to binary array
#
# write the array to a binary file
with open(fileout, 'wb') as f:
data.tofile(f)
f.close()
#
# Translate and rotate geometry
#
def trasRot(saveMesh=False,inMesh='dummy.stl',outMesh='output.stl',tarr=[0.0,0.0,0.0],rotang=0.0,rotax=[0.0,0.0,0.0],scalegeo=0.0):
'''
This function translates and rotates the geometry based on user specification
INPUT
saveMesh: [Boolean] Do you wish to save the mesh?
inMesh: [string] Name of the mesh to be read
tarr: [3 x 1 list] Translation array in x, y, and z
rotang: [float] Rotation angle in degrees
rotax: [3 x 1 list] Rotation axis
scalegeo: [float] scale the input geometry by a factor
OUTPUT:
outMesh: [string] Name of the output mesh, default = output.stl
'''
#
# Exit if inputfile is not defined
#
if(inMesh=='dummy.stl'):
sys.exit("ERROR: Please specify the input filename and location....")
#
# Preliminary setup
#
rotAngRad = np.radians(rotang) # Convert to radians
rotMat = trimesh.transformations.rotation_matrix(rotAngRad, rotax) # Make the rotation matrix
#
# Load the mesh
#
mesh = trimesh.load(inMesh)
#
# Check if the mesh if watertight
#
waterTight = mesh.is_watertight # mesh watertight? [Important for generating SDF]
#
# Print message
#
if(waterTight == 0):
# Print message
warnings.warn("Input file is not watertight, this may cause issues for generating the SDF!")
print("------------------------------------------------------------------------------------")
else:
print("Input file is watertight")
print("------------------------------------------------------------------------------------")
#
# Bounding box
#
print("Oriented Bounding box [before operations]")
print("xmin, ymin, zmin --",mesh.bounds[0])
print("xmax, ymax, zmax --",mesh.bounds[1])
print("------------------------------------------------------------------------------------")
#
# Rotate the mesh
#
mesh.apply_transform(rotMat)
#
# Scale the mesh to user prompted scale
#
mesh.vertices *= scalegeo
#
# Translate mesh
#
mesh.vertices += tarr
#
# Bounding box
#
print("Oriented Bounding box [after operations]")
print("xmin, ymin, zmin --",mesh.bounds[0])
print("xmax, ymax, zmax --",mesh.bounds[1])
print("------------------------------------------------------------------------------------")
#
# Save Mesh now
#
if saveMesh:
mesh.export(outMesh)
#
# Exit
#
print("Done.......")