def interp_bry(obctype,ncglo,tndx_glo,ncbry,tndx_bry,\ h_bry,theta_s,theta_b,hc,N,vtransform,\ Nzgoodmin,depth,angle_bry,\ LonT_bry,LatT_bry,iminT_bry,imaxT_bry,jminT_bry,jmaxT_bry,elemT_bry,coefT_bry,\ LonU_bry,LatU_bry,iminU_bry,imaxU_bry,jminU_bry,jmaxU_bry,elemU_bry,coefU_bry,\ LonV_bry,LatV_bry,iminV_bry,imaxV_bry,jminV_bry,jmaxV_bry,elemV_bry,coefV_bry): # # ################################################################ # function interp_bry(obctype,ncglo,tndx_glo,ncbry,tndx_bry,\ # h_bry,theta_s,theta_b,hc,N,vtransform,\ # Nzgoodmin,depth,angle_bry,\ # LonT_bry,LatT_bry,iminT_bry,imaxT_bry,jminT_bry,jmaxT_bry,elemT_bry,coefT_bry,\ # LonU_bry,LatU_bry,iminU_bry,imaxU_bry,jminU_bry,jmaxU_bry,elemU_bry,coefU_bry,\ # LonV_bry,LatV_bry,iminV_bry,imaxV_bry,jminV_bry,jmaxV_bry,elemV_bry,coefV_bry) # # # Interpolates all the variable for one boundary # # Input: # # obctype,ncglo,tndx_glo,ncbry,tndx_bry, # h_bry,theta_s,theta_b,hc,N,vtransform, # Nzgoodmin,depth,angle_bry, # LonT_bry,LatT_bry,iminT_bry,imaxT_bry,jminT_bry,jmaxT_bry,elemT_bry,coefT_bry, # LonU_bry,LatU_bry,iminU_bry,imaxU_bry,jminU_bry,jmaxU_bry,elemU_bry,coefU_bry, # LonV_bry,LatV_bry,iminV_bry,imaxV_bry,jminV_bry,jmaxV_bry,elemV_bry,coefV_bry # # Output: # # ncbry Netcdf file structure # ################################################################ # # # # # 1: SSH # # print('Interpolate SSH...') (zeta_bry,NzGood) = glor.interp_tracers(ncglo,'ssh',tndx_glo,-1,\ iminT_bry,imaxT_bry,jminT_bry,jmaxT_bry,\ LonT_bry,LatT_bry,coefT_bry,elemT_bry) # # Get CROCO sigma coordinate at rho and w points (using zeta) # z_rho=vgrd.zlevs(h_bry,zeta_bry,theta_s,theta_b,hc,N,'r',vtransform) z_w=vgrd.zlevs(h_bry,zeta_bry,theta_s,theta_b,hc,N,'w',vtransform) # # # 2: Temperature # # print('Interpolate Temperature...') temp_bry=glor.interp3d(ncglo,'temp',tndx_glo,Nzgoodmin,depth,z_rho,\ iminT_bry,imaxT_bry,jminT_bry,jmaxT_bry,\ LonT_bry,LatT_bry,coefT_bry,elemT_bry) # # # 3: Salinity # # print('Interpolate Salinity...') salt_bry=glor.interp3d(ncglo,'salt',tndx_glo,Nzgoodmin,depth,z_rho,\ iminT_bry,imaxT_bry,jminT_bry,jmaxT_bry,\ LonT_bry,LatT_bry,coefT_bry,elemT_bry) # # # 4: U and V # # (interpolate on z levels at rho points - rotate to align with the grid - # put to u and v points - vertical interpolation to sigma grid) # # cosa=np.cos(angle_bry) sina=np.sin(angle_bry) [u_bry,v_bry]=glor.interp3d_uv(ncglo,tndx_glo,Nzgoodmin,depth,z_rho,cosa,sina,\ iminU_bry,imaxU_bry,jminU_bry,jmaxU_bry,\ LonU_bry,LatU_bry,coefU_bry,elemU_bry,\ iminV_bry,imaxV_bry,jminV_bry,jmaxV_bry,\ LonV_bry,LatV_bry,coefV_bry,elemV_bry) # # # 5: UBAR and VBAR # # Here it could be nice to get the barotropic transport from GLORYS, to put it on CROCO grid, # and to correct u and v accordingly... # But let's start simple and just integrate u and v on CROCO grid. # # (ubar_bry,h0)=vgrd.vintegr(u_bry,rho2u_3d(z_w),rho2u_3d(z_rho),np.nan,np.nan)/rho2u_2d(h_bry) (vbar_bry,h0)=vgrd.vintegr(v_bry,rho2v_3d(z_w),rho2v_3d(z_rho),np.nan,np.nan)/rho2v_2d(h_bry) if obctype=='s': ncbry['zeta_south'][tndx_bry,:]=zeta_bry[0,:] ncbry['temp_south'][tndx_bry,:,:]=temp_bry[:,0,:] ncbry['salt_south'][tndx_bry,:,:]=salt_bry[:,0,:] ncbry['u_south'][tndx_bry,:,:]=u_bry[:,0,:] ncbry['v_south'][tndx_bry,:,:]=v_bry[:,0,:] ncbry['ubar_south'][tndx_bry,:]=ubar_bry[0,:] ncbry['vbar_south'][tndx_bry,:]=vbar_bry[0,:] elif obctype=='n': ncbry['zeta_north'][tndx_bry,:]=zeta_bry[-1,:] ncbry['temp_north'][tndx_bry,:,:]=temp_bry[:,-1,:] ncbry['salt_north'][tndx_bry,:,:]=salt_bry[:,-1,:] ncbry['u_north'][tndx_bry,:,:]=u_bry[:,-1,:] ncbry['v_north'][tndx_bry,:,:]=v_bry[:,-1,:] ncbry['ubar_north'][tndx_bry,:]=ubar_bry[-1,:] ncbry['vbar_north'][tndx_bry,:]=vbar_bry[-1,:] elif obctype=='e': ncbry['zeta_east'][tndx_bry,:]=zeta_bry[:,0] ncbry['temp_east'][tndx_bry,:,:]=temp_bry[:,:,0] ncbry['salt_east'][tndx_bry,:,:]=salt_bry[:,:,0] ncbry['u_east'][tndx_bry,:,:]=u_bry[:,:,0] ncbry['v_east'][tndx_bry,:,:]=v_bry[:,:,0] ncbry['ubar_east'][tndx_bry,:]=ubar_bry[:,0] ncbry['vbar_east'][tndx_bry,:]=vbar_bry[:,0] elif obctype=='w': ncbry['zeta_west'][tndx_bry,:]=zeta_bry[:,-1] ncbry['temp_west'][tndx_bry,:,:]=temp_bry[:,:,-1] ncbry['salt_west'][tndx_bry,:,:]=salt_bry[:,:,-1] ncbry['u_west'][tndx_bry,:,:]=u_bry[:,:,-1] ncbry['v_west'][tndx_bry,:,:]=v_bry[:,:,-1] ncbry['ubar_west'][tndx_bry,:]=ubar_bry[:,-1] ncbry['vbar_west'][tndx_bry,:]=vbar_bry[:,-1] return(ncbry)
# # print('Interpolate SSH...') (zeta, NzGood) = glor.interp_tracers(ncglo, 'ssh', tndx_glo, -1, iminT, imaxT, jminT, jmaxT, LonT, LatT, coefT, elemT) ncini['zeta'][tndx_ini, :, :] = zeta # # Get CROCO sigma coordinate at rho and w points (using zeta) # z_rho = vgrd.zlevs(h, zeta, theta_s, theta_b, hc, N, 'r', vtransform) z_w = vgrd.zlevs(h, zeta, theta_s, theta_b, hc, N, 'w', vtransform) # # # 2: Temperature # # print('Interpolate Temperature...') temp = glor.interp3d(ncglo, 'temp', tndx_glo, Nzgoodmin, depth, z_rho, iminT, imaxT, jminT, jmaxT, LonT, LatT, coefT, elemT) ncini['temp'][tndx_ini, :, :, :] = temp
# # Calculate rho at z=0 # a = -P0 * (1 - np.exp(-H)) / (g * (H - 1 + np.exp(-H))) rho1 = rho0 + a * np.exp(-(np.power(X, 2) + np.power(Y, 2)) / radius**2) # # Surface elevation # zeta = (P1 - Pa) / (g * rho1) # # Vertical grid # zw = zlevs(h0, zeta, theta_s, theta_b, hc, N, 'w', vtransform) zr = zlevs(h0, zeta, theta_s, theta_b, hc, N, 'r', vtransform) # # Density # # M, L = np.shape(X) xr = np.reshape(X, (1, M, L)) xr = np.tile(xr, (N, 1, 1)) M, L = np.shape(Y) yr = np.reshape(Y, (1, M, L)) yr = np.tile(yr, (N, 1, 1)) # rho = rho0 * (1 - N2 * zr / g)
def get_NS_section(Lat_min,Lat_max,Lon_sec,fname,vname,tndx): # # Extract a merdional vertical slice from a ROMS netcdf file # (with a regular rectangular grid) # # # On Input: # # Lat_min Minimum latitude of section # Lat_max Maximum latitude of section # Lon_sec Longitude of section # fname ROMS/CROCO netcdf name # vname ROMS/CROCO variable name # # # On Output: LAT,Z,VAR # # LAT Latitudes of the section (2D matrix) # Z Slice Z-positions (2D matrix) # VAR Slice variable (2D matrix) # # ### FUNCTION GET_NS_SECTION ################################################### # # # # Open netcdf file # nc=netcdf(fname,mode='r') # # Read in the file # lon = np.array(nc.variables['lon_rho'][0,:]) lat = np.array(nc.variables['lat_rho'][:,0]) print( 'Lon min: ', lon.min(),' Lon max: ', lon.max()) print( 'Lat min: ', lat.min(),' Lat max: ', lat.max()) dlon=np.abs(lon-Lon_sec) dlat1=np.abs(lat-Lat_min) dlat2=np.abs(lat-Lat_max) i=np.int(np.array(np.where(dlon==np.min(dlon)))) jmin=np.int(np.array(np.where(dlat1==np.min(dlat1)))) jmax=np.int(np.array(np.where(dlat2==np.min(dlat2)))) lat = lat[jmin:jmax] rmask=np.array(nc.variables['mask_rho'][jmin:jmax,i]) h=np.array(nc.variables['h'][jmin:jmax,i]) zeta=np.array(nc.variables['zeta'][tndx,jmin:jmax,i]) print(vname) VAR=np.array(nc.variables[vname][tndx,:,jmin:jmax,i]) theta_s=nc.theta_s theta_b=nc.theta_b hc=nc.hc vtransform=nc.variables['Vtransform'][:] sc_r=nc.variables['sc_r'][:] N=np.size(sc_r) nc.close() LAT=np.matlib.repmat(lat,N,1) MASK=np.matlib.repmat(rmask,N,1) VAR[np.where(MASK==0)]=np.nan Z=vgrd.zlevs(h,zeta,theta_s,theta_b,hc,N,'r',vtransform) return LAT,Z,VAR
def get_UV_section(lonsec,latsec,u,v,lon,lat,rmask,h,zeta,theta_s,theta_b,hc,N,vtransform): # # Extract a vertical slice of cross-section and along section velocities # in any direction (or along a curve) from a ROMS netcdf file. # # # On Input: # # lonsec Longitudes of the points of the section. # latsec Latitudes of the points of the section. # u CROCO eastward velocities at rho point # v CROCO northward velocities at rho point # lon Longitudes at rho points # lat Latitudes at rho points # rmask # h # zeta # theta_s # theta_b # hc # N # vtransform # # # On Output: LON,LAT,X,Z,Un,Ut # # LON Longitudes of the section (2D matrix). # LAT Latitudes of the section (2D matrix). # X Slice X-distances (km) from the first point (2D matrix). # Z Slice Z-positions (2D matrix). # Un Slice cross-section velocities (2D matrix). # Ut Slice along-section velocities (2D matrix). # # Npts=np.size(lonsec) dlon=np.gradient(lonsec) dlat=np.gradient(latsec) Rearth=6367442.76 deg2rad=np.pi/180 dx=Rearth*deg2rad*dlon*np.cos(deg2rad*latsec) dy=Rearth*deg2rad*dlat dl=np.sqrt(dx*dx +dy*dy) tx=dx/dl ty=dy/dl nx=-ty ny=tx # # Get a first subgrid limited by the size of the section (extended by twice the resolution dl) # (dlony,dlonx)=np.gradient(lon) (dlaty,dlatx)=np.gradient(lat) dl=2*np.max((np.max(np.abs(dlonx)),np.max(np.abs(dlony)),np.max(np.abs(dlatx)),np.max(np.abs(dlaty)))) minlon=np.min(lonsec)-dl minlat=np.min(latsec)-dl maxlon=np.max(lonsec)+dl maxlat=np.max(latsec)+dl sub=( (lon>minlon) & (lon<maxlon) & (lat>minlat) & (lat<maxlat) ) (jndx,indx)=np.where(sub) imin=np.min(indx) imax=np.max(indx) jmin=np.min(jndx) jmax=np.max(jndx) lon=lon[jmin:jmax,imin:imax] lat=lat[jmin:jmax,imin:imax] zeta=zeta[jmin:jmax,imin:imax] h=h[jmin:jmax,imin:imax] rmask=rmask[jmin:jmax,imin:imax] u=u[:,jmin:jmax,imin:imax] v=v[:,jmin:jmax,imin:imax] masksec=np.nan+0*lonsec zetasec=np.nan+0*lonsec HSEC=np.nan+0*lonsec Un=np.nan+np.zeros((N,Npts)) Ut=np.nan+np.zeros((N,Npts)) # # Do an interpolation for each point of the section # for i in np.arange(0,Npts): # # Get a subgrid around each point # sub=( (lon>lonsec[i]-dl) & (lon<lonsec[i]+dl) & \ (lat>latsec[i]-dl) & (lat<latsec[i]+dl) ) (jndx,indx)=np.where(sub) imin=np.min(indx) imax=np.max(indx) jmin=np.min(jndx) jmax=np.max(jndx) londata=lon[jmin:jmax,imin:imax].ravel() latdata=lat[jmin:jmax,imin:imax].ravel() maskdata=rmask[jmin:jmax,imin:imax].ravel() zetadata=zeta[jmin:jmax,imin:imax].ravel() hdata=h[jmin:jmax,imin:imax].ravel() # # Get the mask as nearest point # masksec[i]=griddata((londata,latdata),maskdata, (lonsec[i], latsec[i]), method='nearest') # # If there is enough data, do the interpolation # isgood=np.where(np.isfinite(zetadata)) if np.size(isgood)>4: zetasec[i]=griddata((londata[isgood],latdata[isgood]),zetadata[isgood], (lonsec[i], latsec[i]), method='cubic') HSEC[i]=griddata((londata[isgood],latdata[isgood]),hdata[isgood], (lonsec[i], latsec[i]), method='cubic') for k in np.arange(0,N): vdata=u[k,jmin:jmax,imin:imax].ravel() U=griddata((londata[isgood],latdata[isgood]),vdata[isgood], (lonsec[i], latsec[i]), method='cubic') vdata=v[k,jmin:jmax,imin:imax].ravel() V=griddata((londata[isgood],latdata[isgood]),vdata[isgood], (lonsec[i], latsec[i]), method='cubic') Un[k,i]=U*nx[i]+V*ny[i] Ut[k,i]=U*tx[i]+V*ty[i] # # Get the vertical positions # zetasec[np.where(np.isnan(zetasec))]=0. HSEC[np.where(np.isnan(HSEC))]=hc Z=vgrd.zlevs(HSEC,zetasec,theta_s,theta_b,hc,N,'r',vtransform) # # Get the horizontal positions # dx=0.*lonsec for i in np.arange(1,Npts): dx[i]=1e-3*tpx.spheric_dist(latsec[i-1],latsec[i],lonsec[i-1],lonsec[i]) dist=np.cumsum(dx) X=np.matlib.repmat(dist,N,1) LON=np.matlib.repmat(lonsec,N,1) LAT=np.matlib.repmat(latsec,N,1) return LON,LAT,X,Z,Un,Ut
def get_section(lonsec,latsec,var,lon,lat,rmask,h,zeta,theta_s,theta_b,hc,N,vtransform): # # Extract a vertical slice in any direction (or along a curve) # from a ROMS netcdf file. # # # On Input: # # lonsec Longitudes of the points of the section. # latsec Latitudes of the points of the section. # var CROCO 3D variable at rho point # lon Longitudes at rho points # lat Latitudes at rho points # rmask # h # zeta # theta_s # theta_b # hc # N # vtransform # # # On Output:LON,LAT,X,Z,VAR # # LON Longitudes of the section (2D matrix). # LAT Latitudes of the section (2D matrix). # X Slice X-distances (km) from the first point (2D matrix). # Z Slice Z-positions (matrix). # VAR Slice of the variable (matrix). # # Npts=np.size(lonsec) # # Get a first subgrid limited by the size of the section (extended by twice the resolution dl) # (dlony,dlonx)=np.gradient(lon) (dlaty,dlatx)=np.gradient(lat) dl=2*np.max((np.max(np.abs(dlonx)),np.max(np.abs(dlony)),np.max(np.abs(dlatx)),np.max(np.abs(dlaty)))) print(dl) minlon=np.min(lonsec)-dl minlat=np.min(latsec)-dl maxlon=np.max(lonsec)+dl maxlat=np.max(latsec)+dl sub=( (lon>minlon) & (lon<maxlon) & (lat>minlat) & (lat<maxlat) ) (jndx,indx)=np.where(sub) imin=np.min(indx) imax=np.max(indx) jmin=np.min(jndx) jmax=np.max(jndx) lon=lon[jmin:jmax,imin:imax] lat=lat[jmin:jmax,imin:imax] zeta=zeta[jmin:jmax,imin:imax] h=h[jmin:jmax,imin:imax] rmask=rmask[jmin:jmax,imin:imax] var=var[:,jmin:jmax,imin:imax] masksec=np.nan+0*lonsec zetasec=np.nan+0*lonsec HSEC=np.nan+0*lonsec VAR=np.nan+np.zeros((N,Npts)) # # Do an interpolation for each point of the section # for i in np.arange(0,Npts): # # Get a subgrid around each point # sub=( (lon>lonsec[i]-dl) & (lon<lonsec[i]+dl) & \ (lat>latsec[i]-dl) & (lat<latsec[i]+dl) ) (jndx,indx)=np.where(sub) imin=np.min(indx) imax=np.max(indx) jmin=np.min(jndx) jmax=np.max(jndx) londata=lon[jmin:jmax,imin:imax].ravel() latdata=lat[jmin:jmax,imin:imax].ravel() maskdata=rmask[jmin:jmax,imin:imax].ravel() zetadata=zeta[jmin:jmax,imin:imax].ravel() hdata=h[jmin:jmax,imin:imax].ravel() # # Get the mask as nearest point # masksec[i]=griddata((londata,latdata),maskdata, (lonsec[i], latsec[i]), method='nearest') # # If there is enough data, do the interpolation # isgood=np.where(np.isfinite(zetadata)) if np.size(isgood)>4: zetasec[i]=griddata((londata[isgood],latdata[isgood]),zetadata[isgood], (lonsec[i], latsec[i]), method='cubic') HSEC[i]=griddata((londata[isgood],latdata[isgood]),hdata[isgood], (lonsec[i], latsec[i]), method='cubic') for k in np.arange(0,N): vdata=var[k,jmin:jmax,imin:imax].ravel() VAR[k,i]=griddata((londata[isgood],latdata[isgood]),vdata[isgood], (lonsec[i], latsec[i]), method='cubic') # # Get the vertical positions # zetasec[np.where(np.isnan(zetasec))]=0. HSEC[np.where(np.isnan(HSEC))]=hc Z=vgrd.zlevs(HSEC,zetasec,theta_s,theta_b,hc,N,'r',vtransform) # # Get the horizontal positions # # Get the horizontal positions # dx=0.*lonsec for i in np.arange(1,Npts): dx[i]=1e-3*tpx.spheric_dist(latsec[i-1],latsec[i],lonsec[i-1],lonsec[i]) dist=np.cumsum(dx) X=np.matlib.repmat(dist,N,1) LON=np.matlib.repmat(lonsec,N,1) LAT=np.matlib.repmat(latsec,N,1) return LON,LAT,X,Z,VAR