Ignore:
Timestamp:
Aug 3, 2017, 10:31:46 AM (7 years ago)
Author:
acozic
Message:

merges with trunk for rev 2968 and 2971 --
2968 = improved method for ozone forcing
2971 = control outputs for debug are removed

File:
1 edited

Legend:

Unmodified
Added
Removed
  • LMDZ5/branches/IPSLCM6.0.12/libf/phylmd/tropopause_m.F90

    r2788 r2980  
    22
    33!  USE phys_local_var_mod, ONLY: ptrop => pr_tropopause
     4  IMPLICIT NONE
    45  PRIVATE
    56  PUBLIC :: dyn_tropopause
     
    910!-------------------------------------------------------------------------------
    1011!
    11 SUBROUTINE dyn_tropopause(t,ts,paprs,pplay,presnivs,rot,ptrop,tpot0,pvor0,pmin0,pmax0)
     12FUNCTION dyn_tropopause(t, ts, paprs, pplay, rot, thet0, pvor0)
    1213!
    1314!-------------------------------------------------------------------------------
    14   USE assert_m,      ONLY: assert
    15   USE assert_eq_m,   ONLY: assert_eq
    16   USE comvert_mod,   ONLY: preff
    17   USE dimphy,        ONLY: klon, klev
    18   USE geometry_mod,  ONLY: latitude_deg, longitude_deg
    19   USE interpolation, ONLY: locate
    20   IMPLICIT NONE
     15  USE assert_m,     ONLY: assert
     16  USE assert_eq_m,  ONLY: assert_eq
     17  USE dimphy,       ONLY: klon, klev
     18  USE geometry_mod, ONLY: latitude_deg, longitude_deg
     19  USE vertical_layers_mod, ONLY: aps, bps, preff
     20
    2121!-------------------------------------------------------------------------------
    2222! Arguments:
     23  REAL ::     dyn_tropopause(klon) !--- Pressure at tropopause
    2324  REAL, INTENT(IN)  ::      t(:,:) !--- Cells-centers temperature
    2425  REAL, INTENT(IN)  ::     ts(:)   !--- Surface       temperature
    2526  REAL, INTENT(IN)  ::  paprs(:,:) !--- Cells-edges   pressure
    2627  REAL, INTENT(IN)  ::  pplay(:,:) !--- Cells-centers pressure
    27   REAL, INTENT(IN)  :: presnivs(:) !--- Cells-centers nominal pressure
    2828  REAL, INTENT(IN)  ::    rot(:,:) !--- Cells-centers relative vorticity
    29   REAL, INTENT(OUT) :: ptrop(klon) !--- Tropopause pressure
    30   REAL, INTENT(IN), OPTIONAL :: tpot0, pvor0, pmin0, pmax0
     29  REAL, INTENT(IN), OPTIONAL :: thet0, pvor0
    3130!-------------------------------------------------------------------------------
    3231! Local variables:
    3332  include "YOMCST.h"
    3433  CHARACTER(LEN=80)  :: sub
    35   INTEGER :: it, i, nsrf, k, nh, kmin, kmax
    36   REAL    :: p1, p2, tpo0, pvo0, pmn0, pmx0, al
    37   REAL, DIMENSION(klon,klev)   :: t_edg, t_pot
    38   REAL, DIMENSION(klon,klev-1) :: pvort
     34  INTEGER :: i, k, kb, kt, kp, ib, ie, nw
     35  REAL    :: al, th0, pv0
     36  REAL,    DIMENSION(klon,klev) :: tpot_cen, tpot_edg, pvor_cen
     37  REAL,    PARAMETER :: sg0=0.75  !--- Start level for PV=cte search loop
     38  INTEGER, PARAMETER :: nadj=3    !--- Adjacent levs nb for thresholds detection
     39  REAL,    PARAMETER :: w(5)=[0.1,0.25,0.3,0.25,0.1] !--- Vertical smoothing
     40  INTEGER, SAVE :: k0
     41  LOGICAL, SAVE :: first=.TRUE.
     42!$OMP THREADPRIVATE(k0,first)
    3943!-------------------------------------------------------------------------------
    4044  sub='dyn_tropopause'
     
    4246  CALL assert(SIZE(t ,2)==klev, TRIM(sub)//" t klev")
    4347  CALL assert(SIZE(ts,1)==klon, TRIM(sub)//" ts klon")
    44   CALL assert(SIZE(presnivs,1)==klev, TRIM(sub)//" presnivs klev")
    4548  CALL assert(SHAPE(paprs)==[klon,klev+1],TRIM(sub)//" paprs shape")
    4649  CALL assert(SHAPE(pplay)==[klon,klev  ],TRIM(sub)//" pplay shape")
     
    4851
    4952  !--- DEFAULT THRESHOLDS
    50   tpo0=380.;   IF(PRESENT(tpot0)) tpo0=tpot0  !--- In kelvins
    51   pvo0=2.0;    IF(PRESENT(pvor0)) pvo0=pvor0  !--- In PVU
    52   pmn0= 8000.; IF(PRESENT(pmin0)) pmn0=pmin0  !--- In pascals
    53   pmx0=50000.; IF(PRESENT(pmax0)) pmx0=pmax0  !--- In pascals
    54   kmin=klev-locate(presnivs(klev:1:-1),pmx0)+1
    55   kmax=klev-locate(presnivs(klev:1:-1),pmn0)+1
     53  th0=380.; IF(PRESENT(thet0)) th0=thet0   !--- In kelvins
     54  pv0=  2.; IF(PRESENT(pvor0)) pv0=pvor0   !--- In PVU
     55  IF(first) THEN
     56    DO k0=1,klev; IF(aps(k0)/preff+bps(k0)<sg0) EXIT; END DO; first=.FALSE.
     57  END IF
    5658
    57   !--- POTENTIAL TEMPERATURE AT CELLS CENTERS
    58   DO k= 1, klev
    59     DO i = 1, klon
    60       t_pot(i,k) = t(i,k)*(preff/pplay(i,k))**RKAPPA
     59  !--- POTENTIAL TEMPERATURE AT CELLS CENTERS AND INTERFACES
     60  DO i = 1,klon
     61    tpot_cen(i,1) = t(i,1)*(preff/pplay(i,1))**RKAPPA
     62    tpot_edg(i,1) = ts(i) *(preff/paprs(i,1))**RKAPPA
     63    DO k=2,klev
     64      al = LOG(pplay(i,k-1)/paprs(i,k))/LOG(pplay(i,k-1)/pplay(i,k))
     65      tpot_cen(i,k) =  t(i,k)                        *(preff/pplay(i,k))**RKAPPA
     66      tpot_edg(i,k) = (t(i,k-1)+al*(t(i,k)-t(i,k-1)))*(preff/paprs(i,k))**RKAPPA
     67      !--- FORCE QUANTITIES TO BE GROWING
     68      IF(tpot_edg(i,k)<tpot_edg(i,k-1)) tpot_edg(i,k)=tpot_edg(i,k-1)+1.E-5
     69      IF(tpot_cen(i,k)<tpot_cen(i,k-1)) tpot_cen(i,k)=tpot_cen(i,k-1)+1.E-5
    6170    END DO
    62   END DO
    63 
    64   !--- TEMPERATURE AT CELLS INTERFACES (except in top layer)
    65   t_edg(:,1) = ts(:)
    66   DO k= 2, klev
    67     DO i = 1, klon
    68       al = LOG(pplay(i,k-1)/paprs(i,k))/LOG(pplay(i,k-1)/pplay(i,k))
    69       t_edg(i,k) = t(i,k) + al*(t(i,k-1)-t(i,k))
    70     END DO
     71    !--- VERTICAL SMOOTHING
     72    tpot_cen(i,:)=smooth(tpot_cen(i,:),w)
     73    tpot_edg(i,:)=smooth(tpot_edg(i,:),w)
    7174  END DO
    7275
    7376  !--- ERTEL POTENTIAL VORTICITY AT CELLS CENTERS (except in top layer)
    74   DO k= 1, klev-1
    75     DO i = 1, klon
    76       IF(paprs(i,k)==paprs(i,k+1)) THEN; pvort(i,k)=HUGE(1.); CYCLE; END IF
    77       pvort(i,k) = -1.E6 * RG * 2.*ROMEGA*ABS(SIN(latitude_deg(i)*RPI/180.))   &
    78                          * ( t_edg(i,k+1)*(preff/paprs(i,k+1) )**RKAPPA        &
    79                            - t_edg(i,k  )*(preff/paprs(i,k  ) )**RKAPPA)       &
    80                          / ( paprs(i,k+1)  -     paprs(i,k  ) )
     77  DO i = 1, klon
     78    DO k= 1, klev-1
     79      pvor_cen(i,k)=-1.E6*RG*(rot(i,k)+2.*ROMEGA*SIN(latitude_deg(i)*RPI/180.))&
     80                   * (tpot_edg(i,k+1)-tpot_edg(i,k)) / (paprs(i,k+1)-paprs(i,k))
    8181    END DO
     82    !--- VERTICAL SMOOTHING
     83    pvor_cen(i,1:klev-1)=smooth(pvor_cen(i,1:klev-1),w)
    8284  END DO
    8385
    84   !--- LOCATE TROPOPAUSE
    85   ptrop(:)=0.
     86  !--- LOCATE TROPOPAUSE: LOWEST POINT BETWEEN THETA=380K AND PV=2PVU SURFACES.
    8687  DO i = 1, klon
    87     !--- Dynamical tropopause
    88     it=kmax; DO WHILE(pvort(i,it)>pvo0.AND.it>=kmin); it=it-1; END DO
    89     IF(pvort(i,it+1)/=pvort(i,it).AND.ALL([kmax,kmin-1]/=it) &
    90       .AND.ALL([pvort(i,it),pvort(i,it+1)]/=HUGE(1.))) THEN
    91       al = (pvort(i,it+1)-pvo0)/(pvort(i,it+1)-pvort(i,it))
    92       ptrop(i) = MAX(ptrop(i),pplay(i,it)**al * pplay(i,it+1)**(1.-al))
    93     END IF
    94     !--- Potential temperature iso-surface
    95     it = kmin-1+locate(t_pot(i,kmin:kmax),tpo0)
    96     IF(t_pot(i,it+1)/=t_pot(i,it).AND.ALL([kmin-1,kmax]/=it)) THEN
    97       al = (t_pot(i,it+1)-tpo0)/(t_pot(i,it+1)-t_pot(i,it))
    98       ptrop(i) = MAX(ptrop(i),pplay(i,it)**al * pplay(i,it+1)**(1.-al))
    99     END IF
     88    !--- UPPER TROPOPAUSE: |PV|=2PVU POINT STARTING FROM TOP
     89    DO kt=klev-1,1,-1; IF(ALL(ABS(pvor_cen(i,kt-nadj:kt))<=pv0)) EXIT; END DO
     90    !--- LOWER TROPOPAUSE: |PV|=2PVU POINT STARTING FROM BOTTOM
     91    DO kb=k0,klev-1;   IF(ALL(ABS(pvor_cen(i,kb:kb+nadj))> pv0)) EXIT; END DO; kb=kb-1
     92    !--- ISO-THETA POINT: THETA=380K       STARTING FROM TOP
     93    DO kp=klev-1,1,-1; IF(ALL(ABS(tpot_cen(i,kp-nadj:kp))<=th0)) EXIT; END DO
     94    !--- CHOOSE BETWEEN LOWER AND UPPER TROPOPAUSE
     95    IF(2*COUNT(ABS(pvor_cen(i,kb:kt))>pv0)>kt-kb+1) kt=kb
     96    !--- PV-DEFINED TROPOPAUSE
     97    al = (ABS(pvor_cen(i,kt+1))-pv0)/ABS(pvor_cen(i,kt+1)-pvor_cen(i,kt))
     98    dyn_tropopause(i) = pplay(i,kt+1)*(pplay(i,kt)/pplay(i,kt+1))**al
     99    !--- THETA=380K IN THE TROPICAL REGION
     100    al = (tpot_cen(i,kp+1)-th0)/(tpot_cen(i,kp+1)-tpot_cen(i,kp))
     101    dyn_tropopause(i) = MAX( pplay(i,kp+1)*(pplay(i,kp)/pplay(i,kp+1))**al,    &
     102                            dyn_tropopause(i) )
    100103  END DO
    101104
    102 END SUBROUTINE dyn_tropopause
     105END FUNCTION dyn_tropopause
     106
     107
     108!-------------------------------------------------------------------------------
     109!
     110FUNCTION smooth(v,w)
     111!
     112!-------------------------------------------------------------------------------
     113! Arguments:
     114  REAL, INTENT(IN)         :: v(:), w(:)
     115  REAL, DIMENSION(SIZE(v)) :: smooth
     116!-------------------------------------------------------------------------------
     117! Local variables:
     118  INTEGER :: nv, nw, k, kb, ke, lb, le
     119!-------------------------------------------------------------------------------
     120  nv=SIZE(v); nw=(SIZE(w)-1)/2
     121  DO k=1,nv
     122    kb=MAX(k-nw,1 ); lb=MAX(2+nw   -k,1)
     123    ke=MIN(k+nw,nv); le=MIN(1+nw+nv-k,1+2*nw)
     124    smooth(k)=SUM(v(kb:ke)*w(lb:le))/SUM(w(lb:le))
     125  END DO
     126
     127END FUNCTION smooth
     128!
     129!-------------------------------------------------------------------------------
    103130
    104131END MODULE tropopause_m
Note: See TracChangeset for help on using the changeset viewer.