source: LMDZ6/branches/Amaury_dev/libf/phylmd/add_phys_tend_mod.F90 @ 5218

Last change on this file since 5218 was 5160, checked in by abarral, 5 months ago

Put .h into modules

File size: 32.3 KB
Line 
1! $Id$
2
3
4MODULE add_phys_tend_mod
5
6  IMPLICIT NONE
7  ! flag to compute diagnostics to check energy conservation. If  fl_ebil==0, no check
8  INTEGER, SAVE :: fl_ebil
9  !$OMP THREADPRIVATE(fl_ebil)
10  ! flag to include modifcations to ensure energy conservation. If  fl_cor_ebil==0, no corrections
11  ! Note that with time, all these modifications should be included by default
12  INTEGER, SAVE :: fl_cor_ebil
13  !$OMP THREADPRIVATE(fl_cor_ebil)
14
15CONTAINS
16
17  SUBROUTINE add_pbl_tend(zdu, zdv, zdt, zdq, zdql, zdqi, zdqbs, paprs, text, abortphy, flag_inhib_tend, itap)
18    ! ======================================================================
19    ! Ajoute les tendances de couche limite, soit determinees par la
20    ! parametrisation
21    ! physique, soit forcees,  aux variables d etat de la dynamique t_seri,
22    ! q_seri ...
23    ! ======================================================================
24
25
26    ! ======================================================================
27    ! Declarations
28    ! ======================================================================
29
30    USE dimphy, ONLY: klon, klev
31    !  USE dimphy
32    USE phys_local_var_mod
33    USE phys_state_var_mod
34    USE lmdz_grid_phy, ONLY: nbp_lev
35    IMPLICIT NONE
36    REAL, SAVE, ALLOCATABLE :: hthturb_gcssold(:)
37    REAL, SAVE, ALLOCATABLE :: hqturb_gcssold(:)
38    !$OMP THREADPRIVATE(hthturb_gcssold,hqturb_gcssold)
39    REAL, SAVE :: dtime_frcg
40    LOGICAL, SAVE :: turb_fcg_gcssold
41    LOGICAL, SAVE :: firstcall = .TRUE.
42    !$OMP THREADPRIVATE(firstcall,turb_fcg_gcssold,dtime_frcg)
43    INTEGER abortphy
44
45    ! Arguments :
46    ! ------------
47    REAL zdu(klon, klev), zdv(klon, klev)
48    REAL zdt(klon, klev), zdq(klon, klev), zdql(klon, klev), zdqi(klon, klev), zdqbs(klon, klev)
49    CHARACTER *(*) text
50    REAL paprs(klon, klev + 1)
51    INTEGER flag_inhib_tend ! if flag_inhib_tend != 0, tendencies are not added
52    INTEGER itap ! time step number
53
54    ! Local :
55    ! --------
56    REAL zzdt(klon, klev), zzdq(klon, klev)
57    INTEGER i, k
58
59    IF (firstcall) THEN
60      ALLOCATE(hthturb_gcssold(nbp_lev))
61      ALLOCATE(hqturb_gcssold(nbp_lev))
62      firstcall = .FALSE.
63    ENDIF
64
65    IF (turb_fcg_gcssold) THEN
66      DO k = 1, klev
67        DO i = 1, klon
68          zzdt(i, k) = hthturb_gcssold(k) * dtime_frcg
69          zzdq(i, k) = hqturb_gcssold(k) * dtime_frcg
70        ENDDO
71      ENDDO
72      PRINT *, ' add_pbl_tend, dtime_frcg ', dtime_frcg
73      PRINT *, ' add_pbl_tend, zzdt ', zzdt
74      PRINT *, ' add_pbl_tend, zzdq ', zzdq
75      CALL add_phys_tend(zdu, zdv, zzdt, zzdq, zdql, zdqi, zdqbs, paprs, text, abortphy, flag_inhib_tend, itap, 0)
76    ELSE
77      CALL add_phys_tend(zdu, zdv, zdt, zdq, zdql, zdqi, zdqbs, paprs, text, abortphy, flag_inhib_tend, itap, 0)
78    ENDIF
79
80  END SUBROUTINE add_pbl_tend
81
82  ! $Id: add_phys_tend.F90 2611 2016-08-03 15:41:26Z jyg $
83
84  SUBROUTINE add_phys_tend(zdu, zdv, zdt, zdq, zdql, zdqi, zdqbs, paprs, text, &
85          abortphy, flag_inhib_tend, itap, diag_mode)
86    !======================================================================
87    ! Ajoute les tendances des variables physiques aux variables
88    ! d'etat de la dynamique t_seri, q_seri ...
89    ! On en profite pour faire des tests sur les tendances en question.
90    !======================================================================
91
92
93    !======================================================================
94    ! Declarations
95    !======================================================================
96
97    USE dimphy, ONLY: klon, klev
98    USE phys_state_var_mod, ONLY: phys_tstep
99    USE phys_local_var_mod, ONLY: u_seri, v_seri, ql_seri, qs_seri, qbs_seri, q_seri, t_seri
100    USE phys_state_var_mod, ONLY: ftsol
101    USE lmdz_geometry, ONLY: longitude_deg, latitude_deg
102    USE lmdz_print_control, ONLY: prt_level
103    USE cmp_seri_mod
104    USE phys_output_var_mod, ONLY: d_qw_col, d_ql_col, d_qs_col, d_qbs_col, d_qt_col, d_ek_col, d_h_dair_col &
105            , d_h_qw_col, d_h_ql_col, d_h_qs_col, d_h_qbs_col, d_h_col
106    USE lmdz_clesphys
107    USE lmdz_yomcst
108
109    IMPLICIT NONE
110
111    ! Arguments :
112    !------------
113    REAL, DIMENSION(klon, klev), INTENT(IN) :: zdu, zdv
114    REAL, DIMENSION(klon, klev), INTENT(IN) :: zdt, zdql, zdqi, zdqbs
115    REAL, DIMENSION(klon, klev + 1), INTENT(IN) :: paprs
116    CHARACTER*(*), INTENT(IN) :: text
117    INTEGER, INTENT(IN) :: abortphy
118    INTEGER, INTENT(IN) :: flag_inhib_tend ! if not 0, tendencies are not added
119    INTEGER, INTENT(IN) :: itap            ! time step number
120    INTEGER, INTENT(IN) :: diag_mode       ! 0 -> normal effective mode
121    ! 1 -> only conservation stats are computed
122
123    REAL, DIMENSION(klon, klev), INTENT(INOUT) :: zdq
124
125    ! Local :
126    !--------
127    REAL zt, zq
128    REAL zq_int, zqp_int, zq_new
129
130    REAL zqp(klev)
131
132    ! Save variables, used in diagnostic mode (diag_mode=1).
133    REAL, DIMENSION(klon, klev) :: sav_u_seri, sav_v_seri
134    REAL, DIMENSION(klon, klev) :: sav_ql_seri, sav_qs_seri, sav_qbs_seri, sav_q_seri
135    REAL, DIMENSION(klon, klev) :: sav_t_seri
136    REAL, DIMENSION(klon, klev) :: sav_zdq
137
138    INTEGER i, k, j, n
139    INTEGER jadrs(klon * klev), jbad
140    INTEGER jqadrs(klon * klev), jqbad
141    INTEGER kadrs(klon * klev)
142    INTEGER kqadrs(klon * klev)
143
144    LOGICAL done(klon)
145
146    INTEGER debug_level
147    LOGICAL, SAVE :: first = .TRUE.
148    !$OMP THREADPRIVATE(first)
149
150    !======================================================================
151    ! Variables for energy conservation tests
152    !======================================================================
153
154    ! zh_col-------  total enthalpy of vertical air column
155    ! (air with watter vapour, liquid and solid) (J/m2)
156    ! zh_dair_col--- total enthalpy of dry air (J/m2)
157    ! zh_qw_col----  total enthalpy of watter vapour (J/m2)
158    ! zh_ql_col----  total enthalpy of liquid watter (J/m2)
159    ! zh_qs_col----  total enthalpy of solid watter  (J/m2)
160    ! zh_qbs_col----  total enthalpy of blowing snow  (J/m2)
161    ! zqw_col------  total mass of watter vapour (kg/m2)
162    ! zql_col------  total mass of liquid watter (kg/m2)
163    ! zqs_col------  total mass of cloud ice (kg/m2)
164    ! zqbs_col------  total mass of blowing snow (kg/m2)
165    ! zek_col------  total kinetic energy (kg/m2)
166
167    REAL zairm(klon, klev) ! layer air mass (kg/m2)
168    REAL zqw_col(klon, 2)
169    REAL zql_col(klon, 2)
170    REAL zqs_col(klon, 2)
171    REAL zqbs_col(klon, 2)
172    REAL zek_col(klon, 2)
173    REAL zh_dair_col(klon, 2)
174    REAL zh_qw_col(klon, 2), zh_ql_col(klon, 2), zh_qs_col(klon, 2), zh_qbs_col(klon, 2)
175    REAL zh_col(klon, 2)
176    REAL zcpvap, zcwat, zcice
177
178    !======================================================================
179    ! Initialisations
180
181    IF (prt_level >= 5) THEN
182      write (*, *) "In add_phys_tend, after ", text
183      CALL flush
184    ENDIf
185
186    ! if flag_inhib_tend != 0, tendencies are not added
187    IF (flag_inhib_tend /= 0) THEN
188      ! If requiered, diagnostics are shown
189      IF (flag_inhib_tend > 0) THEN
190        ! print some diagnostics if xxx_seri have changed
191        CALL cmp_seri(flag_inhib_tend, text)
192      ENDIF
193      RETURN ! on n ajoute pas les tendance
194    ENDIF
195
196    IF (abortphy==1) RETURN ! on n ajoute pas les tendance si le modele a deja plante.
197
198    debug_level = 10
199    IF (first) THEN
200      PRINT *, "TestJLD rcpv, rcw, rcs", rcpv, rcw, rcs
201      first = .FALSE.
202    ENDIF
203
204    !  PRINT *,'add_phys_tend: paprs ',paprs
205    ! When in diagnostic mode, save initial values of out variables
206    IF (diag_mode == 1) THEN
207      sav_u_seri(:, :) = u_seri(:, :)
208      sav_v_seri(:, :) = v_seri(:, :)
209      sav_ql_seri(:, :) = ql_seri(:, :)
210      sav_qs_seri(:, :) = qs_seri(:, :)
211      sav_qbs_seri(:, :) = qbs_seri(:, :)
212      sav_q_seri(:, :) = q_seri(:, :)
213      sav_t_seri(:, :) = t_seri(:, :)
214      sav_zdq(:, :) = zdq(:, :)
215    ENDIF ! (diag_mode == 1)
216    !======================================================================
217    ! Diagnostics for energy conservation tests
218    !======================================================================
219    DO k = 1, klev
220      ! layer air mass
221      zairm(:, k) = (paprs(:, k) - paprs(:, k + 1)) / rg
222    ENDDO
223
224    IF (fl_ebil > 0) THEN
225      ! ------------------------------------------------
226      ! Compute vertical sum for each atmospheric column
227      ! ------------------------------------------------
228      n = 1   ! begining of time step
229
230      zcpvap = rcpv
231      zcwat = rcw
232      zcice = rcs
233
234      CALL integr_v(klon, klev, zcpvap, &
235              t_seri, q_seri, ql_seri, qs_seri, qbs_seri, u_seri, v_seri, zairm, &
236              zqw_col(:, n), zql_col(:, n), zqs_col(:, n), zqbs_col(:, n), zek_col(:, n), zh_dair_col(:, n), &
237              zh_qw_col(:, n), zh_ql_col(:, n), zh_qs_col(:, n), zh_qbs_col(:, n), zh_col(:, n))
238
239    ENDIF ! END IF (fl_ebil .GT. 0)
240
241    !======================================================================
242    ! Ajout des tendances sur le vent et l'eau liquide
243    !======================================================================
244
245    u_seri(:, :) = u_seri(:, :) + zdu(:, :)
246    v_seri(:, :) = v_seri(:, :) + zdv(:, :)
247    ql_seri(:, :) = ql_seri(:, :) + zdql(:, :)
248    qs_seri(:, :) = qs_seri(:, :) + zdqi(:, :)
249    qbs_seri(:, :) = qbs_seri(:, :) + zdqbs(:, :)
250
251    !======================================================================
252    ! On ajoute les tendances de la temperature et de la vapeur d'eau
253    ! en verifiant que ca ne part pas dans les choux
254    !======================================================================
255
256    jbad = 0
257    jqbad = 0
258    DO k = 1, klev
259      DO i = 1, klon
260        zt = t_seri(i, k) + zdt(i, k)
261        zq = q_seri(i, k) + zdq(i, k)
262        IF (zt>370. .OR. zt<130. .OR. abs(zdt(i, k))>50.) THEN
263          jbad = jbad + 1
264          jadrs(jbad) = i
265          kadrs(jbad) = k
266        ENDIF
267        IF (zq<0. .OR. zq>0.1 .OR. abs(zdq(i, k))>1.e-2) THEN
268          jqbad = jqbad + 1
269          jqadrs(jqbad) = i
270          kqadrs(jqbad) = k
271        ENDIF
272        t_seri(i, k) = zt
273        q_seri(i, k) = zq
274      ENDDO
275    ENDDO
276
277    !=====================================================================================
278    ! Impression et stop en cas de probleme important
279    !=====================================================================================
280
281    IF (jbad > 0) THEN
282      DO j = 1, jbad
283        i = jadrs(j)
284        IF (prt_level>=debug_level) THEN
285          PRINT*, 'PLANTAGE POUR LE POINT i lon lat =', &
286                  i, longitude_deg(i), latitude_deg(i), text
287          PRINT*, 'l    T     dT       Q     dQ    '
288          DO k = 1, klev
289            WRITE(*, '(i3,2f14.4,2e14.2)') k, t_seri(i, k), zdt(i, k), q_seri(i, k), zdq(i, k)
290          ENDDO
291          CALL print_debug_phys(i, debug_level, text)
292        ENDIF
293      ENDDO
294    ENDIF
295
296    !=====================================================================================
297    ! Impression, warning et correction en cas de probleme moins important
298    !=====================================================================================
299    IF (jqbad > 0) THEN
300      done(:) = .FALSE.                         !jyg
301      DO j = 1, jqbad
302        i = jqadrs(j)
303        IF(prt_level>=debug_level) THEN
304          PRINT*, 'WARNING  : EAU POUR LE POINT i lon lat =', &
305                  i, longitude_deg(i), latitude_deg(i), text
306          PRINT*, 'l    T     dT       Q     dQ    '
307          DO k = 1, klev
308            WRITE(*, '(i3,2f14.4,2e14.2)') k, t_seri(i, k), zdt(i, k), q_seri(i, k), zdq(i, k)
309          ENDDO
310        ENDIF
311        IF (ok_conserv_q) THEN
312          !jyg<20140228 Corrections pour conservation de l'eau
313          IF (.NOT.done(i)) THEN                  !jyg
314            DO k = 1, klev
315              zqp(k) = max(q_seri(i, k), 1.e-15)
316            ENDDO
317            zq_int = 0.
318            zqp_int = 0.
319            DO k = 1, klev
320              zq_int = zq_int + q_seri(i, k) * (paprs(i, k) - paprs(i, k + 1)) / Rg
321              zqp_int = zqp_int + zqp(k) * (paprs(i, k) - paprs(i, k + 1)) / Rg
322            ENDDO
323            IF (prt_level>=debug_level) THEN
324              PRINT*, ' cas q_seri<1.e-15 i k zq_int zqp_int zq_int/zqp_int :', &
325                      i, kqadrs(j), zq_int, zqp_int, zq_int / zqp_int
326            ENDIF
327            DO k = 1, klev
328              zq_new = zqp(k) * zq_int / zqp_int
329              zdq(i, k) = zdq(i, k) + zq_new - q_seri(i, k)
330              q_seri(i, k) = zq_new
331            ENDDO
332            done(i) = .TRUE.
333          ENDIF !(.NOT.done(i))
334        ELSE
335          !jyg>
336          DO k = 1, klev
337            zq = q_seri(i, k) + zdq(i, k)
338            IF (zq<1.e-15) THEN
339              IF (q_seri(i, k)<1.e-15) THEN
340                IF (prt_level>=debug_level) THEN
341                  PRINT*, ' cas q_seri<1.e-15 i k q_seri zq zdq :', i, k, q_seri(i, k), zq, zdq(i, k)
342                ENDIF
343                q_seri(i, k) = 1.e-15
344                zdq(i, k) = (1.e-15 - q_seri(i, k))
345              ENDIF
346            ENDIF
347            !              zq=q_seri(i,k)+zdq(i,k)
348            !              if (zq.lt.1.e-15) THEN
349            !                 zdq(i,k)=(1.e-15-q_seri(i,k))
350            !              endif
351          ENDDO
352          !jyg<20140228
353        ENDIF   !  (ok_conserv_q)
354        !jyg>
355      ENDDO ! j = 1, jqbad
356    ENDIF
357
358    !IM ajout memes tests pour reverifier les jbad, jqbad beg
359    jbad = 0
360    jqbad = 0
361    DO k = 1, klev
362      DO i = 1, klon
363        IF (t_seri(i, k)>370. .OR. t_seri(i, k)<130. .OR. abs(zdt(i, k))>50.) THEN
364          jbad = jbad + 1
365          jadrs(jbad) = i
366          !         IF(prt_level.ge.debug_level) THEN
367          !         PRINT*,'cas2 i k t_seri zdt',i,k,t_seri(i,k),zdt(i,k)
368          !        endif
369        ENDIF
370        IF (q_seri(i, k)<0. .OR. q_seri(i, k)>0.1 .OR. abs(zdq(i, k))>1.e-2) THEN
371          jqbad = jqbad + 1
372          jqadrs(jqbad) = i
373          kqadrs(jqbad) = k
374          !        IF(prt_level.ge.debug_level) THEN
375          !         PRINT*,'cas2 i k q_seri zdq',i,k,q_seri(i,k),zdq(i,k)
376          !        endif
377        ENDIF
378      ENDDO
379    ENDDO
380    IF (jbad > 0) THEN
381      DO j = 1, jbad
382        i = jadrs(j)
383        k = kadrs(j)
384        IF(prt_level>=debug_level) THEN
385          PRINT*, 'PLANTAGE2 POUR LE POINT i itap lon lat txt jbad zdt t', &
386                  i, itap, longitude_deg(i), latitude_deg(i), text, jbad, &
387                  zdt(i, k), t_seri(i, k) - zdt(i, k)
388          !!!       IF(prt_level.ge.10.AND.itap.GE.229.AND.i.EQ.3027) THEN
389          PRINT*, 'l    T     dT       Q     dQ    '
390          DO k = 1, klev
391            WRITE(*, '(i3,2f14.4,2e14.2)') k, t_seri(i, k), zdt(i, k), q_seri(i, k), zdq(i, k)
392          ENDDO
393          CALL print_debug_phys(i, debug_level, text)
394        ENDIF
395      ENDDO
396    ENDIF
397
398    IF (jqbad > 0) THEN
399      DO j = 1, jqbad
400        i = jqadrs(j)
401        k = kqadrs(j)
402        IF (prt_level>=debug_level) THEN
403          PRINT*, 'WARNING  : EAU2 POUR LE POINT i itap lon lat txt jqbad zdq q zdql ql', &
404                  i, itap, longitude_deg(i), latitude_deg(i), text, jqbad, &
405                  zdq(i, k), q_seri(i, k) - zdq(i, k), zdql(i, k), ql_seri(i, k) - zdql(i, k)
406          !!!       IF(prt_level.ge.10.AND.itap.GE.229.AND.i.EQ.3027) THEN
407          PRINT*, 'l    T     dT       Q     dQ    '
408          DO k = 1, klev
409            WRITE(*, '(i3,2f14.4,2e14.2)') k, t_seri(i, k), zdt(i, k), q_seri(i, k), zdq(i, k)
410          ENDDO
411          CALL print_debug_phys(i, debug_level, text)
412        ENDIF
413      ENDDO
414    ENDIF
415
416    !======================================================================
417    ! Contrôle des min/max pour arrêt du modèle
418    ! Si le modele est en mode abortphy, on retire les tendances qu'on
419    ! vient d'ajouter. Pas exactement parce qu'on ne tient pas compte des
420    ! seuils.
421    !======================================================================
422
423    CALL hgardfou(t_seri, ftsol, text, abortphy)
424    IF (abortphy==1) THEN
425      PRINT*, 'ERROR ABORT hgardfou dans ', text
426      ! JLD pourquoi on ne modifie pas de meme t_seri et q_seri ?
427      u_seri(:, :) = u_seri(:, :) - zdu(:, :)
428      v_seri(:, :) = v_seri(:, :) - zdv(:, :)
429      ql_seri(:, :) = ql_seri(:, :) - zdql(:, :)
430      qs_seri(:, :) = qs_seri(:, :) - zdqi(:, :)
431      qbs_seri(:, :) = qbs_seri(:, :) - zdqbs(:, :)
432    ENDIF
433
434    !======================================================================
435    ! Diagnostics for energy conservation tests
436    !======================================================================
437
438    IF (fl_ebil > 0) THEn
439
440      ! ------------------------------------------------
441      ! Compute vertical sum for each atmospheric column
442      ! ------------------------------------------------
443      n = 2   ! end of time step
444
445      CALL integr_v(klon, klev, zcpvap, &
446              t_seri, q_seri, ql_seri, qs_seri, qbs_seri, u_seri, v_seri, zairm, &
447              zqw_col(:, n), zql_col(:, n), zqs_col(:, n), zqbs_col(:, n), zek_col(:, n), zh_dair_col(:, n), &
448              zh_qw_col(:, n), zh_ql_col(:, n), zh_qs_col(:, n), zh_qbs_col(:, n), zh_col(:, n))
449
450      ! ------------------------------------------------
451      ! Compute the changes by unit of time
452      ! ------------------------------------------------
453
454      d_qw_col(:) = (zqw_col(:, 2) - zqw_col(:, 1)) / phys_tstep
455      d_ql_col(:) = (zql_col(:, 2) - zql_col(:, 1)) / phys_tstep
456      d_qs_col(:) = (zqs_col(:, 2) - zqs_col(:, 1)) / phys_tstep
457      d_qbs_col(:) = (zqbs_col(:, 2) - zqbs_col(:, 1)) / phys_tstep
458      d_qt_col(:) = d_qw_col(:) + d_ql_col(:) + d_qs_col(:) + d_qbs_col(:)
459
460      d_ek_col(:) = (zek_col(:, 2) - zek_col(:, 1)) / phys_tstep
461
462      d_h_dair_col(:) = (zh_dair_col(:, 2) - zh_dair_col(:, 1)) / phys_tstep
463      d_h_qw_col(:) = (zh_qw_col(:, 2) - zh_qw_col(:, 1)) / phys_tstep
464      d_h_ql_col(:) = (zh_ql_col(:, 2) - zh_ql_col(:, 1)) / phys_tstep
465      d_h_qs_col(:) = (zh_qs_col(:, 2) - zh_qs_col(:, 1)) / phys_tstep
466      d_h_qbs_col(:) = (zh_qbs_col(:, 2) - zh_qbs_col(:, 1)) / phys_tstep
467
468      d_h_col = (zh_col(:, 2) - zh_col(:, 1)) / phys_tstep
469
470    ENDIF ! END IF (fl_ebil .GT. 0)
471
472    ! When in diagnostic mode, restore "out" variables to initial values.
473    IF (diag_mode == 1) THEN
474      u_seri(:, :) = sav_u_seri(:, :)
475      v_seri(:, :) = sav_v_seri(:, :)
476      ql_seri(:, :) = sav_ql_seri(:, :)
477      qs_seri(:, :) = sav_qs_seri(:, :)
478      qbs_seri(:, :) = sav_qbs_seri(:, :)
479      q_seri(:, :) = sav_q_seri(:, :)
480      t_seri(:, :) = sav_t_seri(:, :)
481      zdq(:, :) = sav_zdq(:, :)
482    ENDIF ! (mode == 1)
483
484  END SUBROUTINE add_phys_tend
485
486  SUBROUTINE diag_phys_tend(nlon, nlev, uu, vv, temp, qv, ql, qs, qbs, &
487          zdu, zdv, zdt, zdq, zdql, zdqs, zdqbs, paprs, text)
488    !======================================================================
489    ! Ajoute les tendances des variables physiques aux variables
490    ! d'etat de la dynamique t_seri, q_seri ...
491    ! On en profite pour faire des tests sur les tendances en question.
492    !======================================================================
493
494
495    !======================================================================
496    ! Declarations
497    !======================================================================
498
499    USE phys_state_var_mod, ONLY: phys_tstep, ftsol
500    USE lmdz_geometry, ONLY: longitude_deg, latitude_deg
501    USE lmdz_print_control, ONLY: prt_level
502    USE cmp_seri_mod
503    USE phys_output_var_mod, ONLY: d_qw_col, d_ql_col, d_qs_col, d_qbs_col, d_qt_col, d_ek_col, d_h_dair_col &
504            , d_h_qw_col, d_h_ql_col, d_h_qs_col, d_h_qbs_col, d_h_col
505    USE lmdz_clesphys
506    USE lmdz_yomcst
507
508    IMPLICIT NONE
509
510    ! Arguments :
511    !------------
512    INTEGER, INTENT(IN) :: nlon, nlev
513    REAL, DIMENSION(nlon, nlev), INTENT(IN) :: uu, vv
514    REAL, DIMENSION(nlon, nlev), INTENT(IN) :: temp, qv, ql, qs, qbs
515    REAL, DIMENSION(nlon, nlev), INTENT(IN) :: zdu, zdv
516    REAL, DIMENSION(nlon, nlev), INTENT(IN) :: zdt, zdq, zdql, zdqs, zdqbs
517    REAL, DIMENSION(nlon, nlev + 1), INTENT(IN) :: paprs
518    CHARACTER*(*), INTENT(IN) :: text
519
520    ! Local :
521    !--------
522    REAL, DIMENSION(nlon, nlev) :: uu_n, vv_n
523    REAL, DIMENSION(nlon, nlev) :: temp_n, qv_n, ql_n, qs_n, qbs_n
524
525    INTEGER k, n
526
527    INTEGER debug_level
528    LOGICAL, SAVE :: first = .TRUE.
529    !$OMP THREADPRIVATE(first)
530
531    !======================================================================
532    ! Variables for energy conservation tests
533    !======================================================================
534
535    ! zh_col-------  total enthalpy of vertical air column
536    ! (air with watter vapour, liquid and solid) (J/m2)
537    ! zh_dair_col--- total enthalpy of dry air (J/m2)
538    ! zh_qw_col----  total enthalpy of watter vapour (J/m2)
539    ! zh_ql_col----  total enthalpy of liquid watter (J/m2)
540    ! zh_qs_col----  total enthalpy of solid watter  (J/m2)
541    ! zqw_col------  total mass of watter vapour (kg/m2)
542    ! zql_col------  total mass of liquid watter (kg/m2)
543    ! zqs_col------  total mass of cloud ice (kg/m2)
544    ! zqbs_col------  total mass of blowing snow (kg/m2)
545    ! zek_col------  total kinetic energy (kg/m2)
546
547    REAL zairm(nlon, nlev) ! layer air mass (kg/m2)
548    REAL zqw_col(nlon, 2)
549    REAL zql_col(nlon, 2)
550    REAL zqs_col(nlon, 2)
551    REAL zqbs_col(nlon, 2)
552    REAL zek_col(nlon, 2)
553    REAL zh_dair_col(nlon, 2)
554    REAL zh_qw_col(nlon, 2), zh_ql_col(nlon, 2), zh_qs_col(nlon, 2), zh_qbs_col(nlon, 2)
555    REAL zh_col(nlon, 2)
556
557    !======================================================================
558    ! Initialisations
559
560    IF (prt_level >= 5) THEN
561      write (*, *) "In diag_phys_tend, after ", text
562      CALL flush
563    ENDIF
564
565    debug_level = 10
566    IF (first) THEN
567      PRINT *, "TestJLD rcpv, rcw, rcs", rcpv, rcw, rcs
568      first = .FALSE.
569    ENDIF
570
571    !  PRINT *,'add_phys_tend: paprs ',paprs
572    !======================================================================
573    ! Diagnostics for energy conservation tests
574    !======================================================================
575    DO k = 1, nlev
576      ! layer air mass
577      zairm(:, k) = (paprs(:, k) - paprs(:, k + 1)) / rg
578    ENDDO
579
580    IF (fl_ebil > 0) THEN
581      ! ------------------------------------------------
582      ! Compute vertical sum for each atmospheric column
583      ! ------------------------------------------------
584      n = 1   ! begining of time step
585
586      CALL integr_v(nlon, nlev, rcpv, &
587              temp, qv, ql, qs, qbs, uu, vv, zairm, &
588              zqw_col(:, n), zql_col(:, n), zqs_col(:, n), zqbs_col(:, n), zek_col(:, n), zh_dair_col(:, n), &
589              zh_qw_col(:, n), zh_ql_col(:, n), zh_qs_col(:, n), zh_qbs_col(:, n), zh_col(:, n))
590
591    ENDIF ! END IF (fl_ebil .GT. 0)
592
593    !======================================================================
594    ! Ajout des tendances sur le vent, la temperature et les diverses phases de l'eau
595    !======================================================================
596
597    uu_n(:, :) = uu(:, :) + zdu(:, :)
598    vv_n(:, :) = vv(:, :) + zdv(:, :)
599    qv_n(:, :) = qv(:, :) + zdq(:, :)
600    ql_n(:, :) = ql(:, :) + zdql(:, :)
601    qs_n(:, :) = qs(:, :) + zdqs(:, :)
602    qbs_n(:, :) = qbs(:, :) + zdqbs(:, :)
603    temp_n(:, :) = temp(:, :) + zdt(:, :)
604
605    !======================================================================
606    ! Diagnostics for energy conservation tests
607    !======================================================================
608
609    IF (fl_ebil > 0) THEN
610
611      ! ------------------------------------------------
612      ! Compute vertical sum for each atmospheric column
613      ! ------------------------------------------------
614      n = 2   ! end of time step
615
616      CALL integr_v(nlon, nlev, rcpv, &
617              temp_n, qv_n, ql_n, qs_n, qbs_n, uu_n, vv_n, zairm, &
618              zqw_col(:, n), zql_col(:, n), zqs_col(:, n), zqbs_col(:, n), zek_col(:, n), zh_dair_col(:, n), &
619              zh_qw_col(:, n), zh_ql_col(:, n), zh_qs_col(:, n), zh_qbs_col(:, n), zh_col(:, n))
620
621      ! ------------------------------------------------
622      ! Compute the changes by unit of time
623      ! ------------------------------------------------
624
625      d_qw_col(:) = (zqw_col(:, 2) - zqw_col(:, 1)) / phys_tstep
626      d_ql_col(:) = (zql_col(:, 2) - zql_col(:, 1)) / phys_tstep
627      d_qs_col(:) = (zqs_col(:, 2) - zqs_col(:, 1)) / phys_tstep
628      d_qbs_col(:) = (zqbs_col(:, 2) - zqbs_col(:, 1)) / phys_tstep
629      d_qt_col(:) = d_qw_col(:) + d_ql_col(:) + d_qs_col(:) + d_qbs_col(:)
630
631      d_ek_col(:) = (zek_col(:, 2) - zek_col(:, 1)) / phys_tstep
632
633      PRINT *, 'zdu ', zdu
634      PRINT *, 'zdv ', zdv
635      PRINT *, 'd_ek_col, zek_col(2), zek_col(1) ', d_ek_col(1), zek_col(1, 2), zek_col(1, 1)
636
637      d_h_dair_col(:) = (zh_dair_col(:, 2) - zh_dair_col(:, 1)) / phys_tstep
638      d_h_qw_col(:) = (zh_qw_col(:, 2) - zh_qw_col(:, 1)) / phys_tstep
639      d_h_ql_col(:) = (zh_ql_col(:, 2) - zh_ql_col(:, 1)) / phys_tstep
640      d_h_qs_col(:) = (zh_qs_col(:, 2) - zh_qs_col(:, 1)) / phys_tstep
641      d_h_qbs_col(:) = (zh_qbs_col(:, 2) - zh_qbs_col(:, 1)) / phys_tstep
642
643      d_h_col = (zh_col(:, 2) - zh_col(:, 1)) / phys_tstep
644
645    ENDIF ! END IF (fl_ebil .GT. 0)
646
647  END SUBROUTINE diag_phys_tend
648
649  SUBROUTINE integr_v(nlon, nlev, zcpvap, &
650          temp, qv, ql, qs, qbs, uu, vv, zairm, &
651          zqw_col, zql_col, zqs_col, zqbs_col, zek_col, zh_dair_col, &
652          zh_qw_col, zh_ql_col, zh_qs_col, zh_qbs_col, zh_col)
653
654    USE lmdz_yomcst
655    IMPLICIT NONE
656
657    INTEGER, INTENT(IN) :: nlon, nlev
658    REAL, INTENT(IN) :: zcpvap
659    REAL, DIMENSION(nlon, nlev), INTENT(IN) :: temp, qv, ql, qs, qbs, uu, vv
660    REAL, DIMENSION(nlon, nlev), INTENT(IN) :: zairm
661    REAL, DIMENSION(nlon), INTENT(OUT) :: zqw_col
662    REAL, DIMENSION(nlon), INTENT(OUT) :: zql_col
663    REAL, DIMENSION(nlon), INTENT(OUT) :: zqs_col, zqbs_col
664    REAL, DIMENSION(nlon), INTENT(OUT) :: zek_col
665    REAL, DIMENSION(nlon), INTENT(OUT) :: zh_dair_col
666    REAL, DIMENSION(nlon), INTENT(OUT) :: zh_qw_col
667    REAL, DIMENSION(nlon), INTENT(OUT) :: zh_ql_col
668    REAL, DIMENSION(nlon), INTENT(OUT) :: zh_qs_col, zh_qbs_col
669    REAL, DIMENSION(nlon), INTENT(OUT) :: zh_col
670
671    INTEGER :: i, k
672
673    ! Reset variables
674    zqw_col(:) = 0.
675    zql_col(:) = 0.
676    zqs_col(:) = 0.
677    zqbs_col(:) = 0.
678    zek_col(:) = 0.
679    zh_dair_col(:) = 0.
680    zh_qw_col(:) = 0.
681    zh_ql_col(:) = 0.
682    zh_qs_col(:) = 0.
683    zh_qbs_col(:) = 0.
684
685    !JLD    write (*,*) "rcpd, zcpvap, zcwat, zcice ",rcpd, zcpvap, zcwat, zcice
686
687    ! ------------------------------------------------
688    ! Compute vertical sum for each atmospheric column
689    ! ------------------------------------------------
690    DO k = 1, nlev
691      DO i = 1, nlon
692        ! Watter mass
693        zqw_col(i) = zqw_col(i) + qv(i, k) * zairm(i, k)
694        zql_col(i) = zql_col(i) + ql(i, k) * zairm(i, k)
695        zqs_col(i) = zqs_col(i) + qs(i, k) * zairm(i, k)
696        zqbs_col(i) = zqbs_col(i) + qbs(i, k) * zairm(i, k)
697        ! Kinetic Energy
698        zek_col(i) = zek_col(i) + 0.5 * (uu(i, k)**2 + vv(i, k)**2) * zairm(i, k)
699        ! Air enthalpy : dry air, water vapour, liquid, solid
700        zh_dair_col(i) = zh_dair_col(i) + rcpd * (1. - qv(i, k) - ql(i, k) - qs(i, k)) * &
701                zairm(i, k) * temp(i, k)
702        zh_qw_col(i) = zh_qw_col(i) + zcpvap * temp(i, k) * qv(i, k) * zairm(i, k)    !jyg
703        zh_ql_col(i) = zh_ql_col(i) + (zcpvap * temp(i, k) - rlvtt) * ql(i, k) * zairm(i, k)   !jyg
704        zh_qs_col(i) = zh_qs_col(i) + (zcpvap * temp(i, k) - rlstt) * qs(i, k) * zairm(i, k)   !jyg
705        zh_qbs_col(i) = zh_qbs_col(i) + (zcpvap * temp(i, k) - rlstt) * qbs(i, k) * zairm(i, k)   !jyg
706      ENDDO
707    ENDDO
708    ! compute total air enthalpy
709    zh_col(:) = zh_dair_col(:) + zh_qw_col(:) + zh_ql_col(:) + zh_qs_col(:) + zh_qbs_col(:)
710
711  END SUBROUTINE integr_v
712
713  SUBROUTINE prt_enerbil(text, itap)
714    !======================================================================
715    ! Print enenrgy budget diagnotics for the 1D case
716    !======================================================================
717
718    !======================================================================
719    ! Declarations
720    !======================================================================
721
722    USE dimphy, ONLY: klon, klev
723    USE phys_state_var_mod, ONLY: phys_tstep
724    USE phys_state_var_mod, ONLY: topsw, toplw, solsw, sollw, rain_con, snow_con, bs_fall
725    USE lmdz_geometry, ONLY: longitude_deg, latitude_deg
726    USE lmdz_print_control, ONLY: prt_level
727    USE cmp_seri_mod
728    USE phys_output_var_mod, ONLY: d_qw_col, d_ql_col, d_qs_col, d_qbs_col, d_qt_col, d_ek_col, d_h_dair_col &
729            , d_h_qw_col, d_h_ql_col, d_h_qs_col, d_h_qbs_col, d_h_col
730    USE phys_local_var_mod, ONLY: evap, sens
731    USE phys_local_var_mod, ONLY: u_seri, v_seri, ql_seri, qs_seri, qbs_seri, q_seri, t_seri &
732            , rain_lsc, snow_lsc
733    USE climb_hq_mod, ONLY: d_h_col_vdf, f_h_bnd
734    USE lmdz_yomcst
735
736    IMPLICIT NONE
737
738    ! Arguments :
739    !------------
740    CHARACTER*(*) text ! text specifing the involved parametrization
741    INTEGER itap        ! time step number
742    ! local variables
743    ! ---------------
744    REAL bilq_seuil, bilh_seuil ! thresold on error in Q and H budget
745    REAL bilq_error, bilh_error ! erros in Q and H budget
746    REAL bilq_bnd, bilh_bnd     ! Q and H budget due to exchange with boundaries
747    INTEGER bilq_ok, bilh_ok
748    CHARACTER*(12) status
749
750    bilq_seuil = 1.E-10
751    bilh_seuil = 1.E-1
752    bilq_ok = 0
753    bilh_ok = 0
754
755    !!PRINT *,'prt_level:',prt_level,' fl_ebil:',fl_ebil,' fl_cor_ebil:',fl_cor_ebil
756    IF ((fl_ebil > 0) .AND. (klon == 1)) THEN
757
758      bilq_bnd = 0.
759      bilh_bnd = 0.
760
761      param: SELECT CASE (text)
762      CASE("vdf") param
763        bilq_bnd = evap(1)
764        bilh_bnd = sens(1) + (rcpv - rcpd) * evap(1) * t_seri(1, 1)
765      CASE("lsc") param
766        bilq_bnd = - rain_lsc(1) - snow_lsc(1)
767        bilh_bnd = (-(rcw - rcpd) * t_seri(1, 1) + rlvtt) * rain_lsc(1) &
768                + (-(rcs - rcpd) * t_seri(1, 1) + rlstt) * snow_lsc(1)
769      CASE("bsss") param
770        bilq_bnd = - bs_fall(1)
771        bilh_bnd = (-(rcs - rcpd) * t_seri(1, 1) + rlstt) * bs_fall(1)
772      CASE("convection") param
773        bilq_bnd = - rain_con(1) - snow_con(1)
774        bilh_bnd = (-(rcw - rcpd) * t_seri(1, 1) + rlvtt) * rain_con(1) &
775                + (-(rcs - rcpd) * t_seri(1, 1) + rlstt) * snow_con(1)
776      CASE("SW") param
777        bilh_bnd = topsw(1) - solsw(1)
778      CASE("LW") param
779        bilh_bnd = -(toplw(1) + sollw(1))
780      CASE DEFAULT param
781        bilq_bnd = 0.
782        bilh_bnd = 0.
783      END SELECT param
784
785      bilq_error = d_qt_col(1) - bilq_bnd
786      bilh_error = d_h_col(1) - bilh_bnd
787      ! are the errors too large?
788      IF (abs(bilq_error) > bilq_seuil) bilq_ok = 1
789      IF (abs(bilh_error) > bilh_seuil) bilh_ok = 1
790
791      ! Print diagnostics
792      ! =================
793      IF ((bilq_ok == 0).AND.(bilh_ok == 0)) THEN
794        status = "enerbil-OK"
795      ELSE
796        status = "enerbil-PB"
797      ENDIF
798
799      IF (prt_level >= 3) THEN
800        WRITE(*, 9010) text, status, " itap:", itap, "enerbilERROR: Q", bilq_error, "  H", bilh_error
801        9010  format (1x, A8, 2x, A12, A6, I4, A18, E15.6, A5, E15.6)
802      ENDIF
803      IF (prt_level >= 3) THEN
804        WRITE(*, 9000) text, "enerbil: Q,H,KE budget", d_qt_col(1), d_h_col(1), d_ek_col(1)
805      ENDIF
806      IF (prt_level >= 5) THEN
807        WRITE(*, 9000) text, "enerbil at boundaries: Q, H", bilq_bnd, bilh_bnd
808        WRITE(*, 9000) text, "enerbil: water budget", d_qt_col(1), d_qw_col(1), d_ql_col(1), d_qs_col(1), d_qbs_col(1)
809        WRITE(*, 9000) text, "enerbil: enthalpy budget", d_h_col(1), d_h_dair_col(1), d_h_qw_col(1), d_h_ql_col(1), d_h_qs_col(1), d_h_qbs_col(1)
810      ENDIF
811
812      specific_diag: SELECT CASE (text)
813      CASE("vdf") specific_diag
814        IF (prt_level >= 5) THEN
815          WRITE(*, 9000) text, "enerbil: d_h, bilh, sens,t_seri", d_h_col(1), bilh_bnd, sens(1), t_seri(1, 1)
816          WRITE(*, 9000) text, "enerbil: d_h_col_vdf, f_h, diff", d_h_col_vdf, f_h_bnd, bilh_bnd - sens(1)
817        ENDIF
818      CASE("lsc") specific_diag
819        IF (prt_level >= 5) THEN
820          WRITE(*, 9000) text, "enerbil: rain, bil_lat, bil_sens", rain_lsc(1), rlvtt * rain_lsc(1), -(rcw - rcpd) * t_seri(1, 1) * rain_lsc(1)
821          WRITE(*, 9000) text, "enerbil: snow, bil_lat, bil_sens", snow_lsc(1), rlstt * snow_lsc(1), -(rcs - rcpd) * t_seri(1, 1) * snow_lsc(1)
822        ENDIF
823      CASE("convection") specific_diag
824        IF (prt_level >= 5) THEN
825          WRITE(*, 9000) text, "enerbil: rain, bil_lat, bil_sens", rain_con(1), rlvtt * rain_con(1), -(rcw - rcpd) * t_seri(1, 1) * rain_con(1)
826          WRITE(*, 9000) text, "enerbil: snow, bil_lat, bil_sens", snow_con(1), rlstt * snow_con(1), -(rcs - rcpd) * t_seri(1, 1) * snow_con(1)
827        ENDIF
828      END SELECT specific_diag
829
830      9000 FORMAT(1x, A8, 2x, A35, 10E15.6)
831
832    ENDIF ! END IF (fl_ebil .GT. 0)
833
834  END SUBROUTINE prt_enerbil
835
836END MODULE add_phys_tend_mod
Note: See TracBrowser for help on using the repository browser.