source: LMDZ6/branches/Amaury_dev/libf/phylmd/tropopause_m.F90 @ 5157

Last change on this file since 5157 was 5144, checked in by abarral, 8 weeks ago

Put YOMCST.h into modules

File size: 6.5 KB
Line 
1MODULE tropopause_m
2
3  IMPLICIT NONE
4  PRIVATE
5  PUBLIC :: dyn_tropopause
6
7CONTAINS
8
9  !-------------------------------------------------------------------------------
10
11  FUNCTION dyn_tropopause(t, ts, paprs, pplay, rot, itrop, thet0, pvor0)
12
13    !-------------------------------------------------------------------------------
14    USE lmdz_assert, ONLY: assert
15    USE lmdz_assert_eq, ONLY: assert_eq
16    USE dimphy, ONLY: klon, klev
17    USE lmdz_geometry, ONLY: latitude_deg, longitude_deg
18    USE lmdz_vertical_layers, ONLY: aps, bps, preff
19#ifdef REPROBUS
20  USE chem_rep, ONLY: itroprep
21#endif
22    USE lmdz_yomcst
23
24    !-------------------------------------------------------------------------------
25    ! Arguments:
26    REAL :: dyn_tropopause(klon) !--- Pressure at tropopause
27    REAL, INTENT(IN) :: t(:, :) !--- Cells-centers temperature
28    REAL, INTENT(IN) :: ts(:)   !--- Surface       temperature
29    REAL, INTENT(IN) :: paprs(:, :) !--- Cells-edges   pressure
30    REAL, INTENT(IN) :: pplay(:, :) !--- Cells-centers pressure
31    REAL, INTENT(IN) :: rot(:, :) !--- Cells-centers relative vorticity
32    INTEGER, INTENT(OUT), OPTIONAL :: itrop(klon) !--- Last tropospheric layer idx
33    REAL, INTENT(IN), OPTIONAL :: thet0, pvor0
34    !-------------------------------------------------------------------------------
35    ! Local variables:
36    REAL, PARAMETER :: DynPTrMin = 8.E+3 !--- Thresholds for minimum and maximum
37    REAL, PARAMETER :: DynPTrMax = 4.E+4 !    dynamical tropopause pressure (Pa).
38    CHARACTER(LEN = 80) :: sub
39    INTEGER :: i, k, kb, kt, kp, ib, ie, nw
40    REAL :: al, th0, pv0
41    REAL, DIMENSION(klon, klev) :: tpot_cen, tpot_edg, pvor_cen
42    REAL, PARAMETER :: sg0 = 0.75  !--- Start level for PV=cte search loop
43    INTEGER, PARAMETER :: nadj = 3    !--- Adjacent levs nb for thresholds detection
44    REAL, PARAMETER :: w(5) = [0.1, 0.25, 0.3, 0.25, 0.1] !--- Vertical smoothing
45    INTEGER, SAVE :: k0
46    LOGICAL, SAVE :: first = .TRUE.
47    !$OMP THREADPRIVATE(k0,first)
48    !-------------------------------------------------------------------------------
49    sub = 'dyn_tropopause'
50    CALL assert(SIZE(t, 1)==klon, TRIM(sub) // " t klon")
51    CALL assert(SIZE(t, 2)==klev, TRIM(sub) // " t klev")
52    CALL assert(SIZE(ts, 1)==klon, TRIM(sub) // " ts klon")
53    CALL assert(SHAPE(paprs)==[klon, klev + 1], TRIM(sub) // " paprs shape")
54    CALL assert(SHAPE(pplay)==[klon, klev  ], TRIM(sub) // " pplay shape")
55    CALL assert(SHAPE(rot)  ==[klon, klev  ], TRIM(sub) // " rot shape")
56
57    !--- DEFAULT THRESHOLDS
58    th0 = 380.; IF(PRESENT(thet0)) th0 = thet0   !--- In kelvins
59    pv0 = 2.; IF(PRESENT(pvor0)) pv0 = pvor0   !--- In PVU
60    IF(first) THEN
61      DO k0 = 1, klev; IF(aps(k0) / preff + bps(k0)<sg0) EXIT;
62      END DO; first = .FALSE.
63    END IF
64
65    !--- POTENTIAL TEMPERATURE AT CELLS CENTERS AND INTERFACES
66    DO i = 1, klon
67      tpot_cen(i, 1) = t(i, 1) * (preff / pplay(i, 1))**RKAPPA
68      tpot_edg(i, 1) = ts(i) * (preff / paprs(i, 1))**RKAPPA
69      DO k = 2, klev
70        al = LOG(pplay(i, k - 1) / paprs(i, k)) / LOG(pplay(i, k - 1) / pplay(i, k))
71        tpot_cen(i, k) = t(i, k) * (preff / pplay(i, k))**RKAPPA
72        tpot_edg(i, k) = (t(i, k - 1) + al * (t(i, k) - t(i, k - 1))) * (preff / paprs(i, k))**RKAPPA
73        !--- FORCE QUANTITIES TO BE GROWING
74        IF(tpot_edg(i, k)<tpot_edg(i, k - 1)) tpot_edg(i, k) = tpot_edg(i, k - 1) + 1.E-5
75        IF(tpot_cen(i, k)<tpot_cen(i, k - 1)) tpot_cen(i, k) = tpot_cen(i, k - 1) + 1.E-5
76      END DO
77      !--- VERTICAL SMOOTHING
78      tpot_cen(i, :) = smooth(tpot_cen(i, :), w)
79      tpot_edg(i, :) = smooth(tpot_edg(i, :), w)
80    END DO
81
82    !--- ERTEL POTENTIAL VORTICITY AT CELLS CENTERS (except in top layer)
83    DO i = 1, klon
84      DO k = 1, klev - 1
85        pvor_cen(i, k) = -1.E6 * RG * (rot(i, k) + 2. * ROMEGA * SIN(latitude_deg(i) * RPI / 180.))&
86                * (tpot_edg(i, k + 1) - tpot_edg(i, k)) / (paprs(i, k + 1) - paprs(i, k))
87      END DO
88      !--- VERTICAL SMOOTHING
89      pvor_cen(i, 1:klev - 1) = smooth(pvor_cen(i, 1:klev - 1), w)
90    END DO
91
92    !--- LOCATE TROPOPAUSE: LOWEST POINT BETWEEN THETA=380K AND PV=2PVU SURFACES.
93    DO i = 1, klon
94      !--- UPPER TROPOPAUSE: |PV|=2PVU POINT STARTING FROM TOP
95      DO kt = klev - 1, 1, -1; IF(ALL(ABS(pvor_cen(i, kt - nadj:kt))<=pv0)) EXIT;
96      END DO
97      !--- LOWER TROPOPAUSE: |PV|=2PVU POINT STARTING FROM BOTTOM
98      DO kb = k0, klev - 1;   IF(ALL(ABS(pvor_cen(i, kb:kb + nadj))> pv0)) EXIT;
99      END DO; kb = kb - 1
100      !--- ISO-THETA POINT: THETA=380K       STARTING FROM TOP
101      DO kp = klev - 1, 1, -1; IF(ALL(ABS(tpot_cen(i, kp - nadj:kp))<=th0)) EXIT;
102      END DO
103      !--- CHOOSE BETWEEN LOWER AND UPPER TROPOPAUSE
104      IF(2 * COUNT(ABS(pvor_cen(i, kb:kt))>pv0)>kt - kb + 1) kt = kb
105      !--- PV-DEFINED TROPOPAUSE
106      al = (ABS(pvor_cen(i, kt + 1)) - pv0) / ABS(pvor_cen(i, kt + 1) - pvor_cen(i, kt))
107      dyn_tropopause(i) = pplay(i, kt + 1) * (pplay(i, kt) / pplay(i, kt + 1))**al
108      !--- THETA=380K IN THE TROPICAL REGION
109      al = (tpot_cen(i, kp + 1) - th0) / (tpot_cen(i, kp + 1) - tpot_cen(i, kp))
110      dyn_tropopause(i) = MAX(pplay(i, kp + 1) * (pplay(i, kp) / pplay(i, kp + 1))**al, &
111              dyn_tropopause(i))
112      !--- UNREALISTIC VALUES DETECTION
113      IF(dyn_tropopause(i)<DynPTrMin.OR.dyn_tropopause(i)>DynPTrMax) THEN
114        dyn_tropopause(i) = MIN(MAX(dyn_tropopause(i), DynPTrMax), DynPTrMin)
115        DO kt = 1, klev - 1; IF(pplay(i, kt + 1)>dyn_tropopause(i)) EXIT;
116        END DO; kp = kt
117      END IF
118#ifdef REPROBUS
119    itroprep(i)=MAX(kt,kp)
120#endif
121      !--- LAST TROPOSPHERIC LAYER INDEX NEEDED
122      IF(PRESENT(itrop)) itrop(i) = MAX(kt, kp)
123    END DO
124
125  END FUNCTION dyn_tropopause
126
127
128  !-------------------------------------------------------------------------------
129
130  FUNCTION smooth(v, w)
131
132    !-------------------------------------------------------------------------------
133    ! Arguments:
134    REAL, INTENT(IN) :: v(:), w(:)
135    REAL, DIMENSION(SIZE(v)) :: smooth
136    !-------------------------------------------------------------------------------
137    ! Local variables:
138    INTEGER :: nv, nw, k, kb, ke, lb, le
139    !-------------------------------------------------------------------------------
140    nv = SIZE(v); nw = (SIZE(w) - 1) / 2
141    DO k = 1, nv
142      kb = MAX(k - nw, 1); lb = MAX(2 + nw - k, 1)
143      ke = MIN(k + nw, nv); le = MIN(1 + nw + nv - k, 1 + 2 * nw)
144      smooth(k) = SUM(v(kb:ke) * w(lb:le)) / SUM(w(lb:le))
145    END DO
146
147  END FUNCTION smooth
148
149  !-------------------------------------------------------------------------------
150
151END MODULE tropopause_m
Note: See TracBrowser for help on using the repository browser.