source: trunk/LMDZ.GENERIC/libf/phystd/callcorrk.F90 @ 305

Last change on this file since 305 was 305, checked in by rwordsworth, 13 years ago

Several new files added as part of the climate evolution model
(main program kcm.F90). Some general cleanup in physiq.F90 and
callcorrk.F90. Bugs in dust radiative transfer and H2 Rayleigh
scattering corrected.

  • Property svn:executable set to *
File size: 29.0 KB
Line 
1      subroutine callcorrk(ngrid,nlayer,pq,nq,qsurf,    &
2          albedo,emis,mu0,pplev,pplay,pt,                      &
3          tsurf,fract,dist_star,aerosol,cpp3D,muvar,           &
4          dtlw,dtsw,fluxsurf_lw,                               &
5          fluxsurf_sw,fluxtop_lw,fluxabs_sw,fluxtop_dn,        &
6          reffrad,tau_col,cloudfrac,totcloudfrac,   &
7          clearsky,firstcall,lastcall)
8
9
10      use radinc_h
11      use radcommon_h
12      use watercommon_h
13      use ioipsl_getincom
14
15      implicit none
16
17!==================================================================
18!
19!     Purpose
20!     -------
21!     Solve the radiative transfer using the correlated-k method for
22!     the gaseous absorption and the Toon et al. (1989) method for
23!     scatttering due to aerosols.
24!
25!     Authors
26!     -------
27!     Emmanuel 01/2001, Forget 09/2001
28!     Robin Wordsworth (2009)
29!
30!==================================================================
31
32#include "dimphys.h"
33#include "datafile.h"
34#include "comcstfi.h"
35#include "callkeys.h"
36#include "tracer.h"
37
38!-----------------------------------------------------------------------
39!     Declaration of the arguments (INPUT - OUTPUT) on the LMD GCM grid
40!     Layer #1 is the layer near the ground.
41!     Layer #nlayermx is the layer at the top.
42
43!     INPUT
44      INTEGER icount
45      INTEGER ngrid,nlayer
46      REAL aerosol(ngrid,nlayermx,naerkind) ! aerosol tau (kg/kg)
47      REAL albedo(ngrid)                    ! SW albedo
48      REAL emis(ngrid)                      ! LW emissivity
49      REAL pplay(ngrid,nlayermx)            ! pres. level in GCM mid of layer
50      REAL pplev(ngrid,nlayermx+1)          ! pres. level at GCM layer boundaries
51
52      REAL pt(ngrid,nlayermx)               ! air temperature (K)
53      REAL tsurf(ngrid)                     ! surface temperature (K)
54      REAL dist_star,mu0(ngrid)             ! distance star-planet (AU)
55      REAL fract(ngrid)                     ! fraction of day
56
57!     Globally varying aerosol optical properties on GCM grid
58!     Not needed everywhere so not in radcommon_h
59      REAL :: QVISsQREF3d(ngridmx,nlayermx,L_NSPECTV,naerkind)
60      REAL :: omegaVIS3d(ngridmx,nlayermx,L_NSPECTV,naerkind)
61      REAL :: gVIS3d(ngridmx,nlayermx,L_NSPECTV,naerkind)
62
63      REAL :: QIRsQREF3d(ngridmx,nlayermx,L_NSPECTI,naerkind)
64      REAL :: omegaIR3d(ngridmx,nlayermx,L_NSPECTI,naerkind)
65      REAL :: gIR3d(ngridmx,nlayermx,L_NSPECTI,naerkind)
66
67      REAL :: QREFvis3d(ngridmx,nlayermx,naerkind)
68      REAL :: QREFir3d(ngridmx,nlayermx,naerkind)
69
70!      REAL :: omegaREFvis3d(ngridmx,nlayermx,naerkind)
71!      REAL :: omegaREFir3d(ngridmx,nlayermx,naerkind) ! not sure of the point of these...
72
73      REAL reffrad(ngrid,nlayer,naerkind)
74      REAL nueffrad(ngrid,nlayer,naerkind)
75
76!     OUTPUT
77      REAL dtsw(ngridmx,nlayermx) ! heating rate (K/s) due to SW
78      REAL dtlw(ngridmx,nlayermx) ! heating rate (K/s) due to LW
79      REAL fluxsurf_lw(ngridmx)   ! incident LW flux to surf (W/m2)
80      REAL fluxtop_lw(ngridmx)    ! outgoing LW flux to space (W/m2)
81      REAL fluxsurf_sw(ngridmx)   ! incident SW flux to surf (W/m2)
82      REAL fluxabs_sw(ngridmx)    ! SW flux absorbed by planet (W/m2)
83      REAL fluxtop_dn(ngridmx)    ! incident top of atmosphere SW flux (W/m2)
84
85!-----------------------------------------------------------------------
86!     Declaration of the variables required by correlated-k subroutines
87!     Numbered from top to bottom unlike in the GCM!
88
89      REAL*8 tmid(L_LEVELS),pmid(L_LEVELS)
90      REAL*8 tlevrad(L_LEVELS),plevrad(L_LEVELS)
91
92!     Optical values for the optci/cv subroutines
93      REAL*8 stel(L_NSPECTV),stel_fract(L_NSPECTV)
94      REAL*8 dtaui(L_NLAYRAD,L_NSPECTI,L_NGAUSS)
95      REAL*8 dtauv(L_NLAYRAD,L_NSPECTV,L_NGAUSS)
96      REAL*8 cosbv(L_NLAYRAD,L_NSPECTV,L_NGAUSS)
97      REAL*8 cosbi(L_NLAYRAD,L_NSPECTI,L_NGAUSS)
98      REAL*8 wbari(L_NLAYRAD,L_NSPECTI,L_NGAUSS)
99      REAL*8 wbarv(L_NLAYRAD,L_NSPECTV,L_NGAUSS)
100      REAL*8 tauv(L_NLEVRAD,L_NSPECTV,L_NGAUSS)
101      REAL*8 taucumv(L_LEVELS,L_NSPECTV,L_NGAUSS)
102      REAL*8 taucumi(L_LEVELS,L_NSPECTI,L_NGAUSS)
103
104      REAL*8 tauaero(L_LEVELS+1,naerkind)
105      REAL*8 nfluxtopv,nfluxtopi,nfluxtop
106      real*8 NFLUXTOPV_nu(L_NSPECTV)
107      real*8 NFLUXTOPI_nu(L_NSPECTI)
108      real*8 fluxupi_nu(L_NLAYRAD,L_NSPECTI) ! for 1D diagnostic
109      REAL*8 fmneti(L_NLAYRAD),fmnetv(L_NLAYRAD)
110      REAL*8 fluxupv(L_NLAYRAD),fluxupi(L_NLAYRAD)
111      REAL*8 fluxdnv(L_NLAYRAD),fluxdni(L_NLAYRAD)
112      REAL*8 albi,albv,acosz
113
114      INTEGER ig,l,k,nw,iaer,irad
115
116      real fluxtoplanet
117      real*8 taugsurf(L_NSPECTV,L_NGAUSS-1)
118      real*8 taugsurfi(L_NSPECTI,L_NGAUSS-1)
119
120      real*8 qvar(L_LEVELS)          ! mixing ratio of variable component (mol/mol)
121      REAL pq(ngridmx,nlayer,nq)
122      REAL qsurf(ngridmx,nqmx)       ! tracer on surface (e.g. kg.m-2)
123      integer nq
124
125!     Local aerosol optical properties for each column on RADIATIVE grid
126      real*8  QXVAER(L_LEVELS+1,L_NSPECTV,naerkind)
127      real*8  QSVAER(L_LEVELS+1,L_NSPECTV,naerkind)
128      real*8  GVAER(L_LEVELS+1,L_NSPECTV,naerkind)
129      real*8  QXIAER(L_LEVELS+1,L_NSPECTI,naerkind)
130      real*8  QSIAER(L_LEVELS+1,L_NSPECTI,naerkind)
131      real*8  GIAER(L_LEVELS+1,L_NSPECTI,naerkind)
132
133      save qxvaer, qsvaer, gvaer
134      save qxiaer, qsiaer, giaer
135      save QREFvis3d, QREFir3d
136
137      REAL tau_col(ngrid) ! diagnostic from aeropacity
138
139!     Misc.
140      logical firstcall, lastcall, nantest
141      real*8  tempv(L_NSPECTV)
142      real*8  tempi(L_NSPECTI)
143      real*8  temp,temp1,temp2,pweight
144      character(len=10) :: tmp1
145      character(len=10) :: tmp2
146
147!     for fixed water vapour profiles
148      integer i_var
149      real RH
150      real*8 pq_temp(nlayer)
151      real ptemp, Ttemp, qsat
152
153!      real(KIND=r8) :: pq_temp(nlayer) ! better F90 way.. DOESNT PORT TO F77!!!
154
155!     for OLR spec
156      integer OLRcount
157      save OLRcount
158      integer OLRcount2
159      save OLRcount2
160      character(len=2)  :: tempOLR
161      character(len=30) :: filenomOLR
162      !real ptime, pday
163      logical OLRz
164      real OLR_nu(ngrid,L_NSPECTI)
165      real GSR_nu(ngrid,L_NSPECTV)
166      real*8 NFLUXGNDV_nu(L_NSPECTV)
167
168!     for H2O cloud fraction in aeropacity
169      real cloudfrac(ngridmx,nlayermx)
170      real totcloudfrac(ngridmx)
171      logical clearsky
172
173!     Allow variations in cp with location
174      real cpp3D(ngridmx,nlayermx)   ! specific heat capacity at const. pressure
175
176      ! for weird cloud test
177      real pqtest(ngridmx,nlayer,nq)
178
179!     are particle radii fixed?
180      logical radfixed
181      real maxrad, minrad
182
183      real CBRT
184      external CBRT
185
186!     included by RW for runway greenhouse 1D study
187      real muvar(ngridmx,nlayermx+1)
188      real vtmp(nlayermx)
189      REAL*8 muvarrad(L_LEVELS)
190
191      radfixed=.false.
192
193!=======================================================================
194!     Initialization on first call
195
196      qxvaer(:,:,:)=0.0
197      qsvaer(:,:,:)=0.0
198      gvaer(:,:,:) =0.0
199
200      qxiaer(:,:,:)=0.0
201      qsiaer(:,:,:)=0.0
202      giaer(:,:,:) =0.0
203
204      if(firstcall) then
205
206         call system('rm -f surf_vals_long.out')
207
208!--------------------------------------------------
209!     Effective radius and variance of the aerosols
210
211!     CO2 ice:
212         DO l=1,nlayer
213            DO ig=1,ngrid
214               reffrad(ig,l,1)  = 1.e-4
215               nueffrad(ig,l,1) = 0.1
216!     these values will change once the microphysics gets to work
217!     UNLESS tracer=.false., in which case we should be working with
218!     a fixed aerosol layer, and be able to define reffrad in a
219!     .def file. To be improved!
220            ENDDO
221         ENDDO
222
223!     H2O ice:
224         if(naerkind.eq.2)then
225            DO l=1,nlayer
226               DO ig=1,ngrid
227                  reffrad(ig,l,naerkind)  = 1.e-5
228                  nueffrad(ig,l,naerkind) = 0.1
229               ENDDO 
230            ENDDO
231         endif
232
233         print*, "Correlated-k data base folder:",datafile
234         call getin("corrkdir",corrkdir)
235         print*, "corrkdir = ",corrkdir
236         write( tmp1, '(i3)' ) L_NSPECTI
237         write( tmp2, '(i3)' ) L_NSPECTV
238         banddir=trim(adjustl(tmp1))//'x'//trim(adjustl(tmp2))
239         banddir=trim(adjustl(corrkdir))//'/'//trim(adjustl(banddir))
240
241         call sugas_corrk       ! set up gaseous absorption properties
242         call setspi            ! basic infrared properties
243         call setspv            ! basic visible properties
244         call suaer_corrk       ! set up aerosol optical properties
245
246         Cmk= 0.01 * 1.0 / (g * mugaz * 1.672621e-27) ! q_main=1.0 assumed
247
248
249         if((igcm_h2o_vap.eq.0) .and. varactive)then
250            print*,'varactive in callcorrk but no h2o_vap tracer.'
251            stop
252         endif
253
254         firstcall=.false.   
255
256      end if
257
258!=======================================================================
259!     Initialization on every call   
260
261      do l=1,nlayer
262         do ig=1,ngrid
263            do iaer=1,naerkind
264               nueffrad(ig,l,iaer) = 0.1 ! stays at 0.1
265            enddo
266         enddo
267      enddo
268
269
270      if(kastprof)then
271         radfixed=.true.
272      endif
273
274      if(radfixed)then
275         do l=1,nlayer
276            do ig=1,ngrid
277               reffrad(ig,l,1)    = 5.e-5 ! CO2 ice
278            enddo
279         enddo
280         print*,'CO2 ice particle size = ',reffrad(1,1,1)/1.e-6,' um'
281         if(naerkind.ge.2)then
282            do l=1,nlayer
283               do ig=1,ngrid
284                  !reffrad(ig,l,2) = 2.e-5 ! H2O ice
285                  reffrad(ig,l,2) = 5.e-6 ! H2O ice
286               enddo
287            enddo
288            print*,'H2O ice particle size = ',reffrad(1,1,2)/1.e-6,' um'
289         endif
290         if(naerkind.eq.3)then
291            do l=1,nlayer
292               do ig=1,ngrid
293                  reffrad(ig,l,naerkind) = 2.e-6 ! dust
294               enddo
295            enddo
296            print*,'Dust particle size = ',reffrad(1,1,naerkind)/1.e-6,' um'
297         endif
298         if(naerkind.gt.3)then
299            print*,'Code not general enough to deal with naerkind > 3 yet.'
300            call abort
301         endif
302
303      else
304
305         maxrad=0.0
306         !averad=0.0
307         minrad=1.0
308         do l=1,nlayer
309
310            !masse = (pplev(ig,l) - pplev(ig,l+1))/g
311
312            do ig=1,ngrid
313               if(tracer)then
314                  reffrad(ig,l,1) = CBRT( 3*pq(ig,l,igcm_co2_ice)/ &
315                       (4*Nmix_co2*pi*rho_co2) )
316               endif
317               reffrad(ig,l,1) = max(reffrad(ig,l,1),1.e-6)
318               reffrad(ig,l,1) = min(reffrad(ig,l,1),500.e-6)
319
320               !averad = averad + reffrad(ig,l,1)*area(ig)
321               maxrad = max(reffrad(ig,l,1),maxrad)
322               minrad = min(reffrad(ig,l,1),minrad)
323            enddo
324         enddo
325         if(igcm_co2_ice.gt.0)then
326            print*,'Max. CO2 ice particle size = ',maxrad/1.e-6,' um'
327            print*,'Min. CO2 ice particle size = ',minrad/1.e-6,' um'
328         endif
329
330         if((naerkind.ge.2).and.water)then
331            maxrad=0.0
332            minrad=1.0
333            do l=1,nlayer
334               do ig=1,ngrid
335                  reffrad(ig,l,2) = CBRT( 3*pq(ig,l,igcm_h2o_ice)/ &
336                       (4*Nmix_h2o*pi*rho_ice) )
337                  reffrad(ig,l,2) = max(reffrad(ig,l,2),1.e-6)
338                  reffrad(ig,l,2) = min(reffrad(ig,l,2),100.e-6)
339
340                  maxrad = max(reffrad(ig,l,2),maxrad)
341                  minrad = min(reffrad(ig,l,2),minrad)
342               enddo
343            enddo
344            print*,'Max. H2O ice particle size = ',maxrad/1.e-6,' um'
345            print*,'Min. H2O ice particle size = ',minrad/1.e-6,' um'
346         endif
347
348         if(naerkind.eq.3)then
349            do l=1,nlayer
350               do ig=1,ngrid
351                  reffrad(ig,l,naerkind) = 2.e-6 ! dust
352               enddo
353            enddo
354         endif
355
356      endif
357
358
359!     how much light we get
360      fluxtoplanet=0
361      do nw=1,L_NSPECTV
362         stel(nw)=stellarf(nw)/(dist_star**2)
363         fluxtoplanet=fluxtoplanet + stel(nw)
364      end do
365
366      call aeroptproperties(ngrid,nlayer,reffrad,nueffrad,         &
367           QVISsQREF3d,omegaVIS3d,gVIS3d,                          &
368           QIRsQREF3d,omegaIR3d,gIR3d,                             &
369           QREFvis3d,QREFir3d)                                     ! get 3D aerosol optical properties
370
371      call aeropacity(ngrid,nlayer,nq,pplay,pplev,pq,aerosol,      &
372           reffrad,QREFvis3d,QREFir3d,                             &
373           tau_col,cloudfrac,totcloudfrac,clearsky)                ! get aerosol optical depths
374
375
376!-----------------------------------------------------------------------
377!     Starting Big Loop over every GCM column
378      do ig=1,ngridmx
379
380!=======================================================================
381!     Transformation of the GCM variables
382
383!-----------------------------------------------------------------------
384!     Aerosol optical properties Qext, Qscat and g
385!     The transformation in the vertical is the same as for temperature
386           
387!     shortwave
388            do iaer=1,naerkind
389               DO nw=1,L_NSPECTV
390                  do l=1,nlayermx
391
392                     temp1=QVISsQREF3d(ig,nlayermx+1-l,nw,iaer)         &
393                         *QREFvis3d(ig,nlayermx+1-l,iaer)
394
395                     temp2=QVISsQREF3d(ig,max(nlayermx-l,1),nw,iaer)    &
396                         *QREFvis3d(ig,max(nlayermx-l,1),iaer)
397
398                     qxvaer(2*l,nw,iaer)  = temp1
399                     qxvaer(2*l+1,nw,iaer)=(temp1+temp2)/2
400
401                     temp1=temp1*omegavis3d(ig,nlayermx+1-l,nw,iaer)
402                     temp2=temp2*omegavis3d(ig,max(nlayermx-l,1),nw,iaer)
403
404                     qsvaer(2*l,nw,iaer)  = temp1
405                     qsvaer(2*l+1,nw,iaer)=(temp1+temp2)/2
406
407                     temp1=gvis3d(ig,nlayermx+1-l,nw,iaer)
408                     temp2=gvis3d(ig,max(nlayermx-l,1),nw,iaer)
409
410                     gvaer(2*l,nw,iaer)  = temp1
411                     gvaer(2*l+1,nw,iaer)=(temp1+temp2)/2
412
413                  end do
414
415                  qxvaer(1,nw,iaer)=qxvaer(2,nw,iaer)
416                  qxvaer(2*nlayermx+1,nw,iaer)=0.
417
418                  qsvaer(1,nw,iaer)=qsvaer(2,nw,iaer)
419                  qsvaer(2*nlayermx+1,nw,iaer)=0.
420
421                  gvaer(1,nw,iaer)=gvaer(2,nw,iaer)
422                  gvaer(2*nlayermx+1,nw,iaer)=0.
423
424               end do
425
426
427!     longwave
428               DO nw=1,L_NSPECTI
429                  do l=1,nlayermx
430
431                     temp1=QIRsQREF3d(ig,nlayermx+1-l,nw,iaer)         &
432                          *QREFir3d(ig,nlayermx+1-l,iaer)
433
434                     temp2=QIRsQREF3d(ig,max(nlayermx-l,1),nw,iaer)    &
435                          *QREFir3d(ig,max(nlayermx-l,1),iaer)
436
437                     qxiaer(2*l,nw,iaer)  = temp1
438                     qxiaer(2*l+1,nw,iaer)=(temp1+temp2)/2
439
440                     temp1=temp1*omegair3d(ig,nlayermx+1-l,nw,iaer)
441                     temp2=temp2*omegair3d(ig,max(nlayermx-l,1),nw,iaer)
442
443                     qsiaer(2*l,nw,iaer)  = temp1
444                     qsiaer(2*l+1,nw,iaer)=(temp1+temp2)/2
445
446                     temp1=gir3d(ig,nlayermx+1-l,nw,iaer)
447                     temp2=gir3d(ig,max(nlayermx-l,1),nw,iaer)
448
449                     giaer(2*l,nw,iaer)  = temp1
450                     giaer(2*l+1,nw,iaer)=(temp1+temp2)/2
451
452                  end do
453
454                  qxiaer(1,nw,iaer)=qxiaer(2,nw,iaer)
455                  qxiaer(2*nlayermx+1,nw,iaer)=0.
456
457                  qsiaer(1,nw,iaer)=qsiaer(2,nw,iaer)
458                  qsiaer(2*nlayermx+1,nw,iaer)=0.
459
460                  giaer(1,nw,iaer)=giaer(2,nw,iaer)
461                  giaer(2*nlayermx+1,nw,iaer)=0.
462
463               end do
464            end do
465
466
467            ! test / correct for freaky s. s. albedo values
468            do iaer=1,naerkind
469               do k=1,L_LEVELS+1
470
471                  do nw=1,L_NSPECTV
472                     if(qsvaer(k,nw,iaer).gt.1.05*qxvaer(k,nw,iaer))then
473                        print*,'Serious problems with qsvaer values in callcorrk'
474                        call abort
475                     endif
476                     if(qsvaer(k,nw,iaer).gt.qxvaer(k,nw,iaer))then
477                        qsvaer(k,nw,iaer)=qxvaer(k,nw,iaer)
478                     endif
479                  end do
480
481                  do nw=1,L_NSPECTI
482                     if(qsiaer(k,nw,iaer).gt.1.05*qxiaer(k,nw,iaer))then
483                        print*,'Serious problems with qsiaer values in callcorrk'
484                        call abort
485                     endif
486                     if(qsiaer(k,nw,iaer).gt.qxiaer(k,nw,iaer))then
487                        qsiaer(k,nw,iaer)=qxiaer(k,nw,iaer)
488                     endif
489                  end do
490
491               end do
492            end do
493
494!-----------------------------------------------------------------------
495!     Aerosol optical depths
496           
497         do iaer=1,naerkind     ! a bug was here           
498            do k=0,nlayer-1
499               
500               pweight=(pplay(ig,L_NLAYRAD-k)-pplev(ig,L_NLAYRAD-k+1))/   &
501                        (pplev(ig,L_NLAYRAD-k)-pplev(ig,L_NLAYRAD-k+1))
502
503               temp=aerosol(ig,L_NLAYRAD-k,iaer)/QREFvis3d(ig,L_NLAYRAD-k,iaer)
504
505               tauaero(2*k+2,iaer)=max(temp*pweight,0.0)
506               tauaero(2*k+3,iaer)=max(temp-tauaero(2*k+2,iaer),0.0)
507!
508            end do
509            ! boundary conditions
510            tauaero(1,iaer)          = tauaero(2,iaer)
511            tauaero(L_LEVELS+1,iaer) = tauaero(L_LEVELS,iaer)
512            !tauaero(1,iaer)          = 0.
513            !tauaero(L_LEVELS+1,iaer) = 0.
514         end do
515         !print*,'Note changed tauaero BCs in callcorrk!'
516
517!     Albedo and emissivity
518         albi=1-emis(ig)        ! longwave
519         albv=albedo(ig)        ! shortwave
520
521      if(noradsurf.and.(albv.gt.0.0))then
522         print*,'For open lower boundary in callcorrk must'
523         print*,'have surface albedo set to zero!'
524         call abort
525      endif
526
527      if(ngridmx.eq.1) then       ! fixed zenith angle 'szangle' in 1D
528         acosz = cos(pi*szangle/180.0)
529         print*,'acosz=',acosz,', szangle=',szangle
530      else
531         acosz=mu0(ig)          ! cosine of sun incident angle
532      endif
533
534
535!-----------------------------------------------------------------------
536!     Water vapour (to be generalised for other gases eventually)
537     
538      if(varactive)then
539
540         i_var=igcm_h2o_vap
541         do l=1,nlayer
542            qvar(2*l)   = pq(ig,nlayer+1-l,i_var)
543            qvar(2*l+1) = (pq(ig,nlayer+1-l,i_var)+pq(ig,max(nlayer-l,1),i_var))/2   
544            ! Average approximation as for temperature...
545         end do
546         qvar(1)=qvar(2)
547         qvar(2*nlayermx+1)=qsurf(ig,i_var)
548
549      elseif(varfixed)then
550
551         do l=1,nlayermx        ! here we will assign fixed water vapour profiles globally
552            RH = satval * ((pplay(ig,l)/pplev(ig,1) - 0.02) / 0.98)
553            if(RH.lt.0.0) RH=0.0
554           
555            ptemp=pplay(ig,l)
556            Ttemp=pt(ig,l)
557            call watersat(Ttemp,ptemp,qsat)
558
559            !pq_temp(l) = qsat      ! fully saturated everywhere
560            pq_temp(l) = RH * qsat ! ~realistic profile (e.g. 80% saturation at ground)
561         end do
562         
563         do l=1,nlayer
564            qvar(2*l)   = pq_temp(nlayer+1-l)
565            qvar(2*l+1) = (pq_temp(nlayer+1-l)+pq_temp(max(nlayer-l,1)))/2
566         end do
567         qvar(1)=qvar(2)
568
569         ! Lowest layer of atmosphere
570         RH = satval * (1 - 0.02) / 0.98
571         if(RH.lt.0.0) RH=0.0
572
573         ptemp = pplev(ig,1)
574         Ttemp = tsurf(ig)
575         call watersat(Ttemp,ptemp,qsat)
576
577         !qvar(2*nlayermx+1)=qsat      ! fully saturated everywhere
578         qvar(2*nlayermx+1)= RH * qsat ! ~realistic profile (e.g. 80% saturation at ground)
579
580      else
581         do k=1,L_LEVELS
582            qvar(k) = 1.0D-7
583         end do
584      end if
585
586      ! IMPORTANT: Now convert from kg/kg to mol/mol
587      do k=1,L_LEVELS
588         qvar(k) = qvar(k)/epsi
589      end do
590
591      if(kastprof)then
592
593         DO l=1,nlayer
594            muvarrad(2*l)   = muvar(ig,nlayer+2-l)
595            muvarrad(2*l+1) = (muvar(ig,nlayer+2-l) + &
596                                muvar(ig,max(nlayer+1-l,1)))/2
597         END DO
598     
599         muvarrad(1) = muvarrad(2)
600         muvarrad(2*nlayermx+1)=muvar(ig,1)
601
602         print*,'Recalculating qvar with VARIABLE epsi for kastprof'
603         i_var=igcm_h2o_vap
604         do l=1,nlayer
605            vtmp(l)=pq(ig,l,i_var)*muvar(ig,l+1)/mH2O
606         end do
607
608         do l=1,nlayer
609            qvar(2*l)   = vtmp(nlayer+1-l)
610            qvar(2*l+1) = ( vtmp(nlayer+1-l) + vtmp(max(nlayer-l,1)) )/2
611         end do
612         qvar(1)=qvar(2)
613         qvar(2*nlayermx+1)=qsurf(ig,i_var)*muvar(ig,1)/mH2O
614
615         !do k=1,L_LEVELS
616         !   qvar(k) = 1.0
617         !end do
618         !print*,'ASSUMING qH2O=1 EVERYWHERE IN CALLCORRK!!'
619
620      endif
621
622      ! Keep values inside limits for which we have radiative transfer coefficients
623      if(L_REFVAR.gt.1)then ! there was a bug here!
624         do k=1,L_LEVELS
625            if(qvar(k).lt.wrefvar(1))then
626               qvar(k)=wrefvar(1)+1.0e-8
627            elseif(qvar(k).gt.wrefvar(L_REFVAR))then
628               qvar(k)=wrefvar(L_REFVAR)-1.0e-8
629            endif
630         end do
631      endif
632
633!-----------------------------------------------------------------------
634!     Pressure and temperature
635
636      DO l=1,nlayer
637         plevrad(2*l)   = pplay(ig,nlayer+1-l)/scalep
638         plevrad(2*l+1) = pplev(ig,nlayer+1-l)/scalep
639         tlevrad(2*l)   = pt(ig,nlayer+1-l)
640         tlevrad(2*l+1) = (pt(ig,nlayer+1-l)+pt(ig,max(nlayer-l,1)))/2
641      END DO
642     
643      plevrad(1) = 0
644      plevrad(2) = max(pgasmin,0.0001*plevrad(3))
645
646      tlevrad(1) = tlevrad(2)
647      tlevrad(2*nlayermx+1)=tsurf(ig)
648     
649      tmid(1) = tlevrad(2)
650      tmid(2) = tlevrad(2)
651      pmid(1) = plevrad(2)
652      pmid(2) = plevrad(2)
653     
654      DO l=1,L_NLAYRAD-1
655         tmid(2*l+1) = tlevrad(2*l+1)
656         tmid(2*l+2) = tlevrad(2*l+1)
657         pmid(2*l+1) = plevrad(2*l+1)
658         pmid(2*l+2) = plevrad(2*l+1)
659      END DO
660      pmid(L_LEVELS) = plevrad(L_LEVELS)
661      tmid(L_LEVELS) = tlevrad(L_LEVELS)
662
663
664      ! test for out-of-bounds pressure
665      if(plevrad(3).lt.pgasmin)then
666         print*,'Minimum pressure is outside the radiative'
667         print*,'transfer kmatrix bounds, exiting.'
668         call abort
669      elseif(plevrad(L_LEVELS).gt.pgasmax)then
670         print*,'Maximum pressure is outside the radiative'
671         print*,'transfer kmatrix bounds, exiting.'
672         call abort
673      endif
674
675      ! test for out-of-bounds temperature
676      do k=1,L_LEVELS
677         if(tlevrad(k).lt.tgasmin)then
678            print*,'Minimum temperature is outside the radiative'
679            print*,'transfer kmatrix bounds, exiting.'
680            print*,'WARNING, OVERRIDING FOR TEST'
681            !call abort
682         elseif(tlevrad(k).gt.tgasmax)then
683            print*,'Maximum temperature is outside the radiative'
684            print*,'transfer kmatrix bounds, exiting.'
685            print*,'WARNING, OVERRIDING FOR TEST'
686            !print*, 'T=',pt
687            !call abort
688         endif
689      enddo
690
691!=======================================================================
692!     Calling the main radiative transfer subroutines
693
694
695!-----------------------------------------------------------------------
696!     Shortwave
697
698         if(fract(ig) .ge. 1.0e-4) then ! only during daylight!
699
700            fluxtoplanet=0.
701
702            if((ngridmx.eq.1).and.(.not.(diurnal.or.tlocked)))then
703               do nw=1,L_NSPECTV
704                  stel_fract(nw)= stel(nw) * 0.25 / acosz
705                  fluxtoplanet=fluxtoplanet + stel_fract(nw)
706                                ! globally averaged = divide by 4
707                                ! but we correct for solar zenith angle
708               end do
709            else
710               do nw=1,L_NSPECTV
711                  stel_fract(nw)= stel(nw) * fract(ig)
712                  fluxtoplanet=fluxtoplanet + stel_fract(nw)
713               end do
714            endif
715
716            call optcv(dtauv,tauv,taucumv,plevrad,                 &
717                 qxvaer,qsvaer,gvaer,wbarv,cosbv,tauray,tauaero,   &
718                 tmid,pmid,taugsurf,qvar,muvarrad)
719
720
721            call sfluxv(dtauv,tauv,taucumv,albv,dwnv,wbarv,cosbv,  &
722                 acosz,stel_fract,gweight,nfluxtopv,nfluxgndv_nu,  &
723                 fmnetv,fluxupv,fluxdnv,fzerov,taugsurf)
724
725         else                          ! during the night, fluxes = 0
726            nfluxtopv=0.0
727            do l=1,L_NLAYRAD
728               fmnetv(l)=0.0
729               fluxupv(l)=0.0
730               fluxdnv(l)=0.0
731            end do
732         end if
733
734
735
736
737!-----------------------------------------------------------------------
738!     Longwave
739
740         call optci(plevrad,tlevrad,dtaui,taucumi,                  &
741              qxiaer,qsiaer,giaer,cosbi,wbari,tauaero,tmid,pmid,    &
742              taugsurfi,qvar,muvarrad)
743
744         call sfluxi(plevrad,tlevrad,dtaui,taucumi,ubari,albi,      &
745              wnoi,dwni,cosbi,wbari,gweight,nfluxtopi,nfluxtopi_nu, &
746              fmneti,fluxupi,fluxdni,fluxupi_nu,fzeroi,taugsurfi)
747
748!-----------------------------------------------------------------------
749!     Transformation of the correlated-k code outputs
750!     (into dtlw, dtsw, fluxsurf_lw, fluxsurf_sw, fluxtop_lw, fluxtop_sw)
751
752!     Flux incident at the top of the atmosphere
753         fluxtop_dn(ig)=fluxdnv(1)
754
755         fluxtop_lw(ig)  = real(nfluxtopi)
756         fluxabs_sw(ig)  = real(-nfluxtopv)
757         fluxsurf_lw(ig) = real(fluxdni(L_NLAYRAD))
758         fluxsurf_sw(ig) = real(fluxdnv(L_NLAYRAD))
759
760
761         if(fluxtop_dn(ig).lt.0.0)then
762            print*,'Achtung! fluxtop_dn has lost the plot!'
763            print*,'fluxtop_dn=',fluxtop_dn(ig)
764            print*,'acosz=',acosz
765            print*,'aerosol=',aerosol(ig,:,:)
766            print*,'temp=   ',pt(ig,:)
767            print*,'pplay=  ',pplay(ig,:)
768            call abort
769         endif
770
771!     Spectral output, for exoplanet observational comparison
772         if(specOLR)then
773            do nw=1,L_NSPECTI
774               OLR_nu(ig,nw)=nfluxtopi_nu(nw)
775            end do
776            do nw=1,L_NSPECTV
777               GSR_nu(ig,nw)=nfluxgndv_nu(nw)
778            end do
779         endif
780
781!     Finally, the heating rates
782         if(nonideal)then
783
784            DO l=2,L_NLAYRAD
785               dtsw(ig,L_NLAYRAD+1-l)=(fmnetv(l)-fmnetv(l-1))  &
786                    *g/(cpp3D(ig,L_NLAYRAD+1-l)                &
787                    *scalep*(plevrad(2*l+1)-plevrad(2*l-1)))
788               dtlw(ig,L_NLAYRAD+1-l)=(fmneti(l)-fmneti(l-1))  &
789                    *g/(cpp3D(ig,L_NLAYRAD+1-l)                &
790                    *scalep*(plevrad(2*l+1)-plevrad(2*l-1)))           
791            END DO     
792
793!     These are values at top of atmosphere
794            dtsw(ig,L_NLAYRAD)=(fmnetv(1)-nfluxtopv)           &
795                 *g/(cpp3D(ig,L_NLAYRAD)*scalep*(plevrad(3)-plevrad(1)))
796            dtlw(ig,L_NLAYRAD)=(fmneti(1)-nfluxtopi)           &
797                 *g/(cpp3D(ig,L_NLAYRAD)*scalep*(plevrad(3)-plevrad(1)))
798
799         else
800
801            DO l=2,L_NLAYRAD
802               dtsw(ig,L_NLAYRAD+1-l)=(fmnetv(l)-fmnetv(l-1))  &
803                   *g/(cpp*scalep*(plevrad(2*l+1)-plevrad(2*l-1)))
804               dtlw(ig,L_NLAYRAD+1-l)=(fmneti(l)-fmneti(l-1))  &
805                   *g/(cpp*scalep*(plevrad(2*l+1)-plevrad(2*l-1)))
806            END DO     
807
808!     These are values at top of atmosphere
809            dtsw(ig,L_NLAYRAD)=(fmnetv(1)-nfluxtopv)           &
810                *g/(cpp*scalep*(plevrad(3)-plevrad(1)))
811            dtlw(ig,L_NLAYRAD)=(fmneti(1)-nfluxtopi)           &
812                *g/(cpp*scalep*(plevrad(3)-plevrad(1)))
813
814         endif
815
816!     ---------------------------------------------------------------
817      end do                    ! end of big loop over every GCM column (ig = 1:ngrid)
818
819
820!-----------------------------------------------------------------------
821!     Additional diagnostics
822
823!     IR spectral output, for exoplanet observational comparison
824      if(specOLR)then
825        if(ngrid.ne.1)then
826          call writediagspecIR(ngrid,"OLR3D","OLR(lon,lat,band)","W m^-2",3,OLR_nu)
827          call writediagspecVI(ngrid,"GSR3D","GSR(lon,lat,band)","W m^-2",3,GSR_nu)
828        endif
829      endif
830
831      if(lastcall.and.(ngrid.eq.1))then
832
833           print*,'Saving scalar quantities in surf_vals.out...'
834           print*,'psurf = ', pplev(1,1),' Pa'
835           open(116,file='surf_vals.out')
836           write(116,*) tsurf(1),pplev(1,1),fluxtop_dn(1),         &
837                real(-nfluxtopv),real(nfluxtopi)
838           close(116)
839
840           if(specOLR)then
841               open(117,file='OLRnu.out')
842               do nw=1,L_NSPECTI
843                  write(117,*) OLR_nu(1,nw)
844               enddo
845               close(117)
846
847               open(127,file='GSRnu.out')
848               do nw=1,L_NSPECTV
849                  write(127,*) GSR_nu(1,nw)
850               enddo
851               close(127)
852           endif
853
854!     OLR vs altitude: do it as a .txt file
855           OLRz=.false.
856           if(OLRz)then
857              print*,'saving IR vertical flux for OLRz...'
858              open(118,file='OLRz_plevs.out')
859              open(119,file='OLRz.out')
860              do l=1,L_NLAYRAD
861                 write(118,*) plevrad(2*l)
862                 do nw=1,L_NSPECTI
863                     write(119,*) fluxupi_nu(l,nw)
864                  enddo
865              enddo
866              close(118)
867              close(119)
868           endif
869
870      endif
871
872    end subroutine callcorrk
Note: See TracBrowser for help on using the repository browser.