source: codes/icosagcm/branches/SATURN_DYNAMICO/LMDZ.COMMON/libf/phystd/callcorrk.F90 @ 315

Last change on this file since 315 was 315, checked in by aslmd, 10 years ago

added a dirty fix to continue integrations even if fluxtop lost the plot. just copy the neighboring point and keep on rocking in the free world.

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