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

Last change on this file since 5140 was 5140, checked in by abarral, 3 months ago

Put comsoil.h, conema3.h, cvflag.h into modules

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