source: trunk/LMDZ.MARS/libf/phymars/dustdevil.F90 @ 4009

Last change on this file since 4009 was 4008, checked in by aslmd, 2 weeks ago

MESOSCALE: use precompiling flags to hide instructions related to parallel computations (we consider physics as being like a 1D model without any attached dynamical core when we compile).

File size: 6.3 KB
Line 
1MODULE dustdevil_mod
2
3IMPLICIT NONE
4
5INTEGER,SAVE :: dust_devil_scheme ! dust devil scheme number
6! 0 (default): old Renno et al. 1998 (JAS 55, 3244-3252) scheme
7
8!$OMP THREADPRIVATE(dust_devil_scheme)
9
10CONTAINS
11
12  SUBROUTINE dustdevil(ngrid,nlay,nq, pplev,pu,pv,pt, ptsurf,pq2, &
13                       pdqdev,pdqs_dev)
14
15    use tracer_mod, only: alpha_devil
16    use surfdat_h, only: z0_default
17    USE comcstfi_h, ONLY: g, cpp, r, rcp
18#ifndef MESOSCALE
19    USE mod_phys_lmdz_para, ONLY: is_master, bcast
20#endif
21    USE ioipsl_getin_p_mod, ONLY : getin_p
22    IMPLICIT NONE
23
24!=======================================================================
25!
26!  Parameterization of dust devil activities
27!  to estimate dust lifting
28!  The dust devil activity is estimated based on
29!  Renno et al. 1998 (JAS 55, 3244-3252) 
30!
31!  It is proportional to (1-b)*Fs
32!
33!  With b= [ps**(rcp+1) - ptop**(rcp+1)] / [(ps-ptop)*(rcp+1)* ps**rcp]
34!  with ptop pressure of the top of the boundary layer
35!       rcp = R/cp
36!
37!  and Fs the surface sensible heat flux = Cd*|U|*(T(1) -Tsurf)
38!       
39!=======================================================================
40
41!   arguments:
42!   ----------
43
44    INTEGER,INTENT(IN) :: ngrid,nlay
45    REAL,INTENT(IN) :: pplev(ngrid,nlay+1)
46    REAL,INTENT(IN) :: pt(ngrid,nlay)
47    REAL,INTENT(IN) :: pu(ngrid,nlay)
48    REAL,INTENT(IN) :: pv(ngrid,nlay)
49    REAL,INTENT(IN) :: pq2(ngrid,nlay+1)
50    REAL,INTENT(IN) :: ptsurf(ngrid)
51
52!    Traceurs :
53    INTEGER,INTENT(IN) :: nq
54    real,intent(out) :: pdqdev(ngrid,nlay,nq)
55    real,intent(out) :: pdqs_dev(ngrid,nq)
56     
57!   local:
58!   ------
59
60    INTEGER :: ig,l,iq
61    real,save :: Cd
62!$OMP THREADPRIVATE(Cd)
63    real :: z1
64
65    LOGICAL,SAVE :: firstcall=.true.
66!$OMP THREADPRIVATE(firstcall)
67
68    character(len=20),parameter :: rname="dustdevil"
69
70    REAL :: devila(ngrid)
71    integer :: ltop(ngrid)
72    real :: b,rho,Fs,wind
73
74    REAL,SAVE :: q2top=.5 ! value of q2 at the top of PBL
75    REAL,SAVE :: seuil=.3 ! value of minimum dust devil activity
76                          ! for dust lifting     
77!$OMP THREADPRIVATE(q2top,seuil)
78
79
80!-----------------------------------------------------------------------
81!    initialisation
82!    --------------
83
84    ! AS: OK firstcall absolute
85
86    IF (firstcall) THEN
87
88      ! get scheme number (default=0, old scheme)
89      dust_devil_scheme=0
90      call getin_p("dust_devil_scheme",dust_devil_scheme)
91
92      ! sanity check on available dust_devil_scheme values
93      if (dust_devil_scheme.ne.0) then
94        write(*,*) trim(rname)//" wrong value for dust_devil_scheme:",&
95                   dust_devil_scheme
96        call abort_physic(rname,"bad dust_devil_scheme value",1)
97      endif
98#ifndef MESOSCALE
99      if(is_master) then
100#endif
101        write(*,*) 'In dustdevil :'
102        write(*,*) '    q2top= ',q2top,'     seuil= ', seuil
103
104! A rough estimation of the horizontal drag coefficient Cd
105! (the scale heigh is taken to be 13 km since we are typically
106! dealing with daytime temperature around 250K.
107!
108        z1= -0.5*13.e3*log(pplev(1,2)/pplev(1,1))
109        Cd = (0.4/log(z1/z0_default))**2
110
111!       Temporaire
112!       open(77,file='devil')
113#ifndef MESOSCALE     
114      endif !is_master
115
116      ! share the info with all cores
117      CALL bcast(z1)
118      CALL bcast(Cd)
119#endif
120
121      firstcall=.false.
122
123    ENDIF ! firstcall
124
125
126!-----------------------------------------------------------------------
127! Initialisation of outputs
128    do iq=1,nq
129      do l=1,nlay
130        do ig=1,ngrid
131          pdqdev(ig,l,iq)= 0
132        end do
133      end do
134    end do
135    pdqs_dev(1:ngrid,1:nq)=0
136
137    if (dust_devil_scheme==0) then
138!-----------------------------------------------------------------------
139!      Determining the top of the boundary layer
140!      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
141      do ig=1,ngrid
142        do  l=2,nlay-1
143          if (pq2(ig,l).lt.q2top)then
144            ltop(ig)=l
145            goto 99
146          end if
147        enddo
148 99     continue
149
150!        ***************************************
151!c        if (ptsurf(ig).gt.255)then
152!         write(*,*) 'tsurf, ztop (km): ', ig,
153!     &   ptsurf(ig), -12.*log(pplev(ig,ltop(ig))/pplev(ig,1))
154!         if ((ptsurf(ig).gt.50.).and.(
155!     &      (-12.*log(pplev(ig,ltop(ig))/pplev(ig,1))).gt.60.))then
156!            do l=1,nlay
157!             write(*,*) l,
158!     &       -12.*log(pplev(ig,l)/pplev(ig,1)),pq2(ig,l)
159!            end do
160!         end if
161!c        end if
162!        ***************************************
163     
164      enddo
165
166!        ***************************************
167!        do ig=100,148
168!           write(*,*)'time,tsurf,ztop', localtime(ig),ptsurf(ig),
169!    &      -12.*log(pplev(ig,ltop(ig))/pplev(ig,1))
170!        end do
171!        ***************************************
172
173
174!     Calculation : dust devil intensity
175!     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
176      do ig=1,ngrid
177
178! --------------------------------------------------
179! 1) Version 1 : sensible heat flux using actual wind :
180!      Wind magnitude:
181!      wind = sqrt(pu(ig,1)**2+pv(ig,1)**2)
182!
183! --------------------------------------------------
184! 2) Version 2 : sensible heat flux using  wind = 15 m/s
185        wind = 15.
186! ----------------------------------------------------
187!      Density :
188        rho=pplev(ig,1)/(R*pt(ig,1))
189
190!        Sensible heat flux (W.m-2) (>0 if up)
191        Fs= rho*cpp*Cd * wind * (ptsurf(ig) -pt(ig,1))
192        b= (pplev(ig,1)**(rcp+1) - pplev(ig,ltop(ig))**(rcp+1)) / &
193           ( (pplev(ig,1)-pplev(ig,ltop(ig)))*(rcp+1)*pplev(ig,1)**rcp)
194
195!     b_diag(ig) = b     ! TEMPORAIRE (pour diagnostique)
196
197!   Energy flux available to drive dust devil (W.m-2) : (1-b)*Fs
198!   Dust devil activity :
199        devila(ig)= max( 0. , (1-b)*Fs - seuil )
200      enddo
201!   
202!     lifted dust (kg m-2 s-1)  (<0 when lifting)
203!     ~~~~~~~~~~ 
204      do iq=1,nq
205        do ig=1,ngrid
206          pdqs_dev(ig,iq)= - alpha_devil(iq) * devila(ig)
207        end do
208      end do
209
210  !   Injection of dust in the atmosphere (up to the top of pbl)
211  !   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
212      do iq=1,nq
213        do ig=1,ngrid
214          if (devila(ig).ne.0.) then
215            do l=1,ltop(ig)
216               pdqdev(ig,l,iq)=-pdqs_dev(ig,iq)*g/ &
217                               (pplev(ig,1)-pplev(ig,ltop(ig)))
218            end do
219          end if
220        end do
221      end do
222   
223    endif ! of if (dust_devil_scheme==0)
224     
225  END SUBROUTINE dustdevil
226
227END MODULE dustdevil_mod
Note: See TracBrowser for help on using the repository browser.