source: LMDZ6/trunk/libf/phylmd/yamada_c.F90 @ 5274

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

Replace yomcst.h by existing module

  • Property copyright set to
    Name of program: LMDZ
    Creation date: 1984
    Version: LMDZ5
    License: CeCILL version 2
    Holder: Laboratoire de m\'et\'eorologie dynamique, CNRS, UMR 8539
    See the license file in the root directory
File size: 16.2 KB
Line 
1!
2! $Header$
3!
4      SUBROUTINE yamada_c(ngrid,timestep,plev,play &
5     &   ,pu,pv,pt,d_u,d_v,d_t,cd,q2,km,kn,kq,d_t_diss,ustar &
6     &   ,iflag_pbl)
7      USE dimphy, ONLY: klon, klev
8      USE print_control_mod, ONLY: prt_level
9      USE ioipsl_getin_p_mod, ONLY : getin_p
10
11      USE yomcst_mod_h, ONLY: RPI, RCLUM, RHPLA, RKBOL, RNAVO                   &
12          , RDAY, REA, REPSM, RSIYEA, RSIDAY, ROMEGA                  &
13          , R_ecc, R_peri, R_incl                                      &
14          , RA, RG, R1SA                                         &
15          , RSIGMA                                                     &
16          , R, RMD, RMV, RD, RV, RCPD                    &
17          , RMO3, RMCO2, RMC, RMCH4, RMN2O, RMCFC11, RMCFC12        &
18          , RCPV, RCVD, RCVV, RKAPPA, RETV, eps_w                    &
19          , RCW, RCS                                                 &
20          , RLVTT, RLSTT, RLMLT, RTT, RATM                           &
21          , RESTT, RALPW, RBETW, RGAMW, RALPS, RBETS, RGAMS            &
22          , RALPD, RBETD, RGAMD
23IMPLICIT NONE
24
25!
26! timestep : pas de temps
27! g  : g
28! zlev : altitude a chaque niveau (interface inferieure de la couche
29!        de meme indice)
30! zlay : altitude au centre de chaque couche
31! u,v : vitesse au centre de chaque couche
32!       (en entree : la valeur au debut du pas de temps)
33! teta : temperature potentielle au centre de chaque couche
34!        (en entree : la valeur au debut du pas de temps)
35! cd : cdrag
36!      (en entree : la valeur au debut du pas de temps)
37! q2 : $q^2$ au bas de chaque couche
38!      (en entree : la valeur au debut du pas de temps)
39!      (en sortie : la valeur a la fin du pas de temps)
40! km : diffusivite turbulente de quantite de mouvement (au bas de chaque
41!      couche)
42!      (en sortie : la valeur a la fin du pas de temps)
43! kn : diffusivite turbulente des scalaires (au bas de chaque couche)
44!      (en sortie : la valeur a la fin du pas de temps)
45!
46!  iflag_pbl doit valoir entre 6 et 9
47!      l=6, on prend  systematiquement une longueur d'equilibre
48!    iflag_pbl=6 : MY 2.0
49!    iflag_pbl=7 : MY 2.0.Fournier
50!    iflag_pbl=8/9 : MY 2.5
51!       iflag_pbl=8 with special obsolete treatments for convergence
52!       with Cmpi5 NPv3.1 simulations
53!    iflag_pbl=10/11 :  New scheme M2 and N2 explicit and dissiptation exact
54!    iflag_pbl=12 = 11 with vertical diffusion off q2
55!
56!  2013/04/01 (FH hourdin@lmd.jussieu.fr)
57!     Correction for very stable PBLs (iflag_pbl=10 and 11)
58!     iflag_pbl=8 converges numerically with NPv3.1
59!     iflag_pbl=11 -> the model starts with NP from start files created by ce0l
60!                  -> the model can run with longer time-steps.
61!.......................................................................
62
63      REAL, DIMENSION(klon,klev) :: d_u,d_v,d_t
64      REAL, DIMENSION(klon,klev) :: pu,pv,pt
65      REAL, DIMENSION(klon,klev) :: d_t_diss
66
67      REAL timestep
68      real plev(klon,klev+1)
69      real play(klon,klev)
70      real ustar(klon)
71      real kmin,qmin,pblhmin(klon),coriol(klon)
72      REAL zlev(klon,klev+1)
73      REAL zlay(klon,klev)
74      REAL zu(klon,klev)
75      REAL zv(klon,klev)
76      REAL zt(klon,klev)
77      REAL teta(klon,klev)
78      REAL cd(klon)
79      REAL q2(klon,klev+1),qpre
80      REAL unsdz(klon,klev)
81      REAL unsdzdec(klon,klev+1)
82
83      REAL km(klon,klev)
84      REAL kmpre(klon,klev+1),tmp2
85      REAL mpre(klon,klev+1)
86      REAL kn(klon,klev)
87      REAL kq(klon,klev)
88      real ff(klon,klev+1),delta(klon,klev+1)
89      real aa(klon,klev+1),aa0,aa1
90      integer iflag_pbl,ngrid
91      integer nlay,nlev
92
93      logical first
94      integer ipas
95      save first,ipas
96!FH/IM     data first,ipas/.true.,0/
97      data first,ipas/.false.,0/
98!$OMP THREADPRIVATE( first,ipas)
99       INTEGER, SAVE :: iflag_tke_diff=0
100!$OMP THREADPRIVATE(iflag_tke_diff)
101
102
103      integer ig,k
104
105
106      real ri,zrif,zalpha,zsm,zsn
107      real rif(klon,klev+1),sm(klon,klev+1),alpha(klon,klev)
108
109      real m2(klon,klev+1),dz(klon,klev+1),zq,n2(klon,klev+1)
110      REAL, DIMENSION(klon,klev+1) :: km2,kn2,sqrtq
111      real dtetadz(klon,klev+1)
112      real m2cstat,mcstat,kmcstat
113      real l(klon,klev+1)
114      real leff(klon,klev+1)
115      real,allocatable,save :: l0(:)
116!$OMP THREADPRIVATE(l0)     
117      real sq(klon),sqz(klon),zz(klon,klev+1)
118      integer iter
119
120      real ric,rifc,b1,kap
121      save ric,rifc,b1,kap
122      data ric,rifc,b1,kap/0.195,0.191,16.6,0.4/
123!$OMP THREADPRIVATE(ric,rifc,b1,kap)
124      real frif,falpha,fsm
125      real fl,zzz,zl0,zq2,zn2
126
127      real rino(klon,klev+1),smyam(klon,klev),styam(klon,klev)
128      real lyam(klon,klev),knyam(klon,klev)
129      real w2yam(klon,klev),t2yam(klon,klev)
130      logical,save :: firstcall=.true.
131!$OMP THREADPRIVATE(firstcall)       
132      CHARACTER(len=20),PARAMETER :: modname="yamada_c"
133REAL, DIMENSION(klon,klev+1) :: fluxu,fluxv,fluxt
134REAL, DIMENSION(klon,klev+1) :: dddu,dddv,dddt
135REAL, DIMENSION(klon,klev) :: exner,masse
136REAL, DIMENSION(klon,klev+1) :: masseb,q2old,q2neg
137      LOGICAL okiophys
138
139      frif(ri)=0.6588*(ri+0.1776-sqrt(ri*ri-0.3221*ri+0.03156))
140      falpha(ri)=1.318*(0.2231-ri)/(0.2341-ri)
141      fsm(ri)=1.96*(0.1912-ri)*(0.2341-ri)/((1.-ri)*(0.2231-ri))
142      fl(zzz,zl0,zq2,zn2)= &
143     &     max(min(l0(ig)*kap*zlev(ig,k)/(kap*zlev(ig,k)+l0(ig)) &
144     &     ,0.5*sqrt(q2(ig,k))/sqrt(max(n2(ig,k),1.e-10))) ,1.)
145
146
147      okiophys=klon==1
148      if (firstcall) then
149        CALL getin_p('iflag_tke_diff',iflag_tke_diff)
150        allocate(l0(klon))
151#define IOPHYS
152#ifdef IOPHYS
153!        call iophys_ini(timestep)
154#endif
155        firstcall=.false.
156      endif
157
158   IF (ngrid<=0) RETURN ! Bizarre : on n a pas ce probeleme pour coef_diff_turb
159
160#ifdef IOPHYS
161if (okiophys) then
162call iophys_ecrit('q2i',klev,'q2 debut my','m2/s2',q2(:,1:klev))
163call iophys_ecrit('kmi',klev,'Kz debut my','m/s2',km(:,1:klev))
164endif
165#endif
166
167      nlay=klev
168      nlev=klev+1
169
170
171!-------------------------------------------------------------------------
172! Computation of conservative source terms from the turbulent tendencies
173!-------------------------------------------------------------------------
174
175
176   zalpha=0.5 ! Anciennement 0.5. Essayer de voir pourquoi ?
177   zu(:,:)=pu(:,:)+zalpha*d_u(:,:)
178   zv(:,:)=pv(:,:)+zalpha*d_v(:,:)
179   zt(:,:)=pt(:,:)+zalpha*d_t(:,:)
180
181   do k=1,klev
182      exner(:,k)=(play(:,k)/plev(:,1))**RKAPPA
183      masse(:,k)=(plev(:,k)-plev(:,k+1))/RG
184      teta(:,k)=zt(:,k)/exner(:,k)
185   enddo
186
187! Atmospheric mass at layer interfaces, where the TKE is computed
188   masseb(:,:)=0.
189   do k=1,klev
190      masseb(:,k)=masseb(:,k)+masse(:,k)
191      masseb(:,k+1)=masseb(:,k+1)+masse(:,k)
192    enddo
193    masseb(:,:)=0.5*masseb(:,:)
194
195   zlev(:,1)=0.
196   zlay(:,1)=RCPD*teta(:,1)*(1.-exner(:,1))
197   do k=1,klev-1
198      zlay(:,k+1)=zlay(:,k)+0.5*RCPD*(teta(:,k)+teta(:,k+1))*(exner(:,k)-exner(:,k+1))/RG
199      zlev(:,k)=0.5*(zlay(:,k)+zlay(:,k+1)) ! PASBO
200   enddo
201
202   fluxu(:,klev+1)=0.
203   fluxv(:,klev+1)=0.
204   fluxt(:,klev+1)=0.
205
206   do k=klev,1,-1
207      fluxu(:,k)=fluxu(:,k+1)+masse(:,k)*d_u(:,k)
208      fluxv(:,k)=fluxv(:,k+1)+masse(:,k)*d_v(:,k)
209      fluxt(:,k)=fluxt(:,k+1)+masse(:,k)*d_t(:,k)/exner(:,k) ! Flux de theta
210   enddo
211
212   dddu(:,1)=2*zu(:,1)*fluxu(:,1)
213   dddv(:,1)=2*zv(:,1)*fluxv(:,1)
214   dddt(:,1)=(exner(:,1)-1.)*fluxt(:,1)
215
216   do k=2,klev
217      dddu(:,k)=(zu(:,k)-zu(:,k-1))*fluxu(:,k)
218      dddv(:,k)=(zv(:,k)-zv(:,k-1))*fluxv(:,k)
219      dddt(:,k)=(exner(:,k)-exner(:,k-1))*fluxt(:,k)
220   enddo
221   dddu(:,klev+1)=0.
222   dddv(:,klev+1)=0.
223   dddt(:,klev+1)=0.
224
225#ifdef IOPHYS
226if (okiophys) then
227      call iophys_ecrit('zlay',klev,'Geop','m',zlay)
228      call iophys_ecrit('teta',klev,'teta','K',teta)
229      call iophys_ecrit('temp',klev,'temp','K',zt)
230      call iophys_ecrit('pt',klev,'temp','K',pt)
231      call iophys_ecrit('pu',klev,'u','m/s',pu)
232      call iophys_ecrit('pv',klev,'v','m/s',pv)
233      call iophys_ecrit('d_u',klev,'d_u','m/s2',d_u)
234      call iophys_ecrit('d_v',klev,'d_v','m/s2',d_v)
235      call iophys_ecrit('d_t',klev,'d_t','K/s',d_t)
236      call iophys_ecrit('exner',klev,'exner','',exner)
237      call iophys_ecrit('masse',klev,'masse','',masse)
238      call iophys_ecrit('masseb',klev,'masseb','',masseb)
239endif
240#endif
241
242
243
244      ipas=ipas+1
245
246
247!.......................................................................
248!  les increments verticaux
249!.......................................................................
250!
251!!!!!! allerte !!!!!c
252!!!!!! zlev n'est pas declare a nlev !!!!!c
253!!!!!! ---->
254                                                      DO ig=1,ngrid
255            zlev(ig,nlev)=zlay(ig,nlay) &
256     &             +( zlay(ig,nlay) - zlev(ig,nlev-1) )
257                                                      ENDDO
258!!!!!! <----
259!!!!!! allerte !!!!!c
260!
261      DO k=1,nlay
262                                                      DO ig=1,ngrid
263        unsdz(ig,k)=1.E+0/(zlev(ig,k+1)-zlev(ig,k))
264                                                      ENDDO
265      ENDDO
266                                                      DO ig=1,ngrid
267      unsdzdec(ig,1)=1.E+0/(zlay(ig,1)-zlev(ig,1))
268                                                      ENDDO
269      DO k=2,nlay
270                                                      DO ig=1,ngrid
271        unsdzdec(ig,k)=1.E+0/(zlay(ig,k)-zlay(ig,k-1))
272                                                     ENDDO
273      ENDDO
274                                                      DO ig=1,ngrid
275      unsdzdec(ig,nlay+1)=1.E+0/(zlev(ig,nlay+1)-zlay(ig,nlay))
276                                                     ENDDO
277!
278!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
279! Computing M^2, N^2, Richardson numbers, stability functions
280!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
281
282
283      do k=2,klev
284                                                          do ig=1,ngrid
285         dz(ig,k)=zlay(ig,k)-zlay(ig,k-1)
286         m2(ig,k)=((zu(ig,k)-zu(ig,k-1))**2+(zv(ig,k)-zv(ig,k-1))**2)/(dz(ig,k)*dz(ig,k))
287         dtetadz(ig,k)=(teta(ig,k)-teta(ig,k-1))/dz(ig,k)
288         n2(ig,k)=RG*2.*dtetadz(ig,k)/(teta(ig,k-1)+teta(ig,k))
289!        n2(ig,k)=0.
290         ri=n2(ig,k)/max(m2(ig,k),1.e-10)
291         if (ri.lt.ric) then
292            rif(ig,k)=frif(ri)
293         else
294            rif(ig,k)=rifc
295         endif
296         if(rif(ig,k)<0.16) then
297            alpha(ig,k)=falpha(rif(ig,k))
298            sm(ig,k)=fsm(rif(ig,k))
299         else
300            alpha(ig,k)=1.12
301            sm(ig,k)=0.085
302         endif
303         zz(ig,k)=b1*m2(ig,k)*(1.-rif(ig,k))*sm(ig,k)
304                                                          enddo
305      enddo
306
307
308
309!====================================================================
310!  Computing the mixing length
311!====================================================================
312
313!   Mise a jour de l0
314      if (iflag_pbl==8.or.iflag_pbl==10) then
315
316!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
317! Iterative computation of l0
318! This version is kept for iflag_pbl only for convergence
319! with NPv3.1 Cmip5 simulations
320!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
321
322                                                          do ig=1,ngrid
323      sq(ig)=1.e-10
324      sqz(ig)=1.e-10
325                                                          enddo
326      do k=2,klev-1
327                                                          do ig=1,ngrid
328        zq=sqrt(q2(ig,k))
329        sqz(ig)=sqz(ig)+zq*zlev(ig,k)*(zlay(ig,k)-zlay(ig,k-1))
330        sq(ig)=sq(ig)+zq*(zlay(ig,k)-zlay(ig,k-1))
331                                                          enddo
332      enddo
333                                                          do ig=1,ngrid
334      l0(ig)=0.2*sqz(ig)/sq(ig)
335                                                          enddo
336      do k=2,klev
337                                                          do ig=1,ngrid
338         l(ig,k)=fl(zlev(ig,k),l0(ig),q2(ig,k),n2(ig,k))
339                                                          enddo
340      enddo
341!     print*,'L0 cas 8 ou 10 ',l0
342
343      else
344
345!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
346! In all other case, the assymptotic mixing length l0 is imposed (100m)
347!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
348
349          l0(:)=150.
350          do k=2,klev
351                                                          do ig=1,ngrid
352             l(ig,k)=fl(zlev(ig,k),l0(ig),q2(ig,k),n2(ig,k))
353                                                          enddo
354          enddo
355!     print*,'L0 cas autres ',l0
356
357      endif
358
359
360#ifdef IOPHYS
361if (okiophys) then
362call iophys_ecrit('rif',klev,'Flux Richardson','m',rif(:,1:klev))
363call iophys_ecrit('m2',klev,'m2 ','m/s',m2(:,1:klev))
364call iophys_ecrit('Km2app',klev,'m2 conserv','m/s',km(:,1:klev)*m2(:,1:klev))
365call iophys_ecrit('Km',klev,'Km','m2/s',km(:,1:klev))
366endif
367#endif
368
369
370IF (iflag_pbl<20) then
371      ! For diagnostics only
372      RETURN
373
374ELSE
375
376!  print*,'OK1'
377
378! Evolution of TKE under source terms K M2 and K N2
379   leff(:,:)=max(l(:,:),1.)
380
381!##################################################################
382!#  IF (iflag_pbl==29) THEN
383!#     STOP'Ne pas utiliser iflag_pbl=29'
384!#     km2(:,:)=km(:,:)*m2(:,:)
385!#     kn2(:,:)=kn2(:,:)*rif(:,:)
386!#  ELSEIF (iflag_pbl==25) THEN
387! VERSION AVEC LA TKE EN MILIEU DE COUCHE
388!#     STOP'Ne pas utiliser iflag_pbl=25'
389!#     DO k=1,klev
390!#        km2(:,k)=-0.5*(dddu(:,k)+dddv(:,k)+dddu(:,k+1)+dddv(:,k+1)) &
391!#        &        /(masse(:,k)*timestep)
392!#        kn2(:,k)=rcpd*0.5*(dddt(:,k)+dddt(:,k+1))/(masse(:,k)*timestep)
393!#        leff(:,k)=0.5*(leff(:,k)+leff(:,k+1))
394!#     ENDDO
395!#     km2(:,klev+1)=0. ; kn2(:,klev+1)=0.
396!#  ELSE
397!#################################################################
398
399      km2(:,:)=-(dddu(:,:)+dddv(:,:))/(masseb(:,:)*timestep)
400      kn2(:,:)=rcpd*dddt(:,:)/(masseb(:,:)*timestep)
401!   ENDIF
402   q2neg(:,:)=q2(:,:)+timestep*(km2(:,:)-kn2(:,:))
403   q2(:,:)=min(max(q2neg(:,:),1.e-10),1.e4)
404
405 
406#ifdef IOPHYS
407if (okiophys) then
408      call iophys_ecrit('km2',klev,'m2 conserv','m/s',km2(:,1:klev))
409      call iophys_ecrit('kn2',klev,'n2 conserv','m/s',kn2(:,1:klev))
410endif
411#endif
412
413! Dissipation of TKE
414   q2old(:,:)=q2(:,:)
415   q2(:,:)=1./(1./sqrt(q2(:,:))+timestep/(2*leff(:,:)*b1))
416   q2(:,:)=q2(:,:)*q2(:,:)
417!  IF (iflag_pbl<=24) THEN
418      DO k=1,klev
419         d_t_diss(:,k)=(masseb(:,k)*(q2neg(:,k)-q2(:,k))+masseb(:,k+1)*(q2neg(:,k+1)-q2(:,k+1)))/(2.*rcpd*masse(:,k))
420      ENDDO
421
422!###################################################################
423!  ELSE IF (iflag_pbl<=27) THEN
424!     DO k=1,klev
425!        d_t_diss(:,k)=(q2neg(:,k)-q2(:,k))/rcpd
426!     ENDDO
427!  ENDIF
428!  print*,'iflag_pbl ',d_t_diss
429!###################################################################
430
431
432! Compuation of stability functions
433!   IF (iflag_pbl/=29) THEN
434      DO k=1,klev
435      DO ig=1,ngrid
436         IF (ABS(km2(ig,k))<=1.e-20) THEN
437            rif(ig,k)=0.
438         ELSE
439            rif(ig,k)=min(kn2(ig,k)/km2(ig,k),rifc)
440         ENDIF
441         IF (rif(ig,k).lt.0.16) THEN
442            alpha(ig,k)=falpha(rif(ig,k))
443            sm(ig,k)=fsm(rif(ig,k))
444         else
445            alpha(ig,k)=1.12
446            sm(ig,k)=0.085
447         endif
448      ENDDO
449      ENDDO
450!    ENDIF
451
452! Computation of turbulent diffusivities
453!  IF (25<=iflag_pbl.and.iflag_pbl<=28) THEN
454!    DO k=2,klev
455!       sqrtq(:,k)=sqrt(0.5*(q2(:,k)+q2(:,k-1)))
456!    ENDDO
457!  ELSE
458   kq(:,:)=0.
459   DO k=1,klev
460      ! Coefficient au milieu des couches pour diffuser la TKE
461      kq(:,k)=0.5*leff(:,k)*sqrt(q2(:,k))*0.2
462   ENDDO
463
464#ifdef IOPHYS
465if (okiophys) then
466call iophys_ecrit('q2b',klev,'KTE inter','m2/s',q2(:,1:klev))
467endif
468#endif
469
470  IF (iflag_tke_diff==1) THEN
471    CALL vdif_q2(timestep, RG, RD, ngrid, plev, pt, kq, q2)
472  ENDIF
473
474   km(:,:)=0.
475   kn(:,:)=0.
476   DO k=1,klev
477      km(:,k)=leff(:,k)*sqrt(q2(:,k))*sm(:,k)
478      kn(:,k)=km(:,k)*alpha(:,k)
479   ENDDO
480
481
482#ifdef IOPHYS
483if (okiophys) then
484call iophys_ecrit('mixingl',klev,'Mixing length','m',leff(:,1:klev))
485call iophys_ecrit('rife',klev,'Flux Richardson','m',rif(:,1:klev))
486call iophys_ecrit('q2f',klev,'KTE finale','m2/s',q2(:,1:klev))
487call iophys_ecrit('q2neg',klev,'KTE non bornee','m2/s',q2neg(:,1:klev))
488call iophys_ecrit('alpha',klev,'alpha','',alpha(:,1:klev))
489call iophys_ecrit('sm',klev,'sm','',sm(:,1:klev))
490call iophys_ecrit('q2f',klev,'KTE finale','m2/s',q2(:,1:klev))
491call iophys_ecrit('kmf',klev,'Kz final','m2/s',km(:,1:klev))
492call iophys_ecrit('knf',klev,'Kz final','m2/s',kn(:,1:klev))
493call iophys_ecrit('kqf',klev,'Kz final','m2/s',kq(:,1:klev))
494endif
495#endif
496
497
498ENDIF
499
500
501!  print*,'OK2'
502      RETURN
503      END
Note: See TracBrowser for help on using the repository browser.