source: LMDZ6/branches/Amaury_dev/libf/phylmd/tropopause_m.f90 @ 5218

Last change on this file since 5218 was 5185, checked in by abarral, 3 months ago

Replace REPROBUS CPP KEY by logical using handmade wonky wrapper

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