source: LMDZ6/branches/blowing_snow/libf/phylmdiso/add_phys_tend_mod.F90 @ 5327

Last change on this file since 5327 was 4506, checked in by evignon, 19 months ago

commit sur des modifications propres aux isotopes pour la neige soufflee

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