Ignore:
Timestamp:
Oct 12, 2023, 10:30:22 AM (14 months ago)
Author:
slebonnois
Message:

BBT : Update for the titan microphysics and cloud model

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/LMDZ.TITAN/libf/phytitan/optcv.F90

    r2366 r3083  
    1 SUBROUTINE OPTCV(PQMO,NLAY,PLEV,TMID,PMID,  &
    2      DTAUV,TAUV,TAUCUMV,WBARV,COSBV,TAURAY,TAUGSURF,SEASHAZEFACT)
     1SUBROUTINE OPTCV(PQMO,NLAY,ZLEV,PLEV,TMID,PMID,  &
     2     DTAUV,TAUV,TAUCUMV,WBARV,COSBV,TAURAY,TAUGSURF,SEASHAZEFACT,&
     3     POPT_HAZE,POPT_CLOUDS,CDCOLUMN)
    34
    45  use radinc_h
     
    78  use gases_h
    89  use datafile_mod, only: haze_opt_file
    9   use comcstfi_mod, only: r
    10   use callkeys_mod, only: continuum,graybody,callgasvis,corrk_recombin,     &
    11                           callclouds,callmufi,seashaze,uncoupl_optic_haze
    12   use tracer_h, only: nmicro,nice
     10  use comcstfi_mod, only: pi,r
     11  use callkeys_mod, only: continuum,graybody,callgasvis,corrk_recombin,   &
     12                          callclouds,callmufi,seashaze,uncoupl_optic_haze,&
     13                          opt4clouds,FHVIS, Fssa
     14  use tracer_h, only: nmicro,nice,ices_indx
    1315
    1416  implicit none
     
    2426  !     Adapted from the NASA Ames code by R. Wordsworth (2009)
    2527  !     Clean and adaptation to Titan by J. Vatant d'Ollone (2016-17)
     28  !     Clean and correction to Titan by B. de Batz de Trenquelléon (2022)
     29  !     New optics added for Titan's clouds by B. de Batz de Trenquelléon (2023)
     30  !     The whole routine needs to be redone...
    2631  !     
    2732  !==================================================================
     
    4752  REAL*8, INTENT(IN)  :: PQMO(nlay,nmicro)  ! Tracers for microphysics optics (X/m2).
    4853  INTEGER, INTENT(IN) :: NLAY               ! Number of pressure layers (for pqmo)
     54  REAL*8, INTENT(IN)  :: ZLEV(NLAY+1)
    4955  REAL*8, INTENT(IN)  :: PLEV(L_LEVELS)
    5056  REAL*8, INTENT(IN)  :: TMID(L_LEVELS), PMID(L_LEVELS)
    5157  REAL*8, INTENT(IN)  :: TAURAY(L_NSPECTV)
    5258  REAL*8, INTENT(IN)  :: SEASHAZEFACT(L_LEVELS)
     59  INTEGER, INTENT(IN) :: CDCOLUMN
    5360 
    5461  REAL*8, INTENT(OUT) :: DTAUV(L_NLAYRAD,L_NSPECTV,L_NGAUSS)
     
    5865  REAL*8, INTENT(OUT) :: WBARV(L_NLAYRAD,L_NSPECTV,L_NGAUSS)
    5966  REAL*8, INTENT(OUT) :: TAUGSURF(L_NSPECTV,L_NGAUSS-1)
     67  REAL*8, INTENT(OUT) :: POPT_HAZE(L_LEVELS,L_NSPECTI,3)
     68  REAL*8, INTENT(OUT) :: POPT_CLOUDS(L_LEVELS,L_NSPECTI,3)
    6069  ! ==========================================================
    6170 
     
    6473  ! Titan customisation
    6574  ! J. Vatant d'Ollone (2016)
    66   real*8 DHAZE_T(L_LEVELS,L_NSPECTI)
    67   real*8 DHAZES_T(L_LEVELS,L_NSPECTI)
    68   real*8 SSA_T(L_LEVELS,L_NSPECTI)
    69   real*8 ASF_T(L_LEVELS,L_NSPECTI)
     75  real*8 DHAZE_T(L_LEVELS,L_NSPECTV)
     76  real*8 DHAZES_T(L_LEVELS,L_NSPECTV)
     77  real*8 SSA_T(L_LEVELS,L_NSPECTV)
     78  real*8 ASF_T(L_LEVELS,L_NSPECTV)
    7079  ! ==========================
    7180
     
    105114  real*8  dumwvl
    106115
    107   real*8 m3as,m3af
    108   real*8 dtauaer_s,dtauaer_f
     116  ! Variables for new optics
     117  integer iq, iw, FTYPE, CTYPE
     118  real*8 m0as,m0af,m0ccn,m3as,m3af,m3ccn,m3ices,m3cld
     119  real*8 dtauaer_s,dtauaer_f,dtau_ccn,dtau_cld
    109120  real*8,save :: rhoaer_s(L_NSPECTV),ssa_s(L_NSPECTV),asf_s(L_NSPECTV)
    110121  real*8,save :: rhoaer_f(L_NSPECTV),ssa_f(L_NSPECTV),asf_f(L_NSPECTV)
    111 !$OMP THREADPRIVATE(rhoaer_s,rhoaer_f,ssa_s,ssa_f,asf_s,asf_f)
     122  real*8,save :: ssa_ccn(L_NSPECTI),asf_ccn(L_NSPECTI)
     123  real*8,save :: ssa_cld(L_NSPECTV),asf_cld(L_NSPECTV)
     124!$OMP THREADPRIVATE(rhoaer_s,rhoaer_f,ssa_s,ssa_f,ssa_cld,asf_s,asf_f,asf_cld)
    112125 
    113126  logical,save :: firstcall=.true.
     
    141154  ENDIF
    142155
    143   !=======================================================================
    144   !     Determine the total gas opacity throughout the column, for each
    145   !     spectral interval, NW, and each Gauss point, NG.
    146   !     Calculate the continuum opacities, i.e., those that do not depend on
    147   !     NG, the Gauss index.
    148 
    149   taugsurf(:,:) = 0.0
    150   dpr(:)        = 0.0
    151   lkcoef(:,:)   = 0.0
    152 
    153   do K=2,L_LEVELS
    154  
    155      ilay = L_NLAYRAD+1 - k/2 ! int. arithmetic => gives the gcm layer index (reversed)
    156  
    157      DPR(k) = PLEV(K)-PLEV(K-1)
    158 
    159      ! if we have continuum opacities, we need dz
    160 
     156   !=======================================================================
     157   !     Determine the total gas opacity throughout the column, for each
     158   !     spectral interval, NW, and each Gauss point, NG.
     159   !     Calculate the continuum opacities, i.e., those that do not depend on
     160   !     NG, the Gauss index.
     161
     162   taugsurf(:,:) = 0.0
     163   dpr(:)        = 0.0
     164   lkcoef(:,:)   = 0.0
     165
     166   do K=2,L_LEVELS
     167      ilay = L_NLAYRAD+1 - k/2 ! int. arithmetic => gives the gcm layer index (reversed)
     168      DPR(k) = PLEV(K)-PLEV(K-1)
     169
     170      ! if we have continuum opacities, we need dz
    161171      dz(k) = dpr(k)*R*TMID(K)/(gzlat_ig(ilay)*PMID(K))
    162172      U(k)  = Cmk(ilay)*DPR(k)     ! only Cmk line in optcv.F     
    163173
    164      call tpindex(PMID(K),TMID(K),pfgasref,tgasref,LCOEF,MT(K),MP(K))
    165 
    166      do LK=1,4
    167         LKCOEF(K,LK) = LCOEF(LK)
    168      end do
    169   end do                    ! levels
    170 
    171   ! Rayleigh scattering
    172   do NW=1,L_NSPECTV
    173      TRAY(1:4,NW)   = 1.d-30
    174      do K=5,L_LEVELS
    175         TRAY(K,NW)   = TAURAY(NW) * DPR(K)
    176      end do                    ! levels
    177   end do
    178  
    179   !     we ignore K=1...
    180   do K=2,L_LEVELS
    181  
    182      ilay = L_NLAYRAD+1 - k/2 ! int. arithmetic => gives the gcm layer index (reversed)
    183 
    184      do NW=1,L_NSPECTV
    185      
    186         IF (callmufi .AND. (.NOT. uncoupl_optic_haze)) THEN
    187           m3as = pqmo(ilay,2) / 2.0
    188           m3af = pqmo(ilay,4) / 2.0
    189          
    190           IF ( ilay .lt. 18 ) THEN
    191             m3as = pqmo(18,2) / 2.0 * dz(k) / dz(18)
    192             m3af = pqmo(18,4) / 2.0 * dz(k) / dz(18)
    193           ENDIF
    194 
    195           dtauaer_s     = m3as*rhoaer_s(nw)
    196           dtauaer_f     = m3af*rhoaer_f(nw)
    197           DHAZE_T(k,nw) = dtauaer_s + dtauaer_f
    198 
    199           IF ( dtauaer_s + dtauaer_f .GT. 1.D-30 ) THEN
    200             SSA_T(k,nw)   = ( dtauaer_s*ssa_s(nw) + dtauaer_f*ssa_f(nw) ) / ( dtauaer_s+dtauaer_f )
    201             ASF_T(k,nw)   = ( dtauaer_s*ssa_s(nw)*asf_s(nw) + dtauaer_f*ssa_f(nw)*asf_f(nw) )  &
    202                             / ( ssa_s(nw)*dtauaer_s + ssa_f(nw)*dtauaer_f )
    203           ELSE
    204              DHAZE_T(k,nw) = 0.D0
    205              SSA_T(k,nw)   = 1.0
    206              ASF_T(k,nw)   = 1.0
    207           ENDIF
    208          
    209           IF (callclouds.and.firstcall) &
    210             WRITE(*,*) 'WARNING: In optcv, optical properties &
    211                        &calculations are not implemented yet'
    212         ELSE
    213           ! Call fixed vertical haze profile of extinction - same for all columns
    214           call disr_haze(dz(k),plev(k),wnov(nw),DHAZE_T(k,nw),SSA_T(k,nw),ASF_T(k,nw))
    215           if (seashaze) DHAZE_T(k,nw) = DHAZE_T(k,nw)*seashazefact(k)
    216         ENDIF
    217        
    218         !JL18 It seems to be good to have aerosols in the first "radiative layer" of the gcm in the IR
    219         !   but visible does not handle very well diffusion in first layer.
    220         !   The tauaero and tauray are thus set to 0 (a small value for rayleigh because the code crashes otherwise)
    221         !   in the 4 first semilayers in optcv, but not optci.
    222         !   This solves random variations of the sw heating at the model top.
    223         if (k<5)  DHAZE_T(K,:) = 0.0
     174      call tpindex(PMID(K),TMID(K),pfgasref,tgasref,LCOEF,MT(K),MP(K))
     175
     176      do LK=1,4
     177         LKCOEF(K,LK) = LCOEF(LK)
     178      end do
     179   end do ! L_LEVELS
     180
     181   ! Rayleigh scattering
     182   do NW=1,L_NSPECTV
     183      TRAY(1:4,NW)   = 1.d-30
     184      do K=5,L_LEVELS
     185         TRAY(K,NW)   = TAURAY(NW) * DPR(K)
     186      end do ! L_LEVELS
     187   end do
     188 
     189   do NW=1,L_NSPECTV
     190      ! We ignore K=1...
     191      do K=2,L_LEVELS
     192         ! int. arithmetic => gives the gcm layer index (reversed)
     193         ilay = L_NLAYRAD+1 - k/2
    224194         
    225         DRAYAER = TRAY(K,NW)
    226         !     DRAYAER is Tau RAYleigh scattering, plus AERosol opacity
    227         DRAYAER = DRAYAER + DHAZE_T(K,NW) ! Titan's aerosol
    228 
    229         DCONT = 0.0 ! continuum absorption
    230 
    231         if(continuum.and.(.not.graybody).and.callgasvis)then
    232            ! include continua if necessary
    233            wn_cont = dble(wnov(nw))
    234            T_cont  = dble(TMID(k))
    235            do igas=1,ngasmx
    236 
    237               p_cont  = dble(PMID(k)*scalep*gfrac(igas,ilay))
    238 
    239               dtemp=0.0
    240               if(igas.eq.igas_N2)then
    241 
    242                  interm = indv(nw,igas,igas)
    243 !                 call interpolateN2N2(wn_cont,T_cont,p_cont,dtemp,.false.,interm)
    244                  indv(nw,igas,igas) = interm
    245                  ! only goes to 500 cm^-1, so unless we're around a cold brown dwarf, this is irrelevant in the visible
    246 
    247               elseif(igas.eq.igas_H2)then
    248 
    249                  ! first do self-induced absorption
    250                  interm = indv(nw,igas,igas)
    251                  call interpolateH2H2(wn_cont,T_cont,p_cont,dtemp,.false.,interm)
    252                  indv(nw,igas,igas) = interm
    253 
    254                  ! then cross-interactions with other gases
    255                  do jgas=1,ngasmx
    256                     p_cross = dble(PMID(k)*scalep*gfrac(jgas,ilay))
    257                     dtempc  = 0.0
    258                     if(jgas.eq.igas_N2)then
    259                        interm = indv(nw,igas,jgas)
    260                        call interpolateN2H2(wn_cont,T_cont,p_cross,p_cont,dtempc,.false.,interm)
    261                        indv(nw,igas,jgas) = interm
    262                        ! should be irrelevant in the visible
    263                     endif
    264                     dtemp = dtemp + dtempc
    265                  enddo
    266 
    267                elseif(igas.eq.igas_CH4)then
    268 
    269                  ! first do self-induced absorption
    270                  interm = indv(nw,igas,igas)
    271                  call interpolateCH4CH4(wn_cont,T_cont,p_cont,dtemp,.false.,interm)
    272                  indv(nw,igas,igas) = interm
    273 
    274                  ! then cross-interactions with other gases
    275                  do jgas=1,ngasmx
    276                     p_cross = dble(PMID(k)*scalep*gfrac(jgas,ilay))
    277                     dtempc  = 0.0
    278                     if(jgas.eq.igas_N2)then
    279                        interm = indv(nw,igas,jgas)
    280                        call interpolateN2CH4(wn_cont,T_cont,p_cross,p_cont,dtempc,.false.,interm)
    281                        indv(nw,igas,jgas) = interm
    282                     endif
    283                     dtemp = dtemp + dtempc
    284                  enddo
    285 
    286               endif
    287 
    288               DCONT = DCONT + dtemp
    289 
    290            enddo
    291 
    292            DCONT = DCONT*dz(k)
    293 
    294         endif
    295 
    296         do ng=1,L_NGAUSS-1
    297 
    298            ! Now compute TAUGAS
    299 
    300            ! JVO 2017 : added tmpk because the repeated calls to gasi/v increased dramatically
    301            ! the execution time of optci/v -> ~ factor 2 on the whole radiative
    302            ! transfer on the tested simulations !
    303 
    304            if (corrk_recombin) then
    305              tmpk = GASV_RECOMB(MT(K):MT(K)+1,MP(K):MP(K)+1,NW,NG)
    306            else
    307              tmpk = GASV(MT(K):MT(K)+1,MP(K):MP(K)+1,1,NW,NG)
    308            endif
    309              
    310            KCOEF(1) = tmpk(1,1) ! KCOEF(1) = GASV(MT(K),MP(K),1,NW,NG)
    311            KCOEF(2) = tmpk(1,2) ! KCOEF(2) = GASV(MT(K),MP(K)+1,1,NW,NG)
    312            KCOEF(3) = tmpk(2,2) ! KCOEF(3) = GASV(MT(K)+1,MP(K)+1,1,NW,NG)
    313            KCOEF(4) = tmpk(2,1) ! KCOEF(4) = GASV(MT(K)+1,MP(K),1,NW,NG)
    314 
    315            ! Interpolate the gaseous k-coefficients to the requested T,P values
    316 
    317            ANS = LKCOEF(K,1)*KCOEF(1) + LKCOEF(K,2)*KCOEF(2) +            &
    318                 LKCOEF(K,3)*KCOEF(3) + LKCOEF(K,4)*KCOEF(4)
    319 
    320 
    321            TAUGAS  = U(k)*ANS
    322 
    323            TAUGSURF(NW,NG) = TAUGSURF(NW,NG) + TAUGAS + DCONT
    324            DTAUKV(K,nw,ng) = TAUGAS &
    325                              + DRAYAER & ! DRAYAER includes all scattering contributions
    326                              + DCONT ! For parameterized continuum aborption
    327 
    328         end do
    329 
    330         ! Now fill in the "clear" part of the spectrum (NG = L_NGAUSS),
    331         ! which holds continuum opacity only
    332 
    333         NG              = L_NGAUSS
    334         DTAUKV(K,nw,ng) = DRAYAER + DCONT ! Scattering + parameterized continuum absorption, including Titan's haze
    335 
    336      end do
    337   end do
    338 
     195         ! Optics coupled with the microphysics :
     196         IF (callmufi .AND. (.NOT. uncoupl_optic_haze)) THEN
     197
     198            !==========================================================================================
     199            ! Old optics (must have callclouds = .false.):
     200            !==========================================================================================
     201            IF (.NOT. opt4clouds) THEN
     202               m3as = pqmo(ilay,2) / 2.0
     203               m3af = pqmo(ilay,4) / 2.0
     204               ! Cut-off
     205               IF (ilay .lt. 19) THEN
     206                  m3as = pqmo(19,2) / 2.0 * (zlev(ilay+1)-zlev(ilay)) / (zlev(20)-zlev(19))
     207                  m3af = pqmo(19,4) / 2.0 * (zlev(ilay+1)-zlev(ilay)) / (zlev(20)-zlev(19))
     208               ENDIF
     209               
     210               dtauaer_s = m3as*rhoaer_s(nw)
     211               dtauaer_f = m3af*rhoaer_f(nw)
     212
     213            !==========================================================================================
     214            ! New optics :
     215            !==========================================================================================
     216            ELSE
     217               iw = (L_NSPECTV + 1) - NW ! Visible first and return
     218               !-----------------------------
     219               ! HAZE (Spherical + Fractal) :
     220               !-----------------------------
     221               FTYPE = 1
     222
     223               ! Spherical aerosols :
     224               !---------------------
     225               CTYPE = 5
     226               m0as  = pqmo(ilay,1) / 2.0
     227               m3as  = pqmo(ilay,2) / 2.0
     228               ! If not callclouds : must have a cut-off
     229               IF (.NOT. callclouds) THEN
     230                  IF (ilay .lt. 19) THEN
     231                     m0as = pqmo(19,1) / 2.0 * (zlev(ilay+1)-zlev(ilay)) / (zlev(20)-zlev(19))
     232                     m3as = pqmo(19,2) / 2.0 * (zlev(ilay+1)-zlev(ilay)) / (zlev(20)-zlev(19))
     233                  ENDIF
     234               ENDIF
     235               call get_haze_and_cloud_opacity(FTYPE,CTYPE,m0as,m3as,iw,dtauaer_s,ssa_s(nw),asf_s(nw))
     236
     237               ! Fractal aerosols :
     238               !-------------------
     239               CTYPE = FTYPE
     240               m0af  = pqmo(ilay,3) / 2.0
     241               m3af  = pqmo(ilay,4) / 2.0
     242               ! If not callclouds : must have a cut-off
     243               IF (.NOT. callclouds) THEN
     244                  IF (ilay .lt. 19) THEN
     245                     m0af = pqmo(19,3) / 2.0 * (zlev(ilay+1)-zlev(ilay)) / (zlev(20)-zlev(19))
     246                     m3af = pqmo(19,4) / 2.0 * (zlev(ilay+1)-zlev(ilay)) / (zlev(20)-zlev(19))
     247                  ENDIF
     248               ENDIF
     249               call get_haze_and_cloud_opacity(FTYPE,CTYPE,m0af,m3af,iw,dtauaer_f,ssa_f(nw),asf_f(nw))
     250            ENDIF
     251
     252            ! Total of Haze opacity (dtau), SSA (w) and ASF (COS) :
     253            DHAZE_T(k,nw) = dtauaer_s + dtauaer_f
     254            IF (dtauaer_s + dtauaer_f .GT. 1.D-30) THEN
     255               SSA_T(k,nw) = ( dtauaer_s*ssa_s(nw) + dtauaer_f*ssa_f(nw) ) / ( dtauaer_s+dtauaer_f )
     256               ASF_T(k,nw) = ( dtauaer_s*ssa_s(nw)*asf_s(nw) + dtauaer_f*ssa_f(nw)*asf_f(nw) )  &
     257                             / ( ssa_s(nw)*dtauaer_s + ssa_f(nw)*dtauaer_f )
     258            ELSE
     259               DHAZE_T(k,nw) = 0.D0
     260               SSA_T(k,nw)   = 1.0
     261               ASF_T(k,nw)   = 1.0
     262            ENDIF
     263            ! Diagnostics for the haze :
     264            POPT_HAZE(k,nw,1) = DHAZE_T(k,nw) ! dtau
     265            POPT_HAZE(k,nw,2) = SSA_T(k,nw)   ! wbar
     266            POPT_HAZE(k,nw,3) = ASF_T(k,nw)   ! gbar
     267
     268            !---------------------
     269            ! CLOUDS (Spherical) :
     270            !---------------------
     271            IF (callclouds) THEN
     272               CTYPE = 0
     273               m0ccn = pqmo(ilay,5) / 2.0
     274               m3ccn = pqmo(ilay,6) / 2.0
     275               m3ices = 0.0d0
     276               m3cld  = m3ccn
     277               
     278               ! Clear / Dark column method :
     279               !-----------------------------
     280
     281               ! CCN's SSA :
     282               call get_haze_and_cloud_opacity(FTYPE,FTYPE,m0ccn,m3ccn,iw,dtau_ccn,ssa_ccn(nw),asf_ccn(nw))
     283
     284               ! Clear column (CCN, C2H2, C2H6, HCN) :
     285               IF (CDCOLUMN == 0) THEN
     286                  DO iq = 2, nice
     287                     m3ices = m3ices + (pqmo(ilay,ices_indx(iq)) / 2.0)
     288                     m3cld  = m3cld + (pqmo(ilay,ices_indx(iq)) / 2.0)
     289                  ENDDO
     290                  call get_haze_and_cloud_opacity(FTYPE,CTYPE,m0ccn,m3cld,iw,dtau_cld,ssa_cld(nw),asf_cld(nw))
     291               
     292               ! Dark column (CCN, CH4, C2H2, C2H6, HCN) :
     293               ELSEIF (CDCOLUMN == 1) THEN
     294                  DO iq = 1, nice
     295                     m3ices = m3ices + (pqmo(ilay,ices_indx(iq)) / 2.0)
     296                     m3cld  = m3cld + (pqmo(ilay,ices_indx(iq)) / 2.0)
     297                  ENDDO
     298                  call get_haze_and_cloud_opacity(FTYPE,CTYPE,m0ccn,m3cld,iw,dtau_cld,ssa_cld(nw),asf_cld(nw))
     299               
     300               ELSE
     301                  WRITE(*,*) 'WARNING OPTCV.F90 : CDCOLUMN MUST BE 0 OR 1'
     302                  WRITE(*,*) 'WE USE DARK COLUMN ...'
     303                  DO iq = 1, nice
     304                     m3ices = m3ices + (pqmo(ilay,ices_indx(iq)) / 2.0)
     305                     m3cld  = m3cld + (pqmo(ilay,ices_indx(iq)) / 2.0)
     306                  ENDDO
     307                  call get_haze_and_cloud_opacity(FTYPE,CTYPE,m0ccn,m3cld,iw,dtau_cld,ssa_cld(nw),asf_cld(nw))
     308               ENDIF
     309
     310               ! For small dropplets, opacity of nucleus dominates
     311               !ssa_cld(nw) = (ssa_ccn(nw)*m3ccn + ssa_cld(nw)*m3ices) / (m3ccn + m3ices)
     312               ssa_cld(nw) = (ssa_ccn(nw)*m3ccn + ssa_cld(nw)*m3cld) / (m3ccn + m3cld)
     313               ssa_cld(nw) = ssa_cld(nw) * Fssa
     314
     315               ! Total of Haze + Clouds opacity (dtau), SSA (w) and ASF (COS) :
     316               DHAZE_T(k,nw) = dtauaer_s + dtauaer_f + dtau_cld
     317               IF (DHAZE_T(k,nw) .GT. 1.D-30) THEN
     318                  SSA_T(k,nw) = ( dtauaer_s*ssa_s(nw) + dtauaer_f*ssa_f(nw) + dtau_cld*ssa_cld(nw) ) / ( dtauaer_s+dtauaer_f+dtau_cld )
     319                  ASF_T(k,nw) = ( dtauaer_s*ssa_s(nw)*asf_s(nw) + dtauaer_f*ssa_f(nw)*asf_f(nw) + dtau_cld*ssa_cld(nw)*asf_cld(nw) ) &
     320                                / ( ssa_s(nw)*dtauaer_s + ssa_f(nw)*dtauaer_f + ssa_cld(nw)*dtau_cld )
     321               ELSE
     322                  DHAZE_T(k,nw) = 0.D0
     323                  SSA_T(k,nw)   = 1.0
     324                  ASF_T(k,nw)   = 1.0
     325               ENDIF
     326               
     327               ! Tuning of optical properties (now useless...) :
     328               DHAZE_T(k,nw) = DHAZE_T(k,nw) * (FHVIS * (1-SSA_T(k,nw)) + SSA_T(k,nw))
     329               SSA_T(k,nw)   = SSA_T(k,nw) / (FHVIS * (1-SSA_T(k,nw)) + SSA_T(k,nw))
     330
     331               ! Diagnostics for clouds :
     332               POPT_CLOUDS(k,nw,1) = DHAZE_T(k,nw) ! dtau
     333               POPT_CLOUDS(k,nw,2) = SSA_T(k,nw)   ! wbar
     334               POPT_CLOUDS(k,nw,3) = ASF_T(k,nw)   ! gbar
     335           
     336            ELSE
     337               ! Diagnostics for clouds :
     338               POPT_CLOUDS(k,nw,1) = 0.D0 ! dtau
     339               POPT_CLOUDS(k,nw,2) = 1.0  ! wbar
     340               POPT_CLOUDS(k,nw,3) = 1.0  ! gbar
     341            ENDIF
     342           
     343         ! Optics and microphysics no coupled :
     344         ELSE
     345            ! Call fixed vertical haze profile of extinction - same for all columns
     346            call disr_haze(dz(k),plev(k),wnov(nw),DHAZE_T(k,nw),SSA_T(k,nw),ASF_T(k,nw))
     347            if (seashaze) DHAZE_T(k,nw) = DHAZE_T(k,nw)*seashazefact(k)
     348            ! Diagnostics for the haze :
     349            POPT_HAZE(k,nw,1) = DHAZE_T(k,nw) ! dtau
     350            POPT_HAZE(k,nw,2) = SSA_T(k,nw)   ! wbar
     351            POPT_HAZE(k,nw,3) = ASF_T(k,nw)   ! gbar
     352            ! Diagnostics for clouds :
     353            POPT_CLOUDS(k,nw,1) = 0.D0 ! dtau
     354            POPT_CLOUDS(k,nw,2) = 1.0  ! wbar
     355            POPT_CLOUDS(k,nw,3) = 1.0  ! gbar
     356         ENDIF ! ENDIF callmufi
     357         
     358         !JL18 It seems to be good to have aerosols in the first "radiative layer" of the gcm in the IR
     359         !   but visible does not handle very well diffusion in first layer.
     360         !   The tauaero and tauray are thus set to 0 (a small value for rayleigh because the code crashes otherwise)
     361         !   in the 4 first semilayers in optcv, but not optci.
     362         !   This solves random variations of the sw heating at the model top.
     363         if (k<5)  DHAZE_T(K,:) = 0.0
     364         
     365         DRAYAER = TRAY(K,NW)
     366         ! DRAYAER is Tau RAYleigh scattering, plus AERosol opacity
     367         DRAYAER = DRAYAER + DHAZE_T(K,NW) ! Titan's aerosol
     368
     369         DCONT = 0.0 ! continuum absorption
     370
     371         if(continuum.and.(.not.graybody).and.callgasvis)then
     372            ! include continua if necessary
     373            wn_cont = dble(wnov(nw))
     374            T_cont  = dble(TMID(k))
     375            do igas=1,ngasmx
     376
     377               p_cont  = dble(PMID(k)*scalep*gfrac(igas,ilay))
     378
     379               dtemp=0.0
     380               if(igas.eq.igas_N2)then
     381
     382                  interm = indv(nw,igas,igas)
     383   !                 call interpolateN2N2(wn_cont,T_cont,p_cont,dtemp,.false.,interm)
     384                  indv(nw,igas,igas) = interm
     385                  ! only goes to 500 cm^-1, so unless we're around a cold brown dwarf, this is irrelevant in the visible
     386
     387               elseif(igas.eq.igas_H2)then
     388
     389                  ! first do self-induced absorption
     390                  interm = indv(nw,igas,igas)
     391                  call interpolateH2H2(wn_cont,T_cont,p_cont,dtemp,.false.,interm)
     392                  indv(nw,igas,igas) = interm
     393
     394                  ! then cross-interactions with other gases
     395                  do jgas=1,ngasmx
     396                     p_cross = dble(PMID(k)*scalep*gfrac(jgas,ilay))
     397                     dtempc  = 0.0
     398                     if(jgas.eq.igas_N2)then
     399                        interm = indv(nw,igas,jgas)
     400                        call interpolateN2H2(wn_cont,T_cont,p_cross,p_cont,dtempc,.false.,interm)
     401                        indv(nw,igas,jgas) = interm
     402                        ! should be irrelevant in the visible
     403                     endif
     404                     dtemp = dtemp + dtempc
     405                  enddo
     406
     407                  elseif(igas.eq.igas_CH4)then
     408
     409                  ! first do self-induced absorption
     410                  interm = indv(nw,igas,igas)
     411                  call interpolateCH4CH4(wn_cont,T_cont,p_cont,dtemp,.false.,interm)
     412                  indv(nw,igas,igas) = interm
     413
     414                  ! then cross-interactions with other gases
     415                  do jgas=1,ngasmx
     416                     p_cross = dble(PMID(k)*scalep*gfrac(jgas,ilay))
     417                     dtempc  = 0.0
     418                     if(jgas.eq.igas_N2)then
     419                        interm = indv(nw,igas,jgas)
     420                        call interpolateN2CH4(wn_cont,T_cont,p_cross,p_cont,dtempc,.false.,interm)
     421                        indv(nw,igas,jgas) = interm
     422                     endif
     423                     dtemp = dtemp + dtempc
     424                  enddo
     425
     426               endif
     427
     428               DCONT = DCONT + dtemp
     429
     430            enddo
     431
     432            DCONT = DCONT*dz(k)
     433
     434         endif
     435
     436         do ng=1,L_NGAUSS-1
     437
     438            ! Now compute TAUGAS
     439
     440            ! JVO 2017 : added tmpk because the repeated calls to gasi/v increased dramatically
     441            ! the execution time of optci/v -> ~ factor 2 on the whole radiative
     442            ! transfer on the tested simulations !
     443
     444            if (corrk_recombin) then
     445               tmpk = GASV_RECOMB(MT(K):MT(K)+1,MP(K):MP(K)+1,NW,NG)
     446            else
     447               tmpk = GASV(MT(K):MT(K)+1,MP(K):MP(K)+1,1,NW,NG)
     448            endif
     449               
     450            KCOEF(1) = tmpk(1,1) ! KCOEF(1) = GASV(MT(K),MP(K),1,NW,NG)
     451            KCOEF(2) = tmpk(1,2) ! KCOEF(2) = GASV(MT(K),MP(K)+1,1,NW,NG)
     452            KCOEF(3) = tmpk(2,2) ! KCOEF(3) = GASV(MT(K)+1,MP(K)+1,1,NW,NG)
     453            KCOEF(4) = tmpk(2,1) ! KCOEF(4) = GASV(MT(K)+1,MP(K),1,NW,NG)
     454
     455            ! Interpolate the gaseous k-coefficients to the requested T,P values
     456
     457            ANS = LKCOEF(K,1)*KCOEF(1) + LKCOEF(K,2)*KCOEF(2) +            &
     458                  LKCOEF(K,3)*KCOEF(3) + LKCOEF(K,4)*KCOEF(4)
     459
     460
     461            TAUGAS  = U(k)*ANS
     462
     463            TAUGSURF(NW,NG) = TAUGSURF(NW,NG) + TAUGAS + DCONT
     464            DTAUKV(K,nw,ng) = TAUGAS &
     465                              + DRAYAER & ! DRAYAER includes all scattering contributions
     466                              + DCONT ! For parameterized continuum aborption
     467         end do
     468
     469         ! Now fill in the "clear" part of the spectrum (NG = L_NGAUSS),
     470         ! which holds continuum opacity only
     471
     472         NG              = L_NGAUSS
     473         DTAUKV(K,nw,ng) = DRAYAER + DCONT ! Scattering + parameterized continuum absorption, including Titan's haze
     474
     475      end do ! k = L_LEVELS
     476   end do ! nw = L_NSPECTI
    339477
    340478  !=======================================================================
     
    355493  ENDDO
    356494
    357 
     495  ! NW spectral loop
    358496  DO NW=1,L_NSPECTV
    359      DO L=1,L_NLAYRAD-1
    360         K              = 2*L+1
    361         atemp(L,NW) = ASF_T(K,NW)*DHAZES_T(K,NW) + ASF_T(K+1,NW)*DHAZES_T(K+1,NW)
    362         btemp(L,NW) = DHAZES_T(K,NW) + DHAZES_T(K+1,NW)
    363         ctemp(L,NW) = btemp(L,NW) + 0.9999*(TRAY(K,NW) + TRAY(K+1,NW)) ! JVO 2017 : does this 0.999 is really meaningful ?
    364         btemp(L,NW) = btemp(L,NW) + TRAY(K,NW) + TRAY(K+1,NW)
    365         COSBV(L,NW,1:L_NGAUSS) = atemp(L,NW)/btemp(L,NW)
    366      END DO ! L vertical loop
     497   ! L vertical loop
     498   DO L=1,L_NLAYRAD-1
     499      K = 2*L+1
     500           atemp(L,NW) = ASF_T(K,NW)*DHAZES_T(K,NW) + ASF_T(K+1,NW)*DHAZES_T(K+1,NW)
     501      btemp(L,NW) = DHAZES_T(K,NW) + DHAZES_T(K+1,NW)
     502           ctemp(L,NW) = btemp(L,NW) + 0.9999*(TRAY(K,NW) + TRAY(K+1,NW)) ! JVO 2017 : does this 0.999 is really meaningful ?
     503           btemp(L,NW) = btemp(L,NW) + TRAY(K,NW) + TRAY(K+1,NW)
     504      COSBV(L,NW,1:L_NGAUSS) = atemp(L,NW)/btemp(L,NW)
     505   END DO
    367506     
    368      ! Last level
    369      L           = L_NLAYRAD
    370      K           = 2*L+1
    371      atemp(L,NW) = ASF_T(K,NW)*DHAZES_T(K,NW)
    372      btemp(L,NW) = DHAZES_T(K,NW)
    373      ctemp(L,NW) = btemp(L,NW) + 0.9999*TRAY(K,NW) ! JVO 2017 : does this 0.999 is really meaningful ?
    374      btemp(L,NW) = btemp(L,NW) + TRAY(K,NW)
    375      COSBV(L,NW,1:L_NGAUSS) = atemp(L,NW)/btemp(L,NW)
    376      
    377      
    378   END DO                    ! NW spectral loop
    379 
     507   ! Last level
     508   L = L_NLAYRAD
     509   K = 2*L+1
     510   atemp(L,NW) = ASF_T(K,NW)*DHAZES_T(K,NW)
     511   btemp(L,NW) = DHAZES_T(K,NW)
     512   ctemp(L,NW) = btemp(L,NW) + 0.9999*TRAY(K,NW) ! JVO 2017 : does this 0.999 is really meaningful ?
     513   btemp(L,NW) = btemp(L,NW) + TRAY(K,NW)
     514   COSBV(L,NW,1:L_NGAUSS) = atemp(L,NW)/btemp(L,NW)
     515  END DO
     516
     517  ! NG Gauss loop
    380518  DO NG=1,L_NGAUSS
    381     DO NW=1,L_NSPECTV
    382      DO L=1,L_NLAYRAD-1
    383 
    384         K              = 2*L+1
    385         DTAUV(L,nw,ng) = DTAUKV(K,NW,NG) + DTAUKV(K+1,NW,NG)
    386         WBARV(L,nw,ng) = ctemp(L,NW) / DTAUV(L,nw,ng)
    387 
    388       END DO ! L vertical loop
    389 
    390         ! Last level
    391 
    392         L              = L_NLAYRAD
    393         K              = 2*L+1
    394         DTAUV(L,nw,ng) = DTAUKV(K,NW,NG)
    395 
    396         WBARV(L,NW,NG) = ctemp(L,NW) / DTAUV(L,NW,NG)
    397 
    398      END DO                 ! NW spectral loop
    399   END DO                    ! NG Gauss loop
     519   ! NW spectral loop
     520   DO NW=1,L_NSPECTV
     521      ! L vertical loop
     522      DO L=1,L_NLAYRAD-1
     523         K = 2*L+1
     524         DTAUV(L,nw,ng) = DTAUKV(K,NW,NG) + DTAUKV(K+1,NW,NG)
     525         WBARV(L,nw,ng) = ctemp(L,NW) / DTAUV(L,nw,ng)
     526      END DO
     527
     528      ! Last level
     529      L = L_NLAYRAD
     530      K = 2*L+1
     531           DTAUV(L,nw,ng) = DTAUKV(K,NW,NG)
     532      WBARV(L,NW,NG) = ctemp(L,NW) / DTAUV(L,NW,NG)
     533   END DO
     534  END DO
    400535
    401536  ! Total extinction optical depths
    402 
    403   DO NG=1,L_NGAUSS       ! full gauss loop
    404      DO NW=1,L_NSPECTV       
    405         TAUCUMV(1,NW,NG)=0.0D0
    406         DO K=2,L_LEVELS
    407            TAUCUMV(K,NW,NG)=TAUCUMV(K-1,NW,NG)+DTAUKV(K,NW,NG)
    408         END DO
    409 
    410         DO L=1,L_NLAYRAD
    411            TAUV(L,NW,NG)=TAUCUMV(2*L,NW,NG)
    412         END DO
    413         TAUV(L,NW,NG)=TAUCUMV(2*L_NLAYRAD+1,NW,NG)
    414      END DO           
    415   END DO                 ! end full gauss loop
     537  !DO NG=1,L_NGAUSS       ! full gauss loop
     538  !   DO NW=1,L_NSPECTV       
     539  !      TAUCUMV(1,NW,NG)=0.0D0
     540  !      DO K=2,L_LEVELS
     541  !         TAUCUMV(K,NW,NG)=TAUCUMV(K-1,NW,NG)+DTAUKV(K,NW,NG)
     542  !      END DO
     543  !      DO L=1,L_NLAYRAD
     544  !         TAUV(L,NW,NG)=TAUCUMV(2*L,NW,NG)
     545  !      END DO
     546  !      TAUV(L,NW,NG)=TAUCUMV(2*L_NLAYRAD+1,NW,NG)
     547  !   END DO           
     548  !END DO                 ! end full gauss loop
     549 
     550  TAUCUMV(:,:,:) = DTAUKV(:,:,:)
     551  DO L=1,L_NLAYRAD
     552   TAUV(L,:,:)=TAUCUMV(2*L,:,:)
     553  END DO
     554  TAUV(L,:,:)=TAUCUMV(2*L_NLAYRAD+1,:,:)
    416555
    417556  if(firstcall) firstcall = .false.
Note: See TracChangeset for help on using the changeset viewer.