source: dynamico_lmdz/simple_physics/phyparam/physics/turbulence.F90 @ 4221

Last change on this file since 4221 was 4210, checked in by dubos, 5 years ago

simple_physics : cleanup PRINTs

File size: 13.2 KB
Line 
1MODULE turbulence
2 
3#include "use_logging.h"
4
5  IMPLICIT NONE
6  SAVE
7  PRIVATE
8
9  REAL, PARAMETER :: karman=0.4
10  REAL :: lmixmin=100., emin_turb=1e-8 
11
12  PUBLIC :: vdif, lmixmin, emin_turb
13 
14CONTAINS
15 
16  PURE SUBROUTINE vdif_cd( ngrid,pz0,pg,pz,pu,pv,pts,ph,pcdv,pcdh)
17    !=======================================================================
18    !
19    !   Subject: computation of the surface drag coefficient using the
20    !   -------  approch developed by Loui for ECMWF.
21    !
22    !   Author: Frederic Hourdin  15 /10 /93
23    !   -------
24    !
25    !   Arguments:
26    !   ----------
27    !
28    !   inputs:
29    !   ------
30    !     ngrid            size of the horizontal grid
31    !     pz0(ngrid)       roughness length ?
32    !     pg               gravity (m s -2)
33    !     pz(ngrid)        height of the first atmospheric layer
34    !     pu(ngrid)        u component of the wind in that layer
35    !     pv(ngrid)        v component of the wind in that layer
36    !     pts(ngrid)       surfacte temperature
37    !     ph(ngrid)        potential temperature T*(p/ps)^kappa
38    !
39    !   outputs:
40    !   --------
41    !     pcdv(ngrid)      Cd for the wind
42    !     pcdh(ngrid)      Cd for potential temperature
43    !
44    !=======================================================================
45    !
46    !-----------------------------------------------------------------------
47    !   Declarations:
48    !   -------------
49   
50    !   Arguments:
51    !   ----------
52   
53    INTEGER, INTENT(IN) ::  ngrid
54    REAL, INTENT(IN)  ::  pg, pz0(ngrid), pz(ngrid), &
55         pu(ngrid),pv(ngrid), pts(ngrid),ph(ngrid)
56    REAL, INTENT(OUT) :: pcdv(ngrid),pcdh(ngrid)
57   
58    !   Local:
59    !   ------
60   
61    REAL, PARAMETER :: b=5., c=5., d=5., umin2=1e-12, &
62         c2b=2.*b, c3bc=3.*b*c, c3b=3.*b
63    INTEGER ig
64    REAL zu2,z1,zri,zcd0,zz   
65   
66    !-----------------------------------------------------------------------
67    !   couche de surface:
68    !   ------------------
69   
70    !     DO ig=1,ngrid
71    !        zu2=pu(ig)*pu(ig)+pv(ig)*pv(ig)+umin2
72    !        pcdv(ig)=pz0(ig)*(1.+sqrt(zu2))
73    !        pcdh(ig)=pcdv(ig)
74    !     ENDDO
75    !     RETURN
76   
77   
78!!!! WARNING, verifier la formule originale de Louis!
79    DO ig=1,ngrid
80       zu2=pu(ig)*pu(ig)+pv(ig)*pv(ig)+umin2
81       zri=pg*pz(ig)*(ph(ig)-pts(ig))/(ph(ig)*zu2)
82       z1=1.+pz(ig)/pz0(ig)
83       zcd0=karman/log(z1)
84       zcd0=zcd0*zcd0*sqrt(zu2)
85       IF(zri.LT.0.) THEN
86          z1=b*zri/(1.+c3bc*zcd0*sqrt(-z1*zri))
87          pcdv(ig)=zcd0*(1.-2.*z1)
88          pcdh(ig)=zcd0*(1.-3.*z1)
89       ELSE
90          zz=sqrt(1.+d*zri)
91          pcdv(ig)=zcd0/(1.+c2b*zri/zz)
92          pcdh(ig)=zcd0/(1.+c3b*zri*zz)
93       ENDIF
94    ENDDO
95   
96    !-----------------------------------------------------------------------
97   
98  END SUBROUTINE vdif_cd
99 
100  PURE SUBROUTINE vdif_k(ngrid,nlay,   &
101       ptimestep,pg,pzlev,pzlay,pz0,pu,pv,ph,pkv,pkh)
102    ! FIXME : pkh := pkv
103    USE planet
104    INTEGER, INTENT(IN) :: ngrid,nlay
105    REAL, INTENT(IN) ::  ptimestep, pg, &
106         pzlay(ngrid,nlay),pzlev(ngrid,nlay+1), pz0(ngrid), &
107         pu(ngrid,nlay),pv(ngrid,nlay),ph(ngrid,nlay)
108    REAL, INTENT(OUT) :: pkv(ngrid,nlay+1),pkh(ngrid,nlay+1)
109   
110    INTEGER ig,il
111    REAL zdu,zdv,zri,zdvodz2,zdz,z1,lmix
112   
113    DO ig=1,ngrid
114       pkv(ig,1)=0.
115       pkh(ig,1)=0.
116       pkv(ig,nlay+1)=0.
117       pkh(ig,nlay+1)=0.
118    ENDDO
119   
120    DO il=2,nlay
121       DO ig=1,ngrid
122          z1=pzlev(ig,il)+pz0(ig)
123          lmix=karman*z1/(1.+karman*z1/lmixmin)
124          !           lmix=lmixmin
125          ! WARNING test lmix=lmixmin
126          zdu=pu(ig,il)-pu(ig,il-1)
127          zdv=pv(ig,il)-pv(ig,il-1)
128          zdz=pzlay(ig,il)-pzlay(ig,il-1)
129          zdvodz2=(zdu*zdu+zdv*zdv)/(zdz*zdz)
130          IF(zdvodz2.LT.1.e-5) THEN
131             pkv(ig,il)=lmix*sqrt(emin_turb)
132          ELSE
133             zri=2.*pg*(ph(ig,il)-ph(ig,il-1)) &
134                  / (zdz* (ph(ig,il)+ph(ig,il-1)) *zdvodz2  )
135             pkv(ig,il)= &
136                  lmix*sqrt(MAX(lmix*lmix*zdvodz2*(1-zri/.4),emin_turb))
137          ENDIF
138          pkh(ig,il)=pkv(ig,il)
139       ENDDO
140    ENDDO
141   
142  END SUBROUTINE vdif_k
143
144 
145  SUBROUTINE multipl(n,x1,x2,y)
146!=======================================================================
147!   multiplication de deux vecteurs
148!=======================================================================
149    INTEGER n,i
150    REAL x1(n),x2(n),y(n)
151
152    DO i=1,n
153       y(i)=x1(i)*x2(i)
154    END DO
155  END SUBROUTINE multipl
156
157  SUBROUTINE vdif(ngrid,nlay,ptime, &
158       ptimestep,pcapcal,pz0, &
159       pplay,pplev,pzlay,pzlev, &
160       pu,pv,ph,ptsrf,pemis, &
161       pdufi,pdvfi,pdhfi,pfluxsrf, &
162       pdudif,pdvdif,pdhdif,pdtsrf,pq2,pq2l, &
163       lwrite)
164    USE phys_const
165   
166!=======================================================================
167!
168!   Diffusion verticale
169!   Shema implicite
170!   On commence par rajouter au variables x la tendance physique
171!   et on resoult en fait:
172!      x(t+1) =  x(t) + dt * (dx/dt)phys(t)  +  dt * (dx/dt)difv(t+1)
173!
174!   arguments:
175!   ----------
176!
177!   entree:
178!   -------
179!
180!
181!=======================================================================
182
183!
184!   arguments:
185!   ----------
186
187    INTEGER ngrid,nlay
188    REAL ptime,ptimestep
189    REAL pplay(ngrid,nlay),pplev(ngrid,nlay+1)
190    REAL pzlay(ngrid,nlay),pzlev(ngrid,nlay+1)
191    REAL pu(ngrid,nlay),pv(ngrid,nlay),ph(ngrid,nlay)
192    REAL ptsrf(ngrid),pemis(ngrid)
193    REAL pdufi(ngrid,nlay),pdvfi(ngrid,nlay),pdhfi(ngrid,nlay)
194    REAL pfluxsrf(ngrid)
195    REAL pdudif(ngrid,nlay),pdvdif(ngrid,nlay),pdhdif(ngrid,nlay)
196    REAL pdtsrf(ngrid),pcapcal(ngrid),pz0(ngrid)
197    REAL pq2(ngrid,nlay+1),pq2l(ngrid,nlay+1)
198    LOGICAL lwrite
199    !
200    !   local:
201    !   ------
202   
203    INTEGER ilev,ig,ilay,nlev
204    INTEGER unit,ierr,it1,it2
205    INTEGER cluvdb,putdat,putvdim,setname,setvdim
206    REAL z4st,zdplanck(ngrid),zu2
207    REAL zkv(ngrid,nlay+1),zkh(ngrid,nlay+1)
208    REAL zcdv(ngrid),zcdh(ngrid)
209    REAL zu(ngrid,nlay),zv(ngrid,nlay)
210    REAL zh(ngrid,nlay)
211    REAL ztsrf2(ngrid)
212    REAL z1(ngrid),z2(ngrid)
213    REAL za(ngrid,nlay),zb(ngrid,nlay)
214    REAL zb0(ngrid,nlay)
215    REAL zc(ngrid,nlay),zd(ngrid,nlay)
216    REAL zcst1
217   
218    !
219    !-----------------------------------------------------------------------
220    !   initialisations:
221    !   ----------------
222   
223    nlev=nlay+1
224   
225    !   computation of rho*dz and dt*rho/dz=dt*rho**2 g/dp:
226    !   with rho=p/RT=p/ (R Theta) (p/ps)**kappa
227    !   ---------------------------------
228   
229    DO ilay=1,nlay
230       DO ig=1,ngrid
231          za(ig,ilay) = (pplev(ig,ilay)-pplev(ig,ilay+1))/g
232       ENDDO
233    ENDDO
234   
235    zcst1=4.*g*ptimestep/(r*r)
236    DO ilev=2,nlev-1
237       DO ig=1,ngrid
238          zb0(ig,ilev)=pplev(ig,ilev) &
239               *(pplev(ig,1)/pplev(ig,ilev))**rcp &
240               /(ph(ig,ilev-1)+ph(ig,ilev))
241          zb0(ig,ilev)=zcst1*zb0(ig,ilev)*zb0(ig,ilev) &
242               / (pplay(ig,ilev-1)-pplay(ig,ilev))
243       ENDDO
244    ENDDO
245    DO ig=1,ngrid
246       zb0(ig,1)=ptimestep*pplev(ig,1)/(r*ptsrf(ig))
247    ENDDO
248    IF(lwrite) THEN
249       ig=ngrid/2+1
250       WRITELOG(*,*) 'Pression (mbar) ,altitude (km),u,v,theta, rho dz'
251       DO ilay=1,nlay
252          WRITELOG(*,*) .01*pplay(ig,ilay),.001*pzlay(ig,ilay), &
253               pu(ig,ilay),pv(ig,ilay),ph(ig,ilay),za(ig,ilay)
254       ENDDO
255       WRITELOG(*,*) 'Pression (mbar) ,altitude (km),zb'
256       DO ilev=1,nlay
257          WRITELOG(*,*) .01*pplev(ig,ilev),.001*pzlev(ig,ilev), &
258               zb0(ig,ilev)
259       ENDDO
260       LOG_DBG('vdif')
261    ENDIF
262   
263    !-----------------------------------------------------------------------
264    !   2. ajout des tendances physiques:
265    !   ------------------------------
266   
267    DO ilev=1,nlay
268       DO ig=1,ngrid
269          zu(ig,ilev)=pu(ig,ilev)+pdufi(ig,ilev)*ptimestep
270          zv(ig,ilev)=pv(ig,ilev)+pdvfi(ig,ilev)*ptimestep
271          zh(ig,ilev)=ph(ig,ilev)+pdhfi(ig,ilev)*ptimestep
272       ENDDO
273    ENDDO
274   
275    !-----------------------------------------------------------------------
276    !   3. calcul de  cd :
277    !   ----------------
278    !
279    CALL vdif_cd( ngrid,pz0,g,pzlay,pu,pv,ptsrf,ph,zcdv,zcdh)
280    CALL vdif_k(ngrid,nlay,ptimestep,g,pzlev,pzlay,pz0,pu,pv,ph,zkv,zkh)
281   
282    DO ig=1,ngrid
283       zu2=pu(ig,1)*pu(ig,1)+pv(ig,1)*pv(ig,1)
284       zcdv(ig)=zcdv(ig)*sqrt(zu2)
285       zcdh(ig)=zcdh(ig)*sqrt(zu2)
286    ENDDO
287   
288    IF(lwrite) THEN       
289       WRITELOG(*,*) 'Diagnostique diffusion verticale'
290       WRITELOG(*,*) 'LMIXMIN',lmixmin
291       WRITELOG(*,*) 'coefficients Cd pour v et h'
292       WRITELOG(*,*) zcdv(ngrid/2+1),zcdh(ngrid/2+1)
293       WRITELOG(*,*) ,'coefficients K pour v et h'
294       DO ilev=1,nlay
295          WRITELOG(*,*) zkv(ngrid/2+1,ilev),zkh(ngrid/2+1,ilev)
296       ENDDO
297       LOG_DBG('vdif')
298    ENDIF
299   
300    !-----------------------------------------------------------------------
301    !   integration verticale pour u:
302    !   -----------------------------
303   
304    CALL multipl((nlay-1)*ngrid,zkv(1,2),zb0(1,2),zb(1,2))
305    CALL multipl(ngrid,zcdv,zb0,zb)
306    DO ig=1,ngrid
307       z1(ig)=1./(za(ig,nlay)+zb(ig,nlay))
308       zc(ig,nlay)=za(ig,nlay)*zu(ig,nlay)*z1(ig)
309       zd(ig,nlay)=zb(ig,nlay)*z1(ig)
310    ENDDO
311   
312    DO ilay=nlay-1,1,-1
313       DO ig=1,ngrid
314          z1(ig) = 1./(za(ig,ilay)+zb(ig,ilay) &
315               + zb(ig,ilay+1)*(1.-zd(ig,ilay+1)))
316          zc(ig,ilay) = (za(ig,ilay)*zu(ig,ilay) &
317               + zb(ig,ilay+1)*zc(ig,ilay+1))*z1(ig)
318          zd(ig,ilay) = zb(ig,ilay)*z1(ig)
319       ENDDO
320    ENDDO
321   
322    DO ig=1,ngrid
323       zu(ig,1)=zc(ig,1)
324    ENDDO
325    DO ilay=2,nlay
326       DO ig=1,ngrid
327          zu(ig,ilay)=zc(ig,ilay)+zd(ig,ilay)*zu(ig,ilay-1)
328       ENDDO
329    ENDDO
330   
331    !-----------------------------------------------------------------------
332    !   integration verticale pour v:
333    !   -----------------------------
334    !
335    DO ig=1,ngrid
336       z1(ig)=1./(za(ig,nlay)+zb(ig,nlay))
337       zc(ig,nlay)=za(ig,nlay)*zv(ig,nlay)*z1(ig)
338       zd(ig,nlay)=zb(ig,nlay)*z1(ig)
339    ENDDO
340   
341    DO ilay=nlay-1,1,-1
342       DO ig=1,ngrid
343          z1(ig)=1./(za(ig,ilay)+zb(ig,ilay) &
344               + zb(ig,ilay+1)*(1.-zd(ig,ilay+1)))
345          zc(ig,ilay)=(za(ig,ilay)*zv(ig,ilay) &
346               + zb(ig,ilay+1)*zc(ig,ilay+1))*z1(ig)
347          zd(ig,ilay)=zb(ig,ilay)*z1(ig)
348       ENDDO
349    ENDDO
350   
351    DO ig=1,ngrid
352       zv(ig,1)=zc(ig,1)
353    ENDDO
354    DO ilay=2,nlay
355       DO ig=1,ngrid
356          zv(ig,ilay)=zc(ig,ilay)+zd(ig,ilay)*zv(ig,ilay-1)
357       ENDDO
358    ENDDO
359   
360    !-----------------------------------------------------------------------
361    !   integration verticale pour h:
362    !   -----------------------------
363    !
364    CALL multipl((nlay-1)*ngrid,zkh(1,2),zb0(1,2),zb(1,2))
365    CALL multipl(ngrid,zcdh,zb0,zb)
366    DO ig=1,ngrid
367       z1(ig)=1./(za(ig,nlay)+zb(ig,nlay))
368       zc(ig,nlay)=za(ig,nlay)*zh(ig,nlay)*z1(ig)
369       zd(ig,nlay)=zb(ig,nlay)*z1(ig)
370    ENDDO
371   
372    DO ilay=nlay-1,1,-1
373       DO ig=1,ngrid
374          z1(ig)=1./(za(ig,ilay)+zb(ig,ilay) &
375               + zb(ig,ilay+1)*(1.-zd(ig,ilay+1)))
376          zc(ig,ilay)=(za(ig,ilay)*zh(ig,ilay) &
377               + zb(ig,ilay+1)*zc(ig,ilay+1))*z1(ig)
378          zd(ig,ilay)=zb(ig,ilay)*z1(ig)
379       ENDDO
380    ENDDO
381   
382    !-----------------------------------------------------------------------
383    !   rajout eventuel de planck dans le shema implicite:
384    !   --------------------------------------------------
385   
386    z4st=4.*5.67e-8*ptimestep
387    DO ig=1,ngrid
388       zdplanck(ig)=z4st*pemis(ig)*ptsrf(ig)*ptsrf(ig)*ptsrf(ig)
389    ENDDO
390   
391    !-----------------------------------------------------------------------
392    !   calcul le l'evolution de la temperature du sol:
393    !   -----------------------------------------------
394   
395    DO ig=1,ngrid
396       z1(ig) = pcapcal(ig)*ptsrf(ig)+cpp*zb(ig,1)*zc(ig,1) &
397            + zdplanck(ig)*ptsrf(ig)+ pfluxsrf(ig)*ptimestep
398       z2(ig) = pcapcal(ig)+cpp*zb(ig,1)*(1.-zd(ig,1))+zdplanck(ig)
399       ztsrf2(ig) = z1(ig)/z2(ig)
400       zh(ig,1) = zc(ig,1)+zd(ig,1)*ztsrf2(ig)
401       pdtsrf(ig) = (ztsrf2(ig)-ptsrf(ig))/ptimestep
402    ENDDO
403   
404    !-----------------------------------------------------------------------
405    !   integration verticale finale:
406    !   -----------------------------
407   
408    DO ilay=2,nlay
409       DO ig=1,ngrid
410          zh(ig,ilay)=zc(ig,ilay)+zd(ig,ilay)*zh(ig,ilay-1)
411       ENDDO
412    ENDDO
413   
414    !-----------------------------------------------------------------------
415    !   calcul final des tendances de la diffusion verticale:
416    !   -----------------------------------------------------
417   
418    DO ilev = 1, nlay
419       DO ig=1,ngrid
420          pdudif(ig,ilev) = ( zu(ig,ilev) &
421               - (pu(ig,ilev)+pdufi(ig,ilev)*ptimestep) )/ptimestep
422          pdvdif(ig,ilev) = ( zv(ig,ilev) &
423               - (pv(ig,ilev)+pdvfi(ig,ilev)*ptimestep) )/ptimestep
424          pdhdif(ig,ilev) = ( zh(ig,ilev) &
425               - (ph(ig,ilev)+pdhfi(ig,ilev)*ptimestep) )/ptimestep
426       ENDDO
427    ENDDO
428   
429    IF(lwrite) THEN
430       WRITELOG(*,*)
431       WRITELOG(*,*) ,'Diagnostique de la diffusion verticale'
432       WRITELOG(*,*) ,'h avant et apres diffusion verticale'
433       WRITELOG(*,*) ,ptsrf(ngrid/2+1),ztsrf2(ngrid/2+1)
434       DO  ilev=1,nlay
435          WRITELOG(*,*) ph(ngrid/2+1,ilev),zh(ngrid/2+1,ilev)
436       ENDDO
437       LOG_DBG('vdif')
438    END IF
439
440  END SUBROUTINE vdif
441 
442END MODULE turbulence
Note: See TracBrowser for help on using the repository browser.