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

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

--- AC 03/08/2011 ---
M 267 libf/phymars/physiq.F
<> Minor modification to pass Ch from vdifc to meso_inc_les

M 267 libf/phymars/surflayer_interpol.F
<> Major modification to the formulation of integrals

Now stable for most cases. Some cases with highly negative Monin Obukhov length
remain to be explored.

M 267 libf/phymars/vdif_cd.F
<> Added gustiness to the Richardson computation. Gustiness factor is for now of beta=1., after

several comparisons with LES aerodynamic conductances. May be subject to a minor change (+/- 0.1)
in the near future. (almost transparent for the user)

M 267 libf/phymars/vdifc.F
<> Minor modifications relative to variables.

M 267 libf/phymars/calltherm_mars.F90
<> Added a comment on a "sensitive" parameter that should not be changed without knowing the consequence !

M 267 libf/phymars/meso_inc/meso_inc_les.F
<> Changed the definition for HFX computation in the LES (to be discussed with Aymeric). New definition yields

very similar results to old one and follows a strict definition of what HFX should be.


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