Changeset 212 in lmdz_wrf for trunk


Ignore:
Timestamp:
Jan 9, 2015, 3:13:49 PM (10 years ago)
Author:
lfita
Message:

First final version without checking if everithing is done fine

Location:
trunk/tools
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/iniaqua.py

    r180 r212  
    1919filekinds = ['CF', 'WRF']
    2020
    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
     27def fripx(ri,dx):
     28    fname = 'fripx'
     29
     30    ripx = (ri-1.0) *2.*np.pi/np.float(dx)
     31
     32    return ripx
     33
     34def 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
     41def 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
     50def fbigy(rj,jjp1,jjm):
     51    fname = 'fbigy'
     52
     53    bigy = 2.*(np.float(jjp1)-rj)*np.pi/jjm
     54
     55    return bigy
     56
     57def 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
     64def 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
     71def 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
     135def 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
     228def 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
     247def 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
     274def 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)
     300c
     301c
     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)
     328c
     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
     336def 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
     373250 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
     42950  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
     55582     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
     56384     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
     57487     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
     58289     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
     59192     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
     59994     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
     60897     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
     61699     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    !
     846334 FORMAT(1x,24i3)
     847755 FORMAT(1x,6f10.3,i3)
     848
     849    RETURN
     850  END SUBROUTINE inifilr
     851
     852
     853def 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
     11111111  FORMAT(//20x,'ERREUR dans le dimensionnement du tableau  CHAMP a
     1112     &     filtrer, sur la grille des scalaires'/)
     11132222  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
     1118def 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
     1133def 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
     1147def 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):
     1223c
     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
     1251def 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
     1375def 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
    221395
    231396def sig_hybrid(sig,pa,preff):
     
    761449    return nsig
    771450
    78 def presnivs_calc(hybrid, dz):
     1451def 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
     1615def presnivs_calc_noterre(hybrid, dz):
    791616    """ From dyn3d/disvert_noterre.F calculation of vertical pressure levels
    801617      hybrid= whether hydbrid coordinates have to be used
     
    821619    """
    831620
    84     fname = 'presnivs_calc'
     1621    fname = 'presnivs_calc_noterre'
    851622
    861623#-----------------------------------------------------------------------
     
    2721809    return longitude, latitude
    2731810
     1811def 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
     1888def 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
     1928def 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
     1964def 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
     2012def 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
    2742060####### ###### ##### #### ### ## #
    2752061
     
    2812067parser.add_option("-d", "--dimensions", dest="dims",
    2822068  help="dimensions of the initial conditions: dimx,dimy,dimz", metavar="VALUES")
     2069parser.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")
    2832072parser.add_option("-t", "--time", dest="time",
    2842073  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")
     2074parser.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")
    2872078
    2882079(opts, args) = parser.parse_args()
     
    3172108dimy = int(opts.dims.split(',')[1])
    3182109dimz = int(opts.dims.split(',')[2])
    319 
    320 if opts.hybrid == 'true':
    321     hybrid_calc = True
    322 else:
    323     hybrid_calc = False
    3242110
    3252111ofile = 'iniaqua.nc'
     
    3732159gam_pv=4.
    3742160
    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)
     2163presnivs = presnivs_calc(opts.znivs, dimz)
     2164lon, lat = global_lonlat(dimy,dimx)
     2165lonu, latu = global_lonlat(dimy,dimx+1)
     2166lonv, latv = global_lonlat(dimy+1,dimx)
    3792167
    3802168# 2. Initialize fields towards which to relax
     
    3832171knewt_t = np.zeros((dimz), dtype=np.float)
    3842172kfrict = np.zeros((dimz), dtype=np.float)
    385 clat4 =  np.zeros((dimy+1, dimx), dtype=np.float)
     2173clat4 =  np.zeros((dimy+1, dimx+1), dtype=np.float)
    3862174
    3872175# Friction
     
    3932181
    3942182    for j in 1,range(dimy+1):
    395         clat4[j,:]=np.cos(rlatu[j])**4
     2183        clat4[j,:]=np.cos(latu[j,0])**4
    3962184
    3972185# Vertical profile
    398 tetajl =  np.zeros((dimy+1, dimx), dtype=np.float)
     2186tetajl =  np.zeros((dimz, dimy+1, dimx), dtype=np.float)
    3992187teta = 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):
     2188tetarappel = np.zeros((dimz, dimy+1, dimx+1), dtype=np.float)
     2189
     2190for l in range (dimz):
    4032191    zsig = presnivs[l]/preff
    4042192    tetastrat = ttp*zsig**(-kappa)
     
    4112199    if planet_type == 'giant':
    4122200        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)
    4142202
    4152203# 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]
     2215tetarappel = tetajl
     2216
     2217# 3. Initialize fields (if necessary)
     2218# surface pressure
     2219ps =  np.zeros((dimy, dimx), dtype=np.float)
     2220
     2221if 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. 
     2226else:
     2227# use reference surface pressure
     2228    ps = preff
     2229       
     2230# ground geopotential
     2231phiss =  np.zeros((dimy, dimx), dtype=np.float)
     2232
     2233p = pression(dimx, dimy, dimz, ap, bp, ps)
     2234
     2235if opts.pexner == 'hybdrid':
     2236    pks, pk, pkf = exner_hyb(ip1jmp1, ps, p, alpha, beta)
     2237else:
     2238    pks, pk, pkf = exner_milieu(ip1jmp1, ps, p, beta)
     2239
     2240masse = massdair(p)
     2241
     2242# bulk initialization of temperature
     2243teta = tetarappel.copy()
     2244
     2245# geopotential
     2246phis =  np.zeros((dimy, dimx), dtype=np.float)
     2247phi =  np.zeros((dimz, dimy, dimx), dtype=np.float)
     2248
     2249phis, phi = geopot(ip1jmp1,teta,pk,pks)
     2250
     2251# winds
     2252ucov =  np.zeros((dimz, dimy, dimx), dtype=np.float)
     2253vcov =  np.zeros((dimz, dimy, dimx), dtype=np.float)
     2254
     2255
     2256if ok_geost:
     2257    ucov = ugeostr(phi)
     2258
     2259# bulk initialization of tracers
     2260q = np.zeros((dimz, dimy, dimx, nqtot), dtype=np.float)
     2261
     2262if 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
     2270idum  = -1
     2271zz = RAN1(idum)
     2272idum  = 0
     2273for 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
     2278for l in range(llm):
     2279    for ij in range(0,ip1jmp1,iip1):
     2280        teta[ij+iim,l]=teta[ij,l]
    4282281
    4292282ncf = NetCDFFile(ofile, 'w')
  • trunk/tools/lmdz_const.py

    r180 r212  
    2929# ihf: (W/m2) Intrinsic heat flux (for giant planets)
    3030
     31planet_type = 'terre'
     32iflag_phys = 2
    3133daysec = 86400.
    3234preff = 1013250.
     
    144146r5les = r3les*(tt-r4les)
    145147r5ies = r3ies*(tt-r4ies)
     148
     149# For filtreg
     150#
     151type_sddu=1
     152type_sddv=2
     153type_unsddu=3
     154type_unsddv=4
Note: See TracChangeset for help on using the changeset viewer.