source: trunk/LMDZ.MARS/libf/phymars/surflayer_interpol.F @ 339

Last change on this file since 339 was 339, checked in by acolaitis, 13 years ago

Minor commit: interpolation can be called with or without thermals, with or without convadj.

File size: 11.6 KB
Line 
1      SUBROUTINE surflayer_interpol(ngrid,nlay,pz0,
2     & pg,pz,pu,pv,wmax,pts,ph,z_out,Teta_out,u_out,ustar,tstar,L_mo)
3      IMPLICIT NONE
4!=======================================================================
5!
6!   Subject: interpolation of temperature and velocity norm in the surface layer
7!   by recomputation of surface layer quantities (Richardson, Prandtl, Reynolds, u*, teta*)
8!   ------- 
9!
10!   Author: Arnaud Colaitis 05/08/11
11!   -------
12!
13!   Arguments:
14!   ----------
15!
16!   inputs:
17!   ------
18!     ngrid            size of the horizontal grid
19!     pg               gravity (m s -2)
20!     pz(ngrid,nlay)   height of layers
21!     pu(ngrid,nlay)   u component of the wind
22!     pv(ngrid,nlay)   v component of the wind
23!     pts(ngrid)       surface temperature
24!     ph(ngrid)        potential temperature T*(p/ps)^kappa
25!
26!
27!=======================================================================
28!
29!-----------------------------------------------------------------------
30!   Declarations:
31!   -------------
32
33#include "comcstfi.h"
34#include "callkeys.h"
35
36!   Arguments:
37!   ----------
38
39      INTEGER, INTENT(IN) :: ngrid,nlay
40      REAL, INTENT(IN) :: pz0(ngrid)
41      REAL, INTENT(IN) :: pg,pz(ngrid,nlay)
42      REAL, INTENT(IN) :: pu(ngrid,nlay),pv(ngrid,nlay)
43      REAL, INTENT(IN) :: wmax(ngrid)
44      REAL, INTENT(IN) :: pts(ngrid),ph(ngrid,nlay)
45      REAL, INTENT(IN) :: z_out                  ! output height (in m above surface)
46      REAL, INTENT(OUT) :: Teta_out(ngrid),u_out(ngrid)! interpolated fields at z_out : potential temperature and norm(uv)
47      REAL, INTENT(OUT) :: ustar(ngrid), tstar(ngrid) ! u* and teta*
48      REAL, INTENT(OUT) :: L_mo(ngrid)                ! Monin-Obukhov length
49
50!   Local:
51!   ------
52
53      INTEGER ig
54
55      REAL karman,nu
56      DATA karman,nu/.41,0.001/
57      SAVE karman,nu
58
59!    Local(2):
60!    ---------
61      REAL zout
62
63      REAL rib(ngrid)  ! Bulk Richardson number
64      REAL fm(ngrid) ! stability function for momentum
65      REAL fh(ngrid) ! stability function for heat
66      REAL z1z0,z1z0t ! ratios z1/z0 and z1/z0T
67
68! phim = 1+betam*zeta   or   (1-bm*zeta)**am
69! phih = alphah + betah*zeta    or   alphah(1.-bh*zeta)**ah
70      REAL betam, betah, alphah, bm, bh, lambda
71! ah and am are assumed to be -0.25 and -0.5 respectively
72
73      REAL cdn(ngrid),chn(ngrid)  ! neutral momentum and heat drag coefficient
74      REAL pz0t        ! initial thermal roughness length. (local)
75      REAL ric         ! critical richardson number
76      REAL reynolds(ngrid)    ! reynolds number for UBL
77      REAL prandtl(ngrid)     ! prandtl number for UBL
78      REAL pz0tcomp(ngrid)     ! computed z0t
79      REAL ite
80      REAL residual,zcd0,z1
81      REAL pcdv(ngrid),pcdh(ngrid)
82! For output :
83
84      REAL zu2(ngrid)                  ! Large-scale wind at first layer
85!-----------------------------------------------------------------------
86!   couche de surface:
87!   ------------------
88
89c Init :
90
91      L_mo(:)=0.
92      ustar(:)=0.
93      tstar(:)=0.
94      zout=z_out
95
96      reynolds(:)=0.
97
98! New formulation (AC) :
99
100! phim = 1+betam*zeta   or   (1-bm*zeta)**am
101! phih = alphah + betah*zeta    or   alphah(1.-bh*zeta)**ah
102! am=-0.25, ah=-0.5
103
104      pz0t = 0.     ! for the sake of simplicity
105      pz0tcomp(:) = 0.1*pz0(:)
106      rib(:)=0.
107      pcdv(:)=0.
108      pcdh(:)=0.
109
110! this formulation assumes alphah=1., implying betah=betam
111! We use Dyer et al. parameters, as they cover a broad range of Richardson numbers :
112      bm=16.            !UBL
113      bh=16.            !UBL
114      alphah=1.
115      betam=5.         !SBL
116      betah=5.         !SBL
117      lambda=(sqrt(bh/bm))/alphah
118      ric=betah/(betam**2)
119
120      DO ig=1,ngrid
121
122         ite=0.
123         residual=abs(pz0tcomp(ig)-pz0t)
124
125         do while((residual .gt. 0.01*pz0(ig)) .and.  (ite .lt. 10.))
126
127         pz0t=pz0tcomp(ig)
128
129         if ((pu(ig,1) .ne. 0.) .or. (pv(ig,1) .ne. 0.)) then
130
131! Classical Richardson number formulation
132
133!         rib(ig) = (pg/ph(ig,1))*pz(ig,1)*(ph(ig,1)-pts(ig))
134!     &           /(pu(ig,1)*pu(ig,1) + pv(ig,1)*pv(ig,1))
135
136! Richardson number formulation proposed by D.E. England et al. (1995)
137
138!        IF((pu(ig,1)*pu(ig,1) + pv(ig,1)*pv(ig,1) .lt. 1.)
139!     &            .and. (wmax(ig) .gt. 0.)) THEN
140          zu2(ig)=
141!     &  (MAX(pu(ig,1)*pu(ig,1) + pv(ig,1)*pv(ig,1),wmax(ig)**2))
142     &  ( pu(ig,1)*pu(ig,1) + pv(ig,1)*pv(ig,1))
143!     &  pu(ig,1)*pu(ig,1) + pv(ig,1)*pv(ig,1)
144!        ELSE
145!        zu2(ig)=pu(ig,1)*pu(ig,1) + pv(ig,1)*pv(ig,1)
146!        ENDIF
147
148      if(.not.callrichsl) then
149         rib(ig) = (pg/ph(ig,1))
150     &      *sqrt(pz(ig,1)*pz0(ig))
151     &      *(((log(pz(ig,1)/pz0(ig)))**2)/(log(pz(ig,1)/pz0t)))
152     &      *(ph(ig,1)-pts(ig))/(zu2(ig)+6.)
153      else
154          rib(ig) = (pg/ph(ig,1))
155!     &      *pz(ig,1)*pz0(ig)/sqrt(pz(ig,1)*pz0t)
156     &      *sqrt(pz(ig,1)*pz0(ig))
157     &      *(((log(pz(ig,1)/pz0(ig)))**2)/(log(pz(ig,1)/pz0t)))
158     &      *(ph(ig,1)-pts(ig))/(zu2(ig) + (0.5*wmax(ig))**2)
159
160!     &  /(MAX(pu(ig,1)*pu(ig,1) + pv(ig,1)*pv(ig,1),wmax(ig)**2))
161!     &  /( pu(ig,1)*pu(ig,1) + pv(ig,1)*pv(ig,1) + wmax(ig)**2)
162
163      endif
164
165         else
166         print*,'warning, infinite Richardson at surface'
167         print*,pu(ig,1),pv(ig,1)
168         rib(ig) = ric          ! traiter ce cas !
169         endif
170
171         z1z0=pz(ig,1)/pz0(ig)
172         z1z0t=pz(ig,1)/pz0t
173
174         cdn(ig)=karman/log(z1z0)
175         cdn(ig)=cdn(ig)*cdn(ig)
176         chn(ig)=cdn(ig)*log(z1z0)/log(z1z0t)
177
178! Stable case :
179      if (rib(ig) .gt. 0.) then
180! From D.E. England et al. (95)
181      prandtl(ig)=1.
182         if(rib(ig) .lt. ric) then
183! Assuming alphah=1. and bh=bm for stable conditions :
184            fm(ig)=((ric-rib(ig))/ric)**2
185            fh(ig)=((ric-rib(ig))/ric)**2
186         else
187! For Ri>Ric, we consider Ri->Infinity => no turbulent mixing at surface
188            fm(ig)=0.
189            fh(ig)=0.
190         endif
191! Unstable case :
192      else
193! From D.E. England et al. (95)
194         fm(ig)=sqrt(1.-lambda*bm*rib(ig))
195         fh(ig)=(1./alphah)*((1.-lambda*bh*rib(ig))**0.5)*
196     &                     (1.-lambda*bm*rib(ig))**0.25
197         prandtl(ig)=alphah*((1.-lambda*bm*rib(ig))**0.25)/
198     &             ((1.-lambda*bh*rib(ig))**0.5)
199      endif
200
201       reynolds(ig)=karman*sqrt(fm(ig))
202     &              *sqrt(zu2(ig)+(0.5*wmax(ig))**2)
203!    &               *sqrt(pu(ig,1)**2 + pv(ig,1)**2)
204     &              *pz0(ig)/(log(z1z0)*nu)
205       pz0tcomp(ig)=pz0(ig)*exp(-karman*7.3*
206     &              (reynolds(ig)**0.25)*(prandtl(ig)**0.5))
207
208         
209      residual = abs(pz0t-pz0tcomp(ig))
210      ite = ite+1
211!      if(ite .eq. 10) then
212!        print*, 'iteration max reached'
213!      endif
214!      print*, "iteration nnumber, residual",ite,residual
215
216      enddo  ! of while
217
218          pz0t=0.
219
220! Drag computation :
221
222         pcdv(ig)=cdn(ig)*fm(ig)
223         pcdh(ig)=chn(ig)*fh(ig)
224       
225      ENDDO
226
227!      endif !of if callrichsl
228
229! Large-scale wind at first layer (without gustiness) and
230! u* theta* computation
231      DO ig=1,ngrid
232
233         if (rib(ig) .ge. ric) then
234           ustar(ig)=0.
235           tstar(ig)=0.
236         else
237
238!           ustar(ig)=karman*sqrt(fm(ig)*zu2(ig))/(log(pz(ig,1)/pz0(ig)))
239!           tstar(ig)=karman*fh(ig)*(ph(ig,1)-pts(ig))
240!     &                   /(log(pz(ig,1)/pz0tcomp(ig))*sqrt(fm(ig)))
241
242!simpler definition of u* and teta*, equivalent to the formula above :
243
244            ustar(ig)=sqrt(pcdv(ig))*sqrt(zu2(ig))
245            tstar(ig)=-pcdh(ig)*(pts(ig)-ph(ig,1))
246     &     /sqrt(pcdv(ig))
247
248           if ((tstar(ig) .lt. -50) .and. callrichsl) then
249             print*, fh(ig),rib(ig),(ph(ig,1)-pts(ig))
250     &               ,log(pz(ig,1)/pz0tcomp(ig)),sqrt(fm(ig))
251           endif
252         endif
253      ENDDO
254
255! Monin Obukhov length :
256
257      DO ig=1,ngrid
258         if (rib(ig) .gt. ric) then
259            L_mo(ig)=0.
260         else
261            L_mo(ig)=pts(ig)*(ustar(ig)**2)/(pg*karman*tstar(ig))  !as defined here, L is positive for SBL, negative for UBL
262         endif
263      ENDDO
264
265      DO ig=1,ngrid
266      IF(zout .ge. pz(ig,1)) THEN
267           zout=1.
268           print*, 'Warning, z_out should be less than the first
269     & vertical grid-point'
270           print*, 'z1 =',pz(ig,1)
271           print*, 'z_out=',z_out
272           print*, 'z_out has been changed to 1m
273     & and computation is resumed'
274      ENDIF
275
276      IF(zout .lt. pz0tcomp(ig)) THEN
277           zout=pz0tcomp(ig)
278           print*, 'Warning, z_out should be more than the thermal
279     & roughness length'
280           print*, 'z0 =',pz0tcomp(ig)
281           print*, 'z_out=',z_out
282           print*, 'z_out has been changed to z0t
283     & and computation is resumed'
284      ENDIF
285      ENDDO
286
287      print*, 'interpolation of u and teta at z_out=',zout
288
289      DO ig=1,ngrid
290        IF (L_mo(ig) .gt. 0.) THEN
291           u_out(ig)=(ustar(ig)/karman)*log(zout/pz0(ig)) +
292     &            5.*(ustar(ig)/(karman*L_mo(ig)))*(zout-pz0(ig))
293           Teta_out(ig)=pts(ig)+(tstar(ig)/(prandtl(ig)*karman))
294     &                            *log(zout/pz0tcomp(ig)) +
295     &            5.*(tstar(ig)/(prandtl(ig)*karman*L_mo(ig)))
296     &                            *(zout-pz0tcomp(ig))
297        ELSEIF (L_mo(ig) .lt. 0.) THEN
298
299          IF(L_mo(ig) .gt. -1000.) THEN
300           
301           u_out(ig)=(ustar(ig)/karman)*(
302     &  2.*atan((1.-16.*zout/L_mo(ig))**0.25)
303     & -2.*atan((1.-16.*pz0(ig)/L_mo(ig))**0.25)
304     & -2.*log(1.+(1.-16.*zout/L_mo(ig))**0.25)
305     & +2.*log(1.+(1.-16.*pz0(ig)/L_mo(ig))**0.25)
306     & -   log(1.+sqrt(1.-16.*zout/L_mo(ig)))
307     & +   log(1.+sqrt(1.-16.*pz0(ig)/L_mo(ig)))
308     & +   log(zout/pz0(ig))
309     &                                  )
310
311           Teta_out(ig)=pts(ig)+(tstar(ig)/(prandtl(ig)*karman))*(
312     &  2.*log(1.+sqrt(1.-16.*pz0tcomp(ig)/L_mo(ig)))
313     & -2.*log(1.+sqrt(1.-16.*zout/L_mo(ig)))
314     & +   log(zout/pz0tcomp(ig))
315     &                                                        )
316
317          ELSE
318
319! We have to treat the case where L is very large and negative,
320! corresponding to a very nearly stable atmosphere (but not quite !)
321! i.e. teta* <0 and almost zero. We choose the cutoff
322! corresponding to L_mo < -1000 and use a 3rd order taylor expansion. The difference
323! between the two expression for z/L = -1/1000 is -1.54324*10^-9
324! (we do that to avoid using r*4 precision, otherwise, we get -inf values)         
325
326           u_out(ig)=(ustar(ig)/karman)*(
327     &     (4./L_mo(ig))*(zout-pz0(ig))
328     &   + (20./(L_mo(ig))**2)*(zout**2-pz0(ig)**2)
329     &   + (160./(L_mo(ig))**3)*(zout**3-pz0(ig)**3)
330     &   + log(zout/pz0(ig))
331     &                                   )
332
333           Teta_out(ig)=pts(ig)+(tstar(ig)/(prandtl(ig)*karman))*(
334     &     (8./L_mo(ig))*(zout-pz0tcomp(ig))
335     &   + (48./(L_mo(ig))**2)*(zout**2-pz0tcomp(ig)**2)
336     &   + (1280./(3.*(L_mo(ig))**3))*(zout**3-pz0tcomp(ig)**3)
337     &   + log(zout/pz0tcomp(ig))
338     &                                                           )
339
340          ENDIF
341        ELSE
342           u_out(ig)=0.
343           Teta_out(ig)=pts(ig)
344        ENDIF
345      ENDDO
346
347! when using convective adjustment without thermals, a vertical potential temperature
348! profile is assumed up to the thermal roughness length. Hence, theoretically, theta
349! interpolated at any height in the surface layer is theta at the first level.
350
351      IF ((.not.calltherm).and.(calladj)) THEN
352           Teta_out(:)=ph(:,1)
353      ENDIF
354
355! Usefull diagnostics for the interpolation routine :
356
357!
358!         call WRITEDIAGFI(ngrid,'Ri',
359!     &              'Richardson','m',
360!     &                         2,rib)
361!
362!         call WRITEDIAGFI(ngrid,'z0T',
363!     &              'thermal roughness length','m',
364!     &                         2,pz0tcomp)
365!         call WRITEDIAGFI(ngrid,'z0',
366!     &              'roughness length','m',
367!     &                         2,pz0)
368
369
370      RETURN
371      END
Note: See TracBrowser for help on using the repository browser.