def velocity_distribution(M, start, end, display=False): #compute the distribution of velocity for Ux, Uy and U for all the individual measurements between start and end #substract the mean flow in each point M = cdata.rm_nan(M, 'Ux') M = cdata.rm_nan(M, 'Uy') (nx, ny, n) = M.shape() nt = end - start Ux = np.reshape(M.Ux[:, :, start:end], (nx * ny * nt, )) Uy = np.reshape(M.Uy[:, :, start:end], (nx * ny * nt, )) Ux_rms = np.std(Ux) Uy_rms = np.std(Uy) Ux_moy = np.reshape(np.mean(M.Ux[:, :, start:end], axis=2), (nx, ny, 1)) Uy_moy = np.reshape(np.mean(M.Uy[:, :, start:end], axis=2), (nx, ny, 1)) Ux_m = np.reshape(np.dot(Ux_moy, np.ones((1, 1, nt))), (nx, ny, nt)) Uy_m = np.reshape(np.dot(Uy_moy, np.ones((1, 1, nt))), (nx, ny, nt)) # Ux=np.reshape(M.Ux[:,:,start:end]-Ux_m,(nx*ny*nt,)) # Uy=np.reshape(M.Uy[:,:,start:end]-Uy_m,(nx*ny*nt,)) Ux = np.reshape(M.Ux[:, :, start:end], (nx * ny * nt, )) Uy = np.reshape(M.Uy[:, :, start:end], (nx * ny * nt, )) # U_s=np.zeros(len(Ux)+len(Uy)) U_s = np.concatenate((Ux, Uy)) # U=np.sqrt(Ux**2+Uy**2) #normalized by the RMS velocity : Uxt_rms = np.std(Ux) Uyt_rms = np.std(Uy) U_rms = np.std(U_s) print('RMS velocity : ' + str(U_rms) + ' m/s') mid = (start + end) / 2 #Normalisation by the temporal decay function Nvec = (M.t[mid] / 100)**(-1) Nvec = 1 if display: print(max(U_s)) print(min(U_s)) print(U_s.shape) print(Nvec) # graphes.hist(Ux,Nvec,0,100,'o') # graphes.hist(Uy,Nvec,0,100,'s') graphes.hist(U_s, Nvec, fignum=1, num=10**4, label='o') title = '' # title='Z= '+str(M.param.Zplane)+' mm, t='+str(M.t[mid])+' ms'+', Dt = '+str(nt*M.ft)+' ms' graphes.legende('$U_{x,y} (m/s)$', '$pdf(U)$', title) # fields={'Z':'Zplane','t',} # graphes.set_title(M,fields) return Ux_rms, Uy_rms, Uxt_rms, Uyt_rms
def radial_density(t, fignum=1, label=''): figs = {} nt = len(t.paths) R_tot = [] for j in range(nt): R = np.sum([t.paths[j][..., i]**2 for i in range(3)], axis=0) R_tot = R_tot + np.ndarray.tolist(R) graphes.hist(R_tot, log=True, fignum=fignum, label=label) figs.update(graphes.legende('R', 'PDF(R)', '')) return figs
def V_distribution(): V_tot = [] box = np.arange(-1, 1, 0.5) boxz = np.arange(-2, 2, 0.01) for i in range(1): t = distribution(10, 20) for x0 in box: for y0 in box: X = [np.asarray([x0, y0, z]) for z in boxz] V = biot.velocity_from_line(t.paths, X, Gamma=1, d=3) V_tot = V_tot + np.ndarray.tolist(V) biot.display_profile(X, V, label='', fignum=0) graphes.hist(V_tot, fignum=1)
def test_bound(dataList, W, Dt, **kwargs): maxn = 0 Umin, Umax = bounds_pix(W) ratio = [] for data in dataList: # values = np.asarray(data['u'])**2+np.asarray(data['v']**2) values = np.sqrt(np.asarray(data['u'])**2 + np.asarray(data['v'])**2) r = len(np.where(np.logical_and( values > Umin, values < Umax))[0]) * 100. / len(data['u']) ratio.append(r) xbin, n = graphes.hist(values, normalize=False, num=200, range=(0., 2 * Umax), **kwargs) #xfactor = Dt maxn = max([maxn, max(n) * 1.2]) ratio = np.nanmean(np.asarray(ratio)) graphes.graph([Umin, Umin], [0, maxn], label='r-', **kwargs) graphes.graph([Umax, Umax], [0, maxn], label='r-', **kwargs) graphes.set_axis(0, Umax * 1.2, 0, maxn) title = 'Dt = ' + str(Dt) + ', W = ' + str(W) + 'pix' fig = graphes.legende('U (pix)', 'Histogram of U', title) # graphes.set_axis(0,1.5,0,maxn) return ratio, fig
def shear_limit_M(M, W, Dt, type=1, **kwargs): """ Test the shear criterion : dU/W < 0.1 """ values = access.get(M, 'strain', frame) M, field = vgradient.compute(M, 'strain', step=1, filter=False, Dt=1, rescale=False, type=type, compute=False) values = getattr(M, field) #/W dUmin, dUmax = check.shear_limit_M(M, W) xbin, n = graphes.hist(values, normalize=False, num=200, range=(-0.5, 0.5), **kwargs) #xfactor = Dt maxn = max(n) * 1.2 graphes.graph([dUmin, dUmin], [0, maxn], label='r-', **kwargs) graphes.graph([dUmax, dUmax], [0, maxn], label='r-', **kwargs) graphes.legende('', '', '')
def plots(eigen,omega,cosine,step): """ Make plots of geometrical quantities associated to the strain tensor (eigenvalues, vorticity and stretching vector) INPUT ----- eigen : Dictionnary containing the eigenvalues Lambda and eigenvectors lambda omega : Dictionnary containing components of the vorticity field cosine : orientation angle between lambda and omega step : average number of data point per bin OUTPUT ----- figs : dict dictionnary of output figures, the key correspond to the number of the figure associated value is a title in string format (root name for an eventual saving process) """ figs={} #print('Epsilon : ') graphes.hist(eigen['epsilon'],label='k',step=step,fignum=1) figs.update(graphes.legende('$\epsilon$','PDF','',display=False)) label = ['k','b','r'] if True: # for i,key in enumerate(eigen.keys()): # k='Lambda_' # if key.find(k)>=0: # j=int(key[len(k)]) #hist(eigen_t[key],label=label[j],step=step,fignum=2+j) #plt.title(key) enstrophy = norm(omega,axis=3) graphes.hist(enstrophy,label='r',step=step,fignum=2) figs.update(graphes.legende('$\omega$','PDF','',display=False)) #if False: for i,key in enumerate(cosine.keys()): # print(key) keys = ['lambda_omega_','lambda_W_'] for z,k in enumerate(keys): if key.find(k)>=0: j=int(key[len(k)]) # print(j) graphes.hist(cosine[key],label=label[j],step=step,fignum=5+3*z+j) if z==0: figs.update(graphes.legende('cos($\lambda_'+str(3-j)+',\omega$)','PDF','',display=False)) if z==1: figs.update(graphes.legende('cos($\lambda_'+str(3-j)+',W$)','PDF','',display=False)) if key.find('W_omega')>=0: # print(step) graphes.hist(cosine[key],label='k',step=step,fignum=15) figs.update(graphes.legende('cos($\omega,W$)','PDF','',display=False)) # print(figs) return figs
def isotropy(M, label='k^--', display=True, fignum=1): step = 1 tl = M.t[0:None:step] N = 50 display_part = False Anisotropy = np.zeros(len(tl)) Meanflow = np.zeros(len(tl)) for i, t in enumerate(tl): print(i * 100 / len(tl)) rho, Phi = angles(M, i) theta, U_moy, U_rms = angular_distribution(M, i) # t,U_moy,U_rms = time_window_distribution(M,i,Dt=40) if display_part: graphes.hist(Phi, fignum=1, num=N) graphes.legende('Phi', 'PDF', '') graphes.graph(theta, U_moy, fignum=3, label='k^') graphes.legende('$\theta$', '$U^p$', 'Angular fluctation distribution') graphes.graph(theta, U_rms, fignum=4, label='ro') graphes.legende('$\theta$', '$U^p$', 'Angular average flow') Anisotropy[i] = np.std(U_rms) / np.nanmean(U_rms) Meanflow[i] = np.std(U_moy) / np.nanmean(U_rms) graphes.semilogx(tl, Anisotropy, label='ro', fignum=fignum, subplot=(1, 2, 1)) graphes.legende('Time (s)', 'I', 'Anisotropy' + graphes.set_title(M)) graphes.set_axes(10**-2, 10**4, 0, 2) graphes.semilogx(tl, Meanflow, label='k^', fignum=fignum, subplot=(1, 2, 2)) graphes.legende('Time (s)', '<U>', 'Average flow') graphes.set_axes(10**-2, 10**4, 0, 4)
def v_increment(M, start, end, d, p=1, ort='all', fignum=1, normalize=False): """ Compute the distribution of velocity increments, either longitudinal, transverse, or all INPUT ----- M : Mdata object with attributes : Ux, Uy with method : shape() start : int start indice end : int end indice d : numpy 1d array vector d for computing increments p : int order of the increments ∂u_p = (u(r+d)^p-u(r)^p)^1/p ort : string orientation. can be either 'all','trans','long' """ #compute the distribution of velocity for Ux, Uy and U for all the individual measurements between start and end (nx, ny, n) = M.shape() nt = end - start Ux = M.Ux[..., start:end] Uy = M.Uy[..., start:end] Uz = M.Uz[..., start:end] dim = len(M.shape()) if dim == 3: if d[0] > 0 and d[1] > 0: dU_x = ( Ux[d[0]:, d[1]:, :] - Ux[:-d[0], :-d[1], :])**p #**(1./p) #longitudinal component dU_y = (Uy[d[0]:, d[1]:, :] - Uy[:-d[0], :-d[1], :])**p #**(1./p) #transverse component dU_y = (Uz[d[0]:, d[1]:, :] - Uz[:-d[0], :-d[1], :])**p #**(1./p) else: dU_x = (Ux[d[0]:, ...] - Ux[:-d[0], ...])**p #**(1./p) dU_y = (Uy[d[0]:, ...] - Uy[:-d[0], ...])**p #**(1./p) dU_z = (Uz[d[0]:, ...] - Uz[:-d[0], ...])**p #**(1./p) else: print('not implemented') # U=np.sqrt(Ux**2+Uy**2) # graphes.hist(U,1,100,'k^') graphes.hist(dU_x, fignum=fignum, num=10**3, label='ro', log=True) graphes.hist(dU_y, fignum=fignum, num=10**3, label='bs', log=True) graphes.hist(dU_z, fignum=fignum, num=10**3, label='m^', log=True) mid = (start + end) / 2 # title='Z= '+str(M.param.Zplane)+' mm, t='+str(M.t[mid])+' ms'+', Dt = '+str(nt) figs = {} figs.update(graphes.legende('$dU_{x,y}$', 'rho(U)', 'D = ' + str(d[0]))) return figs
def Test_dv(M, frames=None, W=32, display=True, scale=True, type=1, **kwargs): frames = get_frames(M, frames) r = 0. ropt = 0. dU = access.get(M, 'dU', frames[0], Dt=len(frames), compute=False, rescale=False, type=type) for frame in frames: r0, ropt0 = gradient(M, frame, display=False, W=W, scale=scale) r += r0 ropt += ropt0 R = r / len(frames) Ropt = ropt / len(frames) if display: import stephane.display.graphes as graphes dUmin, dUmax = shear_limit(W) xbin, n = graphes.hist(dU, normalize=False, num=200, range=(-0.5, 0.5), **kwargs) #xfactor = Dt maxn = max(n) * 1.2 graphes.graph([dUmin, dUmin], [0, maxn], label='r-', **kwargs) graphes.graph([dUmax, dUmax], [0, maxn], label='r-', **kwargs) graphes.legende('', '', '') print("Percentage of good values (gradient test) : " + str(R) + " %") print("ratio measured shear / optimal value : " + str(Ropt)) #greater than 1 start to be bad return R
def compute(M, i, Dt=50, display=False): #compute the taylor scale by averaging U dU/dx over space. # the derivative can be taken either in the direction of U or in the direction perpendicular to it #call functions from the derivative module, that compute spatial derivative accurately nx, ny, nt = M.shape() start = max(0, i - Dt // 2) end = min(nt, i + Dt // 2) n = end - start Ux = M.Ux[:, :, start:end] Uy = M.Uy[:, :, start:end] #compute the strain tensor from Ux and Uy components edge = 3 d = 2 dU = np.zeros((nx - edge * 2, ny - edge * 2, d, d, n)) fx = max([np.mean(np.diff(M.x)), np.mean(np.diff(M.x))]) #in mm/box for k in range(n): U = np.transpose( np.asarray([Ux[..., k], Uy[..., k]]), (1, 2, 0) ) #shift the dimension to compute the strain tensor along axis 0 and 1 dU[..., k] = fx * strain_tensor.strain_tensor( U, d=2, step=1) #strain tensor computed at the box size #naive length scale, computed from Ux dUx/dx index = (slice(3, -3, None), slice(3, -3, None), slice(None)) E_dE = Ux[index] * dU[..., 0, 0, :] + Uy[index] * dU[..., 1, 1, :] E = np.power(Ux[index], 2) + np.power(Uy[index], 2) if display: graphes.hist(E_dE / np.std(E_dE), num=1000, label='ko--', fignum=1) graphes.hist(E / np.std(E), num=1000, label='r^-', fignum=1) graphes.set_axes(-10, 10, 1, 10**5) graphes.legende('E', 'pdf(E)', '') lambda_R0 = np.mean(E) / np.std(E_dE) print('') print(str(M.t[i]) + ' : ' + str(lambda_R0)) # input() dtheta = np.pi / 100 angles = np.arange(0, np.pi, dtheta) E_dE_l = [] E_dE_t = [] E_theta = [] lambda_R_l = [] lambda_R_t = [] for j, theta in enumerate(angles): U_theta = Ux[index] * np.cos(theta) + Uy[index] * np.sin(theta) dU_l = dU[..., 0, 0, :] * np.cos(theta) + dU[..., 1, 1, :] * np.sin(theta) dU_t = dU[..., 1, 0, :] * np.cos(theta) + dU[..., 0, 1, :] * np.sin( theta ) #derivative of the same component, but in the normal direction #longitudinal of U dU E_dE_l.append(np.std(U_theta * dU_l)) E_dE_t.append(np.std(U_theta * dU_t)) E_theta.append(np.mean(np.power(U_theta, 2))) lambda_R_l.append(E_theta[j] / E_dE_l[j]) lambda_R_t.append(E_theta[j] / E_dE_t[j]) lambda_Rl = np.mean(np.asarray(lambda_R_l)) lambda_Rt = np.mean(np.asarray(lambda_R_t)) lambda_Rl_std = np.std(np.asarray(lambda_R_l)) lambda_Rt_std = np.std(np.asarray(lambda_R_t)) print(str(M.t[i]) + ' : ' + str(lambda_Rl)) print(str(M.t[i]) + ' : ' + str(lambda_Rt)) # graphes.graph(angles,E_dE_l,fignum=1,label='ko') # graphes.graph(angles,E_dE_t,fignum=1,label='r^') # lambda_R = lambda_Rl lambdas = {} lambdas['l_moy'] = lambda_Rl lambdas['t_moy'] = lambda_R0 lambdas['l_std'] = lambda_Rl_std lambdas['t_std'] = lambda_Rt_std Urms = np.sqrt(np.std(E)) #E is in mm^2/s^-2 return lambdas, Urms
def hist_Sp(M, t, p=2): """ compute the p-th structure function <v(r)**p-v(r+d)**p>_{x,y} in progress INPUT ----- M : Mdata object to be processed t : int time index to process p : int default value : 2. Order of the structure function used for the computation OUTPUT ----- d_para : int array scale of variation of the space correlation function, computed from a parabolic fit of the correlation function around 0. Each element correspond to a given distance d between points d_lin : int array """ ny, nx, nt = M.shape() dlist = range(1, nx) fignum = [4] label = ['^-', '*-', 'o-'] Cxx = {} Cyy = {} CE = {} indices = d_2pts(M.Ux[:, :, t], dlist[0]) for d in dlist: # Cxx[d]=np.asarray(structure_function(M,t,indices,axe='xx',p=2)) # Cyy[d]=np.asarray(structure_function(M,t,indices,axe='yy',p=2)) CE[d] = np.asarray(structure_function(M, t, indices, axe='E', p=p)) # compute the distribution of C values i = dlist.index(d) xbin, n = graphes.hist(np.asarray(CE[d]), Nvec=1, fignum=fignum[i], num=100, label=label[i]) graphes.legende('$S_2 (m^2/s^2)$', 'pdf', str(d)) nlim = 100 part_lin = np.where(np.logical_and(n > nlim, xbin >= 0)) part_para = np.where(n > nlim) result = np.polyfit(xbin[part_para], np.log10(n[part_para]), 2, full=True) P_para = result[0] d_para = result[1] / (len(n[part_para]) * np.mean(n[part_para]**2)) result = np.polyfit(xbin[part_lin], np.log10(n[part_lin]), 1, full=True) P_lin = result[0] d_lin = result[1] / (len(n[part_lin]) * np.mean(n[part_lin]**2)) print(d_para, d_lin) print("ratio = " + str(d_para / d_lin)) # print("Curvature : "+str(P_para[0]*np.mean(xbin[part])*1000)) # print("Straight : "+str(P_lin[0]*1000)) CE_fit = np.polyval(P_para, xbin) CE_fit2 = np.polyval(P_lin, xbin[part_lin]) graphes.semilogy(xbin, 10**CE_fit, fignum=fignum[i], label='r-') graphes.semilogy(xbin[part_lin], 10**CE_fit2, fignum=fignum[i], label='k--') # print(d,len(CE[d]),CE[d]) return d_para, d_lin5