source: dynamico_lmdz/simple_physics/phyparam/physics/vdif_mod.F90 @ 4198

Last change on this file since 4198 was 4194, checked in by dubos, 6 years ago

simple_physics : created plugin for logging

File size: 13.3 KB
Line 
1MODULE vdif_mod
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          !           IF(ig.EQ.ngrid/2+1) PRINT*,il,lmix,pkv(ig,il),
140          !    s      zdu,zdv,zdz,zdvodz2,ph(ig,il)+ph(ig,il-1),
141          !    s      lmix*lmix*zdvodz2*(1-zri/.4),emin_turb,zri,ph(ig,il)-ph(ig,il-1),
142          !    s      ph(ig,il),ph(ig,il-1)
143       ENDDO
144    ENDDO
145   
146  END SUBROUTINE vdif_k
147
148 
149  SUBROUTINE multipl(n,x1,x2,y)
150!=======================================================================
151!   multiplication de deux vecteurs
152!=======================================================================
153    INTEGER n,i
154    REAL x1(n),x2(n),y(n)
155
156    DO i=1,n
157       y(i)=x1(i)*x2(i)
158    END DO
159  END SUBROUTINE multipl
160
161  SUBROUTINE vdif(ngrid,nlay,ptime, &
162       ptimestep,pcapcal,pz0, &
163       pplay,pplev,pzlay,pzlev, &
164       pu,pv,ph,ptsrf,pemis, &
165       pdufi,pdvfi,pdhfi,pfluxsrf, &
166       pdudif,pdvdif,pdhdif,pdtsrf,pq2,pq2l, &
167       lwrite)
168    USE phys_const
169   
170!=======================================================================
171!
172!   Diffusion verticale
173!   Shema implicite
174!   On commence par rajouter au variables x la tendance physique
175!   et on resoult en fait:
176!      x(t+1) =  x(t) + dt * (dx/dt)phys(t)  +  dt * (dx/dt)difv(t+1)
177!
178!   arguments:
179!   ----------
180!
181!   entree:
182!   -------
183!
184!
185!=======================================================================
186
187!
188!   arguments:
189!   ----------
190
191    INTEGER ngrid,nlay
192    REAL ptime,ptimestep
193    REAL pplay(ngrid,nlay),pplev(ngrid,nlay+1)
194    REAL pzlay(ngrid,nlay),pzlev(ngrid,nlay+1)
195    REAL pu(ngrid,nlay),pv(ngrid,nlay),ph(ngrid,nlay)
196    REAL ptsrf(ngrid),pemis(ngrid)
197    REAL pdufi(ngrid,nlay),pdvfi(ngrid,nlay),pdhfi(ngrid,nlay)
198    REAL pfluxsrf(ngrid)
199    REAL pdudif(ngrid,nlay),pdvdif(ngrid,nlay),pdhdif(ngrid,nlay)
200    REAL pdtsrf(ngrid),pcapcal(ngrid),pz0(ngrid)
201    REAL pq2(ngrid,nlay+1),pq2l(ngrid,nlay+1)
202    LOGICAL lwrite
203    !
204    !   local:
205    !   ------
206   
207    INTEGER ilev,ig,ilay,nlev
208    INTEGER unit,ierr,it1,it2
209    INTEGER cluvdb,putdat,putvdim,setname,setvdim
210    REAL z4st,zdplanck(ngrid),zu2
211    REAL zkv(ngrid,nlay+1),zkh(ngrid,nlay+1)
212    REAL zcdv(ngrid),zcdh(ngrid)
213    REAL zu(ngrid,nlay),zv(ngrid,nlay)
214    REAL zh(ngrid,nlay)
215    REAL ztsrf2(ngrid)
216    REAL z1(ngrid),z2(ngrid)
217    REAL za(ngrid,nlay),zb(ngrid,nlay)
218    REAL zb0(ngrid,nlay)
219    REAL zc(ngrid,nlay),zd(ngrid,nlay)
220    REAL zcst1
221   
222    !
223    !-----------------------------------------------------------------------
224    !   initialisations:
225    !   ----------------
226   
227    nlev=nlay+1
228   
229    !   computation of rho*dz and dt*rho/dz=dt*rho**2 g/dp:
230    !   with rho=p/RT=p/ (R Theta) (p/ps)**kappa
231    !   ---------------------------------
232   
233    DO ilay=1,nlay
234       DO ig=1,ngrid
235          za(ig,ilay) = (pplev(ig,ilay)-pplev(ig,ilay+1))/g
236       ENDDO
237    ENDDO
238   
239    zcst1=4.*g*ptimestep/(r*r)
240    DO ilev=2,nlev-1
241       DO ig=1,ngrid
242          zb0(ig,ilev)=pplev(ig,ilev) &
243               *(pplev(ig,1)/pplev(ig,ilev))**rcp &
244               /(ph(ig,ilev-1)+ph(ig,ilev))
245          zb0(ig,ilev)=zcst1*zb0(ig,ilev)*zb0(ig,ilev) &
246               / (pplay(ig,ilev-1)-pplay(ig,ilev))
247       ENDDO
248    ENDDO
249    DO ig=1,ngrid
250       zb0(ig,1)=ptimestep*pplev(ig,1)/(r*ptsrf(ig))
251    ENDDO
252    IF(lwrite) THEN
253       ig=ngrid/2+1
254       WRITELOG(*,*) 'Pression (mbar) ,altitude (km),u,v,theta, rho dz'
255       DO ilay=1,nlay
256          WRITELOG(*,*) .01*pplay(ig,ilay),.001*pzlay(ig,ilay), &
257               pu(ig,ilay),pv(ig,ilay),ph(ig,ilay),za(ig,ilay)
258       ENDDO
259       WRITELOG(*,*) 'Pression (mbar) ,altitude (km),zb'
260       DO ilev=1,nlay
261          WRITELOG(*,*) .01*pplev(ig,ilev),.001*pzlev(ig,ilev), &
262               zb0(ig,ilev)
263       ENDDO
264       CALL flush_log
265    ENDIF
266   
267    !-----------------------------------------------------------------------
268    !   2. ajout des tendances physiques:
269    !   ------------------------------
270   
271    DO ilev=1,nlay
272       DO ig=1,ngrid
273          zu(ig,ilev)=pu(ig,ilev)+pdufi(ig,ilev)*ptimestep
274          zv(ig,ilev)=pv(ig,ilev)+pdvfi(ig,ilev)*ptimestep
275          zh(ig,ilev)=ph(ig,ilev)+pdhfi(ig,ilev)*ptimestep
276       ENDDO
277    ENDDO
278   
279    !-----------------------------------------------------------------------
280    !   3. calcul de  cd :
281    !   ----------------
282    !
283    CALL vdif_cd( ngrid,pz0,g,pzlay,pu,pv,ptsrf,ph,zcdv,zcdh)
284    CALL vdif_k(ngrid,nlay,ptimestep,g,pzlev,pzlay,pz0,pu,pv,ph,zkv,zkh)
285   
286    DO ig=1,ngrid
287       zu2=pu(ig,1)*pu(ig,1)+pv(ig,1)*pv(ig,1)
288       zcdv(ig)=zcdv(ig)*sqrt(zu2)
289       zcdh(ig)=zcdh(ig)*sqrt(zu2)
290    ENDDO
291   
292    IF(lwrite) THEN
293       
294       WRITELOG(*,*) 'Diagnostique diffusion verticale'
295       WRITELOG(*,*) 'LMIXMIN',lmixmin
296       PRINT*,'coefficients Cd pour v et h'
297       PRINT*,zcdv(ngrid/2+1),zcdh(ngrid/2+1)
298       PRINT*,'coefficients K pour v et h'
299       DO ilev=1,nlay
300          PRINT*,zkv(ngrid/2+1,ilev),zkh(ngrid/2+1,ilev)
301       ENDDO
302       CALL flush_log
303    ENDIF
304   
305    !-----------------------------------------------------------------------
306    !   integration verticale pour u:
307    !   -----------------------------
308   
309    CALL multipl((nlay-1)*ngrid,zkv(1,2),zb0(1,2),zb(1,2))
310    CALL multipl(ngrid,zcdv,zb0,zb)
311    DO ig=1,ngrid
312       z1(ig)=1./(za(ig,nlay)+zb(ig,nlay))
313       zc(ig,nlay)=za(ig,nlay)*zu(ig,nlay)*z1(ig)
314       zd(ig,nlay)=zb(ig,nlay)*z1(ig)
315    ENDDO
316   
317    DO ilay=nlay-1,1,-1
318       DO ig=1,ngrid
319          z1(ig) = 1./(za(ig,ilay)+zb(ig,ilay) &
320               + zb(ig,ilay+1)*(1.-zd(ig,ilay+1)))
321          zc(ig,ilay) = (za(ig,ilay)*zu(ig,ilay) &
322               + zb(ig,ilay+1)*zc(ig,ilay+1))*z1(ig)
323          zd(ig,ilay) = zb(ig,ilay)*z1(ig)
324       ENDDO
325    ENDDO
326   
327    DO ig=1,ngrid
328       zu(ig,1)=zc(ig,1)
329    ENDDO
330    DO ilay=2,nlay
331       DO ig=1,ngrid
332          zu(ig,ilay)=zc(ig,ilay)+zd(ig,ilay)*zu(ig,ilay-1)
333       ENDDO
334    ENDDO
335   
336    !-----------------------------------------------------------------------
337    !   integration verticale pour v:
338    !   -----------------------------
339    !
340    DO ig=1,ngrid
341       z1(ig)=1./(za(ig,nlay)+zb(ig,nlay))
342       zc(ig,nlay)=za(ig,nlay)*zv(ig,nlay)*z1(ig)
343       zd(ig,nlay)=zb(ig,nlay)*z1(ig)
344    ENDDO
345   
346    DO ilay=nlay-1,1,-1
347       DO ig=1,ngrid
348          z1(ig)=1./(za(ig,ilay)+zb(ig,ilay) &
349               + zb(ig,ilay+1)*(1.-zd(ig,ilay+1)))
350          zc(ig,ilay)=(za(ig,ilay)*zv(ig,ilay) &
351               + zb(ig,ilay+1)*zc(ig,ilay+1))*z1(ig)
352          zd(ig,ilay)=zb(ig,ilay)*z1(ig)
353       ENDDO
354    ENDDO
355   
356    DO ig=1,ngrid
357       zv(ig,1)=zc(ig,1)
358    ENDDO
359    DO ilay=2,nlay
360       DO ig=1,ngrid
361          zv(ig,ilay)=zc(ig,ilay)+zd(ig,ilay)*zv(ig,ilay-1)
362       ENDDO
363    ENDDO
364   
365    !-----------------------------------------------------------------------
366    !   integration verticale pour h:
367    !   -----------------------------
368    !
369    CALL multipl((nlay-1)*ngrid,zkh(1,2),zb0(1,2),zb(1,2))
370    CALL multipl(ngrid,zcdh,zb0,zb)
371    DO ig=1,ngrid
372       z1(ig)=1./(za(ig,nlay)+zb(ig,nlay))
373       zc(ig,nlay)=za(ig,nlay)*zh(ig,nlay)*z1(ig)
374       zd(ig,nlay)=zb(ig,nlay)*z1(ig)
375    ENDDO
376   
377    DO ilay=nlay-1,1,-1
378       DO ig=1,ngrid
379          z1(ig)=1./(za(ig,ilay)+zb(ig,ilay) &
380               + zb(ig,ilay+1)*(1.-zd(ig,ilay+1)))
381          zc(ig,ilay)=(za(ig,ilay)*zh(ig,ilay) &
382               + zb(ig,ilay+1)*zc(ig,ilay+1))*z1(ig)
383          zd(ig,ilay)=zb(ig,ilay)*z1(ig)
384       ENDDO
385    ENDDO
386   
387    !-----------------------------------------------------------------------
388    !   rajout eventuel de planck dans le shema implicite:
389    !   --------------------------------------------------
390   
391    z4st=4.*5.67e-8*ptimestep
392    DO ig=1,ngrid
393       zdplanck(ig)=z4st*pemis(ig)*ptsrf(ig)*ptsrf(ig)*ptsrf(ig)
394    ENDDO
395   
396    !-----------------------------------------------------------------------
397    !   calcul le l'evolution de la temperature du sol:
398    !   -----------------------------------------------
399   
400    DO ig=1,ngrid
401       z1(ig) = pcapcal(ig)*ptsrf(ig)+cpp*zb(ig,1)*zc(ig,1) &
402            + zdplanck(ig)*ptsrf(ig)+ pfluxsrf(ig)*ptimestep
403       z2(ig) = pcapcal(ig)+cpp*zb(ig,1)*(1.-zd(ig,1))+zdplanck(ig)
404       ztsrf2(ig) = z1(ig)/z2(ig)
405       zh(ig,1) = zc(ig,1)+zd(ig,1)*ztsrf2(ig)
406       pdtsrf(ig) = (ztsrf2(ig)-ptsrf(ig))/ptimestep
407    ENDDO
408   
409    !-----------------------------------------------------------------------
410    !   integration verticale finale:
411    !   -----------------------------
412   
413    DO ilay=2,nlay
414       DO ig=1,ngrid
415          zh(ig,ilay)=zc(ig,ilay)+zd(ig,ilay)*zh(ig,ilay-1)
416       ENDDO
417    ENDDO
418   
419    !-----------------------------------------------------------------------
420    !   calcul final des tendances de la diffusion verticale:
421    !   -----------------------------------------------------
422   
423    DO ilev = 1, nlay
424       DO ig=1,ngrid
425          pdudif(ig,ilev) = ( zu(ig,ilev) &
426               - (pu(ig,ilev)+pdufi(ig,ilev)*ptimestep) )/ptimestep
427          pdvdif(ig,ilev) = ( zv(ig,ilev) &
428               - (pv(ig,ilev)+pdvfi(ig,ilev)*ptimestep) )/ptimestep
429          pdhdif(ig,ilev) = ( zh(ig,ilev) &
430               - (ph(ig,ilev)+pdhfi(ig,ilev)*ptimestep) )/ptimestep
431       ENDDO
432    ENDDO
433   
434    IF(lwrite) THEN
435       PRINT*
436       PRINT*,'Diagnostique de la diffusion verticale'
437       PRINT*,'h avant et apres diffusion verticale'
438       PRINT*,ptsrf(ngrid/2+1),ztsrf2(ngrid/2+1)
439       DO  ilev=1,nlay
440          PRINT*,ph(ngrid/2+1,ilev),zh(ngrid/2+1,ilev)
441       ENDDO
442    END IF
443
444  END SUBROUTINE vdif
445 
446END MODULE vdif_mod
Note: See TracBrowser for help on using the repository browser.