- Timestamp:
- Jan 9, 2015, 3:13:49 PM (10 years ago)
- Location:
- trunk/tools
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/tools/iniaqua.py
r180 r212 19 19 filekinds = ['CF', 'WRF'] 20 20 21 ## g.e. # iniaqua.py -d 32,32,39 -o WRF -t 19791201000000 -y true 21 ## g.e. # iniaqua.py -d 32,32,39 -p hybdrid -o WRF -t 19791201000000 -z param 22 23 # from dyn3d/fxy_new.h 24 #c 25 #c....stretching in x... 26 #c 27 def fripx(ri,dx): 28 fname = 'fripx' 29 30 ripx = (ri-1.0) *2.*np.pi/np.float(dx) 31 32 return ripx 33 34 def ffx(ri): 35 fname = 'ffx' 36 37 fx = fripx(ri) + transx + alphax * np.sin(fripx(ri)+transx-pxo ) - np.pi 38 39 return fx 40 41 def ffxprim(ri,dx): 42 fname = 'ffxprim' 43 44 fxprim = 2.*np.pi/REAL(dx)*( 1.+ alphax*np.cos( fripx(ri)+transx-pxo ) ) 45 46 return fxprim 47 48 #c....stretching in y... 49 #c 50 def fbigy(rj,jjp1,jjm): 51 fname = 'fbigy' 52 53 bigy = 2.*(np.float(jjp1)-rj)*np.pi/jjm 54 55 return bigy 56 57 def fy(rj): 58 fname = 'fy' 59 60 fy = ( fbigy(rj) + transy + alphay * np.sin(fbigy(rj)+transy-pyo) )/2. - np.pi/2. 61 62 return fy 63 64 def ffyprim(rj,jjm): 65 fname = 'ffyprim' 66 67 fyprim = ( np.pi/jjm ) * ( 1. + alphay * np.cos( fbigy(rj)+transy-pyo ) ) 68 69 return fyprim 70 71 def fxy(dx, dy): 72 73 """! 74 ! $Id: fxy.F 1403 2010-07-01 09:02:53Z fairhead $ 75 ! 76 77 c Auteur : P. Le Van 78 c 79 c Calcul des longitudes et des latitudes pour une fonction f(x,y) 80 c a tangente sinusoidale et eventuellement avec zoom . 81 c 82 c 83 """ 84 85 fname ='fxy' 86 87 #c ...... calcul des latitudes et de y' ..... 88 #c 89 vrlatu = np.zeros((dy+1), dtype=np.float) 90 vyprimu = np.zeros((dy+1), dtype=np.float) 91 92 vrlatu = ffy(np.arange(dy+1)*1. + 1.) 93 vyprimu = ffy(np.arange(dy+1)*1. + 1.) 94 95 vrlatv = np.zeros((dy), dtype=np.float) 96 vrlatu1 = np.zeros((dy), dtype=np.float) 97 vrlatu2 = np.zeros((dy), dtype=np.float) 98 yprimv = np.zeros((dy), dtype=np.float) 99 vyprimu1 = np.zeros((dy), dtype=np.float) 100 vyprimu2 = np.zeros((dy), dtype=np.float) 101 102 vrlatv = ffy(np.arange(dy)*1. + 1. + 0.5) 103 vrlatu1 = ffy(np.arange(dy)*1. + 1. + 0.25) 104 vrlatu2 = ffy(np.arange(dy)*1. + 1. + 0.75) 105 106 vyprimv = fyprim(np.arange(dy)*1. + 1. + 0.5) 107 vyprimu1 = fyprim(np.arange(dy)*1. + 1. + 0.25) 108 vyprimu2 = fyprim(np.arange(dy)*1. + 1. + 0.75) 109 110 #c 111 #c ..... calcul des longitudes et de x' ..... 112 #c 113 vrlonv = np.zeros((dx+1), dtype=np.float) 114 vrlonu = np.zeros((dx+1), dtype=np.float) 115 vrlonm025 = np.zeros((dx+1), dtype=np.float) 116 vrlonp025 = np.zeros((dx+1), dtype=np.float) 117 vxprimv = np.zeros((dx+1), dtype=np.float) 118 vxprimu = np.zeros((dx+1), dtype=np.float) 119 vxprimm025 = np.zeros((dx+1), dtype=np.float) 120 vxprimo025 = np.zeros((dx+1), dtype=np.float) 121 122 vrlonv = ffy(np.arange(dx+1)*1. + 1.) 123 vrlonu = ffy(np.arange(dx+1)*1. + 1. + 0.5) 124 vrlonm025 = ffy(np.arange(dx+1)*1. + 1. - 0.25) 125 vrlonp025 = ffy(np.arange(dx+1)*1. + 1. + 0.25) 126 127 vxprimv = fxprim(np.arange(dx+1)*1. + 1.) 128 vxprimu = fxprim(np.arange(dx+1)*1. + 1. + 0.5) 129 vxprimm025 = fxprim(np.arange(dx+1)*1. + 1. - 0.25) 130 vxprimp025 = fxprim(np.arange(dx+1)*1. + 1. + 0.25) 131 132 return vrlatu, vyprimu, vrlatv, vyprimv, vrlatu1, vyprimu1, vrlatu2, vyprimu2, \ 133 vrlonu, vxprimu, vrlonv, vxprimv, vrlonm025, vxprimm025, vrlonp025, vxprimp025 134 135 def jacobi(A,N,NP): 136 """! 137 ! $Id: jacobi.F90 1289 2009-12-18 14:51:22Z emillour $ 138 ! 139 """ 140 fname = 'jacobi' 141 142 D = np.zeros((NP), dtype=np.float) 143 V = np.zeros((NP,NP), dtype=np.float) 144 B = np.zeros((NP), dtype=np.float) 145 Z = np.zeros((NP), dtype=np.float) 146 147 for IP in range(N): 148 V[IP,IP]=1. 149 B[IP] = A[IP,IP] 150 151 D = B 152 NROT = 0 153 for I in range(50): 154 # DO I=1,50 ! 50? I suspect this should be NP 155 # ! but convergence is fast enough anyway 156 SM = 0. 157 for IP in range(N-1): 158 for IQ in range(IP+1,N): 159 SM = SM + np.abs(A[IP,IQ]) 160 161 if SM == 0.: return A, D, V, NROT 162 163 if I < 4: 164 TRESH = 0.2*SM/N**2 165 else: 166 TRESH = 0. 167 168 for IP in range(N-1): 169 for IQ in range(IP+1,N): 170 G = 100.*np.abs(A[IP,IQ]) 171 if I > 4 and np.abs(D[I]) + G == np.abs(D[IP]) and \ 172 np.abs(D[IQ])+G == np.abs(D[IQ]): 173 A[IP,IQ] = 0. 174 elif np.abs(A[IP,IQ]) > TRESH: 175 H = D[IQ]-D[IP] 176 if np.abs(H)+G == np.abs(H): 177 T = A[IP,IQ]/H 178 else: 179 THETA = 0.5*H/A[IP,IQ] 180 T = 1./(np.abs(THETA)+np.sqrt(1.+THETA**2)) 181 if THETA < 0.: T = -T 182 183 C=1./SQRT(1+T**2) 184 S=T*C 185 TAU=S/(1.+C) 186 H=T*A[IP,IQ] 187 Z[IP]=Z[IP]-H 188 Z[IQ]=Z[IQ]+H 189 D[IP]=D[IP]-H 190 D[IQ]=D[IQ]+H 191 A[IP,IQ]=0. 192 for J in range(IP-1): 193 G=A[J,IP] 194 H=A[J,IQ] 195 A[J,IP]=G-S*(H+G*TAU) 196 A[J,IQ]=H+S*(G-H*TAU) 197 198 for J in range(IP+1,IQ-1): 199 G = A[IP,J] 200 H = A[J,IQ] 201 A[IP,J] = G-S*(H+G*TAU) 202 A[J,IQ] = H+S*(G-H*TAU) 203 204 for J in range(IQ+1,N): 205 G = A[IP,J] 206 H = A[IQ,J] 207 A[IP,J] = G-S*(H+G*TAU) 208 A[IQ,J] = H+S*(G-H*TAU) 209 210 for J in range(N): 211 G = V[J,IP] 212 H = V[J,IQ] 213 V[J,IP] = G-S*(H+G*TAU) 214 V[J,IQ] = H+S*(G-H*TAU) 215 216 NROT=NROT+1 217 218 B = B + Z 219 D = B 220 Z = 0. 221 222 print errormsg 223 print ' ' + fname + ': 50 iterations should never happen !!' 224 quit(-1) 225 226 return 227 228 def acc(vec,im): 229 """! 230 ! $Header$ 231 ! 232 """ 233 fname ='acc' 234 235 d = np.zeros((im), dtype=np.float) 236 237 for j in range(im): 238 for i in range(im): 239 d[i] = vec[i,j]*vec[i,j] 240 241 vsum = np.sqrt(np.sum(d)) 242 for i in range(im): 243 vec[i,j] = vec[i,j] / vsum 244 245 return vec, d 246 247 def eigen_sort(d,n,np): 248 """! 249 ! $Header$ 250 ! 251 """ 252 fname = 'eigen_sort' 253 254 v = np.zeros((np,np), dtype=np.float) 255 256 for i in range(n-1): 257 k=i 258 p=d[i] 259 for j in range(i+1,n): 260 if d[j] >= p: 261 k=j 262 p=d[j] 263 264 if k != i: 265 d[k]=d[i] 266 d[i]=p 267 for j in range(n): 268 p=v[j,i] 269 v[j,i]=v[j,k] 270 v[j,k]=p 271 272 return d, v 273 274 def inifgn(dx, dy, dv): 275 """! $Header: /home/cvsroot/LMDZ4/libf/filtrez/inifgn.F,v 1.1.1.1 2004-05-19 12:53:09 lmdzadmin Exp $ 276 ! 277 c 278 c ... H.Upadyaya , O.Sharma ... 279 c 280 """ 281 fname = 'inifgn' 282 283 imm1 = dx - 1 284 285 rlatu, yprimu, rlatv, yprimv, rlatu1, yprimu1, rlatu2, yprimu2, rlonu, xprimu, \ 286 rlonv, xprimv, rlonm025, xprimm025, rlonp025, xprimp025 = fxy(dx,dy) 287 288 dlonu = xprimu 289 dlonv = xprimv 290 291 sddv = np.sqrt(dlonv) 292 sddu = np.sqrt(dlonu) 293 unsddu = 1./sddu 294 unsddv = 1./sddv 295 296 vec = np.zeros((dx,dy), dtype=np.float) 297 vec1 = np.zeros((dx,dy), dtype=np.float) 298 eigenfnv = np.zeros((dx,dy), dtype=np.float) 299 eigenfnu = np.zeros((dx,dy), dtype=np.float) 300 c 301 c 302 eignfnv[0,0] = -1. 303 eignfnv[dx-1,0] = 1. 304 305 for i in range(imm1): 306 eignfnv[i+1,i+1]= -1. 307 eignfnv[i,i+1] = 1. 308 309 for j in range(dx): 310 for i in range(dx): 311 eignfnv[i,j] = eignfnv[i,j]/(sddu[i]*sddv[j]) 312 313 for j in range(dx): 314 for i in range(dx): 315 eignfnu[i,j] = -eignfnv[j,i] 316 317 for j in range(dx): 318 for i in range(dx): 319 vec[i,j] = 0.0 320 vec1[i,j] = 0.0 321 for k in range(dx): 322 vec[i,j] = vec[i,j] + eignfnu[i,k]*eignfnv[k,j] 323 vec1[i,j] = vec1[i,j] + eignfnv[i,k]*eignfnu[k,j] 324 325 vec, dv, eignfnv, nrot = jacobi(vec,iim,iim) 326 eignfnv, d = acc(eignfnv,iim) 327 dv, eignfnv = eigen_sort(dv,iim,iim) 328 c 329 vec1, du, eignfnu, nrot = jacobi(vec1,iim,iim) 330 eignfnu, d = acc(eignfnu,iim) 331 du, eignfnu = eigen_sort(du,iim,iim) 332 333 return sddu, unsddu, sddv, unsddv 334 335 336 def inifilr(iim, xprimu): 337 """ from: filtrez/filtreg_mod.F90 338 ! ... H. Upadhyaya, O.Sharma ... 339 ! 340 ! version 3 ..... 341 342 ! Correction le 28/10/97 P. Le Van . 343 ! ------------------------------------------------------------------- 344 ! 345 ! ------------------------------------------------------------ 346 ! This routine computes the eigenfunctions of the laplacien 347 ! on the stretched grid, and the filtering coefficients 348 ! 349 ! We designate: 350 ! eignfn eigenfunctions of the discrete laplacien 351 ! eigenvl eigenvalues 352 ! jfiltn indexof the last scalar line filtered in NH 353 ! jfilts index of the first line filtered in SH 354 ! modfrst index of the mode from WHERE modes are filtered 355 ! modemax maximum number of modes ( im ) 356 ! coefil filtering coefficients ( lamda_max*COS(rlat)/lamda ) 357 ! sdd SQRT( dx ) 358 ! 359 ! the modes are filtered from modfrst to modemax 360 ! 361 !----------------------------------------------------------- 362 ! 363 """ 364 fname = 'inifilr' 365 366 dlonu = xprimu 367 368 ! 369 CALL inifgn(eignvl) 370 ! 371 PRINT *,'inifilr: EIGNVL ' 372 PRINT 250,eignvl 373 250 FORMAT( 1x,5e14.6) 374 ! 375 ! compute eigenvalues and eigenfunctions 376 ! 377 ! 378 !................................................................. 379 ! 380 ! compute the filtering coefficients for scalar lines and 381 ! meridional wind v-lines 382 ! 383 ! we filter all those latitude lines WHERE coefil < 1 384 ! NO FILTERING AT POLES 385 ! 386 ! colat0 is to be used when alpha (stretching coefficient) 387 ! is set equal to zero for the regular grid CASE 388 ! 389 ! ....... Calcul de colat0 ......... 390 ! ..... colat0 = minimum de ( 0.5, min dy/ min dx ) ... 391 ! 392 ! 393 DO j = 1,jjm 394 dlatu( j ) = rlatu( j ) - rlatu( j+1 ) 395 ENDDO 396 ! 397 #ifdef CRAY 398 iymin = ISMIN( jjm, dlatu, 1 ) 399 ixmineq = ISMIN( iim, dlonu, 1 ) 400 dymin = dlatu( iymin ) 401 dxmin = dlonu( ixmineq ) 402 #else 403 dxmin = dlonu(1) 404 DO i = 2, iim 405 dxmin = MIN( dxmin,dlonu(i) ) 406 ENDDO 407 dymin = dlatu(1) 408 DO j = 2, jjm 409 dymin = MIN( dymin,dlatu(j) ) 410 ENDDO 411 #endif 412 ! 413 ! For a regular grid, we want the filter to start at latitudes 414 ! corresponding to lengths dx of the same size as dy (in terms 415 ! of angles: dx=2*dy) => at colat0=0.5 (i.e. colatitude=30 degrees 416 ! <=> latitude=60 degrees). 417 ! Same idea for the zoomed grid: start filtering polewards as soon 418 ! as length dx becomes of the same size as dy 419 ! 420 colat0 = MIN( 0.5, dymin/dxmin ) 421 ! 422 IF( .NOT.fxyhypb.AND.ysinus ) THEN 423 colat0 = 0.6 424 ! ...... a revoir pour ysinus ! ....... 425 alphax = 0. 426 ENDIF 427 ! 428 PRINT 50, colat0,alphax 429 50 FORMAT(/15x,' Inifilr colat0 alphax ',2e16.7) 430 ! 431 IF(alphax.EQ.1. ) THEN 432 PRINT *,' Inifilr alphax doit etre < a 1. Corriger ' 433 STOP 434 ENDIF 435 ! 436 lamdamax = iim / ( pi * colat0 * ( 1. - alphax ) ) 437 438 ! ... Correction le 28/10/97 ( P.Le Van ) .. 439 ! 440 DO i = 2,iim 441 rlamda( i ) = lamdamax/ SQRT( ABS( eignvl(i) ) ) 442 ENDDO 443 ! 444 445 DO j = 1,jjm 446 DO i = 1,iim 447 coefilu( i,j ) = 0.0 448 coefilv( i,j ) = 0.0 449 coefilu2( i,j ) = 0.0 450 coefilv2( i,j ) = 0.0 451 ENDDO 452 ENDDO 453 454 ! 455 ! ... Determination de jfiltnu,jfiltnv,jfiltsu,jfiltsv .... 456 ! ......................................................... 457 ! 458 modemax = iim 459 460 !!!! imx = modemax - 4 * (modemax/iim) 461 462 imx = iim 463 ! 464 PRINT *,'inifilr: TRUNCATION AT ',imx 465 ! 466 ! Ehouarn: set up some defaults 467 jfiltnu=2 ! avoid north pole 468 jfiltsu=jjm ! avoid south pole (which is at jjm+1) 469 jfiltnv=1 ! NB: no poles on the V grid 470 jfiltsv=jjm 471 472 DO j = 2, jjm/2+1 473 cof = COS( rlatu(j) )/ colat0 474 IF ( cof .LT. 1. ) THEN 475 IF( rlamda(imx) * COS(rlatu(j) ).LT.1. ) THEN 476 jfiltnu= j 477 ENDIF 478 ENDIF 479 480 cof = COS( rlatu(jjp1-j+1) )/ colat0 481 IF ( cof .LT. 1. ) THEN 482 IF( rlamda(imx) * COS(rlatu(jjp1-j+1) ).LT.1. ) THEN 483 jfiltsu= jjp1-j+1 484 ENDIF 485 ENDIF 486 ENDDO 487 ! 488 DO j = 1, jjm/2 489 cof = COS( rlatv(j) )/ colat0 490 IF ( cof .LT. 1. ) THEN 491 IF( rlamda(imx) * COS(rlatv(j) ).LT.1. ) THEN 492 jfiltnv= j 493 ENDIF 494 ENDIF 495 496 cof = COS( rlatv(jjm-j+1) )/ colat0 497 IF ( cof .LT. 1. ) THEN 498 IF( rlamda(imx) * COS(rlatv(jjm-j+1) ).LT.1. ) THEN 499 jfiltsv= jjm-j+1 500 ENDIF 501 ENDIF 502 ENDDO 503 ! 504 505 IF( jfiltnu.GT. jjm/2 +1 ) THEN 506 PRINT *,' jfiltnu en dehors des valeurs acceptables ' ,jfiltnu 507 STOP 508 ENDIF 509 510 IF( jfiltsu.GT. jjm +1 ) THEN 511 PRINT *,' jfiltsu en dehors des valeurs acceptables ' ,jfiltsu 512 STOP 513 ENDIF 514 515 IF( jfiltnv.GT. jjm/2 ) THEN 516 PRINT *,' jfiltnv en dehors des valeurs acceptables ' ,jfiltnv 517 STOP 518 ENDIF 519 520 IF( jfiltsv.GT. jjm ) THEN 521 PRINT *,' jfiltsv en dehors des valeurs acceptables ' ,jfiltsv 522 STOP 523 ENDIF 524 525 PRINT *,'inifilr: jfiltnv jfiltsv jfiltnu jfiltsu ' , & 526 jfiltnv,jfiltsv,jfiltnu,jfiltsu 527 528 IF(first_call_inifilr) THEN 529 ALLOCATE(matriceun(iim,iim,jfiltnu)) 530 ALLOCATE(matriceus(iim,iim,jjm-jfiltsu+1)) 531 ALLOCATE(matricevn(iim,iim,jfiltnv)) 532 ALLOCATE(matricevs(iim,iim,jjm-jfiltsv+1)) 533 ALLOCATE( matrinvn(iim,iim,jfiltnu)) 534 ALLOCATE( matrinvs(iim,iim,jjm-jfiltsu+1)) 535 first_call_inifilr = .FALSE. 536 ENDIF 537 538 ! 539 ! ... Determination de coefilu,coefilv,n=modfrstu,modfrstv .... 540 !................................................................ 541 ! 542 ! 543 DO j = 1,jjm 544 !default initialization: all modes are retained (i.e. no filtering) 545 modfrstu( j ) = iim 546 modfrstv( j ) = iim 547 ENDDO 548 ! 549 DO j = 2,jfiltnu 550 DO k = 2,modemax 551 cof = rlamda(k) * COS( rlatu(j) ) 552 IF ( cof .LT. 1. ) GOTO 82 553 ENDDO 554 GOTO 84 555 82 modfrstu( j ) = k 556 ! 557 kf = modfrstu( j ) 558 DO k = kf , modemax 559 cof = rlamda(k) * COS( rlatu(j) ) 560 coefilu(k,j) = cof - 1. 561 coefilu2(k,j) = cof*cof - 1. 562 ENDDO 563 84 CONTINUE 564 ENDDO 565 ! 566 ! 567 DO j = 1,jfiltnv 568 ! 569 DO k = 2,modemax 570 cof = rlamda(k) * COS( rlatv(j) ) 571 IF ( cof .LT. 1. ) GOTO 87 572 ENDDO 573 GOTO 89 574 87 modfrstv( j ) = k 575 ! 576 kf = modfrstv( j ) 577 DO k = kf , modemax 578 cof = rlamda(k) * COS( rlatv(j) ) 579 coefilv(k,j) = cof - 1. 580 coefilv2(k,j) = cof*cof - 1. 581 ENDDO 582 89 CONTINUE 583 ENDDO 584 ! 585 DO j = jfiltsu,jjm 586 DO k = 2,modemax 587 cof = rlamda(k) * COS( rlatu(j) ) 588 IF ( cof .LT. 1. ) GOTO 92 589 ENDDO 590 GOTO 94 591 92 modfrstu( j ) = k 592 ! 593 kf = modfrstu( j ) 594 DO k = kf , modemax 595 cof = rlamda(k) * COS( rlatu(j) ) 596 coefilu(k,j) = cof - 1. 597 coefilu2(k,j) = cof*cof - 1. 598 ENDDO 599 94 CONTINUE 600 ENDDO 601 ! 602 DO j = jfiltsv,jjm 603 DO k = 2,modemax 604 cof = rlamda(k) * COS( rlatv(j) ) 605 IF ( cof .LT. 1. ) GOTO 97 606 ENDDO 607 GOTO 99 608 97 modfrstv( j ) = k 609 ! 610 kf = modfrstv( j ) 611 DO k = kf , modemax 612 cof = rlamda(k) * COS( rlatv(j) ) 613 coefilv(k,j) = cof - 1. 614 coefilv2(k,j) = cof*cof - 1. 615 ENDDO 616 99 CONTINUE 617 ENDDO 618 ! 619 620 IF(jfiltnv.GE.jjm/2 .OR. jfiltnu.GE.jjm/2)THEN 621 ! Ehouarn: and what are these for??? Trying to handle a limit case 622 ! where filters extend to and meet at the equator? 623 IF(jfiltnv.EQ.jfiltsv)jfiltsv=1+jfiltnv 624 IF(jfiltnu.EQ.jfiltsu)jfiltsu=1+jfiltnu 625 626 PRINT *,'jfiltnv jfiltsv jfiltnu jfiltsu' , & 627 jfiltnv,jfiltsv,jfiltnu,jfiltsu 628 ENDIF 629 630 PRINT *,' Modes premiers v ' 631 PRINT 334,modfrstv 632 PRINT *,' Modes premiers u ' 633 PRINT 334,modfrstu 634 635 ! 636 ! ................................................................... 637 ! 638 ! ... Calcul de la matrice filtre 'matriceu' pour les champs situes 639 ! sur la grille scalaire ........ 640 ! ................................................................... 641 ! 642 DO j = 2, jfiltnu 643 644 DO i=1,iim 645 coff = coefilu(i,j) 646 IF( i.LT.modfrstu(j) ) coff = 0. 647 DO k=1,iim 648 eignft(i,k) = eignfnv(k,i) * coff 649 ENDDO 650 ENDDO ! of DO i=1,iim 651 #ifdef CRAY 652 CALL MXM( eignfnv,iim,eignft,iim,matriceun(1,1,j),iim ) 653 #else 654 #ifdef BLAS 655 CALL SGEMM ('N', 'N', iim, iim, iim, 1.0, & 656 eignfnv, iim, eignft, iim, 0.0, matriceun(1,1,j), iim) 657 #else 658 DO k = 1, iim 659 DO i = 1, iim 660 matriceun(i,k,j) = 0.0 661 DO ii = 1, iim 662 matriceun(i,k,j) = matriceun(i,k,j) & 663 + eignfnv(i,ii)*eignft(ii,k) 664 ENDDO 665 ENDDO 666 ENDDO ! of DO k = 1, iim 667 #endif 668 #endif 669 670 ENDDO ! of DO j = 2, jfiltnu 671 672 DO j = jfiltsu, jjm 673 674 DO i=1,iim 675 coff = coefilu(i,j) 676 IF( i.LT.modfrstu(j) ) coff = 0. 677 DO k=1,iim 678 eignft(i,k) = eignfnv(k,i) * coff 679 ENDDO 680 ENDDO ! of DO i=1,iim 681 #ifdef CRAY 682 CALL MXM(eignfnv,iim,eignft,iim,matriceus(1,1,j-jfiltsu+1),iim) 683 #else 684 #ifdef BLAS 685 CALL SGEMM ('N', 'N', iim, iim, iim, 1.0, & 686 eignfnv, iim, eignft, iim, 0.0, & 687 matriceus(1,1,j-jfiltsu+1), iim) 688 #else 689 DO k = 1, iim 690 DO i = 1, iim 691 matriceus(i,k,j-jfiltsu+1) = 0.0 692 DO ii = 1, iim 693 matriceus(i,k,j-jfiltsu+1) = matriceus(i,k,j-jfiltsu+1) & 694 + eignfnv(i,ii)*eignft(ii,k) 695 ENDDO 696 ENDDO 697 ENDDO ! of DO k = 1, iim 698 #endif 699 #endif 700 701 ENDDO ! of DO j = jfiltsu, jjm 702 703 ! ................................................................... 704 ! 705 ! ... Calcul de la matrice filtre 'matricev' pour les champs situes 706 ! sur la grille de V ou de Z ........ 707 ! ................................................................... 708 ! 709 DO j = 1, jfiltnv 710 711 DO i = 1, iim 712 coff = coefilv(i,j) 713 IF( i.LT.modfrstv(j) ) coff = 0. 714 DO k = 1, iim 715 eignft(i,k) = eignfnu(k,i) * coff 716 ENDDO 717 ENDDO 718 #ifdef CRAY 719 CALL MXM( eignfnu,iim,eignft,iim,matricevn(1,1,j),iim ) 720 #else 721 #ifdef BLAS 722 CALL SGEMM ('N', 'N', iim, iim, iim, 1.0, & 723 eignfnu, iim, eignft, iim, 0.0, matricevn(1,1,j), iim) 724 #else 725 DO k = 1, iim 726 DO i = 1, iim 727 matricevn(i,k,j) = 0.0 728 DO ii = 1, iim 729 matricevn(i,k,j) = matricevn(i,k,j) & 730 + eignfnu(i,ii)*eignft(ii,k) 731 ENDDO 732 ENDDO 733 ENDDO 734 #endif 735 #endif 736 737 ENDDO ! of DO j = 1, jfiltnv 738 739 DO j = jfiltsv, jjm 740 741 DO i = 1, iim 742 coff = coefilv(i,j) 743 IF( i.LT.modfrstv(j) ) coff = 0. 744 DO k = 1, iim 745 eignft(i,k) = eignfnu(k,i) * coff 746 ENDDO 747 ENDDO 748 #ifdef CRAY 749 CALL MXM(eignfnu,iim,eignft,iim,matricevs(1,1,j-jfiltsv+1),iim) 750 #else 751 #ifdef BLAS 752 CALL SGEMM ('N', 'N', iim, iim, iim, 1.0, & 753 eignfnu, iim, eignft, iim, 0.0, & 754 matricevs(1,1,j-jfiltsv+1), iim) 755 #else 756 DO k = 1, iim 757 DO i = 1, iim 758 matricevs(i,k,j-jfiltsv+1) = 0.0 759 DO ii = 1, iim 760 matricevs(i,k,j-jfiltsv+1) = matricevs(i,k,j-jfiltsv+1) & 761 + eignfnu(i,ii)*eignft(ii,k) 762 ENDDO 763 ENDDO 764 ENDDO 765 #endif 766 #endif 767 768 ENDDO ! of DO j = jfiltsv, jjm 769 770 ! ................................................................... 771 ! 772 ! ... Calcul de la matrice filtre 'matrinv' pour les champs situes 773 ! sur la grille scalaire , pour le filtre inverse ........ 774 ! ................................................................... 775 ! 776 DO j = 2, jfiltnu 777 778 DO i = 1,iim 779 coff = coefilu(i,j)/ ( 1. + coefilu(i,j) ) 780 IF( i.LT.modfrstu(j) ) coff = 0. 781 DO k=1,iim 782 eignft(i,k) = eignfnv(k,i) * coff 783 ENDDO 784 ENDDO 785 #ifdef CRAY 786 CALL MXM( eignfnv,iim,eignft,iim,matrinvn(1,1,j),iim ) 787 #else 788 #ifdef BLAS 789 CALL SGEMM ('N', 'N', iim, iim, iim, 1.0, & 790 eignfnv, iim, eignft, iim, 0.0, matrinvn(1,1,j), iim) 791 #else 792 DO k = 1, iim 793 DO i = 1, iim 794 matrinvn(i,k,j) = 0.0 795 DO ii = 1, iim 796 matrinvn(i,k,j) = matrinvn(i,k,j) & 797 + eignfnv(i,ii)*eignft(ii,k) 798 ENDDO 799 ENDDO 800 ENDDO 801 #endif 802 #endif 803 804 ENDDO ! of DO j = 2, jfiltnu 805 806 DO j = jfiltsu, jjm 807 808 DO i = 1,iim 809 coff = coefilu(i,j) / ( 1. + coefilu(i,j) ) 810 IF( i.LT.modfrstu(j) ) coff = 0. 811 DO k=1,iim 812 eignft(i,k) = eignfnv(k,i) * coff 813 ENDDO 814 ENDDO 815 #ifdef CRAY 816 CALL MXM(eignfnv,iim,eignft,iim,matrinvs(1,1,j-jfiltsu+1),iim) 817 #else 818 #ifdef BLAS 819 CALL SGEMM ('N', 'N', iim, iim, iim, 1.0, & 820 eignfnv, iim, eignft, iim, 0.0, matrinvs(1,1,j-jfiltsu+1), iim) 821 #else 822 DO k = 1, iim 823 DO i = 1, iim 824 matrinvs(i,k,j-jfiltsu+1) = 0.0 825 DO ii = 1, iim 826 matrinvs(i,k,j-jfiltsu+1) = matrinvs(i,k,j-jfiltsu+1) & 827 + eignfnv(i,ii)*eignft(ii,k) 828 ENDDO 829 ENDDO 830 ENDDO 831 #endif 832 #endif 833 834 ENDDO ! of DO j = jfiltsu, jjm 835 836 IF (use_filtre_fft) THEN 837 CALL Init_filtre_fft(coefilu,modfrstu,jfiltnu,jfiltsu, & 838 coefilv,modfrstv,jfiltnv,jfiltsv) 839 CALL Init_filtre_fft_loc(coefilu,modfrstu,jfiltnu,jfiltsu, & 840 coefilv,modfrstv,jfiltnv,jfiltsv) 841 ENDIF 842 843 ! ................................................................... 844 845 ! 846 334 FORMAT(1x,24i3) 847 755 FORMAT(1x,6f10.3,i3) 848 849 RETURN 850 END SUBROUTINE inifilr 851 852 853 def filtreg(dx, dy, champorig, nlat, nbniv, ifiltre, iaire, griscal ,iterv): 854 """c======================================================================= 855 c 856 c Auteur: P. Le Van 07/10/97 857 c ------ 858 c 859 c Objet: filtre matriciel longitudinal ,avec les matrices precalculees 860 c pour l'operateur Filtre . 861 c ------ 862 c 863 c Arguments: 864 c ---------- 865 c 866 c nblat nombre de latitudes a filtrer 867 c nbniv nombre de niveaux verticaux a filtrer 868 c champ(iip1,nblat,nbniv) en entree : champ a filtrer 869 c en sortie : champ filtre 870 c ifiltre +1 Transformee directe 871 c -1 Transformee inverse 872 c +2 Filtre directe 873 c -2 Filtre inverse 874 c 875 c iaire 1 si champ intensif 876 c 2 si champ extensif (pondere par les aires) 877 c 878 c iterv 1 filtre simple 879 c 880 c======================================================================= 881 c 882 c 883 c Variable Intensive 884 c ifiltre = 1 filtre directe 885 c ifiltre =-1 filtre inverse 886 c 887 c Variable Extensive 888 c ifiltre = 2 filtre directe 889 c ifiltre =-2 filtre inverse 890 c 891 """ 892 893 fname = 'filtreg' 894 first = True 895 896 sdd12 = np.zeros((dx,4), dtype = np.float) 897 898 champ = fortran_mat(champorig) 899 900 sddu, unsddu, sddv, unsddv = inifgn(dx, dy) 901 902 if first: 903 sdd12[:,type_sddu] = sddu 904 sdd12[:,type_sddv] = sddv 905 sdd12[:,type_unsddu] = unsddu 906 sdd12[:,type_unsddv] = unsddv 907 908 first=False 909 910 if ifiltre == 1 or ifiltre == -1: 911 print ' ' + fname + ': Pas de transformee simple dans cette version' 912 quit() 913 914 if iter == 2: 915 print errormsg 916 print ' ' + fname + ': Pas d iteration du filtre dans cette version !' 917 print ' Utiliser old_filtreg et repasser !' 918 quit() 919 920 if ifiltre == -2 and not griscal: 921 print errormsg 922 print ' ' + fname + ' Cette routine ne calcule le filtre inverse que ' + \ 923 ' sur la grille des scalaires !' 924 quit(-1) 925 926 if ifiltre != 2 and ifiltre != - 2: 927 print errormsg 928 print ' ' + fname + ': Probleme dans filtreg car ifiltre NE 2 et NE -2' + \ 929 ' corriger et repasser !' 930 quit(-1) 931 932 iim = dx 933 jjm = dy 934 935 iim2 = iim*iim 936 immjm = iim*jjm 937 938 if griscal: 939 if nlat != jjp1: 940 print errormsg 941 print ' ' + fname + ': 1111' 942 quit(-1) 943 else 944 if iaire == 1: 945 sdd1_type = type_sddv 946 sdd2_type = type_unsddv 947 else: 948 sdd1_type = type_unsddv 949 sdd2_type = type_sddv 950 951 jdfil1 = 2 952 jffil1 = jfiltnu 953 jdfil2 = jfiltsu 954 jffil2 = jjm 955 else: 956 if nlat != jjm: 957 print errormsg 958 print ' ' + fname + ': 2222' 959 quit(-1) 960 else: 961 if iaire == 1: 962 sdd1_type = type_sddu 963 sdd2_type = type_unsddu 964 else: 965 sdd1_type = type_unsddu 966 sdd2_type = type_sddu 967 968 969 jdfil1 = 1 970 jffil1 = jfiltnv 971 jdfil2 = jfiltsv 972 jffil2 = jjm 973 974 for hemisph in range(1,3): 975 if (hemisph == 1 ): 976 jdfil = jdfil1 977 jffil = jffil1 978 else: 979 jdfil = jdfil2 980 jffil = jffil2 981 982 for l in range(nbniv): 983 for j in rangE(jdfil,jffil): 984 for i in range(iim): 985 champ[i,j,l] = champ[i,j,l]*sdd12[i,sdd1_type] # sdd1(i) 986 987 if hemisph == 1: 988 if ifiltre == -2: 989 for j in range(jdfil,jffil): 990 eignq[:,j-jdfil+1,:] = np.matmul(matrinvn[:,:,j], champ[:,j,:]) 991 #endif 992 END DO 993 994 ELSE IF ( griscal ) THEN 995 996 DO j = jdfil,jffil 997 #ifdef BLAS 998 CALL SGEMM("N", "N", iim, nbniv, iim, 1.0, 999 & matriceun(1,1,j), 1000 & iim, champ(1,j,1), iip1*nlat, 0.0, 1001 & eignq(1,j-jdfil+1,1), iim*nlat) 1002 #else 1003 eignq(:,j-jdfil+1,:) 1004 $ = matmul(matriceun(:,:,j), champ(:iim,j,:)) 1005 #endif 1006 END DO 1007 1008 ELSE 1009 1010 DO j = jdfil,jffil 1011 #ifdef BLAS 1012 CALL SGEMM("N", "N", iim, nbniv, iim, 1.0, 1013 & matricevn(1,1,j), 1014 & iim, champ(1,j,1), iip1*nlat, 0.0, 1015 & eignq(1,j-jdfil+1,1), iim*nlat) 1016 #else 1017 eignq(:,j-jdfil+1,:) 1018 $ = matmul(matricevn(:,:,j), champ(:iim,j,:)) 1019 #endif 1020 END DO 1021 1022 ENDIF 1023 1024 ELSE 1025 1026 IF( ifiltre. EQ. -2 ) THEN 1027 1028 DO j = jdfil,jffil 1029 #ifdef BLAS 1030 CALL SGEMM("N", "N", iim, nbniv, iim, 1.0, 1031 & matrinvs(1,1,j-jfiltsu+1), 1032 & iim, champ(1,j,1), iip1*nlat, 0.0, 1033 & eignq(1,j-jdfil+1,1), iim*nlat) 1034 #else 1035 eignq(:,j-jdfil+1,:) 1036 $ = matmul(matrinvs(:,:,j-jfiltsu+1), 1037 $ champ(:iim,j,:)) 1038 #endif 1039 END DO 1040 1041 1042 ELSE IF ( griscal ) THEN 1043 1044 DO j = jdfil,jffil 1045 #ifdef BLAS 1046 CALL SGEMM("N", "N", iim, nbniv, iim, 1.0, 1047 & matriceus(1,1,j-jfiltsu+1), 1048 & iim, champ(1,j,1), iip1*nlat, 0.0, 1049 & eignq(1,j-jdfil+1,1), iim*nlat) 1050 #else 1051 eignq(:,j-jdfil+1,:) 1052 $ = matmul(matriceus(:,:,j-jfiltsu+1), 1053 $ champ(:iim,j,:)) 1054 #endif 1055 END DO 1056 1057 ELSE 1058 1059 DO j = jdfil,jffil 1060 #ifdef BLAS 1061 CALL SGEMM("N", "N", iim, nbniv, iim, 1.0, 1062 & matricevs(1,1,j-jfiltsv+1), 1063 & iim, champ(1,j,1), iip1*nlat, 0.0, 1064 & eignq(1,j-jdfil+1,1), iim*nlat) 1065 #else 1066 eignq(:,j-jdfil+1,:) 1067 $ = matmul(matricevs(:,:,j-jfiltsv+1), 1068 $ champ(:iim,j,:)) 1069 #endif 1070 END DO 1071 1072 ENDIF 1073 1074 ENDIF 1075 1076 IF( ifiltre.EQ. 2 ) THEN 1077 1078 DO l = 1, nbniv 1079 DO j = jdfil,jffil 1080 DO i = 1, iim 1081 champ( i,j,l ) = 1082 & (champ(i,j,l) + eignq(i,j-jdfil+1,l)) 1083 & * sdd12(i,sdd2_type) ! sdd2(i) 1084 END DO 1085 END DO 1086 END DO 1087 1088 ELSE 1089 1090 DO l = 1, nbniv 1091 DO j = jdfil,jffil 1092 DO i = 1, iim 1093 champ( i,j,l ) = 1094 & (champ(i,j,l) - eignq(i,j-jdfil+1,l)) 1095 & * sdd12(i,sdd2_type) ! sdd2(i) 1096 END DO 1097 END DO 1098 END DO 1099 1100 ENDIF 1101 1102 DO l = 1, nbniv 1103 DO j = jdfil,jffil 1104 champ( iip1,j,l ) = champ( 1,j,l ) 1105 END DO 1106 END DO 1107 1108 1109 ENDDO 1110 1111 1111 FORMAT(//20x,'ERREUR dans le dimensionnement du tableau CHAMP a 1112 & filtrer, sur la grille des scalaires'/) 1113 2222 FORMAT(//20x,'ERREUR dans le dimensionnement du tableau CHAMP a fi 1114 & ltrer, sur la grille de V ou de Z'/) 1115 RETURN 1116 END 1117 1118 def SSUM(n,sx,incx): 1119 """ Obsolete version of sum for non Fortan 90 code 1120 from dyn3d/cray.F 1121 """ 1122 1123 ssumv = 0. 1124 1125 ix = 0 1126 1127 for i in range(n) 1128 ssumv=ssumv+sx[ix] 1129 ix=ix+incx 1130 1131 return ssumv 1132 1133 def SCOPY(n,sx,incx,sy,incy): 1134 """ Obsolete function to copy matrix values 1135 from dyn3d/cray.F 1136 """ 1137 iy = 1 1138 ix = 1 1139 1140 for i in range(n): 1141 sy[iy] = sx[ix] 1142 ix = ix+incx 1143 iy = iy+incy 1144 1145 return sy 1146 1147 def exner_hyb (dx, dy, dz, psv, pv, alphav, betav) 1148 """c 1149 c Auteurs : P.Le Van , Fr. Hourdin . 1150 c .......... 1151 c 1152 c .... ngrid, ps,p sont des argum.d'entree au sous-prog ... 1153 c .... alpha,beta, pks,pk,pkf sont des argum.de sortie au sous-prog ... 1154 c 1155 c ************************************************************************ 1156 c Calcule la fonction d'Exner pk = Cp * p ** kappa , aux milieux des 1157 c couches . Pk(l) sera calcule aux milieux des couches l ,entre les 1158 c pressions p(l) et p(l+1) ,definis aux interfaces des llm couches . 1159 c ************************************************************************ 1160 c .. N.B : Au sommet de l'atmosphere, p(llm+1) = 0. , et ps et pks sont 1161 c la pression et la fonction d'Exner au sol . 1162 c 1163 c -------- z 1164 c A partir des relations ( 1 ) p*dz(pk) = kappa *pk*dz(p) et 1165 c ( 2 ) pk(l) = alpha(l)+ beta(l)*pk(l-1) 1166 c ( voir note de Fr.Hourdin ) , 1167 c 1168 c on determine successivement , du haut vers le bas des couches, les 1169 c coef. alpha(llm),beta(llm) .,.,alpha(l),beta(l),,,alpha(2),beta(2), 1170 c puis pk(ij,1). Ensuite ,on calcule,du bas vers le haut des couches, 1171 c pk(ij,l) donne par la relation (2), pour l = 2 a l = llm . 1172 c 1173 """ 1174 1175 fname = 'exner_hyb' 1176 1177 pks = np.zeros((dy, dx), dtype=np.float) 1178 pk = np.zeros((dz, dy, dx), dtype=np.float) 1179 pkf = np.zeros((dz, dy, dx), dtype=np.float) 1180 1181 if dz == 1: 1182 # Compute pks(:),pk(:),pkf(:) 1183 pks = (cpp/preff)*ps 1184 pk[0,:,:] = 0.5*pks 1185 # CALL SCOPY ( ngrid * llm, pk, 1, pkf, 1 ) is the same as the next line? 1186 pkf = pk 1187 1188 # No filtering... not necessary on aquaplanet 1189 # CALL filtreg ( pkf, jmp1, llm, 2, 1, .TRUE., 1 ) 1190 1191 # our work is done, exit routine 1192 return pksv, pkv, pkfv 1193 1194 #!!!! General case: 1195 1196 unpl2k = 1.+ 2.* kappa 1197 1198 for ij in range(ngrid): 1199 pks[ij] = cpp * ( ps[ij]/preff ) ** kappa 1200 1201 for ij in range(iim): 1202 ppn[ij] = aire[ij] * pks[ij] 1203 pps[ij] = aire[ij+ip1jm] * pks[ij+ip1jm] 1204 1205 xpn = SSUM(iim,ppn,1) /apoln 1206 xps = SSUM(iim,pps,1) /apols 1207 1208 for ij in range(iip1): 1209 pks[ij] = xpn 1210 pks[ij+ip1jm] = xps 1211 # 1212 # 1213 # .... Calcul des coeff. alpha et beta pour la couche l = llm .. 1214 # 1215 for ij in range(ngrid): 1216 alpha[ij,llm] = 0. 1217 beta [ij,llm] = 1./ unpl2k 1218 1219 # 1220 # ... Calcul des coeff. alpha et beta pour l = llm-1 a l = 2 ... 1221 # 1222 for l in range (llm-1,1,-1): 1223 c 1224 for ij in range(ngrid): 1225 dellta = p[ij,l]* unpl2k + p[ij,l+1]* ( beta[ij,l+1]-unpl2k ) 1226 alpha[ij,l] = -p[ij,l+1] / dellta * alpha[ij,l+1] 1227 beta[ij,l] = p[ij,l] / dellta 1228 1229 # *********************************************************************** 1230 # ..... Calcul de pk pour la couche 1 , pres du sol .... 1231 # 1232 for ij in range(ngrid): 1233 pk[ij,0] = ( p[ij,0]*pks[ij] - 0.5*alpha[ij,1]*p[ij,1] ) \ 1234 *( p[ij,0]* (1.+kappa) + 0.5*( beta[ij,1]-unpl2k )* p[ij,1] ) 1235 1236 # 1237 # ..... Calcul de pk(ij,l) , pour l = 2 a l = llm ........ 1238 # 1239 for l in range(1,llm): 1240 for ij in range(ngrid): 1241 pk[ij,l] = alpha[ij,l] + beta[ij,l] * pk[ij,l-1] 1242 # 1243 # 1244 pkfv = SCOPY ( ngrid * llm, pk, 1, pkfv, 1 ) 1245 1246 # We do not filter for iniaqua 1247 # CALL filtreg ( pkf, jmp1, llm, 2, 1, .TRUE., 1 ) 1248 1249 return pksv, pkv, pkfv 1250 1251 def exner_milieu ( ngrid, ps, p,beta, pks, pk, pkf ): 1252 """c 1253 c Auteurs : F. Forget , Y. Wanherdrick 1254 c P.Le Van , Fr. Hourdin . 1255 c .......... 1256 c 1257 c .... ngrid, ps,p sont des argum.d'entree au sous-prog ... 1258 c .... beta, pks,pk,pkf sont des argum.de sortie au sous-prog ... 1259 c 1260 c ************************************************************************ 1261 c Calcule la fonction d'Exner pk = Cp * (p/preff) ** kappa , aux milieux des 1262 c couches . Pk(l) sera calcule aux milieux des couches l ,entre les 1263 c pressions p(l) et p(l+1) ,definis aux interfaces des llm couches . 1264 c ************************************************************************ 1265 c .. N.B : Au sommet de l'atmosphere, p(llm+1) = 0. , et ps et pks sont 1266 c la pression et la fonction d'Exner au sol . 1267 c 1268 c WARNING : CECI est une version speciale de exner_hyb originale 1269 c Utilise dans la version martienne pour pouvoir 1270 c tourner avec des coordonnees verticales complexe 1271 c => Il ne verifie PAS la condition la proportionalite en 1272 c energie totale/ interne / potentielle (F.Forget 2001) 1273 c ( voir note de Fr.Hourdin ) , 1274 c 1275 """ 1276 fname = 'exner_milieu' 1277 1278 pks = np.zeros((dy, dx), dtype=np.float) 1279 pk = np.zeros((dz, dy, dx), dtype=np.float) 1280 pkf = np.zeros((dz, dy, dx), dtype=np.float) 1281 1282 ppn = np.zeros((iim), dtype=np.float)) 1283 ppn = np.zeros((iim), dtype=np.float)) 1284 1285 firstcall = True 1286 modname = 'exner_milieu' 1287 1288 # Sanity check 1289 if firstcall: 1290 # sanity checks for Shallow Water case (1 vertical layer) 1291 if llm == 1: 1292 if kappa != 1: 1293 print errormsg 1294 print ' ' + fname+ ': kappa!=1 , but running in Shallow Water mode!!' 1295 quit(-1) 1296 if cpp != r: 1297 print errormsg 1298 print ' ' + fname+ ': cpp!=r , but running in Shallow Water mode!!' 1299 quit(-1) 1300 1301 1302 firstcall = False 1303 1304 1305 #### Specific behaviour for Shallow Water (1 vertical layer) case: 1306 if llm == 1: 1307 1308 # Compute pks(:),pk(:),pkf(:) 1309 1310 for ij in range(ngrid): 1311 pks[ij] = (cpp/preff) * ps[ij] 1312 pk[ij,1] = .5*pks[ij] 1313 1314 1315 pkf = SCOPY( ngrid * llm, pk, 1, pkf, 1 ) 1316 # We do not filter for iniaqua 1317 # CALL filtreg ( pkf, jmp1, llm, 2, 1, .TRUE., 1 ) 1318 1319 # our work is done, exit routine 1320 return pksv, pkv, pkfv 1321 1322 1323 #### General case: 1324 1325 # ------------- 1326 # Calcul de pks 1327 # ------------- 1328 1329 for ij in range(ngrid): 1330 pks[ij] = cpp * ( ps[ij]/preff ) ** kappa 1331 1332 for ij in range(iim) 1333 ppn[ij] = aire[ij] * pks[ij] 1334 pps[ij] = aire[ij+ip1jm] * pks[ij+ip1jm] 1335 1336 xpn = SSUM(iim,ppn,1) /apoln 1337 xps = SSUM(iim,pps,1) /apols 1338 1339 for ij in range(iip1) 1340 pks[ij] = xpn 1341 pks[ij+ip1jm] = xps 1342 1343 # 1344 # 1345 # .... Calcul de pk pour la couche l 1346 # -------------------------------------------- 1347 # 1348 dum1 = cpp * (2*preff)**(-kappa) 1349 for l in range(llm-1): 1350 for ij in range(ngrid): 1351 pk[ij,l] = dum1 * (p[ij,l] + p[ij,l+1])**kappa 1352 1353 # .... Calcul de pk pour la couche l = llm .. 1354 # (on met la meme distance (en log pression) entre Pk(llm) 1355 # et Pk(llm -1) qu'entre Pk(llm-1) et Pk(llm-2) 1356 1357 for ij in range(ngrid): 1358 pk[ij,llm] = pk[ij,llm-1]**2 / pk[ij,llm-2] 1359 1360 # calcul de pkf 1361 # ------------- 1362 pkf = SCOPY( ngrid * llm, pk, 1, pkf, 1 ) 1363 1364 # We do not filter iniaqua 1365 # CALL filtreg ( pkf, jmp1, llm, 2, 1, .TRUE., 1 ) 1366 1367 # EST-CE UTILE ?? : calcul de beta 1368 # -------------------------------- 1369 for l in range(1, llm): 1370 for ij in range(ngrid): 1371 beta[ij,l] = pk[ij,l] / pk[ij,l-1] 1372 1373 return pksv, pkv, pkfv 1374 1375 def pression(dx, dy, dz, apv, bpv, psv) 1376 """c 1377 1378 c Auteurs : P. Le Van , Fr.Hourdin . 1379 1380 c ************************************************************************ 1381 c Calcule la pression p(l) aux differents niveaux l = 1 ( niveau du 1382 c sol) a l = llm +1 ,ces niveaux correspondant aux interfaces des (llm) 1383 c couches , avec p(ij,llm +1) = 0. et p(ij,1) = ps(ij) . 1384 c ************************************************************************ 1385 c 1386 """ 1387 fname = 'pression' 1388 1389 press = np.zeros((dz, dy, dx), dtype=np.float) 1390 1391 for l in range(dz+1): 1392 press[l,:,:] = apv[l] + bpv[l]*psv[:,:] 1393 1394 return press 22 1395 23 1396 def sig_hybrid(sig,pa,preff): … … 76 1449 return nsig 77 1450 78 def presnivs_calc(hybrid, dz): 1451 def presnivs_calc(vert_sampling, dz): 1452 """ From dyn3d/disvert.F calculation of vertical pressure levels 1453 vert_sampling= which kind of vertical sampling is desired: "param", "tropo", 1454 "strato" and "read" 1455 dz= numbef of vertical layers 1456 """ 1457 1458 fname = 'presnivs_calc' 1459 1460 llmp1 = dz + 1 1461 pnivs = np.zeros((dz), dtype=np.float) 1462 s = np.zeros((dz), dtype=np.float) 1463 sig = np.zeros((dz+1), dtype=np.float) 1464 dsig = np.zeros((dz), dtype=np.float) 1465 dpres = np.zeros((dz), dtype=np.float) 1466 ap = np.zeros((dz+1), dtype=np.float) 1467 bp = np.zeros((dz+1), dtype=np.float) 1468 1469 # default scaleheight is 8km for earth 1470 scaleheight = 8. 1471 1472 # vert_sampling = merge("strato", "tropo ", ok_strato) ! default value 1473 1474 if vert_sampling == 'param': 1475 # On lit les options dans sigma.def: 1476 if not os.path.isfile('easig.def'): 1477 print errormsg 1478 print ' ' + fname + ": parameters file 'easig.def' does not exist!!" 1479 quit(-1) 1480 1481 sfobj = open('sigma.def', 'r') 1482 scaleheight = np.float( ncvar.reduce_spaces(fobj.readline())) 1483 deltaz = np.float( ncvar.reduce_spaces(fobj.readline())) 1484 beta = np.float( ncvar.reduce_spaces(fobj.readline())) 1485 k0 = np.float( ncvar.reduce_spaces(fobj.readline())) 1486 k1 = np.float( ncvar.reduce_spaces(fobj.readline())) 1487 sfobj.close() 1488 1489 alpha = deltaz/(dz*scaleheight) 1490 print ':scaleheight, alpha, k0, k1, beta', scaleheight, alpha, k0, k1, beta 1491 1492 alpha=deltaz/np.tanh(1./k0)*2. 1493 zkm1=0. 1494 sig[0]=1. 1495 for l in range(dz): 1496 sig[l+1]=(np.cosh(l/k0))**(-alpha*k0/scaleheight) \ 1497 *exp(-alpha/scaleheight*np.tanh((llm-k1)/k0) \ 1498 *beta**(l-(llm-k1))/np.log(beta)) 1499 1500 zk=-scaleheight*np.log(sig[l+1]) 1501 1502 dzk1=alpha*np.tanh(l/k0) 1503 dzk2=alpha*np.tanh((llm-k1)/k0)*beta**(l-(llm-k1))/np.log(beta) 1504 1505 print l, sig(l+1), zk, zk-zkm1, dzk1, dzk2 1506 zkm1=zk 1507 1508 sig[dz-1]=0. 1509 1510 bp[0:dz] = np.exp(1.-1./sig[0:dz]**2) 1511 bp[llmp1-1] = 0. 1512 1513 ap = pa * (sig - bp) 1514 1515 elif vert_sampling == 'tropo': 1516 for l in range(dz): 1517 x = 2.*np.arcsin(1.)*(l-0.5)/(dz+1.) 1518 dsig[l] = 1.0+7.0*np.sin(x)**2 1519 1520 dsig = dsig/np.sum(dsig) 1521 sig[dz] = 0. 1522 for l in range(dz-1,0,-1): 1523 sig[l] = sig[l+1] + dsig[l] 1524 1525 bp[0]=1. 1526 bp[1:dz] = np.exp(1.-1./sig[1:dz]**2) 1527 bp[llmp1-1] = 0. 1528 1529 ap[0] = 0. 1530 ap[1:dz+1] = pa*(sig[1:dz+1]-bp[1:dz+1]) 1531 1532 elif vert_sampling == 'strato': 1533 if dz == 39: 1534 dsigmin = 0.3 1535 elif dz == 50: 1536 dsigmin = 1. 1537 else: 1538 print ' ATTENTION discretisation z a ajuster' 1539 dsigmin = 1. 1540 1541 print 'Discretisation verticale DSIGMIN=',dsigmin 1542 1543 for l in range(dz): 1544 x = 2.*np.arcsin(1.)*(l - 0.5)/(dz+1) 1545 dsig[l] =(dsigmin+7.*np.sin(x)**2) \ 1546 *(0.5*(1.-np.tanh(1.*(x-np.arcsin(1.))/np.arcsin(1.))))**2 1547 1548 dsig = dsig/np.sum(dsig) 1549 sig[dz] = 0. 1550 for l in range(dz-1,0,-1): 1551 sig[l] = sig[l+1] + dsig[l] 1552 1553 bp[0] = 1. 1554 bp[1:dz] = np.exp(1.-1./sig[1:dz]**2) 1555 bp[llmp1-1] = 0. 1556 1557 ap[0] = 0. 1558 ap[1:dz+1] = pa*(sig[1:dz+1] - bp[1:dz+1]) 1559 1560 elif vert_sampling == 'read': 1561 # Read "ap" and "bp". First line is skipped (title line). "ap" 1562 # should be in Pa. First couple of values should correspond to 1563 # the surface, that is : "bp" should be in descending order. 1564 if not os.path.isfile('hybrid.txt'): 1565 print errormsg 1566 print ' ' + fname + ": parameters file 'hybrid.txt' does not exist!!" 1567 quit(-1) 1568 sfobj = ('hybrid.txt', 'r') 1569 # skip title line 1570 title = sfobj.readline() 1571 for l in range(dz+1): 1572 values = ncvar.readuce_space(sfobj.readline()) 1573 ap[l] = np.float(values[0]) 1574 bp[l] = np.float(values[0]) 1575 1576 sfobj.close() 1577 if ap[0] == 0. or ap[dz+1] == 0. or bp[0] == 1. or bp[dz+1] == 0.: 1578 print errormsg 1579 print ' ' + fname + ': bad ap or bp values !!' 1580 print ' k ap bp ___________' 1581 for k in range(dz+1): 1582 print k, ap[k], bp[k] 1583 1584 else: 1585 print errormsg 1586 print ' ' + fname + ': wrong value for vert_sampling:', vert_sampling 1587 quit(-1) 1588 1589 1590 nivsigs = np.arange(dz)*1.+1. 1591 nivsig = np.arange(llmp1)*1.+1. 1592 1593 print ' ' + fname + ': k BP AP ________' 1594 for k in range(dz+1): 1595 print k, bp[k], ap[k] 1596 1597 print 'Niveaux de pressions approximatifs aux centres des' 1598 print 'couches calcules pour une pression de surface =', preff 1599 print 'et altitudes equivalentes pour une hauteur d echelle de ' 1600 print scaleheight,' km' 1601 1602 for l in range(dz): 1603 dpres[l] = bp[l] - bp[l+1] 1604 pnivs[l] = 0.5*( ap[l]+bp[l]*preff + ap[l+1]+bp[l+1]*preff ) 1605 print ' PRESNIVS(', l, ')=', pnivs[l], ' Z ~ ', \ 1606 np.log(preff/pnivs[l])*scaleheight, ' DZ ~ ', \ 1607 scaleheight*np.log((ap[l]+bp[l]*preff)/ \ 1608 np.max([ap[l+1]+bp[l+1]*preff, 1.e-10])) 1609 1610 print ' ' + fname + ': PRESNIVS [Pa]:', pnivs 1611 1612 return pnivs 1613 1614 1615 def presnivs_calc_noterre(hybrid, dz): 79 1616 """ From dyn3d/disvert_noterre.F calculation of vertical pressure levels 80 1617 hybrid= whether hydbrid coordinates have to be used … … 82 1619 """ 83 1620 84 fname = 'presnivs_calc '1621 fname = 'presnivs_calc_noterre' 85 1622 86 1623 #----------------------------------------------------------------------- … … 272 1809 return longitude, latitude 273 1810 1811 def massdair(p): 1812 """c 1813 c ********************************************************************* 1814 c .... Calcule la masse d'air dans chaque maille .... 1815 c ********************************************************************* 1816 c 1817 c Auteurs : P. Le Van , Fr. Hourdin . 1818 c .......... 1819 c 1820 c .. p est un argum. d'entree pour le s-pg ... 1821 c .. masse est un argum.de sortie pour le s-pg ... 1822 c 1823 c .... p est defini aux interfaces des llm couches ..... 1824 c 1825 """ 1826 fname = 'massdair' 1827 1828 masse = np.zeros((ip1jmp1,llm), dtype=np.float) 1829 # 1830 # 1831 # Methode pour calculer massebx et masseby . 1832 # ---------------------------------------- 1833 # 1834 # A chaque point scalaire P (i,j) est affecte 4 coefficients d'aires 1835 # alpha1(i,j) calcule au point ( i+1/4,j-1/4 ) 1836 # alpha2(i,j) calcule au point ( i+1/4,j+1/4 ) 1837 # alpha3(i,j) calcule au point ( i-1/4,j+1/4 ) 1838 # alpha4(i,j) calcule au point ( i-1/4,j-1/4 ) 1839 # 1840 # Avec alpha1(i,j) = aire(i+1/4,j-1/4)/ aire(i,j) 1841 # 1842 # N.B . Pour plus de details, voir s-pg ... iniconst ... 1843 # 1844 # 1845 # 1846 # alpha4 . . alpha1 . alpha4 1847 # (i,j) (i,j) (i+1,j) 1848 # 1849 # P . U . . P 1850 # (i,j) (i,j) (i+1,j) 1851 # 1852 # alpha3 . . alpha2 .alpha3 1853 # (i,j) (i,j) (i+1,j) 1854 # 1855 # V . Z . . V 1856 # (i,j) 1857 # 1858 # alpha4 . . alpha1 .alpha4 1859 # (i,j+1) (i,j+1) (i+1,j+1) 1860 # 1861 # P . U . . P 1862 # (i,j+1) (i+1,j+1) 1863 # 1864 # 1865 # 1866 # On a : 1867 # 1868 # massebx(i,j) = masse(i ,j) * ( alpha1(i ,j) + alpha2(i,j)) + 1869 # masse(i+1,j) * ( alpha3(i+1,j) + alpha4(i+1,j) ) 1870 # localise au point ... U (i,j) ... 1871 # 1872 # masseby(i,j) = masse(i,j ) * ( alpha2(i,j ) + alpha3(i,j ) + 1873 # masse(i,j+1) * ( alpha1(i,j+1) + alpha4(i,j+1) 1874 # localise au point ... V (i,j) ... 1875 # 1876 # 1877 #======================================================================= 1878 1879 for l in range (llm): 1880 for ij in range(ip1jmp1): 1881 masse[ij,l] = airesurg[ij] * ( p[ij,l] - p[ij,l+1] ) 1882 1883 for ij in range(ip1jmp1,iip1) 1884 masse[ij+iim,l] = masse[ij,l] 1885 1886 return masse 1887 1888 def geopot(ngrid, teta, pk, pks) 1889 """c======================================================================= 1890 c 1891 c Auteur: P. Le Van 1892 c ------- 1893 c 1894 c Objet: 1895 c ------ 1896 c 1897 c ******************************************************************* 1898 c .... calcul du geopotentiel aux milieux des couches ..... 1899 c ******************************************************************* 1900 c 1901 c .... l'integration se fait de bas en haut .... 1902 c 1903 c .. ngrid,teta,pk,pks,phis sont des argum. d'entree pour le s-pg .. 1904 c phi est un argum. de sortie pour le s-pg . 1905 c 1906 c======================================================================= 1907 """ 1908 fname = 'geopot' 1909 1910 phis = np.zeros((ngrid), dtype=np.float) 1911 phi = np.zeros((ngrid,llm), dtype=np.float) 1912 1913 #----------------------------------------------------------------------- 1914 # calcul de phi au niveau 1 pres du sol ..... 1915 1916 for ij in range(ngrid): 1917 phi[ij,1] = phis[ij] + teta[ij,0] * ( pks[ij] - pk[ij,0] ) 1918 1919 # calcul de phi aux niveaux superieurs ....... 1920 1921 for l in range(1,llm): 1922 for ij in range(ngrid): 1923 phi[ij,l] = phi[ij,l-1] + 0.5 * ( teta[ij,l]+teta[ij,l-1] ) * \ 1924 ( pk[ij,l-1]-pk[ij,l] ) 1925 1926 return phis, phi 1927 1928 def dump2d(im,jm,nom_z): 1929 """ Function to create a dump 2d variable 1930 from dyn3d/dump2d.F 1931 """ 1932 fname = 'dump2d' 1933 1934 z = np.zeros((im,jm), dtype=np.float) 1935 1936 zmin = z[0,0] 1937 zllm = z[0,0] 1938 imin = 0 1939 illm = 0 1940 jmin = 0 1941 jllm = 0 1942 1943 for j in range(jm): 1944 for i in range(im): 1945 if z[i,j] > zllm: 1946 illm=i 1947 jllm=j 1948 zllm=z[i,j] 1949 1950 if z[i,j] < zmin: 1951 imin=i 1952 jmin=j 1953 zmin=z[i,j] 1954 1955 print 'MIN:',zmin 1956 print 'MAX:',zllm 1957 1958 if zllm > zmin: 1959 for j in range(jm): 1960 print int(10.*(z[:,j]-zmin)/(zllm-zmin)) 1961 1962 return z 1963 1964 def ugeostr(phi): 1965 """! Calcul du vent covariant geostrophique a partir du champ de 1966 ! geopotentiel. 1967 ! We actually compute: (1 - cos^8 \phi) u_g 1968 ! to have a wind going smoothly to 0 at the equator. 1969 ! We assume that the surface pressure is uniform so that model 1970 ! levels are pressure levels. 1971 """ 1972 fname = 'ugeostr' 1973 ucov = np.zeros((iip1,jjp1,llm), dtype=np.float) 1974 um = np.zeros((jjm,llm), dtype=np.float) 1975 u = np.zeros((iip1,jjm,llm), dtype=np.float) 1976 1977 1978 for j in range(jjm) 1979 1980 if np.abs(np.sin(rlatv[j])) < 1.e-4: 1981 zlat = 1.e-4 1982 else: 1983 zlat=rlatv(j) 1984 1985 fact = np.cos(zlat) 1986 fact = fact*fact 1987 fact = fact*fact 1988 fact = fact*fact 1989 fact = (1.-fact)/ (2.*omeg*sin(zlat)*(rlatu[j+1]-rlatu[j])) 1990 fact = -fact/rad 1991 for l in range(llm): 1992 for i in range(iim): 1993 u[i,j,l] = fact*(phi[i,j+1,l]-phi[i,j,l]) 1994 um[j,l]=um[j,l]+u[i,j,l]/np.float(iim) 1995 1996 um = dump2d(jjm,llm,'Vent-u geostrophique') 1997 1998 # calcul des champ de vent: 1999 2000 for l in range(llm): 2001 for i in range(iip1): 2002 ucov[i,1,l]=0. 2003 ucov[i,jjp1,l]=0. 2004 for j in range(1,jjm): 2005 for i in range(iim): 2006 ucov[i,j,l] = 0.5*(u[i,j,l]+u[i,j-1,l])*cu[i,j] 2007 2008 ucov[iip1,j,l]=ucov[0,j,l] 2009 2010 return ucov 2011 2012 def RAN1(IDUM, Nvals): 2013 """ Function to generate Nvals random numbers 2014 from dyn3d/ran1.F 2015 IDUM= Random Seed 2016 Nvals= number of values 2017 """ 2018 fname = 'RAN1' 2019 Nvals = 97 2020 2021 R = np.zeros((Nvals), dtype=np.float) 2022 2023 M1 = 259200 2024 IA1 = 7141 2025 IC1 = 54773 2026 RM1 = 3.8580247E-6 2027 M2 = 134456 2028 IA2 = 8121 2029 IC2 = 28411 2030 RM2 = 7.4373773E-6 2031 M3 = 243000 2032 IA3 = 4561 2033 IC3 = 51349 2034 2035 if IDUM < 0 or IFF == 0: 2036 IFF = 1 2037 IX1 = np.mod(IC1-IDUM,M1) 2038 IX1 = np.mod(IA1*IX1+IC1,M1) 2039 IX2 = np.mod(IX1,M2) 2040 IX1 = np.mod(IA1*IX1+IC1,M1) 2041 IX3 = np.mod(IX1,M3) 2042 for J in range(Nvals): 2043 IX1 = np.mod(IA1*IX1+IC1,M1) 2044 IX2 = np.mod(IA2*IX2+IC2,M2) 2045 R[J] = (np.float(IX1)+np.float(IX2)*RM2)*RM1 2046 2047 IDUM=1 2048 2049 IX1 = np.mod(IA1*IX1+IC1,M1) 2050 IX2 = np.mod(IA2*IX2+IC2,M2) 2051 IX3 = np.mod(IA3*IX3+IC3,M3) 2052 J = 1+(Nvals*IX3)/M3 2053 if J > Nvals or J lt 1: quit() 2054 ran1=R[J] 2055 R[J]=(np.float(IX1)+np.float(IX2)*RM2)*RM1 2056 2057 return ran1 2058 2059 274 2060 ####### ###### ##### #### ### ## # 275 2061 … … 281 2067 parser.add_option("-d", "--dimensions", dest="dims", 282 2068 help="dimensions of the initial conditions: dimx,dimy,dimz", metavar="VALUES") 2069 parser.add_option("-p", "--pressure_exner", dest="pexner, 2070 help="how as to b computed Exner pressure ('hybrid': hybrid coordinates, 'middle': middle layer)", 2071 metavar="VALUE") 283 2072 parser.add_option("-t", "--time", dest="time", 284 2073 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") 2074 parser.add_option("-z", "--z_levels", type='choice', dest="znivs", 2075 choices=['param', 'tropo', 'strato', 'read'], 2076 help="which kind of vertical levels have to be computed ('param', 'tropo', 'strato', 'read')", 2077 metavar="VAR") 287 2078 288 2079 (opts, args) = parser.parse_args() … … 317 2108 dimy = int(opts.dims.split(',')[1]) 318 2109 dimz = int(opts.dims.split(',')[2]) 319 320 if opts.hybrid == 'true':321 hybrid_calc = True322 else:323 hybrid_calc = False324 2110 325 2111 ofile = 'iniaqua.nc' … … 373 2159 gam_pv=4. 374 2160 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) 2161 # For extra-terrestrial planets 2162 #presnivs, pseudoalt = presnivs_calc_noterre(opts.znivs, dimz) 2163 presnivs = presnivs_calc(opts.znivs, dimz) 2164 lon, lat = global_lonlat(dimy,dimx) 2165 lonu, latu = global_lonlat(dimy,dimx+1) 2166 lonv, latv = global_lonlat(dimy+1,dimx) 379 2167 380 2168 # 2. Initialize fields towards which to relax … … 383 2171 knewt_t = np.zeros((dimz), dtype=np.float) 384 2172 kfrict = np.zeros((dimz), dtype=np.float) 385 clat4 = np.zeros((dimy+1, dimx ), dtype=np.float)2173 clat4 = np.zeros((dimy+1, dimx+1), dtype=np.float) 386 2174 387 2175 # Friction … … 393 2181 394 2182 for j in 1,range(dimy+1): 395 clat4[j,:]=np.cos( rlatu[j])**42183 clat4[j,:]=np.cos(latu[j,0])**4 396 2184 397 2185 # Vertical profile 398 tetajl = np.zeros((dim y+1, dimx), dtype=np.float)2186 tetajl = np.zeros((dimz, dimy+1, dimx), dtype=np.float) 399 2187 teta = np.zeros((dimy+1, dimx+1), dtype=np.float) 400 tetarappel = np.zeros((dim y+1, dimx+1), dtype=np.float)401 402 for l in range (d z):2188 tetarappel = np.zeros((dimz, dimy+1, dimx+1), dtype=np.float) 2189 2190 for l in range (dimz): 403 2191 zsig = presnivs[l]/preff 404 2192 tetastrat = ttp*zsig**(-kappa) … … 411 2199 if planet_type == 'giant': 412 2200 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)2201 ((latu*3.14159*eps+0.0001)**2))-delt_z*np.log(zsig) 414 2202 415 2203 # 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 2204 for iy in range(dimy): 2205 for ix in range(dimx): 2206 w_pv=(1.-np.tanh((latu[iy,ix]-phi_pv)/dphi_pv))/2. 2207 tetastrat=tetastrat*(1.-w_pv)+tetapv*w_pv 2208 tetajl[l,iy,ix]=np.max([tetajl[l,iy,ix],tetastrat]) 2209 2210 #for iz in range(dimz): 2211 # for iy in range(dimy+1): 2212 # tetarappel[iz,iy,0:dimx] = tetajl[iz,iy,:] 2213 # 2214 # tetarappel[iz,iy,0:dimx] = tetajl[iz,iy,dimx-1] 2215 tetarappel = tetajl 2216 2217 # 3. Initialize fields (if necessary) 2218 # surface pressure 2219 ps = np.zeros((dimy, dimx), dtype=np.float) 2220 2221 if iflag_phys > 2: 2222 # specific value for CMIP5 aqua/terra planets 2223 # "Specify the initial dry mass to be equivalent to 2224 # a global mean surface pressure (101325 minus 245) Pa." 2225 ps = 101080. 2226 else: 2227 # use reference surface pressure 2228 ps = preff 2229 2230 # ground geopotential 2231 phiss = np.zeros((dimy, dimx), dtype=np.float) 2232 2233 p = pression(dimx, dimy, dimz, ap, bp, ps) 2234 2235 if opts.pexner == 'hybdrid': 2236 pks, pk, pkf = exner_hyb(ip1jmp1, ps, p, alpha, beta) 2237 else: 2238 pks, pk, pkf = exner_milieu(ip1jmp1, ps, p, beta) 2239 2240 masse = massdair(p) 2241 2242 # bulk initialization of temperature 2243 teta = tetarappel.copy() 2244 2245 # geopotential 2246 phis = np.zeros((dimy, dimx), dtype=np.float) 2247 phi = np.zeros((dimz, dimy, dimx), dtype=np.float) 2248 2249 phis, phi = geopot(ip1jmp1,teta,pk,pks) 2250 2251 # winds 2252 ucov = np.zeros((dimz, dimy, dimx), dtype=np.float) 2253 vcov = np.zeros((dimz, dimy, dimx), dtype=np.float) 2254 2255 2256 if ok_geost: 2257 ucov = ugeostr(phi) 2258 2259 # bulk initialization of tracers 2260 q = np.zeros((dimz, dimy, dimx, nqtot), dtype=np.float) 2261 2262 if planet_type == 'earth': 2263 # Earth: first two tracers will be water 2264 for i in range(nqtot): 2265 if i == 1: q[:,:,i] = 1.e-10 2266 if i == 2: q[:,:,i] = 1.e-15 2267 if i > 2: q[:,:,i] = 0. 2268 2269 # add random perturbation to temperature 2270 idum = -1 2271 zz = RAN1(idum) 2272 idum = 0 2273 for l in range(llm): 2274 for ij in range(iip2,ip1jm): 2275 teta[ij,l] = teta[ij,l]*(1.+0.005*RAN1(idum)) 2276 2277 # maintain periodicity in longitude 2278 for l in range(llm): 2279 for ij in range(0,ip1jmp1,iip1): 2280 teta[ij+iim,l]=teta[ij,l] 428 2281 429 2282 ncf = NetCDFFile(ofile, 'w') -
trunk/tools/lmdz_const.py
r180 r212 29 29 # ihf: (W/m2) Intrinsic heat flux (for giant planets) 30 30 31 planet_type = 'terre' 32 iflag_phys = 2 31 33 daysec = 86400. 32 34 preff = 1013250. … … 144 146 r5les = r3les*(tt-r4les) 145 147 r5ies = r3ies*(tt-r4ies) 148 149 # For filtreg 150 # 151 type_sddu=1 152 type_sddv=2 153 type_unsddu=3 154 type_unsddv=4
Note: See TracChangeset
for help on using the changeset viewer.