| 1 | ## L. Fita, LMD October 2014. |
|---|
| 2 | # Generation of initial conditions for an aqua-planet from the LMDZ model (r1818) 'iniacademic.F90' program |
|---|
| 3 | # Author: Frederic Hourdin original: 15/01/93 |
|---|
| 4 | # The forcing defined here is from Held and Suarez, 1994, Bulletin |
|---|
| 5 | # of the American Meteorological Society, 75, 1825. |
|---|
| 6 | |
|---|
| 7 | from optparse import OptionParser |
|---|
| 8 | import numpy as np |
|---|
| 9 | from netCDF4 import Dataset as NetCDFFile |
|---|
| 10 | import os |
|---|
| 11 | import re |
|---|
| 12 | import nc_var_tools as ncvar |
|---|
| 13 | from lmdz_const import * |
|---|
| 14 | |
|---|
| 15 | main = 'iniaqua.py' |
|---|
| 16 | errormsg='ERROR -- error -- ERROR -- error' |
|---|
| 17 | warnmsg='WARNING -- warning -- WARNING -- warning' |
|---|
| 18 | |
|---|
| 19 | filekinds = ['CF', 'WRF'] |
|---|
| 20 | |
|---|
| 21 | ## g.e. # iniaqua.py -d 32,32,39 -o WRF -t 19791201000000 -y true |
|---|
| 22 | |
|---|
| 23 | def sig_hybrid(sig,pa,preff): |
|---|
| 24 | """ Function utilisee pour calculer des valeurs de sigma modifie |
|---|
| 25 | pour conserver les coordonnees verticales decrites dans |
|---|
| 26 | esasig.def/z2sig.def lors du passage en coordonnees hybrides |
|---|
| 27 | F. Forget 2002 |
|---|
| 28 | sig= sigma level |
|---|
| 29 | pa= |
|---|
| 30 | preff= reference pressure |
|---|
| 31 | Connaissant sig (niveaux "sigma" ou on veut mettre les couches) |
|---|
| 32 | L'objectif est de calculer newsig telle que |
|---|
| 33 | (1 -pa/preff)*exp(1-1./newsig**2)+(pa/preff)*newsig = sig |
|---|
| 34 | Cela ne se resoud pas analytiquement: |
|---|
| 35 | => on resoud par iterration bourrine |
|---|
| 36 | ---------------------------------------------- |
|---|
| 37 | Information : where exp(1-1./x**2) become << x |
|---|
| 38 | x exp(1-1./x**2) /x |
|---|
| 39 | 1 1 |
|---|
| 40 | 0.68 0.5 |
|---|
| 41 | 0.5 1.E-1 |
|---|
| 42 | 0.391 1.E-2 |
|---|
| 43 | 0.333 1.E-3 |
|---|
| 44 | 0.295 1.E-4 |
|---|
| 45 | 0.269 1.E-5 |
|---|
| 46 | 0.248 1.E-6 |
|---|
| 47 | => on peut utiliser newsig = sig*preff/pa si sig*preff/pa < 0.25 |
|---|
| 48 | """ |
|---|
| 49 | fname = 'sig_hybrid' |
|---|
| 50 | |
|---|
| 51 | # maximum number of iterations |
|---|
| 52 | maxiter = 9999 |
|---|
| 53 | |
|---|
| 54 | nsig = sig |
|---|
| 55 | x1=0 |
|---|
| 56 | x2=1 |
|---|
| 57 | if sig >= 1.: |
|---|
| 58 | nsig = sig |
|---|
| 59 | elif sig*preff/pa >= 0.25: |
|---|
| 60 | for j in range(maxiter): |
|---|
| 61 | F = ((1. -pa/preff)*np.exp(1.-1./nsig**2)+(pa/preff)*nsig)/sig |
|---|
| 62 | # print J,'nsig=', newsig, 'F=', F |
|---|
| 63 | if F > 1: |
|---|
| 64 | X2 = newsig |
|---|
| 65 | nsig = (X1+nsig)*0.5 |
|---|
| 66 | else: |
|---|
| 67 | X1 = newsig |
|---|
| 68 | nsig = (X2+nsig)*0.5 |
|---|
| 69 | |
|---|
| 70 | # Test : on arete lorsque on approxime sig a moins de 0.01 m pres |
|---|
| 71 | # (en pseudo altitude) : |
|---|
| 72 | if np.abs(10.*np.log(F)) < 1.e-5: break |
|---|
| 73 | else: |
|---|
| 74 | nsig= sig*preff/pa |
|---|
| 75 | |
|---|
| 76 | return nsig |
|---|
| 77 | |
|---|
| 78 | def presnivs_calc(hybrid, dz): |
|---|
| 79 | """ From dyn3d/disvert_noterre.F calculation of vertical pressure levels |
|---|
| 80 | hybrid= whether hydbrid coordinates have to be used |
|---|
| 81 | dz= numbef of vertical layers |
|---|
| 82 | """ |
|---|
| 83 | |
|---|
| 84 | fname = 'presnivs_calc' |
|---|
| 85 | |
|---|
| 86 | #----------------------------------------------------------------------- |
|---|
| 87 | # .... Calculs de ap(l) et de bp(l) .... |
|---|
| 88 | # ......................................... |
|---|
| 89 | # |
|---|
| 90 | # ..... pa et preff sont lus sur les fichiers start par dynetat0 ..... |
|---|
| 91 | #----------------------------------------------------------------------- |
|---|
| 92 | # |
|---|
| 93 | llmp1 = dz + 1 |
|---|
| 94 | pnivs = np.zeros((dz), dtype=np.float) |
|---|
| 95 | s = np.zeros((dz), dtype=np.float) |
|---|
| 96 | sig = np.zeros((dz+1), dtype=np.float) |
|---|
| 97 | ap = np.zeros((dz+1), dtype=np.float) |
|---|
| 98 | bp = np.zeros((dz+1), dtype=np.float) |
|---|
| 99 | |
|---|
| 100 | # Ouverture possible de fichiers typiquement E.T. |
|---|
| 101 | |
|---|
| 102 | if os.path.isfile('easig.def'): |
|---|
| 103 | #----------------------------------------------------------------------- |
|---|
| 104 | # cas 1 on lit les options dans esasig.def: |
|---|
| 105 | # ---------------------------------------- |
|---|
| 106 | |
|---|
| 107 | ofet = open('esasig.def', 'r') |
|---|
| 108 | # Lecture de esasig.def : |
|---|
| 109 | # Systeme peu souple, mais qui respecte en theorie |
|---|
| 110 | # La conservation de l'energie (conversion Energie potentielle |
|---|
| 111 | # <-> energie cinetique, d'apres la note de Frederic Hourdin... |
|---|
| 112 | |
|---|
| 113 | print '*****************************' |
|---|
| 114 | print "WARNING reading 'esasig.def'" |
|---|
| 115 | print '*****************************' |
|---|
| 116 | for line in ofet: |
|---|
| 117 | linevalues = ncvar.reduce_spaces(line) |
|---|
| 118 | scaleheight = np.float(linevalues[0]) |
|---|
| 119 | dz0 = np.float(linevalues[1]) |
|---|
| 120 | dz1 = np.float(linevalues[2]) |
|---|
| 121 | nhaut = np.float(linevalues[3]) |
|---|
| 122 | |
|---|
| 123 | ofet.close() |
|---|
| 124 | dz0 = dz0/scaleheight |
|---|
| 125 | dz1 = dz1/scaleheight |
|---|
| 126 | |
|---|
| 127 | sig1=(1.-dz1)/tanh(.5*(dz-1)/nhaut) |
|---|
| 128 | |
|---|
| 129 | esig=1. |
|---|
| 130 | for l in range(19): |
|---|
| 131 | esig=-np.log((1./sig1-1.)*np.exp(-dz0)/esig)/(dz-1.) |
|---|
| 132 | |
|---|
| 133 | csig=(1./sig1-1.)/(np.exp(esig)-1.) |
|---|
| 134 | |
|---|
| 135 | for l in range(1,dz): |
|---|
| 136 | zz=csig*(np.exp(esig*(l-1.))-1.) |
|---|
| 137 | sig[l] = 1./(1.+zz)*np.tanh(.5*(dz+1-l)/nhaut) |
|---|
| 138 | |
|---|
| 139 | sig[0] = 1. |
|---|
| 140 | sig[dz] = 0. |
|---|
| 141 | quoi = 1. + 2.* kappa |
|---|
| 142 | s[dz-1] = 1. |
|---|
| 143 | s[dz-2] = quoi |
|---|
| 144 | if dz > 1: |
|---|
| 145 | for ll in range(1, dz-2): |
|---|
| 146 | l = dz+1 - ll |
|---|
| 147 | quand = sig[l+1]/sig[l] |
|---|
| 148 | s[l-1] = quoi*(1.-quand)*s[l] + quand*s[l+1] |
|---|
| 149 | # |
|---|
| 150 | snorm=(1.-.5*sig[1]+kappa*(1.-sig[1]))*s[0]+.5*sig[1]*s[1] |
|---|
| 151 | for l in range(dz): |
|---|
| 152 | s[l] = s[l]/ snorm |
|---|
| 153 | elif os.path.isfile('z2sig.def'): |
|---|
| 154 | fet = open('z2sig.def', 'r') |
|---|
| 155 | #----------------------------------------------------------------------- |
|---|
| 156 | # cas 2 on lit les options dans z2sig.def: |
|---|
| 157 | # ---------------------------------------- |
|---|
| 158 | print '****************************' |
|---|
| 159 | print 'Reading z2sig.def' |
|---|
| 160 | print '****************************' |
|---|
| 161 | |
|---|
| 162 | for line in ofet: |
|---|
| 163 | linevalues = ncvar.reduce_spaces(line) |
|---|
| 164 | scaleheight = np.float(linevalues[0]) |
|---|
| 165 | for l in range(dz): |
|---|
| 166 | zsig[l] = linevalues[l+1] |
|---|
| 167 | |
|---|
| 168 | ofet.close() |
|---|
| 169 | |
|---|
| 170 | sig[0] = 1. |
|---|
| 171 | for l in range(1,dz): |
|---|
| 172 | sig[l] = 0.5 * ( np.exp(-zsig[l]/scaleheight) + \ |
|---|
| 173 | np.exp(-zsig[l-1]/scaleheight) ) |
|---|
| 174 | |
|---|
| 175 | sig[dz+1] = 0. |
|---|
| 176 | |
|---|
| 177 | #----------------------------------------------------------------------- |
|---|
| 178 | else: |
|---|
| 179 | print errormsg |
|---|
| 180 | print ' ' + fname + ": didn't you forget something ???" |
|---|
| 181 | print " We need file 'z2sig.def' ! (OR 'esasig.def')" |
|---|
| 182 | quit(-1) |
|---|
| 183 | #----------------------------------------------------------------------- |
|---|
| 184 | |
|---|
| 185 | nivsigs = np.arange(dz)*1. |
|---|
| 186 | nivsig = np.arange(llmp1)*1. |
|---|
| 187 | |
|---|
| 188 | if hybrid: |
|---|
| 189 | # use hybrid coordinates |
|---|
| 190 | print "*********************************" |
|---|
| 191 | print "Using hybrid vertical coordinates" |
|---|
| 192 | print |
|---|
| 193 | # Coordonnees hybrides avec mod |
|---|
| 194 | for l in range(dz): |
|---|
| 195 | newsig = sig_hybrid(sig[l],pa,preff) |
|---|
| 196 | bp[l] = np.exp(1.-1./(newsig**2)) |
|---|
| 197 | ap[l] = pa * (newsig - bp[l] ) |
|---|
| 198 | |
|---|
| 199 | bp[llmp1-1] = 0. |
|---|
| 200 | ap[llmp1-1] = 0. |
|---|
| 201 | else: |
|---|
| 202 | # use sigma coordinates |
|---|
| 203 | print "********************************" |
|---|
| 204 | print "Using sigma vertical coordinates" |
|---|
| 205 | print |
|---|
| 206 | # Pour ne pas passer en coordonnees hybrides |
|---|
| 207 | for l in range(dz): |
|---|
| 208 | ap[l] = 0. |
|---|
| 209 | bp[l] = sig[l] |
|---|
| 210 | |
|---|
| 211 | ap[llmp1-1] = 0. |
|---|
| 212 | |
|---|
| 213 | bp[llmp1-1] = 0. |
|---|
| 214 | |
|---|
| 215 | print 'BP________ ', bp |
|---|
| 216 | print 'AP________ ', ap |
|---|
| 217 | |
|---|
| 218 | # Calcul au milieu des couches (llm = dz): |
|---|
| 219 | # WARNING : le choix de placer le milieu des couches au niveau de |
|---|
| 220 | # pression intermediaire est arbitraire et pourrait etre modifie. |
|---|
| 221 | # Le calcul du niveau pour la derniere couche |
|---|
| 222 | # (on met la meme distance (en log pression) entre P(llm) |
|---|
| 223 | # et P(llm -1) qu'entre P(llm-1) et P(llm-2) ) est |
|---|
| 224 | # Specifique. Ce choix est specifie ici ET dans exner_milieu.F |
|---|
| 225 | |
|---|
| 226 | for l in range(dz-1): |
|---|
| 227 | aps[0:dz-1] = 0.5*( ap[0:dz-1]+ap[1:dz]) |
|---|
| 228 | bps[0:dz-1] = 0.5*( bp[0:dz-1]+bp[1:dz]) |
|---|
| 229 | |
|---|
| 230 | if hybrid: |
|---|
| 231 | aps[dz-1] = aps[dz-2]**2 / aps[dz-3] |
|---|
| 232 | bps[dz-1] = 0.5*(bp[dz-1] + bp[dz]) |
|---|
| 233 | else: |
|---|
| 234 | bps[dz-1] = bps[dz-2]**2 / bps[dz-3] |
|---|
| 235 | aps[dz-1] = 0. |
|---|
| 236 | |
|---|
| 237 | print 'BPs_______ ', bps |
|---|
| 238 | print 'APs_______ ', aps |
|---|
| 239 | |
|---|
| 240 | for l in range(dz): |
|---|
| 241 | psnivs[l] = aps[l]+bps[l]*preff |
|---|
| 242 | psalt[l] = -scaleheight*np.log(presnivs[l]/preff) |
|---|
| 243 | |
|---|
| 244 | return psnivs, psalt |
|---|
| 245 | |
|---|
| 246 | def global_lonlat(dx,dy): |
|---|
| 247 | """ Function to generate 2D matrices with the global longitude, latitudes |
|---|
| 248 | dx, dy: dimension of the desired matrix |
|---|
| 249 | >>> global_lonlat(5,5) |
|---|
| 250 | array([[ 36., 108., 180., 252., 324.], |
|---|
| 251 | [ 36., 108., 180., 252., 324.], |
|---|
| 252 | [ 36., 108., 180., 252., 324.], |
|---|
| 253 | [ 36., 108., 180., 252., 324.], |
|---|
| 254 | [ 36., 108., 180., 252., 324.]]), array([[-72., -72., -72., -72., -72.], |
|---|
| 255 | [-36., -36., -36., -36., -36.], |
|---|
| 256 | [ 0., 0., 0., 0., 0.], |
|---|
| 257 | [ 36., 36., 36., 36., 36.], |
|---|
| 258 | [ 72., 72., 72., 72., 72.]])) |
|---|
| 259 | """ |
|---|
| 260 | |
|---|
| 261 | fname = 'global_lonlat' |
|---|
| 262 | |
|---|
| 263 | longitude = np.zeros((dy,dx), dtype=np.float) |
|---|
| 264 | latitude = np.zeros((dy,dx), dtype=np.float) |
|---|
| 265 | |
|---|
| 266 | for ix in range(dx): |
|---|
| 267 | longitude[:,ix] = 360.*(1./2. + ix )/(dx) |
|---|
| 268 | |
|---|
| 269 | for iy in range(dy): |
|---|
| 270 | latitude[iy,:] = 180.*(1./2. + iy )/(dy) - 90. |
|---|
| 271 | |
|---|
| 272 | return longitude, latitude |
|---|
| 273 | |
|---|
| 274 | ####### ###### ##### #### ### ## # |
|---|
| 275 | |
|---|
| 276 | filekindsnames = "'" + ncvar.numVector_String(filekinds, "', '") + "'" |
|---|
| 277 | |
|---|
| 278 | parser = OptionParser() |
|---|
| 279 | parser.add_option("-o", "--outputkind", type='choice', dest="okind", |
|---|
| 280 | choices=filekinds, help="kind of output: " + filekindsnames, metavar="KIND") |
|---|
| 281 | parser.add_option("-d", "--dimensions", dest="dims", |
|---|
| 282 | help="dimensions of the initial conditions: dimx,dimy,dimz", metavar="VALUES") |
|---|
| 283 | parser.add_option("-t", "--time", dest="time", |
|---|
| 284 | help="time of the initial conditions ([YYYY][MM][DD][HH][MI][SS] format)", metavar="VALUE") |
|---|
| 285 | parser.add_option("-y", "--hybrid", dest="hybrid", |
|---|
| 286 | help="whether vertical levels have to compute hydbid or not (true/false)", metavar="VAR") |
|---|
| 287 | |
|---|
| 288 | (opts, args) = parser.parse_args() |
|---|
| 289 | |
|---|
| 290 | ####### ####### |
|---|
| 291 | ## MAIN |
|---|
| 292 | ####### |
|---|
| 293 | |
|---|
| 294 | # dynamic variables |
|---|
| 295 | # vcov, ucov: covariant winds |
|---|
| 296 | # teta: potential temperature |
|---|
| 297 | # q: advecting fields (humidity species) |
|---|
| 298 | # ps: surface pressure |
|---|
| 299 | # masse: air mass |
|---|
| 300 | # phis: surface geopotential |
|---|
| 301 | |
|---|
| 302 | # Local: |
|---|
| 303 | # p: pressure at the interface between layers (half-sigma) |
|---|
| 304 | # pks: Exner function at the surface |
|---|
| 305 | # pk: Exner functino at the half-sigma layers |
|---|
| 306 | # pkf: Filtred Exner function at the half-sigma layers |
|---|
| 307 | # phi: geopotential height |
|---|
| 308 | # ddsin,zsig,tetapv,w_pv: auxiliar variables |
|---|
| 309 | # tetastrat: potential temporeature in the stratosphere (K) |
|---|
| 310 | # teta0,ttp,delt_y,delt_z,eps: constants for the T profile |
|---|
| 311 | # k_f,k_c_a,k_c_s: calling constants |
|---|
| 312 | # ok_geost: Initialisation geostrohic wind |
|---|
| 313 | # ok_pv: Polar Vortex |
|---|
| 314 | # phi_pv,dphi_pv,gam_pv: polar vortex constants |
|---|
| 315 | |
|---|
| 316 | dimx = int(opts.dims.split(',')[0]) |
|---|
| 317 | dimy = int(opts.dims.split(',')[1]) |
|---|
| 318 | dimz = int(opts.dims.split(',')[2]) |
|---|
| 319 | |
|---|
| 320 | if opts.hybrid == 'true': |
|---|
| 321 | hybrid_calc = True |
|---|
| 322 | else: |
|---|
| 323 | hybrid_calc = False |
|---|
| 324 | |
|---|
| 325 | ofile = 'iniaqua.nc' |
|---|
| 326 | |
|---|
| 327 | print 'dimensions: ',dimx,', ',dimy,', ',dimz |
|---|
| 328 | |
|---|
| 329 | if opts.okind == 'CF': |
|---|
| 330 | varnames = ['zg', 'ta', 'ua', 'va', 'pres', 'r'] |
|---|
| 331 | # Reference time from 1949-12-01 00:00:00 UTC |
|---|
| 332 | timev = ncvar.datetimeStr_conversion(opts.time,'YmdHMS','cfTime') |
|---|
| 333 | dimnames = ['time', 'z', 'y', 'x'] |
|---|
| 334 | elif opts.okind == 'WRF': |
|---|
| 335 | varnames = ['Geopot', 'T', 'U', 'V', 'PRES', 'QVAPOR'] |
|---|
| 336 | timev = ncvar.datetimeStr_conversion(opts.time,'YmdHMS','WRFdatetime') |
|---|
| 337 | dimnames = ['Time', 'bottom_top', 'south_north', 'west_east'] |
|---|
| 338 | |
|---|
| 339 | # Constants |
|---|
| 340 | ## |
|---|
| 341 | llm = dimz |
|---|
| 342 | |
|---|
| 343 | ok_geost = True |
|---|
| 344 | # Constants for Newtonian relaxation and friction |
|---|
| 345 | k_f = 1. |
|---|
| 346 | k_f = 1./(daysec*k_f) |
|---|
| 347 | # cooling surface |
|---|
| 348 | k_c_s=4. |
|---|
| 349 | k_c_s=1./(daysec*k_c_s) |
|---|
| 350 | # cooling free atm |
|---|
| 351 | k_c_a=40. |
|---|
| 352 | k_c_a=1./(daysec*k_c_a) |
|---|
| 353 | # Constants for Teta equilibrium profile |
|---|
| 354 | # mean Teta (S.H. 315K) |
|---|
| 355 | teta0=315. |
|---|
| 356 | # Tropopause temperature (S.H. 200K) |
|---|
| 357 | ttp=200. |
|---|
| 358 | # Deviation to N-S symmetry(~0-20K) |
|---|
| 359 | eps=0. |
|---|
| 360 | # Merid Temp. Gradient (S.H. 60K) |
|---|
| 361 | delt_y=60. |
|---|
| 362 | # Vertical Gradient (S.H. 10K) |
|---|
| 363 | delt_z=10. |
|---|
| 364 | # Polar vortex |
|---|
| 365 | ok_pv = False |
|---|
| 366 | # Latitude of edge of vortex |
|---|
| 367 | phi_pv=-50. |
|---|
| 368 | phi_pv=phi_pv*pi/180. |
|---|
| 369 | # Width of the edge |
|---|
| 370 | dphi_pv=5. |
|---|
| 371 | dphi_pv=dphi_pv*pi/180. |
|---|
| 372 | # -dT/dz vortex (in K/km) |
|---|
| 373 | gam_pv=4. |
|---|
| 374 | |
|---|
| 375 | presnivs, pseudoalt = presnivs_calc(hybrid_calc, dimz) |
|---|
| 376 | lon, lat = global_lonlat(dx,dy) |
|---|
| 377 | lonu, latu = global_lonlat(dx+1,dy) |
|---|
| 378 | lonv, latv = global_lonlat(dx,dy+1) |
|---|
| 379 | |
|---|
| 380 | # 2. Initialize fields towards which to relax |
|---|
| 381 | ## |
|---|
| 382 | |
|---|
| 383 | knewt_t = np.zeros((dimz), dtype=np.float) |
|---|
| 384 | kfrict = np.zeros((dimz), dtype=np.float) |
|---|
| 385 | clat4 = np.zeros((dimy+1, dimx), dtype=np.float) |
|---|
| 386 | |
|---|
| 387 | # Friction |
|---|
| 388 | knewt_g = k_c_a |
|---|
| 389 | for l in range(dimz): |
|---|
| 390 | zsig=presnivs[l]/preff |
|---|
| 391 | knewt_t[l]=(k_c_s-k_c_a)*np.max([0.,(zsig-0.7)/0.3]) |
|---|
| 392 | kfrict[l]=k_f*np.max([0.,(zsig-0.7)/0.3]) |
|---|
| 393 | |
|---|
| 394 | for j in 1,range(dimy+1): |
|---|
| 395 | clat4[j,:]=np.cos(rlatu[j])**4 |
|---|
| 396 | |
|---|
| 397 | # Vertical profile |
|---|
| 398 | tetajl = np.zeros((dimy+1, dimx), dtype=np.float) |
|---|
| 399 | teta = np.zeros((dimy+1, dimx+1), dtype=np.float) |
|---|
| 400 | tetarappel = np.zeros((dimy+1, dimx+1), dtype=np.float) |
|---|
| 401 | |
|---|
| 402 | for l in range (dz): |
|---|
| 403 | zsig = presnivs[l]/preff |
|---|
| 404 | tetastrat = ttp*zsig**(-kappa) |
|---|
| 405 | tetapv = tetastrat |
|---|
| 406 | if ok_pv and zsig < 0.1: |
|---|
| 407 | tetapv = tetastrat*(zsig*10.)**(kappa*cpp*gam_pv/1000./g) |
|---|
| 408 | |
|---|
| 409 | ddsin = np.sin(latu) |
|---|
| 410 | tetajl[l,:,:] = teta0-delt_y*ddsin+eps*ddsin-delt_z*(1.-ddsin*ddsin)*np.log(zsig) |
|---|
| 411 | if planet_type == 'giant': |
|---|
| 412 | tetajl[l,:,:] = teta0+(delt_y*((np.sin(latu*3.14159*eps+0.0001))**2) / \ |
|---|
| 413 | ((rlatu*3.14159*eps+0.0001)**2))-delt_z*np.log(zsig) |
|---|
| 414 | |
|---|
| 415 | # Profile stratospheric isotherm (+vortex) |
|---|
| 416 | w_pv=(1.-np.tanh((rlatu-phi_pv)/dphi_pv))/2. |
|---|
| 417 | tetastrat=tetastrat*(1.-w_pv)+tetapv*w_pv |
|---|
| 418 | for iy in range(dy): |
|---|
| 419 | for ix in range(dx): |
|---|
| 420 | tetajl[l,iy,ix]=np.max([tetajl(l,ix,iy),tetastrat]) |
|---|
| 421 | |
|---|
| 422 | for iz in range(dimz): |
|---|
| 423 | for iy in range(dimy+1): |
|---|
| 424 | tetarappel[iz,iy,0:dimx+1] = tetajl[iz,iy,:] |
|---|
| 425 | |
|---|
| 426 | tetarappel[iz,iy,0:dimx] = tetajl[iz,iy,dimx-1] |
|---|
| 427 | |
|---|
| 428 | |
|---|
| 429 | ncf = NetCDFFile(ofile, 'w') |
|---|
| 430 | |
|---|
| 431 | # Dimensions creation |
|---|
| 432 | ncf.createDimension(dimnames[0], None) |
|---|
| 433 | ncf.createDimension(dimnames[1], dimz) |
|---|
| 434 | ncf.createDimension(dimnames[2], dimy) |
|---|
| 435 | ncf.createDimension(dimnames[3], dimx) |
|---|
| 436 | |
|---|
| 437 | ncf.sync() |
|---|
| 438 | ncf.close() |
|---|
| 439 | |
|---|
| 440 | print main + ": successfull writing of file '" + ofile + "' !!" |
|---|