source: LMDZ6/branches/PBLSURF_GPUPORT/libf/phylmd/yamada_c.F90 @ 5914

Last change on this file since 5914 was 5886, checked in by yann meurdesoif, 6 weeks ago

yamada_c : some cleaning

YM

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