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

Last change on this file since 5450 was 5285, checked in by abarral, 2 months ago

As discussed internally, remove generic ONLY: ... for new _mod_h modules

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