#include "rundeck_opts.h"

      SUBROUTINE masterchem 1,103
!@sum masterchem main chemistry routine
!@auth Drew Shindell (modelEifications by Greg Faluvegi)
!@ver  1.0 (based on masterchem000_M23p)   
!@calls photoj,checktracer,Crates,Oxinit,HOxfam,NOxfam,chemstep
C
C IF ALTERING THIS ROUTINE, PLEASE SEE THE WARNING ABOUT THE CHANGEL
C VARIABLE IN THE STRATOSPHERIC OVERWRITE SECTION.
c
C**** GLOBAL parameters and variables:
c
      USE SOMTQ_COM, only   : qmom
      USE DOMAIN_DECOMP,only: GRID,GET,AM_I_ROOT,PACK_COLUMN,
     &                        GLOBALSUM, PACK_DATA, PACK_DATAj,
     &                        write_parallel
      USE MODEL_COM, only   : Q,JDAY,IM,JM,sig,ptop,psf,ls1,JYEAR,
     &                        COUPLED_CHEM
      USE CONSTANT, only    : radian,gasc,mair,mb2kg,pi,avog
      USE DYNAMICS, only    : pedn,LTROPO
      USE FILEMANAGER, only : openunit,closeunit
      USE RAD_COM, only     : COSZ1,alb,rcloudfj=>rcld,
     &                        rad_to_chem,O3_tracer_save,H2ObyCH4,
     &                        SRDN,rad_to_file
      USE GEOM, only        : BYDXYP, DXYP, LAT_DG, IMAXJ
      USE FLUXES, only      : tr3Dsource
      USE TRACER_COM, only  : n_Ox,n_NOx,n_N2O5,n_HNO3,n_H2O2,n_CH3OOH,
     &                        n_HCHO,n_HO2NO2,n_CO,n_CH4,n_PAN,
     &                        n_Isoprene,n_AlkylNit,n_Alkenes,
     &                        n_Paraffin,ntm_chem,n_DMS,n_MSA,n_SO2,
     &                        n_SO4,n_H2O2_s,oh_live,no3_live,
     &                        nChemistry,nStratwrite,rsulf1,rsulf2,
     &                        rsulf3,rsulf4,TR_MM,trname,
     *                        mass2vol,vol2mass
#ifdef SHINDELL_STRAT_CHEM
     &                        ,n_HBr,n_HOCl,n_HCl,n_ClONO2,n_ClOx,
     &                        n_BrOx,n_BrONO2,n_CFC,n_N2O,n_HOBR
#endif
#ifdef regional_Ox_tracers
     &                        ,NregOx,n_OxREG1
#endif
#ifdef TRACERS_HETCHEM
     &                        ,krate,n_N_d1,n_N_d2,n_N_d3
#endif
#ifdef INTERACTIVE_WETLANDS_CH4
      USE TRACER_SOURCES, only: avg_model,n__sw
#endif
      USE TRDIAG_COM, only    : jls_N2O5sulf,tajls=>tajls_loc,
     & taijs=>taijs_loc,ijs_JH2O2,ijs_NO3,jls_COp,jls_COd,jls_Oxp,
     & jls_Oxd
#ifdef SHINDELL_STRAT_CHEM
     &                           ,jls_ClOcon,jls_H2Ocon
#endif
      USE TRCHEM_Shindell_COM

      IMPLICIT NONE

C**** Local parameters and variables and arguments:
!@param by35 1/35 used for spherical geometry constant
!@param JN J around 30 N
!@param JS J around 30 S
!@param JNN,JSS Js for "high-lat" definition
!@param nlast either ntm_chem or ntm_chem-NregOx for chemistry loops
      INTEGER, PARAMETER :: JS = JM/3 + 1, JN = 2*JM/3
      INTEGER, PARAMETER :: JNN = 5*JM/6, JSS= JM/6 + 1
      INTEGER, PARAMETER :: nlast =
#ifdef regional_Ox_tracers
     &                              ntm_chem-NregOx
#else
     &                              ntm_chem
#endif
      REAL*8, PARAMETER  :: by35=1.d0/35.d0
      REAL*8, PARAMETER  :: bymair = 1.d0/mair
      REAL*8, PARAMETER, DIMENSION(LM) :: thick = (/
     & 0.3d0,0.36d0,0.44d0,0.65d0,1.2d0,1.6d0,2.0d0,2.0d0,1.6d0,
     & 1.6d0,1.5d0,1.6d0,1.9d0,2.5d0,3.7d0,3.6d0,4.0d0,5.2d0,
     & 7.4d0,8.6d0,8.6d0,9.2d0,12.4d0/)
!@var FASTJ_PFACT temp factor for vertical pressure-weighting
!@var FACT1,2,3 temp variable for start overwrite
!@var bydtsrc reciprocal of the timestep dtsrc
!@var local logical for error checking 
!@var byam75 the reciprocal air mass near 75 hPa level
!@var average tropospheric ch4 value near 569 hPa level
!@var PRES2 local nominal pressure for verticle interpolations
!@var thick thickness of each layer in km
!@var photO2_glob for O2->Ox diagnostic
!@var ClOx_old total ClOx at start of chemical timestep
!@var ClTOT total chlorine in all forms (reactive and reservoir)
!@var colmO2, colmO3 are overhead oxygen and ozone columns
!@var CH4FACT, r179 for setting CH4 ICs and strat distribution
!@var changeClONO2,changeClOx,changeHOCl,changeHCl nighttime changes
!@var changehetClONO2 nighttime het change in ClONO2 (on sulfate)
!@var pscX flag for psc existence
!@var chg106,chg107,chg108,chg109 reaction rates for het rxns on pscs
!@var rmrClOx,rmrBrOx dummy vars with mixing ratios of halogens
!@var rmv dummy variable for halogne removal in trop vs height
!@var changeL 2D array holds the local change due to chem or strat 
!@+   overwrite until adding to tr3Dsource (replaces 4D "change")
!@var PIfact strat-overwrite adjustment for preindustrial runs
!@var pfactor to convert units on species chemical changes
!@var bypfactor to convert units on species chemical changes
!@var dNO3,gwprodHNO3,gprodHNO3,gwprodN2O5,changeAldehyde,
!@+   changeAlkenes,changeIsoprene,changeHCHO,changeAlkylNit,
!@+   changeHNO3,changeNOx,changeN2O5,wprodHCHO working variables to 
!@+   calculate nighttime chemistry changes
!@var rlossN,rprodN,ratioN variables for nitrogen conservation
!@var I,J,L,N,igas,inss,LL,Lqq,JJ,J3,L2,n2 dummy loop variables
!@var avgTT_CH4 Itime avg CH4 # density at LTROPO between 20N and 20S
!@var avgTT_H2O Itime avg H2O # density at LTROPO between 20N and 20S
!@var countTT # of points between 20N and 20S on LTROPO plane
!@var aero yes(1) or no(0) tag of non-zero rkext from Crates
!@var imonth,m only needed to choose Ox strat correction factors
!@var maxl chosen tropopause 0=LTROPO(I,J), 1=LS1-1
!@var sumOx for summing regional Ox tracers
!@var bysumOx reciprocal of sum of regional Ox tracers
      REAL*8, DIMENSION(LM,NTM) :: changeL
      REAL*8, DIMENSION(NTM)    :: PIfact
      REAL*8, DIMENSION(LM)     :: PRES2
      REAL*8 :: FACT1,FACT2,FACT3,FACT4,FACT5,FACT6,FACT7,fact_so4,
     &  FASTJ_PFACT,bydtsrc,byam75,byavog,CH4FACT,r179,rlossN,
     &  rprodN,ratioN,pfactor,bypfactor,gwprodHNO3,gprodHNO3,
     &  gwprodN2O5,wprod_sulf,wprodCO,dNO3,wprodHCHO,prod_sulf,
     &  RVELN2O5,changeAldehyde,changeAlkenes,changeAlkylNit,
     &  changeIsoprene,changeHCHO,changeHNO3,changeNOx,changeN2O5,
     &  changeOx,fraQ,CH4_569,count_569
#ifdef TRACERS_HETCHEM
      REAL*8 :: changeN_d1,changeN_d2,changeN_d3
#endif
#ifdef regional_Ox_tracers
      REAL*8 :: sumOx, bysumOx
#endif
#ifdef INTERACTIVE_WETLANDS_CH4
      REAL*8 :: temp_SW
#endif
#ifdef SHINDELL_STRAT_CHEM
      REAL*8, DIMENSION(LM)     :: ClOx_old  
      REAL*8 :: CLTOT,colmO2,colmO3,changeClONO2,changeClOx,
     & changeHOCl,changeHCl,changehetClONO2,pscX,chg106,chg107,
     & chg108,chg109,rmrClOx,rmrBrOx,rmv,rmrOx,avgTT_H2O,avgTT_CH4,
     & countTT
      INTEGER, DIMENSION(LM)    :: aero
#endif
      INTEGER                   :: igas,LL,I,J,L,N,inss,Lqq,J3,L2,n2,
     &                             Jqq,Iqq,imonth,m,maxl,iu
      LOGICAL                   :: error, jay
      CHARACTER*4               :: ghg_name
      CHARACTER*80              :: ghg_file
      character(len=300)        :: out_line

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C Some variables defined especially for MPI compliance :         C 
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
      real*8, dimension(LM,IM,JM,5) :: rad_to_file_glob
      real*8, dimension(LM,IM,JM)   :: ss27_glob
      real*8 :: ss27(LM,IM,GRID%J_STRT_HALO:GRID%J_STOP_HALO)
      real*8, dimension(JM)         :: DU_O3_glob
#ifdef SHINDELL_STRAT_CHEM
      real*8, dimension(JM,LM)      :: photO2_glob
#endif
      real*8 :: avgTT_CH4_part(GRID%J_STRT_HALO:GRID%J_STOP_HALO),
     &          avgTT_H2O_part(GRID%J_STRT_HALO:GRID%J_STOP_HALO),
     &            CH4_569_part(GRID%J_STRT_HALO:GRID%J_STOP_HALO),
     &            countTT_part(GRID%J_STRT_HALO:GRID%J_STOP_HALO),
     &          count_569_part(GRID%J_STRT_HALO:GRID%J_STOP_HALO)
      
      INTEGER :: J_0, J_1, J_0S, J_1S
      LOGICAL :: HAVE_SOUTH_POLE, HAVE_NORTH_POLE     
      
      CALL GET(grid, J_STRT    =J_0,  J_STOP    =J_1,
     &               J_STRT_SKP=J_0S, J_STOP_SKP=J_1S,
     &               HAVE_SOUTH_POLE = HAVE_SOUTH_POLE,
     &               HAVE_NORTH_POLE = HAVE_NORTH_POLE)
      
      byavog = 1.d0/avog
#ifdef INITIAL_GHG_SETUP
C-------- special section for ghg runs ---------
      write(out_line,*)'Warning: INITIAL_GHG_SETUP is on!'
      call write_parallel(trim(out_line))
      if(use_rad_ch4>0 .or. use_rad_n2o>0 .or. use_rad_cfc>0)then
        rad_to_file(:,:,J_0:J_1,1)=rad_to_chem(:,:,J_0:J_1,1)
        rad_to_file(:,:,J_0:J_1,2)=rad_to_chem(:,:,J_0:J_1,2)
        do j=J_0,J_1
          rad_to_file(:,:,j,3)=rad_to_chem(:,:,j,3)*2.69e20*byavog*
     &    dxyp(j)*tr_mm(n_N2O) ! i.e. in trm units now!
          rad_to_file(:,:,j,4)=rad_to_chem(:,:,j,4)*2.69e20*byavog*
     &    dxyp(j)*tr_mm(n_CH4) ! i.e. in trm units now!
          rad_to_file(:,:,j,5)=rad_to_chem(:,:,j,5)*2.69e20*byavog*
     &    dxyp(j)*tr_mm(n_CFC)*fact_CFC ! i.e. in trm units now!
        enddo 
        do m=1,5
          call PACK_COLUMN
     &    (grid, rad_to_file(:,:,:,m), rad_to_file_glob(:,:,:,m))
        end do
        if(AM_I_ROOT( ))then
          write(ghg_name,'(I4)') JYEAR  
          ghg_file='GHG_IC_'//ghg_name
          call openunit(ghg_file,iu,.true.,.false.)
          do j=1,5
            write(iu)ghg_file,rad_to_file_glob(:,:,:,j)
          enddo
          call closeunit(iu)          
          write(6,*)'Stopping in masterchem to output inital'
          write(6,*)'conditions for ghgs. You must now recompile'
          write(6,*)'(rerun setup) after removing the'
          write(6,*)'INITIAL_GHG_SETUP directive from your rundeck'
          write(6,*)' & linking the GHGic file to: ',trim(ghg_file)
          write(6,*)'Address questions to Greg Faluvegi. Thanks.'
          call stop_model('Normal INITIAL_GHG_SETUP stop.',255)
        endif
      endif 
#endif

C Some INITIALIZATIONS :
      byavog  = 1.d0/avog
      bydtsrc = 1.d0/dtsrc
      BYFJM   = 1.d0/real(JM)
      PRES2(:)= SIG(:)*(PSF-PTOP)+PTOP
#ifdef SHINDELL_STRAT_CHEM
      if(H2ObyCH4 /= 0.)               
     &call stop_model('H2ObyCH4 not = 0 and strat chem is on.',255)
#endif
#ifdef INTERACTIVE_WETLANDS_CH4
C Not really related to chemistry, but convenient place to update
C running-averages for interactive wetlands CH4:
      do J=J_0,J_1; do I=1,IMAXJ(J)
        temp_SW=ALB(I,J,1)*(SRDN(I,J)+1.d-20)*COSZ1(I,J)
        call running_average(temp_SW,I,J,1.d0,n__sw)
      end do      ; end do
#endif

C Calculation of gas phase reaction rates for sulfur chemistry:
      CALL GET_SULF_GAS_RATES
      
#ifdef TRACERS_HETCHEM
c Calculation of removal rates on dust surfaces:
      CALL HETCDUST
#endif

c Set "chemical time step". Really this is a method of applying only
c a fraction of the chemistry change to the tracer mass for the first
c 30 hours.  That fraction is: dt2/dtscr.  E.g. in the first hour it
c is (dtsrc/24)/dtsrc = 1/24th of the chemistry change is applied.
c This is to work around initial instabilities.

      if(Itime-ItimeI <= 3)then
        dt2=dtsrc/24.d0          ! e.g. 150.
      elseif(Itime-ItimeI > 3 .and. Itime-ItimeI <= 6)then
        dt2=dtsrc/12.d0          ! e.g. 300.
      elseif(Itime-ItimeI > 6 .and. Itime-ItimeI <= 11)then
        dt2=dtsrc/6.d0           ! e.g. 600.
      elseif(Itime-ItimeI > 11 .and. Itime-ItimeI <= 30)then
        dt2=dtsrc/2.4d0          ! e.g. 1500.
      elseif(Itime-ItimeI > 30)then
        dt2=dtsrc                ! e.g. 3600
      endif

c Calculate new photolysis rates every n_phot main timesteps:
      MODPHOT= 0 !!!!!!!!!!!!MOD(Itime-ItimeI,n_phot)

C CALCULATE TX, THE REAL TEMPERATURE:
C (note this section is already done in DIAG.f)
      IF(HAVE_SOUTH_POLE) THEN
        DO L=1,LM
          TX(1,1,L)=T(1,1,L)*PK(L,1,1)
          TX(2:IM,1,L)=TX(1,1,L)
        END DO
      ENDIF  
      IF(HAVE_NORTH_POLE) THEN
        DO L=1,LM
          TX(1,JM,L)=T(1,JM,L)*PK(L,1,JM)
          TX(2:IM,JM,L)=TX(1,JM,L)
        END DO
      ENDIF
      DO L=1,LM
        DO J=J_0S,J_1S
          TX(1:IM,J,L)=T(1:IM,J,L)*PK(L,1:IM,J)
        END DO
      END DO

#ifdef SHINDELL_STRAT_CHEM
C info to set strat H2O based on tropical tropopause H2O and CH4:
      if(Itime == ItimeI)then
        avgTT_H2O_part(:)=0.d0
        avgTT_CH4_part(:)=0.d0
        countTT_part(:)=0.d0
        do J=J_0S,J_1S
          if(LAT_DG(J,1) >= -20. .and. LAT_DG(J,1) <= 20.)then
            do I=1,IMAXJ(J)
              avgTT_H2O_part(J) = avgTT_H2O_part(J) + 
     &                            Q(I,J,LTROPO(I,J))*MWabyMWw
              if(use_rad_ch4 > 0) then
                avgTT_CH4_part(J) = avgTT_CH4_part(J) + 
     &          rad_to_chem(LTROPO(I,J),I,J,4)
     &          *2.69d20*byavog*mair*BYAM(LTROPO(I,J),I,J)
              else
                avgTT_CH4_part(J) = avgTT_CH4_part(J) +
     &          trm(I,J,LTROPO(I,J),n_CH4)
     &          *mass2vol(n_CH4)*BYDXYP(J)*BYAM(LTROPO(I,J),I,J)
              endif
              countTT_part(J) = countTT_part(J) + 1.d0
            end do
          end if
        end do
        CALL GLOBALSUM(grid, avgTT_CH4_part, avgTT_CH4, all=.true.)
        CALL GLOBALSUM(grid, avgTT_H2O_part, avgTT_H2O, all=.true.)
        CALL GLOBALSUM(grid, countTT_part,   countTT,   all=.true.)
        if(countTT <= 0.)call stop_model('countTT.le.0',255)
      end if
#endif


CCCC!$OMP  PARALLEL DO PRIVATE (changeL, FASTJ_PFACT,
CCCC!$OMP* rlossN,rprodN,ratioN,pfactor,bypfactor,gwprodHNO3,gprodHNO3,
CCCC!$OMP* gwprodN2O5,wprod_sulf,wprodCO,dNO3,wprodHCHO,prod_sulf,rveln2o5,
CCCC!$OMP* changeAldehyde,changeAlkenes,changeIsoprene,changeHCHO,
CCCC!$OMP* changeAlkylNit,changeHNO3,changeNOx,changeN2O5,changeOx,FACT_SO4,
CCCC#ifdef TRACERS_HETCHEM
CCCC!$OMP* changeN_d1,changeN_d2,changeN_d3,
CCCC#endif
CCCC#ifdef SHINDELL_STRAT_CHEM
CCCC!$OMP* aero, CLTOT, ClOx_old, COLMO2, COLMO3, changeClONO2, changeClOx,
CCCC!$OMP* changehetClONO2, changeHOCl, changeHCl,
CCCC!$OMP* chg106, chg107, chg108, chg109, fraQ,
CCCC!$OMP* pscx, rmrclox, rmrbrox, rmrox, rmv,
CCCC#endif
CCCC#ifdef regional_Ox_tracers
CCCC!$OMP* bysumOx, sumOx,     n2,
CCCC#endif
CCCC!$OMP* igas, inss, J, jay, L, LL, Lqq, maxl, N, error )
CCCC!$OMP* SHARED (N_NOX,N_HNO3,N_N2O5,N_HCHO,N_ALKENES,N_ISOPRENE,
CCCC!$OMP* N_ALKYLNIT)

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
      DO J=J_0,J_1                  ! >>>> MAIN J LOOP BEGINS <<<<

      DO I=1,IMAXJ(J)               ! >>>> MAIN I LOOP BEGINS <<<<
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

      if(checktracer_on) call checktracer(I,J)
      select case(which_trop)
      case(0); maxl=ltropo(I,J)
      case(1); maxl=ls1-1
      case default; call stop_model('which_trop problem 4',255)
      end select

      DO L=1,LM
#ifdef regional_Ox_tracers
C      Per Volker: make sure the regional Ox tracers didn't
C      diverge from total Ox:
       sumOx  =0.d0
       bysumOx=0.d0
       do n2=n_OxREG1,ntm_chem
         sumOx=sumOx+trm(i,j,l,n2)
       end do
       sumOx=MAX(sumOx,1.d-9) ! Per Drew: minimum to prevent NaN's
       bysumOx=1.d0/sumOx 
       do n2=n_OxREG1,ntm_chem
         trm(i,j,l,n2)=trm(i,j,l,n2)*trm(i,j,l,n_Ox)*bysumOx
       end do
#endif
c Initialize the 2D change variable:
       changeL(L,:)=0.d0
c Save presure and temperature in local arrays:
       pres(L)=PMID(L,I,J)
       ta(L)  =TX(I,J,L)
c Calculate M and set fixed ratios for O2 & H2:
       y(nM,L)=pres(L)/(ta(L)*1.38d-19)
       y(nO2,L)=y(nM,L)*pfix_O2
#ifdef SHINDELL_STRAT_CHEM
       if(pres2(l) > 20.d0)then
         y(nH2,L)=y(nM,L)*pfix_H2
       else
         ! Was: y(nH2,L)=y(nM,L)*pfix_H2*7.d1/(7.d1+L-maxl+1)
         ! Now: a drop of 0.3 molec/cm3 per 12 hPa decrease:
         y(nH2,L)=y(nM,L)*pfix_H2 + 2.5d-2*(pres2(L)-20.d0)
       endif
       CLTOT=0.d0
#else
       y(nH2,L)=y(nM,L)*pfix_H2
#endif

c Tracers (converted from mass to number density):
       do igas=1,nlast
         y(igas,L)=trm(I,J,L,igas)*y(nM,L)*mass2vol(igas)*
     &   BYDXYP(J)*BYAM(L,I,J)
       enddo

C Concentrations of DMS and SO2 for sulfur chemistry:
       if (coupled_chem == 1) then
         ydms(i,j,l)=trm(i,j,l,n_dms)*y(nM,L)*(28.0D0/62.0D0)*
     &   BYDXYP(J)*BYAM(L,I,J)
         yso2(i,j,l)=trm(i,j,l,n_so2)*y(nM,L)*(28.0D0/64.0D0)*
     &   BYDXYP(J)*BYAM(L,I,J)
       else
         ! Convert from pptv to molecule cm-3:
         ydms(i,j,l)=dms_offline(i,j,l)*1.0D-12*y(nM,L)
         yso2(i,j,l)=so2_offline(i,j,l)*1.0D-12*y(nM,L)
       endif

c If desired, fix the methane concentration used in chemistry:
C WHY IS THIS NECESSARY ANY MORE, NOW THAT GET_CH4_IC IS CALLED?
#ifndef SHINDELL_STRAT_CHEM
       if(fix_CH4_chemistry == 1) THEN
         if(J < JEQ)then ! SH
           y(n_CH4,L)=y(nM,L)*pfix_CH4_S
         else            ! NH
           y(n_CH4,L)=y(nM,L)*pfix_CH4_N
         endif
       end if
#endif
#ifdef SHINDELL_STRAT_CHEM
c Save initial ClOx amount for use in ClOxfam:
       ClOx_old(L)=trm(I,J,L,n_ClOx)*y(nM,L)*mass2vol(n_ClOx)*
     & BYDXYP(J)*BYAM(L,I,J)
#endif

c Limit N2O5 number density:
       if(y(n_N2O5,L) < 1.) y(n_N2O5,L)=1.d0
c Set H2O, based on Q:
       y(nH2O,L)=Q(I,J,L)*MWabyMWw*y(nM,L)
#ifdef SHINDELL_STRAT_CHEM
c Initialize stratospheric y(H2O) & GCM Q variable (!),
c based on tropical tropopause H2O and CH4:
       if(Itime == ItimeI .and. L > LTROPO(I,J)) then
         y(nH2O,L) =  y(nM,L)*(avgTT_H2O/countTT +
     &   2.d0*(avgTT_CH4/countTT-y(n_CH4,L)/y(nM,L)))
         fraQ=(y(nH2O,L)/(y(nM,L)*MWabyMWw))/Q(I,J,L)
         Q(I,J,L)=y(nH2O,L)/(y(nM,L)*MWabyMWw)
         if(fraQ < 1.)qmom(:,i,j,l)=qmom(:,i,j,l)*fraQ
       end if 
#endif

c Initialize various other species:
c - set [NO]=0 (where?) for first HOx calc, NO2 = NOx:
c - set reactive species for use in family chemistry & nighttime NO2:

       if(Itime == ItimeI)then 
         y(nAldehyde,L)=y(nM,L)*pfix_Aldehyde
       else
         y(nAldehyde,L)=yAldehyde(I,J,L)
       endif
       y(nNO2,L)     =y(n_NOx,L)*pNOx(I,J,L)
       y(nNO,L)      =y(n_NOx,L)*(1.-pNOx(I,J,L))
       y(nO3,L)      =pOx(I,J,L)*y(n_Ox,L)
       y(nCH3O2,L)   =yCH3O2(I,J,L)
       y(nC2O3,L)    =yC2O3(I,J,L)
       y(nXO2,L)     =yXO2(I,J,L)
       y(nXO2N,L)    =yXO2N(I,J,L)
       y(nRXPAR,L)   =yRXPAR(I,J,L)
       y(nROR,L)     =yROR(I,J,L)
#ifdef SHINDELL_STRAT_CHEM
       y(nCl2,L)     =yCl2(I,J,L)
       y(nCl2O2,L)   =yCl2O2(I,J,L)
       y(nOClO,L)    =y(n_ClOx,L)*pOClOx(I,J,L)
       y(nClO,L)     =y(n_ClOx,L)*pClOx(I,J,L)
       y(nCl,L)      =y(n_ClOx,L)*pClx(I,J,L)
       y(nBr,L)      =y(n_BrOx,L)*(1.d0-pBrOx(I,J,L))
       y(nBrO,L)     =y(n_BrOx,L)*pBrOx(I,J,L)
#endif
      END DO ! L

C For solar zenith angle, we use the arccosine of the COSZ1
C from the radiation code, which is the cosine of the solar zenith 
C angle averaged over the physics time step.
C If the solar zenith angle (sza) from the radiation code is > 90 deg,
C (and hence COSZ1 is set to 0), recalculate it with get_sza routine:
      IF(COSZ1(I,J) == 0.d0) THEN
        call get_sza(I,J,sza)
      ELSE
        sza = acos(COSZ1(I,J))*byradian
      END IF

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C                 BEGIN PHOTOLYSIS                               C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

      if(MODPHOT == 0)then ! i.e. not every time step

       ! additional SUNLIGHT criterion (see also fam chem criterion):
       if((ALB(I,J,1) /= 0.d0).AND.(sza < szamax))then
       
c       define column temperatures to be sent to FASTJ:
        TFASTJ = ta

#ifdef SHINDELL_STRAT_CHEM
c       define pressures to be sent to FASTJ (centers):
        PFASTJ2(1:LM) = PMID(1:LM,I,J)
        PFASTJ2(LM+1)=0.00206d0  ! P at SIGE(LM+1)
        PFASTJ2(LM+2)=0.00058d0  ! unknown, so fudged for now.
        PFASTJ2(LM+3)=0.00028d0  ! unknown, so fudged for now.
#else
c       define pressures to be sent to FASTJ (centers):
        DO LL=2,2*LM,2
          PFASTJ(LL) = PMID(LL/2,I,J)
        END DO
c       define pressures to be sent to FASTJ (edges):
        PFASTJ(1)=PEDN(1,I,J)
        DO LL=3,(2*LM)+1,2
          PFASTJ(LL) = PEDN((LL+1)/2,I,J)
        END DO
        PFASTJ((2*LM)+2) = 0.1d0*PFASTJ((2*LM)+1)
C       This is a fudge, so that we don't have to get mesosphere data:
        PFASTJ((2*LM)+2) = 0.00058d0 ! for 23 layer model...
#endif
        if(LM /= 23) call stop_model('check PFASTJ2(LM+X).',255)
        
#ifdef SHINDELL_STRAT_CHEM
c Pass O3 array (in ppmv) to fastj. Above these levels fastj2 uses
C Nagatani climatological O3, read in by chem_init: 
        if(LM /= 23)call stop_model('check O3_FASTJ(near LM)',255)
        DO LL=1,LM
          if(LL >= LM-1)y(nO3,LL)=y(n_Ox,LL)
          O3_FASTJ(LL)=y(nO3,LL)/y(nM,LL)
        END DO
#else
c Interpolate O3 (in ppmv) from bottom maxl model sigma levels
c (i.e. those levels normally in troposphere) onto bottom 2*maxl
c FASTJ levels. Above these levels fastj uses Nagatani climatological
c O3, read in by chem_init:
c
c       define O3 to be sent to FASTJ (centers):
        DO LL=2,2*maxl,2
          O3_FASTJ(LL)=y(nO3,LL/2)
        ENDDO
c       define O3 to be sent to FASTJ (edges):
        O3_FASTJ(1)=y(nO3,1)*O3_1_fact ! see parameter declaration...
        DO LL=3,2*maxl-1,2
c         interpolation factor, based on pressure:
          FASTJ_PFACT=(PFASTJ(LL)-PFASTJ(LL-1))/
     &    (PFASTJ(LL+1)-PFASTJ(LL-1))
          O3_FASTJ(LL)=y(nO3,(LL-1)/2)+
     &    (y(nO3,((LL-1)/2)+1)-y(nO3,(LL-1)/2))*FASTJ_PFACT
c         lower limit on O3:
          IF(O3_FASTJ(LL) < 0.d0) O3_FASTJ(LL)=-O3_FASTJ(LL) ! weird
        ENDDO
c       Convert to ppm (units used in fastj)
        DO LL=1,2*maxl
          O3_FASTJ(LL)=O3_FASTJ(LL)/(PFASTJ(LL)*2.55d10)
        ENDDO
#endif

        call photoj(I,J) ! CALL THE PHOTOLYSIS SCHEME

C Define and alter resulting photolysis coefficients (zj --> ss):
#ifdef SHINDELL_STRAT_CHEM
        colmO2=5.6d20 
        colmO3=5.0d16 
#endif
        DO L=JPNL,1,-1
          do inss=1,JPPJ
            ss(inss,L,I,J)=zj(L,inss)
            if(inss /= 22)ss(inss,L,I,J)=ss(inss,L,I,J)*
     &      (by35*SQRT(1.224d3*(cos(ABS(LAT_DG(J,1))*radian))**2.
     &      +1.d0)) ! spherical correction but excluding ClONO2.
#ifdef SHINDELL_STRAT_CHEM
c           reduce rates for gases that photolyze in window region
c           (~200nm):
            if(inss == 28)ss(inss,L,I,J)=ss(inss,L,I,J)*1.25d-1 !N2O
            if(inss == 26)ss(inss,L,I,J)=ss(inss,L,I,J)*1.25d-1 !CFC
#endif
          enddo
          taijs(i,j,ijs_JH2O2(l))=taijs(i,j,ijs_JH2O2(l))+ss(4,l,i,j)
#ifdef SHINDELL_STRAT_CHEM
          colmO2=colmO2+y(nO2,L)*thick(L)*1.d5
          colmO3=colmO3+y(nO3,L)*thick(L)*1.d5
c SF3 is photolysis of water in Schumann-Runge bands based on:
c Nicolet, Pl. Space Sci., p 871, 1983.
C SF3_fact is, if x[ ] = bin4_flux[ ]:
C {(x[present] - x[1988]) / (x[1991] - x[1988])} * 0.1E-6
C This gets ADDED to the 1.3E-6 factor in the SF3 calculation. Here,
C bin4_flux is a proxy for the flux from all 175-200nm bins. 
C (Drew says the ratio would be the same.)
          if(SF2_fact == 0.)call stop_model('SF2_fact=0 in master',255)
          if(pres2(L) <= 10.)then
            if((SF3_FACT+1.3d-6) < 0.)call stop_model
     &      ('(SF3_FACT+1.3d-6) < 0 in master',255)
            SF3(I,J,L)=6.d0*(SF3_FACT+1.3d-6)*EXP(-1.d-7*colmO2**.35)
     &      *by35*SQRT(1.224d3*(cos(ABS(LAT_DG(J,1))*radian))**2.+1.d0)
            SF3(I,J,L)=SF3(I,J,L)*5.d-2
          else
            SF3(I,J,L)=0.d0
          endif
C SF2 is photlysis of NO in bands (0-0) and (1-0) based on Nicolet,
C Pl. Space Sci., p 111, 1980. SF2_fact is a ratio representative of
C bands (0-0) and (1-0); =  bin5_flux[present] / bin5_flux[1988] :
          if(L > maxl)then
            if(colmO2 > 2.d19)then
              SF2(I,J,L)=4.5d-6*EXP(-(1.d-8*colmO2**.38+5.d-19*colmO3))
            else
              SF2(I,J,L)=4.75d-6*EXP(-1.5d-20*colmO2)
            endif
            SF2(I,J,L)=SF2(I,J,L)*SF2_fact*
     &      by35*SQRT(1.224d3*(cos(ABS(LAT_DG(J,1))*radian))**2.+1.d0)
          else
            SF2(I,J,L)=0.d0
          endif
#endif
        END DO

       endif ! (sunlight)
      endif  ! (modphot)                           
      
CCCCCCCCCCCCCCCCC END PHOTOLYSIS SECTION CCCCCCCCCCCCCCCCCCCCCCCCC

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C                 BEGIN CHEMISTRY                                C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC


c Calculate the chemical reaction rates:
      call Crates (I,J
#ifdef SHINDELL_STRAT_CHEM
     &                ,aero
#endif
     &                     )      


      if((ALB(I,J,1) /= 0.d0).AND.(sza < szamax))then
CCCCCCCCCCCCCCCCCCCC   SUNLIGHT   CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

CCCCCCCCCCCCCCCCC FAMILY PARTITIONING CCCCCCCCCCCCCCCCCCCCCCCCCC

#ifdef SHINDELL_STRAT_CHEM
       call Oxinit(LM,I,J)
       call HOxfam(LM,I,J)
       call NOxfam(LM,I,J)
       call BrOxfam(LM,I,J)
#else
       call Oxinit(maxl,I,J)
       call HOxfam(maxl,I,J)
       call NOxfam(maxl,I,J)
#endif
CCCCCCCCCCCCCCCCC NON-FAMILY CHEMISTRY CCCCCCCCCCCCCCCCCCCCCCCC

      call chemstep(I,J,changeL)

C Save 3D radical arrays to pass to aerosol code:
      if(coupled_chem == 1) then
        do l=1,maxl
          oh_live(i,j,l)=y(nOH,L)
          no3_live(i,j,l)=yNO3(i,j,l)
        end do
      endif

#ifdef SHINDELL_STRAT_CHEM
      call ClOxfam(LM,I,J,ClOx_old) ! needed something from chemstep.
#endif

CCCCCCCCCCCCC PRINT SOME CHEMISTRY DIAGNOSTICS CCCCCCCCCCCCCCCC
      if(prnchg .and. J == jprn .and. I == iprn) then
       jay = (J >= J_0 .and. J <= J_1) 
       l=lprn
       write(out_line,*) ' '
       call write_parallel(trim(out_line),crit=jay)
       write(out_line,*) 'Family ratios at I,J,L: ',i,j,l
       call write_parallel(trim(out_line),crit=jay)
       write(out_line,*) 'OH/HO2 = ',y(nOH,l)/y(nHO2,l)
       call write_parallel(trim(out_line),crit=jay)
       write(out_line,*) 'O/O3 = ',y(nO,l)/y(nO3,l)
       call write_parallel(trim(out_line),crit=jay)
       write(out_line,*) 'O1D/O3 = ',y(nO1D,l)/y(nO3,l),
     &  '  J(O1D) = ',ss(2,l,I,J)
       call write_parallel(trim(out_line),crit=jay)
       write(out_line,*) 'NO/NO2 = ',y(nNO,l)/y(nNO2,l),
     &  '   J(NO2) = ',ss(1,l,I,J)
       call write_parallel(trim(out_line),crit=jay)
       write(out_line,*) 'conc OH = ',y(nOH,l)
       call write_parallel(trim(out_line),crit=jay)
#ifdef SHINDELL_STRAT_CHEM
       write(out_line,*) 'Cl,ClO,Cl2O2,OClO,Cl2 = ',y(nCl,l),
     &  y(nClO,l),y(nCl2O2,l),y(nOClO,l),y(nCl2,l)
       call write_parallel(trim(out_line),crit=jay)
       write(out_line,*) 'Br,BrO = ',y(nBr,l),y(nBrO,l)
       call write_parallel(trim(out_line),crit=jay)
       write(out_line,*) 'pCl,pClO,pOClO,pBrO = ',pClx(I,J,l),
     &  pClOx(I,J,l),pOClOx(I,J,l),pBrOx(I,J,l)
       call write_parallel(trim(out_line),crit=jay)
#endif
       write(out_line,*)
     & 'sun, SALBFJ,sza,I,J,Itime= ',ALB(I,J,1),sza,I,J,Itime
       call write_parallel(trim(out_line),crit=jay)
       do inss=1,JPPJ
        write(out_line,195) ' J',inss,ay(ks(inss)),' = ',
     &  (ss(inss,Lqq,I,J),Lqq=1,LS1-1)
        call write_parallel(trim(out_line),crit=jay)
       enddo
       write(out_line,196) ' RCloud',(RCLOUDFJ(Lqq,I,J),Lqq=1,LS1-1)
       call write_parallel(trim(out_line),crit=jay)
       write(out_line,196) ' Ozone ',(y(nO3,Lqq),Lqq=1,LS1-1)
       call write_parallel(trim(out_line),crit=jay)
       write(out_line,*) ' '
       call write_parallel(trim(out_line),crit=jay)
      endif
 195  format(a2,i2,1x,a8,a3,11(1x,e9.2))
 196  format(a7,9x,11(1x,e9.2))
CCCCCCCCCCCCCCCCCCCC END CHEM DIAG SECT CCCCCCCCCCCCCCCCCCCCCCC
      
      else

CCCCCCCCCCCCCCCCCCCC END SUNLIGHT CCCCCCCCCCCCCCCCCCCCCCCCCCCCC

CCCCCCCCCCCCCCCCCCCC   DARKNESS  CCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

C*****************************************************************
C               ABOUT: N2O5 sink on sulfate aerosol 
C                REACTION PROBABLITY FORMULATION:
C
C To evaluate 'k' for N2O5 + H2O -> 2HNO3, assume k = GAMMA*SA*v/4
C (Dentener and Crutzen, 1993). GAMMA = 0.1, SA = given,
C v = molecular velocity (cm/s) where v = SQRT (8.Kb.T / PI*M);
C Kb = 1.38062E-23; T = Temp (K); M = mass N2O5 (Kg)
C
C Off-line sulfate fields to run in uncoupled mode give SO4 in
C cm2/cm3 'surface area density'.
C
C On-line sulfate in coupled mode must be converted to aerosol
C surface (cm2 aerosol/cm3 air) via aerosol volume fraction
C (cm3 aerosol/cm3 air). Assume a monodispersed aerosol with diameter
C of 0.078 microns. Specific aerosol density = 1.1g/cm3 (1.7g/cm3 ?)
C See Dentener and Crutzen, 1993 for details. Mr[sulfate] = 96.0g;
C Mr[(NH4)HSO4] = 115.0gC
C*****************************************************************

CCCCCCCCCCCCCCCC NIGHTTIME  TROPOSPHERE  CCCCCCCCCCCCCCCCCCCCCC

      do L=1,maxl ! (troposphere)

        if (coupled_chem == 1) then
          ! Convert SO4 from mass (kg) to aerosol surface per grid box:
          fact_so4 = BYDXYP(J)*BYAM(L,I,J)*28.0D0*y(nM,L) ! *96/96
          ! sulfate(I,J,L)=(trm(I,J,L,n_SO4)*fact_so4*3.0D0)
     &    ! /(3.9D-6*avog*1.1D0)
          sulfate(I,J,L)=trm(I,J,L,n_SO4)*fact_so4*byavog*1.063636d7
        endif

        pfactor=dxyp(J)*AM(L,I,J)/y(nM,L)
        bypfactor=1.D0/pfactor
        RVELN2O5=SQRT(TX(I,J,L)*RKBYPIM)*100.d0
C       Calculate sulfate sink, and cap it at 90% of N2O5:
        wprod_sulf=
     &  dt2*sulfate(I,J,L)*y(n_N2O5,L)*RGAMMASULF*RVELN2O5*0.25d0
        if(wprod_sulf > 0.9d0*y(n_N2O5,L))wprod_sulf=0.9d0*y(n_N2O5,L)
        prod_sulf=wprod_sulf*pfactor
        TAJLS(J,L,jls_N2O5sulf)=TAJLS(J,L,jls_N2O5sulf)
     &  -(prod_sulf*vol2mass(n_N2O5))

C*****************************************************************
c        g signifies gas phase
c        while prod_sulf and wprod_sulf are sulfate rxn
c        wprods are in molecules/cm3/s
c        prods/mass2vol are in mass units to add to tracers
c
c        NO3 amounts are a function of reaction 7 (NO2 + O3 -> NO3),
c        24, 25 (leave out 28, 0.9*32, 46, 52 outside NOx family)
c        NO2, similarly leave out 29, 45, and 46.
c        Keep NOx unchanged as this is only intrafamily
C*****************************************************************

c       define O3 from Ox:
        y(nO3,L)=y(n_Ox,L)*pOx(I,J,L)

c       calculate change in NO3:
        dNO3=rr(7,L)*y(nNO2,L)*y(n_Ox,L)-(rr(24,L)*y(nNO2,L)+
     &       2.d0*rr(25,L)*yNO3(I,J,L))*yNO3(I,J,L) -(rr(36,L)
     &       *y(n_Alkenes,L)+rr(32,L)*y(n_Isoprene,L))*yNO3(I,J,L)
C       including DMS+NO3 :
     &       - ydms(i,j,l)*rsulf3(i,j,l)*yNO3(I,J,L)
#ifdef SHINDELL_STRAT_CHEM
        dNO3=dNO3-(rr(28,L)*y(n_HCHO,L)+rr(99,L)*y(nNO2,L))
     &       *yNO3(I,J,L)+rr(92,L)*y(n_N2O5,L)
#else
        dNO3=dNO3-(rr(28,L)*y(n_HCHO,L)+rr(52,L)*y(nNO2,L))
     &       *yNO3(I,J,L)+rr(46,L)*y(n_N2O5,L)
#endif
        dNO3=dNO3*dt2

c       limit the change in NO3:
        if(-dNO3 > 0.66d0*yNO3(I,J,L)) dNO3=-0.66d0*yNO3(I,J,L)

c       apply the NO3 change; limit the value to positive & 1/2 NOx:
        yNO3(I,J,L)=yNO3(I,J,L)+dNO3
        if(yNO3(I,J,L) < 0.d0) yNO3(I,J,L)=0.d0
        if(yNO3(I,J,L) > y(n_NOx,L)*0.5d0)
     &  yNO3(I,J,L)=y(n_NOx,L)*0.5d0

c       calculate and limit NO2:
        y(nNO2,L)=y(n_NOx,L)-yNO3(I,J,L)
        pNOx(I,J,L)=y(nNO2,L)/(y(n_NOx,L)+1.d-10)
        if(pNOx(I,J,L) > 1.d0) pNOx(I,J,L)=1.d0
        if(pNOx(I,J,L) < 0.5d0)pNOx(I,J,L)=0.5d0

C       LOWER LIMIT ON N2O5:
        if(y(n_N2O5,L) <= 1.d0) y(n_N2O5,L)=1.d0

C Calculate and limit gaseous changes to HNO3, HCHO, N2O5, Aldehyde,
C Alkenes, Isoprene, and AlkylNit:

        gwprodHNO3=(y(n_HCHO,L)*rr(28,L)+2.5d-15*
     &             yAldehyde(I,J,L))*yNO3(I,J,L)*dt2
        if(gwprodHNO3 > 0.5d0*y(n_NOx,L))gwprodHNO3=0.5d0*y(n_NOx,L)
        if(gwprodHNO3 > y(n_HCHO,L))gwprodHNO3=y(n_HCHO,L)
        gprodHNO3=gwprodHNO3*pfactor

#ifdef SHINDELL_STRAT_CHEM
        gwprodN2O5=(yNO3(I,J,L)*y(nNO2,L)*rr(99,L)-y(n_N2O5,L)
     &             *rr(92,L))*dt2
#else
        gwprodN2O5=(yNO3(I,J,L)*y(nNO2,L)*rr(52,L)-y(n_N2O5,L)
     &             *rr(46,L))*dt2
#endif
        if(gwprodN2O5 > 0.25d0*y(n_NOx,L))gwprodN2O5=0.25d0*y(n_NOx,L)
        if(-gwprodN2O5 > 0.5d0*y(n_N2O5,L))
     &       gwprodN2O5=-0.49d0*y(n_N2O5,L)

        changeAldehyde=(rr(36,L)*y(n_Alkenes,L)+rr(32,L)*
     &              y(n_Isoprene,L)*0.12d0-2.5d-15*yAldehyde(I,J,L))*
     &              yNO3(I,J,L)*dt2
        if(-changeAldehyde > 0.75d0*yAldehyde(I,J,L))changeAldehyde=
     &  -0.75d0*yAldehyde(I,J,L)

        changeAlkenes=(rr(32,L)*y(n_Isoprene,L)*0.45d0-rr(36,L)*
     &               y(n_Alkenes,L))*yNO3(I,J,L)*dt2+(rr(31,L)*
     &               y(n_Isoprene,L)-rr(35,L)*y(n_Alkenes,L))*
     &               y(nO3,L)*dt2
        if(-changeAlkenes > 0.75d0*y(n_Alkenes,L))changeAlkenes=
     &  -0.75d0*y(n_Alkenes,L)

        changeIsoprene=-(rr(32,L)*yNO3(I,J,L)
     &                 +rr(31,L)*y(nO3,L))*y(n_Isoprene,L)*dt2
        if(-changeIsoprene > 0.75d0*y(n_Isoprene,L))changeIsoprene=
     &  -0.75d0*y(n_Isoprene,L)

        changeHCHO=(rr(36,L)*y(n_Alkenes,L)+
     &             rr(32,L)*y(n_Isoprene,L)*0.03d0)*yNO3(I,J,L)*dt2
     &             -gwprodHNO3+(rr(31,L)*y(n_Isoprene,L)*0.9d0
     &             +rr(35,L)*y(n_Alkenes,L))*y(nO3,L)*0.64d0*dt2

        changeAlkylNit=rr(32,L)*y(n_Isoprene,L)*
     &                yNO3(I,J,L)*dt2*0.9d0
        if(-changeAlkylNit > 0.75d0*y(n_AlkylNit,L))changeAlkylNit=
     &  -0.75d0*y(n_AlkylNit,L)

c Convert some changes to molecules/cm3/s:
        changeHNO3=gwprodHNO3+2*wprod_sulf  !always positive
        changeNOx=-gwprodHNO3-2*gwprodN2O5-(0.9d0*rr(32,L)*
     &  y(n_Isoprene,L)+2.5d-15*yAldehyde(I,J,L))*yNO3(I,J,L)*dt2
        if(-changeNOx > y(n_NOx,L))changeNOx=-.95d0*y(n_NOx,L)
        changeN2O5=gwprodN2O5-wprod_sulf

c Ensure nitrogen conservation (presumably dNOx<0, others >0):
        rlossN=0.d0
        rprodN=0.d0
        if(changeNOx < 0.d0)then
          rlossN=rlossN+changeNOx
        else
          rprodN=rprodN+changeNOx
        endif
        if(changeHNO3 < 0.d0)then
          rlossN=rlossN+changeHNO3
        else
          rprodN=rprodN+changeHNO3
        endif
        if(changeN2O5 < 0.d0)then
          rlossN=rlossN+2*changeN2O5
        else
          rprodN=rprodN+2*changeN2O5
        endif
        if(changeAlkylNit < 0.d0)then
          rlossN=rlossN+changeAlkylNit
        else
          rprodN=rprodN+changeAlkylNit
        endif
        if(rprodN > rlossN)then
          ratioN=-rlossN/rprodN
          if(changeNOx > 0.d0)     changeNOx    =changeNOx   *ratioN
          if(changeHNO3 > 0.d0)    changeHNO3   =changeHNO3  *ratioN
          if(changeN2O5 > 0.d0)    changeN2O5   =changeN2O5  *ratioN
          if(changeAlkylNit > 0.d0)changeAlkylNit=
     &                                           changeAlkylNit*ratioN
        else
          ratioN=rprodN/(-rlossN)
          if(changeNOx < 0.d0)     changeNOx    =changeNOx   *ratioN
          if(changeHNO3 < 0.d0)    changeHNO3   =changeHNO3  *ratioN
          if(changeN2O5 < 0.d0)    changeN2O5   =changeN2O5  *ratioN
          if(changeAlkylNit < 0.d0)changeAlkylNit=
     &                                           changeAlkylNit*ratioN
        endif
#ifdef TRACERS_HETCHEM
C       Include reactions on dust for HNO3:
        changeHNO3 = changeHNO3 - krate(i,j,l,1,1)*y(n_HNO3,l)*dt2
        changeN_d1 = krate(i,j,l,2,1) * y(n_HNO3,l) *dt2
        changeN_d2 = krate(i,j,l,3,1) * y(n_HNO3,l) *dt2
        changeN_d3 = krate(i,j,l,4,1) * y(n_HNO3,l) *dt2
#endif

C Apply Alkenes, AlkyNit, and Aldehyde changes here:
        y(n_Alkenes,L)  =y(n_Alkenes,L)  +changeAlkenes
        y(n_AlkylNit,L) =y(n_AlkylNit,L) +changeAlkylNit
        yAldehyde(I,J,L)=yAldehyde(I,J,L)+changeAldehyde

C Note: the lower limit of 1 placed on the resulting tracer mass
C from the following changes is to prevent negative tracer mass:

C -- HCHO --
c       Gas phase NO3 + HCHO -> HNO3 + CO yield of HCHO & CO:
        changeL(L,n_HCHO)=changeHCHO*pfactor*vol2mass(n_HCHO)
        if(-changeL(L,n_HCHO) > trm(I,J,L,n_HCHO))then
          changeL(L,n_HCHO)=-.95d0*trm(I,J,L,n_HCHO)
          changeHCHO=changeL(L,n_HCHO)*mass2vol(n_HCHO)*bypfactor
        endif
        IF((trm(i,j,l,n_HCHO)+changeL(l,n_HCHO)) < 1.d0) THEN
          changeL(l,n_HCHO) = 1.d0 - trm(i,j,l,n_HCHO)
          changeHCHO=changeL(L,n_HCHO)*mass2vol(n_HCHO)*bypfactor
        ENDIF
        wprodHCHO=changeHCHO
C -- CO --
        changeL(L,n_CO)=gprodHNO3*vol2mass(n_CO)
        IF((trm(i,j,l,n_CO)+changeL(l,n_CO)) < 1.d0)
     &  changeL(l,n_CO) = 1.d0 - trm(i,j,l,n_CO)
        wprodCO=gwprodHNO3   ! <<< note
        if(changeL(L,n_CO) >= 0.) then  
          TAJLS(J,L,jls_COp)=TAJLS(J,L,jls_COp)+changeL(L,n_CO)
        else
          TAJLS(J,L,jls_COd)=TAJLS(J,L,jls_COd)+changeL(L,n_CO)
        endif       
C -- HNO3 --  (HNO3 from gas and het phase rxns )
        changeL(L,n_HNO3)=changeHNO3*pfactor*vol2mass(n_HNO3)
        IF((trm(i,j,l,n_HNO3)+changeL(l,n_HNO3)) < 1.d0) THEN
          changeL(l,n_HNO3) = 1.d0 - trm(i,j,l,n_HNO3)
          changeHNO3=changeL(L,n_HNO3)*mass2vol(n_HNO3)*bypfactor
        END IF
#ifdef TRACERS_HETCHEM
        changeL(L,n_N_d1)=changeN_d1*pfactor*vol2mass(n_N_d1)
        if(i==36.and.j==28.and.l==1) then
          write(out_line,*)'Mchange L 2 ', changeL(L,n_N_d1),changeN_d1
          call write_parallel(trim(out_line),crit=.true.)
        endif
        IF((trm(i,j,l,n_N_d1)+changeL(l,n_N_d1)) < 1.d0) THEN
          changeL(l,n_N_d1) = 1.d0 - trm(i,j,l,n_N_d1)
          changeN_d1=changeL(L,n_N_d1)*mass2vol(n_N_d1)*bypfactor
        END IF
        changeL(L,n_N_d2)=changeN_d2*pfactor*vol2mass(n_N_d2)
        IF((trm(i,j,l,n_N_d2)+changeL(l,n_N_d2)) < 1.d0) THEN
          changeL(l,n_N_d2) = 1.d0 - trm(i,j,l,n_N_d2)
          changeN_d2=changeL(L,n_N_d2)*mass2vol(n_N_d2)*bypfactor
        END IF
        changeL(L,n_N_d3)=changeN_d3*pfactor*vol2mass(n_N_d3)
        IF((trm(i,j,l,n_N_d3)+changeL(l,n_N_d3)) < 1.d0) THEN
          changeL(l,n_N_d3) = 1.d0 - trm(i,j,l,n_N_d3)
          changeN_d3=changeL(L,n_N_d3)*mass2vol(n_N_d3)*bypfactor
        END IF
#endif
C -- N2O5 --  (N2O5 from gas and het phase rxns)
        changeL(L,n_N2O5)=changeN2O5*pfactor*vol2mass(n_N2O5)
        IF((trm(i,j,l,n_N2O5)+changeL(l,n_N2O5)) < 1.d0) THEN
          changeL(l,n_N2O5) = 1.d0 - trm(i,j,l,n_N2O5)
          changeN2O5=changeL(L,n_N2O5)*mass2vol(n_N2O5)*bypfactor
        END IF
c -- NOx --   (NOx from gas phase rxns)
        changeL(L,n_NOx)=changeNOx*pfactor*vol2mass(n_NOx)
        IF((trm(i,j,l,n_NOx)+changeL(l,n_NOx)) < 1.d0) THEN
          changeL(l,n_NOx) = 1.d0 - trm(i,j,l,n_NOx)
          changeNOx=changeL(L,n_NOx)*mass2vol(n_NOx)*bypfactor
        END IF
C -- Alkenes --  (Alkenes from gas phase rxns)
        changeL(L,n_Alkenes)=
     &  changeAlkenes*pfactor*vol2mass(n_Alkenes)
        IF((trm(i,j,l,n_Alkenes)+changeL(l,n_Alkenes)) < 1.d0)THEN
          changeL(l,n_Alkenes) = 1.d0 - trm(i,j,l,n_Alkenes)
          changeAlkenes=changeL(L,n_Alkenes)*mass2vol(n_Alkenes)
     &    *bypfactor
        END IF
c -- Isoprene -- (Isoprene from gas phase rxns)
        changeL(L,n_Isoprene)=
     &  changeIsoprene*pfactor*vol2mass(n_Isoprene)
        IF((trm(i,j,l,n_Isoprene)+changeL(l,n_Isoprene)) < 1.d0)
     &  THEN
          changeL(l,n_Isoprene) = 1.d0 - trm(i,j,l,n_Isoprene)
          changeIsoprene=changeL(L,n_Isoprene)*mass2vol(n_Isoprene)
     &    *bypfactor
        END IF
c -- AlkylNit -- (AlkylNit from gas phase rxns)
        changeL(L,n_AlkylNit)=
     &  changeAlkylNit*pfactor*vol2mass(n_AlkylNit)
        IF((trm(i,j,l,n_AlkylNit)+changeL(l,n_AlkylNit)) < 1.d0)
     &  THEN
          changeL(l,n_AlkylNit) = 1.d0 - trm(i,j,l,n_AlkylNit)
          changeAlkylNit=changeL(L,n_AlkylNit)*mass2vol(n_AlkylNit)
     &    *bypfactor
        END IF

C Save 3D radical arrays to pass to aerosol code:
C Make sure we get the nightime values; Set OH to zero for now:
        if(coupled_chem == 1) then
          oh_live(i,j,l)=0.d0
          no3_live(i,j,l)=yNO3(i,j,l)
        endif

CCCCCCCCCCCCC PRINT SOME CHEMISTRY DIAGNOSTICS CCCCCCCCCCCCCCCC
        if(prnchg.and.J == jprn.and.I == iprn.and.L == lprn)then
          jay = (J >= J_0 .and. J <= J_1)
          write(out_line,*)
     &    'dark, SALBFJ,sza,I,J,L,Itime= ',ALB(I,J,1),sza,I,J,L,Itime
          call write_parallel(trim(out_line),crit=jay)
          write(out_line,198) ay(n_NOx),': ',
     &    changeNOx,' molecules produced; ',
     &    100.d0*(changeNOx)/y(n_NOx,L),' percent of'
     &    ,y(n_NOx,L),'(',1.d9*y(n_NOx,L)/y(nM,L),' ppbv)'
          call write_parallel(trim(out_line),crit=jay)
          write(out_line,198) ay(n_HNO3),': ',
     &    changeHNO3,' molecules produced; ',
     &    100.d0*(changeHNO3)/y(n_HNO3,L),' percent of'
     &    ,y(n_HNO3,L),'(',1.d9*y(n_HNO3,L)/y(nM,L),' ppbv)'
          call write_parallel(trim(out_line),crit=jay)
#ifdef TRACERS_HETCHEM
          write(out_line,198) ay(n_HNO3),': ',
     &    (-krate(i,j,l,1,1)*y(n_HNO3,l)*dt2),' molecules dest dust ',
     &    (100.d0*(-krate(i,j,l,1,1)*y(n_HNO3,l)*dt2))/y(n_HNO3,L),
     &    ' percent of'
     &    ,y(n_HNO3,L),'(',1.d9*y(n_HNO3,L)/y(nM,L),' ppbv)'
          call write_parallel(trim(out_line),crit=jay)
#endif
          write(out_line,198) ay(n_N2O5),': ',
     &    changeN2O5,' net molec produced; ',
     &    100.d0*(changeN2O5)/y(n_N2O5,L),' percent of'
     &    ,y(n_N2O5,L),'(',1.d9*y(n_N2O5,L)/y(nM,L),' ppbv)'
          call write_parallel(trim(out_line),crit=jay)
          write(out_line,198) ay(n_N2O5),': ',
     &    gwprodN2O5,' molec prod fm gas;  ',
     &    100.d0*(gwprodN2O5)/y(n_N2O5,L),' percent of'
     &    ,y(n_N2O5,L),'(',1.d9*y(n_N2O5,L)/y(nM,L),' ppbv)'
          call write_parallel(trim(out_line),crit=jay)
          write(out_line,198) ay(n_HCHO),': ',
     &    wprodHCHO,' molecules produced; ',
     &    100.d0*(wprodHCHO)/y(n_HCHO,L),' percent of'
     &    ,y(n_HCHO,L),'(',1.d9*y(n_HCHO,L)/y(nM,L),' ppbv)'
          call write_parallel(trim(out_line),crit=jay)
          write(out_line,198) 'Aldehyde',': ',
     &    changeAldehyde,' molecules produced; ',
     &    100.d0*(changeAldehyde)/yAldehyde(I,J,L),' percent of'
     &    ,yAldehyde(I,J,L),'(',1.d9*yAldehyde(I,J,L)/y(nM,L),' ppbv)'
          call write_parallel(trim(out_line),crit=jay)
          write(out_line,198) 'Alkenes ',': ',
     &    changeAlkenes,' molecules produced; ',
     &    100.d0*(changeAlkenes)/y(n_Alkenes,L),' percent of'
     &    ,y(n_Alkenes,L),'(',1.d9*y(n_Alkenes,L)/y(nM,L),' ppbv)'
          call write_parallel(trim(out_line),crit=jay)
          write(out_line,198) 'Isoprene',': ',
     &    changeIsoprene,' molecules produced; ',
     &    100.d0*(changeIsoprene)/y(n_Isoprene,L),' percent of'
     &    ,y(n_Isoprene,L),'(',1.d9*y(n_Isoprene,L)/y(nM,L),' ppbv)'
          call write_parallel(trim(out_line),crit=jay)
          write(out_line,198) 'AlkylNit',': ',
     &    changeAlkylNit,' molecules produced; ',
     &    100.d0*(changeAlkylNit)/y(n_AlkylNit,L),' percent of'
     &    ,y(n_AlkylNit,L),'(',1.d9*y(n_AlkylNit,L)/y(nM,L),' ppbv)'
          call write_parallel(trim(out_line),crit=jay)
          write(out_line,199) 'NO2, NO3  = ',y(nNO2,L),yNO3(I,J,L)
          call write_parallel(trim(out_line),crit=jay)
        endif
 198    format(1x,a8,a2,e13.3,a21,f10.0,a11,2x,e13.3,3x,a1,f12.5,a6)
 199    format(1x,a20,2(2x,e13.3))
CCCCCCCCCCCCCCCCCCCC END CHEM DIAG SECT CCCCCCCCCCCCCCCCCCCCCCC

C Make sure nighttime chemistry changes are not too big:
        error=.false.
        if(changeNOx < -1.d15.OR.changeNOx > 1.d15) then
          write(6,*) 'Big chg@ Itime,I,J,L,NOx ',Itime,I,J,L,changeNOx
          error=.true.
        end if
        if(changeHNO3 < -1.d15.OR.changeHNO3 > 1.d15) then
          write(6,*) 'Big chg@ Itime,I,J,L,HNO3',Itime,I,J,L,changeHNO3
          error=.true.
        end if
        if(changeN2O5 < -1.d15.OR.changeN2O5 > 1.d15) then
          write(6,*) 'Big chg@ Itime,I,J,L,N2O5',Itime,I,J,L,changeN2O5
          error=.true.
        end if
        if(wprodHCHO < -1.d15.OR.wprodHCHO > 1.d15) then
          write(6,*)'Big chg@ Itime,I,J,L,HCHO',Itime,I,J,L,wprodHCHO
          error=.true.
        endif
        if(error)call stop_model('nighttime chem: big changes',255)

C       ACCUMULATE 3D NO3 diagnostic: 
        if (yNO3(I,J,L) > 0.d0 .and. yNO3(I,J,L) < 1.d20)
     &  taijs(i,j,ijs_NO3(l))=taijs(i,j,ijs_NO3(l))+yNO3(i,j,l)
     
       enddo  ! troposphere loop

CCCCCCCCCCCCCCCC END NIGHTTIME TROPOSPHERE CCCCCCCCCCCCCCCCCCCC

CCCCCCCCCCCCCCCC NIGHTTIME STRATOSPHERE CCCCCCCCCCCCCCCCCCCCCCC

#ifdef SHINDELL_STRAT_CHEM
       do L=maxl+1,LM ! (stratosphere)

         pfactor=dxyp(J)*AM(L,I,J)/y(nM,L)
         wprod_sulf=DT2*y(n_N2O5,L)*rr(105,L) !rxn on sulfate & PSCs
         if(wprod_sulf >= 0.5d0*y(n_N2O5,L))wprod_sulf=0.5d0*y(n_N2O5,L)

c        calculate and limit change in NO3:
         dNO3=rr(7,L)*y(nNO2,L)*y(n_Ox,L)-(rr(24,L)*y(nNO2,L)+
     &        2.d0*rr(25,L)*yNO3(I,J,L))*yNO3(I,J,L)
         dNO3=dNO3-(rr(28,L)*y(n_HCHO,L)+rr(99,L)*y(nNO2,L))
     &        *yNO3(I,J,L)+rr(92,L)*y(n_N2O5,L)
         dNO3=dNO3*dt2
         if(-dNO3 > 0.66d0*yNO3(I,J,L))dNO3=-0.66d0*yNO3(I,J,L)

c        apply the NO3 change; limit value to positive and 1/2 NOx:
         yNO3(I,J,L)=yNO3(I,J,L)+dNO3
         if(yNO3(I,J,L) < 0.d0)yNO3(I,J,L)=0.d0
         if(yNO3(I,J,L) > y(n_NOx,L)*0.5d0)yNO3(I,J,L)=
     &   y(n_NOx,L)*0.5d0

c        calculate and limit NO2:
         y(nNO2,L)=y(n_NOx,L)-yNO3(I,J,L)
         pNOx(I,J,L)=y(nNO2,L)/(y(n_NOx,L)+1.d-10)
         if(pNOx(I,J,L) > 1.d0)pNOx(I,J,L)=1.d0
         if(pNOx(I,J,L) < 0.5d0)pNOx(I,J,L)=0.5d0

C        LOWER LIMIT ON N2O5:
         if(y(n_N2O5,L) <= 1.d0)y(n_N2O5,L)=1.d0

C Calculate and limit gaseous changes to HNO3, HCHO, N2O5, Aldehyde,
C Alkenes, Isoprene, and AlkylNit:
         gwprodHNO3=y(n_HCHO,L)*rr(28,L)*yNO3(I,J,L)*dt2
         if(gwprodHNO3 > 0.5d0*y(n_NOx,L))gwprodHNO3=0.5d0*y(n_NOx,L)
         if(gwprodHNO3 > y(n_HCHO,L))gwprodHNO3=y(n_HCHO,L)
         gprodHNO3=gwprodHNO3*pfactor
         gwprodN2O5=(yNO3(I,J,L)*y(nNO2,L)*rr(99,L)-y(n_N2O5,L)
     &              *rr(92,L))*dt2
         if(gwprodN2O5 > 0.25d0*y(n_NOx,L))gwprodN2O5=0.25d0*y(n_NOx,L)
         if(-gwprodN2O5 > 0.5d0*y(n_N2O5,L))
     &   gwprodN2O5=-0.49d0*y(n_N2O5,L)
         changeClONO2=y(nClO,L)*rr(103,L)*y(nNO2,L)*dt2
         if(changeClONO2 >= y(nClO,L))changeClONO2=0.8d0*y(nClO,L)
         if(changeClONO2 >= y(nNO2,L))changeClONO2=0.8d0*y(nNO2,L)
         changeClOx=-changeClONO2

c Convert some changes to molecules/cm3/s:(w/o ClONO2->HNO3 het or PSC)
         changeHNO3=gwprodHNO3+2.d0*wprod_sulf  !always positive
         changeNOx=-gwprodHNO3-2.d0*gwprodN2O5
         if(-changeNOx > y(n_NOx,L))changeNOx=-.95d0*y(n_NOx,L)

         changeN2O5=gwprodN2O5-wprod_sulf

c Ensure nitrogen conservation (presumably dNOx<0, others >0):
         rlossN=0.d0
         rprodN=0.d0
         if(changeNOx < 0.d0)then
           rlossN=rlossN+changeNOx
         else
           rprodN=rprodN+changeNOx
         endif
         if(changeHNO3 < 0.d0)then
           rlossN=rlossN+changeHNO3
         else
           rprodN=rprodN+changeHNO3
         endif
         if(changeN2O5 < 0.d0)then
           rlossN=rlossN+2.d0*changeN2O5
         else
           rprodN=rprodN+2.d0*changeN2O5
         endif
         if(rprodN > rlossN)then
           ratioN=-rlossN/rprodN
           if(changeNOx > 0.d0)   changeNOx     =changeNOx     *ratioN
           if(changeHNO3 > 0.d0)  changeHNO3    =changeHNO3    *ratioN
           if(changeN2O5 > 0.d0)  changeN2O5    =changeN2O5    *ratioN
         else
           ratioN=rprodN/(-rlossN)
           if(changeNOx < 0.d0)   changeNOx     =changeNOx     *ratioN
           if(changeHNO3 < 0.d0)  changeHNO3    =changeHNO3    *ratioN
           if(changeN2O5 < 0.d0)  changeN2O5    =changeN2O5    *ratioN
         endif

         changeNOx=changeNOx-changeClONO2
         if(-changeNOx > y(n_NOx,L))changeNOx=-.95d0*y(n_NOx,L)

c Heterogeneous reaction ClONO2+H2O on sulfate (and PSCs if present):
         if(rr(106,L) > 2.d-35)then
           changehetClONO2=-(rr(106,L)*y(n_ClONO2,L))*dt2
           if(changehetClONO2 >= 0.5*y(n_ClONO2,L))changehetClONO2=
     &     -0.5d0*y(n_ClONO2,L)
           changeClONO2=changeClONO2+changehetClONO2
           changeHOCl=-changehetClONO2
           changeHNO3=changeHNO3-changehetClONO2
         else
           changeHOCl=0.d0
         endif
         
         changeHCl=0.d0

c Polar Stratospheric Clouds (PSC) Chemistry:
c 105 N2O5    +H2O     -->HNO3    +HNO3  (calculated above)
c 106 ClONO2  +H2O     -->HOCl    +HNO3  (calculated above)
c 107 ClONO2  +HCl     -->Cl      +HNO3  !really makes Cl2
c 108 HOCl    +HCl     -->Cl      +H2O   !raeally makes Cl2
c 109 N2O5    +HCl     -->Cl      +HNO3  !really makes ClNO2  2

         pscX=0.d0
         if((pres2(l) <= 150.d0 .and. pres2(l) >= 35.d0) ! certain pres
     &   .and.((lat_dg(J,1)<=-66.).OR.(lat_dg(J,1)>=66.))! near poles
     &   .and. (ta(l) <= T_thresh))then                  ! cold enough
           pscX=1.d0
           chg107=rr(107,L)*y(n_ClONO2,L)*dt2
           if(chg107 >= 0.4d0*y(n_ClONO2,L))chg107=0.4d0*y(n_ClONO2,L)
           if(chg107 >= 0.3d0*y(n_HCl,L))chg107=0.3d0*y(n_HCl,L)
           chg108=rr(108,L)*y(n_HOCl,L)*dt2
           if(chg108 >= 0.8d0*y(n_HOCl,L))chg108=0.8d0*y(n_HOCl,L)
           if(chg108 >= 0.3d0*y(n_HCl,L))chg108=0.3d0*y(n_HCl,L)
           chg109=rr(109,L)*y(n_N2O5,L)*dt2
           if(chg109 >= 0.5d0*y(n_N2O5,L))chg109=0.5d0*y(n_N2O5,L)
           if(chg109 >= 0.3d0*y(n_HCl,L))chg109=0.3d0*y(n_HCl,L)
           changeClONO2=changeClONO2-chg107
           changeHOCl=changeHOCl-chg108
           changeN2O5=changeN2O5-chg109
           changeHCl=changeHCl-chg107-chg108-chg109
           changeHNO3=changeHNO3+chg107+chg109
           changeClOx=changeClOx+chg107+chg108+chg109
c          Note that really the last 3 produce Cl2, not ClOx, and Cl2
C          at night is stable and doesn't go back into ClONO2, so
C          should eventually keep track of Cl2/ClOx partitioning!
         endif

c Remove some of the HNO3 formed heterogeneously, as it doesn't come
c back to the gas phase:
         if(pres2(L) < 245.d0 .and. pres2(L) >= 31.6d0 .and.
     &   (J <= JSS+1.or.J >= JNN+1) .and. ta(L) <= T_thresh)then
           changeHNO3 = changeHNO3 - 3.0d-3*y(n_HNO3,L)
         endif
         if(aero(L)  /=  0)
     &   changeHNO3 = changeHNO3 -1.2d-4*y(n_HNO3,L)
         if(aero(L)  /=  0.and.pres2(L) <= 50.d0.and.pres2(L) > 38.d0)
     &   changeHNO3 = changeHNO3 +9.6d-5*y(n_HNO3,L)
         if(aero(L)  /=  0.and.pres2(L) < 245.d0.and.pres2(L) > 50.d0)
     &   changeHNO3 = changeHNO3 - 1.5d-5*(pres2(L)-30.d0)*y(n_HNO3,L)

C Make sure nighttime chemistry changes are not too big:
         error=.false.
         if(changeNOx < -1.d15.OR.changeNOx > 1.d15) then
           write(*,*) 'Big chg@ Itime,I,J,L,NOx ',Itime,I,J,L,changeNOx
           error=.true.
         end if
         if(changeHNO3 < -1.d15.OR.changeHNO3 > 1.d15) then
           write(*,*) 'Big chg@ Itime,I,J,L,HNO3',Itime,I,J,L,changeHNO3
           error=.true.
         end if
         if(changeN2O5 < -1.d15.OR.changeN2O5 > 1.d15) then
           write(*,*) 'Big chg@ Itime,I,J,L,N2O5',Itime,I,J,L,changeN2O5
           error=.true.
         end if
         if(wprodHCHO < -1.d15.OR.wprodHCHO > 1.d15) then
           write(*,*)'Big chg@ Itime,I,J,L,HCHO',Itime,I,J,L,wprodHCHO
           error=.true.
         endif
         if(error)call stop_model('nighttime chem: big changes',255)

C -- HNO3 --  (HNO3 from gas and het phase rxns )
         changeL(L,n_HNO3)=changeHNO3*pfactor*vol2mass(n_HNO3)
         IF((trm(i,j,l,n_HNO3)+changeL(l,n_HNO3)) < 1.d0) THEN
           changeL(l,n_HNO3) = 1.d0 - trm(i,j,l,n_HNO3)
           changeHNO3=changeL(L,n_HNO3)*mass2vol(n_HNO3)*bypfactor
         END IF
C -- N2O5 --  (N2O5 from gas and het phase rxns)
         changeL(L,n_N2O5)=changeN2O5*pfactor*vol2mass(n_N2O5)
         IF((trm(i,j,l,n_N2O5)+changeL(l,n_N2O5)) < 1.d0) THEN
           changeL(l,n_N2O5) = 1.d0 - trm(i,j,l,n_N2O5)
           changeN2O5=changeL(L,n_N2O5)*mass2vol(n_N2O5)*bypfactor
         END IF
c -- NOx --   (NOx from gas phase rxns)
         changeL(L,n_NOx)=changeNOx*pfactor*vol2mass(n_NOx)
         IF((trm(i,j,l,n_NOx)+changeL(l,n_NOx)) < 1.d0) THEN
           changeL(l,n_NOx) = 1.d0 - trm(i,j,l,n_NOx)
           changeNOx=changeL(L,n_NOx)*mass2vol(n_NOx)*bypfactor
         END IF
c --  Ox --   ( Ox from gas phase rxns)
         if(pres2(l) > 1.0.and.pres2(l) < 25.0)then
           changeOx=-(rr(7,L)*y(nNO2,L) + y(n_H2O2,L)*0.7d0*1.4d-11*
     &     exp(-2000./TA(L)))*y(n_Ox,L)*dt2*2.5d0
           changeL(L,n_Ox)=changeOx*pfactor*vol2mass(n_Ox)
           IF((trm(i,j,l,n_Ox)+changeL(l,n_Ox)) < 1.d0) THEN
             changeL(l,n_Ox) = 1.d0 - trm(i,j,l,n_Ox)
             changeOx=changeL(L,n_Ox)*mass2vol(n_Ox)*bypfactor
           END IF
           if(changeL(L,n_Ox) >= 0.) then  
             TAJLS(J,L,jls_Oxp)=TAJLS(J,L,jls_Oxp)+changeL(L,n_Ox)
           else
             TAJLS(J,L,jls_Oxd)=TAJLS(J,L,jls_Oxd)+changeL(L,n_Ox)
           endif 
         endif
c -- ClONO2 --   (ClONO2 from gas and het phase rxns)
         changeL(L,n_ClONO2)=changeClONO2*pfactor*
     &   vol2mass(n_ClONO2)
         IF((trm(i,j,l,n_ClONO2)+changeL(l,n_ClONO2)) < 1.d0) THEN
           changeL(l,n_ClONO2) = 1.d0 - trm(i,j,l,n_ClONO2)
           changeClONO2=changeL(L,n_ClONO2)*mass2vol(n_ClONO2)*
     &     bypfactor
         END IF
c -- ClOx --   (ClOx from gas and het phase rxns)
         changeL(L,n_ClOx)=changeClOx*pfactor*vol2mass(n_ClOx)
         IF((trm(i,j,l,n_ClOx)+changeL(l,n_ClOx)) < 1.d0) THEN
           changeL(l,n_ClOx) = 1.d0 - trm(i,j,l,n_ClOx)
           changeClOx=changeL(L,n_ClOx)*mass2vol(n_ClOx)*bypfactor
         END IF
         if(pscX > 0.9d0)then
c -- HOCl --   (HOCl from het phase rxns)
           changeL(L,n_HOCl)=changeHOCl*pfactor*vol2mass(n_HOCl)
           IF((trm(i,j,l,n_HOCl)+changeL(l,n_HOCl)) < 1.d0) THEN
             changeL(l,n_HOCl) = 1.d0 - trm(i,j,l,n_HOCl)
             changeHOCl=changeL(L,n_HOCl)*mass2vol(n_HOCl)*bypfactor
           END IF
c -- HCl --   (HCl from het phase rxns)
           changeL(L,n_HCl)=changeHCl*pfactor*vol2mass(n_HCl)
           IF((trm(i,j,l,n_HCl)+changeL(l,n_HCl)) < 1.d0) THEN
             changeL(l,n_HCl) = 1.d0 - trm(i,j,l,n_HCl)
             changeHCl=changeL(L,n_HCl)*mass2vol(n_HCl)*bypfactor
           END IF
         endif  ! pscX > 0.9

CCCCCCCCCCCCC PRINT SOME CHEMISTRY DIAGNOSTICS CCCCCCCCCCCCCCCC
         if(prnchg .and. J == jprn .and. I == iprn .and. L == lprn)then
           jay = (J >= J_0 .and. J <= J_1)
           write(out_line,*) 'dark, SALBFJ,sza,I,J,L,Itime= ',
     &     ALB(I,J,1),sza,I,J,L,Itime
           call write_parallel(trim(out_line),crit=jay)
           if(pscX > 0.9d0)then
             write(out_line,*) 'There are PSCs, T =',ta(L)
             call write_parallel(trim(out_line),crit=jay)
           else
             write(out_line,*) 'There are no PSCs, T =',ta(L)
             call write_parallel(trim(out_line),crit=jay)
           endif
           write(out_line,198) ay(n_NOx),': ',
     &     changeNOx,' molecules produced; ',
     &     100.d0*(changeNOx)/y(n_NOx,L),' percent of'
     &     ,y(n_NOx,L),'(',1.d9*y(n_NOx,L)/y(nM,L),' ppbv)'
           call write_parallel(trim(out_line),crit=jay)
           write(out_line,198) ay(n_HNO3),': ',
     &     changeHNO3,' molecules produced; ',
     &     100.d0*(changeHNO3)/y(n_HNO3,L),' percent of'
     &     ,y(n_HNO3,L),'(',1.d9*y(n_HNO3,L)/y(nM,L),' ppbv)'
           call write_parallel(trim(out_line),crit=jay)
           write(out_line,198) ay(n_N2O5),': ',
     &     changeN2O5,' net molec produced; ',
     &     100.d0*(changeN2O5)/y(n_N2O5,L),' percent of'
     &     ,y(n_N2O5,L),'(',1.d9*y(n_N2O5,L)/y(nM,L),' ppbv)'
           call write_parallel(trim(out_line),crit=jay)
           write(out_line,198) ay(n_N2O5),': ',
     &     gwprodN2O5,' molec prod fm gas;  ',
     &     100.d0*(gwprodN2O5)/y(n_N2O5,L),' percent of'
     &     ,y(n_N2O5,L),'(',1.d9*y(n_N2O5,L)/y(nM,L),' ppbv)'
           call write_parallel(trim(out_line),crit=jay)
           write(out_line,198) ay(n_N2O5),': ',
     &     -wprod_sulf,' molec prod fm sulf; ',
     &     -100.d0*(wprod_sulf)/y(n_N2O5,L),' percent of'
     &     ,y(n_N2O5,L),'(',1.d9*y(n_N2O5,L)/y(nM,L),' ppbv)'
           call write_parallel(trim(out_line),crit=jay)
           write(out_line,198) ay(n_ClONO2),': ',
     &     changeClONO2,' molecules produced; ',
     &     100.d0*(changeClONO2)/y(n_ClONO2,L),' percent of'
     &     ,y(n_ClONO2,L),'(',1.d9*y(n_ClONO2,L)/y(nM,L),' ppbv)'
           call write_parallel(trim(out_line),crit=jay)
           write(out_line,198) ay(n_ClOx),': ',
     &     changeClOx,' molecules produced; ',
     &     100.d0*(changeClOx)/y(n_ClOx,L),' percent of'
     &     ,y(n_ClOx,L),'(',1.d9*y(n_ClOx,L)/y(nM,L),' ppbv)'
           call write_parallel(trim(out_line),crit=jay)
           write(out_line,198) ay(n_HOCl),': ',
     &     changeHOCl,' molecules produced; ',
     &     100.d0*(changeHOCl)/y(n_HOCl,L),' percent of'
     &     ,y(n_HOCl,L),'(',1.d9*y(n_HOCl,L)/y(nM,L),' ppbv)'
           call write_parallel(trim(out_line),crit=jay)
           write(out_line,198) ay(n_HCl),': ',
     &     changeHCl,' molecules produced; ',
     &     100.d0*(changeHCl)/y(n_HCl,L),' percent of'
     &     ,y(n_HCl,L),'(',1.d9*y(n_HCl,L)/y(nM,L),' ppbv)'
           call write_parallel(trim(out_line),crit=jay)
           write(out_line,199) 'NO2, NO3  = ',y(nNO2,L),yNO3(I,J,L)
           call write_parallel(trim(out_line),crit=jay)
           write(out_line,198) ay(n_Ox),': ',
     &     changeOx,' molecules produced; ',
     &     100.d0*(changeOx)/y(n_Ox,L),' percent of'
     &     ,y(n_Ox,L),'(',1.d9*y(n_Ox,L)/y(nM,L),' ppbv)'
           call write_parallel(trim(out_line),crit=jay)
         endif
CCCCCCCCCCCCCCCCCCCC END CHEM DIAG SECT CCCCCCCCCCCCCCCCCCCCCCC

         if (y(nClO,L) > 0.d0 .and. y(nClO,L) < 1.d20)
     &   TAJLS(J,L,jls_ClOcon)=TAJLS(J,L,jls_ClOcon)+y(nClO,L)/y(nM,L)
         if (y(nH2O,L) > 0.d0 .and. y(nH2O,L) < 1.d20)
     &   TAJLS(J,L,jls_H2Ocon)=TAJLS(J,L,jls_H2Ocon)+y(nH2O,L)/y(nM,L)

       enddo ! end stratosphere loop
CCCCCCCCCCCCCCCC END NIGHTTIME STRATOSPHERE CCCCCCCCCCCCCCCCCCC
#endif
      endif
CCCCCCCCCCCCCCCCCCCC END DARKNESS CCCCCCCCCCCCCCCCCCCCCCCCCCCCC

#ifdef SHINDELL_STRAT_CHEM
      LL=LM
#else
      LL=maxl
#endif
      DO L=1,LL  

C Lower limit on HO2NO2 : 
        if(trm(i,j,l,n_HO2NO2)+changeL(l,n_HO2NO2) < 1.d0)
     &  changeL(l,n_HO2NO2) = 1.d0 - trm(i,j,l,n_HO2NO2)

#ifdef SHINDELL_STRAT_CHEM
c Tropospheric halogen sink Br & Cl :
        IF (L <= maxl) THEN 
          rmv=max(0.d0,    ! remove between 0 and 
     &        min(0.99d0,  ! 99% only...
     &        2.389d-1 * LOG(pres2(L))  - 1.05d0
     &        ))           ! about 5% at 100mb and 60% at 1000mb
          changeL(L,n_ClOx)  =-trm(I,J,L,n_ClOx)  *rmv
          changeL(L,n_HCl)   =-trm(I,J,L,n_HCl)   *rmv
          changeL(L,n_HOCl)  =-trm(I,J,L,n_HOCl)  *.85d0
          changeL(L,n_ClONO2)=-trm(I,J,L,n_ClONO2)*rmv
          changeL(L,n_BrOx)  =-trm(I,J,L,n_BrOx)  *0.9d0
          changeL(L,n_HBr)   =-trm(I,J,L,n_HBr)   *0.9d0
          changeL(L,n_HOBr)  =-trm(I,J,L,n_HOBr)  *0.9d0
          changeL(L,n_BrONO2)=-trm(I,J,L,n_BrONO2)*0.9d0
        END IF

c Set CLTOT based on CFCs (3.3 ppbv yield from complete oxidation of
c 1.8 ppbv CFC plus 0.5 ppbv background) :
        if(L > maxl)then
          !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
          !WARNING: RESETTING SOME Y's HERE; SO DON'T USE THEM BELOW!     
          !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
          y(n_ClOx,L)=(trm(I,J,L,n_ClOx)+changeL(L,n_ClOx))*y(nM,L)*
     &    mass2vol(n_ClOx)*BYDXYP(J)*BYAM(L,I,J)
          y(n_HCl,L)= (trm(I,J,L,n_HCl)+changeL(L,n_HCl))*y(nM,L)*
     &    mass2vol(n_HCl)*BYDXYP(J)*BYAM(L,I,J)
          y(n_HOCl,L)=(trm(I,J,L,n_HOCl)+changeL(L,n_HOCl))*y(nM,L)*
     &    mass2vol(n_HOCl)*BYDXYP(J)*BYAM(L,I,J)
          y(n_ClONO2,L)=(trm(I,J,L,n_ClONO2)+changeL(L,n_ClONO2))*
     &    y(nM,L)*mass2vol(n_ClONO2)*BYDXYP(J)*BYAM(L,I,J)

          CLTOT=((y(n_CFC,1)/y(nM,1)-y(n_CFC,L)/y(nM,L))*(3.3d0/1.8d0)*
     &    y(n_CFC,1)/(1.8d-9*y(nM,1)))
          CLTOT=CLTOT+0.5d-9
          CLTOT=CLTOT*y(nM,L)/
     &    (y(n_ClOx,L)+y(n_HCl,L)+y(n_HOCl,L)+y(n_ClONO2,L))
          if(prnchg.and.J == jprn.and.I == iprn.and.L == lprn)then  
            write(out_line,66) CLTOT
            call write_parallel(trim(out_line),crit=jay)
 66         format ('CLTOT = ',F20.5)
          endif
          IF(CLTOT <= 0.999d0 .OR. CLTOT >= 1.001d0) THEN
            changeL(L,n_ClOx)=changeL(L,n_ClOx)*CLTOT+
     &      trm(I,J,L,n_ClOx)*(CLTOT-1.D0)
            changeL(L,n_HCl)=changeL(L,n_HCl)*CLTOT+
     &      trm(I,J,L,n_HCl)*(CLTOT-1.D0)
            changeL(L,n_HOCl)=changeL(L,n_HOCl)*CLTOT+
     &      trm(I,J,L,n_HOCl)*(CLTOT-1.D0)
c           Conserve N wrt ClONO2 once inital Cl changes past:
            if(Itime-ItimeI >= 6)then
              changeL(L,n_NOx)=changeL(L,n_NOx)-
     &        (trm(I,J,L,n_ClONO2)+changeL(L,n_ClONO2))*
     &        (CLTOT-1.D0)*tr_mm(n_NOx)/tr_mm(n_ClONO2)
              if(-changeL(L,n_NOx) > trm(I,J,L,n_NOx))changeL(L,n_NOx)=
     &        -0.8d0*trm(I,J,L,n_NOx)
            endif
            changeL(L,n_ClONO2)=changeL(L,n_ClONO2)*CLTOT+
     &      trm(I,J,L,n_ClONO2)*(CLTOT-1.D0)
          ENDIF

c Set Total Bromine(using CLTOT name!) based on CFCs (1.0 pptv yield
C from complete oxidation of 1.8 ppbv CFC plus 0.5 pptv background) :
          !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
          !WARNING: RESETTING SOME Y's HERE; SO DON'T USE THEM BELOW!     
          !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
          y(n_BrOx,L)=(trm(I,J,L,n_BrOx)+changeL(L,n_BrOx))*y(nM,L)*
     &    mass2vol(n_BrOx)*BYDXYP(J)*BYAM(L,I,J)
          y(n_HBr,L)= (trm(I,J,L,n_HBr)+changeL(L,n_HBr))*y(nM,L)*
     &    mass2vol(n_HBr)*BYDXYP(J)*BYAM(L,I,J)
          y(n_HOBr,L)=(trm(I,J,L,n_HOBr)+changeL(L,n_HOBr))*y(nM,L)*
     &    mass2vol(n_HOBr)*BYDXYP(J)*BYAM(L,I,J)
          y(n_BrONO2,L)=(trm(I,J,L,n_BrONO2)+changeL(L,n_BrONO2))*
     &    y(nM,L)*mass2vol(n_BrONO2)*BYDXYP(J)*BYAM(L,I,J)
     
          CLTOT=((y(n_CFC,1)/y(nM,1)-y(n_CFC,L)/y(nM,L))*(1.0d-3/1.8d0)
     &    *y(n_CFC,1)/(1.8d-9*y(nM,1)))
          CLTOT=CLTOT+0.5d-12
          CLTOT=CLTOT*y(nM,L)/
     &    (y(n_BrOx,L)+y(n_HBr,L)+y(n_HOBr,L)+y(n_BrONO2,L))
          if(prnchg.and.J == jprn.and.I == iprn.and.L == lprn)then  
            write(out_line,67) CLTOT
            call write_parallel(trim(out_line),crit=jay)
 67         format ('BrTOT = ',F20.5)
          endif
          IF(CLTOT <= 0.999d0 .OR. CLTOT >= 1.001d0) THEN
            changeL(L,n_BrOx)=changeL(L,n_BrOx)*CLTOT+
     &      trm(I,J,L,n_BrOx)*(CLTOT-1.D0)
            changeL(L,n_HBr)=changeL(L,n_HBr)*CLTOT+
     &      trm(I,J,L,n_HBr)*(CLTOT-1.D0)
            changeL(L,n_HOBr)=changeL(L,n_HOBr)*CLTOT+
     &      trm(I,J,L,n_HOBr)*(CLTOT-1.D0)
c           Conserve N wrt BrONO2 once inital Br changes past:
            if(Itime-ItimeI >= 6)then
              changeL(L,n_NOx)=changeL(L,n_NOx)-
     &        (trm(I,J,L,n_BrONO2)+changeL(L,n_BrONO2))*
     &        (CLTOT-1.D0)*tr_mm(n_NOx)/tr_mm(n_BrONO2)
              if(-changeL(L,n_NOx) > trm(I,J,L,n_NOx))changeL(L,n_NOx)=
     &        -0.8d0*trm(I,J,L,n_NOx)
            endif
            changeL(L,n_BrONO2)=changeL(L,n_BrONO2)*CLTOT+
     &      trm(I,J,L,n_BrONO2)*(CLTOT-1.D0)
          ENDIF
        endif ! L > maxl
#endif

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C Save chemistry changes for applying in apply_tracer_3Dsource.  C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

        DO N=1,NTM_CHEM
          tr3Dsource(i,j,l,nChemistry,n) = changeL(l,n) * bydtsrc
        END DO
#ifdef TRACERS_HETCHEM
        tr3Dsource(i,j,l,nChemistry,n_N_d1) = changeL(l,n_N_d1) *bydtsrc
        tr3Dsource(i,j,l,nChemistry,n_N_d2) = changeL(l,n_N_d2) *bydtsrc
        tr3Dsource(i,j,l,nChemistry,n_N_d3) = changeL(l,n_N_d3) *bydtsrc
#endif

      END DO ! end current altitude loop

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
      END DO ! >>>> MAIN I LOOP ENDS <<<<

      END DO ! >>>> MAIN J LOOP ENDS <<<<
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
CCCCC!$OMP END PARALLEL DO  

#ifdef SHINDELL_STRAT_CHEM
      if(prnchg)then
       if(LM /= 23) call stop_model('alter O3 map for new LM',255)
       DO J=J_0,J_1; DO I=1,IMAXJ(J)
         ss27(1:LM,I,J)=ss(27,1:LM,I,J)
       ENDDO; ENDDO
       CALL PACK_COLUMN(grid,ss27,ss27_glob)
       IF(AM_I_ROOT()) THEN
         write(6,*) 'Map of O3 production from O2 (Herz & SRB)'
         if(which_trop == 0)write(6,*)
     &   'NOTE: lower limit of strat is actually LTROPO(I,J), however!'
         write(6,'(a4,7(i10))') 'Jqq:',(Jqq,Jqq=3,44,6)
         do Lqq=LM,LS1,-1 ! inconvenient to print down to LTROPO(I,J)
           do jqq=1,JM
             photO2_glob(Jqq,Lqq)=0.d0
             do Iqq=1,IMAXJ(jqq)
               photO2_glob(Jqq,Lqq)=photO2_glob(Jqq,Lqq)
     &         +2.d0*ss27_glob(Lqq,Iqq,Jqq) ! makes 2 Os
             enddo
           enddo
           write(6,'(i2,7(1x,E10.3))') 
     &     Lqq,(photO2_glob(Jqq,Lqq)/REAL(IMAXJ(Jqq)),Jqq=3,44,6)
         enddo
       END IF ! end AM_I_ROOT
      endif
#endif

CCCCCCCCCCCCCCCCCC END CHEMISTRY SECTION CCCCCCCCCCCCCCCCCCCCCCCCC

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C                 BEGIN OVERWRITING                              C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

C If fix_CH4_chemistry is turned on, reset the CH4 tracer everywhere
C to initial conditions (in mixing ratio units) :
      if(fix_CH4_chemistry == 1) call get_CH4_IC(1)
   
C If desired, use correction factors on stratospheric Ox:   
      if(correct_strat_Ox) then
        imonth= 1
        DO m=2,12
          IF((JDAY <= MDOFM(m)).AND.(JDAY > MDOFM(m-1))) THEN
            imonth=m
            EXIT
          END IF
        END DO
        if(Itime == ItimeI) then
          write(out_line,*)'Warning: Please remember that Ox'
     &    //' stratospheric correction factors are on and change with'
     &    //' time.'
          call write_parallel(trim(out_line))
        end if
      end if

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C Special cases of overwriting, when doing stratospheric chemistry C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC     
#ifdef SHINDELL_STRAT_CHEM      
C N2O, CFC, and optional CH4 L=1 overwriting: with all these "fact"s
C this looks complicated, but basically, you are either converting
C from mixing ratio to KG (normal case) or from cm*atm to KG  
C (interactive radiation case - for more on that conversion, see
C the notes on O3MULT in the TRCHEM_Shindell_COM program):
      PIfact(:)=1.d0     
      if(PI_run == 1)then
        PIfact(n_NOx)=PIratio_N
        if(use_rad_n2o > 0 .or. use_rad_cfc > 0) then
          write(out_line,*)
     &    'warning: use_rad_{cfc,n2o} overrides PIfact({cfc,n2o})' 
          call write_parallel(trim(out_line))
        endif     
        if(use_rad_n2o == 0) PIfact(n_N2O)=PIratio_N2O
        if(use_rad_cfc == 0) PIfact(n_CFC)=PIratio_CFC
      endif
      fact2=n2o_pppv  ! default N2O mixing ratio overwrite
      fact3=cfc_pppv  ! default CFC mixing ratio overwrite
      fact7=fact_cfc
      if(use_rad_cfc == 0)fact7=1.d0
      do j=J_0,J_1
       fact6=2.69d20*dxyp(j)*byavog
       fact5=fact6 
       fact4=fact6
       do i=1,IMAXJ(j)
        fact1=bymair*am(1,i,j)*dxyp(j)
        if(use_rad_n2o == 0)fact4=fact1 
        if(use_rad_cfc == 0)fact5=fact1
        if(use_rad_n2o > 0)fact2=rad_to_chem(1,i,j,3)
        if(use_rad_cfc > 0)fact3=rad_to_chem(1,i,j,5)
        tr3Dsource(i,j,1,nChemistry,n_N2O)=0.d0
        tr3Dsource(i,j,1,nChemistry,n_CFC)=0.d0
        tr3Dsource(i,j,1,nStratwrite,n_N2O)=(fact2*fact4*
     &  tr_mm(n_N2O)*PIfact(n_N2O) - trm(i,j,1,n_N2O))*bydtsrc
        tr3Dsource(i,j,1,nStratwrite,n_CFC)=(fact3*fact5*fact7*
     &  tr_mm(n_CFC)*PIfact(n_CFC) - trm(i,j,1,n_CFC))*bydtsrc
        if(use_rad_ch4 > 0)then
          tr3Dsource(i,j,1,nChemistry,n_CH4)=0.d0
          tr3Dsource(i,j,1,nStratwrite,n_CH4)=(rad_to_chem(1,i,j,4)*
     &    fact6*tr_mm(n_CH4)-trm(i,j,1,n_CH4))*bydtsrc
        endif
       end do
      end do

C For Ox, NOx, BrOx, and ClOx, we have overwriting where P < 0.1mb:
      !(Interpolate BrOx & ClOx altitude-dependence to model resolution)
      CALL LOGPINT(LCOalt,PCOalt,BrOxaltIN,LM,PRES2,BrOxalt,.true.)
      CALL LOGPINT(LCOalt,PCOalt,ClOxaltIN,LM,PRES2,ClOxalt,.true.)
      do L=LS1,LM
       if(pres2(L) < 0.1)then
        do j=J_0,J_1         
          do i=1,IMAXJ(j)
            ! -- Ox --
            tr3Dsource(i,j,L,nChemistry,n_Ox)=0.d0
            if(correct_strat_Ox) then
             tr3Dsource(i,j,L,nStratwrite,n_Ox)=(rad_to_chem(L,i,j,1)*
     &       dxyp(j)*O3MULT*corrOx(J,L,imonth)-trm(i,j,L,n_Ox))*bydtsrc
            else
             tr3Dsource(i,j,L,nStratwrite,n_Ox)=(rad_to_chem(L,i,j,1)*
     &       dxyp(j)*O3MULT                   -trm(i,j,L,n_Ox))*bydtsrc
            end if
            ! -- ClOx --
            tr3Dsource(i,j,L,nChemistry,n_ClOx)=0.d0
            tr3Dsource(i,j,L,nStratwrite,n_ClOx)=(1.d-11*ClOxalt(l)
     &      *vol2mass(n_ClOx)*am(L,i,j)*dxyp(j)
     &      -trm(i,j,L,n_ClOx))*bydtsrc    
            ! -- BrOx --
            tr3Dsource(i,j,L,nChemistry,n_BrOx)=0.d0
            tr3Dsource(i,j,L,nStratwrite,n_BrOx)=(1.d-11*BrOxalt(l)
     &      *vol2mass(n_BrOx)*am(L,i,j)*dxyp(j)
     &      -trm(i,j,L,n_BrOx))*bydtsrc
            ! -- NOx --
            if(PIfact(n_NOx) /= 1.) ! what's this for? I forget.
     &      tr3Dsource(i,j,L,nChemistry,n_NOx)=0.d0 !75=1*300*2.5*.1
            tr3Dsource(i,j,L,nStratwrite,n_NOx)=(75.d-11
     &      *am(L,i,j)*dxyp(j)*PIfact(n_NOx)-trm(i,j,L,n_NOx))*bydtsrc 
          end do ! I 
        end do   ! J
       end if    ! pressure
      end do     ! L

#else

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C No stratospheric chemistry; overwrite all tracers in stratosphere C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C
C W A R N I N G : This section should never be used if there is
C chemistry done in the stratosphere, because the stratospheric
C changes below assume that the changeL variable is zero for L>maxl
C at this point in the code. Not the case if chemistry was done.
C To put it another way, the overwritings below are explicitly 
C functions of tracer mass UNCHANGED by chemistry !

C determine pre-industrial factors, if any:
      PIfact(:)=1.d0
      if(PI_run == 1) then
        do N=1,NTM
          select case(trname(n))
          case('NOx','HNO3','N2O5','HO2NO2')
            PIfact(n)=PIratio_N
          case('CO')
            PIfact(n)=PIratio_CO_S
          case('PAN','Isoprene','AlkylNit','Alkenes','Paraffin')
            PIfact(n)=PIratio_other
          end select
        end do
      endif

C Calculate an average tropical CH4 value near 569 hPa::
      CH4_569_part(:)=0.d0   
      count_569_part(:)=0.d0
      DO J=J_0,J_1
        if(LAT_DG(J,1) >= -30. .and. LAT_DG(J,1) <= 30.)then
          do I=1,IMAXJ(J)
            count_569_part(J)=count_569_part(J)+1.d0
            CH4_569_part(J)=CH4_569_part(J)+1.d6*bydxyp(j)*
     &      (F569M*trm(I,J,L569M,n_CH4)*byam(L569M,I,J)+
     &      F569P*trm(I,J,L569P,n_CH4)*byam(L569P,I,J))
          end do
        end if
      END DO
      CALL GLOBALSUM(grid,  CH4_569_part,  CH4_569, all=.true.)
      CALL GLOBALSUM(grid,count_569_part,count_569, all=.true.)
      if(count_569 <= 0.)call stop_model('count_569.le.0',255)
      CH4_569 = CH4_569 / count_569

      r179=1.d0/1.79d0 ! 1.79 is observed trop. CH4

      do j=J_0,J_1
       J3=MAX(1,NINT(float(j)*float(JCOlat)*BYFJM))! index for CO
       do i=1,IMAXJ(J)
         select case(which_trop)
         case(0); maxl=ltropo(I,J)
         case(1); maxl=ls1-1
         case default; call stop_model('which_trop problem 5',255)
         end select
         changeL(:,:)=0.d0 ! initilize the change
         
         do L=maxl+1,LM    ! >> BEGIN LOOP OVER STRATOSPHERE <<
c         Update stratospheric ozone to amount set in radiation:
          if(correct_strat_Ox) then
            changeL(L,n_Ox)=rad_to_chem(L,I,J,1)*DXYP(J)*O3MULT
     &      *corrOx(J,L,imonth) - trm(I,J,L,n_Ox)
          else
            changeL(L,n_Ox)=rad_to_chem(L,I,J,1)*DXYP(J)*O3MULT
     &                          - trm(I,J,L,n_Ox)
          end if
          byam75=F75P*byam(L75P,I,J)+F75M*byam(L75M,I,J)
          FACT1=2.0d-9*DXYP(J)*am(L,I,J)*byam75
C         We think we have too little stratospheric NOx, so, to
C         increase the flux into the troposphere, increasing
C         previous stratospheric value by 70% here: GSF/DTS 9.15.03: 
          changeL(L,n_NOx)=trm(I,J,L,n_Ox)*2.3d-4*1.7d0*PIfact(n_NOx)
     &                                         - trm(I,J,L,n_NOx)
          changeL(L,n_N2O5)=  FACT1*PIfact(n_N2O5)- trm(I,J,L,n_N2O5)
          changeL(L,n_HNO3)=trm(I,J,L,n_Ox)*4.2d-3*PIfact(n_HNO3)
     &                                         - trm(I,J,L,n_HNO3)
          changeL(L,n_H2O2)=  FACT1            - trm(I,J,L,n_H2O2)
          changeL(L,n_CH3OOH)=FACT1            - trm(I,J,L,n_CH3OOH)
          changeL(L,n_HCHO)=  FACT1            - trm(I,J,L,n_HCHO)
          ! here 70. = 1.4E-7/2.0E-9
          changeL(L,n_HO2NO2)=FACT1*70.d0*PIfact(n_HO2NO2)
     &                                         - trm(I,J,L,n_HO2NO2)
          changeL(L,n_CO)=(COlat(J3)*COalt(L)*1.d-9*vol2mass(n_CO)
     &    *AM(L,I,J)*DXYP(J))*0.4d0*PIfact(n_CO)-trm(I,J,L,n_CO)!<<40%
          changeL(L,n_PAN)     = FACT1*1.d-4*PIfact(n_PAN)
     &                           - trm(I,J,L,n_PAN)
          changeL(L,n_Isoprene)= FACT1*1.d-4*PIfact(n_Isoprene)
     &                           - trm(I,J,L,n_Isoprene)
          changeL(L,n_AlkylNit)= FACT1*1.d-4*PIfact(n_AlkylNit)
     &                           - trm(I,J,L,n_AlkylNit)
          changeL(L,n_Alkenes) = FACT1*1.d-4*PIfact(n_Alkenes)
     &                           - trm(I,J,L,n_Alkenes)
          changeL(L,n_Paraffin)= FACT1*1.d-4*PIfact(n_Paraffin)
     &                           - trm(I,J,L,n_Paraffin)

c Overwrite stratospheric ch4 based on HALOE obs for tropics and
C extratropics and scale by the ratio of near-569hPa mixing ratios
C to 1.79:
          if (fix_CH4_chemistry == 0) then ! -------------------------
          CH4FACT=CH4_569*r179
          IF((J <= JS).OR.(J > JN)) THEN               ! extratropics
            DO L2=L,maxl+1,-1
              IF(CH4altX(L2) /= 0.d0) THEN
                CH4FACT=CH4FACT*CH4altX(L2)
                EXIT
              END IF
            END DO
          ELSE IF((J > JS).AND.(J <= JN)) THEN         ! tropics
            DO L2=L,maxl+1,-1
              IF(CH4altT(L2) /= 0.d0) THEN
                CH4FACT=CH4FACT*CH4altT(L2)
                EXIT
              END IF
            END DO
          END IF
          select case(PI_run)
          case(1) ! preindustrial
            if(j <= jm/2)then; PIfact(n_CH4)=pfix_CH4_S
            else             ; PIfact(n_CH4)=pfix_CH4_N
            end if
            changeL(L,n_CH4)=am(l,i,j)*dxyp(j)*vol2mass(n_CH4)
     &      *PIfact(n_CH4)  - trm(I,J,L,n_CH4)
          case default
            ! also ensure that strat overwrite is only a sink:
            changeL(L,n_CH4)=-MAX(0d0,trm(I,J,L,n_CH4)-
     &      (AM(L,I,J)*DXYP(J)*CH4FACT*1.d-6))
          end select
          else   ! ------ fixed CH4 set in get_CH4_IC(1) -------------
            changeL(L,n_CH4)=0.d0
          end if ! ---------------------------------------------------

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C Save overwrite changes for applying in apply_tracer_3Dsource.  C
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC

          DO N=1,NTM_CHEM
            tr3Dsource(i,j,l,nStratwrite,n) = changeL(l,n)*bydtsrc
          END DO

        end do ! >> END LOOP OVER STRATOSPHERE <<
       end do  ! i
      end do   ! j
#endif

CCCCCCCCCCCCCCCCCC END OVERWRITE SECTION CCCCCCCCCCCCCCCCCCCCCC

c Save new tracer Ox field for use in radiation or elsewhere:
      do j=J_0,J_1
        DU_O3(J)=0.d0 ! Drew's diagnostic...
        do i=1,imaxj(j) 
#ifdef SHINDELL_STRAT_CHEM
         maxl = LM
#else
         select case(which_trop)
         case(0); maxl=ltropo(I,J)
         case(1); maxl=ls1-1
         case default; call stop_model('maxl error',255)
         end select
#endif
         do l=1,maxl
           o3_tracer_save(l,i,j)=(trm(i,j,l,n_Ox) +
     &     (tr3Dsource(i,j,l,nChemistry,n_Ox) + 
     &     tr3Dsource(i,j,l,nStratwrite,n_Ox))*dtsrc)
     &     *bydxyp(j)*byO3MULT
           DU_O3(J)=DU_O3(J)+o3_tracer_save(l,i,j)
         end do
         if(maxl < LM) then
           do l=maxl+1,LM
             o3_tracer_save(l,i,j)=rad_to_chem(l,i,j,1)
             DU_O3(J)=DU_O3(J)+o3_tracer_save(l,i,j)
           end do
         end if
        end do ! i
        DU_O3(J)=1.d3*DU_O3(J)/IMAXJ(J)
      end do   ! j
      
      if(MOD(Itime,24) == 0)then
       call PACK_DATA( grid, DU_O3, DU_O3_glob )
       IF(AM_I_ROOT()) THEN
         write(6,*) 'Ozone column fm -90 to +90'
         write(6,'(46(f4.0,1x))') (DU_O3_glob(J),J=1,JM)
       END IF
      endif

      RETURN
      END SUBROUTINE masterchem




      SUBROUTINE Crates(I,J 1,11
#ifdef SHINDELL_STRAT_CHEM
     &   ,aero
#endif
     & )
!@sum Crates calculate chemical reaction rates for each altitude,
!@+   using JPL 00.  Includes special calculations for pressure
!@+   dependent reactions. Specifically:
!@+   #13 CO+OH->HO2+CO2, #15 HO2+HO2->H2O2+O2, #16 OH+HNO3->H2O+NO3,
!@+   and reactions #29, and #42.
!@auth Drew Shindell (modelEifications by Greg Faluvegi)
!@ver  1.0 (based on masterchem000_M23p)

C**** GLOBAL parameters and variables:
      USE MODEL_COM, only: LM,JM,LS1,JEQ,ptop,psf,sig,Itime,ItimeI
      USE RAD_COM, only  : rad_to_chem
      USE GEOM, only     : LAT_DG
      USE CONSTANT, only : PI
      USE DYNAMICS, only : LTROPO
      USE TRCHEM_Shindell_COM, only: nr2,nr3,nmm,nhet,ta,ea,rr,pe,
     &               r1,sb,nst,y,nM,nH2O,ro,sn,which_trop,T_thresh

      IMPLICIT NONE

C**** Local parameters and variables and arguments:
!@param JN J around 30 N
!@param JS J around 30 S
!@param JNN,JSS Js for "high-lat" definition
!@param nlast either ntm_chem or ntm_chem-NregOx for chemistry loops
      INTEGER, PARAMETER :: JS = JM/3 + 1, JN = 2*JM/3
      INTEGER, PARAMETER :: JNN = 5*JM/6, JSS= JM/6 + 1
!@var I,J passed horizontal position indicies
!@var dd,pp,fw,rkp,rk2,rk3M,nb,rrrr,temp dummy "working" variables
!@var L,jj dummy loop variables
!@var byta reciprocal of the local temperature
!@var rkext aerosol extinction from SAGE obs
!@var pscEx NAT PSC surface conc per unit volume (cm^2/cm^3)
!@var Ltop is number of levels with chemistry
      REAL*8                :: byta,dd,pp,fw,rkp,rk2,rk3M,rrrr,temp
      INTEGER               :: L,jj,nb,Ltop
      INTEGER, INTENT(IN)   :: I,J
#ifdef SHINDELL_STRAT_CHEM
!@var PRES local nominal pressure
!@var LAXt,LAXb lowest and highest levels to have nonzero 
!@+   RAD-code aerosol extinction 
!@var aero array =1 for nonzero rkext, otherwise 0.
      REAL*8, DIMENSION(LM) :: PSCEX,PRES,rkext
      INTEGER               :: LAXt,LAXb
      INTEGER, INTENT(OUT), dimension(LM) :: aero
#endif

#ifdef SHINDELL_STRAT_CHEM
      aero(:)=0
      Ltop=LM
      PRES(:)=SIG(:)*(PSF-PTOP)+PTOP
      rkext(:)=0.d0 ! initialize over L
      if(rad_to_chem(1,I,J,2) /= 0.)call stop_model('kext prob 0',255)
      do L=2,Ltop
        if(rad_to_chem(L,I,J,2) /= 0..and.rad_to_chem(L-1,I,J,2) == 0.)
     &  LAXb=L
        if(rad_to_chem(L,I,J,2) == 0..and.rad_to_chem(L-1,I,J,2) /= 0.)
     &  LAXt=L-1
      end do
#else
      select case(which_trop)
      case(0); Ltop=ltropo(I,J)
      case(1); Ltop=ls1-1
      case default; call stop_model('which_trop problem 6',255)
      end select
#endif
      do L=1,Ltop            !  >>> BEGIN ALTITUDE LOOP <<<
        byta=1.d0/ta(L)
        do jj=1,nr2             ! bimolecular rates start
          IF(ea(jj) /= 0.d0) THEN
            rr(jj,L)=pe(jj)*exp(-ea(jj)*byta)
          ELSE
            rr(jj,L)=pe(jj)
          END IF
c         for #13, k=pe*(1+0.6*(Patm/1013)) Patm=[M]*(T*1.38E-19)
          if(jj == 13) rr(jj,L) =
     &    pe(jj)*(1.d0+0.6d0*((y(nM,L)*ta(L)*1.38d-19)/1013.d0))
c         for reaction #15, k=(kc+kp)fw, kc=rr
          if(jj == 15)then
            rkp=1.7d-33*y(nM,L)*exp(1000.d0*byta)
            fw=(1.d0+1.4d-21*y(nH2O,L)*exp(2200.d0*byta))
            rr(jj,L)=(rr(jj,L)+rkp)*fw
          endif
c         for #16, k=[pe*exp(-e(jj)/ta(l))]+k3[M]/(1+k3[M]/k2)
          if(jj == 16)then
            rk3M=y(nM,l)*1.90d-33*exp(725.d0*byta)
            rk2=4.10d-16*exp(1440.d0*byta)
            rr(jj,L)=rr(jj,L)+rk3M/(1.d0+(rk3M/rk2))
          endif
          if(jj == 29)rr(jj,L)=rr(jj,L)/y(nM,L)!PAN+M really PAN
          if(jj == 42)rr(jj,L)=rr(jj,L)/y(nM,L)!ROR+M really ROR
        end do                ! bimolecular rates end

#ifdef SHINDELL_STRAT_CHEM
        rr(87,L)=rr(87,L)*1.76d0  ! N2O+O(1D)-->NO+NO 
#endif
        do jj=1,nr3           ! trimolecular rates start
          rr(nr2+jj,L)=y(nM,L)*ro(jj)*(300.d0*byta)**sn(jj)
          if(sb(jj) >= 0.01d0)then 
            dd=rr(nr2+jj,L)/(r1(jj)*(300.d0*byta)**sb(jj))
            pp=0.6d0**(1.d0/(1.d0+(log10(dd))**2.))
            rr(nr2+jj,L)=(rr(nr2+jj,L)/(1.d0+dd))*pp
          endif
        end do                ! trimolecular rates end

        nb=nr2-nmm
        if(nmm >= 1) then
          do jj=1,nmm         ! monomolecular rates start
           ! 0.5 for precision,correct following line:
           rrrr=exp(0.5d0*ea(jj+nb)*byta)
           rr(jj+nb,L)=rr(nst(jj),L)/(rrrr*pe(jj+nb)*rrrr*y(nM,l))     
          end do              ! monomolecular rates end
        end if

#ifdef SHINDELL_STRAT_CHEM
c Calculate rates for heterogeneous reactions (Divided by solid
C in Chem1). sticking coefficients from JPL '02:
c       1=N2O5 + H2O --> 2HNO3          gamma=0.2 (aero),   0.0004 (PSC)
c       2=ClONO2 + H2O --> HOCl + HNO3  gamma=1.8d-4 (aero), 0.004 (PSC)
c       3=ClONO2 + HCl --> Cl2 + HNO3   gamma=0.2
c       4=HOCl + HCl --> Cl2 + H2O      gamma=0.1
c       5=N2O5 + HCl --> ClNO2 + HNO3   gamma=0.003
C
C Aerosols (14-33 km) & PSCs 14-22 km.
C
c Aerosol profiles and latitudinal distribution of extinction 
c coefficients(in km**-1) are from SAGE II data on GISS web site:

        if(pres(l) >= 245.d0 .or. pres(l) <= 5.d0)then 
          do jj=nr2+nr3+1,nr2+nr3+nhet
            rr(jj,L)=1.0d-35
          enddo 
          CYCLE
        else  
          if((pres(l) < 245.d0.and.pres(l) > 150.d0) .or. 
     &    LAXb < 1.or.LAXb > ltop.or.LAXt < 1.or.LAXt > ltop)then 
            rkext(l)=0.d0
          else
            if(pres(l) <= 150..and.pres(l) > 31.60)then
              if(l < LAXb) then
                rkext(l)=5.d-2*rad_to_chem(LAXb,i,j,2)
              else if(l > LAXt) then
                rkext(l)=0.33d0*rkext(l-1)
              else
                rkext(l)=5.d-2*rad_to_chem(l,i,j,2)
              endif
            endif
            if(pres(l) <= 31.6d0.and.pres(l) >= 17.8d0)then
              if(l < LAXb) then
                call stop_model('kext problem 1',255)
              else if(l > LAXt) then
                rkext(l)=2.0d0*rkext(l-1)
              else
                rkext(l)=5.d-2*rad_to_chem(l,i,j,2)
              endif
            endif
            if(pres(l) <= 17.8d0.and.pres(l) >= 10.0d0)then
              if(l < LAXb) then
                call stop_model('kext problem 2',255)
              else if(l > LAXt) then
                rkext(l)=16.d0*8.33333d-2*rkext(l-1)
              else
                rkext(l)=5.d-2*rad_to_chem(l,i,j,2)
              endif
            endif
            if(pres(l) <= 10.0d0.and.pres(l) >= 4.6d0)then
              if(l < LAXb) then
                call stop_model('kext problem 3',255)
              else if(l > LAXt) then
                rkext(l)=0.4d0*6.6667d-1*rkext(l-1)
              else
                rkext(l)=0.5d-2*rad_to_chem(l,i,j,2)
              endif
            endif
          endif

          IF(PRES(L) < 90. .and. J > JS .and. J <= JN)
     &    rkext(l)=rkext(l)*0.1d0   !<<<<<<<<<<< NOTE <<<<<<<<<<<
   
          rkext(l)=rkext(l)*2.0d0   !<<<<<<<<<<< NOTE <<<<<<<<<<<
           
          if(rkext(l) /= 0.)aero(l) = 1

c         PSCs: (pressure < 245mb and pressure > 5mb here):
          !NAT PSC surface conc per unit volume (cm^2/cm^3)
          pscEx(l)=0.d0
          if(pres(l) >= 31.6d0.and.ta(l) <= T_thresh .and.
     &    ((lat_dg(J,1) <= -66.).OR.(lat_dg(J,1) >= 66.)))then
            pscEx(l)=2.d-6 
            if(ta(l) <= T_thresh-7.d0)pscEx(l)=pscEx(l)*1.d1
          endif

c         Reaction 1 on sulfate and PSCs:      
          temp=sqrt(8.d0*1.38d-16*ta(l)*6.02d23/(PI*108.d0))
          rr(nr2+nr3+1,L)=0.5d0*rkext(l)*1.d-5*temp*0.2d0
          if(pres(l) > 31.6d0) rr(nr2+nr3+1,L)=
     &    rr(nr2+nr3+1,L)+0.25d0*pscEx(l)*temp*0.0008d0

c         Reaction 2 on sulfate and PSCs:      
          temp=sqrt(8.d0*1.38d-16*ta(l)*6.02d23/(PI*97.d0))
          rr(nr2+nr3+2,L)=0.5d0*rkext(l)*1.d-5*temp*1.8d-4
          if(pres(l) > 31.6d0) rr(nr2+nr3+2,L)=
     &    rr(nr2+nr3+2,L)+0.25d0*pscEx(l)*temp*8.d-3 

          if(pres(l) > 31.6d0) then
            rr(nr2+nr3+3,L)=0.25d0*pscEx(l)*temp*0.2d0
            rr(nr2+nr3+4,L)=
     &      sqrt(8.d0*1.38d-16*ta(l)*6.02d23/(PI*52.d0))
            rr(nr2+nr3+4,L)=0.25d0*pscEx(l)*rr(nr2+nr3+4,L)*0.1d0
            rr(nr2+nr3+5,L)=
     &      sqrt(8.d0*1.38d-16*ta(l)*6.02d23/(PI*108.d0))
            rr(nr2+nr3+5,L)=0.25d0*pscEx(l)*rr(nr2+nr3+5,L)*0.003d0
          endif
        endif  
#endif
      end do                  !  >>> END ALTITUDE LOOP <<<
 
      RETURN
      END SUBROUTINE Crates



#ifdef TRACERS_SPECIAL_Shindell

      SUBROUTINE checktracer(I,J) 1,10
!@sum checktracer for various debugging of tracer chemistry
!@auth Drew Shindell (modelEifications by Greg Faluvegi)
!@ver  1.0 (based on masterchem000_M23p)

C**** GLOBAL parameters and variables:
      USE MODEL_COM, only  : Itime, LM, LS1
      USE DYNAMICS, only   : LTROPO
      USE TRACER_COM, only : ntm, trname, n_Ox, ntm_chem
#ifdef regional_Ox_tracers
     & ,NregOx
#endif
      USE TRCHEM_Shindell_COM, only: y, nM, which_trop

      IMPLICIT NONE

C**** Local parameters and variables and arguments:
!@var I,J passed horizontal position indicies
!@var L,igas dummy loop variables
!@var tlimit if tracer goes above this limit, model stops
!@var checkOx logical: should I check for large tropospheric Ox?
!@var checkmax logical: should I check for large tracers throughout?
!@var checkNeg logical: should I check for negative tracers?
!@var checkNaN logical: should I check for unreal tracers?
!@var nlast either ntm or ntm-NregOx
!@var maxL LTROPO(I,J) or LS1-1, depending upon which_trop variable

      INTEGER, PARAMETER :: nlast=
#ifdef regional_Ox_tracers
     & ntm_chem-NregOx
#else
     & ntm_chem
#endif
      INTEGER                  :: L, igas, maxL
      INTEGER, INTENT(IN)      :: I,J
      REAL*8, DIMENSION(nlast) :: tlimit
      DATA tlimit/
     &9.d-5,1.d-5,1.d-7,3.d-6,1.d-1,1.d-6,3.d-6,1.d-1,1.d-1,1.d-1,
     &1.d-1, 1.d-1, 1.d-1, 1.d-1, 1.d-1
#ifdef SHINDELL_STRAT_CHEM
     &,1.d-1, 1.d-1, 1.d-1, 1.d-1, 1.d-1
     &,1.d-1, 1.d-1, 1.d-1, 1.d-1, 1.d-1/
#else
     & /
#endif
    
      LOGICAL :: checkOx, checkmax, checkNeg, checkNan
      DATA checkNeg /.true./
      DATA checkNan /.true./
      DATA checkOx  /.true./
      DATA checkmax /.false./

      IF(i == 1.and.j == 1)
     & WRITE(6,*) 'WARNING: checktracer call is active.'
      select case(which_trop)
      case(0); maxl=ltropo(I,J)
      case(1); maxl=ls1-1
      case default; call stop_model('which_trop problem 7',255)
      end select

      IF(checkmax)
     &call stop_model('checktracer: set tlimit for tracers 11->25',255)
C     please (re)set tlimit values for tracers 11 through 15 in the
C     data statement above. Then, please delete the above stop.

C check if ozone gets really big:
       IF(checkOx) THEN
       do L=1,maxL
         if(y(n_Ox,L)/y(nM,L) > 1.d-5) then
           write(6,*)'Ox @ I,J,L,Ox,Itime:',I,J,L,y(n_Ox,L),Itime
           call stop_model('checktracer: Ox too big in tropo.',255)
         end if
       end do
#ifdef SHINDELL_STRAT_CHEM
       do L=maxL+1,LM
         if(y(n_Ox,L)/y(nM,L) > 1.5d-5) then
           write(6,*)'Ox @ I,J,L,Ox,Itime:',I,J,L,y(n_Ox,L),Itime
           call stop_model('checktracer: Ox too big in strato.',255)
         end if
       end do
#endif
       END IF
       
c general check on maximum of tracers:
      IF(checkmax) THEN
      do L=1,LM
       do igas=1,nlast
        if(y(igas,L)/y(nM,L) > tlimit(igas)) then
          write(6,*) trname(igas),'@ I,J,L,Y :',I,J,L,y(igas,L)
          call stop_model('checktracer: tracer upper limit',255)
        end if
       end do
      end do
      END IF

c check for negative tracers:
      IF(checkNeg) THEN
      do L=1,LM
       do igas=1,nlast
        if(y(igas,L) < 0.d0) THEN
          write(6,*)trname(igas),
     &    'negative @ tau,I,J,L,y:',Itime,I,J,L,y(igas,L)
          call stop_model('checktracer: tracer is negative',255)
        end if
       enddo
      end do
      END IF

c check for unreal (not-a-number) tracers (maybe SGI only?):
      IF(checkNaN) THEN
      do L=1,LM
       do igas=1,nlast
        if(.NOT.(y(igas,L) > 0.d0.OR.y(igas,L) <= 0.d0)) THEN
         write(6,*)trname(igas),
     &   'is not a number @ tau,I,J,L,y:',Itime,I,J,L,y(igas,L)
         call stop_model('checktracer: tracer is NaN',255)
        end if
       enddo
      end do
      END IF
      RETURN

      END SUBROUTINE checktracer
#endif