[4147] | 1 | # -*- Mode: python -*- |
---|
[4151] | 2 | ### =========================================================================== |
---|
| 3 | ### |
---|
| 4 | ### Compute runoff weights. |
---|
| 5 | ### For LMDZ only. Not suitable for DYNAMICO |
---|
| 6 | ### |
---|
| 7 | ### =========================================================================== |
---|
| 8 | ## |
---|
| 9 | ## Warning, to install, configure, run, use any of Olivier Marti's |
---|
| 10 | ## software or to read the associated documentation you'll need at least |
---|
| 11 | ## one (1) brain in a reasonably working order. Lack of this implement |
---|
| 12 | ## will void any warranties (either express or implied). |
---|
| 13 | ## O. Marti assumes no responsability for errors, omissions, |
---|
| 14 | ## data loss, or any other consequences caused directly or indirectly by |
---|
| 15 | ## the usage of his software by incorrectly or partially configured |
---|
| 16 | ## personal. |
---|
| 17 | ## |
---|
| 18 | # SVN information |
---|
| 19 | __Author__ = "$Author$" |
---|
| 20 | __Date__ = "$Date$" |
---|
| 21 | __Revision__ = "$Revision$" |
---|
| 22 | __Id__ = "$Id$" |
---|
| 23 | __HeadURL__ = "$HeadURL$" |
---|
| 24 | __SVN_Date__ = "$SVN_Date: $" |
---|
| 25 | ## |
---|
| 26 | |
---|
[4172] | 27 | ## Modules |
---|
[4147] | 28 | import netCDF4 |
---|
| 29 | import numpy as np |
---|
| 30 | import nemo |
---|
| 31 | from scipy import ndimage |
---|
| 32 | import sys, os, platform, argparse, textwrap, time |
---|
| 33 | |
---|
[4151] | 34 | ## Userful constants |
---|
[4172] | 35 | zero = np.dtype('float64').type(0.0) |
---|
| 36 | zone = np.dtype('float64').type(1.0) |
---|
[4147] | 37 | epsfrac = np.dtype('float64').type(1.0E-10) |
---|
[4172] | 38 | pi = np.pi |
---|
[4186] | 39 | rad = pi/np.dtype('float64').type(180.0) # Conversion from degrees to radian |
---|
[4172] | 40 | ra = np.dtype('float64').type(6371229.0) # Earth radius |
---|
[4147] | 41 | |
---|
[4151] | 42 | ## Functions |
---|
[4147] | 43 | def geodist (plon1, plat1, plon2, plat2) : |
---|
| 44 | """Distance between two points (on sphere)""" |
---|
| 45 | zs = np.sin (rad*plat1) * np.sin (rad*plat2) + np.cos (rad*plat1) * np.cos (rad*plat2) * np.cos(rad*(plon2-plon1)) |
---|
| 46 | zs = np.maximum (-zone, np.minimum (zone, zs)) |
---|
| 47 | geodist = np.arccos (zs) |
---|
| 48 | return geodist |
---|
| 49 | |
---|
[4151] | 50 | ### ===== Reading command line parameters ================================================== |
---|
[4147] | 51 | # Creating a parser |
---|
| 52 | parser = argparse.ArgumentParser ( |
---|
| 53 | description = """Compute calving weights""", |
---|
[4151] | 54 | epilog='-------- End of the help message --------') |
---|
[4147] | 55 | |
---|
| 56 | # Adding arguments |
---|
[4172] | 57 | parser.add_argument ('--oce' , help='oce model name', type=str, default='eORCA1.2', choices=['ORCA2.3', 'eORCA1.2', 'eORCA025'] ) |
---|
[4186] | 58 | parser.add_argument ('--atm' , help='atm model name', type=str, default='LMD9695' ) |
---|
[4172] | 59 | parser.add_argument ('--atmCoastWidth', help='width of the coastal band in atmosphere (in grid points)', type=int, default=1 ) |
---|
| 60 | parser.add_argument ('--oceCoastWidth', help='width of the coastal band in ocean (in grid points)' , type=int, default=2 ) |
---|
[4186] | 61 | parser.add_argument ('--atmQuantity' , help='Quantity if atm provides quantities (m/s), Surfacic if atm provided flux (m/s/m2)' , type=str, default='Quantity', choices=['Quantity', 'Surfacic'] ) |
---|
| 62 | parser.add_argument ('--oceQuantity' , help='Quantity if oce requires quantities (ks/s), Surfacic if oce requires flux (m/s/m2)' , type=str, default='Surfacic', choices=['Quantity', 'Surfacic'] ) |
---|
| 63 | parser.add_argument ('--searchRadius' , help='max distance to connect a land point to an ocean point (in km)', type=float, default=600.0 ) |
---|
[4172] | 64 | parser.add_argument ('--grids' , help='grids file name', default='grids.nc' ) |
---|
| 65 | parser.add_argument ('--areas' , help='masks file name', default='areas.nc' ) |
---|
| 66 | parser.add_argument ('--masks' , help='areas file name', default='masks.nc' ) |
---|
| 67 | parser.add_argument ('--o2a' , help='o2a file name' , default='o2a.nc' ) |
---|
| 68 | parser.add_argument ('--output', help='output rmp file name', default='rmp_tlmd_to_torc_runoff_64bit.nc' ) |
---|
| 69 | parser.add_argument ('--fmt' , help='NetCDF file format, using nco syntax', default='64bit', choices=['classic', 'netcdf3', '64bit', '64bit_data', '64bit_data', 'netcdf4', 'netcdf4_classsic'] ) |
---|
[4147] | 70 | |
---|
| 71 | # Parse command line |
---|
| 72 | myargs = parser.parse_args() |
---|
| 73 | |
---|
| 74 | # |
---|
| 75 | grids = myargs.grids |
---|
| 76 | areas = myargs.areas |
---|
| 77 | masks = myargs.masks |
---|
| 78 | o2a = myargs.o2a |
---|
| 79 | |
---|
| 80 | # Model Names |
---|
| 81 | atm_Name = myargs.atm |
---|
| 82 | oce_Name = myargs.oce |
---|
[4151] | 83 | # Width of the coastal band (land points) in the atmopshere |
---|
[4147] | 84 | atmCoastWidth = myargs.atmCoastWidth |
---|
[4151] | 85 | # Width of the coastal band (ocean points) in the ocean |
---|
[4147] | 86 | oceCoastWidth = myargs.oceCoastWidth |
---|
[4172] | 87 | searchRadius = myargs.searchRadius * 1000.0 # From km to meters |
---|
| 88 | # Netcdf format |
---|
| 89 | if myargs.fmt == 'classic' : FmtNetcdf = 'CLASSIC' |
---|
| 90 | if myargs.fmt == 'netcdf3' : FmtNetcdf = 'CLASSIC' |
---|
| 91 | if myargs.fmt == '64bit' : FmtNetcdf = 'NETCDF3_64BIT_OFFSET' |
---|
| 92 | if myargs.fmt == '64bit_data' : FmtNetcdf = 'NETCDF3_64BIT_DATA' |
---|
| 93 | if myargs.fmt == '64bit_offset' : FmtNetcdf = 'NETCDF3_64BIT_OFFSET' |
---|
| 94 | if myargs.fmt == 'netcdf4' : FmtNetcdf = 'NETCDF4' |
---|
| 95 | if myargs.fmt == 'netcdf4_classic' : FmtNetcdf = 'NETCDF4_CLASSIC' |
---|
[4147] | 96 | |
---|
[4186] | 97 | # |
---|
| 98 | if atm_Name.find('LMD') >= 0 : atm_n = 'lmd' ; atmDomainType = 'rectilinear' |
---|
| 99 | if atm_Name.find('ICO') >= 0 : atm_n = 'ico' ; atmDomainType = 'unstructured' |
---|
| 100 | |
---|
| 101 | print ('atmQuantity : ' + str (myargs.atmQuantity) ) |
---|
| 102 | print ('oceQuantity : ' + str (myargs.oceQuantity) ) |
---|
| 103 | |
---|
[4147] | 104 | ### Read coordinates of all models |
---|
| 105 | ### |
---|
| 106 | |
---|
| 107 | diaFile = netCDF4.Dataset ( o2a ) |
---|
| 108 | gridFile = netCDF4.Dataset ( grids ) |
---|
| 109 | areaFile = netCDF4.Dataset ( areas ) |
---|
| 110 | maskFile = netCDF4.Dataset ( masks ) |
---|
| 111 | |
---|
[4172] | 112 | o2aFrac = diaFile ['OceFrac'][:].squeeze() |
---|
[4147] | 113 | o2aFrac = np.where ( np.abs(o2aFrac) < 1E10, o2aFrac, 0.0) |
---|
| 114 | |
---|
[4186] | 115 | (atm_nvertex, atm_jpj, atm_jpi) = gridFile['t'+atm_n+'.clo'][:].shape |
---|
| 116 | atm_grid_size = atm_jpj*atm_jpi |
---|
| 117 | atm_grid_rank = len(gridFile['t'+atm_n+'.lat'][:].shape) |
---|
[4147] | 118 | |
---|
[4186] | 119 | atm_grid_center_lat = gridFile['t'+atm_n+'.lat'][:].ravel() |
---|
| 120 | atm_grid_center_lon = gridFile['t'+atm_n+'.lon'][:].ravel() |
---|
| 121 | atm_grid_corner_lat = np.reshape ( gridFile['t'+atm_n+'.cla'][:], (atm_nvertex, atm_grid_size) ) |
---|
| 122 | atm_grid_corner_lon = np.reshape ( gridFile['t'+atm_n+'.clo'][:], (atm_nvertex, atm_grid_size) ) |
---|
| 123 | atm_grid_area = areaFile['t'+atm_n+'.srf'][:].ravel() |
---|
| 124 | atm_grid_imask = 1-maskFile['t'+atm_n+'.msk'][:].squeeze().ravel() |
---|
| 125 | atm_grid_dims = gridFile['t'+atm_n+'.lat'][:].shape |
---|
| 126 | |
---|
[4151] | 127 | atm_perio = 0 |
---|
[4186] | 128 | atm_grid_pmask = atm_grid_imask |
---|
| 129 | atm_address = np.arange(atm_jpj*atm_jpi) |
---|
[4147] | 130 | |
---|
[4186] | 131 | |
---|
| 132 | (oce_nvertex, oce_jpj, oce_jpi) = gridFile['torc.cla'][:].shape ; jpon=oce_jpj*oce_jpj |
---|
| 133 | oce_grid_size = oce_jpj*oce_jpi |
---|
| 134 | oce_grid_rank = len(gridFile['torc.lat'][:].shape) |
---|
| 135 | |
---|
| 136 | oce_grid_center_lat = gridFile['torc.lat'][:].ravel() |
---|
| 137 | oce_grid_center_lon = gridFile['torc.lon'][:].ravel() |
---|
| 138 | oce_grid_corner_lat = np.reshape( gridFile['torc.cla'][:], (oce_nvertex, oce_grid_size) ) |
---|
| 139 | oce_grid_corner_lon = np.reshape( gridFile['torc.clo'][:], (oce_nvertex, oce_grid_size) ) |
---|
| 140 | oce_grid_area = areaFile['torc.srf'][:].ravel() |
---|
| 141 | oce_grid_imask = 1-maskFile['torc.msk'][:].ravel() |
---|
| 142 | oce_grid_dims = gridFile['torc.lat'][:].shape |
---|
[4147] | 143 | if oce_jpi == 182 : oce_perio = 4 # ORCA 2 |
---|
| 144 | if oce_jpi == 362 : oce_perio = 6 # ORCA 1 |
---|
| 145 | if oce_jpi == 1442 : oce_perio = 6 # ORCA 025 |
---|
[4186] | 146 | oce_grid_pmask = nemo.lbc_mask (np.reshape(oce_grid_imask, (oce_jpj,oce_jpi)), 'T', oce_perio).ravel() |
---|
| 147 | oce_address = np.arange(oce_jpj*oce_jpi) |
---|
[4147] | 148 | |
---|
[4151] | 149 | ## Fill closed sea with image processing library |
---|
[4186] | 150 | oce_grid_imask2D = np.reshape(oce_grid_pmask,(oce_jpj,oce_jpi)) |
---|
| 151 | oce_grid_imask2D = nemo.lbc_mask ( 1-ndimage.binary_fill_holes (1-nemo.lbc(oce_grid_imask2D, nperio=oce_perio, cd_type='T')), nperio=oce_perio, cd_type='T' ) |
---|
| 152 | oce_grid_imask = oce_grid_imask2D.ravel() |
---|
[4151] | 153 | ## |
---|
[4147] | 154 | print ("Determination d'une bande cotiere ocean") |
---|
| 155 | |
---|
[4186] | 156 | oceLand2D = np.reshape ( np.where (oce_grid_pmask[:] < 0.5, True, False), (oce_jpj, oce_jpi) ) |
---|
| 157 | oceOcean2D = np.reshape ( np.where (oce_grid_pmask[:] > 0.5, True, False), (oce_jpj, oce_jpi) ) |
---|
[4147] | 158 | |
---|
[4151] | 159 | NNocean = 1+2*oceCoastWidth |
---|
[4186] | 160 | oceOceanFiltered2D = ndimage.uniform_filter(oceOcean2D.astype(float), size=NNocean) |
---|
| 161 | oceCoast2D = np.where (oceOceanFiltered2D<(1.0-0.5/(NNocean**2)),True,False) & oceOcean2D |
---|
| 162 | oceCoast2D = nemo.lbc_mask (np.reshape(oceCoast2D,(oce_jpj,oce_jpi)), oce_perio, 'T').ravel() |
---|
[4147] | 163 | |
---|
[4186] | 164 | oceOceanFiltered = oceOceanFiltered2D.ravel() |
---|
| 165 | oceLand = oceLand2D.ravel() |
---|
| 166 | oceOcean = oceOcean2D.ravel() |
---|
| 167 | oceCoast = oceCoast2D.ravel() |
---|
| 168 | |
---|
[4151] | 169 | print ('Number of points in oceLand : ' + str(oceLand.sum()) ) |
---|
| 170 | print ('Number of points in oceOcean : ' + str(oceOcean.sum()) ) |
---|
| 171 | print ('Number of points in oceCoast : ' + str(oceCoast.sum()) ) |
---|
[4147] | 172 | |
---|
[4151] | 173 | # Arrays with coastal points only |
---|
[4147] | 174 | oceCoast_grid_center_lon = oce_grid_center_lon[oceCoast] |
---|
| 175 | oceCoast_grid_center_lat = oce_grid_center_lat[oceCoast] |
---|
| 176 | oceCoast_grid_area = oce_grid_area [oceCoast] |
---|
| 177 | oceCoast_grid_imask = oce_grid_imask [oceCoast] |
---|
| 178 | oceCoast_grid_pmask = oce_grid_pmask [oceCoast] |
---|
| 179 | oceCoast_address = oce_address [oceCoast] |
---|
| 180 | |
---|
| 181 | print ("Determination d'une bande cotiere atmosphere " ) |
---|
[4151] | 182 | atmLand = np.where (o2aFrac[:] < epsfrac , True, False) |
---|
| 183 | atmLandFrac = np.where (o2aFrac[:] < zone-epsfrac , True, False) |
---|
| 184 | atmFrac = np.where (o2aFrac[:] > epsfrac , True, False) & np.where (o2aFrac[:] < (zone-epsfrac), True, False) |
---|
| 185 | atmOcean = np.where (o2aFrac[:] < (zone-epsfrac), True, False) |
---|
| 186 | atmOceanFrac = np.where (o2aFrac[:] > epsfrac , True, False) |
---|
[4147] | 187 | |
---|
[4186] | 188 | ## La suite marche avec LMDZ seulement !! |
---|
| 189 | if atmDomainType == 'rectilinear' : |
---|
| 190 | NNatm = 1+2*atmCoastWidth |
---|
| 191 | atmLand2D = np.reshape ( atmLand, ( atm_jpj, atm_jpi) ) |
---|
[4147] | 192 | |
---|
[4186] | 193 | atmLandFiltered2D = ndimage.uniform_filter(atmLand2D.astype(float), size=NNatm) |
---|
| 194 | atmCoast2D = np.where (atmLandFiltered2D<(1.0-0.5/(NNatm**2)),True,False) & atmLandFrac |
---|
| 195 | |
---|
| 196 | atmLandFiltered = atmLandFiltered2D.ravel() |
---|
| 197 | atmCoast = atmCoast2D.ravel() |
---|
[4147] | 198 | |
---|
[4186] | 199 | print ('Number of points in atmLand : ' + str(atmLand.sum()) ) |
---|
| 200 | print ('Number of points in atmOcean : ' + str(atmOcean.sum()) ) |
---|
| 201 | print ('Number of points in atmCoast : ' + str(atmCoast.sum()) ) |
---|
| 202 | |
---|
| 203 | else : |
---|
| 204 | atmCoast = atmFrac |
---|
| 205 | |
---|
| 206 | |
---|
[4151] | 207 | # Arrays with coastal points only |
---|
[4147] | 208 | atmCoast_grid_center_lon = atm_grid_center_lon[atmCoast] |
---|
| 209 | atmCoast_grid_center_lat = atm_grid_center_lat[atmCoast] |
---|
| 210 | atmCoast_grid_area = atm_grid_area [atmCoast] |
---|
| 211 | atmCoast_grid_imask = atm_grid_imask [atmCoast] |
---|
| 212 | atmCoast_grid_pmask = atm_grid_pmask [atmCoast] |
---|
| 213 | atmCoast_address = atm_address [atmCoast] |
---|
| 214 | |
---|
[4186] | 215 | # Initialisations before the loop |
---|
[4147] | 216 | remap_matrix = np.empty ( shape=(0), dtype=np.float64 ) |
---|
| 217 | atm_address = np.empty ( shape=(0), dtype=np.int32 ) |
---|
| 218 | oce_address = np.empty ( shape=(0), dtype=np.int32 ) |
---|
| 219 | |
---|
[4151] | 220 | ## Loop on atmosphere coastal points |
---|
[4147] | 221 | for ja in np.arange(len(atmCoast_grid_pmask)) : |
---|
| 222 | z_dist = geodist ( atmCoast_grid_center_lon[ja], atmCoast_grid_center_lat[ja], oceCoast_grid_center_lon, oceCoast_grid_center_lat) |
---|
[4172] | 223 | z_mask = np.where ( z_dist*ra < searchRadius, True, False) |
---|
[4186] | 224 | num_links = np.int(z_mask.sum()) |
---|
[4147] | 225 | if num_links == 0 : continue |
---|
| 226 | z_area = oceCoast_grid_area[z_mask].sum() |
---|
[4186] | 227 | poids = np.ones ((num_links),dtype=np.float64) / z_area |
---|
| 228 | if myargs.atmQuantity == 'Surfacic' : poids = poids * atm_grid_area[ja] |
---|
| 229 | if myargs.oceQuantity == 'Quantity' : poids = poids * oceCoast_grid_area[z_mask] |
---|
| 230 | if ja % (len(atmCoast_grid_pmask)//50) == 0 : # Control print |
---|
| 231 | print ( 'ja:{:8d}, num_links:{:8d}, z_area:{:8.4e}, atm area:{:8.4e}, weights sum:{:8.4e} '.format(ja, num_links, z_area, atm_grid_area[ja], poids.sum() ) ) |
---|
[4147] | 232 | # |
---|
[4186] | 233 | matrix_local = poids |
---|
[4147] | 234 | atm_address_local = np.ones(num_links, dtype=np.int32 ) * atmCoast_address[ja] |
---|
[4186] | 235 | # Address on destination grid |
---|
[4147] | 236 | oce_address_local = oceCoast_address[z_mask] |
---|
| 237 | # Append to global tabs |
---|
| 238 | remap_matrix = np.append ( remap_matrix, matrix_local ) |
---|
| 239 | atm_address = np.append ( atm_address , atm_address_local ) |
---|
| 240 | oce_address = np.append ( oce_address , oce_address_local ) |
---|
| 241 | |
---|
[4151] | 242 | print ('End of loop') |
---|
[4147] | 243 | |
---|
| 244 | num_links = remap_matrix.shape[0] |
---|
| 245 | |
---|
[4151] | 246 | ### Output file |
---|
[4147] | 247 | runoff = myargs.output |
---|
[4172] | 248 | f_runoff = netCDF4.Dataset ( runoff, 'w', format=FmtNetcdf ) |
---|
[4147] | 249 | print ('Output file: ' + runoff ) |
---|
| 250 | |
---|
| 251 | f_runoff.Conventions = "CF-1.6" |
---|
| 252 | f_runoff.source = "IPSL Earth system model" |
---|
| 253 | f_runoff.group = "ICMC IPSL Climate Modelling Center" |
---|
| 254 | f_runoff.Institution = "IPSL https.//www.ipsl.fr" |
---|
| 255 | f_runoff.Ocean = oce_Name + " https://www.nemo-ocean.eu" |
---|
| 256 | f_runoff.Atmosphere = atm_Name + " http://lmdz.lmd.jussieu.fr" |
---|
| 257 | f_runoff.associatedFiles = grids + " " + areas + " " + masks |
---|
| 258 | f_runoff.directory = os.getcwd () |
---|
[4151] | 259 | f_runoff.description = "Generated with cotes_etal.py" |
---|
[4147] | 260 | f_runoff.title = runoff |
---|
| 261 | f_runoff.Program = "Generated by " + sys.argv[0] + " with flags " + str(sys.argv[1:]) |
---|
[4172] | 262 | f_runoff.atmCoastWidth = str(atmCoastWidth) + " grid points" |
---|
| 263 | f_runoff.oceCoastWidth = str(oceCoastWidth) + " grid points" |
---|
| 264 | f_runoff.searchRadius = str(searchRadius/1000.) + " km" |
---|
| 265 | f_runoff.gridsFile = grids |
---|
| 266 | f_runoff.areasFile = areas |
---|
| 267 | f_runoff.masksFile = masks |
---|
| 268 | f_runoff.o2aFile = o2a |
---|
[4147] | 269 | f_runoff.timeStamp = time.asctime() |
---|
| 270 | f_runoff.uuid = areaFile.uuid |
---|
| 271 | f_runoff.HOSTNAME = platform.node() |
---|
| 272 | #f_runoff.LOGNAME = os.getlogin() |
---|
| 273 | f_runoff.Python = "Python version " + platform.python_version() |
---|
| 274 | f_runoff.OS = platform.system() |
---|
| 275 | f_runoff.release = platform.release() |
---|
| 276 | f_runoff.hardware = platform.machine() |
---|
| 277 | f_runoff.conventions = "SCRIP" |
---|
| 278 | f_runoff.source_grid = "curvilinear" |
---|
| 279 | f_runoff.dest_grid = "curvilinear" |
---|
| 280 | f_runoff.Model = "IPSL CM6" |
---|
[4148] | 281 | f_runoff.SVN_Author = "$Author$" |
---|
| 282 | f_runoff.SVN_Date = "$Date$" |
---|
| 283 | f_runoff.SVN_Revision = "$Revision$" |
---|
| 284 | f_runoff.SVN_Id = "$Id$" |
---|
| 285 | f_runoff.SVN_HeadURL = "$HeadURL$" |
---|
[4147] | 286 | |
---|
[4186] | 287 | d_num_links = f_runoff.createDimension ('num_links' , num_links ) |
---|
| 288 | d_num_wgts = f_runoff.createDimension ('num_wgts' , 1 ) |
---|
[4147] | 289 | |
---|
[4172] | 290 | d_atm_grid_size = f_runoff.createDimension ('src_grid_size' , atm_grid_size ) |
---|
| 291 | d_atm_grid_corners = f_runoff.createDimension ('src_grid_corners', atm_grid_corner_lon.shape[0] ) |
---|
[4186] | 292 | d_atm_grid_rank = f_runoff.createDimension ('src_grid_rank' , atm_grid_rank ) |
---|
[4147] | 293 | |
---|
[4172] | 294 | d_oce_grid_size = f_runoff.createDimension ('dst_grid_size' , oce_grid_size ) |
---|
| 295 | d_oce_grid_corners = f_runoff.createDimension ('dst_grid_corners', oce_grid_corner_lon.shape[0] ) |
---|
[4186] | 296 | d_oce_grid_rank = f_runoff.createDimension ('dst_grid_rank' , oce_grid_rank ) |
---|
[4147] | 297 | |
---|
| 298 | v_remap_matrix = f_runoff.createVariable ( 'remap_matrix', 'f8', ('num_links', 'num_wgts') ) |
---|
| 299 | |
---|
| 300 | v_atm_address = f_runoff.createVariable ( 'src_address' , 'i4', ('num_links',) ) |
---|
| 301 | v_oce_address = f_runoff.createVariable ( 'dst_address' , 'i4', ('num_links',) ) |
---|
| 302 | |
---|
| 303 | v_remap_matrix[:] = remap_matrix |
---|
[4151] | 304 | v_atm_address [:] = atm_address + 1 # OASIS uses Fortran style indexing |
---|
| 305 | v_oce_address [:] = oce_address + 1 |
---|
[4147] | 306 | |
---|
| 307 | v_atm_grid_dims = f_runoff.createVariable ( 'src_grid_dims' , 'i4', ('src_grid_rank',) ) |
---|
| 308 | v_atm_grid_center_lon = f_runoff.createVariable ( 'src_grid_center_lon', 'i4', ('src_grid_size',) ) |
---|
| 309 | v_atm_grid_center_lat = f_runoff.createVariable ( 'src_grid_center_lat', 'i4', ('src_grid_size',) ) |
---|
| 310 | v_atm_grid_center_lon.units='degrees_east' ; v_atm_grid_center_lon.long_name='Longitude' ; v_atm_grid_center_lon.long_name='longitude' ; v_atm_grid_center_lon.bounds="src_grid_corner_lon" |
---|
| 311 | v_atm_grid_center_lat.units='degrees_north' ; v_atm_grid_center_lat.long_name='Latitude' ; v_atm_grid_center_lat.long_name='latitude ' ; v_atm_grid_center_lat.bounds="src_grid_corner_lat" |
---|
| 312 | v_atm_grid_corner_lon = f_runoff.createVariable ( 'src_grid_corner_lon', 'f8', ('src_grid_size', 'src_grid_corners') ) |
---|
| 313 | v_atm_grid_corner_lat = f_runoff.createVariable ( 'src_grid_corner_lat', 'f8', ('src_grid_size', 'src_grid_corners') ) |
---|
| 314 | v_atm_grid_corner_lon.units="degrees_east" |
---|
| 315 | v_atm_grid_corner_lat.units="degrees_north" |
---|
| 316 | v_atm_grid_area = f_runoff.createVariable ( 'src_grid_area' , 'f8', ('src_grid_size',) ) |
---|
| 317 | v_atm_grid_area.long_name="Grid area" ; v_atm_grid_area.standard_name="cell_area" ; v_atm_grid_area.units="m2" |
---|
[4151] | 318 | v_atm_grid_imask = f_runoff.createVariable ( 'src_grid_imask' , 'i4', ('src_grid_size',) ) |
---|
[4147] | 319 | v_atm_grid_imask.long_name="Land-sea mask" ; v_atm_grid_imask.units="Land:1, Ocean:0" |
---|
[4151] | 320 | v_atm_grid_pmask = f_runoff.createVariable ( 'src_grid_pmask' , 'i4', ('src_grid_size',) ) |
---|
| 321 | v_atm_grid_pmask.long_name="Land-sea mask (periodicity removed)" ; v_atm_grid_pmask.units="Land:1, Ocean:0" |
---|
[4147] | 322 | |
---|
| 323 | v_atm_grid_dims [:] = atm_grid_dims |
---|
[4186] | 324 | v_atm_grid_center_lon[:] = atm_grid_center_lon[:] |
---|
| 325 | v_atm_grid_center_lat[:] = atm_grid_center_lat[:] |
---|
| 326 | v_atm_grid_corner_lon[:] = atm_grid_corner_lon |
---|
| 327 | v_atm_grid_corner_lat[:] = atm_grid_corner_lat |
---|
| 328 | v_atm_grid_area [:] = atm_grid_area[:] |
---|
| 329 | v_atm_grid_imask [:] = atm_grid_imask[:] |
---|
| 330 | v_atm_grid_pmask [:] = atm_grid_pmask[:] |
---|
[4147] | 331 | |
---|
| 332 | # -- |
---|
| 333 | |
---|
| 334 | v_oce_grid_dims = f_runoff.createVariable ( 'dst_grid_dims' , 'i4', ('dst_grid_rank',) ) |
---|
| 335 | v_oce_grid_center_lon = f_runoff.createVariable ( 'dst_grid_center_lon', 'i4', ('dst_grid_size',) ) |
---|
| 336 | v_oce_grid_center_lat = f_runoff.createVariable ( 'dst_grid_center_lat', 'i4', ('dst_grid_size',) ) |
---|
| 337 | v_oce_grid_center_lon.units='degrees_east' ; v_oce_grid_center_lon.long_name='Longitude' ; v_oce_grid_center_lon.long_name='longitude' ; v_oce_grid_center_lon.bounds="dst_grid_corner_lon" |
---|
| 338 | v_oce_grid_center_lat.units='degrees_north' ; v_oce_grid_center_lat.long_name='Latitude' ; v_oce_grid_center_lat.long_name='latitude' ; v_oce_grid_center_lat.bounds="dst_grid_corner_lat" |
---|
[4151] | 339 | v_oce_grid_corner_lon = f_runoff.createVariable ( 'dst_grid_corner_lon', 'f8', ('dst_grid_size', 'dst_grid_corners') ) |
---|
[4147] | 340 | v_oce_grid_corner_lat = f_runoff.createVariable ( 'dst_grid_corner_lat', 'f8', ('dst_grid_size', 'dst_grid_corners') ) |
---|
| 341 | v_oce_grid_corner_lon.units="degrees_east" |
---|
| 342 | v_oce_grid_corner_lat.units="degrees_north" |
---|
[4151] | 343 | v_oce_grid_area = f_runoff.createVariable ( 'dst_grid_area' , 'f8', ('dst_grid_size',) ) |
---|
[4147] | 344 | v_oce_grid_area.long_name="Grid area" ; v_oce_grid_area.standard_name="cell_area" ; v_oce_grid_area.units="m2" |
---|
[4151] | 345 | v_oce_grid_imask = f_runoff.createVariable ( 'dst_grid_imask' , 'i4', ('dst_grid_size',) ) |
---|
[4147] | 346 | v_oce_grid_imask.long_name="Land-sea mask" ; v_oce_grid_imask.units="Land:1, Ocean:0" |
---|
[4151] | 347 | v_oce_grid_pmask = f_runoff.createVariable ( 'dst_grid_pmask' , 'i4', ('dst_grid_size',) ) |
---|
| 348 | v_oce_grid_pmask.long_name="Land-sea mask (periodicity removed)" ; v_oce_grid_pmask.units="Land:1, Ocean:0" |
---|
[4147] | 349 | |
---|
| 350 | v_oce_grid_dims [:] = oce_grid_dims |
---|
[4186] | 351 | v_oce_grid_center_lon[:] = oce_grid_center_lon[:] |
---|
| 352 | v_oce_grid_center_lat[:] = oce_grid_center_lat[:] |
---|
| 353 | v_oce_grid_corner_lon[:] = oce_grid_corner_lon |
---|
| 354 | v_oce_grid_corner_lat[:] = oce_grid_corner_lon |
---|
| 355 | v_oce_grid_area [:] = oce_grid_area[:] |
---|
| 356 | v_oce_grid_imask [:] = oce_grid_imask[:] |
---|
| 357 | v_oce_grid_pmask [:] = oce_grid_pmask[:] |
---|
[4147] | 358 | |
---|
[4151] | 359 | v_atm_lon_addressed = f_runoff.createVariable ( 'src_lon_addressed' , 'f8', ('num_links',) ) |
---|
| 360 | v_atm_lat_addressed = f_runoff.createVariable ( 'src_lat_addressed' , 'f8', ('num_links',) ) |
---|
| 361 | v_atm_area_addressed = f_runoff.createVariable ( 'src_area_addressed' , 'f8', ('num_links',) ) |
---|
| 362 | v_atm_imask_addressed = f_runoff.createVariable ( 'src_imask_addressed', 'i4', ('num_links',) ) |
---|
| 363 | v_atm_pmask_addressed = f_runoff.createVariable ( 'src_pmask_addressed', 'i4', ('num_links',) ) |
---|
[4147] | 364 | |
---|
[4151] | 365 | v_oce_lon_addressed = f_runoff.createVariable ( 'dst_lon_addressed' , 'f8', ('num_links',) ) |
---|
| 366 | v_oce_lat_addressed = f_runoff.createVariable ( 'dst_lat_addressed' , 'f8', ('num_links',) ) |
---|
| 367 | v_oce_area_addressed = f_runoff.createVariable ( 'dst_area_addressed' , 'f8', ('num_links',) ) |
---|
| 368 | v_oce_imask_addressed = f_runoff.createVariable ( 'dst_imask_addressed', 'i4', ('num_links',) ) |
---|
| 369 | v_oce_pmask_addressed = f_runoff.createVariable ( 'dst_pmask_addressed', 'i4', ('num_links',) ) |
---|
| 370 | |
---|
[4147] | 371 | v_atm_lon_addressed.long_name="Longitude" ; v_atm_lon_addressed.standard_name="longitude" ; v_atm_lon_addressed.units="degrees_east" |
---|
[4151] | 372 | v_atm_lat_addressed.long_name="Latitude" ; v_atm_lat_addressed.standard_name="latitude" ; v_atm_lat_addressed.units="degrees_north" |
---|
[4186] | 373 | v_atm_lon_addressed [:] = atm_grid_center_lon[atm_address] |
---|
| 374 | v_atm_lat_addressed [:] = atm_grid_center_lat[atm_address] |
---|
| 375 | v_atm_area_addressed [:] = atm_grid_area[atm_address] |
---|
| 376 | v_atm_imask_addressed[:] = 1-atm_grid_imask[atm_address] |
---|
| 377 | v_atm_pmask_addressed[:] = 1-atm_grid_pmask[atm_address] |
---|
[4147] | 378 | |
---|
| 379 | v_oce_lon_addressed.long_name="Longitude" ; v_oce_lon_addressed.standard_name="longitude" ; v_oce_lon_addressed.units="degrees_east" |
---|
[4151] | 380 | v_oce_lat_addressed.long_name="Latitude" ; v_oce_lat_addressed.standard_name="latitude" ; v_oce_lat_addressed.units="degrees_north" |
---|
[4186] | 381 | v_oce_lon_addressed [:] = oce_grid_center_lon[oce_address] |
---|
| 382 | v_oce_lat_addressed [:] = oce_grid_center_lat[oce_address]#.ravel() |
---|
| 383 | v_oce_area_addressed [:] = oce_grid_area[oce_address] |
---|
| 384 | v_oce_imask_addressed[:] = 1-oce_grid_imask[oce_address] |
---|
| 385 | v_oce_pmask_addressed[:] = 1-oce_grid_pmask[oce_address] |
---|
[4147] | 386 | |
---|
[4186] | 387 | if atmDomainType == 'rectilinear' : |
---|
| 388 | v_atmLand = f_runoff.createVariable ( 'atmLand' , 'i4', ('src_grid_size',) ) |
---|
| 389 | v_atmLandFiltered = f_runoff.createVariable ( 'atmLandFiltered', 'f4', ('src_grid_size',) ) |
---|
| 390 | v_atmLandFrac = f_runoff.createVariable ( 'atmLandFrac' , 'i4', ('src_grid_size',) ) |
---|
| 391 | v_atmFrac = f_runoff.createVariable ( 'atmFrac' , 'i4', ('src_grid_size',) ) |
---|
| 392 | v_atmOcean = f_runoff.createVariable ( 'atmOcean' , 'i4', ('src_grid_size',) ) |
---|
| 393 | v_atmOceanFrac = f_runoff.createVariable ( 'atmOceanFrac' , 'i4', ('src_grid_size',) ) |
---|
| 394 | |
---|
| 395 | v_atmLand[:] = atmLand |
---|
| 396 | v_atmLandFrac[:] = atmLandFrac |
---|
| 397 | v_atmLandFiltered[:] = atmLandFiltered |
---|
| 398 | v_atmFrac[:] = atmFrac |
---|
| 399 | v_atmOcean[:] = atmOcean |
---|
| 400 | v_atmOceanFrac[:] = atmOceanFrac |
---|
[4151] | 401 | |
---|
[4186] | 402 | v_atmCoast = f_runoff.createVariable ( 'atmCoast' , 'i4', ('src_grid_size',) ) |
---|
| 403 | v_atmCoast[:] = atmCoast |
---|
[4151] | 404 | |
---|
| 405 | v_oceLand = f_runoff.createVariable ( 'oceLand' , 'i4', ('dst_grid_size',) ) |
---|
| 406 | v_oceOcean = f_runoff.createVariable ( 'oceOcean' , 'i4', ('dst_grid_size',) ) |
---|
| 407 | v_oceOceanFiltered = f_runoff.createVariable ( 'oceOceanFiltered', 'f4', ('dst_grid_size',) ) |
---|
| 408 | v_oceCoast = f_runoff.createVariable ( 'oceCoast' , 'i4', ('dst_grid_size',) ) |
---|
| 409 | |
---|
[4186] | 410 | v_oceLand[:] = oceLand |
---|
| 411 | v_oceOcean[:] = oceOcean |
---|
| 412 | v_oceOceanFiltered[:] = oceOceanFiltered |
---|
| 413 | v_oceCoast[:] = oceCoast |
---|
[4151] | 414 | |
---|
[4172] | 415 | f_runoff.sync () |
---|
| 416 | |
---|
| 417 | ## |
---|
| 418 | f_runoff.close() |
---|
| 419 | |
---|
| 420 | print ('The end') |
---|
| 421 | |
---|
| 422 | ## ====================================================================================== |
---|