def cellWidthVsLatLon(): lat = np.arange(-90, 90.01, 0.1) lon = np.arange(-180, 180.01, 0.1) QU1 = np.ones(lat.size) EC60to30 = mdt.EC_CellWidthVsLat(lat) RRS30to10 = mdt.RRS_CellWidthVsLat(lat, 30, 10) AtlNH = RRS30to10 AtlGrid = mdt.mergeCellWidthVsLat(lat, EC60to30, AtlNH, 0, 6) PacNH = mdt.mergeCellWidthVsLat(lat, 30 * QU1, RRS30to10, 50, 10) PacGrid = mdt.mergeCellWidthVsLat(lat, EC60to30, PacNH, 0, 6) cellWidth = mdt.AtlanticPacificGrid(lat, lon, AtlGrid, PacGrid) import matplotlib.pyplot as plt import matplotlib matplotlib.use('Agg') plt.clf() plt.plot(lat, AtlGrid, label='Atlantic') plt.plot(lat, PacGrid, label='Pacific') plt.grid(True) plt.xlabel('latitude') plt.title('Grid cell size, km') plt.legend() plt.savefig('cellWidthVsLat.png') return cellWidth, lon, lat
def cellWidthVsLatLon(): lat = np.arange(-90, 90.01, 0.1) lon = np.arange(-180, 180.01, 10.0) cellWidthVsLat = mdt.EC_CellWidthVsLat(lat) cellWidth = np.outer(cellWidthVsLat, np.ones([1, lon.size])) return cellWidth, lon, lat
def create_background_mesh( grd_box, ddeg, mesh_type, dx_min, dx_max, # {{{ plot_option=False, plot_box=[], call=None): print("Create background mesh") print("------------------------") # Create cell width background grid lat_grd = np.arange(grd_box[2], grd_box[3], ddeg) lon_grd = np.arange(grd_box[0], grd_box[1], ddeg) nx_grd = lon_grd.size ny_grd = lat_grd.size print(" Background grid dimensions:", ny_grd, nx_grd) # Assign background grid cell width values if mesh_type == 'QU': cell_width_lat = dx_max / km * np.ones(lat_grd.size) elif mesh_type == 'EC': cell_width_lat = mdt.EC_CellWidthVsLat(lat_grd) elif mesh_type == 'RRS': cell_width_lat = mdt.RRS_CellWidthVsLat(lat_grd, dx_max / km, dx_min / km) cell_width = np.tile(cell_width_lat, (nx_grd, 1)).T * km # Plot background cell width if plot_option: print(" Plotting background cell width") plt.figure() plt.plot(lat_grd, cell_width_lat) plt.savefig('bckgrnd_grid_cell_width_vs_lat' + str(call) + '.png') fig = plt.figure() ax = fig.add_subplot(1, 1, 1, projection=ccrs.PlateCarree()) plt.contourf(lon_grd, lat_grd, cell_width, transform=ccrs.PlateCarree()) plot_coarse_coast(ax, plot_box) plt.colorbar() plt.savefig('bckgnd_grid_cell_width' + str(call) + '.png', bbox_inches='tight') plt.close() print(" Done") return (lon_grd, lat_grd, cell_width) # }}}
def cellWidthVsLatLon(): lat = np.arange(-90, 90.01, 0.1) # Note that longitude step is 10 degrees, but should only be used if mesh does not # vary with longitude. Otherwise, set to 0.1 degrees. lon = np.arange(-180, 180.01, 10.0) # define uniform distributions cellWidth10 = 10.0 * np.ones(lat.size) cellWidth30 = 30.0 * np.ones(lat.size) # Southern transition latTransition = -48.0 latWidthTransition = 10.0 cellWidthSouth = mdt.mergeCellWidthVsLat( lat, cellWidth10, cellWidth30, latTransition, latWidthTransition) # Transition at Equator cellWidthNorth = mdt.EC_CellWidthVsLat(lat) latTransition = 0.0 latWidthTransition = 5.0 cellWidthVsLat = mdt.mergeCellWidthVsLat( lat, cellWidthSouth, cellWidthNorth, latTransition, latWidthTransition) # Uncomment to plot the cell size distribution. #plt.plot(lat,cellWidthVsLat) #plt.grid(True) #plt.xlabel('latitude') #plt.ylabel('grid cell size') #plt.title('SO60to10wISC, transition at 55S') #plt.savefig('cellWidthVsLat.pdf') #plt.savefig('cellWidthVsLat.png') cellWidth = np.ones((lat.size, lon.size)) for i in range(lon.size): cellWidth[:, i] = cellWidthVsLat return cellWidth, lon, lat
def cellWidthVsLatLon(): """ Create cell width array for this mesh on a regular latitude-longitude grid. Returns ------- cellWidth : numpy.ndarray m x n array, entries are desired cell width in km lat : numpy.ndarray latitude, vector of length m, with entries between -90 and 90, degrees lon : numpy.ndarray longitude, vector of length n, with entries between -180 and 180, degrees """ dlon = 0.1 dlat = dlon nlon = int(360. / dlon) + 1 nlat = int(180. / dlat) + 1 lon = np.linspace(-180., 180., nlon) lat = np.linspace(-90., 90., nlat) cellWidthSouth = 30. * np.ones((len(lat))) # Transition at Equator cellWidthNorth = mdt.EC_CellWidthVsLat(lat) latTransition = 0.0 latWidthTransition = 5.0 cellWidthVsLat = mdt.mergeCellWidthVsLat(lat, cellWidthSouth, cellWidthNorth, latTransition, latWidthTransition) _, cellWidth = np.meshgrid(lon, cellWidthVsLat) # now, add the high-res region fc = read_feature_collection('high_res_region.geojson') signed_distance = signed_distance_from_geojson(fc, lon, lat, max_length=0.25) da = xarray.DataArray(signed_distance, dims=['y', 'x'], coords={ 'y': lat, 'x': lon }, name='signed_distance') cw_filename = 'signed_distance.nc' da.to_netcdf(cw_filename) # multiply by 5 because transition_width gets multiplied by 0.2 in # compute_cell_width # Equivalent to 10 degrees latitude trans_width = 5 * 1100e3 # The last term compensates for the offset in compute_cell_width. # The middle of the transition is ~2.5 degrees (300 km) south of the # region boundary to best match previous transition at 48 S. (The mean lat # of the boundary is 45.5 S.) trans_start = -300e3 - 0.5 * trans_width dx_min = 10. cellWidth = compute_cell_width(signed_distance, cellWidth, lon, lat, dx_min, trans_start, trans_width, restrict_box={ 'include': [], 'exclude': [] }) # Uncomment to plot the cell size distribution. # Lon, Lat = np.meshgrid(lon, lat) # ax = plt.subplot(111) # plt.pcolormesh(Lon, Lat, cellWidth) # plt.colorbar() # ax.set_aspect('equal') # ax.autoscale(tight=True) # plt.tight_layout() # plt.savefig('cellWidthVsLat.png', dpi=200) return cellWidth, lon, lat
def cellWidthVsLatLon(): """ Create cell width array for this mesh on a regular latitude-longitude grid. Returns ------- cellWidth : numpy.ndarray m x n array, entries are desired cell width in km lat : numpy.ndarray latitude, vector of length m, with entries between -90 and 90, degrees lon : numpy.ndarray longitude, vector of length n, with entries between -180 and 180, degrees """ # To speed up for testing, set following line to 1.0 degrees dlon = 1.0 dlat = dlon nlon = int(360. / dlon) + 1 nlat = int(180. / dlat) + 1 lon = np.linspace(-180., 180., nlon) lat = np.linspace(-90., 90., nlat) # Create cell width vs latitude for Atlantic and Pacific basins QU1 = np.ones(lat.size) EC60to30 = mdt.EC_CellWidthVsLat(lat) RRS30to10 = mdt.RRS_CellWidthVsLat(lat, 30, 10) AtlNH = RRS30to10 AtlVsLat = mdt.mergeCellWidthVsLat(lat, EC60to30, AtlNH, 0, 6) PacNH = mdt.mergeCellWidthVsLat(lat, 30 * QU1, RRS30to10, 50, 10) PacVsLat = mdt.mergeCellWidthVsLat(lat, EC60to30, PacNH, 0, 6) # Expand from 1D to 2D _, AtlGrid = np.meshgrid(lon, AtlVsLat) _, PacGrid = np.meshgrid(lon, PacVsLat) # Signed distance of Atlantic region fc = read_feature_collection('Atlantic_region.geojson') signedDistance = signed_distance_from_geojson(fc, lon, lat, max_length=0.25) # Merge Atlantic and Pacific distrubutions smoothly transitionWidth = 500.0e3 # [m] maskSmooth = 0.5 * (1 + np.tanh(signedDistance / transitionWidth)) cellWidthSmooth = PacGrid * maskSmooth + AtlGrid * (1 - maskSmooth) # Merge Atlantic and Pacific distrubutions with step function maskSharp = 0.5 * (1 + np.sign(signedDistance)) cellWidthSharp = PacGrid * maskSharp + AtlGrid * (1 - maskSharp) # Create a land mask that is 1 over land fc = read_feature_collection('Americas_land_mask.geojson') Americas_land_mask = mask_from_geojson(fc, lon, lat) fc = read_feature_collection('Europe_Africa_land_mask.geojson') Europe_Africa_land_mask = mask_from_geojson(fc, lon, lat) landMask = np.fmax(Americas_land_mask, Europe_Africa_land_mask) # Merge: step transition over land, smooth transition over water cellWidth = cellWidthSharp * landMask + cellWidthSmooth * (1 - landMask) # save signed distance to a file # da = xarray.DataArray(signedDistance, # dims=['y', 'x'], # coords={'y': lat, 'x': lon}, # name='signedDistance') #cw_filename = 'signedDistance.nc' # da.to_netcdf(cw_filename) print('plotting ...') fig = plt.figure() plt.clf() fig.set_size_inches(10.0, 10.0) ax = plt.subplot(4, 2, 1) ax.plot(lat, AtlVsLat, label='Atlantic') ax.plot(lat, PacVsLat, label='Pacific') ax.grid(True) plt.title('Grid cell size [km] versus latitude') plt.legend() varNames = [ 'signedDistance', 'maskSmooth', 'cellWidthSmooth', 'maskSharp', 'cellWidthSharp', 'landMask', 'cellWidth' ] j = 2 for varName in varNames: plot_cartopy(j, varName, vars()[varName]) j += 1 plt.savefig('mesh_construction.png') return cellWidth, lon, lat
def cellWidthVsLatLon(): """ Create cell width array for this mesh on a regular latitude-longitude grid. Returns ------- cellWidth : numpy.ndarray m x n array, entries are desired cell width in km lat : numpy.ndarray latitude, vector of length m, with entries between -90 and 90, degrees lon : numpy.ndarray longitude, vector of length n, with entries between -180 and 180, degrees """ # To speed up for testing, set following line to 1.0 degrees dlon = 0.1 dlat = dlon print( '\nCreating cellWidth on a lat-lon grid of: {0:.2f} x {0:.2f} degrees'. format(dlon, dlat)) print('This can be set higher for faster test generation\n') nlon = int(360. / dlon) + 1 nlat = int(180. / dlat) + 1 lon = np.linspace(-180., 180., nlon) lat = np.linspace(-90., 90., nlat) km = 1.0e3 print('plotting ...') fig = plt.figure() plt.clf() fig.set_size_inches(10.0, 14.0) mdt.register_sci_viz_colormaps() #cmapBluesHalf = truncate_colormap(cmapIn='Blues', minval=0.0, maxval=0.7) # Create cell width vs latitude for Atlantic and Pacific basins QU1 = np.ones(lat.size) EC60to30 = mdt.EC_CellWidthVsLat(lat) EC60to30Narrow = mdt.EC_CellWidthVsLat(lat, latPosEq=8.0, latWidthEq=3.0) # Expand from 1D to 2D _, cellWidth = np.meshgrid(lon, EC60to30Narrow) plot_cartopy(2, 'narrow EC60to30', cellWidth, '3Wbgy5') plotFrame = 3 # global settings for regionally refines mesh highRes = 14.0 #[km] fileName = 'region_Central_America' transitionWidth = 800.0 * km transitionOffset = 0.0 fc = read_feature_collection('{}.geojson'.format(fileName)) signedDistance = signed_distance_from_geojson(fc, lon, lat, max_length=0.25) mask = 0.5 * (1 + np.tanh( (transitionOffset - signedDistance) / (transitionWidth / 2.))) cellWidth = 30.0 * mask + cellWidth * (1 - mask) fileName = 'coastline_CUSP' distanceToTransition = 600.0 * km # transitionWidth is distance from 0.07 to 0.03 of transition within tanh transitionWidth = 600.0 * km transitionOffset = distanceToTransition + transitionWidth / 2.0 fc = read_feature_collection('{}.geojson'.format(fileName)) signedDistance = signed_distance_from_geojson(fc, lon, lat, max_length=0.25) mask = 0.5 * (1 + np.tanh( (transitionOffset - signedDistance) / (transitionWidth / 2.))) cellWidth = highRes * mask + cellWidth * (1 - mask) plot_cartopy(plotFrame, fileName + ' mask', mask, 'Blues') plot_cartopy(plotFrame + 1, 'cellWidth ', cellWidth, '3Wbgy5') plotFrame += 2 fileName = 'region_Gulf_of_Mexico' transitionOffset = 600.0 * km transitionWidth = 600.0 * km fc = read_feature_collection('{}.geojson'.format(fileName)) signedDistance = signed_distance_from_geojson(fc, lon, lat, max_length=0.25) maskSmooth = 0.5 * (1 + np.tanh( (transitionOffset - signedDistance) / (transitionWidth / 2.))) maskSharp = 0.5 * (1 + np.sign(-signedDistance)) fc = read_feature_collection('land_mask_Mexico.geojson') signedDistance = signed_distance_from_geojson(fc, lon, lat, max_length=0.25) landMask = 0.5 * (1 + np.sign(-signedDistance)) mask = maskSharp * landMask + maskSmooth * (1 - landMask) cellWidth = highRes * mask + cellWidth * (1 - mask) plot_cartopy(plotFrame, fileName + ' mask', mask, 'Blues') plot_cartopy(plotFrame + 1, 'cellWidth ', cellWidth, '3Wbgy5') plotFrame += 2 fileName = 'region_Bering_Sea' transitionOffset = 0.0 * km transitionWidth = 600.0 * km fc = read_feature_collection('{}.geojson'.format(fileName)) signedDistance = signed_distance_from_geojson(fc, lon, lat, max_length=0.25) maskSmooth = 0.5 * (1 + np.tanh( (transitionOffset - signedDistance) / (transitionWidth / 2.))) maskSharp = 0.5 * (1 + np.sign(-signedDistance)) fc = read_feature_collection('land_mask_Kamchatka.geojson') signedDistance = signed_distance_from_geojson(fc, lon, lat, max_length=0.25) landMask = 0.5 * (1 + np.sign(-signedDistance)) mask = maskSharp * landMask + maskSmooth * (1 - landMask) cellWidth = highRes * mask + cellWidth * (1 - mask) plot_cartopy(plotFrame, fileName + ' mask', mask, 'Blues') plot_cartopy(plotFrame + 1, 'cellWidth ', cellWidth, '3Wbgy5') plotFrame += 2 fileName = 'region_Arctic_Ocean' transitionOffset = 0.0 * km transitionWidth = 600.0 * km fc = read_feature_collection('{}.geojson'.format(fileName)) signedDistance = signed_distance_from_geojson(fc, lon, lat, max_length=0.25) mask = 0.5 * (1 + np.tanh( (transitionOffset - signedDistance) / (transitionWidth / 2.))) cellWidth = highRes * mask + cellWidth * (1 - mask) plot_cartopy(plotFrame, fileName + ' mask', mask, 'Blues') plot_cartopy(plotFrame + 1, 'cellWidth ', cellWidth, '3Wbgy5') plotFrame += 2 fileName = 'region_Gulf_Stream_extension' transitionOffset = 0.0 * km transitionWidth = 600.0 * km fc = read_feature_collection('{}.geojson'.format(fileName)) signedDistance = signed_distance_from_geojson(fc, lon, lat, max_length=0.25) mask = 0.5 * (1 + np.tanh( (transitionOffset - signedDistance) / (transitionWidth / 2.))) cellWidth = highRes * mask + cellWidth * (1 - mask) plot_cartopy(plotFrame, fileName + ' mask', mask, 'Blues') plot_cartopy(plotFrame + 1, 'cellWidth ', cellWidth, '3Wbgy5') plotFrame += 2 # save signed distance to a file # da = xarray.DataArray(signedDistance, # dims=['y', 'x'], # coords={'y': lat, 'x': lon}, # name='signedDistance') #cw_filename = 'signedDistance.nc' # da.to_netcdf(cw_filename) ax = plt.subplot(6, 2, 1) ax.plot(lat, EC60to30, label='original EC60to30') ax.plot(lat, EC60to30Narrow, label='narrow EC60to30') ax.grid(True) plt.title('Grid cell size [km] versus latitude') plt.legend(loc="upper left") plt.savefig('mesh_construction.png') return cellWidth, lon, lat
def cellWidthVsLatLon(): """ Create cell width array for this mesh on a regular latitude-longitude grid. Returns ------- cellWidth : numpy.ndarray m x n array, entries are desired cell width in km lat : numpy.ndarray latitude, vector of length m, with entries between -90 and 90, degrees lon : numpy.ndarray longitude, vector of length n, with entries between -180 and 180, degrees """ dlon = 0.1 dlat = dlon nlon = int(360. / dlon) + 1 nlat = int(180. / dlat) + 1 lon = np.linspace(-180., 180., nlon) lat = np.linspace(-90., 90., nlat) cellWidthSouth = mdt.EC_CellWidthVsLat(lat, cellWidthEq=30., cellWidthMidLat=45., cellWidthPole=45., latPosEq=7.5, latWidthEq=3.0) # Transition at Equator cellWidthNorth = mdt.EC_CellWidthVsLat(lat, cellWidthEq=30., cellWidthMidLat=60., cellWidthPole=60., latPosEq=7.5, latWidthEq=3.0) latTransition = 0.0 latWidthTransition = 2.5 cellWidthVsLat = mdt.mergeCellWidthVsLat(lat, cellWidthSouth, cellWidthNorth, latTransition, latWidthTransition) _, cellWidth = np.meshgrid(lon, cellWidthVsLat) # now, add the high-res region fc = read_feature_collection('high_res_region.geojson') so_signed_distance = signed_distance_from_geojson(fc, lon, lat, max_length=0.25) # Equivalent to 20 degrees latitude trans_width = 1600e3 trans_start = -500e3 dx_min = 12. weights = 0.5 * (1 + np.tanh( (so_signed_distance - trans_start) / trans_width)) cellWidth = dx_min * (1 - weights) + cellWidth * weights fc = read_feature_collection('north_mid_res_region.geojson') ar_signed_distance = signed_distance_from_geojson(fc, lon, lat, max_length=0.25) fc = read_feature_collection('greenland.geojson') gr_signed_distance = signed_distance_from_geojson(fc, lon, lat, max_length=0.25) frac = (-ar_signed_distance / (-ar_signed_distance + gr_signed_distance)) frac = np.maximum(0., np.minimum(1., frac)) dx_min = 15. dx_max = 35. arctic_widths = dx_max + (dx_min - dx_max) * frac trans_width = 1000e3 trans_start = 0. weights = 0.5 * (1 + np.tanh( (ar_signed_distance - trans_start) / trans_width)) cellWidth = arctic_widths * (1 - weights) + cellWidth * weights # fig, (ax1, ax2) = plt.subplots(1, 2, figsize=[12, 4.5]) # index = np.argmin(np.abs(lon - (-30.5))) # ax1.plot(lat, cellWidth[:, index]) # ax1.set_ylim([12., 60.]) # ax1.set_title('lon = {}'.format(lon[index])) # index = np.argmin(np.abs(lon - (179.5))) # ax2.plot(lat, cellWidth[:, index]) # ax2.set_ylim([12., 60.]) # ax2.set_title('lon = {}'.format(lon[index])) # plt.tight_layout() # plt.savefig('res_vs_lat.png', dpi=200) # # fig, ax1 = plt.subplots(1, 1, figsize=[6, 4.5]) # index = np.argmin(np.abs(lon - (-62.5))) # ax1.plot(lat, cellWidth[:, index]) # ax1.set_ylim([12., 60.]) # ax1.set_title('Drake Passage lon = {}'.format(lon[index])) # plt.tight_layout() # plt.savefig('drake_res_vs_lat.png', dpi=200) return cellWidth, lon, lat