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

Last change on this file since 5836 was 5836, checked in by rkazeroni, 2 months ago

For GPU porting of add_phys_tend and add_wake_tend routines:

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