source: LMDZ6/trunk/libf/phylmd/add_phys_tend_mod.f90 @ 5274

Last change on this file since 5274 was 5274, checked in by abarral, 9 hours ago

Replace yomcst.h by existing module

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