def get_surf(X_range, Y_range): """ Create the arrays for the surface plot. Parameters ---------- X_range : Narray of float Range along x_axis for the surface. Y_range : Narray of float Range along z axis for the surface. Returns ------- X_surf : Narray of float Meshgrid for x-axis. Y_surf : Narray of float Meshgrid for y-axis. Surf : Narray of float Surface altitude grid. """ Surf = np.zeros((len(Y_range),len(X_range))) X_surf, Y_surf = np.meshgrid(X_range,Y_range) for i in range(len(X_range)): for j in range(len(Y_range)): zpos = np.min(interp.get_Zlist_pos(X_range[i], Y_range[j], np.concatenate((data[:,0:2],np.reshape(Zsurf,(len(Zsurf),1))),axis=1))[1]) Surf[j,i] = zpos; return X_surf, Y_surf, Surf
def get_surface_altitude(self, latitude, longitude): """Get the altitude of the ground of the given coordinates Parameters ---------- latitude : double The latitude of the coordinates longitude : double The longitude of the coordinates Returns ------- double The altitude of the surface """ map_surface = [[ self._wind_cube["Position"][i, 0], self._wind_cube["Position"][i, 1], self._wind_cube["Surface_altitude"][i] ] for i in range(self._nb_points)] map_surface = np.array(map_surface) x, y = flat_distance_point((latitude, longitude), self._location) #Get the smallest cube (x,y) possible x_min, x_max = smallest_interval(x, self._list_point["x"]) y_min, y_max = smallest_interval(y, self._list_point["y"]) if abs(x_min - x) < abs(x_max - x): x = x_min else: x = x_max if abs(y_min - y) < abs(y_max - y): y = y_min else: y = y_max surface_alt = extrapolation.get_Zlist_pos(x, y, map_surface)[1] surface_alt = np.unique(surface_alt)[0] return surface_alt
def plot_wind_cube_turbulent(wind_cube, xlim, ylim, zlim, T, dt, nb_points, plot): """ Calculate a wind_cube with turbulence inside the wind_cube and plots it if needed (if the number of iteration is reasonnable). Parameters ---------- wind_cube : wind_cube The wind cube on which the interpolation will be done. xlim : Narray of floats Numpy array of size 2 containing the limits of the x-axis range. It must be in meters from the bottom left corner. ylim : Narray of floats Numpy array of size 2 containing the limits of the y-axis range. It must be in meters from the bottom left corner. zlim : Narray of floats Numpy array of size 2 containing the limits of the z-axis range. In elevation convention. nb_points : int Number of output points along x and y axes. Default = 10. T : float duration of observation of the wind speed. dt : float timestep of the computation plot : Bool Activates the plot option. Default = False. Returns ------- cube_list : list of 6 Narray containing the evolution of the wind speed in time : X_mesh : Narray of floats 3D-mesh for the interpolated x coordinates. Y_mesh : Narray of floats 3D-mesh for the interpolated x coordinates. Z_mesh : Narray of floats 3D-mesh for the interpolated x coordinates. In elevation convention. Uinterp : Narray of floats 3D-mesh for the interpolated wind speed component along x-axis. Vinterp : Narray of floats 3D-mesh for the interpolated wind speed component along y-axis. Winterp : Narray of floats 3D-mesh for the interpolated wind speed component along z-axis. """ global data_points data_points = wind_cube["Position"] global data_wind data_wind = wind_cube["Wind_speed"] global Zsurf Zsurf = wind_cube["Surface_altitude"].reshape(-1,1) global data data = np.concatenate((data_points, data_wind, Zsurf),axis=1) #Récupération du maillage horizontal global X X = data[:,0] global Y Y = data[:,1] global X_tick X_tick = np.unique(X) global Y_tick Y_tick = np.unique(Y) global Z_tick Z_tick = interp.get_Zlist_pos(X_tick[0], Y_tick[0], data[:,0:3])[1] # Interpolation X_mesh, Y_mesh, Z_mesh, Uinterp, Vinterp, Winterp, Sinterp = get_interp_data(xlim,ylim,zlim,nb_points,False) # Preparation of the values for turbulence fs = 10 N = 120 Ntheta = 25 df, dtheta = fs/2 / N, np.pi / Ntheta nb_iter = int(T/dt) + 1 if nb_iter > 15 : print("Too much iteration ! No images will be generated") plot = False # Getting the mean and direction on each elevation cube_list = [0 for k in range(nb_iter)] list_Uz = [] list_dz = [] tableau_Sprin = [] tableau_Slate = [] tableau_Svert = [] for z in range(np.shape(Z_mesh)[0]) : hauteur = Z_mesh[0,0,z] Umoy = 0 dmoy = 0 count = 0 for x in range(np.shape(X_mesh)[0]) : for y in range(np.shape(Y_mesh)[0]) : u, v = Uinterp[x,y,z], Vinterp[x,y,z] norme = np.sqrt(u**2 + v**2) direction = np.arccos(abs(u)/norme) if v < 0 : direction = - direction count = count + 1 Umoy = Umoy + norme dmoy = dmoy + direction Umoy = Umoy / count dmoy = dmoy / count list_Uz.append(Umoy) list_dz.append(dmoy) altitude_correction = max((CORREC_ALTI - 1)/(1000 - 0)*hauteur + 1, CORREC_ALTI) s_base = Umoy * altitude_correction * CORREC_GLOBAL s_prin = RATIO_PRIN * s_base s_late = RATIO_LAT * s_base s_w = RATIO_VERT * s_base X_prin, X_late, X_vert = [], [], [] for k in range(N): frequency = k/(2*N) * fs s_prink = np.sqrt(TIME_MAX/(2*np.pi) * s_prin**2 * spectre_prin_p(frequency,\ Umoy, hauteur)) s_latek = np.sqrt(TIME_MAX/(2*np.pi) * s_late**2 * spectre_late_p(frequency,\ Umoy, hauteur)) s_wk = np.sqrt(TIME_MAX/(2*np.pi) * s_w**2 * spectre_w_p(frequency, \ Umoy, hauteur)) X_prin.append(s_prink) X_late.append(s_latek) X_vert.append(s_wk) tableau_Sprin.append(X_prin) tableau_Slate.append(X_late) tableau_Svert.append(X_vert) Psi = rd.uniform(0, 2*np.pi, N * Ntheta + 1) # Computing for each timestep the wind cube for t in range(1, nb_iter + 1): Ut = Uinterp.copy() Vt = Vinterp.copy() Wt = Winterp.copy() for x in range(np.shape(X_mesh)[0]) : for y in range(np.shape(Y_mesh)[0]) : for z in range(np.shape(Z_mesh)[0]) : coordx = X_mesh[x,y,z] coordy = Y_mesh[x,y,z] coordz = Z_mesh[x,y,z] u = Uinterp[x, y, z] v = Vinterp[x, y, z] w = Winterp[x, y, z] coordx_prin = np.cos(list_dz[z]) * coordx - np.sin(list_dz[z]) * coordy coordx_late = np.sin(list_dz[z]) * coordx + np.cos(list_dz[z]) * coordy uprin, ulate, uvert = 0, 0, 0 windmoy = list_Uz[z] for k in range(N) : for kk in range(Ntheta): uprin = uprin + np.sqrt(4/np.pi * tableau_Sprin[z][k] * 2*np.pi* df * dtheta * (np.cos(-np.pi/2 + kk * dtheta))**2) * np.cos(2*np.pi*k*df/windmoy * coordx_prin * np.cos(-np.pi/2 + kk * dtheta) + 2*np.pi*k*df/windmoy * coordx_late * np.sin(-np.pi/2 + kk * dtheta) - 2*np.pi*k*df * t*dt + Psi[k*Ntheta + kk]) ulate = ulate + np.sqrt(4/np.pi * tableau_Slate[z][k] * 2*np.pi* df * dtheta * (np.cos(-np.pi/2 + kk * dtheta))**2) * np.cos(2*np.pi*k*df/windmoy * coordx_prin * np.cos(-np.pi/2 + kk * dtheta) + 2*np.pi*k*df/windmoy * coordx_late * np.sin(-np.pi/2 + kk * dtheta) - 2*np.pi*k*df * t*dt + Psi[k*Ntheta + kk]) uvert = uvert + np.sqrt(4/np.pi * tableau_Svert[z][k] * 2*np.pi* df * dtheta * (np.cos(-np.pi/2 + kk * dtheta))**2) * np.cos(2*np.pi*k*df/windmoy * coordx_prin * np.cos(-np.pi/2 + kk * dtheta) + 2*np.pi*k*df/windmoy * coordx_late * np.sin(-np.pi/2 + kk * dtheta) - 2*np.pi*k*df * t*dt + Psi[k*Ntheta + kk]) unew = u + np.cos(list_dz[z]) * uprin - np.sin(list_dz[z]) * ulate vnew = v + np.sin(list_dz[z]) * uprin + np.cos(list_dz[z]) * ulate wnew = w + uvert Ut[x, y, z] = unew Vt[x, y, z] = vnew Wt[x, y, z] = wnew cube_list.append([X_mesh, Y_mesh, Z_mesh, Ut, Vt, Wt]) if plot == True: X_range, Y_range, Z_range = get_interv(xlim, ylim, zlim) X_surf, Y_surf, Surf = get_surf(X_range, Y_range) fig = plt.figure(figsize=(16,10)) ax = fig.gca(projection="3d") ax.plot_surface(X_surf,Y_surf, Surf, cmap=cm.terrain) ax.quiver(X_mesh, Y_mesh, Z_mesh+Sinterp, Uinterp, Vinterp, Winterp, color = "limegreen", length=max(X_mesh[0,:,0])/400, label = "Steady") ax.quiver(X_mesh, Y_mesh, Z_mesh+Sinterp, Ut, Vt, Wt, color = "red", length=max(X_mesh[0,:,0])/400, label = "Turbulent") ax.set_zlim([max(0,min(Sinterp[0,0,:])),max(2000+min((Z_mesh+Sinterp)[0,0,:]),max((Z_mesh+Sinterp)[0,0,:]))]) ax.legend() plt.ion() plt.xlabel("x (m)") plt.ylabel("y (m)") plt.show() return(cube_list)
def plot_wind_surface(wind_cube, axis, coord, alt, nb_points, plot): """ Calculate a wind profile or a wind surface from the wind_cube. Parameters ---------- wind_cube : wind_cube The wind cube on which the interpolation will be done. axis : string Type of interpoltion to do. "z" for a wind surface, "x" or "y" for a wind profile. coord : Narray of float Coordinates of the point for the wind profile. In GPS coordinates. alt : float Altitude for the wind surface. Must be the altitude above sea level. If wind profile required, elevation above ground max for the plot. nb_points : int Number of output points along x and y axes. Default = 10. plot : Bool Activates the plot option. Default = False. Returns ------- X_mesh : Narray of floats Interpolated x coordinates. 1D list. Y_mesh : Narray of floats Interpolated y coordinates. 1D list Z_mesh : Narray of floats Interpolated z coordinates. 1D list in elevation convention for the wind_profile and altitude convention for the wind_surface. Uinterp : Narray of floats 1D array for the interpolated wind speed component along x-axis. Vinterp : Narray of floats 1D array for the interpolated wind speed component along y-axis. Winterp : Narray of floats 1D array for the interpolated wind speed component along z-axis. Sinterp : Narray of floats 1D array for the interpolated surface altitude. """ global data_points data_points = wind_cube["Position"] global data_wind data_wind = wind_cube["Wind_speed"] global Zsurf Zsurf = wind_cube["Surface_altitude"].reshape(-1,1) global data data = np.concatenate((data_points, data_wind, Zsurf),axis=1) # Retrieving the horizontal mesh global X X = data[:,0] global Y Y = data[:,1] global X_tick X_tick = np.unique(X) global Y_tick Y_tick = np.unique(Y) global Z_tick Z_tick = interp.get_Zlist_pos(X_tick[0], Y_tick[0], data[:,0:3])[1] # Wind profile --> interpolation in elevation convention if axis == "x" or axis == "y": #Decomposing the coordinates x = coord[0] y = coord[1] # Creating the limit arrays xlim = np.array([x,x]) ylim = np.array([y,y]) zlim = np.array([Z_tick[0], alt]) # Interpolation X_mesh, Y_mesh, Z_mesh, Uinterp, Vinterp, Winterp, Sinterp = get_interp_data(xlim, ylim, zlim, nb_points, False) # Resizing the result meshes Z_mesh =Z_mesh[0,0,:] Uinterp = Uinterp[0,0,:] Vinterp = Vinterp[0,0,:] Winterp = Winterp[0,0,:] # Calculating the norm Norm = np.sqrt(Uinterp*Uinterp + Vinterp*Vinterp + Winterp*Winterp) # Plot if required if plot == True: # U-component fig = plt.figure(figsize=(16,12)) plt.plot(Uinterp,Z_mesh,'b-o',label='U') plt.legend(fontsize=16) plt.xlabel('Vitesse algébrique (m/s)') plt.ylabel('elevation a.g.l (m)') plt.grid(which='both') plt.title('Wind profile at x=%6.2fm y=%6.2fm' %(x,y)) # V component fig = plt.figure(figsize=(16,12)) plt.plot(Vinterp,Z_mesh,'g-o',label='V') plt.legend(fontsize=16) plt.xlabel('Vitesse algébrique (m/s)') plt.ylabel('elevation a.g.l (m)') plt.grid(which='both') plt.title('Wind profile at x=%6.2fm y=%6.2fm' %(x,y)) # W component fig = plt.figure(figsize=(16,12)) plt.plot(Winterp,Z_mesh,'r-o',label='W') plt.legend(fontsize=16) plt.xlabel('Vitesse algébrique (m/s)') plt.ylabel('elevation a.g.l (m)') plt.grid(which='both') plt.title('Wind profile at x=%6.2fm y=%6.2fm' %(x,y)) # Norm plt.figure(figsize=(16,12)) plt.plot(Norm,Z_mesh,'m-o',label='W') plt.legend(fontsize=16) plt.xlabel('Norme (m/s)') plt.ylabel('elevation a.g.l (m)') plt.grid(which='both') plt.title('Wind profile at x=%6.2fm y=%6.2fm' %(x,y)) plt.show() else: # Wind surface if axis == "z": # Checking altitude inside bounds if alt < min(Zsurf): raise ValueError("Altitude below ground surface") if alt > (max(Zsurf) + max(Z_tick)): raise ValueError("Altitude exceed the maximum altitude of the domain") if alt > (min(Zsurf) + max(Z_tick)): raise Warning("Altitude exceed the maximum calculated elevation over the lowest point of the domain. Some points might not be interpolated") # Creating the limit arrays xlim = np.array([X_tick[0], X_tick[-1]]) ylim = np.array([Y_tick[0], Y_tick[-1]]) zlim = np.array([alt,alt]) # Interpolation X_mesh, Y_mesh, Z_mesh, Uinterp, Vinterp, Winterp, Sinterp = get_interp_data(xlim,ylim,zlim, nb_points, True) # Retrieving the position of the points at the required altitude select = np.argwhere(np.round(Sinterp+Z_mesh)==alt) X = np.zeros(len(select)) Y = np.zeros(len(select)) U = np.zeros(len(select)) V = np.zeros(len(select)) S = np.zeros(len(select)) # Building the surface for i in range(len(select)-1): xarg = select[i,0] yarg = select[i,1] zarg = select[i,2] X[i] = X_mesh[xarg,yarg,zarg] Y[i] = Y_mesh[xarg,yarg,zarg] U[i] = Uinterp[xarg,yarg,zarg] V[i] = Vinterp[xarg,yarg,zarg] S[i] = Sinterp[xarg,yarg,zarg] # Calculating the norm M = np.hypot(U,V) # Plot if required if plot == True: X_surf, Y_surf, Surf = get_surf(X_tick, Y_tick) plt.figure(figsize=(14,12)) # wind surface plt.quiver(X, Y, U, V, M, pivot='mid', units='xy') plt.colorbar() #iso-altitude contours plt.scatter(X, Y, color='r', s=5) CS = plt.contour(X_surf, Y_surf, Surf, colors='black') plt.clabel(CS, inline=1, fontsize=10, fmt='%1.f') plt.title('Wind plot at altitude %im a.s.l (m/s)' %alt) plt.xlabel('x (m)') plt.ylabel('y (m)') plt.grid() plt.show() return X_mesh, Y_mesh, Z_mesh, Uinterp, Vinterp, Winterp, Sinterp
def plot_wind_cube(wind_cube, xlim, ylim, zlim, nb_points, plot): """ Calculate a wind_cube inside the wind_cube and plots it if needed. Parameters ---------- wind_cube : wind_cube The wind cube on which the interpolation will be done. xlim : Narray of floats Numpy array of size 2 containing the limits of the x-axis range. ylim : Narray of floats Numpy array of size 2 containing the limits of the y-axis range. zlim : Narray of floats Numpy array of size 2 containing the limits of the z-axis range. In elevation convention. nb_points : int Number of output points along x and y axes. Default = 10. plot : Bool Activates the plot option. Default = False. Returns ------- X_mesh : Narray of floats 3D-mesh for the interpolated x coordinates. Y_mesh : Narray of floats 3D-mesh for the interpolated x coordinates. Z_mesh : Narray of floats 3D-mesh for the interpolated x coordinates. In elevation convention. Uinterp : Narray of floats 3D-mesh for the interpolated wind speed component along x-axis. Vinterp : Narray of floats 3D-mesh for the interpolated wind speed component along y-axis. Winterp : Narray of floats 3D-mesh for the interpolated wind speed component along z-axis. Sinterp : Narray of floats 3D-mesh for the interpolated surface altitude. """ global data_points data_points = wind_cube["Position"] global data_wind data_wind = wind_cube["Wind_speed"] global Zsurf Zsurf = wind_cube["Surface_altitude"].reshape(-1,1) global data data = np.concatenate((data_points, data_wind, Zsurf),axis=1) # Retrieving the horizontal mesh global X X = data[:,0] global Y Y = data[:,1] global X_tick X_tick = np.unique(X) global Y_tick Y_tick = np.unique(Y) global Z_tick Z_tick = interp.get_Zlist_pos(X_tick[0], Y_tick[0], data[:,0:3])[1] # Interpolation X_mesh, Y_mesh, Z_mesh, Uinterp, Vinterp, Winterp, Sinterp = get_interp_data(xlim,ylim,zlim,nb_points,False) # Plotting the wind-cube if required if plot == True: X_range, Y_range, Z_range = get_interv(xlim, ylim, zlim) X_surf, Y_surf, Surf = get_surf(X_range, Y_range) fig = plt.figure(figsize=(16,10)) ax = fig.gca(projection='3d') ax.plot_surface(X_surf,Y_surf, Surf, cmap=cm.terrain) ax.quiver(X_mesh, Y_mesh, Z_mesh+Sinterp, Uinterp, Vinterp, Winterp, colors='#7F8C8D', length=max(X_mesh[0,:,0])/400) ax.set_zlim([max(0,min(Sinterp[0,0,:])),max(2000+min((Z_mesh+Sinterp)[0,0,:]),max((Z_mesh+Sinterp)[0,0,:]))]) plt.ion() plt.xlabel('x (m)') plt.ylabel('y (m)') plt.show() return X_mesh, Y_mesh, Z_mesh, Uinterp, Vinterp, Winterp, Sinterp