source: trunk/LMDZ.GENERIC/libf/phystd/newsedim.F @ 2987

Last change on this file since 2987 was 2670, checked in by bclmd, 3 years ago

Adding calculation of viscosity/molrad, general stokes law and non-spherical water ice particles in newsedim.F

File size: 11.4 KB
Line 
1      SUBROUTINE newsedim(ngrid,nlay,naersize,ptimestep,
2     &  pplev,masse,epaisseur,pt,rd,rho,pqi,wq,iq)
3     
4      use ioipsl_getin_p_mod, only: getin_p
5      use comcstfi_mod, only: r, g
6      use gases_h
7      use tracer_h, only : igcm_h2o_ice
8      use watercommon_h, only: T_h2O_ice_liq,T_h2O_ice_clouds     
9      use radii_mod, only: h2o_cloudrad
10
11      IMPLICIT NONE
12
13!==================================================================
14!     
15!     Purpose
16!     -------
17!      Calculates sedimentation of 1 tracer
18!      of radius rd (m) and density rho (kg.m-3)
19!     
20!==================================================================
21
22!-----------------------------------------------------------------------
23!   declarations
24!   ------------
25
26!   arguments
27!   ---------
28
29      integer,intent(in) :: ngrid  ! number of atmospheric columns
30      integer,intent(in) :: nlay  ! number of atmospheric layers
31      integer,intent(in) :: naersize   ! number of particle sizes (1 or number
32                                       ! of grid boxes)
33      real,intent(in) :: ptimestep ! physics time step (s)
34      real,intent(in) :: pplev(ngrid,nlay+1)   ! inter-layer pressures (Pa)
35      real,intent(in) :: pt(ngrid,nlay)    ! mid-layer temperatures (K)
36      real,intent(in) :: masse (ngrid,nlay) ! atmospheric mass (kg)
37      real,intent(in) :: epaisseur (ngrid,nlay)  ! thickness of atm. layers (m)
38      real,intent(in) :: rd(naersize) ! particle radius (m)
39      real,intent(in) :: rho ! particle density (kg.m-3)
40      real,intent(inout) :: pqi(ngrid,nlay)  ! tracer   (e.g. ?/kg)
41      real,intent(out) :: wq(ngrid,nlay+1)  ! flux of tracer during timestep (?/m-2)
42      integer,intent(in) :: iq ! tracer index
43
44c   local:
45c   ------
46
47      INTEGER l,ig, k, i, igas
48      REAL rfall, rsurf, Reynolds, Cd, zfrac
49      REAL reffh2oliq(ngrid,nlay), reffh2oice(ngrid,nlay)
50
51      LOGICAL,SAVE :: firstcall=.true.
52!$OMP THREADPRIVATE(firstcall)
53      LOGICAL,SAVE :: crystal_shape
54!$OMP THREADPRIVATE(crystal_shape)     
55
56c    Traceurs :
57c    ~~~~~~~~
58      real traversee (ngrid,nlay)
59      real vstokes(ngrid,nlay)
60      real w(ngrid,nlay)
61      real ptop, dztop, Ep, Stra
62
63
64c    Physical constant
65c    ~~~~~~~~~~~~~~~~~
66c     Gas molecular viscosity (N.s.m-2)
67      real, allocatable, save :: visc(:,:)
68!$OMP THREADPRIVATE(visc)     
69c     Effective gas molecular radius (m)
70      real,save :: molrad
71
72c     local and saved variable
73      real,save :: a,b
74!$OMP THREADPRIVATE(a,b)
75
76c    ** un petit test de coherence
77c       --------------------------
78
79      !print*,'temporary fixed particle rad in newsedim!!'
80
81      IF (firstcall) THEN
82         firstcall=.false.
83
84c        Determination of the viscosity a(N.s.m-2) and the mean molecular radius (m)
85        write(*,*) "Calculation of the viscosity and the mean molecular"
86     &               ," radius from gases.def"
87         allocate(visc(ngrid,nlay))
88         visc(:,:)=0.0
89         molrad=0.
90         do igas=1, ngasmx
91           if(gfrac(igas).ge.0.0) then
92             if(igas.eq.igas_CO2) then
93               molrad = molrad + gfrac(igas)*2.2e-10                              ! CO2
94               visc(:,:) = visc(:,:) + gfrac(igas)*1.0e-5                         ! CO2
95             elseif(igas.eq.igas_N2) then
96               molrad = molrad + gfrac(igas)*1.8e-10                              ! N2 (Kunze et al. 2022)
97               visc(:,:) = visc(:,:) + gfrac(igas)*1.0e-5                         ! N2
98             elseif(igas.eq.igas_H2) then
99               molrad = molrad + gfrac(igas)*1.41e-10                             ! H2 (Ackerman & Marley 2001)
100               visc(:,:) = visc(:,:) + gfrac(igas)*2.0d-07*pt(:,:)**0.66          ! H2 (from Rosner 2000)
101             elseif(igas.eq.igas_H2O) then
102               molrad = molrad + gfrac(igas)*2.3e-10                              ! H2O (Crifo 1989 at 300K)
103               visc(:,:) = visc(:,:) + gfrac(igas)*8e-6                           ! H2O (Sengers & Kamgar-Parsi 1984)
104             elseif(igas.eq.igas_He) then
105               molrad = molrad + gfrac(igas)*1.1e-10                              ! He (Kunze et al. 2022)
106               visc(:,:) = visc(:,:) +                                            ! He
107     &                     gfrac(igas)*1.9e-5*(pt(:,:)/273.15)**0.7               ! He (Petersen 1970)
108             elseif(igas.eq.igas_CH4) then
109               molrad = molrad + gfrac(igas)*1.9e-10                              ! CH4 (Ismail et al. 2015)
110               visc(:,:) = visc(:,:) + gfrac(igas)*1.0e-5                         ! CH4
111             else
112               molrad = molrad + gfrac(igas)*2.2e-10                              ! CO2 by default
113               visc(:,:) = visc(:,:) + gfrac(igas)*1.e-5                          ! CO2 by default
114               write(*,*) trim(gnom(igas))," is not included in"
115     &              ," newsedim, CO2 is used by default"
116             endif
117           endif
118         enddo
119         write(*,*) "visc(1,1)=",visc(1,1),"N.s.m-2; ",
120     &               "molrad=",molrad,"m"
121
122c Correction for non-spherical water ice particles
123         write(*,*) "Use non-spherical water ice particles",
124     &             " for the sedimentation ?"
125         crystal_shape=.false. !default
126         call getin_p("crystal_shape",crystal_shape)
127         write(*,*) " crystal_shape = ",crystal_shape
128
129
130!=======================================================================
131!     Preliminary calculations for sedimenation velocity
132
133!       - Constant to compute stokes speed simple formulae
134!        (Vstokes =  b / visc * rho* r**2   avec   b= (2/9) * rho * g
135         b = 2./9. * g
136
137!       - Constant  to compute gas mean free path
138!        l= (T/P)*a, avec a = (  0.707*8.31/(4*pi*molrad**2 * avogadro))
139         a = 0.707*8.31/(4*3.1416* molrad**2  * 6.023e23)
140
141c       - Correction to account for non-spherical shape (Murphy et al.  1990)
142c   (correction = 0.85 for irregular particles, 0.5 for disk shaped particles)
143c        a = a    * 0.85
144
145
146      ENDIF
147
148c-----------------------------------------------------------------------
149c    1. initialisation
150c    -----------------
151
152c     Sedimentation velocity (m/s)
153c     ~~~~~~~~~~~~~~~~~~~~~~
154c     (stokes law corrected for low pressure by the Cunningham
155c     slip-flow correction  according to Rossow (Icarus 36, 1-50, 1978)
156
157c Compute liquid and ice particle radii
158        if((iq.eq.igcm_h2o_ice).and.crystal_shape) then
159            call h2o_cloudrad(ngrid,nlay,pqi,reffh2oliq,reffh2oice)
160        endif
161
162
163        do  l=1,nlay
164          do ig=1, ngrid
165            if (naersize.eq.1) then
166              rfall=rd(1)
167            else
168              i=ngrid*(l-1)+ig
169              rfall=rd(i) ! how can this be correct!!?
170            endif 
171
172c Correction for non-spherical water ice particles           
173            if((iq.eq.igcm_h2o_ice).and.crystal_shape) then
174              zfrac= (pt(ig,l)-T_h2O_ice_clouds) /
175     &               (T_h2O_ice_liq-T_h2O_ice_clouds)
176              zfrac= MAX(zfrac, 0.0)
177              zfrac= MIN(zfrac, 1.0)
178              rsurf=max(reffh2oice(ig,l),45.6*reffh2oice(ig,l)**1.3)        ! surface radius (formula for rimed dendrites from Hemsfield 1977, transition at around 30 microns)
179              rsurf=1/(zfrac/reffh2oice(ig,l)+(1-zfrac)/rsurf)              ! radius giving the mean velocity between liquid and ice particles
180            else
181              rsurf=rfall
182            endif
183
184            vstokes(ig,l) = b / visc(ig,l) * rho * rfall**3 / rsurf *
185     &      (1 + 1.333* ( a*pt(ig,l)/pplev(ig,l) )/rsurf)
186
187c Correction for high Reynolds number
188            Reynolds=2. * pplev(ig,l) / r / pt(ig,l) *
189     &        rsurf * vstokes(ig,l) / visc(ig,l)
190            if(Reynolds.ge.1.0) then
191              do i=1,5
192              Cd=24. / Reynolds * (1. + 0.15 * Reynolds**0.687) +
193     &           0.42 / (1. + 42500 / Reynolds**1.16)                       ! (Formula from Bagheri 2018)
194              vstokes(ig,l) =(8./3.*pplev(ig,l)/r/pt(ig,l)*g*rfall**3 /
195     &           rsurf**2/rho/Cd *
196     &           (1.+1.333*(a*pt(ig,l)/pplev(ig,l))/rsurf))**0.5
197              Reynolds=2. * pplev(ig,l) / r / pt(ig,l) *
198     &           rsurf * vstokes(ig,l) / visc(ig,l)
199              enddo
200            endif   
201
202c           Layer crossing time (s) :
203            traversee(ig,l)= epaisseur(ig,l)/vstokes(ig,l)
204          end do
205        end do
206
207
208c     Calcul de la masse d'atmosphere correspondant a q transferee
209c     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
210c     (e.g. on recherche le niveau  en dessous de laquelle le traceur
211c      va traverser le niveau intercouche l : "dztop" est sa hauteur
212c      au dessus de l (m), "ptop" est sa pression (Pa))
213      do  l=1,nlay
214        do ig=1, ngrid
215             
216             dztop = vstokes(ig,l)*  ptimestep
217             Ep=0
218             k=0
219           w(ig,l) = 0. !! JF+AS ajout initialisation (LK MARS)
220c **************************************************************
221c            Simple Method
222cc             w(ig,l) =
223cc     &       (1- exp(-dztop*g/(r*pt(ig,l))))*pplev(ig,l) / g
224cc             write(*,*) 'OK simple method l,w =', l, w(ig,l)
225cc            write(*,*) 'OK simple method dztop =', dztop
226           w(ig,l) = 1. - exp(-dztop*g/(r*pt(ig,l)))
227             !!! Diagnostic: JF. Fix: AS. Date: 05/11
228             !!! Probleme arrondi avec la quantite ci-dessus
229             !!! ---> vaut 0 pour -dztop*g/(r*pt(ig,l)) trop petit
230             !!! ---> dans ce cas on utilise le developpement limite !
231             !!! ---> exp(-x) = 1 - x lorsque x --> 0 avec une erreur de x^2 / 2 
232
233             IF ( w(ig,l) .eq. 0. ) THEN
234                w(ig,l) = ( dztop*g/(r*pt(ig,l)) ) * pplev(ig,l) / g
235             ELSE
236                w(ig,l) = w(ig,l) * pplev(ig,l) / g
237             ENDIF
238! LK borrowed simple method from Mars model (AS/JF)
239
240!**************************************************************
241cccc         Complex method :
242           if (dztop.gt.epaisseur(ig,l)) then
243cccc            Cas ou on "epuise" la couche l : On calcule le flux
244cccc            Venant de dessus en tenant compte de la variation de Vstokes
245
246               Ep= epaisseur(ig,l)
247               Stra= traversee(ig,l)
248               do while(dztop.gt.Ep.and.l+k+1.le.nlay)
249                 k=k+1
250                 dztop= Ep + vstokes(ig,l+k)*(ptimestep -Stra)
251                 Ep = Ep + epaisseur(ig,l+k)
252                 Stra = Stra + traversee(ig,l+k)
253               enddo
254               Ep = Ep - epaisseur(ig,l+k)
255!             ptop=pplev(ig,l+k)*exp(-(dztop-Ep)*g/(r*pt(ig,l+k)))
256             ptop=exp(-(dztop-Ep)*g/(r*pt(ig,l+k)))
257             IF ( ptop .eq. 1. ) THEN
258                !PRINT*, 'newsedim: exposant trop petit ', ig, l
259                ptop=pplev(ig,l+k) * ( 1. - (dztop-Ep)*g/(r*pt(ig,l+k)))
260             ELSE
261                ptop=pplev(ig,l+k) * ptop
262             ENDIF
263
264             w(ig,l) = (pplev(ig,l) - ptop)/g
265
266            endif   !!! complex method
267c
268cc           write(*,*) 'OK new    method l,w =', l, w(ig,l)
269cc           write(*,*) 'OK new    method dztop =', dztop
270cc       if(l.eq.7)write(*,*)'l=7,k,pplev,Ptop',pplev(ig,l),Ptop
271cc       if(l.eq.7)write(*,*)'l=7,dztop,Ep',dztop,Ep
272cc            if(l.eq.6)write(*,*)'l=6,k, w',k, w(1,l)
273cc            if(l.eq.7)write(*,*)'l=7,k, w',k, w(1,l)
274cc            if(l.eq.8)write(*,*)'l=8,k, w',k, w(1,l)
275c **************************************************************
276
277        end do
278      end do
279
280      call vlz_fi(ngrid,nlay,pqi,2.,masse,w,wq)
281c         write(*,*) ' newsed: wq(6), wq(7), q(6)',
282c    &                wq(1,6),wq(1,7),pqi(1,6)
283
284      END
Note: See TracBrowser for help on using the repository browser.