source: trunk/LMDZ.GENERIC/libf/phystd/turbdiff.F90 @ 739

Last change on this file since 739 was 736, checked in by jleconte, 13 years ago

24/07/2012 == JL

  • Correction of a bug in turbulent diffusion (turbdiff.F90)

=> This solves a water conservation problem arising when the code tries to
evaporate over dry land.

File size: 27.1 KB
Line 
1      subroutine turbdiff(ngrid,nlay,nq,rnat,          &
2          ptimestep,pcapcal,lecrit,                    &   
3          pplay,pplev,pzlay,pzlev,pz0,                 &
4          pu,pv,pt,ppopsk,pq,ptsrf,pemis,pqsurf,       &
5          pdufi,pdvfi,pdtfi,pdqfi,pfluxsrf,            &
6          Pdudif,pdvdif,pdtdif,pdtsrf,sensibFlux,pq2,  &
7          pdqdif,pdqevap,pdqsdif,lastcall)
8
9      use watercommon_h, only : RLVTT, T_h2O_ice_liq, RCPD, mx_eau_sol,Psat_water
10      use radcommon_h, only : sigma
11
12      implicit none
13
14!==================================================================
15!     
16!     Purpose
17!     -------
18!     Turbulent diffusion (mixing) for pot. T, U, V and tracers
19!     
20!     Implicit scheme
21!     We start by adding to variables x the physical tendencies
22!     already computed. We resolve the equation:
23!
24!     x(t+1) =  x(t) + dt * (dx/dt)phys(t)  +  dt * (dx/dt)difv(t+1)
25!     
26!     Authors
27!     -------
28!     F. Hourdin, F. Forget, R. Fournier (199X)
29!     R. Wordsworth, B. Charnay (2010)
30!     J. Leconte (2012): To f90
31!         - Rewritten the diffusion scheme to conserve total enthalpy
32!               by accounting for dissipation of turbulent kinetic energy.
33!         - Accounting for lost mean flow kinetic energy should come soon.
34!     
35!==================================================================
36
37!-----------------------------------------------------------------------
38!     declarations
39!     ------------
40
41#include "dimensions.h"
42#include "dimphys.h"
43#include "comcstfi.h"
44#include "callkeys.h"
45#include "surfdat.h"
46#include "comgeomfi.h"
47#include "tracer.h"
48
49#include "watercap.h"
50
51!     arguments
52!     ---------
53      INTEGER ngrid,nlay
54      REAL ptimestep
55      REAL pplay(ngrid,nlay),pplev(ngrid,nlay+1)
56      REAL pzlay(ngrid,nlay),pzlev(ngrid,nlay+1)
57      REAL pu(ngrid,nlay),pv(ngrid,nlay)
58      REAL pt(ngrid,nlay),ppopsk(ngrid,nlay)
59      REAL ptsrf(ngrid),pemis(ngrid)
60      REAL pdufi(ngrid,nlay),pdvfi(ngrid,nlay)
61      REAL pdtfi(ngrid,nlay)
62      REAL pfluxsrf(ngrid)
63      REAL pdudif(ngrid,nlay),pdvdif(ngrid,nlay)
64      REAL pdtdif(ngrid,nlay)
65      REAL pdtsrf(ngrid),sensibFlux(ngrid),pcapcal(ngrid)
66      REAL pq2(ngrid,nlay+1)
67     
68      integer rnat(ngrid)     
69
70!     Arguments added for condensation
71      logical lecrit
72      REAL pz0
73
74!     Tracers
75!     --------
76      integer nq
77      real pqsurf(ngrid,nq)
78      real pq(ngrid,nlay,nq), pdqfi(ngrid,nlay,nq)
79      real pdqdif(ngrid,nlay,nq)
80      real pdqsdif(ngrid,nq)
81     
82!     local
83!     -----
84      integer ilev,ig,ilay,nlev
85
86      REAL z4st,zdplanck(ngridmx)
87      REAL zkv(ngridmx,nlayermx+1),zkh(ngridmx,nlayermx+1)
88      REAL zcdv(ngridmx),zcdh(ngridmx)
89      REAL zcdv_true(ngridmx),zcdh_true(ngridmx)
90      REAL zu(ngridmx,nlayermx),zv(ngridmx,nlayermx)
91      REAL zh(ngridmx,nlayermx),zt(ngridmx,nlayermx)
92      REAL ztsrf(ngridmx)
93      REAL z1(ngridmx),z2(ngridmx)
94      REAL zmass(ngridmx,nlayermx)
95      REAL zfluxv(ngridmx,nlayermx),zfluxt(ngridmx,nlayermx),zfluxq(ngridmx,nlayermx)
96      REAL zb0(ngridmx,nlayermx)
97      REAL zExner(ngridmx,nlayermx),zovExner(ngridmx,nlayermx)
98      REAL zcv(ngridmx,nlayermx),zdv(ngridmx,nlayermx)  !inversion coefficient for winds
99      REAL zct(ngridmx,nlayermx),zdt(ngridmx,nlayermx)  !inversion coefficient for temperature
100      REAL zcq(ngridmx,nlayermx),zdq(ngridmx,nlayermx)  !inversion coefficient for tracers
101      REAL zcst1
102      REAL zu2!, a
103      REAL zcq0(ngridmx),zdq0(ngridmx)
104      REAL zx_alf1(ngridmx),zx_alf2(ngridmx)
105
106      LOGICAL firstcall
107      SAVE firstcall
108     
109      LOGICAL lastcall
110!     Tracers
111!     -------
112      INTEGER iq
113      REAL zq(ngridmx,nlayermx,nqmx)
114      REAL zqnoevap(ngridmx,nlayermx) !special for water case to compute where evaporated water goes.
115      REAL pdqevap(ngridmx,nlayermx) !special for water case to compute where evaporated water goes.
116      REAL zdmassevap(ngridmx)
117      REAL rho(ngridmx)         ! near-surface air density
118      REAL qsat(ngridmx),psat(ngridmx)
119      DATA firstcall/.true./
120      REAL kmixmin
121
122!     Variables added for implicit latent heat inclusion
123!     --------------------------------------------------
124      real dqsat(ngridmx), qsat_temp1, qsat_temp2,psat_temp
125
126      integer, save :: ivap, iliq, iliq_surf,iice_surf ! also make liq for clarity on surface...
127
128      real, parameter :: karman=0.4
129      real cd0, roughratio
130
131      real dqsdif_total(ngrid)
132      real zq0(ngrid)
133
134
135!     Coherence test
136!     --------------
137
138      IF (firstcall) THEN
139
140         if(water)then
141             ivap=igcm_h2o_vap
142             iliq=igcm_h2o_ice
143             iliq_surf=igcm_h2o_vap
144             iice_surf=igcm_h2o_ice ! simply to make the code legible               
145                                  ! to be generalised
146         else
147             ivap=0
148             iliq=0
149             iliq_surf=0
150             iice_surf=0 ! simply to make the code legible                       
151         endif
152         sensibFlux(:)=0.
153
154         firstcall=.false.
155      ENDIF
156
157!-----------------------------------------------------------------------
158!     1. Initialisation
159!     -----------------
160
161      nlev=nlay+1
162
163!     Calculate rho*dz, (P/Ps)**(R/cp) and dt*rho/dz=dt*rho**2 g/dp
164!     with rho=p/RT=p/ (R Theta) (p/ps)**kappa
165!     ---------------------------------------------
166
167      DO ilay=1,nlay
168         DO ig=1,ngrid
169            zmass(ig,ilay)=(pplev(ig,ilay)-pplev(ig,ilay+1))/g
170            zExner(ig,ilay)=(pplev(ig,ilay)/pplev(ig,1))**rcp
171            zovExner(ig,ilay)=1./ppopsk(ig,ilay)
172         ENDDO
173      ENDDO
174
175      zcst1=4.*g*ptimestep/(R*R)
176      DO ilev=2,nlev-1
177         DO ig=1,ngrid
178            zb0(ig,ilev)=pplev(ig,ilev)/(pt(ig,ilev-1)+pt(ig,ilev))
179            zb0(ig,ilev)=zcst1*zb0(ig,ilev)*zb0(ig,ilev)/(pplay(ig,ilev-1)-pplay(ig,ilev))
180         ENDDO
181      ENDDO
182      DO ig=1,ngrid
183         zb0(ig,1)=ptimestep*pplev(ig,1)/(R*ptsrf(ig))
184      ENDDO
185      dqsdif_total(:)=0.0
186
187!-----------------------------------------------------------------------
188!     2. Add the physical tendencies computed so far
189!     ----------------------------------------------
190
191      DO ilev=1,nlay
192         DO ig=1,ngrid
193            zu(ig,ilev)=pu(ig,ilev)+pdufi(ig,ilev)*ptimestep
194            zv(ig,ilev)=pv(ig,ilev)+pdvfi(ig,ilev)*ptimestep
195            zt(ig,ilev)=pt(ig,ilev)+pdtfi(ig,ilev)*ptimestep
196            zh(ig,ilev)=pt(ig,ilev)*zovExner(ig,ilev) !for call vdif_kc, but could be moved and computed there
197        ENDDO
198      ENDDO
199      if(tracer) then
200         DO iq =1, nq
201            DO ilev=1,nlay
202               DO ig=1,ngrid
203                  zq(ig,ilev,iq)=pq(ig,ilev,iq) + pdqfi(ig,ilev,iq)*ptimestep
204               ENDDO
205            ENDDO
206         ENDDO
207         if (water) then
208            DO ilev=1,nlay
209               DO ig=1,ngrid
210                  zqnoevap(ig,ilev)=pq(ig,ilev,ivap) + pdqfi(ig,ilev,ivap)*ptimestep
211               ENDDO
212            ENDDO
213         Endif
214      end if
215
216!-----------------------------------------------------------------------
217!     3. Turbulence scheme
218!     --------------------
219!
220!     Source of turbulent kinetic energy at the surface
221!     -------------------------------------------------
222!     Formula is Cd_0 = (karman / log[1+z1/z0])^2
223
224      DO ig=1,ngrid
225         roughratio = 1. + pzlay(ig,1)/pz0
226         cd0 = karman/log(roughratio)
227         cd0 = cd0*cd0
228         zcdv_true(ig) = cd0
229         zcdh_true(ig) = cd0
230!        zcdv_true(ig)=0.!JL12 uncomment to disable atm/surface momentum flux
231!        zcdh_true(ig)=0.!JL12 uncomment to disable sensible heat flux
232      ENDDO
233
234      DO ig=1,ngrid
235         zu2=pu(ig,1)*pu(ig,1)+pv(ig,1)*pv(ig,1)
236         zcdv(ig)=zcdv_true(ig)*sqrt(zu2)
237         zcdh(ig)=zcdh_true(ig)*sqrt(zu2)
238      ENDDO
239
240!     Turbulent diffusion coefficients in the boundary layer
241!     ------------------------------------------------------
242
243      call vdif_kc(ptimestep,g,pzlev,pzlay,pu,pv,zh,zcdv_true,pq2,zkv,zkh) !JL12 why not call vdif_kc with updated winds and temperature
244
245!     Adding eddy mixing to mimic 3D general circulation in 1D
246!     R. Wordsworth & F. Forget (2010)
247      if ((ngrid.eq.1)) then
248         kmixmin = 1.0e-2       ! minimum eddy mix coeff in 1D
249         do ilev=1,nlay
250            do ig=1,ngrid
251               zkh(ig,ilev) = max(kmixmin,zkh(ig,ilev))
252               zkv(ig,ilev) = max(kmixmin,zkv(ig,ilev))
253            end do
254         end do
255      end if
256
257!JL12 change zkv at the surface by zcdv to calculate the surface momentum flux properly
258      DO ig=1,ngrid
259         zkv(ig,1)=zcdv(ig)
260      ENDDO
261!we treat only winds, energy and tracers coefficients will be computed with upadted winds
262 
263!JL12 calculate the flux coefficients (tables multiplied elements by elements)
264      zfluxv(1:ngridmx,1:nlayermx)=zkv(1:ngridmx,1:nlayermx)*zb0(1:ngridmx,1:nlayermx)
265     
266!-----------------------------------------------------------------------
267!     4. Implicit inversion of u
268!     --------------------------
269
270!     u(t+1) =  u(t) + dt * {(du/dt)phys}(t)  +  dt * {(du/dt)difv}(t+1)
271!     avec
272!     /zu/ = u(t) + dt * {(du/dt)phys}(t)   (voir paragraphe 2.)
273!     et
274!     dt * {(du/dt)difv}(t+1) = dt * {(d/dz)[ Ku (du/dz) ]}(t+1)
275!     donc les entrees sont /zcdv/ pour la condition a la limite sol
276!     et /zkv/ = Ku
277
278      DO ig=1,ngrid
279         z1(ig)=1./(zmass(ig,nlay)+zfluxv(ig,nlay))
280         zcv(ig,nlay)=zmass(ig,nlay)*zu(ig,nlay)*z1(ig)
281         zdv(ig,nlay)=zfluxv(ig,nlay)*z1(ig)
282      ENDDO
283
284      DO ilay=nlay-1,1,-1
285         DO ig=1,ngrid
286            z1(ig)=1./(zmass(ig,ilay)+zfluxv(ig,ilay) + zfluxv(ig,ilay+1)*(1.-zdv(ig,ilay+1)))
287            zcv(ig,ilay)=(zmass(ig,ilay)*zu(ig,ilay)+zfluxv(ig,ilay+1)*zcv(ig,ilay+1))*z1(ig)
288            zdv(ig,ilay)=zfluxv(ig,ilay)*z1(ig)
289         ENDDO
290      ENDDO
291
292      DO ig=1,ngrid
293         zu(ig,1)=zcv(ig,1)
294      ENDDO
295      DO ilay=2,nlay
296         DO ig=1,ngrid
297            zu(ig,ilay)=zcv(ig,ilay)+zdv(ig,ilay)*zu(ig,ilay-1)
298         ENDDO
299      ENDDO
300
301!-----------------------------------------------------------------------
302!     5. Implicit inversion of v
303!     --------------------------
304
305!     v(t+1) =  v(t) + dt * {(dv/dt)phys}(t)  +  dt * {(dv/dt)difv}(t+1)
306!     avec
307!     /zv/ = v(t) + dt * {(dv/dt)phys}(t)   (voir paragraphe 2.)
308!     et
309!     dt * {(dv/dt)difv}(t+1) = dt * {(d/dz)[ Kv (dv/dz) ]}(t+1)
310!     donc les entrees sont /zcdv/ pour la condition a la limite sol
311!     et /zkv/ = Kv
312
313      DO ig=1,ngrid
314         z1(ig)=1./(zmass(ig,nlay)+zfluxv(ig,nlay))
315         zcv(ig,nlay)=zmass(ig,nlay)*zv(ig,nlay)*z1(ig)
316         zdv(ig,nlay)=zfluxv(ig,nlay)*z1(ig)
317      ENDDO
318
319      DO ilay=nlay-1,1,-1
320         DO ig=1,ngrid
321            z1(ig)=1./(zmass(ig,ilay)+zfluxv(ig,ilay)+zfluxv(ig,ilay+1)*(1.-zdv(ig,ilay+1)))
322            zcv(ig,ilay)=(zmass(ig,ilay)*zv(ig,ilay)+zfluxv(ig,ilay+1)*zcv(ig,ilay+1))*z1(ig)
323            zdv(ig,ilay)=zfluxv(ig,ilay)*z1(ig)
324         ENDDO
325      ENDDO
326
327      DO ig=1,ngrid
328         zv(ig,1)=zcv(ig,1)
329      ENDDO
330      DO ilay=2,nlay
331         DO ig=1,ngrid
332            zv(ig,ilay)=zcv(ig,ilay)+zdv(ig,ilay)*zv(ig,ilay-1)
333         ENDDO
334      ENDDO
335
336
337
338!----------------------------------------------------------------------------
339!     6. Implicit inversion of h, not forgetting the coupling with the ground
340
341!     h(t+1) =  h(t) + dt * {(dh/dt)phys}(t)  +  dt * {(dh/dt)difv}(t+1)
342!     avec
343!     /zh/ = h(t) + dt * {(dh/dt)phys}(t)   (voir paragraphe 2.)
344!     et
345!     dt * {(dh/dt)difv}(t+1) = dt * {(d/dz)[ Kh (dh/dz) ]}(t+1)
346!     donc les entrees sont /zcdh/ pour la condition de raccord au sol
347!     et /zkh/ = Kh
348
349!     Using the wind modified by friction for lifting and sublimation
350!     ---------------------------------------------------------------
351      DO ig=1,ngrid
352         zu2      = zu(ig,1)*zu(ig,1)+zv(ig,1)*zv(ig,1)
353         zcdv(ig) = zcdv_true(ig)*sqrt(zu2)
354         zcdh(ig) = zcdh_true(ig)*sqrt(zu2)
355         zkh(ig,1)= zcdh(ig)
356      ENDDO
357
358!     JL12 calculate the flux coefficients (tables multiplied elements by elements)
359!     ---------------------------------------------------------------
360      zfluxq(1:ngridmx,1:nlayermx)=zkh(1:ngridmx,1:nlayermx)*zb0(1:ngridmx,1:nlayermx) !JL12 we save zfluxq which doesn't need the Exner factor
361      zfluxt(1:ngridmx,1:nlayermx)=zfluxq(1:ngridmx,1:nlayermx)*zExner(1:ngridmx,1:nlayermx)
362
363
364      DO ig=1,ngrid
365         z1(ig)=1./(zmass(ig,nlay)+zfluxt(ig,nlay)*zovExner(ig,nlay))
366         zct(ig,nlay)=zmass(ig,nlay)*zt(ig,nlay)*z1(ig)
367         zdt(ig,nlay)=zfluxt(ig,nlay)*zovExner(ig,nlay-1)*z1(ig)
368      ENDDO
369
370      DO ilay=nlay-1,2,-1
371         DO ig=1,ngrid
372            z1(ig)=1./(zmass(ig,ilay)+zfluxt(ig,ilay)*zovExner(ig,ilay)+   &
373            zfluxt(ig,ilay+1)*(zovExner(ig,ilay)-zdt(ig,ilay+1)*zovExner(ig,ilay+1)))
374            zct(ig,ilay)=(zmass(ig,ilay)*zt(ig,ilay)+zfluxt(ig,ilay+1)*zct(ig,ilay+1)*zovExner(ig,ilay+1))*z1(ig)
375            zdt(ig,ilay)=zfluxt(ig,ilay)*z1(ig)*zovExner(ig,ilay-1)
376         ENDDO
377      ENDDO
378
379!JL12 we treat last point afterward because zovExner(ig,ilay-1) does not exist there
380      DO ig=1,ngrid
381         z1(ig)=1./(zmass(ig,1)+zfluxt(ig,1)*zovExner(ig,1)+  &
382             zfluxt(ig,2)*(zovExner(ig,1)-zdt(ig,2)*zovExner(ig,2)))
383         zct(ig,1)=(zmass(ig,1)*zt(ig,1)+zfluxt(ig,2)*zct(ig,2)*zovExner(ig,2))*z1(ig)
384         zdt(ig,1)=zfluxt(ig,1)*z1(ig)
385      ENDDO
386
387
388!     Calculate (d Planck / dT) at the interface temperature
389!     ------------------------------------------------------
390
391      z4st=4.0*sigma*ptimestep
392      DO ig=1,ngrid
393         zdplanck(ig)=z4st*pemis(ig)*ptsrf(ig)*ptsrf(ig)*ptsrf(ig)
394      ENDDO
395
396!     Calculate temperature tendency at the interface (dry case)
397!     ----------------------------------------------------------
398!     Sum of fluxes at interface at time t + \delta t gives change in T:
399!       radiative fluxes
400!       turbulent convective (sensible) heat flux
401!       flux (if any) from subsurface
402
403      if(.not.water) then
404
405         DO ig=1,ngrid
406
407            z1(ig)=pcapcal(ig)*ptsrf(ig)+cpp*zfluxt(ig,1)*zct(ig,1)*zovExner(ig,1) &
408                + pfluxsrf(ig)*ptimestep + zdplanck(ig)*ptsrf(ig)
409            z2(ig) = pcapcal(ig)+zdplanck(ig)+cpp*zfluxt(ig,1)*(1.-zovExner(ig,1)*zdt(ig,1))
410            ztsrf(ig) = z1(ig) / z2(ig)
411            pdtsrf(ig) = (ztsrf(ig) - ptsrf(ig))/ptimestep
412            zt(ig,1)   = zct(ig,1) + zdt(ig,1)*ztsrf(ig)
413         ENDDO
414! JL12 note that the black body radiative flux emitted by the surface has been updated by the implicit scheme
415
416
417!     Recalculate temperature to top of atmosphere, starting from ground
418!     ------------------------------------------------------------------
419
420         DO ilay=2,nlay
421            DO ig=1,ngrid
422               zt(ig,ilay)=zct(ig,ilay)+zdt(ig,ilay)*zt(ig,ilay-1)
423            ENDDO
424         ENDDO
425
426      endif                     ! not water
427
428!-----------------------------------------------------------------------
429!     TRACERS (no vapour)
430!     -------
431
432      if(tracer) then
433
434!     Calculate vertical flux from the bottom to the first layer (dust)
435!     -----------------------------------------------------------------
436         do ig=1,ngridmx 
437            rho(ig) = zb0(ig,1) /ptimestep
438         end do
439
440         pdqsdif(:,:)=0.
441
442!     Implicit inversion of q
443!     -----------------------
444         do iq=1,nq
445
446            if (iq.ne.ivap) then
447
448               DO ig=1,ngrid
449                  z1(ig)=1./(zmass(ig,nlay)+zfluxq(ig,nlay))
450                  zcq(ig,nlay)=zmass(ig,nlay)*zq(ig,nlay,iq)*z1(ig)
451                  zdq(ig,nlay)=zfluxq(ig,nlay)*z1(ig)
452               ENDDO
453           
454               DO ilay=nlay-1,2,-1
455                  DO ig=1,ngrid
456                     z1(ig)=1./(zmass(ig,ilay)+zfluxq(ig,ilay)+zfluxq(ig,ilay+1)*(1.-zdq(ig,ilay+1)))
457                     zcq(ig,ilay)=(zmass(ig,ilay)*zq(ig,ilay,iq)+zfluxq(ig,ilay+1)*zcq(ig,ilay+1))*z1(ig)
458                     zdq(ig,ilay)=zfluxq(ig,ilay)*z1(ig)
459                  ENDDO
460               ENDDO
461
462               if ((water).and.(iq.eq.iliq)) then
463                  ! special case for condensed water tracer: do not include
464                  ! h2o ice tracer from surface (which is set when handling
465                  ! h2o vapour case (see further down).
466                  ! zb(ig,1)=0 if iq ne ivap
467                  DO ig=1,ngrid
468                     z1(ig)=1./(zmass(ig,1)+zfluxq(ig,2)*(1.-zdq(ig,2)))
469                     zcq(ig,1)=(zmass(ig,1)*zq(ig,1,iq)+zfluxq(ig,2)*zcq(ig,2))*z1(ig)
470                  ENDDO
471               else             ! general case
472                  DO ig=1,ngrid
473                     z1(ig)=1./(zmass(ig,1)+zfluxq(ig,2)*(1.-zdq(ig,2)))
474                     zcq(ig,1)=(zmass(ig,1)*zq(ig,1,iq)+zfluxq(ig,2)*zcq(ig,2)+(-pdqsdif(ig,iq))*ptimestep)*z1(ig)
475                          ! tracer flux from surface
476                          ! currently pdqsdif always zero here,
477                          ! so last line is superfluous
478                  enddo
479               endif            ! of if (water.and.(iq.eq.igcm_h2o_ice))
480
481
482!     Starting upward calculations for simple tracer mixing (e.g., dust)
483               do ig=1,ngrid
484                  zq(ig,1,iq)=zcq(ig,1)
485               end do
486
487               do ilay=2,nlay
488                  do ig=1,ngrid
489                     zq(ig,ilay,iq)=zcq(ig,ilay)+zdq(ig,ilay)*zq(ig,ilay-1,iq)
490                  end do
491               end do
492
493            endif               ! if (iq.ne.ivap)
494
495!     Calculate temperature tendency including latent heat term
496!     and assuming an infinite source of water on the ground
497!     ------------------------------------------------------------------
498
499            if (water.and.(iq.eq.ivap)) then
500           
501               ! compute evaporation efficiency
502               do ig = 1, ngrid
503                  if(rnat(ig).eq.1)then
504                     dryness(ig)=pqsurf(ig,iliq_surf)+pqsurf(ig,iice_surf)
505                     dryness(ig)=MIN(1.,2*dryness(ig)/mx_eau_sol)
506                     dryness(ig)=MAX(0.,dryness(ig))
507                  endif
508               enddo
509
510               do ig=1,ngrid
511
512                ! Calculate the value of qsat at the surface (water)
513                call Psat_water(ptsrf(ig),pplev(ig,1),psat(ig),qsat(ig))
514                call Psat_water(ptsrf(ig)-0.0001,pplev(ig,1),psat_temp,qsat_temp1)
515                call Psat_water(ptsrf(ig)+0.0001,pplev(ig,1),psat_temp,qsat_temp2)
516                dqsat(ig)=(qsat_temp2-qsat_temp1)/0.0002
517                ! calculate dQsat / dT by finite differences
518                ! we cannot use the updated temperature value yet...
519               enddo
520
521! coefficients for q
522
523               do ig=1,ngrid
524                  z1(ig)=1./(zmass(ig,nlay)+zfluxq(ig,nlay))
525                  zcq(ig,nlay)=zmass(ig,nlay)*zq(ig,nlay,iq)*z1(ig)
526                  zdq(ig,nlay)=zfluxq(ig,nlay)*z1(ig)
527               enddo
528           
529               do ilay=nlay-1,2,-1
530                  do ig=1,ngrid
531                     z1(ig)=1./(zmass(ig,ilay)+zfluxq(ig,ilay)+zfluxq(ig,ilay+1)*(1.-zdq(ig,ilay+1)))
532                     zcq(ig,ilay)=(zmass(ig,ilay)*zq(ig,ilay,iq)+zfluxq(ig,ilay+1)*zcq(ig,ilay+1))*z1(ig)
533                     zdq(ig,ilay)=zfluxq(ig,ilay)*z1(ig)
534                  enddo
535               enddo
536
537               do ig=1,ngrid
538                  z1(ig)=1./(zmass(ig,1)+zfluxq(ig,1)*dryness(ig)+zfluxq(ig,2)*(1.-zdq(ig,2)))
539                  zcq(ig,1)=(zmass(ig,1)*zq(ig,1,iq)+zfluxq(ig,2)*zcq(ig,2))*z1(ig)
540                  zdq(ig,1)=dryness(ig)*zfluxq(ig,1)*z1(ig)
541               enddo
542
543              do ig=1,ngrid
544!calculation of surface temperature
545                  zdq0(ig) = dqsat(ig)
546                  zcq0(ig) = qsat(ig)-dqsat(ig)*ptsrf(ig)
547
548                  z1(ig) = pcapcal(ig)*ptsrf(ig) +cpp*zfluxq(ig,1)*zct(ig,1)*zovExner(ig,1)   &
549                      + zdplanck(ig)*ptsrf(ig) + pfluxsrf(ig)*ptimestep                       &
550                      + zfluxq(ig,1)*dryness(ig)*RLVTT*((zdq(ig,1)-1.0)*zcq0(ig)+zcq(ig,1))
551
552                  z2(ig) = pcapcal(ig) + cpp*zfluxq(ig,1)*(1.-zovExner(ig,1)*zdt(ig,1))       &
553                      + zdplanck(ig)+zfluxq(ig,1)*dryness(ig)*RLVTT*zdq0(ig)*(1.0-zdq(ig,1))
554
555                  ztsrf(ig) = z1(ig) / z2(ig)
556
557! calculation of qs and q1
558                  zq0(ig)     = zcq0(ig)+zdq0(ig)*ztsrf(ig)
559                  zq(ig,1,iq) = zcq(ig,1)+zdq(ig,1)*zq0(ig)
560
561! calculation of evaporation             
562                  dqsdif_total(ig)=zfluxq(ig,1)*dryness(ig)*(zq(ig,1,ivap)-zq0(ig))
563
564!     --------------------------------------------------------
565!     Now check if we've taken too much water from the surface
566!     This can only occur on the continent
567!     If we do, we recompute Tsurf, T1 and q1 accordingly
568                  if((-dqsdif_total(ig).gt.(pqsurf(ig,iice_surf)+pqsurf(ig,iliq_surf))).and.rnat(ig).eq.1)then
569                      !water flux * ptimestep
570                      dqsdif_total(ig)=-(pqsurf(ig,iice_surf)+pqsurf(ig,iliq_surf))
571
572                      !recompute surface temperature 
573                      z1(ig) = pcapcal(ig)*ptsrf(ig) +cpp*zfluxq(ig,1)*zct(ig,1)*zovExner(ig,1)   &
574                        + zdplanck(ig)*ptsrf(ig) + pfluxsrf(ig)*ptimestep                       &
575                        + RLVTT*dqsdif_total(ig)
576                      z2(ig) = pcapcal(ig) + cpp*zfluxq(ig,1)*(1.-zovExner(ig,1)*zdt(ig,1))       &
577                        + zdplanck(ig)
578                      ztsrf(ig) = z1(ig) / z2(ig)
579
580                      !recompute q1 with new water flux from surface 
581                      zq(ig,1,iq) = (zmass(ig,1)*(pq(ig,1,iq)+ptimestep*pdqfi(ig,1,iq))  &
582                                            +zfluxq(ig,2)*zcq(ig,2)-dqsdif_total(ig))     &
583                                 / (zmass(ig,1)+(1.-zdq(ig,2))*zfluxq(ig,2))                 
584                  end if
585                 
586! calculation surface T tendency  and T(1)           
587                  pdtsrf(ig) = (ztsrf(ig) - ptsrf(ig))/ptimestep
588                  zt(ig,1)   = zct(ig,1) + zdt(ig,1)*ztsrf(ig)               
589               enddo
590
591
592! recalculate temperature and q(vap) to top of atmosphere, starting from ground
593               do ilay=2,nlay
594                  do ig=1,ngrid
595                     zq(ig,ilay,iq)=zcq(ig,ilay)+zdq(ig,ilay)*zq(ig,ilay-1,iq)
596                     zt(ig,ilay)=zct(ig,ilay)+zdt(ig,ilay)*zt(ig,ilay-1)
597                  end do
598               end do
599
600
601               do ig=1,ngrid
602!     --------------------------------------------------------------------------
603!     On the ocean, if T > 0 C then the vapour tendency must replace the ice one
604!     The surface vapour tracer is actually liquid. To make things difficult.
605
606                  if (rnat(ig).eq.0) then ! unfrozen ocean
607                     
608                     pdqsdif(ig,iliq_surf)=dqsdif_total(ig)/ptimestep
609                     pdqsdif(ig,iice_surf)=0.0
610
611                  elseif (rnat(ig).eq.1) then ! (continent)
612!     If water is evaporating / subliming, we take it from ice before liquid
613!     -- is this valid??
614                     if(dqsdif_total(ig).lt.0)then
615                        if (-dqsdif_total(ig).gt.pqsurf(ig,iice_surf))then
616                           pdqsdif(ig,iice_surf) = -pqsurf(ig,iice_surf)/ptimestep ! removes all the ice!
617                           pdqsdif(ig,iliq_surf) = dqsdif_total(ig)/ptimestep- pdqsdif(ig,iice_surf) ! take the remainder from the liquid instead
618                        else               
619                           pdqsdif(ig,iice_surf)=dqsdif_total(ig)/ptimestep
620                           pdqsdif(ig,iliq_surf)=0.
621                        end if
622                     else !dqsdif_total(ig).ge.0
623                        !If water vapour is condensing, we must decide whether it forms ice or liquid.
624                        if(ztsrf(ig).gt.T_h2O_ice_liq)then
625                           pdqsdif(ig,iice_surf)=0.0
626                           pdqsdif(ig,iliq_surf)=dqsdif_total(ig)/ptimestep
627                        else
628                           pdqsdif(ig,iice_surf)=dqsdif_total(ig)/ptimestep
629                           pdqsdif(ig,iliq_surf)=0.0
630                        endif               
631                     endif
632
633                  elseif (rnat(ig).eq.2) then ! (continental glaciers)
634                     pdqsdif(ig,iliq_surf)=0.0
635                     pdqsdif(ig,iice_surf)=dqsdif_total(ig)/ptimestep
636
637                  endif !rnat
638               end do            ! of DO ig=1,ngrid
639
640           endif                ! if (water et iq=ivap)
641        end do                  ! of do iq=1,nq
642
643        if (water) then  ! special case where we recompute water mixing without any evaporation.
644                         !    The difference with the first calculation then tells us where evaporated water has gone
645
646            DO ig=1,ngrid
647               z1(ig)=1./(zmass(ig,nlay)+zfluxq(ig,nlay))
648               zcq(ig,nlay)=zmass(ig,nlay)*zqnoevap(ig,nlay)*z1(ig)
649               zdq(ig,nlay)=zfluxq(ig,nlay)*z1(ig)
650            ENDDO
651           
652            DO ilay=nlay-1,2,-1
653               DO ig=1,ngrid
654                  z1(ig)=1./(zmass(ig,ilay)+zfluxq(ig,ilay)+zfluxq(ig,ilay+1)*(1.-zdq(ig,ilay+1)))
655                  zcq(ig,ilay)=(zmass(ig,ilay)*zqnoevap(ig,ilay)+zfluxq(ig,ilay+1)*zcq(ig,ilay+1))*z1(ig)
656                  zdq(ig,ilay)=zfluxq(ig,ilay)*z1(ig)
657               ENDDO
658            ENDDO
659
660            DO ig=1,ngrid
661               z1(ig)=1./(zmass(ig,1)+zfluxq(ig,2)*(1.-zdq(ig,2)))
662               zcq(ig,1)=(zmass(ig,1)*zqnoevap(ig,1)+zfluxq(ig,2)*zcq(ig,2))*z1(ig)
663            enddo
664
665!     Starting upward calculations for simple tracer mixing (e.g., dust)
666            do ig=1,ngrid
667               zqnoevap(ig,1)=zcq(ig,1)
668            end do
669
670            do ilay=2,nlay
671               do ig=1,ngrid
672                  zqnoevap(ig,ilay)=zcq(ig,ilay)+zdq(ig,ilay)*zqnoevap(ig,ilay-1)
673               end do
674            end do
675
676         endif               ! if water
677       
678       
679      endif                     ! tracer
680
681
682!-----------------------------------------------------------------------
683!     8. Final calculation of the vertical diffusion tendencies
684!     -----------------------------------------------------------------
685
686      do ilev = 1, nlay
687         do ig=1,ngrid
688            pdudif(ig,ilev)=(zu(ig,ilev)-(pu(ig,ilev)+pdufi(ig,ilev)*ptimestep))/ptimestep
689            pdvdif(ig,ilev)=(zv(ig,ilev)-(pv(ig,ilev)+pdvfi(ig,ilev)*ptimestep))/ptimestep
690            pdtdif(ig,ilev)=( zt(ig,ilev)- pt(ig,ilev))/ptimestep-pdtfi(ig,ilev)
691         enddo
692      enddo
693     
694      DO ig=1,ngrid  ! computing sensible heat flux (atm => surface)
695         sensibFlux(ig)=cpp*zfluxt(ig,1)/ptimestep*(zt(ig,1)*zovExner(ig,1)-ztsrf(ig))
696      ENDDO
697
698      if (tracer) then
699         do iq = 1, nq
700            do ilev = 1, nlay
701               do ig=1,ngrid
702                  pdqdif(ig,ilev,iq)=(zq(ig,ilev,iq)-(pq(ig,ilev,iq)+pdqfi(ig,ilev,iq)*ptimestep))/ptimestep
703               enddo
704            enddo
705         enddo
706         if (water) then
707            do ilev = 1, nlay
708               do ig=1,ngrid
709                  pdqevap(ig,ilev)=(zq(ig,ilev,ivap)-zqnoevap(ig,ilev))/ptimestep
710               enddo
711            enddo
712            do ig=1,ngrid
713               zdmassevap(ig)=SUM(pdqevap(ig,:)*zmass(ig,:))*ptimestep
714            end do         
715         endif
716      endif
717
718      if(water)then
719         call writediagfi(ngrid,'beta','Dryness coefficient',' ',2,dryness)
720         if (tracer) then
721            call writediagfi(ngrid,'dqevap','evaporated water vapor specific concentration','s-1',3,pdqevap)
722         endif
723      endif
724
725!      if(lastcall)then
726!        if(ngrid.eq.1)then
727!           print*,'Saving k.out...'
728!           OPEN(12,file='k.out',form='formatted')
729!           DO ilay=1,nlay
730!              write(12,*) zkh(1,ilay), pplay(1,ilay)
731!           ENDDO
732!           CLOSE(12)
733!         endif
734!      endif
735
736
737      return
738      end
Note: See TracBrowser for help on using the repository browser.