plot3d 1.6.4__tar.gz → 1.6.7__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {plot3d-1.6.4 → plot3d-1.6.7}/PKG-INFO +1 -1
- {plot3d-1.6.4 → plot3d-1.6.7}/plot3d/__init__.py +13 -13
- {plot3d-1.6.4 → plot3d-1.6.7}/plot3d/block.py +264 -254
- {plot3d-1.6.4 → plot3d-1.6.7}/plot3d/blockfunctions.py +179 -179
- {plot3d-1.6.4 → plot3d-1.6.7}/plot3d/connectivity.py +567 -567
- {plot3d-1.6.4 → plot3d-1.6.7}/plot3d/differencing.py +116 -116
- {plot3d-1.6.4 → plot3d-1.6.7}/plot3d/face.py +368 -368
- {plot3d-1.6.4 → plot3d-1.6.7}/plot3d/facefunctions.py +492 -492
- {plot3d-1.6.4 → plot3d-1.6.7}/plot3d/graph.py +188 -154
- {plot3d-1.6.4 → plot3d-1.6.7}/plot3d/listfunctions.py +15 -15
- {plot3d-1.6.4 → plot3d-1.6.7}/plot3d/periodicity.py +794 -794
- {plot3d-1.6.4 → plot3d-1.6.7}/plot3d/point_match.py +30 -30
- {plot3d-1.6.4 → plot3d-1.6.7}/plot3d/read.py +181 -181
- {plot3d-1.6.4 → plot3d-1.6.7}/plot3d/split_block.py +229 -229
- {plot3d-1.6.4 → plot3d-1.6.7}/plot3d/write.py +87 -87
- {plot3d-1.6.4 → plot3d-1.6.7}/pyproject.toml +19 -19
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
from .block import Block, reduce_blocks
|
|
2
|
-
from .blockfunctions import rotate_block,get_outer_bounds,block_connection_matrix
|
|
3
|
-
from .connectivity import find_matching_blocks, get_face_intersection, connectivity_fast, face_matches_to_dict
|
|
4
|
-
from .face import Face
|
|
5
|
-
from .facefunctions import create_face_from_diagonals, get_outer_faces, find_connected_faces, find_bounding_faces,split_face,find_face_nearest_point,match_faces_dict_to_list,outer_face_dict_to_list,find_closest_block
|
|
6
|
-
from .read import read_plot3D, read_ap_nasa
|
|
7
|
-
from .write import write_plot3D
|
|
8
|
-
from .differencing import find_edges, find_face_edges
|
|
9
|
-
from .periodicity import periodicity, periodicity_fast, create_rotation_matrix, rotated_periodicity, translational_periodicity
|
|
10
|
-
from .point_match import point_match
|
|
11
|
-
from .split_block import split_blocks, Direction
|
|
12
|
-
from .listfunctions import unique_pairs
|
|
13
|
-
from .graph import block_to_graph,get_face_vertex_indices,get_starting_vertex,add_connectivity_to_graph
|
|
1
|
+
from .block import Block, reduce_blocks
|
|
2
|
+
from .blockfunctions import rotate_block,get_outer_bounds,block_connection_matrix
|
|
3
|
+
from .connectivity import find_matching_blocks, get_face_intersection, connectivity_fast, face_matches_to_dict
|
|
4
|
+
from .face import Face
|
|
5
|
+
from .facefunctions import create_face_from_diagonals, get_outer_faces, find_connected_faces, find_bounding_faces,split_face,find_face_nearest_point,match_faces_dict_to_list,outer_face_dict_to_list,find_closest_block
|
|
6
|
+
from .read import read_plot3D, read_ap_nasa
|
|
7
|
+
from .write import write_plot3D
|
|
8
|
+
from .differencing import find_edges, find_face_edges
|
|
9
|
+
from .periodicity import periodicity, periodicity_fast, create_rotation_matrix, rotated_periodicity, translational_periodicity
|
|
10
|
+
from .point_match import point_match
|
|
11
|
+
from .split_block import split_blocks, Direction
|
|
12
|
+
from .listfunctions import unique_pairs
|
|
13
|
+
from .graph import block_to_graph,get_face_vertex_indices,get_starting_vertex,add_connectivity_to_graph, block_connectivity_to_graph
|
|
@@ -1,254 +1,264 @@
|
|
|
1
|
-
import numpy as np
|
|
2
|
-
import math
|
|
3
|
-
from tqdm import trange
|
|
4
|
-
from typing import List
|
|
5
|
-
|
|
6
|
-
class Block:
|
|
7
|
-
"""Plot3D Block definition
|
|
8
|
-
"""
|
|
9
|
-
def __init__(self, X:np.ndarray,Y:np.ndarray,Z:np.ndarray):
|
|
10
|
-
"""Initializes the block using all the X,Y,Z coordinates of the block
|
|
11
|
-
|
|
12
|
-
Args:
|
|
13
|
-
X (np.ndarray): All the X coordinates (i,j,k)
|
|
14
|
-
Y (np.ndarray): All the Y coordinates (i,j,k)
|
|
15
|
-
Z (np.ndarray): All the Z coordinates (i,j,k)
|
|
16
|
-
|
|
17
|
-
"""
|
|
18
|
-
self.IMAX,self.JMAX,self.KMAX = X.shape;
|
|
19
|
-
self.X = X
|
|
20
|
-
self.Y = Y
|
|
21
|
-
self.Z = Z
|
|
22
|
-
# Centroid
|
|
23
|
-
self.cx = np.mean(X)
|
|
24
|
-
self.cy = np.mean(Y)
|
|
25
|
-
self.cz = np.mean(Z)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def scale(self,factor:float):
|
|
29
|
-
"""Scales a mesh by a certain factor
|
|
30
|
-
|
|
31
|
-
Args:
|
|
32
|
-
factor (float): _description_
|
|
33
|
-
"""
|
|
34
|
-
|
|
35
|
-
self.X *= factor
|
|
36
|
-
self.Y *= factor
|
|
37
|
-
self.Z *= factor
|
|
38
|
-
|
|
39
|
-
def shift(self,shift_amount:float,direction:str="z"):
|
|
40
|
-
"""shifts the blocks by a certain amount
|
|
41
|
-
|
|
42
|
-
Args:
|
|
43
|
-
shift_amount (float): _description_
|
|
44
|
-
direction (str, optional): _description_. Defaults to "z".
|
|
45
|
-
"""
|
|
46
|
-
if direction.lower() == 'z':
|
|
47
|
-
self.Z +=shift_amount
|
|
48
|
-
elif direction.lower() == 'y':
|
|
49
|
-
self.Y +=shift_amount
|
|
50
|
-
elif direction.lower() == 'x':
|
|
51
|
-
self.X +=shift_amount
|
|
52
|
-
|
|
53
|
-
def cylindrical(self):
|
|
54
|
-
"""Converts the block to cylindrical coordinate system. The rotation axis is assumed to be "x" direction
|
|
55
|
-
"""
|
|
56
|
-
self.r = np.sqrt(self.Z*self.Z + self.Y*self.Y)
|
|
57
|
-
self.theta = np.arctan2(self.Y,self.Z)
|
|
58
|
-
|
|
59
|
-
def cell_volumes(self):
|
|
60
|
-
"""Compute volume of all cells
|
|
61
|
-
|
|
62
|
-
Returns:
|
|
63
|
-
numpy.ndarray: volume of all cells
|
|
64
|
-
|
|
65
|
-
Reference:
|
|
66
|
-
Davies, D.E. and Salmond, D.J., "Calculation of the Volume of a General Hexahedron for Flow Predicitons", AIAA Journal, vol. 23, No. 6, pp. 954-956, June 1985. It is (supposedly) exact for a hexahedral whose faces are bi-linear surfaces (i.e., the simplest surface that can be fit through the four nodes defining the face).
|
|
67
|
-
"""
|
|
68
|
-
X = self.X
|
|
69
|
-
Y = self.Y
|
|
70
|
-
Z = self.Z
|
|
71
|
-
a = [np.zeros(shape=(self.IMAX,self.JMAX,self.KMAX)) for _ in range(9)]
|
|
72
|
-
# face csi=const
|
|
73
|
-
for k in range(1,self.KMAX):
|
|
74
|
-
for j in range(1,self.JMAX):
|
|
75
|
-
for i in range(self.IMAX): # csi-const
|
|
76
|
-
dx1 = X[i,j,k-1] - X[i,j-1,k]
|
|
77
|
-
dy1 = Y[i,j,k-1] - Y[i,j-1,k]
|
|
78
|
-
dz1 = Z[i,j,k-1] - Z[i,j-1,k]
|
|
79
|
-
|
|
80
|
-
dx2 = X[i,j,k] - X[i,j-1,k-1]
|
|
81
|
-
dy2 = Y[i,j,k] - Y[i,j-1,k-1]
|
|
82
|
-
dz2 = Z[i,j,k] - Z[i,j-1,k-1]
|
|
83
|
-
|
|
84
|
-
ax = dy1*dz2 - dz1*dy2
|
|
85
|
-
ay = dz1*dx2 - dx1*dz2
|
|
86
|
-
az = dx1*dy2 - dy1*dx2
|
|
87
|
-
|
|
88
|
-
a[0][i,j,k] = ax*0.5
|
|
89
|
-
a[1][i,j,k] = ay*0.5
|
|
90
|
-
a[2][i,j,k] = az*0.5
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
for k in range(1,self.KMAX):
|
|
94
|
-
for j in range(self.JMAX): # face eta=const
|
|
95
|
-
for i in range(1,self.IMAX):
|
|
96
|
-
dx1 = X[i,j,k] - X[i-1,j,k-1]
|
|
97
|
-
dy1 = Y[i,j,k] - Y[i-1,j,k-1]
|
|
98
|
-
dz1 = Z[i,j,k] - Z[i-1,j,k-1]
|
|
99
|
-
|
|
100
|
-
dx2 = X[i,j,k-1] - X[i-1,j,k]
|
|
101
|
-
dy2 = Y[i,j,k-1] - Y[i-1,j,k]
|
|
102
|
-
dz2 = Z[i,j,k-1] - Z[i-1,j,k]
|
|
103
|
-
|
|
104
|
-
ax = dy1*dz2 - dz1*dy2
|
|
105
|
-
ay = dz1*dx2 - dx1*dz2
|
|
106
|
-
az = dx1*dy2 - dy1*dx2
|
|
107
|
-
|
|
108
|
-
a[3][i,j,k] = ax*0.5
|
|
109
|
-
a[4][i,j,k] = ay*0.5
|
|
110
|
-
a[5][i,j,k] = az*0.5
|
|
111
|
-
|
|
112
|
-
# face zit=const
|
|
113
|
-
for k in range(self.KMAX): # zit=const
|
|
114
|
-
for j in range(1,self.JMAX):
|
|
115
|
-
for i in range(1,self.IMAX):
|
|
116
|
-
dx1 = X[i,j,k] - X[i-1,j-1,k]
|
|
117
|
-
dy1 = Y[i,j,k] - Y[i-1,j-1,k]
|
|
118
|
-
dz1 = Z[i,j,k] - Z[i-1,j-1,k]
|
|
119
|
-
|
|
120
|
-
dx2 = X[i-1,j,k] - X[i,j-1,k]
|
|
121
|
-
dy2 = Y[i-1,j,k] - Y[i,j-1,k]
|
|
122
|
-
dz2 = Z[i-1,j,k] - Z[i,j-1,k]
|
|
123
|
-
|
|
124
|
-
ax = dy1*dz2 - dz1*dy2
|
|
125
|
-
ay = dz1*dx2 - dx1*dz2
|
|
126
|
-
az = dx1*dy2 - dy1*dx2
|
|
127
|
-
|
|
128
|
-
a[6][i,j,k] = ax*0.5
|
|
129
|
-
a[7][i,j,k] = ay*0.5
|
|
130
|
-
a[8][i,j,k] = az*0.5
|
|
131
|
-
|
|
132
|
-
cf = np.zeros(shape=(6,3))
|
|
133
|
-
v = np.zeros(shape=(self.IMAX,self.JMAX,self.KMAX))
|
|
134
|
-
|
|
135
|
-
for k in trange(1,self.KMAX,desc='Calculating the volumes'):
|
|
136
|
-
for j in range(1,self.JMAX):
|
|
137
|
-
for i in range(1,self.IMAX):
|
|
138
|
-
cf[0,0] = X[i-1,j-1,k-1] + X[i-1,j-1,k] + X[i-1,j,k-1] + X[i-1,j,k]
|
|
139
|
-
cf[0,1] = Y[i-1,j-1,k-1] + Y[i-1,j-1,k] + Y[i-1,j,k-1] + Y[i-1,j,k]
|
|
140
|
-
cf[0,2] = Z[i-1,j-1,k-1] + Z[i-1,j-1,k] + Z[i-1,j,k-1] + Z[i-1,j,k]
|
|
141
|
-
cf[1,0] = X[i,j-1,k-1] + X[i,j-1,k] + X[i,j,k-1] + X[i,j,k]
|
|
142
|
-
cf[1,1] = Y[i,j-1,k-1] + Y[i,j-1,k] + Y[i,j,k-1] + Y[i,j,k]
|
|
143
|
-
cf[1,2] = Z[i,j-1,k-1] + Z[i,j-1,k] + Z[i,j,k-1] + Z[i,j,k]
|
|
144
|
-
cf[2,0] = X[i-1,j-1,k-1] + X[i-1,j-1,k] + X[i,j-1,k-1] + X[i,j-1,k]
|
|
145
|
-
cf[2,1] = Y[i-1,j-1,k-1] + Y[i-1,j-1,k] + Y[i,j-1,k-1] + Y[i,j-1,k]
|
|
146
|
-
cf[2,2] = Z[i-1,j-1,k-1] + Z[i-1,j-1,k] + Z[i,j-1,k-1] + Z[i,j-1,k]
|
|
147
|
-
cf[3,0] = X[i-1,j,k-1] + X[i-1,j,k] + X[i,j,k-1] + X[i,j,k]
|
|
148
|
-
cf[3,1] = Y[i-1,j,k-1] + Y[i-1,j,k] + Y[i,j,k-1] + Y[i,j,k]
|
|
149
|
-
cf[3,2] = Z[i-1,j,k-1] + Z[i-1,j,k] + Z[i,j,k-1] + Z[i,j,k]
|
|
150
|
-
cf[4,0] = X[i-1,j-1,k-1] + X[i-1,j,k-1] + X[i,j-1,k-1] + X[i,j,k-1]
|
|
151
|
-
cf[4,1] = Y[i-1,j-1,k-1] + Y[i-1,j,k-1] + Y[i,j-1,k-1] + Y[i,j,k-1]
|
|
152
|
-
cf[4,2] = Z[i-1,j-1,k-1] + Z[i-1,j,k-1] + Z[i,j-1,k-1] + Z[i,j,k-1]
|
|
153
|
-
cf[5,0] = X[i-1,j-1,k] + X[i-1,j,k] + X[i,j-1,k] + X[i,j,k]
|
|
154
|
-
cf[5,1] = Y[i-1,j-1,k] + Y[i-1,j,k] + Y[i,j-1,k] + Y[i,j,k]
|
|
155
|
-
cf[5,2] = Z[i-1,j-1,k] + Z[i-1,j,k] + Z[i,j-1,k] + Z[i,j,k]
|
|
156
|
-
|
|
157
|
-
vol12=0
|
|
158
|
-
for n in range(0,2): # n = 0,1
|
|
159
|
-
for l in range(0,3): # l = 0,1,2
|
|
160
|
-
vol12 += math.pow(-1,n+1) *(
|
|
161
|
-
+cf[n,l]*a[l][i-1+n,j,k]
|
|
162
|
-
+cf[2+n,l]*a[3+l][i,j-1+n,k]
|
|
163
|
-
+cf[4+n,l]*a[6+l][i,j,k-1+n])
|
|
164
|
-
v[i,j,k]= vol12/12
|
|
165
|
-
return v
|
|
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
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
blocks[
|
|
253
|
-
|
|
254
|
-
|
|
1
|
+
import numpy as np
|
|
2
|
+
import math
|
|
3
|
+
from tqdm import trange
|
|
4
|
+
from typing import List
|
|
5
|
+
|
|
6
|
+
class Block:
|
|
7
|
+
"""Plot3D Block definition
|
|
8
|
+
"""
|
|
9
|
+
def __init__(self, X:np.ndarray,Y:np.ndarray,Z:np.ndarray):
|
|
10
|
+
"""Initializes the block using all the X,Y,Z coordinates of the block
|
|
11
|
+
|
|
12
|
+
Args:
|
|
13
|
+
X (np.ndarray): All the X coordinates (i,j,k)
|
|
14
|
+
Y (np.ndarray): All the Y coordinates (i,j,k)
|
|
15
|
+
Z (np.ndarray): All the Z coordinates (i,j,k)
|
|
16
|
+
|
|
17
|
+
"""
|
|
18
|
+
self.IMAX,self.JMAX,self.KMAX = X.shape;
|
|
19
|
+
self.X = X
|
|
20
|
+
self.Y = Y
|
|
21
|
+
self.Z = Z
|
|
22
|
+
# Centroid
|
|
23
|
+
self.cx = np.mean(X)
|
|
24
|
+
self.cy = np.mean(Y)
|
|
25
|
+
self.cz = np.mean(Z)
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def scale(self,factor:float):
|
|
29
|
+
"""Scales a mesh by a certain factor
|
|
30
|
+
|
|
31
|
+
Args:
|
|
32
|
+
factor (float): _description_
|
|
33
|
+
"""
|
|
34
|
+
|
|
35
|
+
self.X *= factor
|
|
36
|
+
self.Y *= factor
|
|
37
|
+
self.Z *= factor
|
|
38
|
+
|
|
39
|
+
def shift(self,shift_amount:float,direction:str="z"):
|
|
40
|
+
"""shifts the blocks by a certain amount
|
|
41
|
+
|
|
42
|
+
Args:
|
|
43
|
+
shift_amount (float): _description_
|
|
44
|
+
direction (str, optional): _description_. Defaults to "z".
|
|
45
|
+
"""
|
|
46
|
+
if direction.lower() == 'z':
|
|
47
|
+
self.Z +=shift_amount
|
|
48
|
+
elif direction.lower() == 'y':
|
|
49
|
+
self.Y +=shift_amount
|
|
50
|
+
elif direction.lower() == 'x':
|
|
51
|
+
self.X +=shift_amount
|
|
52
|
+
|
|
53
|
+
def cylindrical(self):
|
|
54
|
+
"""Converts the block to cylindrical coordinate system. The rotation axis is assumed to be "x" direction
|
|
55
|
+
"""
|
|
56
|
+
self.r = np.sqrt(self.Z*self.Z + self.Y*self.Y)
|
|
57
|
+
self.theta = np.arctan2(self.Y,self.Z)
|
|
58
|
+
|
|
59
|
+
def cell_volumes(self):
|
|
60
|
+
"""Compute volume of all cells
|
|
61
|
+
|
|
62
|
+
Returns:
|
|
63
|
+
numpy.ndarray: volume of all cells
|
|
64
|
+
|
|
65
|
+
Reference:
|
|
66
|
+
Davies, D.E. and Salmond, D.J., "Calculation of the Volume of a General Hexahedron for Flow Predicitons", AIAA Journal, vol. 23, No. 6, pp. 954-956, June 1985. It is (supposedly) exact for a hexahedral whose faces are bi-linear surfaces (i.e., the simplest surface that can be fit through the four nodes defining the face).
|
|
67
|
+
"""
|
|
68
|
+
X = self.X
|
|
69
|
+
Y = self.Y
|
|
70
|
+
Z = self.Z
|
|
71
|
+
a = [np.zeros(shape=(self.IMAX,self.JMAX,self.KMAX)) for _ in range(9)]
|
|
72
|
+
# face csi=const
|
|
73
|
+
for k in range(1,self.KMAX):
|
|
74
|
+
for j in range(1,self.JMAX):
|
|
75
|
+
for i in range(self.IMAX): # csi-const
|
|
76
|
+
dx1 = X[i,j,k-1] - X[i,j-1,k]
|
|
77
|
+
dy1 = Y[i,j,k-1] - Y[i,j-1,k]
|
|
78
|
+
dz1 = Z[i,j,k-1] - Z[i,j-1,k]
|
|
79
|
+
|
|
80
|
+
dx2 = X[i,j,k] - X[i,j-1,k-1]
|
|
81
|
+
dy2 = Y[i,j,k] - Y[i,j-1,k-1]
|
|
82
|
+
dz2 = Z[i,j,k] - Z[i,j-1,k-1]
|
|
83
|
+
|
|
84
|
+
ax = dy1*dz2 - dz1*dy2
|
|
85
|
+
ay = dz1*dx2 - dx1*dz2
|
|
86
|
+
az = dx1*dy2 - dy1*dx2
|
|
87
|
+
|
|
88
|
+
a[0][i,j,k] = ax*0.5
|
|
89
|
+
a[1][i,j,k] = ay*0.5
|
|
90
|
+
a[2][i,j,k] = az*0.5
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
for k in range(1,self.KMAX):
|
|
94
|
+
for j in range(self.JMAX): # face eta=const
|
|
95
|
+
for i in range(1,self.IMAX):
|
|
96
|
+
dx1 = X[i,j,k] - X[i-1,j,k-1]
|
|
97
|
+
dy1 = Y[i,j,k] - Y[i-1,j,k-1]
|
|
98
|
+
dz1 = Z[i,j,k] - Z[i-1,j,k-1]
|
|
99
|
+
|
|
100
|
+
dx2 = X[i,j,k-1] - X[i-1,j,k]
|
|
101
|
+
dy2 = Y[i,j,k-1] - Y[i-1,j,k]
|
|
102
|
+
dz2 = Z[i,j,k-1] - Z[i-1,j,k]
|
|
103
|
+
|
|
104
|
+
ax = dy1*dz2 - dz1*dy2
|
|
105
|
+
ay = dz1*dx2 - dx1*dz2
|
|
106
|
+
az = dx1*dy2 - dy1*dx2
|
|
107
|
+
|
|
108
|
+
a[3][i,j,k] = ax*0.5
|
|
109
|
+
a[4][i,j,k] = ay*0.5
|
|
110
|
+
a[5][i,j,k] = az*0.5
|
|
111
|
+
|
|
112
|
+
# face zit=const
|
|
113
|
+
for k in range(self.KMAX): # zit=const
|
|
114
|
+
for j in range(1,self.JMAX):
|
|
115
|
+
for i in range(1,self.IMAX):
|
|
116
|
+
dx1 = X[i,j,k] - X[i-1,j-1,k]
|
|
117
|
+
dy1 = Y[i,j,k] - Y[i-1,j-1,k]
|
|
118
|
+
dz1 = Z[i,j,k] - Z[i-1,j-1,k]
|
|
119
|
+
|
|
120
|
+
dx2 = X[i-1,j,k] - X[i,j-1,k]
|
|
121
|
+
dy2 = Y[i-1,j,k] - Y[i,j-1,k]
|
|
122
|
+
dz2 = Z[i-1,j,k] - Z[i,j-1,k]
|
|
123
|
+
|
|
124
|
+
ax = dy1*dz2 - dz1*dy2
|
|
125
|
+
ay = dz1*dx2 - dx1*dz2
|
|
126
|
+
az = dx1*dy2 - dy1*dx2
|
|
127
|
+
|
|
128
|
+
a[6][i,j,k] = ax*0.5
|
|
129
|
+
a[7][i,j,k] = ay*0.5
|
|
130
|
+
a[8][i,j,k] = az*0.5
|
|
131
|
+
|
|
132
|
+
cf = np.zeros(shape=(6,3))
|
|
133
|
+
v = np.zeros(shape=(self.IMAX,self.JMAX,self.KMAX))
|
|
134
|
+
|
|
135
|
+
for k in trange(1,self.KMAX,desc='Calculating the volumes'):
|
|
136
|
+
for j in range(1,self.JMAX):
|
|
137
|
+
for i in range(1,self.IMAX):
|
|
138
|
+
cf[0,0] = X[i-1,j-1,k-1] + X[i-1,j-1,k] + X[i-1,j,k-1] + X[i-1,j,k]
|
|
139
|
+
cf[0,1] = Y[i-1,j-1,k-1] + Y[i-1,j-1,k] + Y[i-1,j,k-1] + Y[i-1,j,k]
|
|
140
|
+
cf[0,2] = Z[i-1,j-1,k-1] + Z[i-1,j-1,k] + Z[i-1,j,k-1] + Z[i-1,j,k]
|
|
141
|
+
cf[1,0] = X[i,j-1,k-1] + X[i,j-1,k] + X[i,j,k-1] + X[i,j,k]
|
|
142
|
+
cf[1,1] = Y[i,j-1,k-1] + Y[i,j-1,k] + Y[i,j,k-1] + Y[i,j,k]
|
|
143
|
+
cf[1,2] = Z[i,j-1,k-1] + Z[i,j-1,k] + Z[i,j,k-1] + Z[i,j,k]
|
|
144
|
+
cf[2,0] = X[i-1,j-1,k-1] + X[i-1,j-1,k] + X[i,j-1,k-1] + X[i,j-1,k]
|
|
145
|
+
cf[2,1] = Y[i-1,j-1,k-1] + Y[i-1,j-1,k] + Y[i,j-1,k-1] + Y[i,j-1,k]
|
|
146
|
+
cf[2,2] = Z[i-1,j-1,k-1] + Z[i-1,j-1,k] + Z[i,j-1,k-1] + Z[i,j-1,k]
|
|
147
|
+
cf[3,0] = X[i-1,j,k-1] + X[i-1,j,k] + X[i,j,k-1] + X[i,j,k]
|
|
148
|
+
cf[3,1] = Y[i-1,j,k-1] + Y[i-1,j,k] + Y[i,j,k-1] + Y[i,j,k]
|
|
149
|
+
cf[3,2] = Z[i-1,j,k-1] + Z[i-1,j,k] + Z[i,j,k-1] + Z[i,j,k]
|
|
150
|
+
cf[4,0] = X[i-1,j-1,k-1] + X[i-1,j,k-1] + X[i,j-1,k-1] + X[i,j,k-1]
|
|
151
|
+
cf[4,1] = Y[i-1,j-1,k-1] + Y[i-1,j,k-1] + Y[i,j-1,k-1] + Y[i,j,k-1]
|
|
152
|
+
cf[4,2] = Z[i-1,j-1,k-1] + Z[i-1,j,k-1] + Z[i,j-1,k-1] + Z[i,j,k-1]
|
|
153
|
+
cf[5,0] = X[i-1,j-1,k] + X[i-1,j,k] + X[i,j-1,k] + X[i,j,k]
|
|
154
|
+
cf[5,1] = Y[i-1,j-1,k] + Y[i-1,j,k] + Y[i,j-1,k] + Y[i,j,k]
|
|
155
|
+
cf[5,2] = Z[i-1,j-1,k] + Z[i-1,j,k] + Z[i,j-1,k] + Z[i,j,k]
|
|
156
|
+
|
|
157
|
+
vol12=0
|
|
158
|
+
for n in range(0,2): # n = 0,1
|
|
159
|
+
for l in range(0,3): # l = 0,1,2
|
|
160
|
+
vol12 += math.pow(-1,n+1) *(
|
|
161
|
+
+cf[n,l]*a[l][i-1+n,j,k]
|
|
162
|
+
+cf[2+n,l]*a[3+l][i,j-1+n,k]
|
|
163
|
+
+cf[4+n,l]*a[6+l][i,j,k-1+n])
|
|
164
|
+
v[i,j,k]= vol12/12
|
|
165
|
+
return v
|
|
166
|
+
|
|
167
|
+
@property
|
|
168
|
+
def size(self)->int:
|
|
169
|
+
"""returns the total number of nodes
|
|
170
|
+
|
|
171
|
+
Returns:
|
|
172
|
+
int: number of nodes
|
|
173
|
+
"""
|
|
174
|
+
return self.IMAX*self.JMAX*self.KMAX
|
|
175
|
+
|
|
176
|
+
def checkCollinearity(v1:np.ndarray, v2:np.ndarray):
|
|
177
|
+
# Calculate their cross product
|
|
178
|
+
cross_P = np.cross(v1,v2)
|
|
179
|
+
|
|
180
|
+
# Check if their cross product
|
|
181
|
+
# is a NULL Vector or not
|
|
182
|
+
if (cross_P[0] == 0 and
|
|
183
|
+
cross_P[1] == 0 and
|
|
184
|
+
cross_P[2] == 0):
|
|
185
|
+
return True
|
|
186
|
+
else:
|
|
187
|
+
return False
|
|
188
|
+
|
|
189
|
+
def calculate_outward_normals(block:Block):
|
|
190
|
+
# Calculate Normals
|
|
191
|
+
X = block.X
|
|
192
|
+
Y = block.Y
|
|
193
|
+
Z = block.Z
|
|
194
|
+
imax = block.IMAX
|
|
195
|
+
jmax = block.JMAX
|
|
196
|
+
kmax = block.KMAX
|
|
197
|
+
# IMAX - Normal should be out of the page
|
|
198
|
+
# Normals I direction: IMIN https://www.khronos.org/opengl/wiki/Calculating_a_Surface_Normal
|
|
199
|
+
x = [X[0,0,0],X[0,jmax,0],X[0,0,kmax]]
|
|
200
|
+
y = [Y[0,0,0],Y[0,jmax,0],Y[0,0,kmax]]
|
|
201
|
+
z = [Z[0,0,0],Z[0,jmax,0],Z[0,0,kmax]]
|
|
202
|
+
u = np.array([x[1]-x[0],y[1]-y[0],z[1]-z[0]])
|
|
203
|
+
v = np.array([x[2]-x[0],y[2]-y[0],z[2]-z[0]])
|
|
204
|
+
n_imin = np.cross(v1,v2)
|
|
205
|
+
|
|
206
|
+
# Normals I direction: IMAX
|
|
207
|
+
x = [X[imax,0,0],X[imax,jmax,0],X[imax,0,kmax]]
|
|
208
|
+
y = [Y[imax,0,0],Y[imax,jmax,0],Y[imax,0,kmax]]
|
|
209
|
+
z = [Z[imax,0,0],Z[imax,jmax,0],Z[imax,0,kmax]]
|
|
210
|
+
v1 = np.array([x[1]-x[0],y[1]-y[0],z[1]-z[0]])
|
|
211
|
+
v2 = np.array([x[2]-x[0],y[2]-y[0],z[2]-z[0]])
|
|
212
|
+
n_imax = np.cross(v1,v2)
|
|
213
|
+
|
|
214
|
+
# Normals J direction: JMIN
|
|
215
|
+
x = [X[0,0,0],X[imax,0,0],X[0,0,kmax]]
|
|
216
|
+
y = [Y[0,0,0],Y[imax,0,0],Y[0,0,kmax]]
|
|
217
|
+
z = [Z[0,0,0],Z[imax,0,0],Z[0,0,kmax]]
|
|
218
|
+
v1 = np.array([x[1]-x[0],y[1]-y[0],z[1]-z[0]])
|
|
219
|
+
v2 = np.array([x[2]-x[0],y[2]-y[0],z[2]-z[0]])
|
|
220
|
+
n_jmin = np.cross(v1,v2)
|
|
221
|
+
|
|
222
|
+
# Normals J direction: JMAX
|
|
223
|
+
x = [X[0,jmax,0],X[imax,jmax,0],X[0,jmax,kmax]]
|
|
224
|
+
y = [Y[0,jmax,0],Y[imax,jmax,0],Y[0,jmax,kmax]]
|
|
225
|
+
z = [Z[0,jmax,0],Z[imax,jmax,0],Z[0,jmax,kmax]]
|
|
226
|
+
v1 = np.array([x[1]-x[0],y[1]-y[0],z[1]-z[0]])
|
|
227
|
+
v2 = np.array([x[2]-x[0],y[2]-y[0],z[2]-z[0]])
|
|
228
|
+
n_jmax = np.cross(v1,v2)
|
|
229
|
+
|
|
230
|
+
# Normals K direction: KMIN
|
|
231
|
+
x = [X[imax,0,0],X[0,jmax,0],X[0,0,0]]
|
|
232
|
+
y = [Y[imax,0,0],Y[0,jmax,0],Y[0,0,0]]
|
|
233
|
+
z = [Z[imax,0,0],Z[0,jmax,0],Z[0,0,0]]
|
|
234
|
+
v1 = np.array([x[1]-x[0],y[1]-y[0],z[1]-z[0]])
|
|
235
|
+
v2 = np.array([x[2]-x[0],y[2]-y[0],z[2]-z[0]])
|
|
236
|
+
n_kmin = np.cross(v1,v2)
|
|
237
|
+
|
|
238
|
+
# Normals K direction: KMAX
|
|
239
|
+
x = [X[imax,0,kmax],X[0,jmax,kmax],X[0,0,kmax]]
|
|
240
|
+
y = [Y[imax,0,kmax],Y[0,jmax,kmax],Y[0,0,kmax]]
|
|
241
|
+
z = [Z[imax,0,kmax],Z[0,jmax,kmax],Z[0,0,kmax]]
|
|
242
|
+
v1 = np.array([x[1]-x[0],y[1]-y[0],z[1]-z[0]])
|
|
243
|
+
v2 = np.array([x[2]-x[0],y[2]-y[0],z[2]-z[0]])
|
|
244
|
+
n_kmax = np.cross(v1,v2)
|
|
245
|
+
|
|
246
|
+
return n_imin,n_jmin,n_kmin,n_imax,n_jmax,n_kmax
|
|
247
|
+
|
|
248
|
+
def reduce_blocks(blocks:List[Block],factor:int):
|
|
249
|
+
"""reduce the blocks by a factor of (factor)
|
|
250
|
+
|
|
251
|
+
Args:
|
|
252
|
+
blocks (List[Block]): list of blocks to reduce in size
|
|
253
|
+
factor (int, optional): Number of indicies to skip . Defaults to 2.
|
|
254
|
+
|
|
255
|
+
Returns:
|
|
256
|
+
[type]: [description]
|
|
257
|
+
"""
|
|
258
|
+
for i in range(len(blocks)):
|
|
259
|
+
blocks[i].X = blocks[i].X[::factor,::factor,::factor]
|
|
260
|
+
blocks[i].Y = blocks[i].Y[::factor,::factor,::factor]
|
|
261
|
+
blocks[i].Z = blocks[i].Z[::factor,::factor,::factor]
|
|
262
|
+
blocks[i].IMAX,blocks[i].JMAX,blocks[i].KMAX = blocks[i].X.shape
|
|
263
|
+
return blocks
|
|
264
|
+
|