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

Last change on this file since 253 was 253, checked in by emillour, 13 years ago

Generic GCM

  • Massive update to version 0.7

EM+RW

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