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

Last change on this file since 1482 was 1482, checked in by mturbet, 9 years ago

Implementation of the Spectral Albedo

  • Property svn:executable set to *
File size: 35.1 KB
Line 
1      subroutine callcorrk(ngrid,nlayer,pq,nq,qsurf,           &
2          albedo,albedo_equivalent,emis,mu0,pplev,pplay,pt,    &
3          tsurf,fract,dist_star,aerosol,muvar,                 &
4          dtlw,dtsw,fluxsurf_lw,                               &
5          fluxsurf_sw,fluxsurfabs_sw,fluxtop_lw,               &
6          fluxabs_sw,fluxtop_dn,                               &
7          OLR_nu,OSR_nu,                                       &
8          tau_col,cloudfrac,totcloudfrac,                      &
9          clearsky,firstcall,lastcall)
10
11      use radinc_h
12      use radcommon_h
13      use watercommon_h
14      use datafile_mod, only: datadir
15!      use ioipsl_getincom
16      use ioipsl_getincom_p
17      use gases_h
18      use radii_mod, only : su_aer_radii,co2_reffrad,h2o_reffrad,dust_reffrad,h2so4_reffrad,back2lay_reffrad
19      use aerosol_mod, only : iaero_co2,iaero_h2o,iaero_dust,iaero_h2so4, iaero_back2lay
20      USE tracer_h
21      use comcstfi_mod, only: pi, mugaz, cpp
22      use callkeys_mod, only: varactive,diurnal,tracer,water,nosurf,varfixed,satval,    &
23                kastprof,strictboundcorrk,specOLR,CLFvarying
24
25      implicit none
26
27!==================================================================
28!
29!     Purpose
30!     -------
31!     Solve the radiative transfer using the correlated-k method for
32!     the gaseous absorption and the Toon et al. (1989) method for
33!     scatttering due to aerosols.
34!
35!     Authors
36!     -------
37!     Emmanuel 01/2001, Forget 09/2001
38!     Robin Wordsworth (2009)
39!
40!==================================================================
41
42!-----------------------------------------------------------------------
43!     Declaration of the arguments (INPUT - OUTPUT) on the LMD GCM grid
44!     Layer #1 is the layer near the ground.
45!     Layer #nlayer is the layer at the top.
46
47      INTEGER,INTENT(IN) :: ngrid ! number of atmospheric columns
48      INTEGER,INTENT(IN) :: nlayer ! number of atmospheric layers
49      REAL,INTENT(IN) :: pq(ngrid,nlayer,nq) ! tracers (.../kg_of_air)
50      integer,intent(in) :: nq ! number of tracers
51      REAL,INTENT(IN) :: qsurf(ngrid,nq) ! tracer on surface (kg.m-2)
52      REAL,INTENT(IN) :: albedo(ngrid,L_NSPECTV)   ! Spectral SW albedo.MT2015.
53      REAL,INTENT(IN) :: emis(ngrid)     ! LW emissivity
54      real,intent(in) :: mu0(ngrid) ! cosine of sun incident angle
55      REAL,INTENT(IN) :: pplev(ngrid,nlayer+1)  ! inter-layer pressure (Pa)
56      REAL,INTENT(IN) :: pplay(ngrid,nlayer)    ! mid-layer pressure (Pa)
57      REAL,INTENT(IN) :: pt(ngrid,nlayer)  ! air temperature (K)
58      REAL,INTENT(IN) :: tsurf(ngrid)        ! surface temperature (K)
59      REAL,INTENT(IN) :: fract(ngrid)        ! fraction of day
60      REAL,INTENT(IN) :: dist_star           ! distance star-planet (AU)
61      REAL,INTENT(OUT) :: aerosol(ngrid,nlayer,naerkind) ! aerosol tau (kg/kg)
62      real,intent(in) :: muvar(ngrid,nlayer+1)
63      REAL,INTENT(OUT) :: dtlw(ngrid,nlayer) ! heating rate (K/s) due to LW
64      REAL,INTENT(OUT) :: dtsw(ngrid,nlayer) ! heating rate (K/s) due to SW
65      REAL,INTENT(OUT) :: fluxsurf_lw(ngrid)   ! incident LW flux to surf (W/m2)
66      REAL,INTENT(OUT) :: fluxsurf_sw(ngrid)   ! incident SW flux to surf (W/m2)
67      REAL,INTENT(OUT) :: fluxsurfabs_sw(ngrid)   ! absorbed SW flux by the surface (W/m2). By MT2015.
68      REAL,INTENT(OUT) :: fluxtop_lw(ngrid)    ! outgoing LW flux to space (W/m2)
69      REAL,INTENT(OUT) :: fluxabs_sw(ngrid)    ! SW flux absorbed by planet (W/m2)
70      REAL,INTENT(OUT) :: fluxtop_dn(ngrid)    ! incident top of atmosphere SW flux (W/m2)
71      REAL,INTENT(OUT) :: OLR_nu(ngrid,L_NSPECTI)! Outgoing LW radition in each band (Normalized to the band width (W/m2/cm-1)
72      REAL,INTENT(OUT) :: OSR_nu(ngrid,L_NSPECTV)! Outgoing SW radition in each band (Normalized to the band width (W/m2/cm-1)
73      REAL,INTENT(OUT) :: tau_col(ngrid) ! diagnostic from aeropacity
74      REAL,INTENT(OUT) :: albedo_equivalent(ngrid) ! Spectrally Integrated Albedo. For Diagnostic. By MT2015
75!     for H2O cloud fraction in aeropacity
76      real,intent(in) :: cloudfrac(ngrid,nlayer)
77      real,intent(out) :: totcloudfrac(ngrid)
78      logical,intent(in) :: clearsky
79      logical,intent(in) :: firstcall ! signals first call to physics
80      logical,intent(in) :: lastcall ! signals last call to physics
81
82!     Globally varying aerosol optical properties on GCM grid
83!     Not needed everywhere so not in radcommon_h
84      REAL :: QVISsQREF3d(ngrid,nlayer,L_NSPECTV,naerkind)
85      REAL :: omegaVIS3d(ngrid,nlayer,L_NSPECTV,naerkind)
86      REAL :: gVIS3d(ngrid,nlayer,L_NSPECTV,naerkind)
87
88      REAL :: QIRsQREF3d(ngrid,nlayer,L_NSPECTI,naerkind)
89      REAL :: omegaIR3d(ngrid,nlayer,L_NSPECTI,naerkind)
90      REAL :: gIR3d(ngrid,nlayer,L_NSPECTI,naerkind)
91
92!      REAL :: omegaREFvis3d(ngrid,nlayer,naerkind)
93!      REAL :: omegaREFir3d(ngrid,nlayer,naerkind) ! not sure of the point of these...
94
95      REAL,ALLOCATABLE,SAVE :: reffrad(:,:,:) ! aerosol effective radius (m)
96      REAL,ALLOCATABLE,SAVE :: nueffrad(:,:,:) ! aerosol effective variance
97!$OMP THREADPRIVATE(reffrad,nueffrad)
98
99!-----------------------------------------------------------------------
100!     Declaration of the variables required by correlated-k subroutines
101!     Numbered from top to bottom unlike in the GCM!
102
103      REAL*8 tmid(L_LEVELS),pmid(L_LEVELS)
104      REAL*8 tlevrad(L_LEVELS),plevrad(L_LEVELS)
105
106!     Optical values for the optci/cv subroutines
107      REAL*8 stel(L_NSPECTV),stel_fract(L_NSPECTV)
108      REAL*8 dtaui(L_NLAYRAD,L_NSPECTI,L_NGAUSS)
109      REAL*8 dtauv(L_NLAYRAD,L_NSPECTV,L_NGAUSS)
110      REAL*8 cosbv(L_NLAYRAD,L_NSPECTV,L_NGAUSS)
111      REAL*8 cosbi(L_NLAYRAD,L_NSPECTI,L_NGAUSS)
112      REAL*8 wbari(L_NLAYRAD,L_NSPECTI,L_NGAUSS)
113      REAL*8 wbarv(L_NLAYRAD,L_NSPECTV,L_NGAUSS)
114      REAL*8 tauv(L_NLEVRAD,L_NSPECTV,L_NGAUSS)
115      REAL*8 taucumv(L_LEVELS,L_NSPECTV,L_NGAUSS)
116      REAL*8 taucumi(L_LEVELS,L_NSPECTI,L_NGAUSS)
117
118      REAL*8 tauaero(L_LEVELS+1,naerkind)
119      REAL*8 nfluxtopv,nfluxtopi,nfluxtop,fluxtopvdn
120      real*8 nfluxoutv_nu(L_NSPECTV) ! outgoing band-resolved VI flux at TOA (W/m2)
121      real*8 nfluxtopi_nu(L_NSPECTI) ! net band-resolved IR flux at TOA (W/m2)
122      real*8 fluxupi_nu(L_NLAYRAD,L_NSPECTI) ! for 1D diagnostic
123      REAL*8 fmneti(L_NLAYRAD),fmnetv(L_NLAYRAD)
124      REAL*8 fluxupv(L_NLAYRAD),fluxupi(L_NLAYRAD)
125      REAL*8 fluxdnv(L_NLAYRAD),fluxdni(L_NLAYRAD)
126      REAL*8 albi,acosz
127      REAL*8 albv(L_NSPECTV) ! Spectral Visible Albedo.
128
129      INTEGER ig,l,k,nw,iaer,irad
130      INTEGER icount
131
132      real szangle
133      logical global1d
134      save szangle,global1d
135!$OMP THREADPRIVATE(szangle,global1d)
136      real*8 taugsurf(L_NSPECTV,L_NGAUSS-1)
137      real*8 taugsurfi(L_NSPECTI,L_NGAUSS-1)
138
139      real*8 qvar(L_LEVELS)          ! mixing ratio of variable component (mol/mol)
140
141!     Local aerosol optical properties for each column on RADIATIVE grid
142      real*8,save ::  QXVAER(L_LEVELS+1,L_NSPECTV,naerkind)
143      real*8,save ::  QSVAER(L_LEVELS+1,L_NSPECTV,naerkind)
144      real*8,save ::  GVAER(L_LEVELS+1,L_NSPECTV,naerkind)
145      real*8,save ::  QXIAER(L_LEVELS+1,L_NSPECTI,naerkind)
146      real*8,save ::  QSIAER(L_LEVELS+1,L_NSPECTI,naerkind)
147      real*8,save ::  GIAER(L_LEVELS+1,L_NSPECTI,naerkind)
148
149      !REAL :: QREFvis3d(ngrid,nlayer,naerkind)
150      !REAL :: QREFir3d(ngrid,nlayer,naerkind)
151      !save QREFvis3d, QREFir3d
152      real, dimension(:,:,:), save, allocatable :: QREFvis3d
153      real, dimension(:,:,:), save, allocatable :: QREFir3d
154!$OMP THREADPRIVATE(QXVAER,QSVAER,GVAER,QXIAER,QSIAER,GIAER,QREFvis3d,QREFir3d)
155
156
157!     Misc.
158      logical nantest
159      real*8  tempv(L_NSPECTV)
160      real*8  tempi(L_NSPECTI)
161      real*8  temp,temp1,temp2,pweight
162      character(len=10) :: tmp1
163      character(len=10) :: tmp2
164
165!     for fixed water vapour profiles
166      integer i_var
167      real RH
168      real*8 pq_temp(nlayer)
169      real ptemp, Ttemp, qsat
170
171!      real(KIND=r8) :: pq_temp(nlayer) ! better F90 way.. DOESNT PORT TO F77!!!
172
173      !real ptime, pday
174      logical OLRz
175      real*8 NFLUXGNDV_nu(L_NSPECTV)
176
177
178      ! for weird cloud test
179      real pqtest(ngrid,nlayer,nq)
180
181      real maxrad, minrad
182           
183      real,external :: CBRT
184
185!     included by RW for runaway greenhouse 1D study
186      real vtmp(nlayer)
187      REAL*8 muvarrad(L_LEVELS)
188     
189!     included by MT for albedo calculations.     
190      REAL*8 albedo_temp(L_NSPECTV) ! For equivalent albedo calculation.
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         !!! ALLOCATED instances are necessary because of CLFvarying
206         !!! strategy to call callcorrk twice in physiq...
207         IF(.not.ALLOCATED(QREFvis3d)) ALLOCATE(QREFvis3d(ngrid,nlayer,naerkind))
208         IF(.not.ALLOCATED(QREFir3d)) ALLOCATE(QREFir3d(ngrid,nlayer,naerkind))
209         ! Effective radius and variance of the aerosols
210         IF(.not.ALLOCATED(reffrad)) allocate(reffrad(ngrid,nlayer,naerkind))
211         IF(.not.ALLOCATED(nueffrad)) allocate(nueffrad(ngrid,nlayer,naerkind))
212
213         call system('rm -f surf_vals_long.out')
214
215         if(naerkind.gt.4)then
216            print*,'Code not general enough to deal with naerkind > 4 yet.'
217            call abort
218         endif
219         call su_aer_radii(ngrid,nlayer,reffrad,nueffrad)
220         
221!--------------------------------------------------
222!     set up correlated k
223         print*, "callcorrk: Correlated-k data base folder:",trim(datadir)
224         call getin_p("corrkdir",corrkdir)
225         print*, "corrkdir = ",corrkdir
226         write( tmp1, '(i3)' ) L_NSPECTI
227         write( tmp2, '(i3)' ) L_NSPECTV
228         banddir=trim(adjustl(tmp1))//'x'//trim(adjustl(tmp2))
229         banddir=trim(adjustl(corrkdir))//'/'//trim(adjustl(banddir))
230
231         call setspi            ! basic infrared properties
232         call setspv            ! basic visible properties
233         call sugas_corrk       ! set up gaseous absorption properties
234         call suaer_corrk       ! set up aerosol optical properties
235
236
237         if((igcm_h2o_vap.eq.0) .and. varactive)then
238            print*,'varactive in callcorrk but no h2o_vap tracer.'
239            stop
240         endif
241
242         OLR_nu(:,:) = 0.
243         OSR_nu(:,:) = 0.
244
245         if (ngrid.eq.1) then
246           PRINT*, 'Simulate global averaged conditions ?'
247           global1d = .false. ! default value
248           call getin_p("global1d",global1d)
249           write(*,*) "global1d = ",global1d
250           ! Test of incompatibility:
251           ! if global1d is true, there should not be any diurnal cycle
252           if (global1d.and.diurnal) then
253            print*,'if global1d is true, diurnal must be set to false'
254            stop
255           endif
256
257           if (global1d) then
258             PRINT *,'Solar Zenith angle (deg.) ?'
259             PRINT *,'(assumed for averaged solar flux S/4)'
260             szangle=60.0  ! default value
261             call getin_p("szangle",szangle)
262             write(*,*) "szangle = ",szangle
263           endif
264         endif
265
266      end if ! of if (firstcall)
267
268!=======================================================================
269!     Initialization on every call   
270
271!--------------------------------------------------
272!     Effective radius and variance of the aerosols
273      do iaer=1,naerkind
274
275         if ((iaer.eq.iaero_co2).and.tracer.and.(igcm_co2_ice.gt.0)) then ! treat condensed co2 particles.
276            call co2_reffrad(ngrid,nlayer,nq,pq,reffrad(1,1,iaero_co2))
277            print*,'Max. CO2 ice particle size = ',maxval(reffrad(1:ngrid,1:nlayer,iaer))/1.e-6,' um'
278            print*,'Min. CO2 ice particle size = ',minval(reffrad(1:ngrid,1:nlayer,iaer))/1.e-6,' um'
279         end if
280         if ((iaer.eq.iaero_h2o).and.water) then ! treat condensed water particles. to be generalized for other aerosols
281            call h2o_reffrad(ngrid,nlayer,pq(1,1,igcm_h2o_ice),pt, &
282                             reffrad(1,1,iaero_h2o),nueffrad(1,1,iaero_h2o))
283            print*,'Max. H2O cloud particle size = ',maxval(reffrad(1:ngrid,1:nlayer,iaer))/1.e-6,' um'
284            print*,'Min. H2O cloud particle size = ',minval(reffrad(1:ngrid,1:nlayer,iaer))/1.e-6,' um'
285         endif
286         if(iaer.eq.iaero_dust)then
287            call dust_reffrad(ngrid,nlayer,reffrad(1,1,iaero_dust))
288            print*,'Dust particle size = ',reffrad(1,1,iaer)/1.e-6,' um'
289         endif
290         if(iaer.eq.iaero_h2so4)then
291            call h2so4_reffrad(ngrid,nlayer,reffrad(1,1,iaero_h2so4))
292            print*,'H2SO4 particle size =',reffrad(1,1,iaer)/1.e-6,' um'
293         endif
294          if(iaer.eq.iaero_back2lay)then
295            call back2lay_reffrad(ngrid,reffrad(1,1,iaero_back2lay),nlayer,pplev)
296         endif
297     end do !iaer=1,naerkind
298
299
300!     how much light we get
301      do nw=1,L_NSPECTV
302         stel(nw)=stellarf(nw)/(dist_star**2)
303      end do
304
305      call aeroptproperties(ngrid,nlayer,reffrad,nueffrad,         &
306           QVISsQREF3d,omegaVIS3d,gVIS3d,                          &
307           QIRsQREF3d,omegaIR3d,gIR3d,                             &
308           QREFvis3d,QREFir3d)                                     ! get 3D aerosol optical properties
309
310      call aeropacity(ngrid,nlayer,nq,pplay,pplev,pq,aerosol,      &
311           reffrad,QREFvis3d,QREFir3d,                             &
312           tau_col,cloudfrac,totcloudfrac,clearsky)                ! get aerosol optical depths
313         
314!-----------------------------------------------------------------------
315!     Starting Big Loop over every GCM column
316      do ig=1,ngrid
317
318!=======================================================================
319!     Transformation of the GCM variables
320
321!-----------------------------------------------------------------------
322!     Aerosol optical properties Qext, Qscat and g
323!     The transformation in the vertical is the same as for temperature
324           
325!     shortwave
326            do iaer=1,naerkind
327               DO nw=1,L_NSPECTV
328                  do l=1,nlayer
329
330                     temp1=QVISsQREF3d(ig,nlayer+1-l,nw,iaer)         &
331                         *QREFvis3d(ig,nlayer+1-l,iaer)
332
333                     temp2=QVISsQREF3d(ig,max(nlayer-l,1),nw,iaer)    &
334                         *QREFvis3d(ig,max(nlayer-l,1),iaer)
335
336                     qxvaer(2*l,nw,iaer)  = temp1
337                     qxvaer(2*l+1,nw,iaer)=(temp1+temp2)/2
338
339                     temp1=temp1*omegavis3d(ig,nlayer+1-l,nw,iaer)
340                     temp2=temp2*omegavis3d(ig,max(nlayer-l,1),nw,iaer)
341
342                     qsvaer(2*l,nw,iaer)  = temp1
343                     qsvaer(2*l+1,nw,iaer)=(temp1+temp2)/2
344
345                     temp1=gvis3d(ig,nlayer+1-l,nw,iaer)
346                     temp2=gvis3d(ig,max(nlayer-l,1),nw,iaer)
347
348                     gvaer(2*l,nw,iaer)  = temp1
349                     gvaer(2*l+1,nw,iaer)=(temp1+temp2)/2
350
351                  end do
352
353                  qxvaer(1,nw,iaer)=qxvaer(2,nw,iaer)
354                  qxvaer(2*nlayer+1,nw,iaer)=0.
355
356                  qsvaer(1,nw,iaer)=qsvaer(2,nw,iaer)
357                  qsvaer(2*nlayer+1,nw,iaer)=0.
358
359                  gvaer(1,nw,iaer)=gvaer(2,nw,iaer)
360                  gvaer(2*nlayer+1,nw,iaer)=0.
361
362               end do
363
364!     longwave
365               DO nw=1,L_NSPECTI
366                  do l=1,nlayer
367
368                     temp1=QIRsQREF3d(ig,nlayer+1-l,nw,iaer)         &
369                          *QREFir3d(ig,nlayer+1-l,iaer)
370
371                     temp2=QIRsQREF3d(ig,max(nlayer-l,1),nw,iaer)    &
372                          *QREFir3d(ig,max(nlayer-l,1),iaer)
373
374                     qxiaer(2*l,nw,iaer)  = temp1
375                     qxiaer(2*l+1,nw,iaer)=(temp1+temp2)/2
376
377                     temp1=temp1*omegair3d(ig,nlayer+1-l,nw,iaer)
378                     temp2=temp2*omegair3d(ig,max(nlayer-l,1),nw,iaer)
379
380                     qsiaer(2*l,nw,iaer)  = temp1
381                     qsiaer(2*l+1,nw,iaer)=(temp1+temp2)/2
382
383                     temp1=gir3d(ig,nlayer+1-l,nw,iaer)
384                     temp2=gir3d(ig,max(nlayer-l,1),nw,iaer)
385
386                     giaer(2*l,nw,iaer)  = temp1
387                     giaer(2*l+1,nw,iaer)=(temp1+temp2)/2
388
389                  end do
390
391                  qxiaer(1,nw,iaer)=qxiaer(2,nw,iaer)
392                  qxiaer(2*nlayer+1,nw,iaer)=0.
393
394                  qsiaer(1,nw,iaer)=qsiaer(2,nw,iaer)
395                  qsiaer(2*nlayer+1,nw,iaer)=0.
396
397                  giaer(1,nw,iaer)=giaer(2,nw,iaer)
398                  giaer(2*nlayer+1,nw,iaer)=0.
399
400               end do
401            end do
402
403            ! test / correct for freaky s. s. albedo values
404            do iaer=1,naerkind
405               do k=1,L_LEVELS+1
406
407                  do nw=1,L_NSPECTV
408                     if(qsvaer(k,nw,iaer).gt.1.05*qxvaer(k,nw,iaer))then
409                        print*,'Serious problems with qsvaer values'
410                        print*,'in callcorrk'
411                        call abort
412                     endif
413                     if(qsvaer(k,nw,iaer).gt.qxvaer(k,nw,iaer))then
414                        qsvaer(k,nw,iaer)=qxvaer(k,nw,iaer)
415                     endif
416                  end do
417
418                  do nw=1,L_NSPECTI
419                     if(qsiaer(k,nw,iaer).gt.1.05*qxiaer(k,nw,iaer))then
420                        print*,'Serious problems with qsiaer values'
421                        print*,'in callcorrk'
422                        call abort
423                     endif
424                     if(qsiaer(k,nw,iaer).gt.qxiaer(k,nw,iaer))then
425                        qsiaer(k,nw,iaer)=qxiaer(k,nw,iaer)
426                     endif
427                  end do
428
429               end do
430            end do
431
432!-----------------------------------------------------------------------
433!     Aerosol optical depths
434           
435         do iaer=1,naerkind     ! a bug was here           
436            do k=0,nlayer-1
437               
438               pweight=(pplay(ig,L_NLAYRAD-k)-pplev(ig,L_NLAYRAD-k+1))/   &
439                        (pplev(ig,L_NLAYRAD-k)-pplev(ig,L_NLAYRAD-k+1))
440
441               temp=aerosol(ig,L_NLAYRAD-k,iaer)/QREFvis3d(ig,L_NLAYRAD-k,iaer)
442
443               tauaero(2*k+2,iaer)=max(temp*pweight,0.d0)
444               tauaero(2*k+3,iaer)=max(temp-tauaero(2*k+2,iaer),0.d0)
445!
446            end do
447            ! boundary conditions
448            tauaero(1,iaer)          = tauaero(2,iaer)
449            tauaero(L_LEVELS+1,iaer) = tauaero(L_LEVELS,iaer)
450            !tauaero(1,iaer)          = 0.
451            !tauaero(L_LEVELS+1,iaer) = 0.
452         end do
453
454!     Albedo and emissivity
455         albi=1-emis(ig)   ! Longwave.
456         DO nw=1,L_NSPECTV ! Shortwave loop.
457            albv(nw)=albedo(ig,nw)
458         ENDDO
459
460         if (nosurf) then
461            DO nw=1,L_NSPECTV
462               if(albv(nw).gt.0.0) then
463                  print*,'For open lower boundary in callcorrk must'
464                  print*,'have spectral surface band albedos all set to zero!'
465                  call abort
466               endif
467            ENDDO         
468         endif
469
470      if ((ngrid.eq.1).and.(global1d)) then       ! fixed zenith angle 'szangle' in 1D simulations w/ globally-averaged sunlight
471         acosz = cos(pi*szangle/180.0)
472         print*,'acosz=',acosz,', szangle=',szangle
473      else
474         acosz=mu0(ig)          ! cosine of sun incident angle : 3D simulations or local 1D simulations using latitude
475      endif
476
477!!! JL13: in the following, I changed some indices in the interpolations so that the model rsults are less dependent on the number of layers
478!!!    the older verions are commented with the commetn !JL13index
479
480
481!-----------------------------------------------------------------------
482!     Water vapour (to be generalised for other gases eventually)
483     
484      if(varactive)then
485
486         i_var=igcm_h2o_vap
487         do l=1,nlayer
488            qvar(2*l)   = pq(ig,nlayer+1-l,i_var)
489            qvar(2*l+1) = pq(ig,nlayer+1-l,i_var)   
490!JL13index            qvar(2*l+1) = (pq(ig,nlayer+1-l,i_var)+pq(ig,max(nlayer-l,1),i_var))/2   
491!JL13index            ! Average approximation as for temperature...
492         end do
493         qvar(1)=qvar(2)
494
495      elseif(varfixed)then
496
497         do l=1,nlayer        ! here we will assign fixed water vapour profiles globally
498            RH = satval * ((pplay(ig,l)/pplev(ig,1) - 0.02) / 0.98)
499            if(RH.lt.0.0) RH=0.0
500           
501            ptemp=pplay(ig,l)
502            Ttemp=pt(ig,l)
503            call watersat(Ttemp,ptemp,qsat)
504
505            !pq_temp(l) = qsat      ! fully saturated everywhere
506            pq_temp(l) = RH * qsat ! ~realistic profile (e.g. 80% saturation at ground)
507         end do
508         
509         do l=1,nlayer
510            qvar(2*l)   = pq_temp(nlayer+1-l)
511            qvar(2*l+1) = (pq_temp(nlayer+1-l)+pq_temp(max(nlayer-l,1)))/2
512         end do
513         qvar(1)=qvar(2)
514
515         ! Lowest layer of atmosphere
516         RH = satval * (1 - 0.02) / 0.98
517         if(RH.lt.0.0) RH=0.0
518
519!         ptemp = pplev(ig,1)
520!         Ttemp = tsurf(ig)
521!         call watersat(Ttemp,ptemp,qsat)
522
523         qvar(2*nlayer+1)= RH * qsat ! ~realistic profile (e.g. 80% saturation at ground)
524 
525      else
526         do k=1,L_LEVELS
527            qvar(k) = 1.0D-7
528         end do
529      end if
530
531      if(.not.kastprof)then
532      ! IMPORTANT: Now convert from kg/kg to mol/mol
533         do k=1,L_LEVELS
534            qvar(k) = qvar(k)/(epsi+qvar(k)*(1.-epsi))
535         end do
536      end if
537
538!-----------------------------------------------------------------------
539!     kcm mode only
540      if(kastprof)then
541
542         ! initial values equivalent to mugaz
543         DO l=1,nlayer
544            muvarrad(2*l)   = mugaz
545            muvarrad(2*l+1) = mugaz
546         END DO
547
548         if(ngasmx.gt.1)then
549
550            DO l=1,nlayer
551               muvarrad(2*l)   = muvar(ig,nlayer+2-l)
552               muvarrad(2*l+1) = (muvar(ig,nlayer+2-l) + &
553                                muvar(ig,max(nlayer+1-l,1)))/2
554            END DO
555     
556            muvarrad(1) = muvarrad(2)
557            muvarrad(2*nlayer+1)=muvar(ig,1)
558
559            print*,'Recalculating qvar with VARIABLE epsi for kastprof'
560            print*,'Assumes that the variable gas is H2O!!!'
561            print*,'Assumes that there is only one tracer'
562            !i_var=igcm_h2o_vap
563            i_var=1
564            if(nq.gt.1)then
565               print*,'Need 1 tracer only to run kcm1d.e'
566               stop
567            endif
568            do l=1,nlayer
569               vtmp(l)=pq(ig,l,i_var)/(epsi+pq(ig,l,i_var)*(1.-epsi))
570               !vtmp(l)=pq(ig,l,i_var)*muvar(ig,l+1)/mH2O !JL to be changed
571            end do
572
573            do l=1,nlayer
574               qvar(2*l)   = vtmp(nlayer+1-l)
575               qvar(2*l+1) = vtmp(nlayer+1-l)
576!               qvar(2*l+1) = ( vtmp(nlayer+1-l) + vtmp(max(nlayer-l,1)) )/2
577            end do
578            qvar(1)=qvar(2)
579
580            print*,'Warning: reducing qvar in callcorrk.'
581            print*,'Temperature profile no longer consistent ', &
582                            'with saturated H2O. qsat=',satval
583            do k=1,L_LEVELS
584               qvar(k) = qvar(k)*satval
585            end do
586
587         endif
588      else ! if kastprof
589         DO l=1,nlayer
590            muvarrad(2*l)   = muvar(ig,nlayer+2-l)
591            muvarrad(2*l+1) = (muvar(ig,nlayer+2-l)+muvar(ig,max(nlayer+1-l,1)))/2
592         END DO
593     
594         muvarrad(1) = muvarrad(2)
595         muvarrad(2*nlayer+1)=muvar(ig,1)         
596      endif
597     
598      ! Keep values inside limits for which we have radiative transfer coefficients
599      if(L_REFVAR.gt.1)then ! there was a bug here!
600         do k=1,L_LEVELS
601            if(qvar(k).lt.wrefvar(1))then
602               qvar(k)=wrefvar(1)+1.0e-8
603            elseif(qvar(k).gt.wrefvar(L_REFVAR))then
604               qvar(k)=wrefvar(L_REFVAR)-1.0e-8
605            endif
606         end do
607      endif
608
609!-----------------------------------------------------------------------
610!     Pressure and temperature
611
612      DO l=1,nlayer
613         plevrad(2*l)   = pplay(ig,nlayer+1-l)/scalep
614         plevrad(2*l+1) = pplev(ig,nlayer+1-l)/scalep
615         tlevrad(2*l)   = pt(ig,nlayer+1-l)
616         tlevrad(2*l+1) = (pt(ig,nlayer+1-l)+pt(ig,max(nlayer-l,1)))/2
617      END DO
618     
619      plevrad(1) = 0.
620      plevrad(2) = 0.   !! Trick to have correct calculations of fluxes in gflux(i/v).F,
621                        !! but the pmid levels are not impacted by this change.
622
623      tlevrad(1) = tlevrad(2)
624      tlevrad(2*nlayer+1)=tsurf(ig)
625     
626      pmid(1) = max(pgasmin,0.0001*plevrad(3))
627      pmid(2) =  pmid(1)
628
629      tmid(1) = tlevrad(2)
630      tmid(2) = tmid(1)
631   
632      DO l=1,L_NLAYRAD-1
633         tmid(2*l+1) = tlevrad(2*l+1)
634         tmid(2*l+2) = tlevrad(2*l+1)
635         pmid(2*l+1) = plevrad(2*l+1)
636         pmid(2*l+2) = plevrad(2*l+1)
637      END DO
638      pmid(L_LEVELS) = plevrad(L_LEVELS)
639      tmid(L_LEVELS) = tlevrad(L_LEVELS)
640
641!!Alternative interpolation:
642!         pmid(3) = pmid(1)
643!         pmid(4) = pmid(1)
644!         tmid(3) = tmid(1)
645!         tmid(4) = tmid(1)
646!      DO l=2,L_NLAYRAD-1
647!         tmid(2*l+1) = tlevrad(2*l)
648!         tmid(2*l+2) = tlevrad(2*l)
649!         pmid(2*l+1) = plevrad(2*l)
650!         pmid(2*l+2) = plevrad(2*l)
651!      END DO
652!      pmid(L_LEVELS) = plevrad(L_LEVELS-1)
653!      tmid(L_LEVELS) = tlevrad(L_LEVELS-1)
654
655      ! test for out-of-bounds pressure
656      if(plevrad(3).lt.pgasmin)then
657         print*,'Minimum pressure is outside the radiative'
658         print*,'transfer kmatrix bounds, exiting.'
659         call abort
660      elseif(plevrad(L_LEVELS).gt.pgasmax)then
661         print*,'Maximum pressure is outside the radiative'
662         print*,'transfer kmatrix bounds, exiting.'
663         call abort
664      endif
665
666      ! test for out-of-bounds temperature
667      do k=1,L_LEVELS
668         if(tlevrad(k).lt.tgasmin)then
669            print*,'Minimum temperature is outside the radiative'
670            print*,'transfer kmatrix bounds'
671            print*,"k=",k," tlevrad(k)=",tlevrad(k)
672            print*,"tgasmin=",tgasmin
673            if (strictboundcorrk) then
674              call abort
675            else
676              print*,'***********************************************'
677              print*,'we allow model to continue with tlevrad=tgasmin'
678              print*,'  ... we assume we know what you are doing ... '
679              print*,'  ... but do not let this happen too often ... '
680              print*,'***********************************************'
681              !tlevrad(k)=tgasmin
682            endif
683         elseif(tlevrad(k).gt.tgasmax)then
684            print*,'Maximum temperature is outside the radiative'
685            print*,'transfer kmatrix bounds, exiting.'
686            print*,"k=",k," tlevrad(k)=",tlevrad(k)
687            print*,"tgasmax=",tgasmax
688            if (strictboundcorrk) then
689              call abort
690            else
691              print*,'***********************************************'
692              print*,'we allow model to continue with tlevrad=tgasmax' 
693              print*,'  ... we assume we know what you are doing ... '
694              print*,'  ... but do not let this happen too often ... '
695              print*,'***********************************************'
696              !tlevrad(k)=tgasmax
697            endif
698         endif
699      enddo
700      do k=1,L_NLAYRAD+1
701         if(tmid(k).lt.tgasmin)then
702            print*,'Minimum temperature is outside the radiative'
703            print*,'transfer kmatrix bounds, exiting.'
704            print*,"k=",k," tmid(k)=",tmid(k)
705            print*,"tgasmin=",tgasmin
706            if (strictboundcorrk) then
707              call abort
708            else
709              print*,'***********************************************'
710              print*,'we allow model to continue with tmid=tgasmin'
711              print*,'  ... we assume we know what you are doing ... '
712              print*,'  ... but do not let this happen too often ... '
713              print*,'***********************************************'
714              tmid(k)=tgasmin
715            endif
716         elseif(tmid(k).gt.tgasmax)then
717            print*,'Maximum temperature is outside the radiative'
718            print*,'transfer kmatrix bounds, exiting.'
719            print*,"k=",k," tmid(k)=",tmid(k)
720            print*,"tgasmax=",tgasmax
721            if (strictboundcorrk) then
722              call abort
723            else
724              print*,'***********************************************'
725              print*,'we allow model to continue with tmid=tgasmin'
726              print*,'  ... we assume we know what you are doing ... '
727              print*,'  ... but do not let this happen too often ... '
728              print*,'***********************************************'
729              tmid(k)=tgasmax
730            endif
731         endif
732      enddo
733
734!=======================================================================
735!     Calling the main radiative transfer subroutines
736
737
738         Cmk= 0.01 * 1.0 / (glat(ig) * mugaz * 1.672621e-27) ! q_main=1.0 assumed
739         glat_ig=glat(ig)
740
741!-----------------------------------------------------------------------
742!     Shortwave
743
744         if(fract(ig) .ge. 1.0e-4) then ! only during daylight!
745            if((ngrid.eq.1).and.(global1d))then
746               do nw=1,L_NSPECTV
747                  stel_fract(nw)= stel(nw)* 0.25 / acosz
748                                ! globally averaged = divide by 4
749                                ! but we correct for solar zenith angle
750               end do
751            else
752               do nw=1,L_NSPECTV
753                  stel_fract(nw)= stel(nw) * fract(ig)
754               end do
755            endif
756            call optcv(dtauv,tauv,taucumv,plevrad,                 &
757                 qxvaer,qsvaer,gvaer,wbarv,cosbv,tauray,tauaero,   &
758                 tmid,pmid,taugsurf,qvar,muvarrad)
759
760            call sfluxv(dtauv,tauv,taucumv,albv,dwnv,wbarv,cosbv,  &
761                 acosz,stel_fract,gweight,                         &
762                 nfluxtopv,fluxtopvdn,nfluxoutv_nu,nfluxgndv_nu,              &
763                 fmnetv,fluxupv,fluxdnv,fzerov,taugsurf)
764
765         else                          ! during the night, fluxes = 0
766            nfluxtopv       = 0.0d0
767            fluxtopvdn      = 0.0d0
768            nfluxoutv_nu(:) = 0.0d0
769            nfluxgndv_nu(:) = 0.0d0
770            do l=1,L_NLAYRAD
771               fmnetv(l)=0.0d0
772               fluxupv(l)=0.0d0
773               fluxdnv(l)=0.0d0
774            end do
775         end if
776
777
778         ! Equivalent Albedo Calculation. MT2015
779         if(fract(ig) .ge. 1.0e-4) then ! equivalent albedo makes sense only during daylight.           
780            DO nw=1,L_NSPECTV             
781               albedo_temp(nw)=albedo(ig,nw)*nfluxgndv_nu(nw)
782            ENDDO
783            albedo_temp(1:L_NSPECTV)=albedo_temp(1:L_NSPECTV)/sum(nfluxgndv_nu(1:L_NSPECTV))
784            albedo_equivalent(ig)=sum(albedo_temp(1:L_NSPECTV))
785         else
786            albedo_equivalent(ig)=0.0 ! Spectrally Integrated Albedo not defined for non-irradiated grid points. So we arbitrary set the equivalent albedo to 0.
787         endif
788
789
790!-----------------------------------------------------------------------
791!     Longwave
792
793         call optci(plevrad,tlevrad,dtaui,taucumi,                  &
794              qxiaer,qsiaer,giaer,cosbi,wbari,tauaero,tmid,pmid,    &
795              taugsurfi,qvar,muvarrad)
796
797         call sfluxi(plevrad,tlevrad,dtaui,taucumi,ubari,albi,      &
798              wnoi,dwni,cosbi,wbari,gweight,nfluxtopi,nfluxtopi_nu, &
799              fmneti,fluxupi,fluxdni,fluxupi_nu,fzeroi,taugsurfi)
800
801!-----------------------------------------------------------------------
802!     Transformation of the correlated-k code outputs
803!     (into dtlw, dtsw, fluxsurf_lw, fluxsurf_sw, fluxtop_lw, fluxtop_sw)
804
805!     Flux incident at the top of the atmosphere
806         fluxtop_dn(ig)=fluxtopvdn
807
808         fluxtop_lw(ig)  = real(nfluxtopi)
809         fluxabs_sw(ig)  = real(-nfluxtopv)
810         fluxsurf_lw(ig) = real(fluxdni(L_NLAYRAD))
811         fluxsurf_sw(ig) = real(fluxdnv(L_NLAYRAD))
812         
813!        Flux absorbed by the surface. By MT2015.         
814         fluxsurfabs_sw(ig) = fluxsurf_sw(ig)*(1.-albedo_equivalent(ig))
815
816         if(fluxtop_dn(ig).lt.0.0)then
817            print*,'Achtung! fluxtop_dn has lost the plot!'
818            print*,'fluxtop_dn=',fluxtop_dn(ig)
819            print*,'acosz=',acosz
820            print*,'aerosol=',aerosol(ig,:,:)
821            print*,'temp=   ',pt(ig,:)
822            print*,'pplay=  ',pplay(ig,:)
823            call abort
824         endif
825
826!     Spectral output, for exoplanet observational comparison
827         if(specOLR)then
828            do nw=1,L_NSPECTI
829               OLR_nu(ig,nw)=nfluxtopi_nu(nw)/DWNI(nw) !JL Normalize to the bandwidth
830            end do
831            do nw=1,L_NSPECTV
832               !GSR_nu(ig,nw)=nfluxgndv_nu(nw)
833               OSR_nu(ig,nw)=nfluxoutv_nu(nw)/DWNV(nw) !JL Normalize to the bandwidth
834            end do
835         endif
836
837!     Finally, the heating rates
838
839         DO l=2,L_NLAYRAD
840            dtsw(ig,L_NLAYRAD+1-l)=(fmnetv(l)-fmnetv(l-1))  &
841                *glat(ig)/(cpp*scalep*(plevrad(2*l+1)-plevrad(2*l-1)))
842            dtlw(ig,L_NLAYRAD+1-l)=(fmneti(l)-fmneti(l-1))  &
843                *glat(ig)/(cpp*scalep*(plevrad(2*l+1)-plevrad(2*l-1)))
844         END DO     
845
846!     These are values at top of atmosphere
847         dtsw(ig,L_NLAYRAD)=(fmnetv(1)-nfluxtopv)           &
848             *glat(ig)/(cpp*scalep*(plevrad(3)-plevrad(1)))
849         dtlw(ig,L_NLAYRAD)=(fmneti(1)-nfluxtopi)           &
850             *glat(ig)/(cpp*scalep*(plevrad(3)-plevrad(1)))
851
852!     ---------------------------------------------------------------
853      end do                    ! end of big loop over every GCM column (ig = 1:ngrid)
854
855
856!-----------------------------------------------------------------------
857!     Additional diagnostics
858
859!     IR spectral output, for exoplanet observational comparison
860
861
862      if(lastcall.and.(ngrid.eq.1))then  ! could disable the 1D output, they are in the diagfi and diagspec... JL12
863
864           print*,'Saving scalar quantities in surf_vals.out...'
865           print*,'psurf = ', pplev(1,1),' Pa'
866           open(116,file='surf_vals.out')
867           write(116,*) tsurf(1),pplev(1,1),fluxtop_dn(1),         &
868                real(-nfluxtopv),real(nfluxtopi)
869           close(116)
870
871!          I am useful, please don`t remove me!
872!           if(specOLR)then
873!               open(117,file='OLRnu.out')
874!               do nw=1,L_NSPECTI
875!                  write(117,*) OLR_nu(1,nw)
876!               enddo
877!               close(117)
878!
879!               open(127,file='OSRnu.out')
880!               do nw=1,L_NSPECTV
881!                  write(127,*) OSR_nu(1,nw)
882!               enddo
883!               close(127)
884!           endif
885
886!     OLR vs altitude: do it as a .txt file
887           OLRz=.false.
888           if(OLRz)then
889              print*,'saving IR vertical flux for OLRz...'
890              open(118,file='OLRz_plevs.out')
891              open(119,file='OLRz.out')
892              do l=1,L_NLAYRAD
893                 write(118,*) plevrad(2*l)
894                 do nw=1,L_NSPECTI
895                     write(119,*) fluxupi_nu(l,nw)
896                  enddo
897              enddo
898              close(118)
899              close(119)
900           endif
901
902      endif
903
904      ! see physiq.F for explanations about CLFvarying. This is temporary.
905      if (lastcall .and. .not.CLFvarying) then
906        IF( ALLOCATED( gasi ) ) DEALLOCATE( gasi )
907        IF( ALLOCATED( gasv ) ) DEALLOCATE( gasv )
908!$OMP BARRIER
909!$OMP MASTER
910        IF( ALLOCATED( pgasref ) ) DEALLOCATE( pgasref )
911        IF( ALLOCATED( tgasref ) ) DEALLOCATE( tgasref )
912        IF( ALLOCATED( wrefvar ) ) DEALLOCATE( wrefvar )
913        IF( ALLOCATED( pfgasref ) ) DEALLOCATE( pfgasref )
914!$OMP END MASTER
915!$OMP BARRIER   
916        IF ( ALLOCATED(reffrad)) DEALLOCATE(reffrad)
917        IF ( ALLOCATED(nueffrad)) DEALLOCATE(nueffrad)
918      endif
919
920
921    end subroutine callcorrk
Note: See TracBrowser for help on using the repository browser.