source: trunk/LMDZ.MARS/libf/phymars/co2condens_mod4micro.F90 @ 2461

Last change on this file since 2461 was 2456, checked in by aslmd, 4 years ago

MESOSCALE Mars: fixing a couple of problems with double types related to introduction of CO2 model in r2362

File size: 35.7 KB
Line 
1!======================================================================================================================!
2! Module: CO2 condensation for the CO2 cloud microphysics =============================================================!
3!----------------------------------------------------------------------------------------------------------------------!
4! Authors: Christophe Mathé, Anni Määttänen
5! Date: 16/04/2020
6!----------------------------------------------------------------------------------------------------------------------!
7! Contains subroutines:
8!     - co2condens4micro: condensation/sublimation of CO2 ice on the ground and compute pressure change resulting
9!
10!     - vl1d: Van-Leer scheme
11!======================================================================================================================!
12module co2condens_mod4micro
13
14implicit none
15
16contains
17!======================================================================================================================!
18! SUBROUTINE: co2condens4micro ========================================================================================!
19!======================================================================================================================!
20! Subject:
21!---------
22!   Condensation/sublimation of CO2 ice on the ground and compute pressure change resulting
23!----------------------------------------------------------------------------------------------------------------------!
24! Comments:
25!----------
26!   Adapted from co2condens_mod.F
27!----------------------------------------------------------------------------------------------------------------------!
28! Paper:
29!-------
30!  Forget et al. (2008), "Non condensable gas enrichment and depletion in the Martian polar regions."
31!----------------------------------------------------------------------------------------------------------------------!
32! Algorithm:
33!-----------
34!   1. Initialization
35!   2. Firstcall
36!   3. Compute CO2 Volume mixing ratio
37!   4. Set zcondicea, zfallice from co2clouds condensation rate and set zt
38!   5. Main co2condens
39!     5.1. Forecast of ground temperature ztsrf and frost temperature ztcondsol
40!     5.2. Check if we have condensation/sublimation on the ground
41!     5.3. Compute zfallheat
42!     5.4. Compute direct condensation/sublimation of CO2 ice
43!       5.4.a. If there is not enough CO2 tracer in 1st layer to condense
44!       5.4.b. If the entire CO2 ice layer sublimes (including what has just condensed in the atmosphere)
45!     5.5. Changing CO2 ice amount and pressure
46!     5.6. Surface albedo and emissivity of the surface below the snow (emisref)
47!       5.6.a. Check that amont of CO2 ice is not problematic
48!       5.6.b. Set albedo and emissivity of the surface
49!       5.6.c. Set pemisurf to emissiv when there is bare surface (needed for co2snow)
50!     5.7. Correction to account for redistribution between sigma or hybrid layers when changing surface pressure (and
51!         warming/cooling of the CO2 currently changing phase).
52!       5.7.a. Mass fluxes through the sigma levels (kg.m-2.s-1)  (>0 when up)
53!       5.7.b. Mass of each layer at the end of timestep
54!       5.7.c. Corresponding fluxes for T, U, V and Q (averaging operator for transport)
55!         5.7.c.i. Value transfert at the surface interface when condensation/sublimation
56!         5.7.c.ii. Van Leer scheme
57!         5.7.c.iii Compute tendencies on T, U, V, Q
58!   6. CO2 snow / clouds scheme
59!   7. Extra special case for surface temperature tendency pdtsrfc
60!----------------------------------------------------------------------------------------------------------------------!
61  subroutine co2condens4micro(ngrid, nlayer, nq, ptimestep, pcapcal, pplay, pplev, ptsrf, pt, pphi, pdt, pdu, pdv, &
62                              pdtsrf, pu, pv, pq, pdq, piceco2, psolaralb, pemisurf, pdtc, pdtsrfc, pdpsrf, pduc, &
63                              pdvc, pdqc, fluxsurf_sw, zls, zdqssed_co2, pcondicea_co2microp, zdtcloudco2)
64
65  use tracer_mod, only: noms, igcm_co2, igcm_co2_ice, igcm_h2o_vap, igcm_h2o_ice, igcm_dust_number, igcm_dust_mass, &
66                        igcm_ccnco2_number, igcm_ccnco2_mass, igcm_ccn_mass
67
68  use surfdat_h, only: emissiv, phisfi
69
70  use geometry_mod, only: latitude, longitude_deg, latitude_deg
71
72  use planete_h, only: obliquit
73
74  use comcstfi_h, only: cpp, g, r, pi
75
76#ifndef MESOSCALE
77  use vertical_layers_mod, only: ap, bp
78#endif
79
80  implicit none
81
82  include "callkeys.h"
83!----------------------------------------------------------------------------------------------------------------------!
84! VARIABLE DECLARATION
85!----------------------------------------------------------------------------------------------------------------------!
86! Input arguments:
87!-----------------
88  integer, intent(in) :: &
89     nq,    &! number of tracers
90     ngrid, &! number of atmospheric columns
91     nlayer  ! number of vertical layers
92
93  real, intent(in) :: &
94     ptimestep,                       &! physics timestep (s)
95     pcapcal(ngrid),                  &! surface specific heat
96     pplay(ngrid,nlayer),             &! mid-layer pressure (Pa)
97     pplev(ngrid,nlayer+1),           &! inter-layer pressure (Pa)
98     ptsrf(ngrid),                    &! surface temperature (K)
99     pphi(ngrid,nlayer),              &! geopotential (m2.s-2)
100     pt(ngrid,nlayer),                &! atmospheric temperature (K)
101     pu(ngrid,nlayer),                &! zonal wind (m/s)
102     pv(ngrid,nlayer),                &! meridional wind (m/s)
103     pdt(ngrid,nlayer),               &! tendency on temperature from previous physical processes (K/s)
104     pdu(ngrid,nlayer),               &! tendency on zonal wind from previous physical processes(m/s2)
105     pdv(ngrid,nlayer),               &! tendency on meridional wind from previous physical processes (m/s2)
106     pdtsrf(ngrid),                   &! tendency on surface temperature from previous physical processes (K/s)
107     pq(ngrid,nlayer,nq),             &! tracers (../kg_air)
108     pdq(ngrid,nlayer,nq),            &! tendency on tracers from previous physical processes
109     zdqssed_co2(ngrid),              &! CO2 flux at the surface  (kg.m-2.s-1)
110     zdtcloudco2(ngrid,nlayer),       &! tendency on temperature due to latent heat
111     fluxsurf_sw(ngrid,2),            &! added to calculate flux dependent albedo
112     zls,                             &! solar longitude (rad)
113     pcondicea_co2microp(ngrid,nlayer) ! tendency due to CO2 condensation (kg/kg.s-1)
114!----------------------------------------------------------------------------------------------------------------------!
115! In/output arguments:
116!---------------------
117  real, intent(inout) :: &
118     piceco2(ngrid),   &! CO2 ice on the surface (kg.m-2)
119     pemisurf(ngrid),  &! emissivity of the surface
120     psolaralb(ngrid,2) ! albedo of the surface
121!----------------------------------------------------------------------------------------------------------------------!
122! Output arguments:
123!------------------
124  real, intent(out) :: &
125     pdtc(ngrid,nlayer),  &! tendency on temperature dT/dt due to cond/sub (K/s)
126     pdtsrfc(ngrid),      &! tendency on surface temperature (K/s)
127     pdpsrf(ngrid),       &! tendency on surface pressure (Pa/s)
128     pduc(ngrid,nlayer),  &! tendency on zonal wind (m.s-2)
129     pdvc(ngrid,nlayer),  &! tendency on meridional wind (m.s-2)
130     pdqc(ngrid,nlayer,nq) ! tendency on tracers
131!----------------------------------------------------------------------------------------------------------------------!
132! Local:
133!-------
134!----1) Parameters:
135!------------------
136  real, parameter :: &
137     latcond = 595594, &! latent heat of solid CO2 ice (J/kg)
138     cpice = 1000.,    &! specific heat of CO2 ice (J.kg-1.K-1)
139     tcond1mb = 136.27,&! condensation temperature at 1 mbar (K)
140     m_co2 = 44.01E-3, &! CO2 molecular mass (kg/mol)
141     m_noco2 = 33.37E-3 ! non condensible molecular mass (kg/mol)
142
143  logical, parameter :: &
144     improved_ztcond = .true. ! improved_ztcond flag: If set to .true. (AND running with a 'co2' tracer) then
145                              !  condensation temperature is computed using partial pressure of CO2
146!----------------------------------------------------------------------------------------------------------------------!
147!----2) Saved:
148!-------------
149  real, save :: &
150     A,    &! coefficient used to compute mean molecular mass
151     B,    &! coefficient used to compute mean molecular mass
152     acond,&! coefficient used to compute ztcondsol
153     bcond,&! coefficient used to compute ztcondsol
154     ccond  ! coefficient used to compute ztcondsol
155
156  logical, save :: &
157     firstcall = .true. ! Used to compute saved variables
158!----------------------------------------------------------------------------------------------------------------------!
159!----3) Variables:
160!-----------------
161  integer :: &
162     l,  &! loop on layers
163     ig, &! loop on ngrid points
164     iq   ! loop on tracer
165
166  real :: &
167     qco2,                   &! effective quantity of CO2, used to compute mean molecular mass
168     mmean,                  &! mean molecular mass
169     zfallheat,              &! aerodynamical friction and energy used to heat the amount of ice
170     zmflux(nlayer+1),       &! mass fluxes through the sigma levels (kg.m-2.s-1)
171     zu(nlayer),             &! effective zonal wind
172     zv(nlayer),             &! effective meridional wind
173     zq(nlayer,nq),          &! effective tracers quantities
174     zq1(nlayer),            &! buffer of zq
175     ztsrf(ngrid),           &! effective temperature at the surface
176     ztm(nlayer+1),          &! temperature fluxes through the sigma levels
177     zum(nlayer+1),          &! zonal wind fluxes through the sigma levels
178     zvm(nlayer+1),          &! meridional wind fluxes through the sigma levels
179     zqm(nlayer+1,nq),       &! quantity of tracers flux through the sigma levels
180     zqm1(nlayer),           &! quantity of tracers after Van-Leer scheme
181     masse(nlayer),          &! mass layer (kg)
182     w(nlayer+1),            &! total mass fluxes through the sigma levels during ptimestep (kg.m-2)
183     availco2,               &! available quantity of co2 (kg)
184     emisref(ngrid),         &! emissivity reference
185     vmr_co2(ngrid,nlayer),  &! CO2 volume mixing ratio
186     zt(nlayer),             &! effective temperature in the atmosphere (K)
187     ztcond(ngrid,nlayer+1), &! CO2 condensation temperature (atm)
188     ztcondsol(ngrid),       &! CO2 condensation temperature (surface)
189     zdiceco2(ngrid),        &! tendency on co2ice surface tracer (kg/m2/s)
190     zcondicea(ngrid,nlayer),&! condensation rate in layer l (kg/m2/s)
191     zcondices(ngrid),       &! condensation rate on the ground (kg/m2/s)
192     zfallice(ngrid)          ! amount of ice falling from layer l (kg/m2/s)
193
194  logical :: &
195     condsub(ngrid) ! True if there is condensation/sublimation (used for co2snow)
196
197
198  ! check with co2 cloud parameterisation
199  real :: &
200     zt_2(ngrid,nlayer), &
201     ztcond_2(ngrid,nlayer+1), &
202     zfallice_2(ngrid,nlayer+1), &
203     pdtc_2(ngrid,nlayer), &
204     zfallheat_2, &
205     zcondicea_2(ngrid,nlayer), &
206     diff_zcondicea(ngrid,nlayer), &
207     diff_zfallice(ngrid)
208!======================================================================================================================!
209! BEGIN ===============================================================================================================!
210!======================================================================================================================!
211! 1. Initialization
212!----------------------------------------------------------------------------------------------------------------------!
213  availco2 = 0.
214  zfallheat = 0.
215  zt(1:nlayer) = 0.
216  ztcond(1:ngrid, 1:nlayer+1) = 0.
217  ztcondsol(1:ngrid) = 0.
218  zmflux(1:nlayer+1) = 0.
219  zu(1:nlayer) = 0.
220  zv(1:nlayer) = 0.
221  zq(1:nlayer, 1:nq) = 0.
222  zq1(1:nlayer) = 0.
223  ztsrf(1:ngrid) = 0.
224  ztm(1:nlayer+1) = 0.
225  zum(1:nlayer+1) = 0.
226  zvm(1:nlayer+1) = 0.
227  zqm(1:nlayer+1, 1:nq) = 0.
228  masse(1:nlayer) = 0.
229  w(1:nlayer+1) = 0.
230  emisref(1:ngrid) = 0.
231  vmr_co2(1:ngrid, 1:nlayer) = 0.
232  zcondices(1:ngrid) = 0.
233  pdtsrfc(1:ngrid) = 0.
234  pdpsrf(1:ngrid) = 0.
235  zdiceco2(1:ngrid) = 0.
236  condsub(1:ngrid) = .false.
237  zcondicea(1:ngrid, 1:nlayer) = 0.
238  zfallice(1:ngrid) = 0.
239  pduc(1:ngrid, 1:nlayer) = 0.
240  pdvc(1:ngrid, 1:nlayer) = 0.
241  pdqc(1:ngrid, 1:nlayer, 1:nq) = 0.
242  pdtc(1:ngrid,1:nlayer) = 0.
243!----------------------------------------------------------------------------------------------------------------------!
244! 2. Firstcall
245!----------------------------------------------------------------------------------------------------------------------!
246! AS: firstcall OK absolute
247  if (firstcall) then
248    firstcall = .false.
249
250    bcond = 1. / tcond1mb
251    ccond = cpp / (g*latcond)
252    acond = r / latcond
253
254    write(*,*)'CO2condens: improved_ztcond=', improved_ztcond
255    write(*,*)'In co2condens:Tcond(P=1mb)=', tcond1mb, ' Lcond=', latcond
256    write(*,*)'acond,bcond,ccond', acond, bcond, ccond
257
258!   Prepare Special treatment if one of the tracer is CO2 gas. Compute A and B coefficient use to compute mean molecular
259!   mass Mair defined by:
260!     1/Mair = q(igcm_co2)/m_co2 + (1-q(igcm_co2))/m_noco2
261!     1/Mair = A*q(igcm_co2) + B
262    A = (1./m_co2 - 1./m_noco2)
263    B = 1./m_noco2
264  end if ! of IF (firstcall)
265!----------------------------------------------------------------------------------------------------------------------!
266! 3. Compute CO2 Volume mixing ratio
267!----------------------------------------------------------------------------------------------------------------------!
268  if (improved_ztcond.and.(igcm_co2/=0)) then
269    do l = 1, nlayer
270      do ig = 1, ngrid
271        qco2 = pq(ig,l,igcm_co2) + pdq(ig,l,igcm_co2)*ptimestep
272!       Mean air molecular mass = 1/(q(igcm_co2)/m_co2 + (1-q(igcm_co2))/m_noco2)
273        mmean = 1. / (A*qco2 +B)
274        vmr_co2(ig,l) = (qco2*mmean) / m_co2
275      end do
276    end do
277  else
278    do l = 1, nlayer
279      do ig = 1, ngrid
280        vmr_co2(ig,l) = 0.95
281      end do
282    end do
283  end if
284!----------------------------------------------------------------------------------------------------------------------!
285! 4. Set zcondicea, zfallice from co2clouds condensation rate
286!----------------------------------------------------------------------------------------------------------------------!
287  do l = nlayer, 1, -1
288    do ig = 1, ngrid
289      zcondicea(ig,l) = pcondicea_co2microp(ig,l) *  (pplev(ig,l) - pplev(ig,l+1))/g
290    end do
291  end do
292
293! Only sedimentation falls on the ground !
294  do ig = 1, ngrid
295      zfallice(ig) = zdqssed_co2(ig)
296      piceco2(ig) = piceco2(ig) + zfallice(ig)*ptimestep
297  end do
298
299  call writediagfi(ngrid, "zcondicea","Condensation rate in layers", " ", 3, zcondicea)
300
301  call writediagfi(ngrid,"zfallice", "Sedimentation rate", " ", 2, zfallice)
302
303! Compute without microphysics
304 do l =1, nlayer
305   do ig = 1, ngrid
306     zt_2(ig,l) = pt(ig,l) + pdt(ig,l)*ptimestep
307   end do
308 end do
309
310 do l = 1, nlayer
311   do ig = 1, ngrid
312     if (pplay(ig,l).ge.1e-4) then
313       ztcond_2(ig,l) = 1. / (bcond-acond*log(.01*vmr_co2(ig,l)*pplay(ig,l)))
314     else
315       ztcond_2(ig,l) = 0.0 !mars Monica
316     endif
317   end do
318 end do
319
320 ztcond_2(:,nlayer+1)=ztcond_2(:,nlayer)
321 zfallice_2(:,:) = 0
322
323 do l = nlayer , 1, -1
324   do ig = 1, ngrid
325     pdtc_2(ig,l) = 0.
326     if ((zt_2(ig,l).lt.ztcond_2(ig,l)).or.(zfallice_2(ig,l+1).gt.0)) then
327       if (zfallice_2(ig,l+1).gt.0) then 
328         zfallheat_2 = zfallice_2(ig,l+1)*(pphi(ig,l+1)-pphi(ig,l) + cpice*(ztcond_2(ig,l+1)-ztcond_2(ig,l)))/latcond
329       else
330         zfallheat_2 = 0.
331       end if
332       pdtc_2(ig,l) = (ztcond_2(ig,l) - zt_2(ig,l))/ptimestep
333       zcondicea_2(ig,l) = (pplev(ig,l)-pplev(ig,l+1))*ccond*pdtc(ig,l)- zfallheat_2
334       ! Case when the ice from above sublimes entirely
335       ! """""""""""""""""""""""""""""""""""""""""""""""
336       if (zfallice_2(ig,l+1).lt.- zcondicea_2(ig,l)) then
337         zcondicea_2(ig,l)= -zfallice_2(ig,l+1)
338       end if
339       zfallice_2(ig,l) = zcondicea_2(ig,l)+zfallice_2(ig,l+1)
340     end if
341   end do
342 end do
343 diff_zcondicea(:,:) = zcondicea_2(:,:) - zcondicea(:,:)
344 diff_zfallice(:) = zfallice_2(:,1) - zfallice(:)
345 call writediagfi(ngrid, "diff_zfallice", "sans - avec microphysique", "", 2, diff_zfallice)
346 call writediagfi(ngrid, "diff_zcondicea", "sans - avec microphysique", "", 3, diff_zcondicea)
347!----------------------------------------------------------------------------------------------------------------------!
348! 5. Main co2condens
349!----------------------------------------------------------------------------------------------------------------------!
350  do ig = 1, ngrid
351!----------------------------------------------------------------------------------------------------------------------!
352!   5.1. Forecast of ground temperature ztsrf and frost temperature ztcondsol
353!----------------------------------------------------------------------------------------------------------------------!
354    ztcondsol(ig) = 1. / (bcond-acond*log(.01*vmr_co2(ig,1)*pplev(ig,1)))
355    ztsrf(ig) = ptsrf(ig) + pdtsrf(ig)*ptimestep
356!----------------------------------------------------------------------------------------------------------------------!
357!   5.2. Check if we have condensation/sublimation on the ground
358!----------------------------------------------------------------------------------------------------------------------!
359!        ground condensation       ||   falling snow       ||    ground sublimation
360!----------------------------------------------------------------------------------------------------------------------!
361    if ((ztsrf(ig)<ztcondsol(ig)) .OR. (zfallice(ig)/=0.) .OR. ((ztsrf(ig)>ztcondsol(ig)) .AND. (piceco2(ig)/=0.))) then
362      condsub(ig) = .true.
363!----------------------------------------------------------------------------------------------------------------------!
364!   5.3. Compute zfallheat
365!----------------------------------------------------------------------------------------------------------------------!
366      zfallheat = 0.
367!----------------------------------------------------------------------------------------------------------------------!
368!   5.4. Compute direct condensation/sublimation of CO2 ice
369!----------------------------------------------------------------------------------------------------------------------!
370      zcondices(ig) = pcapcal(ig) * (ztcondsol(ig)-ztsrf(ig)) / (latcond*ptimestep) - zfallheat
371      pdtsrfc(ig) = (ztcondsol(ig) - ztsrf(ig)) / ptimestep
372!----------------------------------------------------------------------------------------------------------------------!
373!   5.4.a. If there is not enough CO2 tracer in 1st layer to condense
374!----------------------------------------------------------------------------------------------------------------------!
375!     Available CO2 tracer in layer 1 at end of timestep (kg/m2)
376#ifndef MESOSCALE
377      availco2 = pq(ig,1,igcm_co2) * ( (ap(1)-ap(2)) + (bp(1)-bp(2)) * (pplev(ig,1)/g - zcondices(ig)*ptimestep) )
378#else
379      availco2 = pq(ig,1,igcm_co2)
380      PRINT*, "MESOSCALE: CO2 tracer AT FIRST LEVEL IS NOT CORRECTED FROM SIGMA LEVELS"
381#endif
382      if ( zcondices(ig) * ptimestep>availco2 ) then
383        zcondices(ig) = availco2/ptimestep
384        zdiceco2(ig) = zcondices(ig) + zfallice(ig)
385        pdtsrfc(ig) = (latcond/pcapcal(ig)) *  (zcondices(ig)+zfallheat)
386      end if
387!----------------------------------------------------------------------------------------------------------------------!
388!   5.4.b. If the entire CO2 ice layer sublimes (including what has just condensed in the atmosphere)
389!----------------------------------------------------------------------------------------------------------------------!
390      if ( (piceco2(ig)/ptimestep) <= -zcondices(ig) ) then
391        zcondices(ig) = -piceco2(ig)/ptimestep
392        pdtsrfc(ig) = (latcond/pcapcal(ig)) *  (zcondices(ig)+zfallheat)
393      end if
394!----------------------------------------------------------------------------------------------------------------------!
395!   5.5. Changing CO2 ice amount and pressure
396!----------------------------------------------------------------------------------------------------------------------!
397      zdiceco2(ig) = zcondices(ig) + zfallice(ig) + sum(zcondicea(ig,:))
398      piceco2(ig) = piceco2(ig) + zcondices(ig)*ptimestep
399      pdpsrf(ig) = -zdiceco2(ig) * g
400
401      if (abs(pdpsrf(ig)*ptimestep)>pplev(ig,1)) then
402        print *, 'STOP in condens'
403        print *, 'condensing more than total mass'
404        print *, 'Grid point ', ig
405        print *, 'Longitude(degrees): ', longitude_deg(ig)
406        print *, 'Latitude(degrees): ', latitude_deg(ig)
407        print *, 'Ps = ', pplev(ig,1)
408        print *, 'd Ps = ', pdpsrf(ig)
409        call abort_physic('co2condens4micro', 'condensing more than total mass', 1)
410      end if
411!----------------------------------------------------------------------------------------------------------------------!
412!   5.6. Surface albedo and emissivity of the surface below the snow (emisref)
413!----------------------------------------------------------------------------------------------------------------------!
414!   5.6.a. Check that amont of CO2 ice is not problematic
415!----------------------------------------------------------------------------------------------------------------------!
416      if(.not.piceco2(ig)>=0.) then
417        if(piceco2(ig)<=-5.e-8) then
418          write(*,*)'WARNING co2condens piceco2(', ig, ')=', piceco2(ig)
419          piceco2(ig) = 0.
420        end if
421      end if
422!----------------------------------------------------------------------------------------------------------------------!
423!   5.6.c. Set pemisurf to emissiv when there is bare surface (needed for co2snow)
424!----------------------------------------------------------------------------------------------------------------------!
425      if (piceco2(ig)==0) then
426        pemisurf(ig) = emissiv
427      end if
428!----------------------------------------------------------------------------------------------------------------------!
429!  5.7. Correction to account for redistribution between sigma or hybrid layers when changing surface pressure (and
430!         warming/cooling of the CO2 currently changing phase).
431!----------------------------------------------------------------------------------------------------------------------!
432      do l= 1, nlayer
433        zt(l) = pt(ig,l) + pdt(ig,l)*ptimestep
434        zu(l) = pu(ig,l) + pdu(ig,l)*ptimestep
435        zv(l) = pv(ig,l) + pdv(ig,l)*ptimestep
436        do iq=1,nq
437          zq(l,iq) = pq(ig,l,iq) + pdq(ig,l,iq)*ptimestep
438        end do
439      end do
440!----------------------------------------------------------------------------------------------------------------------!
441!   5.7.a. Mass fluxes through the sigma levels (kg.m-2.s-1)  (>0 when up)
442!----------------------------------------------------------------------------------------------------------------------!
443      zmflux(1) = - zcondices(ig) - zfallice(ig)
444      do l = 1, nlayer
445#ifndef MESOSCALE
446        zmflux(l+1) = zmflux(l) - zcondicea(ig,l) &
447                      + (bp(l)-bp(l+1)) * (-pdpsrf(ig)/g)
448! zmflux set to 0 if very low to avoid: top layer is disappearing in v1ld
449        if (abs(zmflux(l+1))<1E-13.OR.bp(l+1)==0.) then
450          zmflux(l+1) = 0.
451        end if
452#else
453        zmflux(l+1) = zmflux(l) - zcondicea(ig,l)
454        if (abs(zmflux(l+1))<1E-13) then
455          zmflux(l+1) = 0.
456        end if
457        PRINT*, "MESOSCALE: FLUX THROUGH SIGMA LEVELS from dPS HAVE TO BE IMPLEMENTED"
458#endif
459      end do
460!----------------------------------------------------------------------------------------------------------------------!
461!   5.7.b. Mass of each layer at the end of timestep
462!----------------------------------------------------------------------------------------------------------------------!
463      do l = 1, nlayer
464#ifndef MESOSCALE
465        masse(l) = (pplev(ig,l) - pplev(ig,l+1) + (bp(l)-bp(l+1))*pdpsrf(ig)*ptimestep)/g
466#else
467        masse(l) = (pplev(ig,l) - pplev(ig,l+1))/g
468        PRINT*, "MESOSCALE: MASS OF EACH LAYER IS NOT CORRECTED AT END OF TIMESTEP (from SIGMA LEVELS and dPS)"
469#endif
470      end do
471!----------------------------------------------------------------------------------------------------------------------!
472!   5.7.c. Corresponding fluxes for T, U, V and Q (averaging operator for transport)
473!----------------------------------------------------------------------------------------------------------------------!
474!   5.7.c.i. Value transfert at the surface interface when condensation/sublimation
475!----------------------------------------------------------------------------------------------------------------------!
476      ztm(1) = ztsrf(ig) + pdtsrfc(ig)*ptimestep
477      zum(1) = 0
478      zvm(1) = 0
479
480!     Most tracer do not condense
481      do iq = 1, nq
482        zqm(1,iq) = 0.
483      end do
484
485!     Special case if one of the tracer is CO2 gas
486      if (igcm_co2/=0) then
487        zqm(1,igcm_co2) = 1. ! flux is 100% CO2
488      end if
489!----------------------------------------------------------------------------------------------------------------------!
490!   5.7.c.ii. Van Leer scheme
491!----------------------------------------------------------------------------------------------------------------------!
492      do l=1,nlayer
493        w(l)=-zmflux(l)*ptimestep
494      end do
495
496      call vl1d(nlayer,zt,2.,masse,w,ztm)
497      call vl1d(nlayer,zu ,2.,masse,w,zum)
498      call vl1d(nlayer,zv ,2.,masse,w,zvm)
499
500      do iq=1, nq
501        do l=1, nlayer
502          zq1(l) = zq(l,iq)
503        end do
504
505        zqm1(1) = zqm(1,iq)
506        zqm1(2:nlayer) = 0.
507
508        call vl1d(nlayer,zq1,2.,masse,w,zqm1)
509
510        do l = 2, nlayer
511          zq(l,iq) = zq1(l)
512          zqm(l,iq) = zqm1(l)
513        end do
514      end do
515
516!     Surface condensation affects low winds
517      if (zmflux(1)<0) then
518        zum(1) = zu(1) * (w(1)/masse(1))
519        zvm(1) = zv(1) * (w(1)/masse(1))
520        if (w(1)>masse(1)) then ! ensure numerical stability
521          zum(1) = ((zu(1)-zum(2))*masse(1)/w(1)) + zum(2)
522          zvm(1) = ((zv(1)-zvm(2))*masse(1)/w(1)) + zvm(2)
523        end if
524      end if
525
526      ztm(nlayer+1) = zt(nlayer) ! should not be used, but...
527      zum(nlayer+1) = zu(nlayer)  ! should not be used, but...
528      zvm(nlayer+1) = zv(nlayer)  ! should not be used, but...
529
530      do iq = 1, nq
531        zqm(nlayer+1,iq) = zq(nlayer,iq)
532      end do
533!----------------------------------------------------------------------------------------------------------------------!
534!   5.7.c.iii Compute tendencies on T, U, V, Q
535!----------------------------------------------------------------------------------------------------------------------!
536#ifdef MESOSCALE
537! AS: This part must be commented in the mesoscale model
538! AS: ... to avoid instabilities.
539! AS: you have to compile with -DMESOSCALE to do so
540#else
541      do l = 1, nlayer
542!       Tendencies on T
543        pdtc(ig,l) = (1./masse(l)) * ( zmflux(l)*(ztm(l) - zt(l))  - zmflux(l+1)*(ztm(l+1) - zt(l)) )
544
545!       Tendencies on U
546        pduc(ig,l) = (1./masse(l)) * ( zmflux(l)*(zum(l) - zu(l)) - zmflux(l+1)*(zum(l+1) - zu(l)) )
547
548!       Tendencies on V
549        pdvc(ig,l) = (1./masse(l)) * ( zmflux(l)*(zvm(l) - zv(l)) - zmflux(l+1)*(zvm(l+1) - zv(l)) )
550      end do
551#endif
552!       Tendencies on Q
553      do iq = 1, nq
554        if (iq==igcm_co2) then
555          do l = 1, nlayer
556            pdqc(ig,l,iq) = (1./masse(l)) * (zmflux(l)*(zqm(l,iq) - zq(l,iq))- zmflux(l+1)*(zqm(l+1,iq) - zq(l,iq))&
557                            + zcondicea(ig,l)*(zq(l,iq) - 1.))
558          end do
559        else
560          do l = 1, nlayer
561            pdqc(ig,l,iq) = (1./masse(l)) * ( zmflux(l)*(zqm(l,iq)-zq(l,iq)) - zmflux(l+1)*(zqm(l+1,iq)-zq(l,iq))&
562                            + zcondicea(ig,l)*zq(l,iq) )
563          end do
564        end if
565      end do
566    end if ! if
567  end do  ! loop on ig
568!----------------------------------------------------------------------------------------------------------------------!
569!   5.6.b. Set albedo and emissivity of the surface
570!----------------------------------------------------------------------------------------------------------------------!
571  call albedocaps(zls,ngrid,piceco2,psolaralb,emisref)
572!----------------------------------------------------------------------------------------------------------------------!
573! 6. CO2 snow / clouds scheme
574!----------------------------------------------------------------------------------------------------------------------!
575  call co2snow(ngrid, nlayer, ptimestep, emisref, condsub, pplev, zcondicea, zcondices, zdqssed_co2, &
576               pemisurf)
577!----------------------------------------------------------------------------------------------------------------------!
578! 7. Extra special case for surface temperature tendency pdtsrfc:
579!      We want to fix the south pole temperature to CO2 condensation temperature.
580!----------------------------------------------------------------------------------------------------------------------!
581#ifndef MESOSCALE
582  if (caps.and.(obliquit<27.)) then
583    ! check if last grid point is the south pole
584    if (abs(latitude(ngrid)-(-pi/2.))<1.e-5) then
585!     NB: Updated surface pressure, at grid point 'ngrid', is ps(ngrid)=pplev(ngrid,1)+pdpsrf(ngrid)*ptimestep
586!     write(*,*)"co2condens: South pole: latitude(ngrid)=", latitude(ngrid)
587      ztcondsol(ngrid) = 1./(bcond-acond*log(.01*vmr_co2(ngrid,1) * (pplev(ngrid,1)+pdpsrf(ngrid)*ptimestep)))
588      pdtsrfc(ngrid) = (ztcondsol(ngrid)-ztsrf(ngrid))/ptimestep
589    end if
590  end if
591#endif
592!======================================================================================================================!
593! END =================================================================================================================!
594!======================================================================================================================!
595  end subroutine co2condens4micro
596
597
598!**********************************************************************************************************************!
599!**********************************************************************************************************************!
600
601
602!======================================================================================================================!
603! SUBROUTINE: Van-Leer scheme =========================================================================================!
604!======================================================================================================================!
605! Subject:
606!---------
607!  Operateur de moyenne inter-couche pour calcul de transport type Van-Leer " pseudo amont " dans la verticale
608!----------------------------------------------------------------------------------------------------------------------!
609! Comments:
610!----------
611!  q,w are input arguments for the s-pg ....
612!----------------------------------------------------------------------------------------------------------------------!
613! Paper:
614!-------
615!  Van-Leer (1977), "Towards the Ultimate Conservative Difference Scheme. IV. A New Approach to Numerical Convection"
616!----------------------------------------------------------------------------------------------------------------------!
617  subroutine vl1d(nlayer,q,pente_max,masse,w,qm)
618
619  implicit none
620!----------------------------------------------------------------------------------------------------------------------!
621! VARIABLE DECLARATION
622!----------------------------------------------------------------------------------------------------------------------!
623! Input arguments:
624!-----------------
625  integer, intent(in) :: &
626     nlayer ! number of layers
627
628  real, intent(in) :: &
629     pente_max,     &! coefficient, pente_max = 2 advised
630     masse(nlayer), &! masse layer Dp/g (kg)
631     q(nlayer)       ! quantity of tracer
632!----------------------------------------------------------------------------------------------------------------------!
633! In-Output arguments:
634!---------------------
635  real, intent(inout) :: &
636     w(nlayer+1) ! masse d'atm ``transferee'' a chaque pas de temps (kg.m-2)
637!----------------------------------------------------------------------------------------------------------------------!
638! Output arguments:
639!------------------
640  real, intent(out) :: &
641     qm(nlayer+1) ! quantity of tracer after Van-Leer scheme
642!----------------------------------------------------------------------------------------------------------------------!
643! Locals variables:
644!------------------
645  integer :: &
646     l, &! loop on nlayer
647     m   ! index
648
649  real :: &
650     dzqmax,      &! maximum of dzq between two adjacent layers
651     sigw,        &!
652     Mtot,        &!
653     MQtot,       &!
654     dzq(nlayer), &!
655     dzqw(nlayer),&!
656     adzqw(nlayer) !
657!======================================================================================================================!
658! BEGIN ===============================================================================================================!
659!======================================================================================================================!
660! 1. On oriente tout dans le sens de la pression: w > 0 when down
661!----------------------------------------------------------------------------------------------------------------------!
662  do l = 2, nlayer
663    dzqw(l) = q(l-1) - q(l)
664    adzqw(l) = abs(dzqw(l))
665  end do
666
667  do l = 2, nlayer-1
668    if(dzqw(l)*dzqw(l+1)>0.) then
669      dzq(l) = 0.5 * (dzqw(l)+dzqw(l+1))
670    else
671      dzq(l) = 0.
672    end if
673
674    dzqmax = pente_max * min(adzqw(l), adzqw(l+1))
675
676    dzq(l) = sign(min(abs(dzq(l)),dzqmax), dzq(l))
677  end do
678
679  dzq(1)=0.
680  dzq(nlayer)=0.
681
682  do l = 1, nlayer-1
683!----------------------------------------------------------------------------------------------------------------------!
684! 2.1. Regular scheme (transfered mass < layer mass)
685!----------------------------------------------------------------------------------------------------------------------!
686    if (w(l+1)>0. .and. w(l+1)<=masse(l+1)) then
687      sigw = w(l+1) / masse(l+1)
688      qm(l+1) = (q(l+1) + 0.5*(1.-sigw)*dzq(l+1))
689    else if (w(l+1)<=0. .and. -w(l+1)<=masse(l)) then
690      sigw = w(l+1) / masse(l)
691      qm(l+1) = (q(l) - 0.5*(1.+sigw)*dzq(l))
692!----------------------------------------------------------------------------------------------------------------------!
693! 2.2. Extended scheme (transfered mass > layer mass)
694!----------------------------------------------------------------------------------------------------------------------!
695    else if (w(l+1)>0.) then
696      m = l+1
697      Mtot = masse(m)
698      MQtot = masse(m)*q(m)
699
700      do while ((m<nlayer).and.(w(l+1)>(Mtot+masse(m+1))))
701        m = m+1
702        Mtot = Mtot + masse(m)
703        MQtot = MQtot + masse(m)*q(m)
704      end do
705
706      if (m<nlayer) then
707        sigw = (w(l+1)-Mtot) / masse(m+1)
708        qm(l+1) = (1/w(l+1))*( MQtot + (w(l+1)-Mtot)* (q(m+1)+0.5*(1.-sigw)*dzq(m+1)) )
709      else
710        w(l+1) = Mtot
711        qm(l+1) = Mqtot / Mtot
712        call abort_physic('co2condens4micro', 'top layer is disapearing !', 1)
713      end if
714!----------------------------------------------------------------------------------------------------------------------!
715    else ! if(w(l+1).lt.0)
716      m = l-1
717      Mtot = masse(m+1)
718      MQtot = masse(m+1)*q(m+1)
719      if (m>0) then ! because some compilers will have problems evaluating masse(0)
720        do while ((m>0).and.(-w(l+1)>(Mtot+masse(m))))
721          m = m-1
722          Mtot = Mtot + masse(m+1)
723          MQtot = MQtot + masse(m+1)*q(m+1)
724          if (m==0) then
725            call abort_physic('co2condens_mod4micro','vl1d',1)
726          end if
727        end do
728      end if
729
730      if (m>0) then
731        sigw = (w(l+1)+Mtot) / masse(m)
732        qm(l+1) = (-1/w(l+1)) * ( MQtot + (-w(l+1)-Mtot) * (q(m)-0.5*(1.+sigw)*dzq(m)) )
733      else
734        qm(l+1) = (-1/w(l+1)) * (MQtot + (-w(l+1)-Mtot)*qm(1))
735      end if
736    end if
737  end do ! l = 1, nlayer-1
738!======================================================================================================================!
739! END =================================================================================================================!
740!======================================================================================================================!
741  end subroutine vl1d
742
743end module co2condens_mod4micro
Note: See TracBrowser for help on using the repository browser.