modulo-vki 2.0.6__py3-none-any.whl → 2.0.7__py3-none-any.whl
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.
- modulo_vki/__init__.py +22 -22
- modulo_vki/core/__init__.py +9 -9
- modulo_vki/core/_dft.py +61 -61
- modulo_vki/core/_dmd_s.py +72 -72
- modulo_vki/core/_k_matrix.py +81 -81
- modulo_vki/core/_mpod_space.py +180 -180
- modulo_vki/core/_mpod_time.py +154 -154
- modulo_vki/core/_pod_space.py +184 -184
- modulo_vki/core/_pod_time.py +48 -48
- modulo_vki/core/_spod_s.py +101 -101
- modulo_vki/core/_spod_t.py +104 -104
- modulo_vki/modulo.py +828 -828
- modulo_vki/utils/__init__.py +4 -4
- modulo_vki/utils/_plots.py +51 -51
- modulo_vki/utils/_utils.py +341 -341
- modulo_vki/utils/others.py +452 -452
- modulo_vki/utils/read_db.py +339 -339
- {modulo_vki-2.0.6.dist-info → modulo_vki-2.0.7.dist-info}/LICENSE +21 -21
- {modulo_vki-2.0.6.dist-info → modulo_vki-2.0.7.dist-info}/METADATA +304 -304
- modulo_vki-2.0.7.dist-info/RECORD +22 -0
- modulo_vki-2.0.6.dist-info/RECORD +0 -22
- {modulo_vki-2.0.6.dist-info → modulo_vki-2.0.7.dist-info}/WHEEL +0 -0
- {modulo_vki-2.0.6.dist-info → modulo_vki-2.0.7.dist-info}/top_level.txt +0 -0
modulo_vki/utils/others.py
CHANGED
|
@@ -1,452 +1,452 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
"""
|
|
3
|
-
Created on Mon Dec 30 20:33:42 2019
|
|
4
|
-
@author: mendez
|
|
5
|
-
"""
|
|
6
|
-
|
|
7
|
-
import numpy as np
|
|
8
|
-
import matplotlib.pyplot as plt
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def Plot_Field_TEXT_JET(File):
|
|
12
|
-
"""
|
|
13
|
-
This function plots the vector field from the TR-PIV in Exercise 4.
|
|
14
|
-
|
|
15
|
-
:param File: Name of the file to load
|
|
16
|
-
|
|
17
|
-
"""
|
|
18
|
-
# We first perform a zero padding
|
|
19
|
-
Name = File
|
|
20
|
-
# Read data from a file
|
|
21
|
-
DATA = np.genfromtxt(Name) # Here we have the four colums
|
|
22
|
-
Dat = DATA[1:, :] # Here we remove the first raw, containing the header
|
|
23
|
-
nxny = Dat.shape[0] # is the to be doubled at the end we will have n_s=2 * n_x * n_y
|
|
24
|
-
n_s = 2 * nxny
|
|
25
|
-
## 1. Reconstruct Mesh from file
|
|
26
|
-
X_S = Dat[:, 0]
|
|
27
|
-
Y_S = Dat[:, 1]
|
|
28
|
-
# Reshape also the velocity components
|
|
29
|
-
V_X = Dat[:, 2] # U component
|
|
30
|
-
V_Y = Dat[:, 3] # V component
|
|
31
|
-
# Put both components as fields in the grid
|
|
32
|
-
Xg, Yg, Vxg, Vyg, Magn = Plot_Field_JET(X_S, Y_S, V_X, V_Y, False, 2, 0.6)
|
|
33
|
-
# Show this particular step
|
|
34
|
-
fig, ax = plt.subplots(figsize=(8, 5)) # This creates the figure
|
|
35
|
-
# Or you can plot it as streamlines
|
|
36
|
-
plt.contourf(Xg, Yg, Magn)
|
|
37
|
-
# One possibility is to use quiver
|
|
38
|
-
STEPx = 2
|
|
39
|
-
STEPy = 2
|
|
40
|
-
plt.quiver(Xg[::STEPx, ::STEPy], Yg[::STEPx, ::STEPy], \
|
|
41
|
-
Vxg[::STEPx, ::STEPy], -Vyg[::STEPx, ::STEPy], color='k') # Create a quiver (arrows) plot
|
|
42
|
-
|
|
43
|
-
plt.rc('text', usetex=True) # This is Miguel's customization
|
|
44
|
-
plt.rc('font', family='serif')
|
|
45
|
-
plt.rc('xtick', labelsize=16)
|
|
46
|
-
plt.rc('ytick', labelsize=16)
|
|
47
|
-
ax.set_aspect('equal') # Set equal aspect ratio
|
|
48
|
-
ax.set_xlabel('$x[mm]$', fontsize=16)
|
|
49
|
-
ax.set_ylabel('$y[mm]$', fontsize=16)
|
|
50
|
-
ax.set_title('Velocity Field via TR-PIV', fontsize=18)
|
|
51
|
-
ax.set_xticks(np.arange(0, 40, 10))
|
|
52
|
-
ax.set_yticks(np.arange(10, 30, 5))
|
|
53
|
-
ax.set_xlim([0, 35])
|
|
54
|
-
ax.set_ylim(10, 29)
|
|
55
|
-
ax.invert_yaxis() # Invert Axis for plotting purpose
|
|
56
|
-
plt.show()
|
|
57
|
-
Name[len(Name) - 12:len(Name)] + ' Plotted'
|
|
58
|
-
return n_s, Xg, Yg, Vxg, -Vyg, X_S, Y_S
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def Plot_Field_JET(X_S, Y_S, V_X, V_Y, PLOT, Step, Scale):
|
|
62
|
-
# Number of n_X/n_Y from forward differences
|
|
63
|
-
GRAD_X = np.diff(X_S)
|
|
64
|
-
# GRAD_Y=np.diff(Y_S);
|
|
65
|
-
# Depending on the reshaping performed, one of the two will start with
|
|
66
|
-
# non-zero gradient. The other will have zero gradient only on the change.
|
|
67
|
-
IND_X = np.where(GRAD_X != 0);
|
|
68
|
-
DAT = IND_X[0];
|
|
69
|
-
n_y = DAT[0] + 1;
|
|
70
|
-
nxny = X_S.shape[0] # is the to be doubled at the end we will have n_s=2 * n_x * n_y
|
|
71
|
-
# n_s=2*nxny
|
|
72
|
-
# Reshaping the grid from the data
|
|
73
|
-
n_x = (nxny // (n_y)) # Carefull with integer and float!
|
|
74
|
-
Xg = np.transpose(X_S.reshape((n_x, n_y)))
|
|
75
|
-
Yg = np.transpose(Y_S.reshape((n_x, n_y))) # This is now the mesh! 60x114.
|
|
76
|
-
Mod = np.sqrt(V_X ** 2 + V_Y ** 2)
|
|
77
|
-
Vxg = np.transpose(V_X.reshape((n_x, n_y)))
|
|
78
|
-
Vyg = np.transpose(V_Y.reshape((n_x, n_y)))
|
|
79
|
-
Magn = np.transpose(Mod.reshape((n_x, n_y)))
|
|
80
|
-
if PLOT:
|
|
81
|
-
# Show this particular step
|
|
82
|
-
# fig, ax = plt.subplots(figsize=(8, 5)) # This creates the figure
|
|
83
|
-
# Or you can plot it as streamlines
|
|
84
|
-
#fig, ax = plt.subplots(figsize=(8, 5)) # This creates the figure
|
|
85
|
-
#ax.contourf(Xg, Yg, Magn)
|
|
86
|
-
plt.contourf(Xg,Yg,Magn)
|
|
87
|
-
# One possibility is to use quiver
|
|
88
|
-
STEPx = Step
|
|
89
|
-
STEPy = Step
|
|
90
|
-
|
|
91
|
-
plt.quiver(Xg[::STEPx, ::STEPy], Yg[::STEPx, ::STEPy], \
|
|
92
|
-
Vxg[::STEPx, ::STEPy], -Vyg[::STEPx, ::STEPy], color='k',
|
|
93
|
-
scale=Scale) # Create a quiver (arrows) plot
|
|
94
|
-
|
|
95
|
-
plt.rc('text', usetex=True) # This is Miguel's customization
|
|
96
|
-
plt.rc('font', family='serif')
|
|
97
|
-
plt.rc('xtick', labelsize=16)
|
|
98
|
-
plt.rc('ytick', labelsize=16)
|
|
99
|
-
# ax.set_aspect('equal') # Set equal aspect ratio
|
|
100
|
-
# ax.set_xlabel('$x[mm]$',fontsize=16)
|
|
101
|
-
# ax.set_ylabel('$y[mm]$',fontsize=16)
|
|
102
|
-
# ax.set_title('Velocity Field via TR-PIV',fontsize=18)
|
|
103
|
-
# ax.set_xticks(np.arange(0,40,10))
|
|
104
|
-
# ax.set_yticks(np.arange(10,30,5))
|
|
105
|
-
# ax.set_xlim([0,35])
|
|
106
|
-
# ax.set_ylim(10,29)
|
|
107
|
-
# ax.invert_yaxis() # Invert Axis for plotting purpose
|
|
108
|
-
# plt.show()
|
|
109
|
-
|
|
110
|
-
return Xg, Yg, Vxg, Vyg, Magn
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
# Define the function to produce a gif file
|
|
114
|
-
def Animation_JET(Giff_NAME,D,X_S,Y_S,In,Fin,Step):
|
|
115
|
-
"""
|
|
116
|
-
The gif file is created from the provided data snapshot
|
|
117
|
-
"""
|
|
118
|
-
n_t=Fin-In
|
|
119
|
-
GRAD_X = np.diff(X_S)
|
|
120
|
-
IND_X = np.where(GRAD_X != 0);
|
|
121
|
-
DAT = IND_X[0];
|
|
122
|
-
n_y = DAT[0] + 1;
|
|
123
|
-
nxny = X_S.shape[0] # is the to be doubled at the end we will have n_s=2 * n_x * n_y
|
|
124
|
-
# n_s=2*nxny
|
|
125
|
-
# Reshaping the grid from the data
|
|
126
|
-
n_x = (nxny // (n_y)) # Carefull with integer and float!
|
|
127
|
-
Xg = np.transpose(X_S.reshape((n_x, n_y)))
|
|
128
|
-
Yg = np.transpose(Y_S.reshape((n_x, n_y))) # This is now the mesh! 60x114. n_y, n_x = Yg.shape;
|
|
129
|
-
nxny = n_x * n_y
|
|
130
|
-
import os
|
|
131
|
-
# Create a temporary file to store the images in the GIF
|
|
132
|
-
Fol_Out = 'Gif_Images_temporary'
|
|
133
|
-
if not os.path.exists(Fol_Out):
|
|
134
|
-
os.mkdir(Fol_Out)
|
|
135
|
-
|
|
136
|
-
# Prepare Animation of the analytical solution
|
|
137
|
-
for k in range(1,n_t,Step):
|
|
138
|
-
Dat = D[:, k+In]
|
|
139
|
-
V_X_m = Dat[0:nxny]
|
|
140
|
-
V_Y_m = Dat[nxny::]
|
|
141
|
-
# Put both components as fields in the grid
|
|
142
|
-
Mod = np.sqrt(V_X_m ** 2 + V_Y_m ** 2)
|
|
143
|
-
Vxg = np.transpose(V_X_m.reshape((n_x, n_y)))
|
|
144
|
-
Vyg = np.transpose(V_Y_m.reshape((n_x, n_y)))
|
|
145
|
-
Magn = np.transpose(Mod.reshape((n_x, n_y)))
|
|
146
|
-
fig, ax = plt.subplots(figsize=(8, 5)) # This creates the figure
|
|
147
|
-
# Or you can plot it as streamlines
|
|
148
|
-
plt.contourf(Xg, Yg, Magn)
|
|
149
|
-
# One possibility is to use quiver
|
|
150
|
-
STEPx = 2
|
|
151
|
-
STEPy = 2
|
|
152
|
-
plt.quiver(Xg[::STEPx, ::STEPy], Yg[::STEPx, ::STEPy], \
|
|
153
|
-
Vxg[::STEPx, ::STEPy], -Vyg[::STEPx, ::STEPy], color='k') # Create a quiver (arrows) plot
|
|
154
|
-
|
|
155
|
-
plt.rc('text', usetex=True) # This is Miguel's customization
|
|
156
|
-
plt.rc('font', family='serif')
|
|
157
|
-
plt.rc('xtick', labelsize=16)
|
|
158
|
-
plt.rc('ytick', labelsize=16)
|
|
159
|
-
ax.set_aspect('equal') # Set equal aspect ratio
|
|
160
|
-
ax.set_xlabel('$x[mm]$', fontsize=16)
|
|
161
|
-
ax.set_ylabel('$y[mm]$', fontsize=16)
|
|
162
|
-
#ax.set_title('Velocity Field via TR-PIV', fontsize=18)
|
|
163
|
-
ax.set_xticks(np.arange(0, 40, 10))
|
|
164
|
-
ax.set_yticks(np.arange(10, 30, 5))
|
|
165
|
-
ax.set_xlim([0, 35])
|
|
166
|
-
ax.set_ylim(10, 29)
|
|
167
|
-
plt.clim(0, 6)
|
|
168
|
-
ax.invert_yaxis() # Invert Axis for plotting purpose
|
|
169
|
-
#plt.show()
|
|
170
|
-
|
|
171
|
-
NameOUT = Fol_Out + os.sep + 'Im%03d' % (k) + '.png'
|
|
172
|
-
plt.savefig(NameOUT, dpi=100)
|
|
173
|
-
plt.close(fig)
|
|
174
|
-
print('Image n ' + str(k) + ' of ' + str(n_t))
|
|
175
|
-
|
|
176
|
-
# Assembly the GIF
|
|
177
|
-
import imageio # This used for the animation
|
|
178
|
-
|
|
179
|
-
images = []
|
|
180
|
-
|
|
181
|
-
for k in range(1,n_t,Step):
|
|
182
|
-
MEX = 'Preparing Im ' + str(k)
|
|
183
|
-
print(MEX)
|
|
184
|
-
NameOUT = Fol_Out + os.sep + 'Im%03d' % (k) + '.png'
|
|
185
|
-
images.append(imageio.imread(NameOUT))
|
|
186
|
-
|
|
187
|
-
# Now we can assembly the video and clean the folder of png's (optional)
|
|
188
|
-
imageio.mimsave(Giff_NAME, images, duration=0.05)
|
|
189
|
-
import shutil # nice and powerfull tool to delete a folder and its content
|
|
190
|
-
|
|
191
|
-
shutil.rmtree(Fol_Out)
|
|
192
|
-
return 'Gif Created'
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
def Plot_2D_CFD_Cyl(Xg,Yg,U,V,k=10,CL=16,Name='', verbose=False):
|
|
198
|
-
# Make a 2D plot of the 2D cylinder test case in Openfoam.
|
|
199
|
-
n_x,n_y=np.shape(Xg)
|
|
200
|
-
U_g=U[:,k].reshape(n_y,n_x).T
|
|
201
|
-
V_g=V[:,k].reshape(n_y,n_x).T
|
|
202
|
-
# Prepare the plot
|
|
203
|
-
fig, ax = plt.subplots(figsize=(6, 3)) # This creates the figure
|
|
204
|
-
plt.contourf(Xg,Yg,np.sqrt(U_g**2+V_g**2),30)
|
|
205
|
-
# plt.quiver(Xg,Yg,U_g,V_g,scale=10000)
|
|
206
|
-
ax.set_aspect('equal') # Set equal aspect ratio
|
|
207
|
-
ax.set_xlabel('$x[mm]$',fontsize=13)
|
|
208
|
-
ax.set_ylabel('$y[mm]$',fontsize=13)
|
|
209
|
-
#ax.set_title('Tutorial 2: Cylinder Wake',fontsize=12)
|
|
210
|
-
ax.set_xticks(np.arange(-0.1,0.2,0.05))
|
|
211
|
-
ax.set_yticks(np.arange(-0.1,0.1,0.05))
|
|
212
|
-
ax.set_xlim([-0.05,0.2])
|
|
213
|
-
ax.set_ylim(-0.05,0.05)
|
|
214
|
-
|
|
215
|
-
if CL !=0:
|
|
216
|
-
plt.clim(0, CL)
|
|
217
|
-
|
|
218
|
-
circle = plt.Circle((0,0),0.0075,fill=True,color='r',edgecolor='k',alpha=0.5)
|
|
219
|
-
plt.gcf().gca().add_artist(circle)
|
|
220
|
-
plt.tight_layout()
|
|
221
|
-
|
|
222
|
-
if len(Name) !=0:
|
|
223
|
-
plt.savefig(Name, dpi=200)
|
|
224
|
-
plt.close(fig)
|
|
225
|
-
|
|
226
|
-
if verbose:
|
|
227
|
-
print('Image exported')
|
|
228
|
-
|
|
229
|
-
return
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
def Animation_2D_CFD_Cyl(Giff_NAME,D,Xg,Yg,In,Fin,Step):
|
|
233
|
-
"""
|
|
234
|
-
The gif file is created from the provided data snapshot
|
|
235
|
-
"""
|
|
236
|
-
n_t=Fin-In
|
|
237
|
-
n_x,n_y=np.shape(Xg); nxny=n_x*n_y
|
|
238
|
-
U = D[0:nxny,:]
|
|
239
|
-
V = D[nxny::,]
|
|
240
|
-
|
|
241
|
-
import os
|
|
242
|
-
# Create a temporary file to store the images in the GIF
|
|
243
|
-
Fol_Out = 'Gif_Images_temporary'
|
|
244
|
-
if not os.path.exists(Fol_Out):
|
|
245
|
-
os.mkdir(Fol_Out)
|
|
246
|
-
# Loop to produce the Gifs
|
|
247
|
-
for k in range(1,n_t,Step):
|
|
248
|
-
NameOUT = Fol_Out + os.sep + 'Im%03d' % (k) + '.png'
|
|
249
|
-
Plot_2D_CFD_Cyl(Xg,Yg,U,V,k=k+In,CL=16,Name=NameOUT)
|
|
250
|
-
|
|
251
|
-
import imageio # This used for the animation
|
|
252
|
-
images = []
|
|
253
|
-
|
|
254
|
-
for k in range(1,n_t,Step):
|
|
255
|
-
MEX = 'Preparing Im ' + str(k)
|
|
256
|
-
print(MEX)
|
|
257
|
-
NameOUT = Fol_Out + os.sep + 'Im%03d' % (k) + '.png'
|
|
258
|
-
images.append(imageio.imread(NameOUT))
|
|
259
|
-
|
|
260
|
-
# Now we can assembly the video and clean the folder of png's (optional)
|
|
261
|
-
imageio.mimsave(Giff_NAME, images, duration=0.05)
|
|
262
|
-
import shutil # nice and powerfull tool to delete a folder and its content
|
|
263
|
-
|
|
264
|
-
shutil.rmtree(Fol_Out)
|
|
265
|
-
return 'Gif Created'
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
def Plot_Field_TEXT_Cylinder(File,Name_Mesh,Name_FIG):
|
|
270
|
-
"""
|
|
271
|
-
This function plots the vector field from the TR-PIV in Exercise 4.
|
|
272
|
-
|
|
273
|
-
:param File: Name of the file to load
|
|
274
|
-
|
|
275
|
-
"""
|
|
276
|
-
# We first perform a zero padding
|
|
277
|
-
Name=File
|
|
278
|
-
# Read data from a file
|
|
279
|
-
DATA = np.genfromtxt(Name) # Here we have the four colums
|
|
280
|
-
Dat=DATA[1:,:] # Here we remove the first raw, containing the header
|
|
281
|
-
nxny=Dat.shape[0] # is the to be doubled at the end we will have n_s=2 * n_x * n_y
|
|
282
|
-
n_s=2*nxny
|
|
283
|
-
## 1. Reconstruct Mesh from file Name_Mesh
|
|
284
|
-
DATA_mesh=np.genfromtxt(Name_Mesh);
|
|
285
|
-
Dat_mesh=DATA_mesh[1:,:]
|
|
286
|
-
X_S=Dat_mesh[:,0];
|
|
287
|
-
Y_S=Dat_mesh[:,1];
|
|
288
|
-
# Reshape also the velocity components
|
|
289
|
-
V_X=Dat[:,0] # U component
|
|
290
|
-
V_Y=Dat[:,1] # V component
|
|
291
|
-
# Put both components as fields in the grid
|
|
292
|
-
Xg,Yg,Vxg,Vyg,Magn=Plot_Field_Cylinder(X_S,Y_S,V_X,V_Y,False,2,0.6)
|
|
293
|
-
# Show this particular step
|
|
294
|
-
fig, ax = plt.subplots(figsize=(5, 3)) # This creates the figure
|
|
295
|
-
# Or you can plot it as streamlines
|
|
296
|
-
CL=plt.contourf(Xg,Yg,Magn,levels=np.arange(0,18,2))
|
|
297
|
-
# One possibility is to use quiver
|
|
298
|
-
STEPx=1; STEPy=1
|
|
299
|
-
plt.quiver(Xg[::STEPx,::STEPy],Yg[::STEPx,::STEPy],\
|
|
300
|
-
Vxg[::STEPx,::STEPy],Vyg[::STEPx,::STEPy],color='k')
|
|
301
|
-
plt.rc('text', usetex=True)
|
|
302
|
-
plt.rc('font', family='serif')
|
|
303
|
-
plt.rc('xtick',labelsize=12)
|
|
304
|
-
plt.rc('ytick',labelsize=12)
|
|
305
|
-
fig.colorbar(CL,pad=0.05,fraction=0.025)
|
|
306
|
-
ax.set_aspect('equal') # Set equal aspect ratio
|
|
307
|
-
ax.set_xlabel('$x[mm]$',fontsize=13)
|
|
308
|
-
ax.set_ylabel('$y[mm]$',fontsize=13)
|
|
309
|
-
#ax.set_title('Tutorial 2: Cylinder Wake',fontsize=12)
|
|
310
|
-
ax.set_xticks(np.arange(0,70,10))
|
|
311
|
-
ax.set_yticks(np.arange(-10,11,10))
|
|
312
|
-
ax.set_xlim([0,50])
|
|
313
|
-
ax.set_ylim(-10,10)
|
|
314
|
-
circle = plt.Circle((0,0),2.5,fill=True,color='r',edgecolor='k',alpha=0.5)
|
|
315
|
-
plt.gcf().gca().add_artist(circle)
|
|
316
|
-
plt.tight_layout()
|
|
317
|
-
plt.savefig(Name_FIG, dpi=200)
|
|
318
|
-
plt.show()
|
|
319
|
-
print(Name_FIG+' printed')
|
|
320
|
-
return n_s, Xg, Yg, Vxg, Vyg, X_S, Y_S
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
def Plot_Field_Cylinder(X_S,Y_S,V_X,V_Y,PLOT,Step,Scale):
|
|
324
|
-
# Number of n_X/n_Y from forward differences
|
|
325
|
-
GRAD_X=np.diff(Y_S)
|
|
326
|
-
#GRAD_Y=np.diff(Y_S);
|
|
327
|
-
# Depending on the reshaping performed, one of the two will start with
|
|
328
|
-
# non-zero gradient. The other will have zero gradient only on the change.
|
|
329
|
-
IND_X=np.where(GRAD_X!=0); DAT=IND_X[0]; n_y=DAT[0]+1;
|
|
330
|
-
nxny=X_S.shape[0] # is the to be doubled at the end we will have n_s=2 * n_x * n_y
|
|
331
|
-
#n_s=2*nxny
|
|
332
|
-
# Reshaping the grid from the data
|
|
333
|
-
n_x=(nxny//(n_y)) # Carefull with integer and float!
|
|
334
|
-
Xg=np.transpose(X_S.reshape((n_x,n_y)))
|
|
335
|
-
Yg=np.transpose(Y_S.reshape((n_x,n_y))) # This is now the mesh! 60x114.
|
|
336
|
-
Mod=np.sqrt(V_X**2+V_Y**2)
|
|
337
|
-
Vxg=np.transpose(V_X.reshape((n_x,n_y)))
|
|
338
|
-
Vyg=np.transpose(V_Y.reshape((n_x,n_y)))
|
|
339
|
-
Magn=np.transpose(Mod.reshape((n_x,n_y)))
|
|
340
|
-
|
|
341
|
-
if PLOT:
|
|
342
|
-
# One possibility is to use quiver
|
|
343
|
-
STEPx=Step; STEPy=Step
|
|
344
|
-
fig, ax = plt.subplots(figsize=(5, 3)) # This creates the figure
|
|
345
|
-
# Or you can plot it as streamlines
|
|
346
|
-
CL=plt.contourf(Xg,Yg,Magn,levels=np.arange(0,18,2))
|
|
347
|
-
# One possibility is to use quiver
|
|
348
|
-
STEPx=1; STEPy=1
|
|
349
|
-
plt.quiver(Xg[::STEPx,::STEPy],Yg[::STEPx,::STEPy],\
|
|
350
|
-
Vxg[::STEPx,::STEPy],Vyg[::STEPx,::STEPy],color='k')
|
|
351
|
-
plt.rc('text', usetex=True)
|
|
352
|
-
plt.rc('font', family='serif')
|
|
353
|
-
plt.rc('xtick',labelsize=12)
|
|
354
|
-
plt.rc('ytick',labelsize=12)
|
|
355
|
-
fig.colorbar(CL,pad=0.05,fraction=0.025)
|
|
356
|
-
ax.set_aspect('equal') # Set equal aspect ratio
|
|
357
|
-
ax.set_xlabel('$x[mm]$',fontsize=13)
|
|
358
|
-
ax.set_ylabel('$y[mm]$',fontsize=13)
|
|
359
|
-
#ax.set_title('Tutorial 2: Cylinder Wake',fontsize=12)
|
|
360
|
-
ax.set_xticks(np.arange(0,70,10))
|
|
361
|
-
ax.set_yticks(np.arange(-10,11,10))
|
|
362
|
-
ax.set_xlim([0,50])
|
|
363
|
-
ax.set_ylim(-10,10)
|
|
364
|
-
circle = plt.Circle((0,0),2.5,fill=True,color='r',edgecolor='k',alpha=0.5)
|
|
365
|
-
plt.gcf().gca().add_artist(circle)
|
|
366
|
-
plt.tight_layout()
|
|
367
|
-
plt.show()
|
|
368
|
-
|
|
369
|
-
return Xg,Yg,Vxg,Vyg,Magn
|
|
370
|
-
|
|
371
|
-
def Plot_Scalar_Field_Cylinder(X_S,Y_S,V_X,V_Y,Scalar,PLOT,Step,Scale):
|
|
372
|
-
# Number of n_X/n_Y from forward differences
|
|
373
|
-
GRAD_X=np.diff(Y_S)
|
|
374
|
-
#GRAD_Y=np.diff(Y_S);
|
|
375
|
-
# Depending on the reshaping performed, one of the two will start with
|
|
376
|
-
# non-zero gradient. The other will have zero gradient only on the change.
|
|
377
|
-
IND_X=np.where(GRAD_X!=0); DAT=IND_X[0]; n_y=DAT[0]+1;
|
|
378
|
-
nxny=X_S.shape[0] # is the to be doubled at the end we will have n_s=2 * n_x * n_y
|
|
379
|
-
#n_s=2*nxny
|
|
380
|
-
# Reshaping the grid from the data
|
|
381
|
-
n_x=(nxny//(n_y)) # Carefull with integer and float!
|
|
382
|
-
Xg=np.transpose(X_S.reshape((n_x,n_y)))
|
|
383
|
-
Yg=np.transpose(Y_S.reshape((n_x,n_y))) # This is now the mesh! 60x114.
|
|
384
|
-
Vxg=np.transpose(V_X.reshape((n_x,n_y)))
|
|
385
|
-
Vyg=np.transpose(V_Y.reshape((n_x,n_y)))
|
|
386
|
-
Magn=np.transpose(Scalar.reshape((n_x,n_y)))
|
|
387
|
-
|
|
388
|
-
if PLOT:
|
|
389
|
-
# One possibility is to use quiver
|
|
390
|
-
STEPx=Step; STEPy=Step
|
|
391
|
-
fig, ax = plt.subplots(figsize=(5, 3)) # This creates the figure
|
|
392
|
-
# Or you can plot it as streamlines
|
|
393
|
-
CL=plt.contourf(Xg,Yg,Magn*100,levels=np.arange(0,70,10))
|
|
394
|
-
# One possibility is to use quiver
|
|
395
|
-
STEPx=1; STEPy=1
|
|
396
|
-
plt.quiver(Xg[::STEPx,::STEPy],Yg[::STEPx,::STEPy],\
|
|
397
|
-
Vxg[::STEPx,::STEPy],Vyg[::STEPx,::STEPy],color='k')
|
|
398
|
-
plt.rc('text', usetex=True)
|
|
399
|
-
plt.rc('font', family='serif')
|
|
400
|
-
plt.rc('xtick',labelsize=12)
|
|
401
|
-
plt.rc('ytick',labelsize=12)
|
|
402
|
-
fig.colorbar(CL,pad=0.05,fraction=0.025)
|
|
403
|
-
ax.set_aspect('equal') # Set equal aspect ratio
|
|
404
|
-
ax.set_xlabel('$x[mm]$',fontsize=13)
|
|
405
|
-
ax.set_ylabel('$y[mm]$',fontsize=13)
|
|
406
|
-
#ax.set_title('Tutorial 2: Cylinder Wake',fontsize=12)
|
|
407
|
-
ax.set_xticks(np.arange(0,70,10))
|
|
408
|
-
ax.set_yticks(np.arange(-10,11,10))
|
|
409
|
-
ax.set_xlim([0,50])
|
|
410
|
-
ax.set_ylim(-10,10)
|
|
411
|
-
circle = plt.Circle((0,0),2.5,fill=True,color='r',edgecolor='k',alpha=0.5)
|
|
412
|
-
plt.gcf().gca().add_artist(circle)
|
|
413
|
-
plt.tight_layout()
|
|
414
|
-
plt.show()
|
|
415
|
-
|
|
416
|
-
return Xg,Yg,Vxg,Vyg,Magn
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
def plot_grid_cylinder_flow(Xg,Yg,Vxg,Vyg):
|
|
421
|
-
STEPx=1; STEPy=1
|
|
422
|
-
# This creates the figure
|
|
423
|
-
fig, ax = plt.subplots(figsize=(6, 3))
|
|
424
|
-
Magn=np.sqrt(Vxg**2+Vyg**2)
|
|
425
|
-
# Plot Contour
|
|
426
|
-
#CL=plt.contourf(Xg,Yg,Magn,levels=np.linspace(0,np.max(Magn),5))
|
|
427
|
-
CL=plt.contourf(Xg,Yg,Magn,20,cmap='viridis',alpha=0.95)
|
|
428
|
-
# One possibility is to use quiver
|
|
429
|
-
STEPx=1; STEPy=1
|
|
430
|
-
plt.quiver(Xg[::STEPx,::STEPy],Yg[::STEPx,::STEPy],\
|
|
431
|
-
Vxg[::STEPx,::STEPy],Vyg[::STEPx,::STEPy],color='k')
|
|
432
|
-
plt.rc('text', usetex=True)
|
|
433
|
-
plt.rc('font', family='serif')
|
|
434
|
-
plt.rc('xtick',labelsize=12)
|
|
435
|
-
plt.rc('ytick',labelsize=12)
|
|
436
|
-
#fig.colorbar(CL,pad=0.05,fraction=0.025)
|
|
437
|
-
ax.set_aspect('equal') # Set equal aspect ratio
|
|
438
|
-
ax.set_xlabel('$x[mm]$',fontsize=13)
|
|
439
|
-
ax.set_ylabel('$y[mm]$',fontsize=13)
|
|
440
|
-
#ax.set_title('Tutorial 2: Cylinder Wake',fontsize=12)
|
|
441
|
-
ax.set_xticks(np.arange(0,70,10))
|
|
442
|
-
ax.set_yticks(np.arange(-10,11,10))
|
|
443
|
-
ax.set_xlim([0,50])
|
|
444
|
-
ax.set_ylim(-10,10)
|
|
445
|
-
circle = plt.Circle((0,0),2.5,fill=True,color='r',edgecolor='k',alpha=0.5)
|
|
446
|
-
plt.gcf().gca().add_artist(circle)
|
|
447
|
-
plt.tight_layout()
|
|
448
|
-
|
|
449
|
-
return fig, ax
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""
|
|
3
|
+
Created on Mon Dec 30 20:33:42 2019
|
|
4
|
+
@author: mendez
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
import matplotlib.pyplot as plt
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def Plot_Field_TEXT_JET(File):
|
|
12
|
+
"""
|
|
13
|
+
This function plots the vector field from the TR-PIV in Exercise 4.
|
|
14
|
+
|
|
15
|
+
:param File: Name of the file to load
|
|
16
|
+
|
|
17
|
+
"""
|
|
18
|
+
# We first perform a zero padding
|
|
19
|
+
Name = File
|
|
20
|
+
# Read data from a file
|
|
21
|
+
DATA = np.genfromtxt(Name) # Here we have the four colums
|
|
22
|
+
Dat = DATA[1:, :] # Here we remove the first raw, containing the header
|
|
23
|
+
nxny = Dat.shape[0] # is the to be doubled at the end we will have n_s=2 * n_x * n_y
|
|
24
|
+
n_s = 2 * nxny
|
|
25
|
+
## 1. Reconstruct Mesh from file
|
|
26
|
+
X_S = Dat[:, 0]
|
|
27
|
+
Y_S = Dat[:, 1]
|
|
28
|
+
# Reshape also the velocity components
|
|
29
|
+
V_X = Dat[:, 2] # U component
|
|
30
|
+
V_Y = Dat[:, 3] # V component
|
|
31
|
+
# Put both components as fields in the grid
|
|
32
|
+
Xg, Yg, Vxg, Vyg, Magn = Plot_Field_JET(X_S, Y_S, V_X, V_Y, False, 2, 0.6)
|
|
33
|
+
# Show this particular step
|
|
34
|
+
fig, ax = plt.subplots(figsize=(8, 5)) # This creates the figure
|
|
35
|
+
# Or you can plot it as streamlines
|
|
36
|
+
plt.contourf(Xg, Yg, Magn)
|
|
37
|
+
# One possibility is to use quiver
|
|
38
|
+
STEPx = 2
|
|
39
|
+
STEPy = 2
|
|
40
|
+
plt.quiver(Xg[::STEPx, ::STEPy], Yg[::STEPx, ::STEPy], \
|
|
41
|
+
Vxg[::STEPx, ::STEPy], -Vyg[::STEPx, ::STEPy], color='k') # Create a quiver (arrows) plot
|
|
42
|
+
|
|
43
|
+
plt.rc('text', usetex=True) # This is Miguel's customization
|
|
44
|
+
plt.rc('font', family='serif')
|
|
45
|
+
plt.rc('xtick', labelsize=16)
|
|
46
|
+
plt.rc('ytick', labelsize=16)
|
|
47
|
+
ax.set_aspect('equal') # Set equal aspect ratio
|
|
48
|
+
ax.set_xlabel('$x[mm]$', fontsize=16)
|
|
49
|
+
ax.set_ylabel('$y[mm]$', fontsize=16)
|
|
50
|
+
ax.set_title('Velocity Field via TR-PIV', fontsize=18)
|
|
51
|
+
ax.set_xticks(np.arange(0, 40, 10))
|
|
52
|
+
ax.set_yticks(np.arange(10, 30, 5))
|
|
53
|
+
ax.set_xlim([0, 35])
|
|
54
|
+
ax.set_ylim(10, 29)
|
|
55
|
+
ax.invert_yaxis() # Invert Axis for plotting purpose
|
|
56
|
+
plt.show()
|
|
57
|
+
Name[len(Name) - 12:len(Name)] + ' Plotted'
|
|
58
|
+
return n_s, Xg, Yg, Vxg, -Vyg, X_S, Y_S
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def Plot_Field_JET(X_S, Y_S, V_X, V_Y, PLOT, Step, Scale):
|
|
62
|
+
# Number of n_X/n_Y from forward differences
|
|
63
|
+
GRAD_X = np.diff(X_S)
|
|
64
|
+
# GRAD_Y=np.diff(Y_S);
|
|
65
|
+
# Depending on the reshaping performed, one of the two will start with
|
|
66
|
+
# non-zero gradient. The other will have zero gradient only on the change.
|
|
67
|
+
IND_X = np.where(GRAD_X != 0);
|
|
68
|
+
DAT = IND_X[0];
|
|
69
|
+
n_y = DAT[0] + 1;
|
|
70
|
+
nxny = X_S.shape[0] # is the to be doubled at the end we will have n_s=2 * n_x * n_y
|
|
71
|
+
# n_s=2*nxny
|
|
72
|
+
# Reshaping the grid from the data
|
|
73
|
+
n_x = (nxny // (n_y)) # Carefull with integer and float!
|
|
74
|
+
Xg = np.transpose(X_S.reshape((n_x, n_y)))
|
|
75
|
+
Yg = np.transpose(Y_S.reshape((n_x, n_y))) # This is now the mesh! 60x114.
|
|
76
|
+
Mod = np.sqrt(V_X ** 2 + V_Y ** 2)
|
|
77
|
+
Vxg = np.transpose(V_X.reshape((n_x, n_y)))
|
|
78
|
+
Vyg = np.transpose(V_Y.reshape((n_x, n_y)))
|
|
79
|
+
Magn = np.transpose(Mod.reshape((n_x, n_y)))
|
|
80
|
+
if PLOT:
|
|
81
|
+
# Show this particular step
|
|
82
|
+
# fig, ax = plt.subplots(figsize=(8, 5)) # This creates the figure
|
|
83
|
+
# Or you can plot it as streamlines
|
|
84
|
+
#fig, ax = plt.subplots(figsize=(8, 5)) # This creates the figure
|
|
85
|
+
#ax.contourf(Xg, Yg, Magn)
|
|
86
|
+
plt.contourf(Xg,Yg,Magn)
|
|
87
|
+
# One possibility is to use quiver
|
|
88
|
+
STEPx = Step
|
|
89
|
+
STEPy = Step
|
|
90
|
+
|
|
91
|
+
plt.quiver(Xg[::STEPx, ::STEPy], Yg[::STEPx, ::STEPy], \
|
|
92
|
+
Vxg[::STEPx, ::STEPy], -Vyg[::STEPx, ::STEPy], color='k',
|
|
93
|
+
scale=Scale) # Create a quiver (arrows) plot
|
|
94
|
+
|
|
95
|
+
plt.rc('text', usetex=True) # This is Miguel's customization
|
|
96
|
+
plt.rc('font', family='serif')
|
|
97
|
+
plt.rc('xtick', labelsize=16)
|
|
98
|
+
plt.rc('ytick', labelsize=16)
|
|
99
|
+
# ax.set_aspect('equal') # Set equal aspect ratio
|
|
100
|
+
# ax.set_xlabel('$x[mm]$',fontsize=16)
|
|
101
|
+
# ax.set_ylabel('$y[mm]$',fontsize=16)
|
|
102
|
+
# ax.set_title('Velocity Field via TR-PIV',fontsize=18)
|
|
103
|
+
# ax.set_xticks(np.arange(0,40,10))
|
|
104
|
+
# ax.set_yticks(np.arange(10,30,5))
|
|
105
|
+
# ax.set_xlim([0,35])
|
|
106
|
+
# ax.set_ylim(10,29)
|
|
107
|
+
# ax.invert_yaxis() # Invert Axis for plotting purpose
|
|
108
|
+
# plt.show()
|
|
109
|
+
|
|
110
|
+
return Xg, Yg, Vxg, Vyg, Magn
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
# Define the function to produce a gif file
|
|
114
|
+
def Animation_JET(Giff_NAME,D,X_S,Y_S,In,Fin,Step):
|
|
115
|
+
"""
|
|
116
|
+
The gif file is created from the provided data snapshot
|
|
117
|
+
"""
|
|
118
|
+
n_t=Fin-In
|
|
119
|
+
GRAD_X = np.diff(X_S)
|
|
120
|
+
IND_X = np.where(GRAD_X != 0);
|
|
121
|
+
DAT = IND_X[0];
|
|
122
|
+
n_y = DAT[0] + 1;
|
|
123
|
+
nxny = X_S.shape[0] # is the to be doubled at the end we will have n_s=2 * n_x * n_y
|
|
124
|
+
# n_s=2*nxny
|
|
125
|
+
# Reshaping the grid from the data
|
|
126
|
+
n_x = (nxny // (n_y)) # Carefull with integer and float!
|
|
127
|
+
Xg = np.transpose(X_S.reshape((n_x, n_y)))
|
|
128
|
+
Yg = np.transpose(Y_S.reshape((n_x, n_y))) # This is now the mesh! 60x114. n_y, n_x = Yg.shape;
|
|
129
|
+
nxny = n_x * n_y
|
|
130
|
+
import os
|
|
131
|
+
# Create a temporary file to store the images in the GIF
|
|
132
|
+
Fol_Out = 'Gif_Images_temporary'
|
|
133
|
+
if not os.path.exists(Fol_Out):
|
|
134
|
+
os.mkdir(Fol_Out)
|
|
135
|
+
|
|
136
|
+
# Prepare Animation of the analytical solution
|
|
137
|
+
for k in range(1,n_t,Step):
|
|
138
|
+
Dat = D[:, k+In]
|
|
139
|
+
V_X_m = Dat[0:nxny]
|
|
140
|
+
V_Y_m = Dat[nxny::]
|
|
141
|
+
# Put both components as fields in the grid
|
|
142
|
+
Mod = np.sqrt(V_X_m ** 2 + V_Y_m ** 2)
|
|
143
|
+
Vxg = np.transpose(V_X_m.reshape((n_x, n_y)))
|
|
144
|
+
Vyg = np.transpose(V_Y_m.reshape((n_x, n_y)))
|
|
145
|
+
Magn = np.transpose(Mod.reshape((n_x, n_y)))
|
|
146
|
+
fig, ax = plt.subplots(figsize=(8, 5)) # This creates the figure
|
|
147
|
+
# Or you can plot it as streamlines
|
|
148
|
+
plt.contourf(Xg, Yg, Magn)
|
|
149
|
+
# One possibility is to use quiver
|
|
150
|
+
STEPx = 2
|
|
151
|
+
STEPy = 2
|
|
152
|
+
plt.quiver(Xg[::STEPx, ::STEPy], Yg[::STEPx, ::STEPy], \
|
|
153
|
+
Vxg[::STEPx, ::STEPy], -Vyg[::STEPx, ::STEPy], color='k') # Create a quiver (arrows) plot
|
|
154
|
+
|
|
155
|
+
plt.rc('text', usetex=True) # This is Miguel's customization
|
|
156
|
+
plt.rc('font', family='serif')
|
|
157
|
+
plt.rc('xtick', labelsize=16)
|
|
158
|
+
plt.rc('ytick', labelsize=16)
|
|
159
|
+
ax.set_aspect('equal') # Set equal aspect ratio
|
|
160
|
+
ax.set_xlabel('$x[mm]$', fontsize=16)
|
|
161
|
+
ax.set_ylabel('$y[mm]$', fontsize=16)
|
|
162
|
+
#ax.set_title('Velocity Field via TR-PIV', fontsize=18)
|
|
163
|
+
ax.set_xticks(np.arange(0, 40, 10))
|
|
164
|
+
ax.set_yticks(np.arange(10, 30, 5))
|
|
165
|
+
ax.set_xlim([0, 35])
|
|
166
|
+
ax.set_ylim(10, 29)
|
|
167
|
+
plt.clim(0, 6)
|
|
168
|
+
ax.invert_yaxis() # Invert Axis for plotting purpose
|
|
169
|
+
#plt.show()
|
|
170
|
+
|
|
171
|
+
NameOUT = Fol_Out + os.sep + 'Im%03d' % (k) + '.png'
|
|
172
|
+
plt.savefig(NameOUT, dpi=100)
|
|
173
|
+
plt.close(fig)
|
|
174
|
+
print('Image n ' + str(k) + ' of ' + str(n_t))
|
|
175
|
+
|
|
176
|
+
# Assembly the GIF
|
|
177
|
+
import imageio # This used for the animation
|
|
178
|
+
|
|
179
|
+
images = []
|
|
180
|
+
|
|
181
|
+
for k in range(1,n_t,Step):
|
|
182
|
+
MEX = 'Preparing Im ' + str(k)
|
|
183
|
+
print(MEX)
|
|
184
|
+
NameOUT = Fol_Out + os.sep + 'Im%03d' % (k) + '.png'
|
|
185
|
+
images.append(imageio.imread(NameOUT))
|
|
186
|
+
|
|
187
|
+
# Now we can assembly the video and clean the folder of png's (optional)
|
|
188
|
+
imageio.mimsave(Giff_NAME, images, duration=0.05)
|
|
189
|
+
import shutil # nice and powerfull tool to delete a folder and its content
|
|
190
|
+
|
|
191
|
+
shutil.rmtree(Fol_Out)
|
|
192
|
+
return 'Gif Created'
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
def Plot_2D_CFD_Cyl(Xg,Yg,U,V,k=10,CL=16,Name='', verbose=False):
|
|
198
|
+
# Make a 2D plot of the 2D cylinder test case in Openfoam.
|
|
199
|
+
n_x,n_y=np.shape(Xg)
|
|
200
|
+
U_g=U[:,k].reshape(n_y,n_x).T
|
|
201
|
+
V_g=V[:,k].reshape(n_y,n_x).T
|
|
202
|
+
# Prepare the plot
|
|
203
|
+
fig, ax = plt.subplots(figsize=(6, 3)) # This creates the figure
|
|
204
|
+
plt.contourf(Xg,Yg,np.sqrt(U_g**2+V_g**2),30)
|
|
205
|
+
# plt.quiver(Xg,Yg,U_g,V_g,scale=10000)
|
|
206
|
+
ax.set_aspect('equal') # Set equal aspect ratio
|
|
207
|
+
ax.set_xlabel('$x[mm]$',fontsize=13)
|
|
208
|
+
ax.set_ylabel('$y[mm]$',fontsize=13)
|
|
209
|
+
#ax.set_title('Tutorial 2: Cylinder Wake',fontsize=12)
|
|
210
|
+
ax.set_xticks(np.arange(-0.1,0.2,0.05))
|
|
211
|
+
ax.set_yticks(np.arange(-0.1,0.1,0.05))
|
|
212
|
+
ax.set_xlim([-0.05,0.2])
|
|
213
|
+
ax.set_ylim(-0.05,0.05)
|
|
214
|
+
|
|
215
|
+
if CL !=0:
|
|
216
|
+
plt.clim(0, CL)
|
|
217
|
+
|
|
218
|
+
circle = plt.Circle((0,0),0.0075,fill=True,color='r',edgecolor='k',alpha=0.5)
|
|
219
|
+
plt.gcf().gca().add_artist(circle)
|
|
220
|
+
plt.tight_layout()
|
|
221
|
+
|
|
222
|
+
if len(Name) !=0:
|
|
223
|
+
plt.savefig(Name, dpi=200)
|
|
224
|
+
plt.close(fig)
|
|
225
|
+
|
|
226
|
+
if verbose:
|
|
227
|
+
print('Image exported')
|
|
228
|
+
|
|
229
|
+
return
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def Animation_2D_CFD_Cyl(Giff_NAME,D,Xg,Yg,In,Fin,Step):
|
|
233
|
+
"""
|
|
234
|
+
The gif file is created from the provided data snapshot
|
|
235
|
+
"""
|
|
236
|
+
n_t=Fin-In
|
|
237
|
+
n_x,n_y=np.shape(Xg); nxny=n_x*n_y
|
|
238
|
+
U = D[0:nxny,:]
|
|
239
|
+
V = D[nxny::,]
|
|
240
|
+
|
|
241
|
+
import os
|
|
242
|
+
# Create a temporary file to store the images in the GIF
|
|
243
|
+
Fol_Out = 'Gif_Images_temporary'
|
|
244
|
+
if not os.path.exists(Fol_Out):
|
|
245
|
+
os.mkdir(Fol_Out)
|
|
246
|
+
# Loop to produce the Gifs
|
|
247
|
+
for k in range(1,n_t,Step):
|
|
248
|
+
NameOUT = Fol_Out + os.sep + 'Im%03d' % (k) + '.png'
|
|
249
|
+
Plot_2D_CFD_Cyl(Xg,Yg,U,V,k=k+In,CL=16,Name=NameOUT)
|
|
250
|
+
|
|
251
|
+
import imageio # This used for the animation
|
|
252
|
+
images = []
|
|
253
|
+
|
|
254
|
+
for k in range(1,n_t,Step):
|
|
255
|
+
MEX = 'Preparing Im ' + str(k)
|
|
256
|
+
print(MEX)
|
|
257
|
+
NameOUT = Fol_Out + os.sep + 'Im%03d' % (k) + '.png'
|
|
258
|
+
images.append(imageio.imread(NameOUT))
|
|
259
|
+
|
|
260
|
+
# Now we can assembly the video and clean the folder of png's (optional)
|
|
261
|
+
imageio.mimsave(Giff_NAME, images, duration=0.05)
|
|
262
|
+
import shutil # nice and powerfull tool to delete a folder and its content
|
|
263
|
+
|
|
264
|
+
shutil.rmtree(Fol_Out)
|
|
265
|
+
return 'Gif Created'
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
|
|
269
|
+
def Plot_Field_TEXT_Cylinder(File,Name_Mesh,Name_FIG):
|
|
270
|
+
"""
|
|
271
|
+
This function plots the vector field from the TR-PIV in Exercise 4.
|
|
272
|
+
|
|
273
|
+
:param File: Name of the file to load
|
|
274
|
+
|
|
275
|
+
"""
|
|
276
|
+
# We first perform a zero padding
|
|
277
|
+
Name=File
|
|
278
|
+
# Read data from a file
|
|
279
|
+
DATA = np.genfromtxt(Name) # Here we have the four colums
|
|
280
|
+
Dat=DATA[1:,:] # Here we remove the first raw, containing the header
|
|
281
|
+
nxny=Dat.shape[0] # is the to be doubled at the end we will have n_s=2 * n_x * n_y
|
|
282
|
+
n_s=2*nxny
|
|
283
|
+
## 1. Reconstruct Mesh from file Name_Mesh
|
|
284
|
+
DATA_mesh=np.genfromtxt(Name_Mesh);
|
|
285
|
+
Dat_mesh=DATA_mesh[1:,:]
|
|
286
|
+
X_S=Dat_mesh[:,0];
|
|
287
|
+
Y_S=Dat_mesh[:,1];
|
|
288
|
+
# Reshape also the velocity components
|
|
289
|
+
V_X=Dat[:,0] # U component
|
|
290
|
+
V_Y=Dat[:,1] # V component
|
|
291
|
+
# Put both components as fields in the grid
|
|
292
|
+
Xg,Yg,Vxg,Vyg,Magn=Plot_Field_Cylinder(X_S,Y_S,V_X,V_Y,False,2,0.6)
|
|
293
|
+
# Show this particular step
|
|
294
|
+
fig, ax = plt.subplots(figsize=(5, 3)) # This creates the figure
|
|
295
|
+
# Or you can plot it as streamlines
|
|
296
|
+
CL=plt.contourf(Xg,Yg,Magn,levels=np.arange(0,18,2))
|
|
297
|
+
# One possibility is to use quiver
|
|
298
|
+
STEPx=1; STEPy=1
|
|
299
|
+
plt.quiver(Xg[::STEPx,::STEPy],Yg[::STEPx,::STEPy],\
|
|
300
|
+
Vxg[::STEPx,::STEPy],Vyg[::STEPx,::STEPy],color='k')
|
|
301
|
+
plt.rc('text', usetex=True)
|
|
302
|
+
plt.rc('font', family='serif')
|
|
303
|
+
plt.rc('xtick',labelsize=12)
|
|
304
|
+
plt.rc('ytick',labelsize=12)
|
|
305
|
+
fig.colorbar(CL,pad=0.05,fraction=0.025)
|
|
306
|
+
ax.set_aspect('equal') # Set equal aspect ratio
|
|
307
|
+
ax.set_xlabel('$x[mm]$',fontsize=13)
|
|
308
|
+
ax.set_ylabel('$y[mm]$',fontsize=13)
|
|
309
|
+
#ax.set_title('Tutorial 2: Cylinder Wake',fontsize=12)
|
|
310
|
+
ax.set_xticks(np.arange(0,70,10))
|
|
311
|
+
ax.set_yticks(np.arange(-10,11,10))
|
|
312
|
+
ax.set_xlim([0,50])
|
|
313
|
+
ax.set_ylim(-10,10)
|
|
314
|
+
circle = plt.Circle((0,0),2.5,fill=True,color='r',edgecolor='k',alpha=0.5)
|
|
315
|
+
plt.gcf().gca().add_artist(circle)
|
|
316
|
+
plt.tight_layout()
|
|
317
|
+
plt.savefig(Name_FIG, dpi=200)
|
|
318
|
+
plt.show()
|
|
319
|
+
print(Name_FIG+' printed')
|
|
320
|
+
return n_s, Xg, Yg, Vxg, Vyg, X_S, Y_S
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
def Plot_Field_Cylinder(X_S,Y_S,V_X,V_Y,PLOT,Step,Scale):
|
|
324
|
+
# Number of n_X/n_Y from forward differences
|
|
325
|
+
GRAD_X=np.diff(Y_S)
|
|
326
|
+
#GRAD_Y=np.diff(Y_S);
|
|
327
|
+
# Depending on the reshaping performed, one of the two will start with
|
|
328
|
+
# non-zero gradient. The other will have zero gradient only on the change.
|
|
329
|
+
IND_X=np.where(GRAD_X!=0); DAT=IND_X[0]; n_y=DAT[0]+1;
|
|
330
|
+
nxny=X_S.shape[0] # is the to be doubled at the end we will have n_s=2 * n_x * n_y
|
|
331
|
+
#n_s=2*nxny
|
|
332
|
+
# Reshaping the grid from the data
|
|
333
|
+
n_x=(nxny//(n_y)) # Carefull with integer and float!
|
|
334
|
+
Xg=np.transpose(X_S.reshape((n_x,n_y)))
|
|
335
|
+
Yg=np.transpose(Y_S.reshape((n_x,n_y))) # This is now the mesh! 60x114.
|
|
336
|
+
Mod=np.sqrt(V_X**2+V_Y**2)
|
|
337
|
+
Vxg=np.transpose(V_X.reshape((n_x,n_y)))
|
|
338
|
+
Vyg=np.transpose(V_Y.reshape((n_x,n_y)))
|
|
339
|
+
Magn=np.transpose(Mod.reshape((n_x,n_y)))
|
|
340
|
+
|
|
341
|
+
if PLOT:
|
|
342
|
+
# One possibility is to use quiver
|
|
343
|
+
STEPx=Step; STEPy=Step
|
|
344
|
+
fig, ax = plt.subplots(figsize=(5, 3)) # This creates the figure
|
|
345
|
+
# Or you can plot it as streamlines
|
|
346
|
+
CL=plt.contourf(Xg,Yg,Magn,levels=np.arange(0,18,2))
|
|
347
|
+
# One possibility is to use quiver
|
|
348
|
+
STEPx=1; STEPy=1
|
|
349
|
+
plt.quiver(Xg[::STEPx,::STEPy],Yg[::STEPx,::STEPy],\
|
|
350
|
+
Vxg[::STEPx,::STEPy],Vyg[::STEPx,::STEPy],color='k')
|
|
351
|
+
plt.rc('text', usetex=True)
|
|
352
|
+
plt.rc('font', family='serif')
|
|
353
|
+
plt.rc('xtick',labelsize=12)
|
|
354
|
+
plt.rc('ytick',labelsize=12)
|
|
355
|
+
fig.colorbar(CL,pad=0.05,fraction=0.025)
|
|
356
|
+
ax.set_aspect('equal') # Set equal aspect ratio
|
|
357
|
+
ax.set_xlabel('$x[mm]$',fontsize=13)
|
|
358
|
+
ax.set_ylabel('$y[mm]$',fontsize=13)
|
|
359
|
+
#ax.set_title('Tutorial 2: Cylinder Wake',fontsize=12)
|
|
360
|
+
ax.set_xticks(np.arange(0,70,10))
|
|
361
|
+
ax.set_yticks(np.arange(-10,11,10))
|
|
362
|
+
ax.set_xlim([0,50])
|
|
363
|
+
ax.set_ylim(-10,10)
|
|
364
|
+
circle = plt.Circle((0,0),2.5,fill=True,color='r',edgecolor='k',alpha=0.5)
|
|
365
|
+
plt.gcf().gca().add_artist(circle)
|
|
366
|
+
plt.tight_layout()
|
|
367
|
+
plt.show()
|
|
368
|
+
|
|
369
|
+
return Xg,Yg,Vxg,Vyg,Magn
|
|
370
|
+
|
|
371
|
+
def Plot_Scalar_Field_Cylinder(X_S,Y_S,V_X,V_Y,Scalar,PLOT,Step,Scale):
|
|
372
|
+
# Number of n_X/n_Y from forward differences
|
|
373
|
+
GRAD_X=np.diff(Y_S)
|
|
374
|
+
#GRAD_Y=np.diff(Y_S);
|
|
375
|
+
# Depending on the reshaping performed, one of the two will start with
|
|
376
|
+
# non-zero gradient. The other will have zero gradient only on the change.
|
|
377
|
+
IND_X=np.where(GRAD_X!=0); DAT=IND_X[0]; n_y=DAT[0]+1;
|
|
378
|
+
nxny=X_S.shape[0] # is the to be doubled at the end we will have n_s=2 * n_x * n_y
|
|
379
|
+
#n_s=2*nxny
|
|
380
|
+
# Reshaping the grid from the data
|
|
381
|
+
n_x=(nxny//(n_y)) # Carefull with integer and float!
|
|
382
|
+
Xg=np.transpose(X_S.reshape((n_x,n_y)))
|
|
383
|
+
Yg=np.transpose(Y_S.reshape((n_x,n_y))) # This is now the mesh! 60x114.
|
|
384
|
+
Vxg=np.transpose(V_X.reshape((n_x,n_y)))
|
|
385
|
+
Vyg=np.transpose(V_Y.reshape((n_x,n_y)))
|
|
386
|
+
Magn=np.transpose(Scalar.reshape((n_x,n_y)))
|
|
387
|
+
|
|
388
|
+
if PLOT:
|
|
389
|
+
# One possibility is to use quiver
|
|
390
|
+
STEPx=Step; STEPy=Step
|
|
391
|
+
fig, ax = plt.subplots(figsize=(5, 3)) # This creates the figure
|
|
392
|
+
# Or you can plot it as streamlines
|
|
393
|
+
CL=plt.contourf(Xg,Yg,Magn*100,levels=np.arange(0,70,10))
|
|
394
|
+
# One possibility is to use quiver
|
|
395
|
+
STEPx=1; STEPy=1
|
|
396
|
+
plt.quiver(Xg[::STEPx,::STEPy],Yg[::STEPx,::STEPy],\
|
|
397
|
+
Vxg[::STEPx,::STEPy],Vyg[::STEPx,::STEPy],color='k')
|
|
398
|
+
plt.rc('text', usetex=True)
|
|
399
|
+
plt.rc('font', family='serif')
|
|
400
|
+
plt.rc('xtick',labelsize=12)
|
|
401
|
+
plt.rc('ytick',labelsize=12)
|
|
402
|
+
fig.colorbar(CL,pad=0.05,fraction=0.025)
|
|
403
|
+
ax.set_aspect('equal') # Set equal aspect ratio
|
|
404
|
+
ax.set_xlabel('$x[mm]$',fontsize=13)
|
|
405
|
+
ax.set_ylabel('$y[mm]$',fontsize=13)
|
|
406
|
+
#ax.set_title('Tutorial 2: Cylinder Wake',fontsize=12)
|
|
407
|
+
ax.set_xticks(np.arange(0,70,10))
|
|
408
|
+
ax.set_yticks(np.arange(-10,11,10))
|
|
409
|
+
ax.set_xlim([0,50])
|
|
410
|
+
ax.set_ylim(-10,10)
|
|
411
|
+
circle = plt.Circle((0,0),2.5,fill=True,color='r',edgecolor='k',alpha=0.5)
|
|
412
|
+
plt.gcf().gca().add_artist(circle)
|
|
413
|
+
plt.tight_layout()
|
|
414
|
+
plt.show()
|
|
415
|
+
|
|
416
|
+
return Xg,Yg,Vxg,Vyg,Magn
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
def plot_grid_cylinder_flow(Xg,Yg,Vxg,Vyg):
|
|
421
|
+
STEPx=1; STEPy=1
|
|
422
|
+
# This creates the figure
|
|
423
|
+
fig, ax = plt.subplots(figsize=(6, 3))
|
|
424
|
+
Magn=np.sqrt(Vxg**2+Vyg**2)
|
|
425
|
+
# Plot Contour
|
|
426
|
+
#CL=plt.contourf(Xg,Yg,Magn,levels=np.linspace(0,np.max(Magn),5))
|
|
427
|
+
CL=plt.contourf(Xg,Yg,Magn,20,cmap='viridis',alpha=0.95)
|
|
428
|
+
# One possibility is to use quiver
|
|
429
|
+
STEPx=1; STEPy=1
|
|
430
|
+
plt.quiver(Xg[::STEPx,::STEPy],Yg[::STEPx,::STEPy],\
|
|
431
|
+
Vxg[::STEPx,::STEPy],Vyg[::STEPx,::STEPy],color='k')
|
|
432
|
+
plt.rc('text', usetex=True)
|
|
433
|
+
plt.rc('font', family='serif')
|
|
434
|
+
plt.rc('xtick',labelsize=12)
|
|
435
|
+
plt.rc('ytick',labelsize=12)
|
|
436
|
+
#fig.colorbar(CL,pad=0.05,fraction=0.025)
|
|
437
|
+
ax.set_aspect('equal') # Set equal aspect ratio
|
|
438
|
+
ax.set_xlabel('$x[mm]$',fontsize=13)
|
|
439
|
+
ax.set_ylabel('$y[mm]$',fontsize=13)
|
|
440
|
+
#ax.set_title('Tutorial 2: Cylinder Wake',fontsize=12)
|
|
441
|
+
ax.set_xticks(np.arange(0,70,10))
|
|
442
|
+
ax.set_yticks(np.arange(-10,11,10))
|
|
443
|
+
ax.set_xlim([0,50])
|
|
444
|
+
ax.set_ylim(-10,10)
|
|
445
|
+
circle = plt.Circle((0,0),2.5,fill=True,color='r',edgecolor='k',alpha=0.5)
|
|
446
|
+
plt.gcf().gca().add_artist(circle)
|
|
447
|
+
plt.tight_layout()
|
|
448
|
+
|
|
449
|
+
return fig, ax
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
|