Index: trunk/LMDZ.GENERIC/README
===================================================================
--- trunk/LMDZ.GENERIC/README	(revision 2541)
+++ trunk/LMDZ.GENERIC/README	(revision 2542)
@@ -1662,2 +1662,8 @@
 ==16/06/2021 == MT
 - Add the Surface SW spectrum in diagspecVI netcdf output file (useful as a diagnostic of surface radiation condition for e.g. habitability studies)
+
+== 05/07/2021 == YJ
+Large update of the chemical modules
+- Read chemical network from input files
+- Init chemistry with ModernTrac
+- Photolysis online calculation
Index: trunk/LMDZ.GENERIC/deftank/traceur.def.modern
===================================================================
--- trunk/LMDZ.GENERIC/deftank/traceur.def.modern	(revision 2541)
+++ trunk/LMDZ.GENERIC/deftank/traceur.def.modern	(revision 2542)
@@ -22,21 +22,34 @@
 #               only mandatory information ! But you can specify all the options you
 #               want in separate blocks following 'option=value', assuming this option
-#               is defined in traceur_h.F90 & initracer.F for physics or infotrac.F90 
-#               for dynamics. Indeed this file is read once by dynamics who keep only
-#               the information needed and re-read by physics.
+#               is defined in traceur_h.F90 & initracer.F for physics, infotrac.F90 
+#               for dynamics or chimiedata_h.F90 & calchim_asis.F90 for chemistry.
+#               Indeed this file is read once by dynamics, once by physics and once by
+#               chemistry who keep only the information needed.
 #
 #               Note that by default a tracer listed below will be sent to dynamics
 #               except if you specify is_dyn=0. If nothing is given, then is_dyn=1.
+#               Not yet fully implemented.
 #
 # 3. Options.   Implemented options listed below.
 # ~~~~~~~~~~~~  For dynamic see "infotrac.F90".
 #               For physic see "initracer.F90".
+#               For chemistry see "calchim_asis.F90".
+#                        init see "inichim_1D.F90" and "inichim_newstart.F90"
 #
-# Dynamic:      vadv        ! index of vertical trasport schema
-#               hadv        ! index of horizontal trasport schema
-#               tnom_transp ! transporting fluid short name: CRisi
+# Dynamic:      vadv           ! index of vertical trasport schema
+#               hadv           ! index of horizontal trasport schema
+#               tnom_transp    ! transporting fluid short name: CRisi
 #
-# Physic:       mmol        ! mole mass of tracer (g/mol-1)
+# Physic:       mmol           ! mole mass of tracer [g.mol-1]
+#               aki            ! coefficient of thermal concduction
+#               cpi            ! heat capacity [J.kg-1.K-1]
+#               is_chim        ! 1 if tracer used in chemistry, else 0
 #
+# Chemistry:    SF_mode        ! 1 if surface set up value, else 2 sedimentation velocity
+#               SF_value       ! [vmr] if SF_mode=1, else [cm.s-1]
+#               prod_rate      ! if SF_mode=2 production flux [molecules.m-2.s-1]
+#
+#      init:    qx             ! value that initialize constant profile [vmr]
+#               qxf            ! file that initialize profile [Pa,vmr] (1 line header)
 #
 #
Index: trunk/LMDZ.GENERIC/libf/aeronostd/calchim_asis.F90
===================================================================
--- trunk/LMDZ.GENERIC/libf/aeronostd/calchim_asis.F90	(revision 2541)
+++ trunk/LMDZ.GENERIC/libf/aeronostd/calchim_asis.F90	(revision 2542)
@@ -3,15 +3,15 @@
                          zzlev,zzlay,zday,pq,pdq,dqchim,dqschim,            &
                          tauref,co2ice,                                     &
-                         pu,pdu,pv,pdv,surfdust,surfice)
-
-      use tracer_h, only:   igcm_co2, igcm_co, igcm_o, igcm_o1d, igcm_o2, &
-                            igcm_o3, igcm_h, igcm_h2, igcm_oh, igcm_ho2,  &
-                            igcm_h2o2, igcm_ch4, igcm_n2, igcm_h2o_vap,   &
-                            igcm_n, igcm_no, igcm_no2, igcm_n2d,   &
-                            mmol
+                         pu,pdu,pv,pdv,surfdust,surfice,icount,zdtchim)
+
+      use tracer_h, only: mmol, noms, nesp, is_chim
 
       use conc_mod, only: mmean ! mean molecular mass of the atmosphere
       USE comcstfi_mod
       use callkeys_mod
+      use time_phylmdz_mod, only: ecritphy, iphysiq ! output rate set by ecritphy
+      use types_asis,       only: v_phot_3d, jlabel, nb_phot_hv_max
+      use chimiedata_h
+      use radcommon_h,      only: glat
 
       implicit none
@@ -35,4 +35,5 @@
 !    update 11/12/2013 optimization (Franck Lefevre)
 !    update 20/10/2017 adapted to LMDZ GENERIC+cosmetic changes (Benjamin Charnay)
+!    update 06/03/2021 generic tracer/network + photolysis online (Yassin Jaziri)
 !
 !   Arguments:
@@ -62,10 +63,8 @@
 !  Output:
 !
-!    dqchim(ngrid,nlayer,nq) ! tendencies on pq due to chemistry
-!    dqschim(ngrid,nq)         ! tendencies on qsurf 
-!
-!=======================================================================
-
-#include "chimiedata.h"
+!    dqchim(ngrid,nlayer,nesp)   ! tendencies on pq due to chemistry
+!    dqschim(ngrid,nesp)         ! tendencies on qsurf 
+!
+!=======================================================================
 
 !     input:
@@ -76,5 +75,5 @@
       real :: ptimestep
       real :: pplay(ngrid,nlayer)    ! pressure at the middle of the layers
-      real :: zzlay(ngrid,nlayer)    ! pressure at the middle of the layers
+      real :: zzlay(ngrid,nlayer)    ! altitude at the middle of the layers
       real :: pplev(ngrid,nlayer+1)  ! intermediate pressure levels
       real :: zzlev(ngrid,nlayer+1)  ! altitude at layer boundaries
@@ -97,39 +96,15 @@
 !     output:
 
-      real :: dqchim(ngrid,nlayer,nq)   ! tendencies on pq due to chemistry
-      real :: dqschim(ngrid,nq)         ! tendencies on qsurf 
+      real :: dqchim(ngrid,nlayer,nesp)   ! tendencies on pq due to chemistry
+      real :: dqschim(ngrid,nesp)         ! tendencies on qsurf 
 
 !     local variables:
 
-      integer,save :: nbq                   ! number of tracers used in the chemistry
-      integer,allocatable,save :: niq(:)    ! array storing the indexes of the tracers
-      integer :: iloc(1)                    ! index of major species
-      integer :: ig,l,i,iq,iqmax
-      integer :: foundswitch, lswitch
+      integer :: iloc(1)                  ! index of major species
+      integer :: ig,l,i,iq,iqmax,iesp
+      integer :: foundswitch, lswitch     ! to switch between photochem and thermochem ? (YJ)
       integer,save :: chemthermod
 
-      integer,save :: i_co2  = 0
-      integer,save :: i_co   = 0
-      integer,save :: i_o    = 0
-      integer,save :: i_o1d  = 0
-      integer,save :: i_o2   = 0
-      integer,save :: i_o3   = 0
-      integer,save :: i_h    = 0
-      integer,save :: i_h2   = 0
-      integer,save :: i_oh   = 0
-      integer,save :: i_ho2  = 0
-      integer,save :: i_h2o2 = 0
-      integer,save :: i_ch4  = 0
-      integer,save :: i_n2   = 0
-      integer,save :: i_h2o  = 0
-      integer,save :: i_n    = 0
-      integer,save :: i_no    = 0
-      integer,save :: i_no2    = 0
-      integer,save :: i_n2d    = 0
-
-      integer :: ig_vl1
-
-      real    :: latvl1, lonvl1
-      real    :: zq(ngrid,nlayer,nq)   ! pq+pdq*ptimestep before chemistry
+      real    :: zq(ngrid,nlayer,nesp) ! pq+pdq*ptimestep before chemistry
                                        ! new mole fraction after
       real    :: zt(ngrid,nlayer)      ! temperature
@@ -137,7 +112,7 @@
       real    :: zv(ngrid,nlayer)      ! v component of the wind
       real    :: taucol                ! optical depth at 7 hPa
-
+      real    :: xmmol(nlayer,nesp)    ! mmol/mmean but only for chemical species
+ 
       logical,save :: firstcall = .true.
-      logical,save :: depos = .false.  ! switch for dry deposition
 
 !     for each column of atmosphere:
@@ -147,5 +122,5 @@
       real :: ztemp(nlayer)        ! Temperature (K)
       real :: zlocal(nlayer)       ! Altitude (km)
-      real :: zycol(nlayer,nq)     ! Composition (mole fractions)
+      real :: zycol(nlayer,nesp)   ! Composition (mole fractions)
       real :: zmmean(nlayer)       ! Mean molecular mass (g.mole-1)
       real :: szacol               ! Solar zenith angle
@@ -154,16 +129,18 @@
       real :: surfice1d(nlayer)    ! Ice surface area (cm2/cm3)
       real :: surfdust1d(nlayer)   ! Dust surface area (cm2/cm3)
-      real :: jo3(nlayer)          ! Photodissociation rate O3->O1D (s-1)
 
       integer :: iter(nlayer)      !  Number of chemical iterations
                                    !  within one physical timestep 
-
+      integer :: icount
 !     for output:
 
-      logical :: output             ! to issue calls to writediagfi and stats
+      logical :: output              ! to issue calls to writediagfi and stats
       parameter (output = .true.)
-      real :: jo3_3d(ngrid,nlayer)  ! Photodissociation rate O3->O1D (s-1)
-      real :: iter_3d(ngrid,nlayer) ! Number of chemical iterations
-                                    !  within one physical timestep
+      real :: iter_3d(ngrid,nlayer)  ! Number of chemical iterations
+                                     !  within one physical timestep
+      integer           ::  ierr
+      real              ::  zdtchim(ngrid,nlayer)    ! temperature modification by chemistry
+      real              ::  dEzchim(ngrid,nlayer)    ! energy modification by chemistry
+      real              ::  zdtchim_output(ngrid)    ! flux modification by chemistry in W.m-2
 
 !=======================================================================
@@ -173,203 +150,41 @@
       if (firstcall) then
 
-         if (photochem) then
-            print*,'calchim: Read photolysis lookup table'
-            call read_phototable
-         end if
-         ! find index of chemical tracers to use
-         allocate(niq(nq))
-         ! Listed here are all tracers that can go into photochemistry
-         nbq = 0 ! to count number of tracers
-         ! Species ALWAYS present if photochem=.T. or thermochem=.T.
-         i_co2 = igcm_co2
-         if (i_co2 == 0) then
-            write(*,*) "calchim: Error; no CO2 tracer !!!"
-            stop
-         else
-            nbq = nbq + 1
-            niq(nbq) = i_co2
-         end if
-         i_co = igcm_co
-         if (i_co == 0) then
-            write(*,*) "calchim: Error; no CO tracer !!!"
-            stop
-         else
-            nbq = nbq + 1
-            niq(nbq) = i_co
-         end if
-         i_o = igcm_o
-         if (i_o == 0) then
-            write(*,*) "calchim: Error; no O tracer !!!"
-            stop
-         else
-            nbq = nbq + 1
-            niq(nbq) = i_o
-         end if
-         i_o1d = igcm_o1d
-         if (i_o1d == 0) then
-            write(*,*) "calchim: Error; no O1D tracer !!!"
-            stop
-         else
-            nbq = nbq + 1
-            niq(nbq) = i_o1d
-         end if
-         i_o2 = igcm_o2
-         if (i_o2 == 0) then
-            write(*,*) "calchim: Error; no O2 tracer !!!"
-            stop
-         else
-            nbq = nbq + 1
-            niq(nbq) = i_o2
-         end if
-         i_o3 = igcm_o3
-         if (i_o3 == 0) then
-            write(*,*) "calchim: Error; no O3 tracer !!!"
-            stop
-         else
-            nbq = nbq + 1
-            niq(nbq) = i_o3
-         end if
-         i_h = igcm_h
-         if (i_h == 0) then
-            write(*,*) "calchim: Error; no H tracer !!!"
-            stop
-         else
-            nbq = nbq + 1
-            niq(nbq) = i_h
-         end if
-         i_h2 = igcm_h2
-         if (i_h2 == 0) then
-            write(*,*) "calchim: Error; no H2 tracer !!!"
-            stop
-         else
-            nbq = nbq + 1
-            niq(nbq) = i_h2
-         end if
-         i_oh = igcm_oh
-         if (i_oh == 0) then
-            write(*,*) "calchim: Error; no OH tracer !!!"
-            stop
-         else
-            nbq = nbq + 1
-            niq(nbq) = i_oh
-         end if
-         i_ho2 = igcm_ho2
-         if (i_ho2 == 0) then
-            write(*,*) "calchim: Error; no HO2 tracer !!!"
-            stop
-         else
-            nbq = nbq + 1
-            niq(nbq) = i_ho2
-         end if
-         i_h2o2 = igcm_h2o2
-         if (i_h2o2 == 0) then
-            write(*,*) "calchim: Error; no H2O2 tracer !!!"
-            stop
-         else
-            nbq = nbq + 1
-            niq(nbq) = i_h2o2
-         end if
-         i_ch4 = igcm_ch4
-         if (i_ch4 == 0) then
-            write(*,*) "calchim: Error; no CH4 tracer !!!"
-            write(*,*) "CH4 will be ignored in the chemistry"
-         else
-            nbq = nbq + 1
-            niq(nbq) = i_ch4
-         end if
-         i_n2 = igcm_n2
-         if (i_n2 == 0) then
-            write(*,*) "calchim: Error; no N2 tracer !!!"
-            stop
-         else
-            nbq = nbq + 1
-            niq(nbq) = i_n2
-         end if
-         i_n = igcm_n
-         if (i_n == 0) then
-            if (photochem) then
-               write(*,*) "calchim: Error; no N tracer !!!"
-               write(*,*) "N will be ignored in the chemistry"
+!! Moved to routine indice in photochemistry_asis
+!! because nb_phot_hv_max value needed in order
+!! to choose if we call read_phototable or not.
+!! A cleaner solution need to be find.
+!         if (photochem .and. .not. jonline) then
+!           print*,'calchim: Read photolysis lookup table'
+!           call read_phototable
+!         end if
+
+         if (.not.allocated(SF_mode))       allocate(SF_mode(nesp))
+         if (.not.allocated(SF_value))      allocate(SF_value(nesp))
+         if (.not.allocated(prod_rate))     allocate(prod_rate(nesp))
+         if (.not.allocated(surface_flux))  allocate(surface_flux(ngrid,nesp))
+         if (.not.allocated(surface_flux2)) allocate(surface_flux2(ngrid,nesp))
+         if (.not.allocated(escape))        allocate(escape(ngrid,nesp))
+         if (.not.allocated(chemnoms))      allocate(chemnoms(nesp))
+
+         surface_flux(:,:)  = 0.
+         surface_flux2(:,:) = 0.
+         escape(:,:)        = 0.
+         SF_mode(:)         = 2
+         SF_value(:)        = 0.
+         prod_rate(:)       = 0.
+         iter_3d(:,:)       = 0.
+         iter(:)            = 0.
+
+         call ini_tracchim
+
+         ! Sanity check mmol /= 0. in chemistry
+         do iq = 1,nq
+            if (is_chim(iq).eq.1 .and. mmol(iq).eq.0.) then
+               write(*,*) 'Error in calchim:'
+               write(*,*) 'Mmol cannot be equal to 0 for chemical species'
+               stop
             end if
-         else
-            nbq = nbq + 1
-            niq(nbq) = i_n
-         end if
-         i_n2d = igcm_n2d
-         if (i_n2d == 0) then
-            if (photochem) then
-               write(*,*) "calchim: Error; no N2D tracer !!!"
-               write(*,*) "N2d will be ignored in the chemistry"
-            end if
-         else
-            nbq = nbq + 1
-            niq(nbq) = i_n2d
-         end if
-         i_no = igcm_no
-         if (i_no == 0) then
-            if (photochem) then
-               write(*,*) "calchim: Error; no NO tracer !!!"
-               write(*,*) "NO will be ignored in the chemistry"
-            end if
-         else
-            nbq = nbq + 1
-            niq(nbq) = i_no
-         end if
-         i_no2 = igcm_no2
-         if (i_no2 == 0) then
-            if (photochem) then
-               write(*,*) "calchim: Error; no NO2 tracer !!!"
-               write(*,*) "NO2 will be ignored in the chemistry"
-            end if
-         else
-            nbq = nbq + 1
-            niq(nbq) = i_no2
-         end if
-         i_h2o = igcm_h2o_vap
-         if (i_h2o == 0) then
-            write(*,*) "calchim: Error; no water vapor tracer !!!"
-            stop
-         else
-            nbq = nbq + 1
-            niq(nbq) = i_h2o
-         end if
-         !Check tracers needed for thermospheric chemistry
-!         if(thermochem) then
-!            chemthermod=0  !Default: C/O/H chemistry
-!            !Nitrogen chemistry
-!            !NO is used to determine if N chemistry is wanted
-!            !chemthermod=2 -> N chemistry
-!            if (i_no == 0) then
-!               write(*,*) "calchim: no NO tracer"
-!               write(*,*) "C/O/H themosp chemistry only "
-!            else
-!               chemthermod=2
-!               write(*,*) "calchim: NO in traceur.def"
-!               write(*,*) "Nitrogen chemistry included"
-!            end if
-!            ! N
-!            if(chemthermod == 2) then
-!               if (i_n == 0) then
-!                  write(*,*) "calchim: Error; no N tracer !!!"
-!                  write(*,*) "N is needed if NO is in traceur.def"
-!                  stop
-!               end if
-!            ! NO2
-!               if (i_no2 == 0) then
-!                  write(*,*) "calchim: Error; no NO2 tracer !!!"
-!                  write(*,*) "NO2 is needed if NO is in traceur.def"
-!                  stop
-!               end if
-!            ! N(2D)
-!               if (i_n2d == 0) then
-!                  write(*,*) "calchim: Error; no N2D !!!"
-!                  write(*,*) "N2D is needed if NO is in traceur.def"
-!                  stop
-!               end if
-!            endif    !Of if(chemthermod == 2)
-!         endif      !Of thermochem
-
-         write(*,*) 'calchim: found nbq    = ',nbq,' tracers'
-               
+         end do
+
          firstcall = .false.
       end if ! if (firstcall)
@@ -380,9 +195,4 @@
       dqchim(:,:,:) = 0.
       dqschim(:,:)  = 0.
-
-!     latvl1= 22.27
-!     lonvl1= -47.94
-!     ig_vl1= 1+ int( (1.5-(latvl1-90.)*jjm/180.)  -2 )*iim +    &
-!             int(1.5+(lonvl1+180)*iim/360.)
 
 !=======================================================================
@@ -394,9 +204,14 @@
          foundswitch = 0
          do l = 1,nlayer
-            do i = 1,nbq
-               iq = niq(i) ! get tracer index
-               zq(ig,l,iq) = pq(ig,l,iq) + pdq(ig,l,iq)*ptimestep
-               zycol(l,iq) = zq(ig,l,iq)*mmean(ig,l)/mmol(iq)
-            end do
+            iesp = 0
+            do iq = 1,nq
+               if (is_chim(iq).eq.1) then
+                  iesp = iesp + 1
+                  zq(ig,l,iesp) = pq(ig,l,iq) + pdq(ig,l,iq)*ptimestep
+                  xmmol(l,iesp) = mmol(iq)/mmean(ig,l)
+                  zycol(l,iesp) = zq(ig,l,iesp)/xmmol(l,iesp)
+               end if
+            end do
+
             zt(ig,l)  = pt(ig,l) + pdt(ig,l)*ptimestep
             zu(ig,l)  = pu(ig,l) + pdu(ig,l)*ptimestep
@@ -430,7 +245,7 @@
          end do ! of do l=1,nlayer
 
-         szacol = acos(mu0(ig))*180./pi
-         taucol = tauref(ig)*(700./610.)  ! provisoire en attente de nouveau jmars
-         fractcol=fract(ig)
+         szacol   = acos(mu0(ig))*180./pi
+         taucol   = tauref(ig)*(700./610.)  ! provisoire en attente de nouveau jmars
+         fractcol = fract(ig)
 
 !=======================================================================
@@ -440,24 +255,21 @@
 !        chemistry in lower atmosphere
 
-         if (photochem) then
-
-            call photochemistry_asis(nlayer,nq,ngrid,                          &
-                                ig,lswitch,zycol,szacol,fractcol,ptimestep,    &
-                                zpress,ztemp,zdens,zmmean,dist_sol,            &
-                                surfdust1d,surfice1d,jo3,taucol,iter)
-
-!        ozone photolysis, for output
-
+!         if (photochem) then
+
+            call photochemistry_asis(nlayer,ngrid,                         &
+                                ig,lswitch,zycol,szacol,fractcol,ptimestep,&
+                                zpress,zlocal,ztemp,zdens,zmmean,dist_sol, &
+                                surfdust1d,surfice1d,taucol,iter,zdtchim(ig,:))
+
+            ! diagnostic photochemical heating
+            zdtchim_output(ig) = 0.
             do l = 1,nlayer
-               jo3_3d(ig,l) = jo3(l)
+              dEzchim(ig,l) = zdtchim(ig,l)*cpp*(pplev(ig,l) - pplev(ig,l+1))/glat(ig)
+              zdtchim_output(ig) = zdtchim_output(ig) + zdtchim(ig,l)*cpp*(pplev(ig,l) - pplev(ig,l+1))/glat(ig)
+            end do
+
+            do l = 1,nlayer
                iter_3d(ig,l) = iter(l)
             end do
-
-!        condensation of h2o2
-
-!            call perosat(ngrid, nlayer, nq,                        &
-!                         ig,ptimestep,pplev,pplay,                 &
-!                         ztemp,zycol,dqcloud,dqscloud)
-         end if
 
 !        chemistry in upper atmosphere
@@ -470,9 +282,18 @@
 !        dry deposition
 
-!         if (depos) then
-!            call deposition(ngrid, nlayer, nq,                      &
-!                            ig, ig_vl1, pplay, pplev, zzlay, zzlev, & 
-!                            zu, zv, zt, zycol, ptimestep, co2ice)
-!         end if
+         if (depos) then
+            call deposition_source(ngrid, nlayer, nq,   &
+                        ig, zzlay, zzlev, zdens, zycol, ptimestep)
+            surface_flux2(ig,:) = surface_flux2(ig,:) + surface_flux(ig,:)
+            if (ngrid==1) then
+              if(mod(icount,ecritphy).eq.0) then
+                surface_flux2(ig,:) = surface_flux2(ig,:)/float(ecritphy)
+              endif
+            else
+              if(mod(icount*iphysiq,ecritphy).eq.0) then
+                surface_flux2(ig,:) = surface_flux2(ig,:)*iphysiq/float(ecritphy)
+              endif
+            endif
+         end if
 
 !=======================================================================
@@ -489,12 +310,12 @@
             iloc=maxloc(zycol(l,:))
             iqmax=iloc(1)
-            do i = 1,nbq
-               iq = niq(i) ! get tracer index
+            do iq = 1,nesp
                if (iq /= iqmax) then
-                  dqchim(ig,l,iq) = (zycol(l,iq)*mmol(iq)/mmean(ig,l) - zq(ig,l,iq))/ptimestep
+                  dqchim(ig,l,iq) = (zycol(l,iq)*xmmol(l,iq) - zq(ig,l,iq))/ptimestep
                   dqchim(ig,l,iq) = max(dqchim(ig,l,iq),-zq(ig,l,iq)/ptimestep)
                   dqchim(ig,l,iqmax) = dqchim(ig,l,iqmax) - dqchim(ig,l,iq) 
                end if
             end do
+
          end do ! of do l = 1,nlayer
 
@@ -508,5 +329,5 @@
 !=======================================================================
 
-      end do ! of do ig=1,ngrid
+      end do ! of do ig=1,ngridbidon(ig,:) = 1
 
 !=======================================================================
@@ -516,18 +337,167 @@
 ! value of parameter 'output' to trigger writting of outputs
 ! is set above at the declaration of the variable.
-
       if (photochem .and. output) then
-            call writediagfi(ngrid,'jo3','j o3->o1d',    &
-                             's-1',3,jo3_3d(1,1))
-            call writediagfi(ngrid,'iter','iterations',  &
+
+         if (callstats) then
+            ! photoloysis
+            do i=1,nb_phot_hv_max
+               call wstats(ngrid,trim(jlabel(i,1)),jlabel(i,1),    &
+                                's-1',3,v_phot_3d(1,1,i))
+            end do
+            ! iter
+            call wstats(ngrid,'iter','iterations',  &
                              ' ',3,iter_3d(1,1))
-            if (callstats) then
-               call wstats(ngrid,'jo3','j o3->o1d',       &
-                           's-1',3,jo3_3d(1,1))
-               call wstats(ngrid,'mmean','mean molecular mass',       &
+            ! phothcemical heating
+            call wstats(ngrid,'zdtchim','dT chim',    &
+                             'K.s-1',3,zdtchim)
+            call wstats(ngrid,'dEzchim','dE chim',    &
+                             'W m-2',3,dEzchim)
+            call wstats(ngrid,"Ezchim","integrated dT chim","W m-2",2,zdtchim_output)
+            ! Mean molecular mass
+            call wstats(ngrid,'mmean','mean molecular mass',       &
                            'g.mole-1',3,mmean(1,1))
+            ! Chemical tendencies
+            do iesp=1,nesp
+               call wstats(ngrid,trim(chemnoms(iesp))//'_dq',trim(chemnoms(iesp))//'_dq',    & 
+                               'kg/kg s^-1',3,dqchim(1,1,iesp) )
+            end do
+            if (depos) then
+               ! Surface fluxes
+               do iesp=1,nesp
+                  call wstats(ngrid,trim(chemnoms(iesp))//'_flux_mean',trim(chemnoms(iesp))//' mean flux',    & 
+                               'molecule.m-2.s-1',2,surface_flux2(1,indexchim(trim(chemnoms(iesp)))))
+                  call wstats(ngrid,trim(chemnoms(iesp))//'_flux',trim(chemnoms(iesp))//' flux',    & 
+                               'molecule.m-2.s-1',2,surface_flux(1,indexchim(trim(chemnoms(iesp)))))
+               end do
+            endif ! end depos
+         endif ! end callstats
+
+         ! photoloysis
+         do i=1,nb_phot_hv_max
+            call writediagfi(ngrid,trim(jlabel(i,1)),jlabel(i,1),    &
+                             's-1',3,v_phot_3d(1,1,i))
+         end do
+         ! iter
+         call writediagfi(ngrid,'iter','iterations',  &
+                          ' ',3,iter_3d(1,1))
+         ! phothcemical heating
+         call writediagfi(ngrid,'zdtchim','dT chim',    &
+                          'K.s-1',3,zdtchim)
+         call writediagfi(ngrid,'dEzchim','dE chim',    &
+                          'W m-2',3,dEzchim)
+         call writediagfi(ngrid,"Ezchim","integrated dT chim","W m-2",2,zdtchim_output)
+         ! Mean molecular mass
+         call writediagfi(ngrid,'mmean','mean molecular mass',       &
+                        'g.mole-1',3,mmean(1,1))
+         ! Chemical tendencies
+         do iesp=1,nesp
+            call writediagfi(ngrid,trim(chemnoms(iesp))//'_dq',trim(chemnoms(iesp))//'_dq',    & 
+                            'kg/kg s^-1',3,dqchim(1,1,iesp) )
+         end do
+         if (depos) then
+            ! Surface fluxes
+            do iesp=1,nesp
+               call writediagfi(ngrid,trim(chemnoms(iesp))//'_flux_mean',trim(chemnoms(iesp))//' mean flux',    & 
+                            'molecule.m-2.s-1',2,surface_flux2(1,indexchim(trim(chemnoms(iesp)))))
+               call writediagfi(ngrid,trim(chemnoms(iesp))//'_flux',trim(chemnoms(iesp))//' flux',    & 
+                            'molecule.m-2.s-1',2,surface_flux(1,indexchim(trim(chemnoms(iesp)))))
+            end do
+            ! Restart flux average
+            if (ngrid == 1) then
+               if(mod(icount,ecritphy).eq.0) then
+                  surface_flux2(:,:) = 0.0
+               endif
+            else
+               if(mod(icount*iphysiq,ecritphy).eq.0) then
+                  surface_flux2(:,:) = 0.0
+               endif
             endif
+         endif ! end depos
+
       end if ! of if (output)
 
       return
-      end
+
+
+      contains
+
+
+!======================================================================
+
+      subroutine ini_tracchim
+
+!======================================================================
+! YJ Modern tracer.def
+! Get in tracer.def chemical parameters
+!======================================================================
+
+         use chimiedata_h
+         use tracer_h, only:   is_chim
+         implicit none
+
+         ! local
+         character(len=500) :: tracline ! to store a line of text
+         integer            :: nq       ! number of tracers
+         integer            :: iesp, iq
+
+         ! Get nq
+         open(90,file='traceur.def',status='old',form='formatted',iostat=ierr)
+         if (ierr.eq.0) then
+           READ(90,'(A)') tracline
+           IF (trim(tracline).ne.'#ModernTrac-v1') THEN ! Test modern traceur.def
+            READ(tracline,*,iostat=ierr) nq ! Try standard traceur.def
+           ELSE
+              DO
+                READ(90,'(A)',iostat=ierr) tracline
+                IF (ierr.eq.0) THEN
+                  IF (index(tracline,'#').ne.1) THEN ! Allows arbitary number of comments lines in the header
+                    READ(tracline,*,iostat=ierr) nq
+                    EXIT
+                  ENDIF
+                ELSE ! If pb, or if reached EOF without having found number of tracer
+                   write(*,*) "calchim: error reading line of tracers"
+                   write(*,*) "   (first lines of traceur.def) "
+                   stop
+                ENDIF
+              ENDDO
+           ENDIF ! if modern or standard traceur.def
+         else
+            write(*,*) "calchim: error opening traceur.def"
+            stop
+         endif
+
+         ! Get data of tracers
+         iesp = 0
+         do iq=1,nq
+            read(90,'(A)') tracline
+            if (is_chim(iq).eq.1) then
+               iesp = iesp + 1
+               read(tracline,*) chemnoms(iesp)
+               write(*,*)"ini_tracchim: iq=",iq,"noms(iq)=",trim(chemnoms(iesp))
+               if (index(tracline,'SF_mode='    ) /= 0) then
+                  read(tracline(index(tracline,'SF_mode=')+len('SF_mode='):),*) SF_mode(iesp)
+                  write(*,*) ' Parameter value (traceur.def) : SF_mode=', SF_mode(iesp)
+               else
+                  write(*,*) ' Parameter value (default)     : SF_mode=', SF_mode(iesp)
+               end if
+               if (index(tracline,'SF_value='    ) /= 0) then
+                  read(tracline(index(tracline,'SF_value=')+len('SF_value='):),*) SF_value(iesp)
+                  write(*,*) ' Parameter value (traceur.def) : SF_value=', SF_value(iesp)
+               else
+                  write(*,*) ' Parameter value (default)     : SF_value=', SF_value(iesp)
+               end if
+               if (index(tracline,'prod_rate='    ) /= 0) then
+                  read(tracline(index(tracline,'prod_rate=')+len('prod_rate='):),*) prod_rate(iesp)
+                  write(*,*) ' Parameter value (traceur.def) : prod_rate=', prod_rate(iesp)
+               else
+                  write(*,*) ' Parameter value (default)     : prod_rate=', prod_rate(iesp)
+               end if
+            end if
+         end do
+
+         close(90)
+
+      end subroutine ini_tracchim
+
+      end subroutine calchim_asis
+
Index: trunk/LMDZ.GENERIC/libf/aeronostd/chimiedata.h
===================================================================
--- trunk/LMDZ.GENERIC/libf/aeronostd/chimiedata.h	(revision 2541)
+++ 	(revision )
@@ -1,42 +1,0 @@
-!--------------------------------------------
-!     data for photochemistry
-!--------------------------------------------
-
-!--------------------------------------------
-!     dimensions of photolysis lookup table
-!--------------------------------------------
-
-      integer, parameter :: nd    = 13  ! species
-      integer, parameter :: nz    = 143 ! altitude
-      integer, parameter :: nozo  = 7   ! ozone
-      integer, parameter :: nsza  = 27  ! solar zenith angle
-      integer, parameter :: ntemp = 4   ! temperature
-      integer, parameter :: ntau  = 8   ! dust
-
-!--------------------------------------------
-
-      real, parameter :: kb = 1.3806e-23
-
-      common/chimiedata/jphot,colairtab,table_ozo
-
-      real jphot(ntemp,nsza,nz,nozo,ntau,nd)
-      real colairtab(nz)
-      real szatab(nsza)
-      real table_ozo(nozo)
-      real tautab(ntau)
-
-      data szatab/0.,  5., 10., 15., 20., 25.,                          &
-     &            30., 35., 40., 45., 50., 55.,                         &
-     &            60., 65., 70., 75., 80., 82.,                         &
-     &            84., 86., 88., 90., 91., 92.,                         &
-     &            93., 94., 95./
-
-      data tautab/0., 0.2, 0.4, 0.6, 0.8, 1., 2., 4./
-
-!--------------------------------------------
-!     number of reactions in ASIS solver
-!--------------------------------------------
-
-      integer, parameter :: nb_phot_max       = 18
-      integer, parameter :: nb_reaction_3_max = 6
-      integer, parameter :: nb_reaction_4_max = 30
Index: trunk/LMDZ.GENERIC/libf/aeronostd/chimiedata_h.F90
===================================================================
--- trunk/LMDZ.GENERIC/libf/aeronostd/chimiedata_h.F90	(revision 2542)
+++ trunk/LMDZ.GENERIC/libf/aeronostd/chimiedata_h.F90	(revision 2542)
@@ -0,0 +1,549 @@
+!***********************************************************************
+
+      module chimiedata_h
+
+!***********************************************************************
+!
+!   subject:
+!   --------
+!
+!   data for photochemistry
+!
+!   update 06/03/2021 set to module - add global variable (Yassin Jaziri)
+!
+!
+!***********************************************************************
+
+      implicit none
+
+      character*30, save, allocatable :: chemnoms(:)   ! name of chemical tracers
+
+!--------------------------------------------
+!     dimensions of photolysis lookup table
+!--------------------------------------------
+
+      integer, save :: nd     ! species
+      integer, save :: nz     ! altitude
+      integer, save :: nozo   ! ozone
+      integer, save :: nsza   ! solar zenith angle
+      integer, save :: ntemp  ! temperature
+      integer, save :: ntau   ! dust
+      integer, save :: nch4   ! ch4
+
+!--------------------------------------------
+
+      real, parameter :: kb = 1.3806e-23
+
+      ! photolysis
+      real, save, allocatable :: jphot(:,:,:,:,:,:,:)
+      real, save, allocatable :: ephot(:,:,:,:,:,:,:)
+      real, save, allocatable :: colairtab(:)
+      real, save, allocatable :: szatab(:)
+      real, save, allocatable :: table_ozo(:)
+      real, save, allocatable :: tautab(:)
+      real, save, allocatable :: table_ch4(:)
+
+      ! deposition
+      real, save, allocatable ::  SF_value(:)        ! SF_mode=1 (vmr) SF_mode=2 (cm.s-1)
+      real, save, allocatable ::  prod_rate(:)       ! production flux in molecules/m2/s
+      real, save, allocatable ::  surface_flux(:,:)  ! Surface flux from deposition molecules/m2/s
+      real, save, allocatable ::  surface_flux2(:,:) ! Surface flux mean molecules/m2/s
+      real, save, allocatable ::  escape(:,:)        ! escape rate in molecules/m2/s
+      integer, save, allocatable ::  SF_mode(:)      ! SF_mode=1 (fixed mixing ratio) / 2 (fixed sedimentation velocity in cm/s and/or flux in molecules/m^3)
+
+!--------------------------------------------
+
+      real, save, allocatable :: albedo_snow_chim(:)    ! albedo snow on chemistry wavelenght grid
+      real, save, allocatable :: albedo_co2_ice_chim(:) ! albedo co2 ice on chemistry wavelenght grid
+
+!--------------------------------------------
+!      For hard coding reactions
+!--------------------------------------------
+
+      integer, parameter :: nphot_hard_coding = 0
+      integer, parameter :: n4_hard_coding    = 0
+      integer, parameter :: n3_hard_coding    = 0
+
+      contains
+
+      subroutine indice_HC(nb_phot,nb_reaction_4,nb_reaction_3)
+
+      use types_asis
+
+      implicit none
+
+      integer, intent(inout) :: nb_phot
+      integer, intent(inout) :: nb_reaction_4
+      integer, intent(inout) :: nb_reaction_3
+
+      !!!!!!!!!!! Hard coding reaction !!!!!!!!!!!!!!!!!!!!!!!!!!!
+      !===========================================================
+      !      d022 : HO2 + NO + M -> HNO3 + M
+      !===========================================================
+      !nb_reaction_4 = nb_reaction_4 + 1
+      !indice_4(nb_reaction_4) = z4spec(1.0, indexchim('ho2'), 1.0, indexchim('no'), 1.0, indexchim('hno3'), 0.0, 1)
+      
+      !===========================================================
+      !      e001 : CO + OH -> CO2 + H 
+      !===========================================================
+      !nb_reaction_4 = nb_reaction_4 + 1
+      !indice_4(nb_reaction_4) = z4spec(1.0, indexchim('co'), 1.0, indexchim('oh'), 1.0, indexchim('co2'), 1.0, indexchim('h'))
+      
+      !===========================================================
+      !      f028 : CH + CH4 -> C2H4 + H
+      !===========================================================
+      !nb_reaction_4 = nb_reaction_4 + 1
+      !indice_4(nb_reaction_4) = z4spec(1.0, indexchim('ch'), 1.0, indexchim('ch4'), 1.0, indexchim('c2h4'), 1.0, indexchim('h'))
+
+      !===========================================================
+      !      r001 : HNO3 + rain -> H2O
+      !===========================================================
+      !nb_phot = nb_phot + 1
+      !indice_phot(nb_phot) = z3spec(1.0, indexchim('hno3'), 1.0, indexchim('h2o_vap'), 0.0, 1)
+
+      !===========================================================
+      !      e001 : CO + OH -> CO2 + H 
+      !===========================================================
+      !nb_reaction_4 = nb_reaction_4 + 1
+      !indice_4(nb_reaction_4) = z4spec(1.0, indexchim('co'), 1.0, indexchim('oh'), 1.0, indexchim('co2'), 1.0, indexchim('h'))
+
+      !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+      !     photodissociation of NO : NO + hv -> N + O
+      !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+      !nb_phot = nb_phot + 1
+      !indice_phot(nb_phot) = z3spec(1.0, indexchim('no'), 1.0, indexchim('n'), 1.0, indexchim('o'))
+
+      !!!!!!!!!!! END Hard coding reaction !!!!!!!!!!!!!!!!!!!!!!!
+      end subroutine indice_HC
+
+      subroutine reactionrates_HC(nlayer,nesp,dens,t,press,zmmean,sza,c,v_phot,v_4,v_3,nb_phot,nb_reaction_4,nb_reaction_3)
+
+      use comcstfi_mod, only:  g, avocado
+      use types_asis
+
+      implicit none
+
+      integer, intent(in)     :: nlayer            ! number of atmospheric layers
+      integer, intent(in)     :: nesp              ! number of chemical species
+      integer, intent(inout)  :: nb_phot
+      integer, intent(inout)  :: nb_reaction_4
+      integer, intent(inout)  :: nb_reaction_3
+      real, intent(in), dimension(nlayer) :: dens              ! total number density (molecule.cm-3)
+      real, intent(in), dimension(nlayer) :: press             ! pressure (hPa)
+      real, intent(in), dimension(nlayer) :: t                 ! temperature (K)
+      real, intent(in), dimension(nlayer) :: zmmean            ! mean molar mass (g/mole)
+      real, intent(in)                    :: sza               ! solar zenith angle (deg)
+      real (kind = 8), intent(in), dimension(nlayer,nesp) :: c ! species number density (molecule.cm-3)
+      real (kind = 8), intent(inout), dimension(nlayer,      nb_phot_max) :: v_phot
+      real (kind = 8), intent(inout), dimension(nlayer,nb_reaction_4_max) :: v_4
+      real (kind = 8), intent(inout), dimension(nlayer,nb_reaction_3_max) :: v_3
+
+      ! local
+
+      real, dimension(nlayer) :: colo3 ! ozone columns (molecule.cm-2)
+      integer :: ilev
+      real :: k1a0, k1b0, k1ainf, k1a, k1b, fc, fx, x, y
+      real :: ak0, ak1, rate, xpo, deq, rate1, rate2, xpo1, xpo2
+      real :: rain_h2o, rain_rate
+
+      !!!!!!!!!!! Hard coding reaction !!!!!!!!!!!!!!!!!!!!!!!!!!!
+      !----------------------------------------------------------------------
+      !     nitrogen reactions
+      !----------------------------------------------------------------------
+
+      !---  d022: ho2 + no + m -> hno3 + m
+      !     Butkovskaya et al. 2007
+
+            !d022(:) = 6.4e-14*exp(1644/T(:))
+            !nb_reaction_4 = nb_reaction_4 + 1
+            !v_4(:,nb_reaction_4) = 3.3e-12*exp(270./t(:))*((530/T(:)+6.4*1e-4*press(:)/1.33322-1.73))*1e-2
+
+      !----------------------------------------------------------------------
+      !     carbon reactions
+      !----------------------------------------------------------------------
+     
+      !---  e001: oh + co -> co2 + h
+
+            !nb_reaction_4 = nb_reaction_4 + 1
+
+      !     jpl 2003
+     
+            !e001(:) = 1.5e-13*(1 + 0.6*press(:)/1013.)
+     
+      !     mccabe et al., grl, 28, 3135, 2001
+
+            !e001(:) = 1.57e-13 + 3.54e-33*dens(:)
+     
+      !     jpl 2006
+     
+            !ak0 = 1.5e-13*(t(:)/300.)**(0.6)
+            !ak1 = 2.1e-9*(t(:)/300.)**(6.1)
+            !rate1 = ak0/(1. + ak0/(ak1/dens(:)))
+            !xpo1 = 1./(1. + alog10(ak0/(ak1/dens(:)))**2)
+     
+            !ak0 = 5.9e-33*(t(:)/300.)**(-1.4)
+            !ak1 = 1.1e-12*(t(:)/300.)**(1.3)
+            !rate2 = (ak0*dens(:))/(1. + ak0*dens(:)/ak1)
+            !xpo2 = 1./(1. + alog10((ak0*dens(:))/ak1)**2)
+     
+            !e001(:) = rate1*0.6**xpo1 + rate2*0.6**xpo2
+     
+      !     jpl 2015
+      
+            !do ilev = 1,nlayer
+            !!oh + co -> h + co2
+            !   rate1 = 1.5e-13*(t(ilev)/300.)**(0.0)
+            !!oh + co + m -> hoco
+            !   ak0 = 5.9e-33*(t(ilev)/300.)**(-1.0)
+            !   ak1 = 1.1e-12*(t(ilev)/300.)**(1.3)
+            !   rate2 = (ak0*dens(ilev))/(1. + ak0*dens(ilev)/ak1)
+            !   xpo2 = 1./(1. + alog10((ak0*dens(ilev))/ak1)**2)
+            !      
+            !   v_4(ilev,nb_reaction_4) = rate1 + rate2*0.6**xpo2
+            !end do
+
+      !     joshi et al., 2006
+
+            !do ilev = 1,nlayer
+            !   k1a0 = 1.34*2.5*dens(ilev)                                  &
+            !         *1/(1/(3.62e-26*t(ilev)**(-2.739)*exp(-20./t(ilev)))  &
+            !         + 1/(6.48e-33*t(ilev)**(0.14)*exp(-57./t(ilev))))     ! typo in paper corrected
+            !   k1b0 = 1.17e-19*t(ilev)**(2.053)*exp(139./t(ilev))          &
+            !        + 9.56e-12*t(ilev)**(-0.664)*exp(-167./t(ilev))
+            !   k1ainf = 1.52e-17*t(ilev)**(1.858)*exp(28.8/t(ilev))        &
+            !          + 4.78e-8*t(ilev)**(-1.851)*exp(-318./t(ilev))
+            !   x = k1a0/(k1ainf - k1b0)
+            !   y = k1b0/(k1ainf - k1b0)
+            !   fc = 0.628*exp(-1223./t(ilev)) + (1. - 0.628)*exp(-39./t(ilev))  &
+            !      + exp(-t(ilev)/255.)
+            !   fx = fc**(1./(1. + (alog(x))**2))                           ! typo in paper corrected
+            !   k1a = k1a0*((1. + y)/(1. + x))*fx
+            !   k1b = k1b0*(1./(1.+x))*fx
+            !      
+            !   v_4(ilev,nb_reaction_4) = k1a + k1b
+            !end do
+     
+      !---  f028: ch + ch4 + m -> c2h4 + h + m
+      !     Romani 1993
+     
+            !nb_reaction_4 = nb_reaction_4 + 1
+            !v_4(:,nb_reaction_4) = min(2.5e-11*exp(200./t(:)),1.7e-10)
+
+      !----------------------------------------------------------------------
+      !     washout r001 : HNO3 + rain -> H2O
+      !----------------------------------------------------------------------
+
+      !nb_phot = nb_phot + 1
+      !      
+      !rain_h2o  = 100.e-6
+      !!rain_rate = 1.e-6  ! 10 days
+      !rain_rate = 1.e-8
+      !
+      !do ilev = 1,nlayer
+      !   if (c(ilev,indexchim('h2o_vap'))/dens(ilev) >= rain_h2o) then
+      !      v_phot(ilev,nb_phot) = rain_rate
+      !   else
+      !      v_phot(ilev,nb_phot) = 0.
+      !   end if
+      !end do
+
+      !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+      !     photodissociation of NO
+      !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+      
+      !nb_phot = nb_phot + 1
+      !
+      !colo3(nlayer) = 0.
+      !!     ozone columns for other levels (molecule.cm-2)
+      !do ilev = nlayer-1,1,-1
+      !   colo3(ilev) = colo3(ilev+1) + (c(ilev+1,indexchim('o3')) + c(ilev,indexchim('o3')))*0.5*avocado*1e-4*((press(ilev) - press(ilev+1))*100.)/(1.e-3*zmmean(ilev)*g*dens(ilev))
+      !end do
+      !call jno(nlayer, c(nlayer:1:-1,indexchim('no')), c(nlayer:1:-1,indexchim('o2')), colo3(nlayer:1:-1), dens(nlayer:1:-1), press(nlayer:1:-1), sza, v_phot(nlayer:1:-1,nb_phot))
+
+      !!!!!!!!!!! END Hard coding reaction !!!!!!!!!!!!!!!!!!!!!!!
+      end subroutine reactionrates_HC
+
+      subroutine jno(nivbas, c_no, c_o2, o3t, hnm, pm, sza, tjno)
+  
+        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+        !                                                       !
+        ! parametrisation de la photodissociation de no         !
+        ! d'apres minschwaner and siskind, a new calculation    !
+        ! of nitric oxide photolysis in the stratosphere,       !
+        ! mesosphere, and lower thermosphere, j. geophys. res., !
+        ! 98, 20401-20412, 1993                                 !
+        !                                                       !
+        !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+        
+        implicit none
+        
+        ! input 
+        
+        integer, intent(in)                  :: nivbas
+        real (kind = 8), dimension(nivbas), intent(in)  :: c_no, c_o2
+        real, dimension(nivbas), intent(in)  :: hnm, o3t, pm
+        real, intent(in)  :: sza
+        
+        ! output
+        
+        real, dimension(nivbas), intent(out) :: tjno
+        
+        ! local
+        
+        real, parameter                      :: factor = 3.141592/180.
+        real, dimension(nivbas)              :: colo2, colno, colo3
+        real, dimension(nivbas)              :: r_o2, r_no
+        real, dimension(nivbas)              :: p, t_o3_1, t_o3_2, t_o3_3
+        real, dimension(nivbas)              :: bd1, bd2, bd3
+        real, dimension(6,3)                 :: sigma_o2, sigma_no_1, sigma_no_2
+        real, dimension(6,3)                 :: w_no_1, w_no_2
+        real, dimension(3)                   :: delta_lambda, i0, sigma_o3
+        real                                 :: a, d, kq, n2
+        real                                 :: sec, zcmt, dp
+        integer                              :: iniv
+        
+        ! sections efficaces
+        
+        sigma_o2(:,1) = (/1.12e-23, 2.45e-23, 7.19e-23, &
+                          3.04e-22, 1.75e-21, 1.11e-20/)
+        sigma_o2(:,2) = (/1.35e-22, 2.99e-22, 7.33e-22, &
+                          3.07e-21, 1.69e-20, 1.66e-19/)
+        sigma_o2(:,3) = (/2.97e-22, 5.83e-22, 2.05e-21, &
+                          8.19e-21, 4.80e-20, 2.66e-19/)
+        
+        sigma_no_1(:,1) = (/0.00e+00, 1.32e-18, 6.35e-19, &
+                            7.09e-19, 2.18e-19, 4.67e-19/)
+        sigma_no_1(:,2) = (/0.00e+00, 0.00e+00, 3.05e-21, &
+                            5.76e-19, 2.29e-18, 2.21e-18/)
+        sigma_no_1(:,3) = (/1.80e-18, 1.50e-18, 5.01e-19, &
+                            7.20e-20, 6.72e-20, 1.49e-21/)
+        
+        sigma_no_2(:,1) = (/0.00e+00, 4.41e-17, 4.45e-17, &
+                            4.50e-17, 2.94e-17, 4.35e-17/)
+        sigma_no_2(:,2) = (/0.00e+00, 0.00e+00, 3.20e-21, &
+                            5.71e-17, 9.09e-17, 6.00e-17/)
+        sigma_no_2(:,3) = (/1.40e-16, 1.52e-16, 7.00e-17, &
+                            2.83e-17, 2.73e-17, 6.57e-18/)
+        
+        ! facteurs de ponderation
+        
+        w_no_1(:,1) = (/0.00e+00, 5.12e-02, 1.36e-01, &
+                        1.65e-01, 1.41e-01, 4.50e-02/)
+        w_no_1(:,2) = (/0.00e+00, 0.00e+00, 1.93e-03, &
+                        9.73e-02, 9.75e-02, 3.48e-02/)
+        w_no_1(:,3) = (/4.50e-02, 1.80e-01, 2.25e-01, &
+                        2.25e-01, 1.80e-01, 4.50e-02/)
+        
+        w_no_2(:,1) = (/0.00e+00, 5.68e-03, 1.52e-02, &
+                        1.83e-02, 1.57e-02, 5.00e-03/)
+        w_no_2(:,2) = (/0.00e+00, 0.00e+00, 2.14e-04, &
+                        1.08e-02, 1.08e-02, 3.86e-03/)
+        w_no_2(:,3) = (/5.00e-03, 2.00e-02, 2.50e-02, &
+                        2.50e-02, 2.00e-02, 5.00e-03/)
+        
+        ! largeurs spectrales pour les trois bandes considerees (nm)
+        
+        delta_lambda = (/2.3, 1.5, 1.5/)
+        
+        ! flux pour les trois bandes considerees (s-1 cm-2 nm-1)
+        
+        i0 = (/3.98e+11, 2.21e+11, 2.30e+11/)
+        
+        ! sections efficaces de l'ozone pour les trois bandes
+        ! considerees (cm2) d'apres wmo 1985
+        
+        sigma_o3 = (/4.6e-19, 6.7e-19, 7.1e-19/)
+         
+        ! zcmt: gas constant/boltzmann constant*g
+        
+        zcmt = 287.0/(1.38e-23*9.81)
+        
+        ! d: taux de predissociation spontanee (s-1)
+        
+        d = 1.65e+09
+        
+        ! a: taux d'emission spontanee (s-1)
+        
+        a = 5.1e+07
+        
+        ! kq: quenching rate constant (cm3 s-1)
+        
+        kq = 1.5e-09
+        
+        ! rapports de melange
+        
+        r_no(:) = c_no(:)/hnm(:)
+        r_o2(:) = c_o2(:)/hnm(:)
+        
+        !=============================================================
+        !  calcul des colonnes de o2 et no
+        !=============================================================
+        
+        !  premier niveau du modele (mol/cm2)
+        
+        colo2(1) = 6.8e+05*c_o2(1)
+        colno(1) = 6.8e+05*c_no(1)
+        colo3(1) = o3t(1)
+        
+        !  cas general
+        
+        do iniv = 2,nivbas
+           dp = (pm(iniv) - pm(iniv - 1))*100.
+           dp = max(dp, 0.)
+           colo2(iniv) = colo2(iniv - 1)                 &
+                       + zcmt*(r_o2(iniv-1) + r_o2(iniv))*0.5*dp*1.e-4
+           colno(iniv) = colno(iniv - 1)                 &
+                       + zcmt*(r_no(iniv-1) + r_no(iniv))*0.5*dp*1.e-4
+           colo3(iniv) = o3t(iniv)
+        end do 
+        
+        !=============================================================
+        !  boucle sur les niveaux
+        !=============================================================
+        
+        do iniv = 1,nivbas
+           if (sza <= 89.0) then
+        
+              sec = 1./cos(sza*factor)
+        
+              colo2(iniv) = colo2(iniv)*sec
+              colno(iniv) = colno(iniv)*sec
+              colo3(iniv) = colo3(iniv)*sec
+        
+        !     facteurs de transmission de l'ozone
+        
+              t_o3_1(iniv) = exp(-sigma_o3(1)*colo3(iniv))
+              t_o3_2(iniv) = exp(-sigma_o3(2)*colo3(iniv))
+              t_o3_3(iniv) = exp(-sigma_o3(3)*colo3(iniv))
+        
+        !     calcul de la probabilite de predissociation
+        
+              n2 = hnm(iniv)*0.78
+              p(iniv) = d/(a + d + kq*n2)
+        
+           end if
+        end do
+        
+        !  calcul proprement dit, pour les 3 bandes
+        
+        do iniv = 1,nivbas
+           if (sza <= 89.0) then
+        
+              bd1(iniv) = delta_lambda(1)*i0(1)*t_o3_1(iniv)*p(iniv)*(  &
+                     exp(-sigma_o2(1,1)*colo2(iniv))   &
+                   *(w_no_1(1,1)*sigma_no_1(1,1)*exp(-sigma_no_1(1,1)*colno(iniv))  &
+                   + w_no_2(1,1)*sigma_no_2(1,1)*exp(-sigma_no_2(1,1)*colno(iniv))) &
+                   + exp(-sigma_o2(2,1)*colo2(iniv))   &
+                   *(w_no_1(2,1)*sigma_no_1(2,1)*exp(-sigma_no_1(2,1)*colno(iniv))  &
+                   + w_no_2(2,1)*sigma_no_2(2,1)*exp(-sigma_no_2(2,1)*colno(iniv))) &
+                   + exp(-sigma_o2(3,1)*colo2(iniv))   &
+                   *(w_no_1(3,1)*sigma_no_1(3,1)*exp(-sigma_no_1(3,1)*colno(iniv))  &
+                   + w_no_2(3,1)*sigma_no_2(3,1)*exp(-sigma_no_2(3,1)*colno(iniv))) &
+                   + exp(-sigma_o2(4,1)*colo2(iniv))   &
+                   *(w_no_1(4,1)*sigma_no_1(4,1)*exp(-sigma_no_1(4,1)*colno(iniv))  &
+                   + w_no_2(4,1)*sigma_no_2(4,1)*exp(-sigma_no_2(4,1)*colno(iniv))) &
+                   + exp(-sigma_o2(5,1)*colo2(iniv))   &
+                   *(w_no_1(5,1)*sigma_no_1(5,1)*exp(-sigma_no_1(5,1)*colno(iniv))  &
+                   + w_no_2(5,1)*sigma_no_2(5,1)*exp(-sigma_no_2(5,1)*colno(iniv))) &
+                   + exp(-sigma_o2(6,1)*colo2(iniv))  &
+                   *(w_no_1(6,1)*sigma_no_1(6,1)*exp(-sigma_no_1(6,1)*colno(iniv))  &
+                   + w_no_2(6,1)*sigma_no_2(6,1)*exp(-sigma_no_2(6,1)*colno(iniv))) &
+                   )
+        
+              bd2(iniv) = delta_lambda(2)*i0(2)*t_o3_2(iniv)*p(iniv)*(  &
+                     exp(-sigma_o2(1,2)*colo2(iniv))   &
+                   *(w_no_1(1,2)*sigma_no_1(1,2)*exp(-sigma_no_1(1,2)*colno(iniv))  &
+                   + w_no_2(1,2)*sigma_no_2(1,2)*exp(-sigma_no_2(1,2)*colno(iniv))) &
+                   + exp(-sigma_o2(2,2)*colo2(iniv))   &
+                   *(w_no_1(2,2)*sigma_no_1(2,2)*exp(-sigma_no_1(2,2)*colno(iniv))  &
+                   + w_no_2(2,2)*sigma_no_2(2,2)*exp(-sigma_no_2(2,2)*colno(iniv))) &
+                   + exp(-sigma_o2(3,2)*colo2(iniv))   &
+                   *(w_no_1(3,2)*sigma_no_1(3,2)*exp(-sigma_no_1(3,2)*colno(iniv))  &
+                   + w_no_2(3,2)*sigma_no_2(3,2)*exp(-sigma_no_2(3,2)*colno(iniv))) &
+                   + exp(-sigma_o2(4,2)*colo2(iniv))   &
+                   *(w_no_1(4,2)*sigma_no_1(4,2)*exp(-sigma_no_1(4,2)*colno(iniv))  &
+                   + w_no_2(4,2)*sigma_no_2(4,2)*exp(-sigma_no_2(4,2)*colno(iniv))) &
+                   + exp(-sigma_o2(5,2)*colo2(iniv))   &
+                   *(w_no_1(5,2)*sigma_no_1(5,2)*exp(-sigma_no_1(5,2)*colno(iniv))  &
+                   + w_no_2(5,2)*sigma_no_2(5,2)*exp(-sigma_no_2(5,2)*colno(iniv))) &
+                   + exp(-sigma_o2(6,2)*colo2(iniv))  &
+                   *(w_no_1(6,2)*sigma_no_1(6,2)*exp(-sigma_no_1(6,2)*colno(iniv))  &
+                   + w_no_2(6,2)*sigma_no_2(6,2)*exp(-sigma_no_2(6,2)*colno(iniv))) &
+                   )
+        
+              bd3(iniv) = delta_lambda(3)*i0(3)*t_o3_3(iniv)*p(iniv)*(  &
+                     exp(-sigma_o2(1,3)*colo2(iniv))   &
+                   *(w_no_1(1,3)*sigma_no_1(1,3)*exp(-sigma_no_1(1,3)*colno(iniv))  &
+                   + w_no_2(1,3)*sigma_no_2(1,3)*exp(-sigma_no_2(1,3)*colno(iniv))) &
+                   + exp(-sigma_o2(2,3)*colo2(iniv))   &
+                   *(w_no_1(2,3)*sigma_no_1(2,3)*exp(-sigma_no_1(2,3)*colno(iniv))  &
+                   + w_no_2(2,3)*sigma_no_2(2,3)*exp(-sigma_no_2(2,3)*colno(iniv))) &
+                   + exp(-sigma_o2(3,3)*colo2(iniv))   &
+                   *(w_no_1(3,3)*sigma_no_1(3,3)*exp(-sigma_no_1(3,3)*colno(iniv))  &
+                   + w_no_2(3,3)*sigma_no_2(3,3)*exp(-sigma_no_2(3,3)*colno(iniv))) &
+                   + exp(-sigma_o2(4,3)*colo2(iniv))   &
+                   *(w_no_1(4,3)*sigma_no_1(4,3)*exp(-sigma_no_1(4,3)*colno(iniv))  &
+                   + w_no_2(4,3)*sigma_no_2(4,3)*exp(-sigma_no_2(4,3)*colno(iniv))) &
+                   + exp(-sigma_o2(5,3)*colo2(iniv))   &
+                   *(w_no_1(5,3)*sigma_no_1(5,3)*exp(-sigma_no_1(5,3)*colno(iniv))  &
+                   + w_no_2(5,3)*sigma_no_2(5,3)*exp(-sigma_no_2(5,3)*colno(iniv))) &
+                   + exp(-sigma_o2(6,3)*colo2(iniv))  &
+                   *(w_no_1(6,3)*sigma_no_1(6,3)*exp(-sigma_no_1(6,3)*colno(iniv))  &
+                   + w_no_2(6,3)*sigma_no_2(6,3)*exp(-sigma_no_2(6,3)*colno(iniv))) &
+                   )
+        
+              tjno(iniv) = bd1(iniv) + bd2(iniv) + bd3(iniv)
+  
+           else  ! night
+              tjno(iniv) = 0.
+           end if
+        end do
+        
+      end subroutine jno
+
+      function indexchim(traceurname)
+
+      use tracer_h, only: noms, nqtot, is_chim
+
+      implicit none
+
+      !=======================================================================
+      ! Get index of tracer in chemistry with its name using traceur tab
+      !
+      ! version: April 2019 - Yassin Jaziri (update September 2020)
+      !=======================================================================
+
+!     input/output
+
+      integer             :: indexchim   ! index of tracer in chemistry
+      character(len=*)    :: traceurname ! name of traceur to find
+
+!     local variables
+
+      integer :: iq, iesp
+
+
+      iesp = 0
+      indexchim = 0
+      do iq = 1,nqtot
+        if (is_chim(iq)==1) then
+          iesp = iesp + 1
+          if (trim(traceurname)==trim(noms(iq))) then
+              indexchim = iesp
+            exit
+          end if
+        end if
+      end do
+
+      if (indexchim==0) then
+        print*, 'Error indexchim: wrong traceur name ', trim(traceurname)
+        print*, 'Check if the specie ', trim(traceurname),' is in traceur.def'
+        print*, 'Check if the specie ', trim(traceurname),' is a chemical species'
+        print*, '(option is_chim = 1)'
+        call abort
+      end if
+
+      return
+      end function indexchim
+
+      end module chimiedata_h
Index: trunk/LMDZ.GENERIC/libf/aeronostd/concentrations.F
===================================================================
--- trunk/LMDZ.GENERIC/libf/aeronostd/concentrations.F	(revision 2541)
+++ trunk/LMDZ.GENERIC/libf/aeronostd/concentrations.F	(revision 2542)
@@ -2,19 +2,10 @@
      &                          pplay,pt,pdt,pq,pdq,ptimestep)
                                              
-      use tracer_h, only: igcm_co2, igcm_co, igcm_o, igcm_o1d,
-     &                      igcm_o2, igcm_o3, igcm_h, igcm_h2,
-     &                      igcm_oh, igcm_ho2, igcm_n2, igcm_ar,
-     &                      igcm_h2o_vap, igcm_n, igcm_no, igcm_no2,
-     &                      igcm_n2d, igcm_ch4, 
-     &                      igcm_ch3, igcm_ch, igcm_3ch2, igcm_1ch2,      
-     &                      igcm_cho, igcm_ch2o, igcm_ch3o,               
-     &                      igcm_c, igcm_c2, igcm_c2h, igcm_c2h2,         
-     &                      igcm_c2h3, igcm_c2h4, igcm_c2h6, igcm_ch2co,  
-     &                      igcm_ch3co, igcm_hcaer,
-     &                      igcm_h2o2, mmol
+      use tracer_h, only: mmol, noms, aki, cpi, nesp
 
-      use conc_mod, only: mmean, Akknew, rnew, cpnew
+      use conc_mod, only: mmean, akknew, rnew, cpnew
       USE comcstfi_mod                   
       use callkeys_mod
+      use chimiedata_h
       implicit none
 
@@ -28,274 +19,25 @@
 !
 ! version: April 2012 - Franck Lefevre
+! update 06/03/2021 cpi/aki input (Yassin Jaziri)
 !=======================================================================
 
-!     declarations
- 
-#include "chimiedata.h"
 !     input/output
 
-      integer,intent(in) :: ngrid ! number of atmospheric columns
+      integer,intent(in) :: ngrid  ! number of atmospheric columns
       integer,intent(in) :: nlayer ! number of atmospheric layers
-      integer,intent(in) :: nq ! number of tracers
-      real,intent(in) :: pplay(ngrid,nlayer)
-      real,intent(in) :: pt(ngrid,nlayer)
-      real,intent(in) :: pdt(ngrid,nlayer)
-      real,intent(in) :: pq(ngrid,nlayer,nq)
-      real,intent(in) :: pdq(ngrid,nlayer,nq)
-      real,intent(in) :: ptimestep
+      integer,intent(in) :: nq     ! number of tracers
+      real,   intent(in) :: pplay(ngrid,nlayer)
+      real,   intent(in) :: pt(ngrid,nlayer)
+      real,   intent(in) :: pdt(ngrid,nlayer)
+      real,   intent(in) :: pq(ngrid,nlayer,nq)
+      real,   intent(in) :: pdq(ngrid,nlayer,nq)
+      real,   intent(in) :: ptimestep
 
 !     local variables
 
-      integer       :: i, l, ig, iq
-      integer, save :: nbq
-      integer,allocatable,save :: niq(:)
+      integer       :: l, ig, iq
       real          :: ni(nq), ntot
       real          :: zq(ngrid, nlayer, nq)
       real          :: zt(ngrid, nlayer)
-      real,allocatable,save    :: aki(:)
-      real,allocatable,save    :: cpi(:)
-
-      logical, save :: firstcall = .true.
-
-
-      if (firstcall) then
-
-         ! allocate local saved arrays:
-         allocate(aki(nq))
-         allocate(cpi(nq))
-         allocate(niq(nq))
-!        find index of chemical tracers to use
-!        initialize thermal conductivity and specific heat coefficients
-!        !? values are estimated
-
-         nbq = 0 ! to count number of tracers used in this subroutine
-
-         if (igcm_co2 /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_co2
-            aki(nbq) = 3.072e-4
-            cpi(nbq) = 0.834e3
-         end if
-         if (igcm_co /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_co
-            aki(nbq) = 4.87e-4
-            cpi(nbq) = 1.034e3
-         end if
-         if (igcm_o /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_o
-            aki(nbq) = 7.59e-4
-            cpi(nbq) = 1.3e3
-         end if
-         if (igcm_o1d /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_o1d
-            aki(nbq) = 7.59e-4  !?
-            cpi(nbq) = 1.3e3    !?
-         end if
-         if (igcm_o2 /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_o2
-            aki(nbq) = 5.68e-4
-            cpi(nbq) = 0.9194e3
-         end if
-         if (igcm_o3 /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_o3
-            aki(nbq) = 3.00e-4  !?
-            cpi(nbq) = 0.800e3  !?
-         end if
-         if (igcm_h /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_h
-            aki(nbq) = 0.0
-            cpi(nbq) = 20.780e3
-         end if
-         if (igcm_h2 /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_h2
-            aki(nbq) = 36.314e-4
-            cpi(nbq) = 14.266e3
-         end if
-         if (igcm_oh /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_oh
-            aki(nbq)  = 7.00e-4 !?
-            cpi(nbq)  = 1.045e3
-         end if
-         if (igcm_ho2 /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_ho2
-            aki(nbq) = 0.0
-            cpi(nbq) = 1.065e3  !?
-         end if
-         if (igcm_h2o2 /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_h2o2
-            aki(nbq) = 0.0
-            cpi(nbq) = 1.065e3  !?
-         end if
-         if (igcm_h2o_vap /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_h2o_vap
-            aki(nbq) = 0.0
-            cpi(nbq) = 1.870e3
-         end if
-         if (igcm_n /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_n
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_n2d /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_n2d
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_no /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_no
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_no2 /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_no2
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if (igcm_n2 /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_n2
-            aki(nbq) = 5.6e-4
-            cpi(nbq) = 1.034e3
-         end if
-         if(igcm_ch4 /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_ch4
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_ch3 /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_ch3
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_ch /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_ch
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_1ch2 /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_1ch2
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_3ch2 /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_3ch2
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_cho /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_cho
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_ch2o /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_ch2o
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_ch3o /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_ch3o
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_c /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_c
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_c2 /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_c2
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_c2h /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_c2h
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_c2h2 /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_c2h2
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_c2h3 /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_c2h3
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_c2h4 /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_c2h4
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_c2h6 /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_c2h6
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_ch2co /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_ch2co
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_ch3co /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_ch3co
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if(igcm_hcaer /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_hcaer
-            aki(nbq) = 0.0
-            cpi(nbq) = 0.0
-         endif
-         if (igcm_ar /= 0) then
-            nbq = nbq + 1
-            niq(nbq) = igcm_ar
-            aki(nbq) = 0.0      !?
-            cpi(nbq) = 1.000e3  !?
-         end if
-
-
-         ! tell the world about it:
-         write(*,*) "concentrations: firstcall, nbq=",nbq
-         write(*,*) "  niq(1:nbq)=",niq(1:nbq)
-         write(*,*) "  aki(1:nbq)=",aki(1:nbq)
-         write(*,*) "  cpi(1:nbq)=",cpi(1:nbq)
-
-         firstcall = .false.
-
-      end if ! if (firstcall)
 
 !     update temperature
@@ -311,6 +53,5 @@
       do l = 1,nlayer
          do ig = 1,ngrid
-            do i = 1,nbq
-               iq = niq(i) 
+            do iq = 1,nq
                zq(ig,l,iq) = max(1.e-30, pq(ig,l,iq)
      $                                 + pdq(ig,l,iq)*ptimestep)
@@ -325,7 +66,8 @@
       do l = 1,nlayer
          do ig = 1,ngrid
-            do i = 1,nbq
-               iq = niq(i)
-               mmean(ig,l) = mmean(ig,l) + zq(ig,l,iq)/mmol(iq)
+            do iq = 1,nq
+               if (mmol(iq).ne.0.) then
+                  mmean(ig,l) = mmean(ig,l) + zq(ig,l,iq)/mmol(iq)
+               end if
             end do
             mmean(ig,l) = 1./mmean(ig,l)
@@ -343,11 +85,10 @@
          do ig = 1,ngrid
             ntot = pplay(ig,l)/(1.381e-23*zt(ig,l))*1.e-6  ! in #/cm3
-            do i = 1,nbq
-               iq = niq(i) 
+            do iq = 1,nq
                ni(iq) = ntot*zq(ig,l,iq)*mmean(ig,l)/mmol(iq)
-               cpnew(ig,l) = cpnew(ig,l) + ni(iq)*cpi(i)
-               akknew(ig,l) = akknew(ig,l) + ni(iq)*aki(i)
+               cpnew(ig,l)  = cpnew(ig,l) + ni(iq)*cpi(iq)
+               akknew(ig,l) = akknew(ig,l) + ni(iq)*aki(iq)
             end do 
-            cpnew(ig,l) = cpnew(ig,l)/ntot
+            cpnew(ig,l)  = cpnew(ig,l)/ntot
             akknew(ig,l) = akknew(ig,l)/ntot
          end do
Index: trunk/LMDZ.GENERIC/libf/aeronostd/deposition_source.F90
===================================================================
--- trunk/LMDZ.GENERIC/libf/aeronostd/deposition_source.F90	(revision 2542)
+++ trunk/LMDZ.GENERIC/libf/aeronostd/deposition_source.F90	(revision 2542)
@@ -0,0 +1,79 @@
+      subroutine deposition_source(ngrid, nlayer, nq,   &
+                           ig, zzlay, zzlev,zdens,      &
+                           zycol, ptimestep)
+!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+!
+!     dry deposition of chemical species
+!
+!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+!
+      use chimiedata_h
+      use gases_h
+      use tracer_h, only: noms, nesp, mmol
+      use conc_mod, only: mmean ! mean molecular mass of the atmosphere
+
+      implicit none
+!
+!
+!     input
+! 
+      integer,intent(in) :: ngrid    ! number of atmospheric columns
+      integer,intent(in) :: nlayer   ! number of atmospheric layers
+      integer,intent(in) :: nq       ! number of tracers
+      integer ig                     ! grid point index
+      real    zzlay(ngrid,nlayer)    ! altitude at the middle of the layers (m)
+      real    zzlev(ngrid,nlayer+1)  ! altitude at layer boundaries (m)
+      real    zdens(nlayer)          ! density (cm^-3)
+      real    zycol(nlayer,nesp)     ! composition (volume mixing ratio)
+      real    ptimestep              ! physical timestep (s)
+!
+!     local
+!
+      real    vd                         ! dry deposition velocity (cm.s-1)
+      real    deltaz                     ! thickness of first layer (m)
+      real    deltaznlay                 ! thickness of last layer (m)
+      real    loss                       ! loss rate (s-1)
+      real    prod                       ! production rate (s-1) 
+      integer iq
+      logical, save :: firstcall = .true.
+
+
+      if (firstcall) then
+         print*,'photochemistry: initialize deposition/source'
+
+         ! You can set SF_mode/SF_value/prod_rate in traceur.def with #Moderntrac-v1
+         !! Cases SF_mode=1 (fixed mixing ratio)
+         !SF_mode(igcm_co2)=1
+         !SF_value(igcm_co2)=gfrac(igas_CO2)
+
+         !! Cases SF_mode=2 (production flux in molecules/m2/s)
+         !prod_rate(indexchim('co'))=3.0e13
+
+         firstcall=.false.
+      endif !firstcall
+
+      ! thickness of first layer (m)
+      deltaz = zzlev(ig,2) - zzlev(ig,1)
+      deltaznlay = zzlev(ig,nlayer) - zzlev(ig,nlayer-1)
+
+      ! hydrogen escape
+      !escape(ig,indexchim('h2'))=2.5e17*(zycol(nlayer,indexchim('h2'))+2*zycol(nlayer,indexchim('ch4'))+zycol(nlayer,indexchim('h2o_vap')))
+
+      do iq=1,nesp
+        if(SF_mode(iq).eq.1) then
+          surface_flux(ig,iq)=(SF_value(iq)-zycol(1,iq))/ptimestep*(zdens(1)*1e6*deltaz)
+          zycol(1,iq) = SF_value(iq)
+          !! Set mmr instead of vmr
+          !surface_flux(ig,iq)=(SF_value(iq)*mmean(ig,1)/mmol(iq+1)-zycol(1,iq))/ptimestep*(zdens(1)*1e6*deltaz)
+          !zycol(1,iq) = SF_value(iq)*mmean(ig,1)/mmol(iq+1)
+          zycol(nlayer,iq) = zycol(nlayer,iq)-ptimestep*escape(ig,iq)/(zdens(nlayer)*1e6*deltaznlay)
+        elseif(SF_mode(iq).eq.2) then ! loss/prod rate (s-1)
+          loss = 0.01*SF_value(iq)/deltaz
+          zycol(1,iq) = zycol(1,iq)*exp(-loss*ptimestep)+(prod_rate(iq)/(zdens(1)*1e6*deltaz))*ptimestep
+          zycol(nlayer,iq) = zycol(nlayer,iq)-ptimestep*escape(ig,iq)/(zdens(nlayer)*1e6*deltaznlay)
+          surface_flux(ig,iq)=-0.01*SF_value(iq)*zycol(1,iq)*(zdens(1)*1e6)+prod_rate(iq)
+        endif
+      enddo ! end nesp
+
+      return
+      end
Index: trunk/LMDZ.GENERIC/libf/aeronostd/pfunc.F90
===================================================================
--- trunk/LMDZ.GENERIC/libf/aeronostd/pfunc.F90	(revision 2542)
+++ trunk/LMDZ.GENERIC/libf/aeronostd/pfunc.F90	(revision 2542)
@@ -0,0 +1,95 @@
+module pfunc
+implicit none
+
+contains
+
+!=======================================================================
+! Reaction rate function
+!
+! version: April 2019 - Yassin Jaziri
+!=======================================================================
+
+
+function pfunc1(nlayer,t,dens,param)
+
+use types_asis
+
+implicit none
+
+! input/output
+
+integer                 :: nlayer       ! number of atmospheric layers
+real, dimension(nlayer) :: pfunc1       ! output values
+type(rtype1)            :: param        ! parameters
+real, dimension(nlayer) :: t            ! temperature (K)
+real, dimension(nlayer) :: dens         ! total number density (molecule.cm-3)
+
+
+pfunc1(:) = param%a*exp(-param%b/t(:))*((t(:)/param%t0)**param%c)*(dens(:)**param%d)
+
+return
+end function pfunc1
+
+
+function pfunc2(nlayer,t,dens,param)
+
+use types_asis
+
+implicit none
+
+! input/output
+
+integer                 :: nlayer       ! number of atmospheric layers
+real, dimension(nlayer) :: pfunc2       ! output values
+type(rtype2)            :: param        ! parameters
+real, dimension(nlayer) :: t            ! temperature (K)
+real, dimension(nlayer) :: dens         ! total number density (molecule.cm-3)
+
+! local
+
+real, dimension(nlayer) :: ak0, ak1, ak2, rate, xpo
+
+ak0(:)  = param%k0*exp(-param%a/t(:))*((t(:)/param%t0)**param%n)
+ak1(:)  = param%kinf*exp(-param%b/t(:))*((t(:)/param%t0)**param%m)
+ak2(:)  = param%g*exp(-param%h/t(:))
+rate(:) = (ak0(:)*dens(:)**param%dup)/(1. + ak0(:)*(dens(:)**param%ddown)/ak1(:))
+xpo(:)  = 1./(1. + alog10((ak0(:)*dens(:))/ak1(:))**2)
+
+pfunc2(:) = ak2(:) + rate(:)*(param%fc**xpo(:))
+
+return
+end function pfunc2
+
+function pfunc3(nlayer,t,dens,param)
+
+use types_asis
+
+implicit none
+
+! input/output
+
+integer                 :: nlayer       ! number of atmospheric layers
+real, dimension(nlayer) :: pfunc3       ! output values
+type(rtype3)            :: param        ! parameters
+real, dimension(nlayer) :: t            ! temperature (K)
+real, dimension(nlayer) :: dens         ! total number density (molecule.cm-3)
+
+! local
+
+real, dimension(nlayer) :: ak0, ak1, rate, fc, c, N, d, xpo
+
+ak0(:)  = param%k0*exp(-param%a/t(:))*((t(:)/param%t0)**param%n)
+ak1(:)  = param%kinf*exp(-param%b/t(:))*((t(:)/param%t0)**param%m)
+rate(:) = (ak0(:)*dens(:)**param%dup)/(1. + ak0(:)*(dens(:)**param%ddown)/ak1(:))
+fc(:)   = (1-param%atroe)*exp(-t(:)/param%btroe) + param%atroe*exp(-t(:)/param%ctroe) + exp(-param%dtroe/t(:))
+c(:)    = -0.4-0.67*alog10(fc(:))
+N(:)    = 0.75-1.27*alog10(fc(:))
+d(:)    = 0.14
+xpo(:)  = 1./(1. + ( (alog10((ak0(:)*dens(:))/ak1(:))+c(:))/(N(:)-d(:)*(alog10((ak0(:)*dens(:))/ak1(:))+c(:))) )**2)
+
+pfunc3(:) = rate(:)*(fc(:)**xpo(:))
+
+return
+end function pfunc3
+
+end module pfunc
Index: trunk/LMDZ.GENERIC/libf/aeronostd/photochemistry_asis.F90
===================================================================
--- trunk/LMDZ.GENERIC/libf/aeronostd/photochemistry_asis.F90	(revision 2541)
+++ trunk/LMDZ.GENERIC/libf/aeronostd/photochemistry_asis.F90	(revision 2542)
@@ -4,20 +4,27 @@
 !
 !     Author: Franck Lefevre
+!             Benjamin Charnay
+!             Yassin Jaziri
 !     ------
 !
-!     Version: 10/11/2015
+!     Version: 27/05/2016
+!     update 06/03/2021 generic tracer/network + photolysis online (Yassin Jaziri)
 !
 !*****************************************************************
 
-subroutine photochemistry_asis(nlayer, nq, ngrid,                               &
+subroutine photochemistry_asis(nlayer, ngrid,                                   &
                           ig, lswitch, zycol, sza, fractcol, ptimestep, press,  &
-                          temp, dens, zmmean, dist_sol, surfdust1d,             &
-                          surfice1d, jo3, tau, iter)
+                          alt, temp, dens, zmmean, dist_sol, surfdust1d,        &
+                          surfice1d, tau, iter,zdtchim)
 
       use callkeys_mod
+      use comcstfi_mod, only:  r,cpp,avocado,pi
+      use tracer_h
+      use types_asis
+      use chimiedata_h
+      use photolysis_mod
+
 implicit none
 
-#include "chimiedata.h" 
-
 !===================================================================
 !     inputs:
@@ -25,6 +32,6 @@
 
 integer, intent(in) :: nlayer ! number of atmospheric layers
-integer, intent(in) :: nq     ! number of tracers
-integer,intent(in) :: ngrid   ! number of atmospheric columns
+integer, intent(in) :: ngrid  ! number of atmospheric columns
+
 integer :: ig                 ! grid point index
       
@@ -33,4 +40,5 @@
 real :: ptimestep             ! physics timestep (s)
 real :: press(nlayer)         ! pressure (hpa)
+real :: alt(nlayer)           ! altitude (km)
 real :: temp(nlayer)          ! temperature (k)
 real :: dens(nlayer)          ! density (cm-3)
@@ -45,5 +53,5 @@
 !===================================================================
       
-real :: zycol(nlayer,nq)       ! chemical species volume mixing ratio
+real :: zycol(nlayer,nesp)    ! chemical species volume mixing ratio
 
 !===================================================================
@@ -51,6 +59,6 @@
 !===================================================================
       
-integer :: iter(nlayer)        ! iteration counter
-real    :: jo3(nlayer)         ! photodissociation rate o3 -> o1d
+integer :: iter(nlayer)       ! iteration counter
+real    :: zdtchim(nlayer)    ! temperature modification by ozone
 
 !===================================================================
@@ -59,31 +67,8 @@
 
 integer :: phychemrat         ! (physical timestep)/(nominal chemical timestep)
-integer :: j_o3_o1d, ilev
-integer :: iesp, nesp
+integer :: ilev, iesp, iphot, iw
 integer :: lswitch
 
 logical, save :: firstcall = .true.
-
-parameter (nesp = 17)         ! number of species in the chemistry
-
-! tracer indexes in the chemistry:
-
-integer,parameter :: i_co2  =  1
-integer,parameter :: i_co   =  2
-integer,parameter :: i_o    =  3
-integer,parameter :: i_o1d  =  4
-integer,parameter :: i_o2   =  5
-integer,parameter :: i_o3   =  6
-integer,parameter :: i_h    =  7
-integer,parameter :: i_h2   =  8
-integer,parameter :: i_oh   =  9
-integer,parameter :: i_ho2  = 10
-integer,parameter :: i_h2o2 = 11
-integer,parameter :: i_h2o  = 12
-integer,parameter :: i_n    = 13
-integer,parameter :: i_n2d  = 14
-integer,parameter :: i_no   = 15
-integer,parameter :: i_no2  = 16
-integer,parameter :: i_n2   = 17
 
 real :: stimestep           ! standard timestep for the chemistry (s) 
@@ -95,4 +80,5 @@
 real :: j(nlayer,nd)        ! interpolated photolysis rates (s-1)
 real :: time                ! internal time (between 0 and ptimestep, in s)
+real :: rho(nlayer)         ! mass density (kg/m-3)
 
 real, dimension(nlayer,nesp)            :: rm   ! mixing ratios 
@@ -103,22 +89,23 @@
 ! reaction rates
  
-real (kind = 8), dimension(nlayer,      nb_phot_max) :: v_phot
-real (kind = 8), dimension(nlayer,nb_reaction_3_max) :: v_3
-real (kind = 8), dimension(nlayer,nb_reaction_4_max) :: v_4
-logical :: hetero_dust, hetero_ice
+real (kind = 8), allocatable, save     :: v_phot(:,:)
+real (kind = 8), allocatable, save     :: v_3(:,:)
+real (kind = 8), allocatable, save     :: v_4(:,:)
+real (kind = 8), allocatable, save     :: e_phot(:,:)    ! photolysis rates by energie (J.mol-1.s-1)
+
+integer, save                          :: nreact         ! number of reactions in reactions files
+integer, allocatable, save             :: rtype(:)       ! reaction rate type
+integer, allocatable, save             :: third_body(:)  ! if the reaction have a third body: index of the third body, else zero
+logical, allocatable, save             :: three_prod(:)  ! if the reaction have a three defferent proucts egal .true.
 
 ! matrix
 
-real (kind = 8), dimension(nesp,nesp) :: mat, mat1
-integer, dimension(nesp)              :: indx
-integer                               :: code
+real (kind = 8), dimension(nesp,nesp)  :: mat, mat1
+integer, dimension(nesp)               :: indx
+integer                                :: code
 
 ! production and loss terms (for first-guess solution only)
 
-real (kind = 8), dimension(nesp) :: prod, loss
-
-! curvatures
-
-real :: ratio, curv, e, e1, e2, e3
+real (kind = 8), dimension(nesp)       :: prod, loss
 
 !===================================================================
@@ -128,7 +115,42 @@
 if (firstcall) then
    print*,'photochemistry: initialize indexes'
-   call indice(i_co2, i_co, i_o, i_o1d, i_o2, i_o3, i_h,       &
-               i_h2, i_oh, i_ho2, i_h2o2, i_h2o,               &
-               i_n, i_n2d, i_no, i_no2, i_n2)
+   call indice(nreact,rtype,third_body,three_prod)
+   allocate(v_phot(nlayer,nb_phot_max))
+   allocate(v_3(nlayer,nb_reaction_3_max))
+   allocate(v_4(nlayer,nb_reaction_4_max))
+   allocate(v_phot_3d(ngrid,nlayer,nb_phot_hv_max))
+   allocate(e_phot(nlayer,nb_phot_max))
+   v_phot(:,:)      = 0.
+   v_3(:,:)         = 0.
+   v_4(:,:)         = 0.
+   v_phot_3d(:,:,:) = 0.
+   e_phot(:,:)      = 0.
+
+   ! Need to be done after subroutine indice
+   if (jonline) then
+     print*,'calchim: Read UV absorption cross-sections'
+     ! Jonline cannot run without photolysis
+     if (nb_phot_hv_max == 0) then
+       print*,'Jonline cannot run without photolysis'
+       print*,'set jonline=.false. in callphys.def'
+       print*,'or set photolysis reactions in monoreact file'
+       stop
+     end if
+     call init_photolysis(nlayer,nreact,three_prod)     ! on-line photolysis
+     allocate(albedo_snow_chim(nw))
+     allocate(albedo_co2_ice_chim(nw))
+    ! Step 1 : Initialisation of the Spectral Albedos.
+     DO iw=1,nw
+      albedo_snow_chim(iw)=albedosnow
+      albedo_co2_ice_chim(iw)=albedoco2ice
+
+      ! Spectral Snow Albedo Calculation.
+      call albedo_snow_calc(wc(iw)*1.0e-3,        &
+                     albedo_snow_chim(iw),  & 
+                     albedosnow)
+      
+     ENDDO
+   end if
+
    firstcall = .false.
 end if
@@ -138,8 +160,5 @@
 !===================================================================
 
-call gcmtochim(nlayer, nq, zycol, lswitch, nesp,               &
-               i_co2, i_co, i_o, i_o1d, i_o2, i_o3, i_h,       &
-               i_h2, i_oh, i_ho2, i_h2o2, i_h2o,               &
-               i_n, i_n2d, i_no, i_no2, i_n2, dens, rm, c) 
+call gcmtochim(nlayer, zycol, lswitch, nesp, dens, rm, c) 
 
 !===================================================================
@@ -147,26 +166,71 @@
 !===================================================================
 
-call photolysis_asis(nlayer, ngrid, lswitch, press, temp, sza, fractcol, tau, zmmean, dist_sol, & 
-                     rm(:,i_co2), rm(:,i_o3), v_phot)
-
-! save o3 photolysis for output
-
-j_o3_o1d = 5
-jo3(:) = v_phot(:,j_o3_o1d)
+if (jonline) then
+   if (sza <= 95.) then
+      call photolysis_online(nlayer, alt, press, temp, zmmean, rm,   &
+                             tau, sza, dist_sol, v_phot, e_phot, ig, ngrid, nreact, three_prod)
+      if (ngrid.eq.1) then
+        do iphot = 1,nb_phot_hv_max
+          v_phot(:,iphot) = v_phot(:,iphot)* 0.25 / cos(sza*pi/180.) ! globally averaged = divide by 4
+          e_phot(:,iphot) = e_phot(:,iphot)* 0.25 / cos(sza*pi/180.) ! globally averaged = divide by 4
+        end do
+      elseif(diurnal .eqv. .false.) then
+        do iphot = 1,nb_phot_hv_max
+          v_phot(:,iphot) = v_phot(:,iphot) * fractcol
+          e_phot(:,iphot) = e_phot(:,iphot) * fractcol
+        end do
+      endif
+   else ! night
+      v_phot(:,:) = 0.
+      e_phot(:,:) = 0.
+   end if
+   ! save photolysis for output
+   v_phot_3d(ig,:,:) = v_phot(:,1:nb_phot_hv_max)
+else if (nb_phot_hv_max /= 0) then
+   call photolysis_asis(nlayer, ngrid, lswitch, press, temp, sza, fractcol,tau, zmmean, dist_sol, & 
+                     rm(:,indexchim('co2')), rm(:,indexchim('o3')), rm(:,indexchim('ch4')), v_phot)
+   ! save photolysis for output
+   v_phot_3d(ig,:,:) = v_phot(:,1:nb_phot_hv_max)
+end if
 
 !===================================================================
 !     reaction rates                                     
 !===================================================================
-!     switches for heterogeneous chemistry
-!     hetero_ice  : reactions on ice clouds
-!     hetero_dust : reactions on dust    
-!===================================================================
-
-hetero_dust = .false.
-hetero_ice  = .false.
-
-call reactionrates(nlayer, lswitch, dens, c(:,i_co2), c(:,i_o2), &
-                   press, temp, hetero_dust, hetero_ice,         &
-                   surfdust1d, surfice1d, v_phot, v_3, v_4)
+
+call reactionrates(nlayer, nreact, rtype, third_body, three_prod, c, lswitch, dens, &
+                   press, temp, zmmean, sza, surfdust1d, surfice1d, v_phot, v_3, v_4)
+
+zdtchim(:) = 0.
+rho(:)     = (press(:)*1e2)/(r*temp(:))
+
+!===================================================================
+!     temperature modification by photolysis reaction                                    
+!===================================================================
+
+if (photoheat .and. jonline) then ! for now just with jonline
+
+  do iphot = 1,nb_phot_hv_max
+    zdtchim(:nlayer-1) = zdtchim(:nlayer-1) + e_phot(:nlayer-1,iphot)*c(:nlayer-1,indexchim(trim(jlabel(iphot,2))))/(cpp*(rho(:nlayer-1)*1e-6)*avocado)
+  end do
+
+else
+
+!! o + o2 -> o3
+!!dE = 24 ! kcal.mol-1
+!!zdtchim(:) = zdtchim(:) + 4.184*24e3*v_4(:,1)*c(:,indexchim('o'))*c(:,indexchim('o2'))*1e6/(cpp*rho*avocado)
+!
+!! o3 -> o2 + o1d
+!! E(250nm) = 480 kJ.mol-1
+!j_o3_o1d   = 3
+!zdtchim(:) = zdtchim(:) + 480e3*v_phot(:,j_o3_o1d)*c(:,indexchim('o3'))/(cpp*(rho*1e-6)*avocado)
+!
+!! o3 -> o2 + o
+!! E(350nm) = 343 kJ.mol-1
+!j_o3_o     = 4
+!zdtchim(:) = zdtchim(:) + 343e3*v_phot(:,j_o3_o)*c(:,indexchim('o3'))/(cpp*(rho*1e-6)*avocado)
+
+zdtchim(:) = 0.
+
+end if
 
 !===================================================================
@@ -182,10 +246,4 @@
 
 ctimestep = ptimestep/real(phychemrat)
-
-!print*, "stimestep  = ", stimestep
-!print*, "ptimestep  = ", ptimestep
-!print*, "phychemrat = ", phychemrat
-!print*, "ctimestep  = ", ctimestep
-!stop
 
 !===================================================================
@@ -207,5 +265,5 @@
 
    iter(ilev) = iter(ilev) + 1    ! iteration counter
-
+  
 !  first-guess: fill matrix
 
@@ -268,8 +326,5 @@
 !===================================================================
 
-call chimtogcm(nlayer, nq, zycol, lswitch, nesp,              &
-               i_co2, i_co, i_o, i_o1d, i_o2, i_o3, i_h,      &
-               i_h2, i_oh, i_ho2, i_h2o2, i_h2o,              &
-               i_n, i_n2d, i_no, i_no2, i_n2, dens, c) 
+call chimtogcm(nlayer, zycol, lswitch, nesp, dens, c) 
 
 contains
@@ -318,5 +373,5 @@
 real (kind = 8), parameter :: dtmin   = 10.      ! minimum time step (s)
 real (kind = 8), parameter :: vmrtol  = 1.e-11   ! absolute tolerance on vmr
-real (kind = 8), parameter :: rtol    = 1./0.05   ! 1/rtol recommended value : 0.1-0.02
+real (kind = 8), parameter :: rtol    = 1./0.05  ! 1/rtol recommended value : 0.1-0.02
 integer,         parameter :: niter   = 3        ! number of iterations
 real (kind = 8), parameter :: coefmax = 2.
@@ -382,5 +437,9 @@
 ! timestep correction
 
-coef = max(coefmin, min(coefmax,0.8/sqrt(e)))
+if (e <= 0.) then
+  coef = coefmax
+else
+  coef = max(coefmin, min(coefmax,0.8/sqrt(e)))
+end if
 
 dttest = max(dtmin,dttest*coef)
@@ -396,11 +455,8 @@
 
 
-
-
 !======================================================================
 
- subroutine reactionrates(nlayer,                               &
-                          lswitch, dens, co2, o2, press, t,     &
-                          hetero_dust, hetero_ice,              &
+ subroutine reactionrates(nlayer, nreact, rtype, third_body, three_prod, c, &
+                          lswitch, dens, press, t, zmmean, sza, &
                           surfdust1d, surfice1d,                &
                           v_phot, v_3, v_4)
@@ -418,8 +474,10 @@
 
 use comcstfi_mod
+use types_asis
+use pfunc
+use tracer_h
+use chimiedata_h
 
 implicit none
-
-#include "chimiedata.h"
 
 !----------------------------------------------------------------------
@@ -427,15 +485,20 @@
 !----------------------------------------------------------------------
 
-integer, intent(in)     :: nlayer            ! number of atmospheric layers
-integer                 :: lswitch           ! interface level between lower
-                                             ! atmosphere and thermosphere chemistries
-real, dimension(nlayer) :: dens              ! total number density (molecule.cm-3)
-real, dimension(nlayer) :: press             ! pressure (hPa)
-real, dimension(nlayer) :: t                 ! temperature (K)
-real, dimension(nlayer) :: surfdust1d        ! dust surface area (cm2.cm-3)
-real, dimension(nlayer) :: surfice1d         ! ice surface area (cm2.cm-3)
-real (kind = 8), dimension(nlayer) :: co2    ! co2 number density (molecule.cm-3)
-real (kind = 8), dimension(nlayer) :: o2     ! o2 number density (molecule.cm-3)
-logical :: hetero_dust, hetero_ice           ! switches for heterogeneous chemistry
+integer, intent(in)     :: nlayer             ! number of atmospheric layers
+integer, intent(in)     :: nreact             ! number of reactions in reactions files
+integer                 :: lswitch            ! interface level between lower
+                                              ! atmosphere and thermosphere chemistries
+real, dimension(nlayer) :: dens               ! total number density (molecule.cm-3)
+real, dimension(nlayer) :: press              ! pressure (hPa)
+real, dimension(nlayer) :: t                  ! temperature (K)
+real, dimension(nlayer) :: zmmean             ! mean molar mass (g/mole)
+real                    :: sza                ! solar zenith angle (deg)
+real, dimension(nlayer) :: surfdust1d         ! dust surface area (cm2.cm-3)
+real, dimension(nlayer) :: surfice1d          ! ice surface area (cm2.cm-3)
+real (kind = 8), dimension(nlayer,nesp) :: c  ! species number density (molecule.cm-3)
+
+integer, intent(in)     :: rtype(nreact)      ! reaction rate type
+integer, intent(in)     :: third_body(nreact) ! if the reaction have a third body: index of the third body, else zero
+logical, intent(in)     :: three_prod(nreact) ! if the reaction have three different products egal .true.
 
 !----------------------------------------------------------------------
@@ -451,19 +514,9 @@
 !----------------------------------------------------------------------
 
-integer          :: ilev
+logical,save     :: firstcall = .true.
+integer          :: ilev, ireact
 integer          :: nb_phot, nb_reaction_3, nb_reaction_4
-real :: ak0, ak1, xpo, rate
-real :: k1a0, k1b0, k1ainf, k1a, k1b, fc, fx, x, y, gam
-real, dimension(nlayer) :: deq
-real, dimension(nlayer) :: a001, a002, a003,                           &
-                             b001, b002, b003, b004, b005, b006, b007,   &
-                             b008, b009,                                 &
-                             c001, c002, c003, c004, c005, c006, c007,   &
-                             c008, c009, c010, c011, c012, c013, c014,   &
-                             c015, c016, c017, c018,                     &
-                             d001, d002, d003, d004, d005, d006, d007,   &
-                             d008, d009,                                 &
-                             e001, e002,                                 &
-                             h001, h002, h003, h004, h005
+integer          :: nb_hv, nb_pfunc1, nb_pfunc2, nb_pfunc3
+real, dimension(nlayer) :: ratec ! rate coefficient
 
 !----------------------------------------------------------------------
@@ -471,534 +524,203 @@
 !----------------------------------------------------------------------
 
-      nb_phot       = 11       ! jmars.20140930 reduit de 13 a 11
+      nb_phot       = nb_phot_hv_max
       nb_reaction_3 = 0
       nb_reaction_4 = 0
 
+      nb_hv         = 0
+      nb_pfunc1     = 0
+      nb_pfunc2     = 0
+      nb_pfunc3     = 0
+
 !----------------------------------------------------------------------
-!     oxygen reactions 
+!     reactions 
 !----------------------------------------------------------------------
 
-!---  a001: o + o2 + co2 -> o3 + co2
-
-!     jpl 2003
-!
-!     co2 efficiency as a third body (2.075)
-!     from sehested et al., j. geophys. res., 100, 1995.
-
-      a001(:) = 2.075*6.0e-34*(t(:)/300.)**(-2.4)*dens(:)
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = a001(:)
-
-!---  a002: o + o + co2 -> o2 + co2
-
-!     Tsang and Hampson, J. Chem. Phys. Ref. Data, 15, 1087, 1986
-
-!     a002(:) = 2.5*5.2e-35*exp(900./t(:))*dens(:)
-
-!     Campbell and Gray, Chem. Phys. Lett., 18, 607, 1973
-
-!     a002(:) = 1.2e-32*(300./t(:))**(2.0)*dens(:)  ! yung expression
-      a002(:) = 2.5*9.46e-34*exp(485./t(:))*dens(:) ! nist expression
-
-      nb_reaction_3 = nb_reaction_3 + 1
-      v_3(:,nb_reaction_3) = a002(:)
-
-!---  a003: o + o3 -> o2 + o2
-
-!     jpl 2003
-
-      a003(:) = 8.0e-12*exp(-2060./t(:))
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = a003(:)
-
-!----------------------------------------------------------------------
-!     o(1d) reactions
-!----------------------------------------------------------------------
-
-!---  b001: o(1d) + co2  -> o + co2
-
-!     jpl 2006
-
-      b001(:) = 7.5e-11*exp(115./t(:))
-   
+ireact = 1
+
+! Reaction from monoreact file are implemented first
+do while(nb_phot<nb_phot_max-nphot_hard_coding)
+
+  if (rtype(ireact)/=0) then     ! skip photolysis reactions
+    ! get right coefficient rate function
+    if (rtype(ireact)==1) then
+      nb_pfunc1 = nb_pfunc1 + 1
+      if (third_body(ireact)==0) then            !! third_body check
+        ratec = pfunc1(nlayer,t,dens,pfunc1_param(nb_pfunc1))
+      else
+        ratec = pfunc1(nlayer,t,c(:,third_body(ireact)),pfunc1_param(nb_pfunc1))
+      end if
+    else if (rtype(ireact)==2) then
+      nb_pfunc2 = nb_pfunc2 + 1
+      if (third_body(ireact)==0) then            !! third_body check
+        ratec = pfunc2(nlayer,t,dens,pfunc2_param(nb_pfunc2))
+      else
+        ratec = pfunc2(nlayer,t,c(:,third_body(ireact)),pfunc2_param(nb_pfunc2))
+      end if
+    else if (rtype(ireact)==3) then
+      nb_pfunc3 = nb_pfunc3 + 1
+      if (third_body(ireact)==0) then            !! third_body check
+        ratec = pfunc3(nlayer,t,dens,pfunc3_param(nb_pfunc3))
+      else
+        ratec = pfunc3(nlayer,t,c(:,third_body(ireact)),pfunc3_param(nb_pfunc3))
+      end if
+    else
+      print*, 'Error in reactionrates: wrong index coefficient rate vphot'
+      print*, 'rtype(ireact) = ',rtype(ireact)
+      print*, 'It should be 1 or 2 '
+      print*, 'Please check the reaction ',ireact
+      if (ireact>nreact) print*, 'Please check the reaction count into the code beacause ireact > nreact is not possible'
+      stop
+    end if
+
+    ! fill the right type index
+    nb_phot = nb_phot + 1
+    v_phot(:,nb_phot) = ratec(:)
+    if (three_prod(ireact)) then             ! three_prod check
       nb_phot = nb_phot + 1
-      v_phot(:,nb_phot) = b001(:)*co2(:)
-
-!---  b002: o(1d) + h2o  -> oh + oh
-
-!     jpl 2006
- 
-      b002(:) = 1.63e-10*exp(60./t(:))
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = b002(:)
-
-!---  b003: o(1d) + h2  -> oh + h
-
-!     jpl 2011
-
-      b003(:) = 1.2e-10
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = b003(:)
-
-!---  b004: o(1d) + o2  -> o + o2
-
-!     jpl 2006
-
-      b004(:) = 3.3e-11*exp(55./t(:))
-
-      nb_phot = nb_phot + 1
-      v_phot(:,nb_phot) = b004(:)*o2(:)
-    
-!---  b005: o(1d) + o3  -> o2 + o2
-
-!     jpl 2003
-
-      b005(:) = 1.2e-10
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = b005(:)
-    
-!---  b006: o(1d) + o3  -> o2 + o + o
-
-!     jpl 2003
-
-      b006(:) = 1.2e-10
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = b006(:)
-    
-!---  b007: o(1d) + ch4 -> ch3 + oh
-
-!     jpl 2003
-
-      b007(:) = 1.5e-10*0.75
-
-!---  b008: o(1d) + ch4 -> ch3o + h
-
-!     jpl 2003
-
-      b008(:) = 1.5e-10*0.20
-!
-!---  b009: o(1d) + ch4 -> ch2o + h2
-
-!     jpl 2003
-
-      b009(:) = 1.5e-10*0.05
-
-!----------------------------------------------------------------------
-!     hydrogen reactions
-!----------------------------------------------------------------------
-
-!---  c001: o + ho2 -> oh + o2
-
-!     jpl 2003
-
-      c001(:) = 3.0e-11*exp(200./t(:))
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = c001(:)
-
-!---  c002: o + oh -> o2 + h
-
-!     jpl 2011
-
-      c002(:) = 1.8e-11*exp(180./t(:))
-
-!     robertson and smith, j. chem. phys. a 110, 6673, 2006
-
-!     c002(:) = 11.2e-11*t(:)**(-0.32)*exp(177./t(:))
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = c002(:)
-
-!---  c003: h + o3 -> oh + o2
-
-!     jpl 2003
-
-      c003(:) = 1.4e-10*exp(-470./t(:))
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = c003(:)
-
-!---  c004: h + ho2 -> oh + oh
-
-!     jpl 2006
-
-      c004(:) = 7.2e-11
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = c004(:)
-
-!---  c005: h + ho2 -> h2 + o2
-
-!     jpl 2006
-
-      c005(:) = 6.9e-12
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = c005(:)
-
-!---  c006: h + ho2 -> h2o + o
-
-!     jpl 2006
-
-      c006(:) = 1.6e-12
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = c006(:)
-
-!---  c007: oh + ho2 -> h2o + o2
-
-!     jpl 2003
-
-!     canty et al., grl, 2006 suggest to increase this rate
-!     by 20%. not done here.
-
-      c007(:) = 4.8e-11*exp(250./t(:))
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = c007(:)
-
-!---  c008: ho2 + ho2 -> h2o2 + o2
-
-!     jpl 2006
-
-!     c008(:) = 3.5e-13*exp(430./t(:))
-
-!     christensen et al., grl, 13, 2002
-
-      c008(:) = 1.5e-12*exp(19./t(:))
-
-      nb_reaction_3 = nb_reaction_3 + 1
-      v_3(:,nb_reaction_3) = c008(:)
-
-!---  c009: oh + h2o2 -> h2o + ho2
-
-!     jpl 2006
-
-      c009(:) = 1.8e-12
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = c009(:)
-
-!---  c010: oh + h2 -> h2o + h
-
-!     jpl 2006
-
-      c010(:) = 2.8e-12*exp(-1800./t(:))
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = c010(:)
-
-!---  c011: h + o2 + co2 -> ho2 + co2
-
-!     jpl 2011
-
-      do ilev = 1,lswitch-1
-         ak0 = 2.5*4.4e-32*(t(ilev)/300.)**(-1.3)
-         ak1 = 7.5e-11*(t(ilev)/300.)**(0.2)
-
-         rate = (ak0*dens(ilev))/(1. + ak0*dens(ilev)/ak1)
-         xpo = 1./(1. + alog10((ak0*dens(ilev))/ak1)**2)
-         c011(ilev) = rate*0.6**xpo
-      end do
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = c011(:)
-
-!---  c012: o + h2o2 -> oh + ho2
-
-!     jpl 2003
-
-      c012(:) = 1.4e-12*exp(-2000./t(:))
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = c012(:)
-
-!---  c013: oh + oh -> h2o + o
-
-!     jpl 2006
-
-      c013(:) = 1.8e-12
-
-      nb_reaction_3 = nb_reaction_3 + 1
-      v_3(:,nb_reaction_3) = c013(:)
-
-!---  c014: oh + o3 -> ho2 + o2
-
-!     jpl 2003
-
-      c014(:) = 1.7e-12*exp(-940./t(:))
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = c014(:)
-
-!---  c015: ho2 + o3 -> oh + o2 + o2
-
-!     jpl 2003
-
-      c015(:) = 1.0e-14*exp(-490./t(:))
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = c015(:)
-
-!---  c016: ho2 + ho2 + co2 -> h2o2 + o2 + co2
-
-!     jpl 2011
-
-      c016(:) = 2.5*2.1e-33*exp(920./t(:))*dens(:)
-
-      nb_reaction_3 = nb_reaction_3 + 1
-      v_3(:,nb_reaction_3) = c016(:)
-
-!---  c017: oh + oh + co2 -> h2o2 + co2
-
-!     jpl 2003
-
-      do ilev = 1,lswitch-1
-         ak0 = 2.5*6.9e-31*(t(ilev)/300.)**(-1.0)
-         ak1 = 2.6e-11*(t(ilev)/300.)**(0.0)
-
-         rate = (ak0*dens(ilev))/(1. + ak0*dens(ilev)/ak1)
-         xpo = 1./(1. + alog10((ak0*dens(ilev))/ak1)**2)
-         c017(ilev) = rate*0.6**xpo
-      end do
-
-      nb_reaction_3 = nb_reaction_3 + 1
-      v_3(:,nb_reaction_3) = c017(:)
-
-!---  c018: h + h + co2 -> h2 + co2
-
-!     baulch et al., 2005
-
-      c018(:) = 2.5*1.8e-30*(t(:)**(-1.0))*dens(:)
-
-      nb_reaction_3 = nb_reaction_3 + 1
-      v_3(:,nb_reaction_3) = c018(:)
-
-!----------------------------------------------------------------------
-!     nitrogen reactions
-!----------------------------------------------------------------------
-
-!---  d001: no2 + o -> no + o2
-
-!     jpl 2006
-
-      d001(:) = 5.1e-12*exp(210./t(:))
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = d001(:)
-
-!---  d002: no + o3 -> no2 + o2
-
-!     jpl 2006
-
-      d002(:) = 3.0e-12*exp(-1500./t(:))
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = d002(:)
-
-!---  d003: no + ho2 -> no2 + oh
-
-!     jpl 2011
-
-      d003(:) = 3.3e-12*exp(270./t(:))
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = d003(:)
-
-!---  d004: n + no -> n2 + o
-
-!     jpl 2011
-
-      d004(:) = 2.1e-11*exp(100./t(:))
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = d004(:)
-
-!---  d005: n + o2 -> no + o
-
-!     jpl 2011
-
-      d005(:) = 1.5e-11*exp(-3600./t(:))
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = d005(:)
-
-!---  d006: no2 + h -> no + oh
-
-!     jpl 2011
-
-      d006(:) = 4.0e-10*exp(-340./t(:))
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = d006(:)
-
-!---  d007: n + o -> no
- 
-      d007(:) = 2.8e-17*(300./t(:))**0.5
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = d007(:)
-
-!---  d008: n + ho2 -> no + oh
-
-!     brune et al., j. chem. phys., 87, 1983 
-
-      d008(:) = 2.19e-11
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = d008(:)
-
-!---  d009: n + oh -> no + h
-
-!     atkinson et al., j. phys. chem. ref. data, 18, 881, 1989 
-
-      d009(:) = 3.8e-11*exp(85./t(:))
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = d009(:)
-
-!----------------------------------------------------------------------
-!     carbon reactions
-!----------------------------------------------------------------------
-
-!---  e001: oh + co -> co2 + h
-
-!     jpl 2003
-
-!     e001(:) = 1.5e-13*(1 + 0.6*press(:)/1013.)
-
-!     mccabe et al., grl, 28, 3135, 2001
-
-!     e001(:) = 1.57e-13 + 3.54e-33*dens(:)
-
-!     jpl 2006
-
-!     ak0 = 1.5e-13*(t(:)/300.)**(0.6)
-!     ak1 = 2.1e-9*(t(:)/300.)**(6.1)
-!     rate1 = ak0/(1. + ak0/(ak1/dens(:)))
-!     xpo1 = 1./(1. + alog10(ak0/(ak1/dens(:)))**2)
-
-!     ak0 = 5.9e-33*(t(:)/300.)**(-1.4)
-!     ak1 = 1.1e-12*(t(:)/300.)**(1.3)
-!     rate2 = (ak0*dens(:))/(1. + ak0*dens(:)/ak1)
-!     xpo2 = 1./(1. + alog10((ak0*dens(:))/ak1)**2)
-
-!     e001(:) = rate1*0.6**xpo1 + rate2*0.6**xpo2
-
-!     joshi et al., 2006
-
-      do ilev = 1,lswitch-1
-         k1a0 = 1.34*2.5*dens(ilev)                                  &
-               *1/(1/(3.62e-26*t(ilev)**(-2.739)*exp(-20./t(ilev)))  &
-               + 1/(6.48e-33*t(ilev)**(0.14)*exp(-57./t(ilev))))     ! typo in paper corrected
-         k1b0 = 1.17e-19*t(ilev)**(2.053)*exp(139./t(ilev))          &
-              + 9.56e-12*t(ilev)**(-0.664)*exp(-167./t(ilev))
-         k1ainf = 1.52e-17*t(ilev)**(1.858)*exp(28.8/t(ilev))        &
-                + 4.78e-8*t(ilev)**(-1.851)*exp(-318./t(ilev))
-         x = k1a0/(k1ainf - k1b0)
-         y = k1b0/(k1ainf - k1b0)
-         fc = 0.628*exp(-1223./t(ilev)) + (1. - 0.628)*exp(-39./t(ilev))  &
-            + exp(-t(ilev)/255.)
-         fx = fc**(1./(1. + (alog(x))**2))                           ! typo in paper corrected
-         k1a = k1a0*((1. + y)/(1. + x))*fx
-         k1b = k1b0*(1./(1.+x))*fx
-
-         e001(ilev) = k1a + k1b
-      end do
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = e001(:)
-
-!---  e002: o + co + m -> co2 + m
-
-!     tsang and hampson, 1986.
-
-      e002(:) = 2.5*6.5e-33*exp(-2184./t(:))*dens(:)
-
-      nb_reaction_4 = nb_reaction_4 + 1
-      v_4(:,nb_reaction_4) = e002(:)
-
-!----------------------------------------------------------------------
-!     heterogeneous chemistry 
-!----------------------------------------------------------------------
-
-      if (hetero_ice) then
-
-!        k = (surface*v*gamma)/4 (s-1)
-!        v = 100*sqrt(8rt/(pi*m))  (cm s-1)
- 
-!---     h001: ho2 + ice -> products
- 
-!        cooper and abbatt, 1996: gamma = 0.025
-      
-         gam = 0.025
-         h001(:) = surfice1d(:)       &
-                   *100.*sqrt(8.*8.31*t(:)/(33.e-3*pi))*gam/4.
- 
-!        h002: oh + ice -> products
- 
-!        cooper and abbatt, 1996: gamma = 0.03
- 
-         gam = 0.03
-         h002(:) = surfice1d(:)       &
-                   *100.*sqrt(8.*8.31*t(:)/(17.e-3*pi))*gam/4.
-
-!---     h003: h2o2 + ice -> products
- 
-!        gamma = 0.    test value
- 
-         gam = 0.
-         h003(:) = surfice1d(:)       &
-                   *100.*sqrt(8.*8.31*t(:)/(34.e-3*pi))*gam/4.
-      else
-         h001(:) = 0.
-         h002(:) = 0.
-         h003(:) = 0.
-      end if
-
-      nb_phot = nb_phot + 1
-      v_phot(:,nb_phot) = h001(:)
-
-      nb_phot = nb_phot + 1
-      v_phot(:,nb_phot) = h002(:)
-
-      nb_phot = nb_phot + 1
-      v_phot(:,nb_phot) = h003(:)
-
-      if (hetero_dust) then
- 
-!---     h004: ho2 + dust -> products
- 
-!        jacob, 2000: gamma = 0.2
-!        see dereus et al., atm. chem. phys., 2005
- 
-         gam = 0.2
-         h004(:) = surfdust1d(:)  &
-                   *100.*sqrt(8.*8.31*t(:)/(33.e-3*pi))*gam/4.
- 
-!---     h005: h2o2 + dust -> products
- 
-!        gamma = 5.e-4
-!        see dereus et al., atm. chem. phys., 2005
- 
-         gam = 5.e-4
-         h005(:) = surfdust1d(:)  &
-                   *100.*sqrt(8.*8.31*t(:)/(34.e-3*pi))*gam/4.
-      else
-         h004(:) = 0.
-         h005(:) = 0.
-      end if
- 
-      nb_phot = nb_phot + 1
-      v_phot(:,nb_phot) = h004(:)
-
-      nb_phot = nb_phot + 1
-      v_phot(:,nb_phot) = h005(:)
+      v_phot(:,nb_phot) = ratec(:)
+    end if
+  else
+    nb_hv = nb_hv + 1
+  end if
+
+  ireact = ireact + 1
+
+end do
+
+! Reaction from bimolreact file are implemented secondly
+do while(nb_reaction_4<nb_reaction_4_max-n4_hard_coding)
+
+  ! get right coefficient rate function
+  if (rtype(ireact)==1) then
+    nb_pfunc1 = nb_pfunc1 + 1
+    if (third_body(ireact)==0) then            !! third_body check
+      ratec = pfunc1(nlayer,t,dens,pfunc1_param(nb_pfunc1))
+    else
+      ratec = pfunc1(nlayer,t,c(:,third_body(ireact)),pfunc1_param(nb_pfunc1))
+    end if
+  else if (rtype(ireact)==2) then
+    nb_pfunc2 = nb_pfunc2 + 1
+    if (third_body(ireact)==0) then            !! third_body check
+      ratec = pfunc2(nlayer,t,dens,pfunc2_param(nb_pfunc2))
+    else
+      ratec = pfunc2(nlayer,t,c(:,third_body(ireact)),pfunc2_param(nb_pfunc2))
+    end if
+  else if (rtype(ireact)==3) then
+    nb_pfunc3 = nb_pfunc3 + 1
+    if (third_body(ireact)==0) then            !! third_body check
+      ratec = pfunc3(nlayer,t,dens,pfunc3_param(nb_pfunc3))
+    else
+      ratec = pfunc3(nlayer,t,c(:,third_body(ireact)),pfunc3_param(nb_pfunc3))
+    end if
+  else
+    print*, 'Error in reactionrates: wrong index coefficient rate v4'
+    print*, 'rtype(ireact) = ',rtype(ireact)
+    print*, 'It should be 1 or 2 '
+    print*, 'Please check the reaction ',ireact-nb_phot_max
+    if (ireact>nreact) print*, 'Please check the reaction count into the code beacause ireact > nreact is not possible'
+    stop
+  end if
+
+  ! fill the right type index
+  nb_reaction_4 = nb_reaction_4 + 1
+  v_4(:,nb_reaction_4) = ratec(:)
+  if (three_prod(ireact)) then             ! three_prod check
+    nb_reaction_4 = nb_reaction_4 + 1
+    v_4(:,nb_reaction_4) = ratec(:)
+  end if
+
+  ireact = ireact + 1
+
+end do
+
+! Reaction from quadrareact file are implemented thirdly
+do while(nb_reaction_3<nb_reaction_3_max-n3_hard_coding)
+
+  ! get right coefficient rate function
+  if (rtype(ireact)==1) then
+    nb_pfunc1 = nb_pfunc1 + 1
+    if (third_body(ireact)==0) then            !! third_body check
+      ratec = pfunc1(nlayer,t,dens,pfunc1_param(nb_pfunc1))
+    else
+      ratec = pfunc1(nlayer,t,c(:,third_body(ireact)),pfunc1_param(nb_pfunc1))
+    end if
+  else if (rtype(ireact)==2) then
+    nb_pfunc2 = nb_pfunc2 + 1
+    if (third_body(ireact)==0) then            !! third_body check
+      ratec = pfunc2(nlayer,t,dens,pfunc2_param(nb_pfunc2))
+    else
+      ratec = pfunc2(nlayer,t,c(:,third_body(ireact)),pfunc2_param(nb_pfunc2))
+    end if
+  else if (rtype(ireact)==3) then
+    nb_pfunc3 = nb_pfunc3 + 1
+    if (third_body(ireact)==0) then            !! third_body check
+      ratec = pfunc3(nlayer,t,dens,pfunc3_param(nb_pfunc3))
+    else
+      ratec = pfunc3(nlayer,t,c(:,third_body(ireact)),pfunc3_param(nb_pfunc3))
+    end if
+  else
+    print*, 'Error in reactionrates: wrong index coefficient rate v3'
+    print*, 'rtype(ireact) = ',rtype(ireact)
+    print*, 'It should be 1 or 2 '
+    print*, 'Please check the reaction ',ireact-nb_phot_max-nb_reaction_4_max
+    if (ireact>nreact) print*, 'Please check the reaction count into the code beacause ireact > nreact is not possible'
+    stop
+  end if
+
+  ! fill the right type index
+  nb_reaction_3 = nb_reaction_3 + 1
+  v_3(:,nb_reaction_3) = ratec(:)
+  if (three_prod(ireact)) then             ! three_prod check
+    nb_reaction_3 = nb_reaction_3 + 1
+    v_3(:,nb_reaction_3) = ratec(:)
+  end if
+
+  ireact = ireact + 1
+
+end do
+
+call reactionrates_HC(nlayer,nesp,dens,t,press,zmmean,sza,c,v_phot,v_4,v_3,nb_phot,nb_reaction_4,nb_reaction_3)
+
+!===========================================================
+!  check dimensions 
+!===========================================================
+
+if (firstcall) then
+ ireact = ireact-1
+ if (ireact /= nreact) print*, 'wrong dimensions in reactionrates : number of reaction should be ', nreact,' and not ', ireact
+ if ((nb_phot /= nb_phot_max)             .or.  &
+     (nb_reaction_3 /= nb_reaction_3_max) .or.  &
+     (nb_reaction_4 /= nb_reaction_4_max)) then
+    print*, 'nb_phot       = ', nb_phot
+    print*, 'nb_reaction_4 = ', nb_reaction_4
+    print*, 'nb_reaction_3 = ', nb_reaction_3
+    print*, 'wrong dimensions in reactionrates' 
+    print*, 'nb_phot_max       = ', nb_phot_max
+    print*, 'nb_reaction_4_max = ', nb_reaction_4_max
+    print*, 'nb_reaction_3_max = ', nb_reaction_3_max
+    print*, '------ hard coding reaction ------'
+    print*, 'nphot_hard_coding = ', nphot_hard_coding
+    print*, 'n4_hard_coding    = ', n4_hard_coding
+    print*, 'n3_hard_coding    = ', n3_hard_coding
+    stop
+ end if
+ if ((nb_hv /= nb_hv_max)         .or.  &
+     (nb_pfunc1 /= nb_pfunc1_max) .or.  &
+     (nb_pfunc2 /= nb_pfunc2_max) .or.  &
+     (nb_pfunc3 /= nb_pfunc3_max)) then
+    print*, 'nb_hv         = ', nb_hv
+    print*, 'nb_pfunc1     = ', nb_pfunc1
+    print*, 'nb_pfunc2     = ', nb_pfunc2
+    print*, 'nb_pfunc3     = ', nb_pfunc3
+    print*, 'wrong dimensions in reactionrates'
+    print*, 'nb_hv_max     = ', nb_hv_max
+    print*, 'nb_pfunc1_max = ', nb_pfunc1_max
+    print*, 'nb_pfunc2_max = ', nb_pfunc2_max
+    print*, 'nb_pfunc3_max = ', nb_pfunc3_max
+    stop
+ end if
+firstcall = .false.
+end if 
 
 end subroutine reactionrates
@@ -1013,8 +735,7 @@
 
 use types_asis
+use chimiedata_h
 
 implicit none
-
-#include "chimiedata.h"
 
 ! input
@@ -1122,7 +843,5 @@
 !================================================================
 
- subroutine indice(i_co2, i_co, i_o, i_o1d, i_o2, i_o3, i_h,       &
-                   i_h2, i_oh, i_ho2, i_h2o2, i_h2o,               &
-                   i_n, i_n2d, i_no, i_no2, i_n2)
+ subroutine indice(nreact,rtype,third_body,three_prod)
 
 !================================================================
@@ -1139,471 +858,187 @@
 
 use types_asis
+use datafile_mod
+use ioipsl_getin_p_mod, only: getin_p
+use tracer_h, only: nesp
+use chimiedata_h
+use callkeys_mod, only: jonline
 
 implicit none
 
-#include "chimiedata.h"
-
-! input
-
-integer :: i_co2, i_co, i_o, i_o1d, i_o2, i_o3, i_h,       &
-           i_h2, i_oh, i_ho2, i_h2o2, i_h2o,               &
-           i_n, i_n2d, i_no, i_no2, i_n2
+! output
+
+integer, intent(out)              :: nreact          ! number of reactions in reactions files
+integer, allocatable, intent(out) :: rtype(:)        ! reaction rate type
+integer, allocatable, intent(out) :: third_body(:)   ! if the reaction have a third body: index of the third body, else zero
+logical, allocatable, intent(out) :: three_prod(:)   ! if the reaction have a three defferent proucts egal .true.
 
 ! local
 
 integer :: nb_phot, nb_reaction_3, nb_reaction_4
-integer :: i_dummy
-
-allocate (indice_phot(nb_phot_max))
-allocate (indice_3(nb_reaction_3_max))
-allocate (indice_4(nb_reaction_4_max))
-
-i_dummy = 1
-
-nb_phot       = 0
-nb_reaction_3 = 0
-nb_reaction_4 = 0
+integer :: nb_hv, nb_pfunc1, nb_pfunc2, nb_pfunc3
+integer :: iq, ireact
+
+character(len = 128)              :: reactfile       ! reactions table file name
+character(len = 128)              :: monoreact       ! photochemical reactions table file name
+character(len = 128)              :: bimolreact      ! bimolecular reactions table file name
+character(len = 128)              :: quadrareact     ! quadratic reactions table file name
+integer                           :: nbq             ! number of species in reactions file
+integer                           :: pnlines         ! number of lines in photochemical reactions file
+integer                           :: bnlines         ! number of lines in bimolecular reactions file
+integer                           :: qnlines         ! number of lines in quadratic reactions file
+integer                           :: pnreact         ! number of reaction in photochemical reactions file
+integer                           :: bnreact         ! number of reaction in bimolecular reactions file
+integer                           :: qnreact         ! number of reaction in quadratic reactions file
+integer                           :: specheck(nesp)  ! to count the species of traceur.def in reactions file
+integer                           :: specheckr(nesp) ! to count the reactant species of traceur.def in reactions file
+integer                           :: specheckp(nesp) ! to count the product species of traceur.def in reactions file
+
+nb_phot        = 0
+nb_reaction_3  = 0
+nb_reaction_4  = 0
+nb_phot_hv_max = 0
+
+nb_hv          = 0
+nb_pfunc1      = 0
+nb_pfunc2      = 0
+nb_pfunc3      = 0
 
 !===========================================================
-!      O2 + hv -> O + O
+!  Read chemical reactions
 !===========================================================
 
-nb_phot = nb_phot + 1
-
-indice_phot(nb_phot) = z3spec(1.0, i_o2, 2.0, i_o, 0.0, i_dummy) 
+! Get number of reactions
+pnlines        = 0
+bnlines        = 0
+qnlines        = 0
+nreact         = 0
+pnreact        = 0
+bnreact        = 0
+qnreact        = 0
+
+write(*,*) "Read photochemical reaction"
+ monoreact = "monoreact" ! default
+call getin_p("monoreact",monoreact) ! default path
+write(*,*) " monoreact = ",trim(monoreact)
+
+write(*,*) "Read bimolecular reaction"
+ bimolreact = "bimolreact" ! default
+call getin_p("bimolreact",bimolreact) ! default path
+write(*,*) " bimolreact = ",trim(bimolreact)
+
+write(*,*) "Read quadratic reaction"
+ quadrareact = "quadrareact" ! default
+call getin_p("quadrareact",quadrareact) ! default path
+write(*,*) " quadrareact = ",trim(quadrareact)
+
+call count_react(monoreact,pnlines,pnreact,nb_phot,nb_hv,nb_pfunc1,nb_pfunc2,nb_pfunc3)
+call count_react(bimolreact,bnlines,bnreact,nb_reaction_4,nb_hv,nb_pfunc1,nb_pfunc2,nb_pfunc3)
+call count_react(quadrareact,qnlines,qnreact,nb_reaction_3,nb_hv,nb_pfunc1,nb_pfunc2,nb_pfunc3)
+nreact = pnreact + bnreact + qnreact
+
+!!!!!!!!!!! Hard coding reaction !!!!!!!!!!!!!!!!!!!!!!!!!!!
+nb_phot       = nb_phot       + nphot_hard_coding
+nb_reaction_4 = nb_reaction_4 + n4_hard_coding
+nb_reaction_3 = nb_reaction_3 + n3_hard_coding
+!!!!!!!!!!! END Hard coding reaction !!!!!!!!!!!!!!!!!!!!!!!
+
+write(*,*)'number of reaction in reaction files is = ',nreact
+print*, 'nb_phot       = ', nb_phot
+print*, 'nb_reaction_4 = ', nb_reaction_4
+print*, 'nb_reaction_3 = ', nb_reaction_3
+print*, '****************'
+print*, 'nb_hv         = ', nb_hv
+print*, 'nb_pfunc1     = ', nb_pfunc1
+print*, 'nb_pfunc2     = ', nb_pfunc2
+print*, 'nb_pfunc3     = ', nb_pfunc3
+nb_phot_max       = nb_phot
+nb_reaction_4_max = nb_reaction_4
+nb_reaction_3_max = nb_reaction_3
+nb_hv_max         = nb_hv
+nb_pfunc1_max     = nb_pfunc1
+nb_pfunc2_max     = nb_pfunc2
+nb_pfunc3_max     = nb_pfunc3
+
+! Allocate
+allocate(indice_phot(nb_phot_max))
+allocate(indice_4(nb_reaction_4_max))
+allocate(indice_3(nb_reaction_3_max))
+allocate(rtype(nreact))
+allocate(third_body(nreact))
+allocate(three_prod(nreact))
+allocate(jlabel(nb_phot_hv_max,2))
+allocate(jparamline(nb_phot_hv_max))
+allocate(pfunc1_param(nb_pfunc1_max))
+allocate(pfunc2_param(nb_pfunc2_max))
+allocate(pfunc3_param(nb_pfunc3_max))
+
+! Get reactants, products and number of species in reactfile
+! inititialize variables
+nbq             = 0
+specheck(:)     = 0
+specheckr(:)    = 0
+specheckp(:)    = 0
+rtype(:)        = 0
+third_body(:)   = 0
+pfunc1_param(:) = rtype1(0.,0.,0.,0.,0.)
+pfunc2_param(:) = rtype2(0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.)
+pfunc3_param(:) = rtype3(0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.)
+nb_pfunc1       = 0
+nb_pfunc2       = 0
+nb_pfunc3       = 0
+three_prod(:)   = .false.
+jlabel(:,:)     = ''
+jparamline(:)   = ''
+
+call get_react(monoreact,pnlines,pnreact,rtype(1:pnreact),third_body(1:pnreact),three_prod(1:pnreact),    &
+               nb_phot,specheck,specheckr,specheckp,'vphot',nbq,nb_pfunc1,nb_pfunc2,nb_pfunc3)
+call get_react(bimolreact,bnlines,bnreact,rtype(pnreact+1:pnreact+bnreact),third_body(pnreact+1:pnreact+bnreact), &
+               three_prod(pnreact+1:pnreact+bnreact),nb_reaction_4,specheck,specheckr,specheckp,'v4',nbq,nb_pfunc1,nb_pfunc2,nb_pfunc3)
+call get_react(quadrareact,qnlines,qnreact,rtype(pnreact+bnreact+1:nreact),third_body(pnreact+bnreact+1:nreact),  &
+               three_prod(pnreact+bnreact+1:nreact),nb_reaction_3,specheck,specheckr,specheckp,'v3',nbq,nb_pfunc1,nb_pfunc2,nb_pfunc3)
+
+! rewrite jlabel corretly for output
+do ireact=1,nb_phot_hv_max
+  if (three_prod(ireact)) then
+    jlabel(ireact+1:nb_phot_hv_max,2) = jlabel(ireact:nb_phot_hv_max-1,2)
+    jlabel(ireact+1:nb_phot_hv_max,1) = jlabel(ireact:nb_phot_hv_max-1,1)
+    jlabel(ireact,1) = trim(jlabel(ireact,1))//'_a'
+    jlabel(ireact+1,1) = trim(jlabel(ireact+1,1))//'_b'
+  end if
+end do
+
+!!!!!!!!!!! Hard coding reaction !!!!!!!!!!!!!!!!!!!!!!!!!!!
+call indice_HC(nb_phot,nb_reaction_4,nb_reaction_3)
+!!!!!!!!!!! END Hard coding reaction !!!!!!!!!!!!!!!!!!!!!!!
+
+write(*,*)'number of species in reaction files is = ',nbq
+write(*,*)'species in reaction files are:'
+
+do iq=1,nesp
+  if (specheck(iq)==1) print*, chemnoms(iq)
+end do
 
 !===========================================================
-!      O2 + hv -> O + O(1D)
+!  check species only destroy or product
 !===========================================================
 
-nb_phot = nb_phot + 1
-
-indice_phot(nb_phot) = z3spec(1.0, i_o2, 1.0, i_o, 1.0, i_o1d) 
+do iq=1,nesp
+  if (specheckr(iq)/=specheckp(iq)) then
+    if (specheckr(iq)==0 .and. specheckp(iq)==1) then
+      print*, 'WARNING: ', chemnoms(iq),' is only product'
+    else if (specheckr(iq)==1 .and. specheckp(iq)==0) then
+      print*, 'WARNING: ', chemnoms(iq),' is only destroy'
+    else
+      print*, 'Error in indice: bad value in specheckr or specheckp'
+      stop
+    end if
+  end if
+end do 
 
 !===========================================================
-!      CO2 + hv -> CO + O
+!  check stochiometry
 !===========================================================
 
-nb_phot = nb_phot + 1
-
-indice_phot(nb_phot) = z3spec(1.0, i_co2, 1.0, i_co, 1.0, i_o) 
-
-!===========================================================
-!      CO2 + hv -> CO + O(1D)
-!===========================================================
-
-nb_phot = nb_phot + 1
-
-indice_phot(nb_phot) = z3spec(1.0, i_co2, 1.0, i_co, 1.0, i_o1d) 
-
-!===========================================================
-!      O3 + hv -> O2 + O(1D)
-!===========================================================
-
-nb_phot = nb_phot + 1
-
-indice_phot(nb_phot) = z3spec(1.0, i_o3, 1.0, i_o2, 1.0, i_o1d) 
-
-!===========================================================
-!      O3 + hv -> O2 + O
-!===========================================================
-
-nb_phot = nb_phot + 1
-
-indice_phot(nb_phot) = z3spec(1.0, i_o3, 1.0, i_o2, 1.0, i_o) 
-
-!===========================================================
-!      H2O + hv -> H + OH
-!===========================================================
-
-nb_phot = nb_phot + 1
-
-indice_phot(nb_phot) = z3spec(1.0, i_h2o, 1.0, i_h, 1.0, i_oh) 
-
-!===========================================================
-!      H2O2 + hv -> OH + OH
-!===========================================================
-
-nb_phot = nb_phot + 1
-
-indice_phot(nb_phot) = z3spec(1.0, i_h2o2, 2.0, i_oh, 0.0, i_dummy) 
-
-!===========================================================
-!      HO2 + hv -> OH + O
-!===========================================================
-
-nb_phot = nb_phot + 1
-
-indice_phot(nb_phot) = z3spec(1.0, i_ho2, 1.0, i_oh, 1.0, i_o) 
-
-!===========================================================
-!      NO + hv -> N + O
-!===========================================================
-
-nb_phot = nb_phot + 1
-
-indice_phot(nb_phot) = z3spec(1.0, i_no, 1.0, i_n, 1.0, i_o) 
-
-!===========================================================
-!      NO2 + hv -> NO + O
-!===========================================================
-
-nb_phot = nb_phot + 1
-
-indice_phot(nb_phot) = z3spec(1.0, i_no2, 1.0, i_no, 1.0, i_o) 
-
-!===========================================================
-!      a001 : O + O2 + CO2 -> O3 + CO2
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_o, 1.0, i_o2, 1.0, i_o3, 0.0, i_dummy) 
-
-!===========================================================
-!      a002 : O + O + CO2 -> O2 + CO2
-!===========================================================
-
-nb_reaction_3 = nb_reaction_3 + 1
-
-indice_3(nb_reaction_3) = z3spec(2.0, i_o, 1.0, i_o2, 0.0, i_dummy) 
-
-!===========================================================
-!      a003 : O + O3 -> O2 + O2
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_o, 1.0, i_o3, 2.0, i_o2, 0.0, i_dummy) 
-
-!===========================================================
-!      b001 : O(1D) + CO2 -> O + CO2
-!===========================================================
-
-nb_phot = nb_phot + 1
-
-indice_phot(nb_phot) = z3spec(1.0, i_o1d, 1.0, i_o, 0.0, i_dummy) 
-
-!===========================================================
-!      b002 : O(1D) + H2O -> OH + OH
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_o1d, 1.0, i_h2o, 2.0, i_oh, 0.0, i_dummy) 
-
-!===========================================================
-!      b003 : O(1D) + H2 -> OH + H
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_o1d, 1.0, i_h2, 1.0, i_oh, 1.0, i_h) 
-
-!===========================================================
-!      b004 : O(1D) + O2 -> O + O2
-!===========================================================
-
-nb_phot = nb_phot + 1
-
-indice_phot(nb_phot) = z3spec(1.0, i_o1d, 1.0, i_o, 0.0, i_dummy) 
-
-!===========================================================
-!      b005 : O(1D) + O3 -> O2 + O2
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_o1d, 1.0, i_o3, 2.0, i_o2, 0.0, i_dummy) 
-
-!===========================================================
-!      b006 : O(1D) + O3 -> O2 + O + O
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_o1d, 1.0, i_o3, 1.0, i_o2, 2.0, i_o) 
-
-!===========================================================
-!      c001 : O + HO2 -> OH + O2
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_o, 1.0, i_ho2, 1.0, i_oh, 1.0, i_o2) 
-
-!===========================================================
-!      c002 : O + OH -> O2 + H
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_o, 1.0, i_oh, 1.0, i_o2, 1.0, i_h) 
-
-!===========================================================
-!      c003 : H + O3 -> OH + O2
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_h, 1.0, i_o3, 1.0, i_oh, 1.0, i_o2) 
-
-!===========================================================
-!      c004 : H + HO2 -> OH + OH
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_h, 1.0, i_ho2, 2.0, i_oh, 0.0, i_dummy) 
-
-!===========================================================
-!      c005 : H + HO2 -> H2 + O2
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_h, 1.0, i_ho2, 1.0, i_h2, 1.0, i_o2) 
-
-!===========================================================
-!      c006 : H + HO2 -> H2O + O
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_h, 1.0, i_ho2, 1.0, i_h2o, 1.0, i_o) 
-
-!===========================================================
-!      c007 : OH + HO2 -> H2O + O2
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_oh, 1.0, i_ho2, 1.0, i_h2o, 1.0, i_o2) 
-
-!===========================================================
-!      c008 : HO2 + HO2 -> H2O2 + O2
-!===========================================================
-
-nb_reaction_3 = nb_reaction_3 + 1
-
-indice_3(nb_reaction_3) = z3spec(2.0, i_ho2, 1.0, i_h2o2, 1.0, i_o2) 
-
-!===========================================================
-!      c009 : OH + H2O2 -> H2O + HO2
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_oh, 1.0, i_h2o2, 1.0, i_h2o, 1.0, i_ho2) 
-
-!===========================================================
-!      c010 : OH + H2 -> H2O + H
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_oh, 1.0, i_h2, 1.0, i_h2o, 1.0, i_h) 
-
-!===========================================================
-!      c011 : H + O2 + CO2 -> HO2 + CO2
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_h, 1.0, i_o2, 1.0, i_ho2, 0.0, i_dummy) 
-
-!===========================================================
-!      c012 : O + H2O2 -> OH + HO2
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_o, 1.0, i_h2o2, 1.0, i_oh, 1.0, i_ho2) 
-
-!===========================================================
-!      c013 : OH + OH -> H2O + O
-!===========================================================
-
-nb_reaction_3 = nb_reaction_3 + 1
-
-indice_3(nb_reaction_3) = z3spec(2.0, i_oh, 1.0, i_h2o, 1.0, i_o) 
-
-!===========================================================
-!      c014 : OH + O3 -> HO2 + O2 
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_oh, 1.0, i_o3, 1.0, i_ho2, 1.0, i_o2) 
-
-!===========================================================
-!      c015 : HO2 + O3 -> OH + O2 + O2 
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_ho2, 1.0, i_o3, 1.0, i_oh, 2.0, i_o2) 
-
-!===========================================================
-!      c016 : HO2 + HO2 + CO2 -> H2O2 + O2 + CO2 
-!===========================================================
-
-nb_reaction_3 = nb_reaction_3 + 1
-
-indice_3(nb_reaction_3) = z3spec(2.0, i_ho2, 1.0, i_h2o2, 1.0, i_o2) 
-
-!===========================================================
-!      c017 : OH + OH + CO2 -> H2O2 + CO2 
-!===========================================================
-
-nb_reaction_3 = nb_reaction_3 + 1
-
-indice_3(nb_reaction_3) = z3spec(2.0, i_oh, 1.0, i_h2o2, 0.0, i_dummy) 
-
-!===========================================================
-!      c018 : H + H + CO2 -> H2 + CO2 
-!===========================================================
-
-nb_reaction_3 = nb_reaction_3 + 1
-
-indice_3(nb_reaction_3) = z3spec(2.0, i_h, 1.0, i_h2, 0.0, i_dummy) 
-
-!===========================================================
-!      d001 : NO2 + O -> NO + O2 
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_no2, 1.0, i_o, 1.0, i_no, 1.0, i_o2) 
-
-!===========================================================
-!      d002 : NO + O3 -> NO2 + O2 
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_no, 1.0, i_o3, 1.0, i_no2, 1.0, i_o2) 
-
-!===========================================================
-!      d003 : NO + HO2 -> NO2 + OH 
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_no, 1.0, i_ho2, 1.0, i_no2, 1.0, i_oh) 
-
-!===========================================================
-!      d004 : N + NO -> N2 + O 
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_n, 1.0, i_no, 1.0, i_n2, 1.0, i_o) 
-
-!===========================================================
-!      d005 : N + O2 -> NO + O 
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_n, 1.0, i_o2, 1.0, i_no, 1.0, i_o) 
-
-!===========================================================
-!      d006 : NO2 + H -> NO + OH 
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_no2, 1.0, i_h, 1.0, i_no, 1.0, i_oh) 
-
-!===========================================================
-!      d007 : N + O -> NO
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_n, 1.0, i_o, 1.0, i_no, 0.0, i_dummy) 
-
-!===========================================================
-!      d008 : N + HO2 -> NO + OH
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_n, 1.0, i_ho2, 1.0, i_no, 1.0, i_oh) 
-
-!===========================================================
-!      d009 : N + OH -> NO + H
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_n, 1.0, i_oh, 1.0, i_no, 1.0, i_h) 
-
-!===========================================================
-!      e001 : CO + OH -> CO2 + H 
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_co, 1.0, i_oh, 1.0, i_co2, 1.0, i_h) 
-
-!===========================================================
-!      e002 : CO + O + M -> CO2 + M 
-!===========================================================
-
-nb_reaction_4 = nb_reaction_4 + 1
-
-indice_4(nb_reaction_4) = z4spec(1.0, i_co, 1.0, i_o, 1.0, i_co2, 0.0, i_dummy) 
-
-!===========================================================
-!      h001: HO2 + ice -> products
-!            treated as
-!            HO2 -> 0.5 H2O + 0.75 O2
-!===========================================================
-
-nb_phot = nb_phot + 1
-
-indice_phot(nb_phot) = z3spec(1.0, i_ho2, 0.5, i_h2o, 0.75, i_o2) 
-
-!===========================================================
-!      h002: OH + ice -> products
-!            treated as
-!            OH -> 0.5 H2O + 0.25 O2
-!===========================================================
-
-nb_phot = nb_phot + 1
-
-indice_phot(nb_phot) = z3spec(1.0, i_oh, 0.5, i_h2o, 0.25, i_o2) 
-
-!===========================================================
-!      h003: H2O2 + ice -> products
-!            treated as
-!            H2O2 -> H2O + 0.5 O2
-!===========================================================
-
-nb_phot = nb_phot + 1
-
-indice_phot(nb_phot) = z3spec(1.0, i_h2o2, 1.0, i_h2o, 0.5, i_o2) 
-
-!===========================================================
-!      h004: HO2 + dust -> products
-!            treated as
-!            HO2 -> 0.5 H2O + 0.75 O2
-!===========================================================
-
-nb_phot = nb_phot + 1
-
-indice_phot(nb_phot) = z3spec(1.0, i_ho2, 0.5, i_h2o, 0.75, i_o2) 
-
-!===========================================================
-!      h005: H2O2 + dust -> products
-!            treated as
-!            H2O2 -> H2O + 0.5 O2
-!===========================================================
-
-nb_phot = nb_phot + 1
-
-indice_phot(nb_phot) = z3spec(1.0, i_h2o2, 1.0, i_h2o, 0.5, i_o2) 
+! If you found a way
 
 !===========================================================
@@ -1611,12 +1046,25 @@
 !===========================================================
 
-print*, 'nb_phot       = ', nb_phot
-print*, 'nb_reaction_4 = ', nb_reaction_4
-print*, 'nb_reaction_3 = ', nb_reaction_3
+if (jonline) then
+  nd = nb_hv_max
+else if (nb_phot_hv_max /= 0) then
+  print*,'calchim: Read photolysis lookup table'
+  call read_phototable
+end if
 
 if ((nb_phot /= nb_phot_max)             .or.  &
     (nb_reaction_3 /= nb_reaction_3_max) .or.  &
-    (nb_reaction_4 /= nb_reaction_4_max)) then
+    (nb_reaction_4 /= nb_reaction_4_max) .or.  &
+    (nd /= nb_hv_max)) then
+   print*, 'nb_phot       = ', nb_phot
+   print*, 'nb_reaction_4 = ', nb_reaction_4
+   print*, 'nb_reaction_3 = ', nb_reaction_3
+   print*, 'nd            = ', nd
    print*, 'wrong dimensions in indice' 
+   print*, 'nb_phot_max       = ', nb_phot_max
+   print*, 'nb_reaction_4_max = ', nb_reaction_4_max
+   print*, 'nb_reaction_3_max = ', nb_reaction_3_max
+   print*, 'nb_phot_hv_max    = ', nb_phot_hv_max
+   print*, 'nb_hv_max         = ', nb_hv_max
    stop
 end if  
@@ -1626,16 +1074,7 @@
 !*****************************************************************
 
-      subroutine gcmtochim(nlayer, nq, zycol, lswitch, nesp,         &
-                           i_co2, i_co, i_o, i_o1d, i_o2, i_o3, i_h, &
-                           i_h2, i_oh, i_ho2, i_h2o2, i_h2o,         &
-                           i_n, i_n2d, i_no, i_no2, i_n2,            &
-                           dens, rm, c) 
+      subroutine gcmtochim(nlayer, zycol, lswitch, nesp, dens, rm, c) 
 
 !*****************************************************************
-
-      use tracer_h, only: igcm_co2, igcm_co, igcm_o, igcm_o1d,         &
-     &                      igcm_o2, igcm_o3, igcm_h, igcm_h2, igcm_oh,  &
-     &                      igcm_ho2, igcm_h2o2, igcm_h2o_vap,           &
-     &                      igcm_n, igcm_n2d, igcm_no, igcm_no2, igcm_n2
 
       use callkeys_mod
@@ -1649,13 +1088,8 @@
       
       integer, intent(in) :: nlayer ! number of atmospheric layers
-      integer, intent(in) :: nq     ! number of tracers in the gcm
-      integer :: nesp               ! number of species in the chemistry
+      integer, intent(in) :: nesp   ! number of species in the chemistry
       integer :: lswitch            ! interface level between chemistries
 
-      integer :: i_co2, i_co, i_o, i_o1d, i_o2, i_o3, i_h,           &
-                 i_h2, i_oh, i_ho2, i_h2o2, i_h2o,                   &
-                 i_n, i_n2d, i_no, i_no2, i_n2
-
-      real :: zycol(nlayer,nq)      ! volume mixing ratios in the gcm
+      real :: zycol(nlayer,nesp)    ! volume mixing ratios in the gcm
       real :: dens(nlayer)          ! total number density (molecule.cm-3) 
 
@@ -1672,84 +1106,7 @@
 
       integer      :: l, iesp
-      logical,save :: firstcall = .true.
       
+      rm(:,:) = 0.
       
-!     first call initializations
-
-      if (firstcall) then
-
-!       identify the indexes of the tracers we need
-
-         if (igcm_co2 == 0) then
-            write(*,*) "gcmtochim: Error; no CO2 tracer !!!"
-            stop
-         endif
-         if (igcm_co == 0) then
-            write(*,*) "gcmtochim: Error; no CO tracer !!!"
-            stop
-         end if
-         if (igcm_o == 0) then
-            write(*,*) "gcmtochim: Error; no O tracer !!!"
-            stop
-         end if
-         if (igcm_o1d == 0) then
-            write(*,*) "gcmtochim: Error; no O1D tracer !!!"
-            stop
-         end if
-         if (igcm_o2 == 0) then
-            write(*,*) "gcmtochim: Error; no O2 tracer !!!"
-            stop
-         end if
-         if (igcm_o3 == 0) then
-            write(*,*) "gcmtochim: Error; no O3 tracer !!!"
-            stop
-         end if
-         if (igcm_h == 0) then
-            write(*,*) "gcmtochim: Error; no H tracer !!!"
-            stop
-         end if
-         if (igcm_h2 == 0) then
-            write(*,*) "gcmtochim: Error; no H2 tracer !!!"
-            stop
-         end if
-         if (igcm_oh == 0) then
-            write(*,*) "gcmtochim: Error; no OH tracer !!!"
-            stop
-         end if
-         if (igcm_ho2 == 0) then
-            write(*,*) "gcmtochim: Error; no HO2 tracer !!!"
-            stop
-         end if
-         if (igcm_h2o2 == 0) then
-            write(*,*) "gcmtochim: Error; no H2O2 tracer !!!"
-            stop
-         end if
-         if (igcm_n == 0) then
-            write(*,*) "gcmtochim: Error; no N tracer !!!"
-!            stop
-         end if
-         if (igcm_n2d == 0) then
-            write(*,*) "gcmtochim: Error; no N2D tracer !!!"
-!            stop
-         end if
-         if (igcm_no == 0) then
-            write(*,*) "gcmtochim: Error; no NO tracer !!!"
-!            stop
-         end if
-         if (igcm_no2 == 0) then
-            write(*,*) "gcmtochim: Error; no NO2 tracer !!!"
-!            stop
-         end if
-         if (igcm_n2 == 0) then
-            write(*,*) "gcmtochim: Error; no N2 tracer !!!"
-            stop
-         end if
-         if (igcm_h2o_vap == 0) then
-            write(*,*) "gcmtochim: Error; no water vapor tracer !!!"
-            stop
-         end if
-         firstcall = .false.
-      end if ! of if (firstcall)
-
 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccc
 !     initialise mixing ratios
@@ -1757,21 +1114,5 @@
 
       do l = 1,lswitch-1
-         rm(l,i_co2)  = zycol(l, igcm_co2)
-         rm(l,i_co)   = zycol(l, igcm_co)
-         rm(l,i_o)    = zycol(l, igcm_o)
-         rm(l,i_o1d)  = zycol(l, igcm_o1d)
-         rm(l,i_o2)   = zycol(l, igcm_o2)
-         rm(l,i_o3)   = zycol(l, igcm_o3)
-         rm(l,i_h)    = zycol(l, igcm_h)
-         rm(l,i_h2)   = zycol(l, igcm_h2)
-         rm(l,i_oh)   = zycol(l, igcm_oh)
-         rm(l,i_ho2)  = zycol(l, igcm_ho2)
-         rm(l,i_h2o2) = zycol(l, igcm_h2o2)
-         rm(l,i_h2o)  = zycol(l, igcm_h2o_vap)
-         rm(l,i_n)    = zycol(l, igcm_n)
-         rm(l,i_n2d)  = zycol(l, igcm_n2d)
-         rm(l,i_no)   = zycol(l, igcm_no)
-         rm(l,i_no2)  = zycol(l, igcm_no2)
-         rm(l,i_n2)   = zycol(l, igcm_n2)
+         rm(l,:) = zycol(l,:)
       end do 
 
@@ -1794,15 +1135,8 @@
 !*****************************************************************
  
-      subroutine chimtogcm(nlayer, nq, zycol, lswitch, nesp,         &
-                           i_co2, i_co, i_o, i_o1d, i_o2, i_o3, i_h, &
-                           i_h2, i_oh, i_ho2, i_h2o2, i_h2o,         &
-                           i_n, i_n2d, i_no, i_no2, i_n2, dens, c) 
+      subroutine chimtogcm(nlayer, zycol, lswitch, nesp, dens, c) 
+
  
 !*****************************************************************
- 
-      use tracer_h, only: igcm_co2, igcm_co, igcm_o, igcm_o1d,          &
-                            igcm_o2, igcm_o3, igcm_h, igcm_h2, igcm_oh,   &
-                            igcm_ho2, igcm_h2o2, igcm_h2o_vap,            &
-                            igcm_n, igcm_n2d, igcm_no, igcm_no2, igcm_n2
 
       use callkeys_mod
@@ -1816,10 +1150,6 @@
  
       integer, intent(in) :: nlayer  ! number of atmospheric layers
-      integer, intent(in) :: nq      ! number of tracers in the gcm
-      integer :: nesp                ! number of species in the chemistry
+      integer, intent(in) :: nesp    ! number of species in the chemistry
       integer :: lswitch             ! interface level between chemistries
-      integer :: i_co2, i_co, i_o, i_o1d, i_o2, i_o3, i_h,       &
-                 i_h2, i_oh, i_ho2, i_h2o2, i_h2o,               &
-                 i_n, i_n2d, i_no, i_no2, i_n2
 
       real :: dens(nlayer)     ! total number density (molecule.cm-3) 
@@ -1830,5 +1160,5 @@
 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
        
-      real zycol(nlayer,nq)  ! volume mixing ratios in the gcm
+      real zycol(nlayer,nesp)  ! volume mixing ratios in the gcm
 
 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
@@ -1843,25 +1173,394 @@
 
       do l = 1,lswitch-1
-         zycol(l, igcm_co2)     = c(l,i_co2)/dens(l) 
-         zycol(l, igcm_co)      = c(l,i_co)/dens(l) 
-         zycol(l, igcm_o)       = c(l,i_o)/dens(l) 
-         zycol(l, igcm_o1d)     = c(l,i_o1d)/dens(l)
-         zycol(l, igcm_o2)      = c(l,i_o2)/dens(l) 
-         zycol(l, igcm_o3)      = c(l,i_o3)/dens(l) 
-         zycol(l, igcm_h)       = c(l,i_h)/dens(l)  
-         zycol(l, igcm_h2)      = c(l,i_h2)/dens(l) 
-         zycol(l, igcm_oh)      = c(l,i_oh)/dens(l) 
-         zycol(l, igcm_ho2)     = c(l,i_ho2)/dens(l) 
-         zycol(l, igcm_h2o2)    = c(l,i_h2o2)/dens(l)
-         zycol(l, igcm_h2o_vap) = c(l,i_h2o)/dens(l)
-         zycol(l, igcm_n)       = c(l,i_n)/dens(l)
-         zycol(l, igcm_n2d)     = c(l,i_n2d)/dens(l)
-         zycol(l, igcm_no)      = c(l,i_no)/dens(l)
-         zycol(l, igcm_no2)     = c(l,i_no2)/dens(l)
-         zycol(l, igcm_n2)      = c(l,i_n2)/dens(l)
+         zycol(l,:)  = c(l,:)/dens(l) 
       end do 
 
       end subroutine chimtogcm
 
+!*****************************************************************
+
+    subroutine split_str(line,words,n,nmax)
+
+!*****************************************************************
+
+        implicit none
+        character(*), intent(in)  :: line
+        integer,      intent(in)  :: nmax
+        character(*), intent(out) :: words(nmax)
+        integer,      intent(out) :: n          ! number of words at the end
+        integer :: ios
+        character(100) :: buf(100)  ! large buffer!
+    
+        n = 0
+        do
+            n = n + 1
+            read(line,*,iostat=ios) buf(1:n)  ! use list-directed input
+            if (ios==0) then
+                words(1:n) = buf(1:n)   ! if success, copy to the original array
+            else
+                n = n-1
+                exit       ! if all the words are obtained, finish
+            endif
+            if (n>nmax) then
+              print*,'Error in split_str: to much words'
+              print*,'limit = ',nmax
+              print*,'change it, if you want, with increasing nmax'
+              stop
+            end if
+        enddo
+    end subroutine split_str
+
+!*****************************************************************
+
+    subroutine count_react(reactfile,nlines,nreact,nrtype,nb_hv,nb_pfunc1,nb_pfunc2,nb_pfunc3)
+
+!*****************************************************************
+
+        use types_asis, only : nb_phot_hv_max
+
+        implicit none
+        character(*), intent(in)     :: reactfile ! name of the file to read 
+        integer,      intent(inout)  :: nlines    ! number of lines in the file
+        integer,      intent(out)    :: nreact    ! real number of reaction
+        integer,      intent(inout)  :: nrtype    ! number of reaction for calculation
+        integer,      intent(inout)  :: nb_hv, nb_pfunc1, nb_pfunc2, nb_pfunc3
+
+        ! local
+        character(len = 50) :: reactline          ! all reactants of one reaction
+        character(len = 50) :: prodline           ! all produts of one reaction
+        integer             :: typerate           ! get the type of the rate reaction coefficient (pfunc_i)
+        integer             :: nwp                ! number of products for a reaction
+        integer,parameter   :: nmax = 5           ! number max of reactants or products
+        character(len = 24) :: words(nmax)        ! to get words in reactants and products line
+        integer             :: ierr
+
+        nreact     = 0
+
+        open(402, form = 'formatted', status = 'old',                &
+              file ='chemnetwork/'//trim(reactfile),iostat=ierr)
+
+        if (ierr /= 0) THEN
+           write(*,*)'Error : cannot open chemical reaction file : chemnetwork/'//trim(reactfile)
+           write(*,*)'It should be in your simulation directory in chemnetwork directory'
+           write(*,*)'   You can change the input chemical reactions file name in'
+           write(*,*)'   callphys.def with:'
+           write(*,*)'   monoreact=filename or bimolreact=filename or quadrareact=filename'
+           write(*,*)'   depending on what chemical reaction type it is'
+           stop
+        end if
+    
+        do
+          read(402,'(A,A,I2)',iostat=ierr) reactline, prodline, typerate
+          if (ierr<0) exit
+          nlines = nlines + 1
+          if (reactline(1:1)/='!' .and. reactline(1:1)/='') then
+            ! count the number of reaction
+            nreact = nreact + 1
+            call split_str(prodline,words,nwp,nmax)
+            nrtype = nrtype + 1
+            ! check three product reaction
+            if (nwp>2 .and. trim(words(1))/=trim(words(2)) &
+                      .and. trim(words(1))/=trim(words(3)) &
+                      .and. trim(words(2))/=trim(words(3))) nrtype = nrtype + 1
+
+            ! count the number of each rate reaction coefficient type
+            if (typerate==0) then
+              nb_hv = nb_hv + 1
+              nb_phot_hv_max = nb_phot_hv_max + 1
+              if (nwp>2 .and. trim(words(1))/=trim(words(2)) &
+                        .and. trim(words(1))/=trim(words(3)) &
+                        .and. trim(words(2))/=trim(words(3))) nb_phot_hv_max = nb_phot_hv_max + 1
+            else if (typerate==1) then
+              nb_pfunc1 = nb_pfunc1 + 1
+            else if (typerate==2) then
+              nb_pfunc2 = nb_pfunc2 + 1
+            else if (typerate==3) then
+              nb_pfunc3 = nb_pfunc3 + 1
+            else
+              print*, 'Error in indice: wrong index coefficient rate line ',nlines
+              print*, 'in file : chemnetwork/'//trim(reactfile)
+              print*, 'It should be 0 for photolysis reations and 1 or 2 for the others'
+              print*, 'And not : ', typerate
+              stop
+            end if
+
+          end if
+
+        end do
+
+        close(402)
+
+    end subroutine count_react
+
+!*****************************************************************
+
+    subroutine get_react(reactfile,nlines,nreact,rtype,third_body,three_prod, &
+                         nrtype,specheck,specheckr,specheckp,typeindice,nbq,  &
+                         init_nb_pfunc1,init_nb_pfunc2,init_nb_pfunc3)
+
+!*****************************************************************
+
+        use types_asis
+        use tracer_h
+        use chimiedata_h, only: indexchim
+        use callkeys_mod, only: jonline
+
+        implicit none
+        character(*), intent(in)     :: reactfile          ! name of the file to read 
+        integer,      intent(in)     :: nlines             ! number of lines in the file
+        integer,      intent(in)     :: nreact             ! real number of reaction in the file
+        integer,      intent(inout)  :: rtype(nreact)      ! reaction rate type
+        integer,      intent(inout)  :: third_body(nreact) ! if the reaction have a third body: index of the third body, else zero
+        logical,      intent(inout)  :: three_prod(nreact) ! if the reaction have a three defferent proucts egal .true.
+        integer,      intent(out)    :: nrtype             ! number of calculation reactions
+        integer,      intent(inout)  :: specheck(nesp)     ! to count the species of traceur.def in reactions file
+        integer,      intent(inout)  :: specheckr(nesp)    ! to count the reactant species of traceur.def in reactions file
+        integer,      intent(inout)  :: specheckp(nesp)    ! to count the product species of traceur.def in reactions file
+        character(*), intent(in)     :: typeindice         ! reaction type (v3, v4 or vphot)
+        integer,      intent(inout)  :: nbq                ! number of species in reactions file
+        integer,      intent(inout)  :: init_nb_pfunc1     ! in : initial value of nb_pfunc1 - out : final value of nb_pfunc1
+        integer,      intent(inout)  :: init_nb_pfunc2     ! in : initial value of nb_pfunc2 - out : final value of nb_pfunc2
+        integer,      intent(inout)  :: init_nb_pfunc3     ! in : initial value of nb_pfunc3 - out : final value of nb_pfunc3
+
+        ! local
+        character(len = 50)  :: reactline                  ! all reactants of one reaction
+        character(len = 50)  :: prodline                   ! all produts of one reaction
+        integer              :: nwr                        ! number of reactants for a reaction
+        integer              :: nwp                        ! number of products for a reaction
+        integer,parameter    :: nmax = 5                   ! number max of reactants or products
+        character(len = 24)  :: words(nmax)                ! to get words in reactants and products line
+        real                 :: nindice(2*nmax)            ! stoichiometry of species (for indice variables)
+        integer              :: iindice(2*nmax)            ! indice of species (for indice variables)
+        character(len = 500) :: paramline                  ! line of reactions parameters
+        character(len = 50)  :: reactants(nreact,nmax)     ! reactions reactants
+        character(len = 50)  :: products(nreact,nmax)      ! reactions products
+        logical              :: spedouble                  ! check if a specie appears twice in reactants or products
+        integer              :: ierr, ilines, ireact, i_dummy, iw, iwhere, i
+        integer              :: nb_hv, nb_pfunc1, nb_pfunc2, nb_pfunc3
+
+        i_dummy   = 1
+        nrtype    = 0
+        ireact    = 0
+        nb_hv     = 0
+        nb_pfunc1 = init_nb_pfunc1
+        nb_pfunc2 = init_nb_pfunc2
+        nb_pfunc3 = init_nb_pfunc3
+
+        open(402, form = 'formatted', status = 'old',                &
+              file ='chemnetwork/'//trim(reactfile),iostat=ierr)
+
+        if (ierr /= 0) THEN
+           write(*,*)'Error : cannot open chemical reaction file : chemnetwork/'//trim(reactfile)
+           write(*,*)'It should be in your simulation directory in chemnetwork directory'
+           write(*,*)'   You can change the input chemical reactions file name in'
+           write(*,*)'   callphys.def with:'
+           write(*,*)'   monoreact=filename or bimolreact=filename or quadrareact=filename'
+           write(*,*)'   depending on what chemical reaction type it is'
+           stop
+        end if
+
+        do ilines=1,nlines
+          paramline = ''
+
+          read(402,'(A,A,A)') reactline, prodline, paramline
+
+          ! continue only if it's not a comment line
+          if (reactline(1:1)/='!' .and. reactline(1:1)/='') then
+
+            ! increment number of reactions and init
+            ireact = ireact + 1
+        !!!!!!!!!!!!!!!!!!!!!!!!!!! for fill indice part
+            nrtype = nrtype + 1
+            nindice(:) = 0.0
+            iindice(:) = i_dummy
+        !!!!!!!!!!!!!!!!!!!!!!!!!!! end
+            ! get indice, rate type and parameters
+            if (trim(paramline)=='') then
+              print*, 'Error in reactfile: where are the parameters - line',ilines
+              stop
+            else
+              read(paramline,*) rtype(ireact)
+              if (rtype(ireact)==1) then
+                nb_pfunc1 = nb_pfunc1 + 1
+                read(paramline,*) rtype(ireact), pfunc1_param(nb_pfunc1)
+              else if (rtype(ireact)==0) then
+                nb_hv = nb_hv + 1
+                if (jonline) then
+                  read(paramline,'(I5,A,A)') rtype(ireact), jlabel(nb_hv,1), jparamline(nb_hv)
+                else
+                  read(paramline,*) rtype(ireact), jlabel(nb_hv,1)
+                end if
+              else if (rtype(ireact)==2) then
+                nb_pfunc2 = nb_pfunc2 + 1
+                read(paramline,*) rtype(ireact), pfunc2_param(nb_pfunc2)
+              else if (rtype(ireact)==3) then
+                nb_pfunc3 = nb_pfunc3 + 1
+                read(paramline,*) rtype(ireact), pfunc3_param(nb_pfunc3)
+              end if
+            end if
+        
+            ! get reactants
+            call split_str(reactline,words,nwr,nmax)
+            if (rtype(ireact)==0) jlabel(nb_hv,2) = words(1)
+            ! loop on reactants
+            do iw=1,nwr
+              ! store reactants in variable 'reactants'
+              reactants(ireact,iw) = trim(words(iw))
+              ! check third body and exit reactants loop
+              if (reactants(ireact,iw)=='M') then
+                if (iw==nwr) then
+                  exit
+                else if (iw==nwr-1) then
+                  third_body(ireact) = indexchim(words(iw+1))
+                  exit
+                else
+                  print*, 'Error in reactfile: just only one specie can be after M corresponding to the third body - line',ilines
+                  stop
+                end if
+              end if
+              if (trim(words(iw))/='hv' .and. trim(words(iw))/='dummy') then
+                iwhere = indexchim(words(iw))
+                ! check if species are chemical tracers
+                if (iwhere>nesp) then
+                  print*, 'Error: in ', trim(reactfile)
+                  print*, 'check if the specie', trim(words(iw)),' is include into chemical tracers in traceur.def'
+                  stop
+                end if
+                ! to count the species used in 'reactfile'
+                if (specheck(iwhere)==0) then
+                  specheckr(iwhere) = 1
+                  specheck(iwhere) = 1
+                  nbq = nbq + 1
+                else if (specheckr(iwhere)==0) then
+                  specheckr(iwhere) = 1
+                end if
+        
+        !!!!!!!!!!!!!!!!!!! for fill indice part
+                ! fill stochiometry and indice of rection species depending of reaction type
+                if (trim(typeindice)=='v3') then
+                  nindice(1) = 2.0
+                  iindice(1) = indexchim(words(iw))
+                  if (nwr>3 .or. nwr<2) print*, 'Error in reactfile: wrong number of reactants for v3 reaction line',ilines
+                  if (nwr==2 .and. trim(words(1))/=trim(words(2))) print*, 'Error in reactfile: both reactants should be the same for v3 reaction line',ilines
+                else if (trim(typeindice)=='v4') then
+                  nindice(iw) = 1.0
+                  iindice(iw) = indexchim(words(iw))
+                else if (trim(typeindice)=='vphot') then
+                  nindice(1) = 1.0
+                  if (iw>2) then
+                    print*, 'Something weird in your photolysis reaction'
+                    print*, 'You should have 1 reactants and hv'
+                    print*, 'Reactants are: ',words
+                    stop
+                  end if
+                  iindice(1) = indexchim(words(iw))
+                end if
+        !!!!!!!!!!!!!!!!!!! end
+        
+              end if
+            end do
+
+            ! same as reactants but for the products
+            call split_str(prodline,words,nwp,nmax)
+            do iw=1,nwp
+              spedouble = .false.
+              products(ireact,iw) = trim(words(iw))
+              if (trim(words(iw))/='hv' .and. trim(words(iw))/='dummy' .and. trim(words(iw))/='M') then
+                iwhere = indexchim(words(iw))
+                if (iwhere>nesp) then
+                  print*, 'Error: in ', trim(reactfile)
+                  print*, 'check if the specie', trim(words(iw)),' is include into chemical tracers in traceur.def'
+                  stop
+                end if
+                if (specheck(iwhere)==0) then
+                  specheckp(iwhere) = 1
+                  specheck(iwhere) = 1
+                  nbq = nbq + 1
+                else if (specheckp(iwhere)==0) then
+                  specheckp(iwhere) = 1
+                end if
+        
+        !!!!!!!!!!!!!!!!!!!!!!!!!! for fill indice part
+                if (trim(typeindice)=='v3' .or. trim(typeindice)=='vphot') then
+                    iindice(1+iw) = indexchim(words(iw))
+                  do i=1,iw-1
+                    if (iindice(1+iw)==iindice(1+i)) then
+                      nindice(1+i)  = nindice(1+i) + 1.0
+                      iindice(1+iw) = i_dummy
+                      spedouble = .true.
+                    end if
+                  end do
+                  if (.not. spedouble) nindice(1+iw) = 1.0
+                else if (trim(typeindice)=='v4') then
+                  iindice(2+iw) = indexchim(words(iw))
+                  do i=1,iw-1
+                    if (iindice(2+iw)==iindice(2+i)) then
+                      nindice(2+i)  = nindice(2+i) + 1.0
+                      iindice(2+iw) = i_dummy
+                      spedouble = .true.
+                    end if
+                  end do
+                  if (.not. spedouble) nindice(2+iw) = 1.0
+                end if
+        !!!!!!!!!!!!!!!!!!!!!!!!!!! end
+              else
+                print*, 'Error: no hv, dummy or M in products'
+                stop
+              end if
+            end do
+
+            ! fill indice variables
+            if (trim(typeindice)=='v3') then
+              if (nindice(4)/=0.0) then ! reaction with 3 products
+                if (nindice(3)==0.0) then ! 2 are the same species
+                  indice_3(nrtype) = z3spec(nindice(1), iindice(1), nindice(2), iindice(2), nindice(4), iindice(4))
+                else ! reaction with 3 different products
+                  indice_3(nrtype) = z3spec(nindice(1)/2., iindice(1), nindice(2), iindice(2), 0.0, i_dummy)
+                  nrtype = nrtype + 1
+                  indice_3(nrtype) = z3spec(nindice(1)/2., iindice(1), nindice(3), iindice(3), nindice(4), iindice(4))
+                  three_prod(ireact) = .true.
+                end if
+              else ! reaction with 1 or 2 products
+                indice_3(nrtype) = z3spec(nindice(1), iindice(1), nindice(2), iindice(2), nindice(3), iindice(3))
+              end if
+            else if (trim(typeindice)=='v4') then
+              if (nindice(5)/=0.0) then ! reaction with 3 products
+                if (nindice(4)==0.0) then ! 2 are the same species
+                  indice_4(nrtype) = z4spec(nindice(1), iindice(1), nindice(2), iindice(2), nindice(3), iindice(3), nindice(5), iindice(5))
+                else ! reaction with 3 different products
+                  indice_4(nrtype) = z4spec(nindice(1)/2., iindice(1), nindice(2)/2., iindice(2), nindice(3), iindice(3), nindice(4)/2., iindice(4))
+                  nrtype = nrtype + 1
+                  indice_4(nrtype) = z4spec(nindice(1)/2., iindice(1), nindice(2)/2., iindice(2), nindice(5), iindice(5), nindice(4)/2., iindice(4))
+                  three_prod(ireact) = .true.
+                end if
+              else ! reaction with 1 or 2 products
+                indice_4(nrtype) = z4spec(nindice(1), iindice(1), nindice(2), iindice(2), nindice(3), iindice(3), nindice(4), iindice(4))
+              end if
+            else if (trim(typeindice)=='vphot') then
+              if (nindice(4)/=0.0) then ! reaction with 3 products
+                if (nindice(3)==0.0) then ! 2 are the same species
+                  indice_phot(nrtype) = z3spec(nindice(1), iindice(1), nindice(2), iindice(2), nindice(4), iindice(4))
+                else ! reaction with 3 different products
+                  indice_phot(nrtype) = z3spec(nindice(1)/2., iindice(1), nindice(2), iindice(2), 0.0, i_dummy)
+                  nrtype = nrtype + 1
+                  indice_phot(nrtype) = z3spec(nindice(1)/2., iindice(1), nindice(3), iindice(3), nindice(4), iindice(4))
+                  three_prod(ireact) = .true.
+                end if
+              else ! reaction with 1 or 2 products
+                indice_phot(nrtype) = z3spec(nindice(1), iindice(1), nindice(2), iindice(2), nindice(3), iindice(3))
+              end if
+            end if
+        
+          end if
+
+        end do
+
+        init_nb_pfunc1 = nb_pfunc1
+        init_nb_pfunc2 = nb_pfunc2
+        init_nb_pfunc3 = nb_pfunc3
+
+        close(402)
+
+    end subroutine get_react
+
 end subroutine photochemistry_asis
-
Index: trunk/LMDZ.GENERIC/libf/aeronostd/photolysis_asis.F90
===================================================================
--- trunk/LMDZ.GENERIC/libf/aeronostd/photolysis_asis.F90	(revision 2541)
+++ trunk/LMDZ.GENERIC/libf/aeronostd/photolysis_asis.F90	(revision 2542)
@@ -1,7 +1,7 @@
 !==========================================================================
 
-      subroutine photolysis_asis(nlayer, ngrid,                                 &
-                                 lswitch, press, temp, sza, fractcol, tauref,   &
-                                 zmmean, dist_sol, rmco2, rmo3, v_phot)
+      subroutine photolysis_asis(nlayer, ngrid,                    &
+                                 lswitch, press, temp, sza,fractcol, tauref,   &
+                                 zmmean, dist_sol, rmco2, rmo3, rmch4, v_phot, e_phot, nreact, three_prod)
 
 !==========================================================================
@@ -9,8 +9,10 @@
       use comcstfi_mod
       use callkeys_mod
+      use types_asis
+      use chimiedata_h
 
       implicit none
 
-#include "chimiedata.h" 
+!#include "chimiedata.h" 
 
 !==========================================================================
@@ -19,5 +21,5 @@
        
       integer, intent(in) :: nlayer ! number of atmospheric layers
-      integer,intent(in) :: ngrid   ! number of atmospheric columns
+      integer, intent(in) :: ngrid  ! number of atmospheric columns
       integer :: lswitch            ! interface level between chemistries
       real :: press(nlayer)         ! pressure (hPa)
@@ -26,8 +28,11 @@
       real :: fractcol              ! day fraction
       real :: tauref                ! optical depth at 7 hpa
-      real :: zmmean(nlayer)        ! mean molecular mass (g)
+      real :: zmmean(nlayer)        ! mean molecular mass (g/mol)
       real :: dist_sol              ! sun distance (AU) 
       real :: rmco2(nlayer)         ! co2 mixing ratio
       real :: rmo3(nlayer)          ! ozone mixing ratio
+      real :: rmch4(nlayer)         ! ch4 mixing ratio
+      integer, intent(in) :: nreact             ! number of reactions in reactions files
+      logical, intent(in) :: three_prod(nreact) ! if the reaction have a three defferent products egal .true.
 
 !==========================================================================
@@ -36,4 +41,5 @@
 
       real (kind = 8), dimension(nlayer,nb_phot_max) :: v_phot
+      real (kind = 8), dimension(nlayer,nb_phot_max) :: e_phot
 
 !==========================================================================
@@ -42,24 +48,21 @@
 
       integer :: icol, ij, indsza, indtau, indcol, indozo, indtemp,     &
-                 iozo, isza, itau, it, l
-
-      integer :: j_o2_o, j_o2_o1d, j_co2_o, j_co2_o1d, j_o3_o1d,        &
-                 j_o3_o, j_h2o, j_hdo, j_h2o2, j_ho2, j_no, j_no2,      &
-                 j_hno3, j_hno4,                                        &
-                 j_ch4_ch3_h, j_ch4_1ch2_h2, j_ch4_3ch2_h_h,            &
-                 j_ch4_ch_h2_h, j_ch3o2h, j_ch2o_hco, j_ch2o_co,        &
-                 j_ch3oh, j_c2h6, j_hcl, j_hocl, j_clo, j_so2, j_so,    &
-                 j_h2s, j_so3
+                 iozo, isza, itau, it, ich4, indch4, l, nb_phot 
 
       real :: col(nlayer)                 ! overhead air column   (molecule cm-2)
       real :: colo3(nlayer)               ! overhead ozone column (molecule cm-2)
-      real :: poids(2,2,2,2,2)            ! 5D interpolation weights 
+      real :: colch4(nlayer)               ! overhead CH4 column (molecule cm-2)
+      real :: tauch4(nlayer)               ! estimation of optical depth by CH4
+      real :: ch4_equ(nlayer)               ! equivalent constant mixing ratio for the same column of CH4
+      real :: poids(2,2,2,2,2,2)          ! 6D interpolation weights 
       real :: tref                        ! temperature  at 1.9 hPa in the gcm (K)
       real :: table_temp(ntemp)           ! temperatures at 1.9 hPa in jmars   (K)
-      real :: cinf, csup, cicol, ciozo, cisza, citemp, citau
+      real :: ch4ref                      ! ch4 mixing ratio at top of the atmosphere
+      real :: cinf, csup, cicol, ciozo, cisza, citemp, citau, cich4
       real :: colo3min, dp, coef
       real :: ratio_o3(nlayer)
       real :: tau
       real :: j(nlayer,nd)
+      real :: e(nlayer,nd)
 
 !==========================================================================
@@ -73,8 +76,11 @@
 !==========================================================================
       
-      table_temp(1) = 226.2
-      table_temp(2) = 206.2
-      table_temp(3) = 186.2
-      table_temp(4) = 169.8
+!      table_temp(1) = 226.2
+!      table_temp(2) = 206.2
+!      table_temp(3) = 186.2
+!      table_temp(4) = 169.8
+
+!      table_temp(2) = 186.2
+      table_temp(1) = 176.2
 
 !==========================================================================
@@ -90,6 +96,12 @@
          end if
       end do
-      cisza = (sza - szatab(indsza))  &
+
+      if(nsza.eq.1) then
+        cisza = 0.
+        indsza=1
+      else
+        cisza = (sza - szatab(indsza))  &
              /(szatab(indsza + 1) - szatab(indsza))
+      endif
 
 !==========================================================================
@@ -108,43 +120,100 @@
          end if
       end do
-      citau = (tau - tautab(indtau))     &
+
+      if(ntau.eq.1) then
+        citau=0.
+        indtau=1
+      else
+        citau = (tau - tautab(indtau))     &
              /(tautab(indtau + 1) - tautab(indtau))
-
-!==========================================================================
-!     co2 and ozone columns
+      endif
+
+
+
+!==========================================================================
+!     air and ozone columns
 !==========================================================================
 
 !     co2 column at model top (molecule.cm-2)
 
-      col(lswitch-1) = 6.022e22*rmco2(lswitch-1)*press(lswitch-1)*100.  &
-                       /(zmmean(lswitch-1)*g)
+!      col(lswitch-1) = 6.022e22*rmco2(lswitch-1)*press(lswitch-1)*100.  &
+!                       /(zmmean(lswitch-1)*g)
+      col(lswitch-1) = 6.022e22*press(lswitch-1)*100./(zmmean(lswitch-1)*g)
+
 
 !     ozone column at model top
 
       colo3(lswitch-1) = 0.
-
 !     co2 and ozone columns for other levels (molecule.cm-2)
 
       do l = lswitch-2,1,-1
          dp = (press(l) - press(l+1))*100.
-         col(l) = col(l+1) + (rmco2(l+1) + rmco2(l))*0.5   &
-                             *6.022e22*dp/(zmmean(l)*g)
+!         col(l) = col(l+1) + (rmco2(l+1) + rmco2(l))*0.5   &
+!                             *6.022e22*dp/(zmmean(l)*g)
+         col(l) = col(l+1) +  6.022e22*dp/(zmmean(l)*g)
          col(l) = min(col(l), colairtab(1))
          colo3(l) = colo3(l+1) + (rmo3(l+1) + rmo3(l))*0.5 &
                                  *6.022e22*dp/(zmmean(l)*g)
-      end do
-
-!     ratio ozone column/minimal theoretical column (0.1 micron-atm) 
-
-!     ro3 = 7.171e-10 is the o3 mixing ratio for a uniform
-!     profile giving a column 0.1 micron-atmosphere at
-!     a surface pressure of 10 hpa.
+
+      end do
+
+!     ratio ozone column/minimal theoretical column (10 micron-atm) 
+
+!     ro3 = 1.227e-10 is the o3 mixing ratio for a uniform
+!     profile giving a column 10 micron-atmosphere at
+!     a surface pressure of 1 bar.
 
       do l = 1,lswitch-1
-         colo3min    = col(l)*7.171e-10
+!         colo3min    = col(l)*7.171e-10
+         colo3min    = col(l)*1.227e-10*(g/9.81)*(mugaz/28)
          ratio_o3(l) = colo3(l)/colo3min
-         ratio_o3(l) = min(ratio_o3(l), table_ozo(nozo)*10.)
-         ratio_o3(l) = max(ratio_o3(l), 1.)
-      end do
+         ratio_o3(l) = min(ratio_o3(l), table_ozo(nozo))
+         ratio_o3(l) = max(ratio_o3(l), 0.)
+      end do
+
+!      print*,'co3(1)=',colo3(1)
+!      print*,'col(1)=',col(1)
+!      print*,'ratio_o3(1)=',ratio_o3(1)
+!      print*,'maxval(ratio_o3)=',maxval(ratio_o3(:))
+!      print*,'maxval(ozo)=',table_ozo(nozo)/10.
+
+!==========================================================================
+!     ch4 dependence
+!==========================================================================
+
+!     1) search for temperature at 1.9 hPa (tref): vertical
+!     interpolation
+
+      ch4ref = rmch4(lswitch-2)
+      colch4(lswitch-1) = 0.
+      ch4_equ(lswitch-1) = 0.
+      do l = lswitch-2,1,-1
+         dp = (press(l) - press(l+1))*100.
+         colch4(l) = colch4(l+1) + (rmch4(l+1) + rmch4(l))*0.5 &
+                                 *6.022e22*dp/(zmmean(l)*g)
+         ch4_equ(l)=colch4(l)/col(l)
+!         tauch4(l)=1.8e-21*colch4(l)
+!         if(tauch4(l).ge.1.0) exit
+      end do
+!      ch4ref = (rmch4(l+1)*(tauch4(l)-1)+rmch4(l)*(1-tauch4(l+1))) &
+!                                 /(tauch4(l)-tauch4(l+1))
+
+!     2) interpolation in CH4
+
+!      ch4ref = min(ch4ref,table_ch4(nch4))
+!      ch4ref = max(ch4ref,table_ch4(1))
+
+!      indch4 = nch4 - 1
+!      do ich4 = 1,nch4
+!         if (table_ch4(ich4) >= ch4ref) then
+!            indch4 = ich4 - 1
+!            indch4 = max(indch4, 1)
+!            exit
+!         end if
+!      end do
+!      cich4 = (ch4ref - table_ch4(indch4))     &
+!             /(table_ch4(indch4 + 1) - table_ch4(indch4))
+
+
 
 !==========================================================================
@@ -169,12 +238,19 @@
       tref = max(tref,table_temp(ntemp))
 
-      do it = 2, ntemp
-         if (table_temp(it) <= tref) then
-            citemp = (log(tref) - log(table_temp(it)))              &
-                    /(log(table_temp(it-1)) - log(table_temp(it)))
-            indtemp = it - 1
-            exit
-         end if
-      end do
+      if(ntemp.eq.1) then
+        citemp = 1.
+        indtemp = 1
+      else
+        do it = 2, ntemp
+           if (table_temp(it) <= tref) then
+              citemp = (log(tref) - log(table_temp(it)))              &
+                      /(log(table_temp(it-1)) - log(table_temp(it)))
+              indtemp = it - 1
+              exit
+           end if
+        end do
+      endif
+
+
 
 !==========================================================================
@@ -200,5 +276,5 @@
          indozo = nozo - 1
          do iozo = 1,nozo
-            if (table_ozo(iozo)*10. >= ratio_o3(l)) then
+            if (table_ozo(iozo) >= ratio_o3(l)) then
                indozo = iozo - 1
                indozo = max(indozo, 1)
@@ -206,83 +282,259 @@
             end if
          end do
-         ciozo = (ratio_o3(l) - table_ozo(indozo)*10.)             &
-                /(table_ozo(indozo + 1)*10. - table_ozo(indozo)*10.)
-
-!     4-dimensional interpolation weights
-
-!     poids(temp,sza,co2,o3,tau)
-
-         poids(1,1,1,1,1) = citemp*(1.-cisza)*cicol*(1.-ciozo)*(1.-citau)
-         poids(1,1,1,2,1) = citemp*(1.-cisza)*cicol*ciozo*(1.-citau)
-         poids(1,1,2,1,1) = citemp*(1.-cisza)*(1.-cicol)*(1.-ciozo)*(1.-citau)
-         poids(1,1,2,2,1) = citemp*(1.-cisza)*(1.-cicol)*ciozo*(1.-citau)
-         poids(1,2,1,1,1) = citemp*cisza*cicol*(1.-ciozo)*(1.-citau)
-         poids(1,2,1,2,1) = citemp*cisza*cicol*ciozo*(1.-citau)
-         poids(1,2,2,1,1) = citemp*cisza*(1.-cicol)*(1.-ciozo)*(1.-citau)
-         poids(1,2,2,2,1) = citemp*cisza*(1.-cicol)*ciozo*(1.-citau)
-         poids(2,1,1,1,1) = (1.-citemp)*(1.-cisza)*cicol*(1.-ciozo)*(1.-citau)
-         poids(2,1,1,2,1) = (1.-citemp)*(1.-cisza)*cicol*ciozo*(1.-citau)
-         poids(2,1,2,1,1) = (1.-citemp)*(1.-cisza)*(1.-cicol)*(1.-ciozo)*(1.-citau)
-         poids(2,1,2,2,1) = (1.-citemp)*(1.-cisza)*(1.-cicol)*ciozo*(1.-citau)
-         poids(2,2,1,1,1) = (1.-citemp)*cisza*cicol*(1.-ciozo)*(1.-citau)
-         poids(2,2,1,2,1) = (1.-citemp)*cisza*cicol*ciozo*(1.-citau)
-         poids(2,2,2,1,1) = (1.-citemp)*cisza*(1.-cicol)*(1.-ciozo)*(1.-citau)
-         poids(2,2,2,2,1) = (1.-citemp)*cisza*(1.-cicol)*ciozo*(1.-citau)
-!
-         poids(1,1,1,1,2) = citemp*(1.-cisza)*cicol*(1.-ciozo)*citau
-         poids(1,1,1,2,2) = citemp*(1.-cisza)*cicol*ciozo*citau
-         poids(1,1,2,1,2) = citemp*(1.-cisza)*(1.-cicol)*(1.-ciozo)*citau
-         poids(1,1,2,2,2) = citemp*(1.-cisza)*(1.-cicol)*ciozo*citau
-         poids(1,2,1,1,2) = citemp*cisza*cicol*(1.-ciozo)*citau
-         poids(1,2,1,2,2) = citemp*cisza*cicol*ciozo*citau
-         poids(1,2,2,1,2) = citemp*cisza*(1.-cicol)*(1.-ciozo)*citau
-         poids(1,2,2,2,2) = citemp*cisza*(1.-cicol)*ciozo*citau
-         poids(2,1,1,1,2) = (1.-citemp)*(1.-cisza)*cicol*(1.-ciozo)*citau
-         poids(2,1,1,2,2) = (1.-citemp)*(1.-cisza)*cicol*ciozo*citau
-         poids(2,1,2,1,2) = (1.-citemp)*(1.-cisza)*(1.-cicol)*(1.-ciozo)*citau
-         poids(2,1,2,2,2) = (1.-citemp)*(1.-cisza)*(1.-cicol)*ciozo*citau
-         poids(2,2,1,1,2) = (1.-citemp)*cisza*cicol*(1.-ciozo)*citau
-         poids(2,2,1,2,2) = (1.-citemp)*cisza*cicol*ciozo*citau
-         poids(2,2,2,1,2) = (1.-citemp)*cisza*(1.-cicol)*(1.-ciozo)*citau
-         poids(2,2,2,2,2) = (1.-citemp)*cisza*(1.-cicol)*ciozo*citau
+
+      if(nozo.eq.1) then
+         ciozo = 0.
+      else
+         ciozo = (ratio_o3(l) - table_ozo(indozo))             &
+                /(table_ozo(indozo + 1) - table_ozo(indozo))
+      endif
+
+!     2) interpolation in CH4
+
+      ch4ref = min(ch4_equ(l),table_ch4(nch4))
+      ch4ref = max(ch4ref,table_ch4(1))
+
+      indch4 = nch4 - 1
+      do ich4 = 1,nch4
+         if (table_ch4(ich4) >= ch4ref) then
+            indch4 = ich4 - 1
+            indch4 = max(indch4, 1)
+            exit
+         end if
+      end do
+      if(nch4.eq.1) then
+        cich4=0.
+        indch4=1
+      else
+        cich4 = (ch4ref - table_ch4(indch4))     &
+               /(table_ch4(indch4 + 1) - table_ch4(indch4))
+      endif
+
+!     5-dimensional interpolation weights
+
+!     poids(temp,sza,co2,o3,tau,ch4)
+
+         poids(1,1,1,1,1,1) = citemp*(1.-cisza)*cicol*(1.-ciozo)*(1.-citau)*(1.-cich4)
+         poids(1,1,1,2,1,1) = citemp*(1.-cisza)*cicol*ciozo*(1.-citau)*(1.-cich4)       
+         poids(1,1,2,1,1,1) = citemp*(1.-cisza)*(1.-cicol)*(1.-ciozo)*(1.-citau)*(1.-cich4)
+         poids(1,1,2,2,1,1) = citemp*(1.-cisza)*(1.-cicol)*ciozo*(1.-citau)*(1.-cich4) 
+         poids(1,2,1,1,1,1) = citemp*cisza*cicol*(1.-ciozo)*(1.-citau)*(1.-cich4)               
+         poids(1,2,1,2,1,1) = citemp*cisza*cicol*ciozo*(1.-citau)*(1.-cich4)                    
+         poids(1,2,2,1,1,1) = citemp*cisza*(1.-cicol)*(1.-ciozo)*(1.-citau)*(1.-cich4)          
+         poids(1,2,2,2,1,1) = citemp*cisza*(1.-cicol)*ciozo*(1.-citau)*(1.-cich4)               
+!         poids(2,1,1,1,1,1) = (1.-citemp)*(1.-cisza)*cicol*(1.-ciozo)*(1.-citau)*(1.-cich4)     
+!         poids(2,1,1,2,1,1) = (1.-citemp)*(1.-cisza)*cicol*ciozo*(1.-citau)*(1.-cich4)          
+!         poids(2,1,2,1,1,1) = (1.-citemp)*(1.-cisza)*(1.-cicol)*(1.-ciozo)*(1.-citau)*(1.-cich4)
+!         poids(2,1,2,2,1,1) = (1.-citemp)*(1.-cisza)*(1.-cicol)*ciozo*(1.-citau)*(1.-cich4)     
+!         poids(2,2,1,1,1,1) = (1.-citemp)*cisza*cicol*(1.-ciozo)*(1.-citau)*(1.-cich4)          
+!         poids(2,2,1,2,1,1) = (1.-citemp)*cisza*cicol*ciozo*(1.-citau)*(1.-cich4)               
+!         poids(2,2,2,1,1,1) = (1.-citemp)*cisza*(1.-cicol)*(1.-ciozo)*(1.-citau)*(1.-cich4)     
+!         poids(2,2,2,2,1,1) = (1.-citemp)*cisza*(1.-cicol)*ciozo*(1.-citau)*(1.-cich4)          
+!!
+!         poids(1,1,1,1,2,1) = citemp*(1.-cisza)*cicol*(1.-ciozo)*citau*(1.-cich4)               
+!         poids(1,1,1,2,2,1) = citemp*(1.-cisza)*cicol*ciozo*citau*(1.-cich4)                    
+!         poids(1,1,2,1,2,1) = citemp*(1.-cisza)*(1.-cicol)*(1.-ciozo)*citau*(1.-cich4)          
+!         poids(1,1,2,2,2,1) = citemp*(1.-cisza)*(1.-cicol)*ciozo*citau*(1.-cich4)               
+!         poids(1,2,1,1,2,1) = citemp*cisza*cicol*(1.-ciozo)*citau*(1.-cich4)                    
+!         poids(1,2,1,2,2,1) = citemp*cisza*cicol*ciozo*citau*(1.-cich4)                         
+!         poids(1,2,2,1,2,1) = citemp*cisza*(1.-cicol)*(1.-ciozo)*citau*(1.-cich4)               
+!         poids(1,2,2,2,2,1) = citemp*cisza*(1.-cicol)*ciozo*citau*(1.-cich4)                    
+!         poids(2,1,1,1,2,1) = (1.-citemp)*(1.-cisza)*cicol*(1.-ciozo)*citau*(1.-cich4)          
+!         poids(2,1,1,2,2,1) = (1.-citemp)*(1.-cisza)*cicol*ciozo*citau*(1.-cich4)               
+!         poids(2,1,2,1,2,1) = (1.-citemp)*(1.-cisza)*(1.-cicol)*(1.-ciozo)*citau*(1.-cich4)     
+!         poids(2,1,2,2,2,1) = (1.-citemp)*(1.-cisza)*(1.-cicol)*ciozo*citau*(1.-cich4)          
+!         poids(2,2,1,1,2,1) = (1.-citemp)*cisza*cicol*(1.-ciozo)*citau*(1.-cich4)               
+!         poids(2,2,1,2,2,1) = (1.-citemp)*cisza*cicol*ciozo*citau*(1.-cich4)                    
+!         poids(2,2,2,1,2,1) = (1.-citemp)*cisza*(1.-cicol)*(1.-ciozo)*citau*(1.-cich4)          
+!         poids(2,2,2,2,2,1) = (1.-citemp)*cisza*(1.-cicol)*ciozo*citau*(1.-cich4)               
+!      
+         poids(1,1,1,1,1,2) = citemp*(1.-cisza)*cicol*(1.-ciozo)*(1.-citau)*cich4               
+         poids(1,1,1,2,1,2) = citemp*(1.-cisza)*cicol*ciozo*(1.-citau)*cich4                    
+         poids(1,1,2,1,1,2) = citemp*(1.-cisza)*(1.-cicol)*(1.-ciozo)*(1.-citau)*cich4          
+         poids(1,1,2,2,1,2) = citemp*(1.-cisza)*(1.-cicol)*ciozo*(1.-citau)*cich4               
+         poids(1,2,1,1,1,2) = citemp*cisza*cicol*(1.-ciozo)*(1.-citau)*cich4                    
+         poids(1,2,1,2,1,2) = citemp*cisza*cicol*ciozo*(1.-citau)*cich4                         
+         poids(1,2,2,1,1,2) = citemp*cisza*(1.-cicol)*(1.-ciozo)*(1.-citau)*cich4               
+         poids(1,2,2,2,1,2) = citemp*cisza*(1.-cicol)*ciozo*(1.-citau)*cich4                    
+!         poids(2,1,1,1,1,2) = (1.-citemp)*(1.-cisza)*cicol*(1.-ciozo)*(1.-citau)*cich4          
+!         poids(2,1,1,2,1,2) = (1.-citemp)*(1.-cisza)*cicol*ciozo*(1.-citau)*cich4               
+!         poids(2,1,2,1,1,2) = (1.-citemp)*(1.-cisza)*(1.-cicol)*(1.-ciozo)*(1.-citau)*cich4     
+!         poids(2,1,2,2,1,2) = (1.-citemp)*(1.-cisza)*(1.-cicol)*ciozo*(1.-citau)*cich4          
+!         poids(2,2,1,1,1,2) = (1.-citemp)*cisza*cicol*(1.-ciozo)*(1.-citau)*cich4               
+!         poids(2,2,1,2,1,2) = (1.-citemp)*cisza*cicol*ciozo*(1.-citau)*cich4                    
+!         poids(2,2,2,1,1,2) = (1.-citemp)*cisza*(1.-cicol)*(1.-ciozo)*(1.-citau)*cich4          
+!         poids(2,2,2,2,1,2) = (1.-citemp)*cisza*(1.-cicol)*ciozo*(1.-citau)*cich4               
+!!
+!         poids(1,1,1,1,2,2) = citemp*(1.-cisza)*cicol*(1.-ciozo)*citau*cich4                    
+!         poids(1,1,1,2,2,2) = citemp*(1.-cisza)*cicol*ciozo*citau*cich4                         
+!         poids(1,1,2,1,2,2) = citemp*(1.-cisza)*(1.-cicol)*(1.-ciozo)*citau*cich4               
+!         poids(1,1,2,2,2,2) = citemp*(1.-cisza)*(1.-cicol)*ciozo*citau*cich4                    
+!         poids(1,2,1,1,2,2) = citemp*cisza*cicol*(1.-ciozo)*citau*cich4                         
+!         poids(1,2,1,2,2,2) = citemp*cisza*cicol*ciozo*citau*cich4                              
+!         poids(1,2,2,1,2,2) = citemp*cisza*(1.-cicol)*(1.-ciozo)*citau*cich4                    
+!         poids(1,2,2,2,2,2) = citemp*cisza*(1.-cicol)*ciozo*citau*cich4                         
+!         poids(2,1,1,1,2,2) = (1.-citemp)*(1.-cisza)*cicol*(1.-ciozo)*citau*cich4               
+!         poids(2,1,1,2,2,2) = (1.-citemp)*(1.-cisza)*cicol*ciozo*citau*cich4                    
+!         poids(2,1,2,1,2,2) = (1.-citemp)*(1.-cisza)*(1.-cicol)*(1.-ciozo)*citau*cich4          
+!         poids(2,1,2,2,2,2) = (1.-citemp)*(1.-cisza)*(1.-cicol)*ciozo*citau*cich4               
+!         poids(2,2,1,1,2,2) = (1.-citemp)*cisza*cicol*(1.-ciozo)*citau*cich4                    
+!         poids(2,2,1,2,2,2) = (1.-citemp)*cisza*cicol*ciozo*citau*cich4                         
+!         poids(2,2,2,1,2,2) = (1.-citemp)*cisza*(1.-cicol)*(1.-ciozo)*citau*cich4               
+!         poids(2,2,2,2,2,2) = (1.-citemp)*cisza*(1.-cicol)*ciozo*citau*cich4                    
+
+
+
+
+
+
+
 
 !     4-dimensional interpolation in the lookup table
 
          do ij = 1,nd
-            j(l,ij) =                                                                & 
-            poids(1,1,1,1,1)*jphot(indtemp,indsza,indcol,indozo,indtau,ij)           &
-          + poids(1,1,1,2,1)*jphot(indtemp,indsza,indcol,indozo+1,indtau,ij)         &
-          + poids(1,1,2,1,1)*jphot(indtemp,indsza,indcol+1,indozo,indtau,ij)         &
-          + poids(1,1,2,2,1)*jphot(indtemp,indsza,indcol+1,indozo+1,indtau,ij)       &
-          + poids(1,2,1,1,1)*jphot(indtemp,indsza+1,indcol,indozo,indtau,ij)         &
-          + poids(1,2,1,2,1)*jphot(indtemp,indsza+1,indcol,indozo+1,indtau,ij)       &
-          + poids(1,2,2,1,1)*jphot(indtemp,indsza+1,indcol+1,indozo,indtau,ij)       &
-          + poids(1,2,2,2,1)*jphot(indtemp,indsza+1,indcol+1,indozo+1,indtau,ij)     &
-          + poids(2,1,1,1,1)*jphot(indtemp+1,indsza,indcol,indozo,indtau,ij)         &
-          + poids(2,1,1,2,1)*jphot(indtemp+1,indsza,indcol,indozo+1,indtau,ij)       &
-          + poids(2,1,2,1,1)*jphot(indtemp+1,indsza,indcol+1,indozo,indtau,ij)       &
-          + poids(2,1,2,2,1)*jphot(indtemp+1,indsza,indcol+1,indozo+1,indtau,ij)     &
-          + poids(2,2,1,1,1)*jphot(indtemp+1,indsza+1,indcol,indozo,indtau,ij)       &
-          + poids(2,2,1,2,1)*jphot(indtemp+1,indsza+1,indcol,indozo+1,indtau,ij)     &
-          + poids(2,2,2,1,1)*jphot(indtemp+1,indsza+1,indcol+1,indozo,indtau,ij)     &
-          + poids(2,2,2,2,1)*jphot(indtemp+1,indsza+1,indcol+1,indozo+1,indtau,ij)   &
-!
-          + poids(1,1,1,1,2)*jphot(indtemp,indsza,indcol,indozo,indtau+1,ij)         &
-          + poids(1,1,1,2,2)*jphot(indtemp,indsza,indcol,indozo+1,indtau+1,ij)       &
-          + poids(1,1,2,1,2)*jphot(indtemp,indsza,indcol+1,indozo,indtau+1,ij)       &
-          + poids(1,1,2,2,2)*jphot(indtemp,indsza,indcol+1,indozo+1,indtau+1,ij)     &
-          + poids(1,2,1,1,2)*jphot(indtemp,indsza+1,indcol,indozo,indtau+1,ij)       &
-          + poids(1,2,1,2,2)*jphot(indtemp,indsza+1,indcol,indozo+1,indtau+1,ij)     &
-          + poids(1,2,2,1,2)*jphot(indtemp,indsza+1,indcol+1,indozo,indtau+1,ij)     &
-          + poids(1,2,2,2,2)*jphot(indtemp,indsza+1,indcol+1,indozo+1,indtau+1,ij)   &
-          + poids(2,1,1,1,2)*jphot(indtemp+1,indsza,indcol,indozo,indtau+1,ij)       &
-          + poids(2,1,1,2,2)*jphot(indtemp+1,indsza,indcol,indozo+1,indtau+1,ij)     &
-          + poids(2,1,2,1,2)*jphot(indtemp+1,indsza,indcol+1,indozo,indtau+1,ij)     &
-          + poids(2,1,2,2,2)*jphot(indtemp+1,indsza,indcol+1,indozo+1,indtau+1,ij)   &
-          + poids(2,2,1,1,2)*jphot(indtemp+1,indsza+1,indcol,indozo,indtau+1,ij)     &
-          + poids(2,2,1,2,2)*jphot(indtemp+1,indsza+1,indcol,indozo+1,indtau+1,ij)   &
-          + poids(2,2,2,1,2)*jphot(indtemp+1,indsza+1,indcol+1,indozo,indtau+1,ij)   &
-          + poids(2,2,2,2,2)*jphot(indtemp+1,indsza+1,indcol+1,indozo+1,indtau+1,ij)
+            j(l,ij) =                                                                         & 
+            poids(1,1,1,1,1,1)*jphot(indtemp,indsza,indcol,indozo,indtau,indch4,ij)           &
+          + poids(1,1,1,2,1,1)*jphot(indtemp,indsza,indcol,indozo+1,indtau,indch4,ij)         &
+          + poids(1,1,2,1,1,1)*jphot(indtemp,indsza,indcol+1,indozo,indtau,indch4,ij)         &
+          + poids(1,1,2,2,1,1)*jphot(indtemp,indsza,indcol+1,indozo+1,indtau,indch4,ij)       &
+          + poids(1,2,1,1,1,1)*jphot(indtemp,indsza+1,indcol,indozo,indtau,indch4,ij)         &
+          + poids(1,2,1,2,1,1)*jphot(indtemp,indsza+1,indcol,indozo+1,indtau,indch4,ij)       &
+          + poids(1,2,2,1,1,1)*jphot(indtemp,indsza+1,indcol+1,indozo,indtau,indch4,ij)       &
+          + poids(1,2,2,2,1,1)*jphot(indtemp,indsza+1,indcol+1,indozo+1,indtau,indch4,ij)     &
+!          + poids(2,1,1,1,1,1)*jphot(indtemp+1,indsza,indcol,indozo,indtau,indch4,ij)         &
+!          + poids(2,1,1,2,1,1)*jphot(indtemp+1,indsza,indcol,indozo+1,indtau,indch4,ij)       &
+!          + poids(2,1,2,1,1,1)*jphot(indtemp+1,indsza,indcol+1,indozo,indtau,indch4,ij)       &
+!          + poids(2,1,2,2,1,1)*jphot(indtemp+1,indsza,indcol+1,indozo+1,indtau,indch4,ij)     &
+!          + poids(2,2,1,1,1,1)*jphot(indtemp+1,indsza+1,indcol,indozo,indtau,indch4,ij)       &
+!          + poids(2,2,1,2,1,1)*jphot(indtemp+1,indsza+1,indcol,indozo+1,indtau,indch4,ij)     &
+!          + poids(2,2,2,1,1,1)*jphot(indtemp+1,indsza+1,indcol+1,indozo,indtau,indch4,ij)     &
+!          + poids(2,2,2,2,1,1)*jphot(indtemp+1,indsza+1,indcol+1,indozo+1,indtau,indch4,ij)   &
+!!
+!          + poids(1,1,1,1,2,1)*jphot(indtemp,indsza,indcol,indozo,indtau+1,indch4,ij)         &
+!          + poids(1,1,1,2,2,1)*jphot(indtemp,indsza,indcol,indozo+1,indtau+1,indch4,ij)       &
+!          + poids(1,1,2,1,2,1)*jphot(indtemp,indsza,indcol+1,indozo,indtau+1,indch4,ij)       &
+!          + poids(1,1,2,2,2,1)*jphot(indtemp,indsza,indcol+1,indozo+1,indtau+1,indch4,ij)     &
+!          + poids(1,2,1,1,2,1)*jphot(indtemp,indsza+1,indcol,indozo,indtau+1,indch4,ij)       &
+!          + poids(1,2,1,2,2,1)*jphot(indtemp,indsza+1,indcol,indozo+1,indtau+1,indch4,ij)     &
+!          + poids(1,2,2,1,2,1)*jphot(indtemp,indsza+1,indcol+1,indozo,indtau+1,indch4,ij)     &
+!          + poids(1,2,2,2,2,1)*jphot(indtemp,indsza+1,indcol+1,indozo+1,indtau+1,indch4,ij)   &
+!          + poids(2,1,1,1,2,1)*jphot(indtemp+1,indsza,indcol,indozo,indtau+1,indch4,ij)       &
+!          + poids(2,1,1,2,2,1)*jphot(indtemp+1,indsza,indcol,indozo+1,indtau+1,indch4,ij)     &
+!          + poids(2,1,2,1,2,1)*jphot(indtemp+1,indsza,indcol+1,indozo,indtau+1,indch4,ij)     &
+!          + poids(2,1,2,2,2,1)*jphot(indtemp+1,indsza,indcol+1,indozo+1,indtau+1,indch4,ij)   &
+!          + poids(2,2,1,1,2,1)*jphot(indtemp+1,indsza+1,indcol,indozo,indtau+1,indch4,ij)     &
+!          + poids(2,2,1,2,2,1)*jphot(indtemp+1,indsza+1,indcol,indozo+1,indtau+1,indch4,ij)   &
+!          + poids(2,2,2,1,2,1)*jphot(indtemp+1,indsza+1,indcol+1,indozo,indtau+1,indch4,ij)   &
+!          + poids(2,2,2,2,2,1)*jphot(indtemp+1,indsza+1,indcol+1,indozo+1,indtau+1,indch4,ij)
+! CH4
+          + poids(1,1,1,1,1,2)*jphot(indtemp,indsza,indcol,indozo,indtau,indch4+1,ij)         &
+          + poids(1,1,1,2,1,2)*jphot(indtemp,indsza,indcol,indozo+1,indtau,indch4+1,ij)       &
+          + poids(1,1,2,1,1,2)*jphot(indtemp,indsza,indcol+1,indozo,indtau,indch4+1,ij)       &
+          + poids(1,1,2,2,1,2)*jphot(indtemp,indsza,indcol+1,indozo+1,indtau,indch4+1,ij)     &
+          + poids(1,2,1,1,1,2)*jphot(indtemp,indsza+1,indcol,indozo,indtau,indch4+1,ij)       &
+          + poids(1,2,1,2,1,2)*jphot(indtemp,indsza+1,indcol,indozo+1,indtau,indch4+1,ij)     &
+          + poids(1,2,2,1,1,2)*jphot(indtemp,indsza+1,indcol+1,indozo,indtau,indch4+1,ij)     &
+          + poids(1,2,2,2,1,2)*jphot(indtemp,indsza+1,indcol+1,indozo+1,indtau,indch4+1,ij) 
+!          + poids(2,1,1,1,1,2)*jphot(indtemp+1,indsza,indcol,indozo,indtau,indch4+1,ij) &
+!          + poids(2,1,1,2,1,2)*jphot(indtemp+1,indsza,indcol,indozo+1,indtau,indch4+1,ij) &
+!          + poids(2,1,2,1,1,2)*jphot(indtemp+1,indsza,indcol+1,indozo,indtau,indch4+1,ij) &
+!          + poids(2,1,2,2,1,2)*jphot(indtemp+1,indsza,indcol+1,indozo+1,indtau,indch4+1,ij) &
+!          + poids(2,2,1,1,1,2)*jphot(indtemp+1,indsza+1,indcol,indozo,indtau,indch4+1,ij) &
+!          + poids(2,2,1,2,1,2)*jphot(indtemp+1,indsza+1,indcol,indozo+1,indtau,indch4+1,ij) &
+!          + poids(2,2,2,1,1,2)*jphot(indtemp+1,indsza+1,indcol+1,indozo,indtau,indch4+1,ij) &
+!          + poids(2,2,2,2,1,2)*jphot(indtemp+1,indsza+1,indcol+1,indozo+1,indtau,indch4+1,ij) &
+!!
+!          + poids(1,1,1,1,2,2)*jphot(indtemp,indsza,indcol,indozo,indtau+1,indch4+1,ij) &
+!          + poids(1,1,1,2,2,2)*jphot(indtemp,indsza,indcol,indozo+1,indtau+1,indch4+1,ij) &
+!          + poids(1,1,2,1,2,2)*jphot(indtemp,indsza,indcol+1,indozo,indtau+1,indch4+1,ij) &
+!          + poids(1,1,2,2,2,2)*jphot(indtemp,indsza,indcol+1,indozo+1,indtau+1,indch4+1,ij) &
+!          + poids(1,2,1,1,2,2)*jphot(indtemp,indsza+1,indcol,indozo,indtau+1,indch4+1,ij) &
+!          + poids(1,2,1,2,2,2)*jphot(indtemp,indsza+1,indcol,indozo+1,indtau+1,indch4+1,ij) &
+!          + poids(1,2,2,1,2,2)*jphot(indtemp,indsza+1,indcol+1,indozo,indtau+1,indch4+1,ij) &
+!          + poids(1,2,2,2,2,2)*jphot(indtemp,indsza+1,indcol+1,indozo+1,indtau+1,indch4+1,ij) &
+!          + poids(2,1,1,1,2,2)*jphot(indtemp+1,indsza,indcol,indozo,indtau+1,indch4+1,ij) &
+!          + poids(2,1,1,2,2,2)*jphot(indtemp+1,indsza,indcol,indozo+1,indtau+1,indch4+1,ij) &
+!          + poids(2,1,2,1,2,2)*jphot(indtemp+1,indsza,indcol+1,indozo,indtau+1,indch4+1,ij) &
+!          + poids(2,1,2,2,2,2)*jphot(indtemp+1,indsza,indcol+1,indozo+1,indtau+1,indch4+1,ij) &
+!          + poids(2,2,1,1,2,2)*jphot(indtemp+1,indsza+1,indcol,indozo,indtau+1,indch4+1,ij) &
+!          + poids(2,2,1,2,2,2)*jphot(indtemp+1,indsza+1,indcol,indozo+1,indtau+1,indch4+1,ij) &
+!          + poids(2,2,2,1,2,2)*jphot(indtemp+1,indsza+1,indcol+1,indozo,indtau+1,indch4+1,ij) &
+!          + poids(2,2,2,2,2,2)*jphot(indtemp+1,indsza+1,indcol+1,indozo+1,indtau+1,indch4+1,ij)
+
          end do
+
+      if (photoheat) then
+         do ij = 1,nd
+            e(l,ij) =                                                                         & 
+            poids(1,1,1,1,1,1)*ephot(indtemp,indsza,indcol,indozo,indtau,indch4,ij)           &
+          + poids(1,1,1,2,1,1)*ephot(indtemp,indsza,indcol,indozo+1,indtau,indch4,ij)         &
+          + poids(1,1,2,1,1,1)*ephot(indtemp,indsza,indcol+1,indozo,indtau,indch4,ij)         &
+          + poids(1,1,2,2,1,1)*ephot(indtemp,indsza,indcol+1,indozo+1,indtau,indch4,ij)       &
+          + poids(1,2,1,1,1,1)*ephot(indtemp,indsza+1,indcol,indozo,indtau,indch4,ij)         &
+          + poids(1,2,1,2,1,1)*ephot(indtemp,indsza+1,indcol,indozo+1,indtau,indch4,ij)       &
+          + poids(1,2,2,1,1,1)*ephot(indtemp,indsza+1,indcol+1,indozo,indtau,indch4,ij)       &
+          + poids(1,2,2,2,1,1)*ephot(indtemp,indsza+1,indcol+1,indozo+1,indtau,indch4,ij)     &
+!          + poids(2,1,1,1,1,1)*ephot(indtemp+1,indsza,indcol,indozo,indtau,indch4,ij)         &
+!          + poids(2,1,1,2,1,1)*ephot(indtemp+1,indsza,indcol,indozo+1,indtau,indch4,ij)       &
+!          + poids(2,1,2,1,1,1)*ephot(indtemp+1,indsza,indcol+1,indozo,indtau,indch4,ij)       &
+!          + poids(2,1,2,2,1,1)*ephot(indtemp+1,indsza,indcol+1,indozo+1,indtau,indch4,ij)     &
+!          + poids(2,2,1,1,1,1)*ephot(indtemp+1,indsza+1,indcol,indozo,indtau,indch4,ij)       &
+!          + poids(2,2,1,2,1,1)*ephot(indtemp+1,indsza+1,indcol,indozo+1,indtau,indch4,ij)     &
+!          + poids(2,2,2,1,1,1)*ephot(indtemp+1,indsza+1,indcol+1,indozo,indtau,indch4,ij)     &
+!          + poids(2,2,2,2,1,1)*ephot(indtemp+1,indsza+1,indcol+1,indozo+1,indtau,indch4,ij)   &
+!!
+!          + poids(1,1,1,1,2,1)*ephot(indtemp,indsza,indcol,indozo,indtau+1,indch4,ij)         &
+!          + poids(1,1,1,2,2,1)*ephot(indtemp,indsza,indcol,indozo+1,indtau+1,indch4,ij)       &
+!          + poids(1,1,2,1,2,1)*ephot(indtemp,indsza,indcol+1,indozo,indtau+1,indch4,ij)       &
+!          + poids(1,1,2,2,2,1)*ephot(indtemp,indsza,indcol+1,indozo+1,indtau+1,indch4,ij)     &
+!          + poids(1,2,1,1,2,1)*ephot(indtemp,indsza+1,indcol,indozo,indtau+1,indch4,ij)       &
+!          + poids(1,2,1,2,2,1)*ephot(indtemp,indsza+1,indcol,indozo+1,indtau+1,indch4,ij)     &
+!          + poids(1,2,2,1,2,1)*ephot(indtemp,indsza+1,indcol+1,indozo,indtau+1,indch4,ij)     &
+!          + poids(1,2,2,2,2,1)*ephot(indtemp,indsza+1,indcol+1,indozo+1,indtau+1,indch4,ij)   &
+!          + poids(2,1,1,1,2,1)*ephot(indtemp+1,indsza,indcol,indozo,indtau+1,indch4,ij)       &
+!          + poids(2,1,1,2,2,1)*ephot(indtemp+1,indsza,indcol,indozo+1,indtau+1,indch4,ij)     &
+!          + poids(2,1,2,1,2,1)*ephot(indtemp+1,indsza,indcol+1,indozo,indtau+1,indch4,ij)     &
+!          + poids(2,1,2,2,2,1)*ephot(indtemp+1,indsza,indcol+1,indozo+1,indtau+1,indch4,ij)   &
+!          + poids(2,2,1,1,2,1)*ephot(indtemp+1,indsza+1,indcol,indozo,indtau+1,indch4,ij)     &
+!          + poids(2,2,1,2,2,1)*ephot(indtemp+1,indsza+1,indcol,indozo+1,indtau+1,indch4,ij)   &
+!          + poids(2,2,2,1,2,1)*ephot(indtemp+1,indsza+1,indcol+1,indozo,indtau+1,indch4,ij)   &
+!          + poids(2,2,2,2,2,1)*ephot(indtemp+1,indsza+1,indcol+1,indozo+1,indtau+1,indch4,ij)
+! CH4
+          + poids(1,1,1,1,1,2)*ephot(indtemp,indsza,indcol,indozo,indtau,indch4+1,ij)         &
+          + poids(1,1,1,2,1,2)*ephot(indtemp,indsza,indcol,indozo+1,indtau,indch4+1,ij)       &
+          + poids(1,1,2,1,1,2)*ephot(indtemp,indsza,indcol+1,indozo,indtau,indch4+1,ij)       &
+          + poids(1,1,2,2,1,2)*ephot(indtemp,indsza,indcol+1,indozo+1,indtau,indch4+1,ij)     &
+          + poids(1,2,1,1,1,2)*ephot(indtemp,indsza+1,indcol,indozo,indtau,indch4+1,ij)       &
+          + poids(1,2,1,2,1,2)*ephot(indtemp,indsza+1,indcol,indozo+1,indtau,indch4+1,ij)     &
+          + poids(1,2,2,1,1,2)*ephot(indtemp,indsza+1,indcol+1,indozo,indtau,indch4+1,ij)     &
+          + poids(1,2,2,2,1,2)*ephot(indtemp,indsza+1,indcol+1,indozo+1,indtau,indch4+1,ij) 
+!          + poids(2,1,1,1,1,2)*ephot(indtemp+1,indsza,indcol,indozo,indtau,indch4+1,ij) &
+!          + poids(2,1,1,2,1,2)*ephot(indtemp+1,indsza,indcol,indozo+1,indtau,indch4+1,ij) &
+!          + poids(2,1,2,1,1,2)*ephot(indtemp+1,indsza,indcol+1,indozo,indtau,indch4+1,ij) &
+!          + poids(2,1,2,2,1,2)*ephot(indtemp+1,indsza,indcol+1,indozo+1,indtau,indch4+1,ij) &
+!          + poids(2,2,1,1,1,2)*ephot(indtemp+1,indsza+1,indcol,indozo,indtau,indch4+1,ij) &
+!          + poids(2,2,1,2,1,2)*ephot(indtemp+1,indsza+1,indcol,indozo+1,indtau,indch4+1,ij) &
+!          + poids(2,2,2,1,1,2)*ephot(indtemp+1,indsza+1,indcol+1,indozo,indtau,indch4+1,ij) &
+!          + poids(2,2,2,2,1,2)*ephot(indtemp+1,indsza+1,indcol+1,indozo+1,indtau,indch4+1,ij) &
+!!
+!          + poids(1,1,1,1,2,2)*ephot(indtemp,indsza,indcol,indozo,indtau+1,indch4+1,ij) &
+!          + poids(1,1,1,2,2,2)*ephot(indtemp,indsza,indcol,indozo+1,indtau+1,indch4+1,ij) &
+!          + poids(1,1,2,1,2,2)*ephot(indtemp,indsza,indcol+1,indozo,indtau+1,indch4+1,ij) &
+!          + poids(1,1,2,2,2,2)*ephot(indtemp,indsza,indcol+1,indozo+1,indtau+1,indch4+1,ij) &
+!          + poids(1,2,1,1,2,2)*ephot(indtemp,indsza+1,indcol,indozo,indtau+1,indch4+1,ij) &
+!          + poids(1,2,1,2,2,2)*ephot(indtemp,indsza+1,indcol,indozo+1,indtau+1,indch4+1,ij) &
+!          + poids(1,2,2,1,2,2)*ephot(indtemp,indsza+1,indcol+1,indozo,indtau+1,indch4+1,ij) &
+!          + poids(1,2,2,2,2,2)*ephot(indtemp,indsza+1,indcol+1,indozo+1,indtau+1,indch4+1,ij) &
+!          + poids(2,1,1,1,2,2)*ephot(indtemp+1,indsza,indcol,indozo,indtau+1,indch4+1,ij) &
+!          + poids(2,1,1,2,2,2)*ephot(indtemp+1,indsza,indcol,indozo+1,indtau+1,indch4+1,ij) &
+!          + poids(2,1,2,1,2,2)*ephot(indtemp+1,indsza,indcol+1,indozo,indtau+1,indch4+1,ij) &
+!          + poids(2,1,2,2,2,2)*ephot(indtemp+1,indsza,indcol+1,indozo+1,indtau+1,indch4+1,ij) &
+!          + poids(2,2,1,1,2,2)*ephot(indtemp+1,indsza+1,indcol,indozo,indtau+1,indch4+1,ij) &
+!          + poids(2,2,1,2,2,2)*ephot(indtemp+1,indsza+1,indcol,indozo+1,indtau+1,indch4+1,ij) &
+!          + poids(2,2,2,1,2,2)*ephot(indtemp+1,indsza+1,indcol+1,indozo,indtau+1,indch4+1,ij) &
+!          + poids(2,2,2,2,2,2)*ephot(indtemp+1,indsza+1,indcol+1,indozo+1,indtau+1,indch4+1,ij)
+
+         end do
+       end if
 
 !     correction for sun distance
@@ -291,13 +543,20 @@
 !            j(l,ij) = j(l,ij)*(1.52/dist_sol)**2.
             j(l,ij) = j(l,ij)*(1.0/dist_sol)**2.
-
+            if (photoheat) e(l,ij) = e(l,ij)*(1.0/dist_sol)**2.
+  
             ! Only during daylight.
             if((ngrid.eq.1))then
-                  j(l,ij)= j(l,ij)* 0.25 ! globally averaged = divide by 4
+                  j(l,ij)= j(l,ij)* 0.25 / cos(sza*pi/180.) ! globally averaged = divide by 4
+                  if (photoheat) e(l,ij)= e(l,ij)* 0.25 / cos(sza*pi/180.) ! globally averaged = divide by 4
             elseif(diurnal .eqv. .false.) then
                   j(l,ij)= j(l,ij) * fractcol
+                  if (photoheat) e(l,ij)= e(l,ij) * fractcol
             endif
+
+
          end do 
 
+
+
 !==========================================================================
 !     end of loop over vertical levels
@@ -313,74 +572,30 @@
 
          j(:,:) = 0.
+         if (photoheat) e(:,:) = 0.
 
       end if
 
-! photodissociation rates numbering in the lookup table
-
-! jmars.20140930
-
-
-      j_o2_o         =  1      ! o2 + hv     -> o + o
-      j_o2_o1d       =  2      ! o2 + hv     -> o + o(1d)
-      j_co2_o        =  3      ! co2 + hv    -> co + o
-      j_co2_o1d      =  4      ! co2 + hv    -> co + o(1d)
-      j_o3_o1d       =  5      ! o3 + hv     -> o2 + o(1d)
-      j_o3_o         =  6      ! o3 + hv     -> o2 + o
-      j_h2o          =  7      ! h2o + hv    -> h + oh
-      j_h2o2         =  8      ! h2o2 + hv   -> oh + oh
-      j_ho2          =  9      ! ho2 + hv    -> oh + o
-      j_no           =  10     ! no + hv     -> n + o
-      j_no2          =  11     ! no2 + hv    -> no + o
-      j_hno3         =  12     ! hno3 + hv   -> no2 + oh
-      j_hno4         =  13     ! hno4 + hv   -> no2 + ho2
-
-! jmars.20111014
-
-!     j_o2_o         =  1      ! o2 + hv     -> o + o
-!     j_o2_o1d       =  2      ! o2 + hv     -> o + o(1d)
-!     j_co2_o        =  3      ! co2 + hv    -> co + o
-!     j_co2_o1d      =  4      ! co2 + hv    -> co + o(1d)
-!     j_o3_o1d       =  5      ! o3 + hv     -> o2 + o(1d)
-!     j_o3_o         =  6      ! o3 + hv     -> o2 + o
-!     j_h2o          =  7      ! h2o + hv    -> h + oh
-!     j_hdo          =  8      ! hdo + hv    -> d + oh
-!     j_h2o2         =  9      ! h2o2 + hv   -> oh + oh
-!     j_ho2          =  10     ! ho2 + hv    -> oh + o
-!     j_no2          =  11     ! no2 + hv    -> no + o
-!     j_ch4_ch3_h    =  12     ! ch4 + hv    -> ch3 + h
-!     j_ch4_1ch2_h2  =  13     ! ch4 + hv    -> 1ch2 + h2
-!     j_ch4_3ch2_h_h =  14     ! ch4 + hv    -> 3ch2 + h + h
-!     j_ch4_ch_h2_h  =  15     ! ch4 + hv    -> ch + h2 + h
-!     j_ch3o2h       =  16     ! ch3o2h + hv -> ch3o + oh
-!     j_ch2o_hco     =  17     ! ch2o + hv   -> h + hco
-!     j_ch2o_co      =  18     ! ch2o + hv   -> h2 + co
-!     j_ch3oh        =  19     ! ch3oh + hv  -> ch3o + h
-!     j_c2h6         =  20     ! c2h6 + hv   -> products
-!     j_hcl          =  21     ! hcl + hv    -> h + cl
-!     j_hocl         =  22     ! hocl + hv   -> oh + cl
-!     j_clo          =  23     ! clo + hv    -> o + cl
-!     j_so2          =  24     ! so2 + hv    -> so + o
-!     j_so           =  25     ! so + hv     -> s + o
-!     j_h2s          =  26     ! h2s + hv    -> hs + s
-!     j_so3          =  27     ! so2 + hv    -> so2 + o
-!     j_hno3         =  28     ! hno3 + hv   -> oh + no2
-!     j_hno4         =  29     ! hno4 + hv   -> ho2 + no2
-
 ! fill v_phot array
 
       v_phot(:,:) = 0.
-
-      do l = 1,lswitch-1
-         v_phot(l, 1) = j(l,j_o2_o)
-         v_phot(l, 2) = j(l,j_o2_o1d)
-         v_phot(l, 3) = j(l,j_co2_o)
-         v_phot(l, 4) = j(l,j_co2_o1d)
-         v_phot(l, 5) = j(l,j_o3_o1d)
-         v_phot(l, 6) = j(l,j_o3_o)
-         v_phot(l, 7) = j(l,j_h2o)
-         v_phot(l, 8) = j(l,j_h2o2)
-         v_phot(l, 9) = j(l,j_ho2)
-         v_phot(l,10) = j(l,j_no)
-         v_phot(l,11) = j(l,j_no2)
+      e_phot(:,:) = 0.
+
+! Order of photolysis reaction has to be the same in monoreact file and the phototable file
+      ij      = 0
+      nb_phot = 0
+      do while(nb_phot<nb_phot_hv_max)
+        ij      = ij + 1
+        nb_phot = nb_phot + 1
+        do l = 1,lswitch-1
+          v_phot(l,nb_phot) = j(l,ij)
+          if (photoheat) e_phot(l,nb_phot) = e(l,ij)
+        end do
+        if (three_prod(ij)) then
+          nb_phot = nb_phot + 1
+          do l = 1,lswitch-1
+            v_phot(l,nb_phot) = j(l,ij)
+            if (photoheat) e_phot(l,nb_phot) = e(l,ij)
+          end do
+        end if
       end do
 
Index: trunk/LMDZ.GENERIC/libf/aeronostd/photolysis_mod.F90
===================================================================
--- trunk/LMDZ.GENERIC/libf/aeronostd/photolysis_mod.F90	(revision 2542)
+++ trunk/LMDZ.GENERIC/libf/aeronostd/photolysis_mod.F90	(revision 2542)
@@ -0,0 +1,1002 @@
+module photolysis_mod
+
+!***********************************************************************
+!
+!   subject:
+!   --------
+!
+!   module for photolysis online
+!
+!   VERSION: Extracted from LMDZ.MARS work of Franck Lefevre (Yassin Jaziri)
+!   April 2019 - Yassin Jaziri add updates generic input (Yassin Jaziri)
+!
+!***********************************************************************
+
+    use types_asis
+    implicit none
+  
+    ! photolysis
+  
+    integer, save :: nabs                      ! number of absorbing gases
+  
+    ! spectral grid
+  
+    integer, save :: nw                        ! number of spectral intervals (low-res)
+    integer, save :: mopt                      ! high-res/low-res switch
+  
+    real, allocatable, save :: wl(:)           ! lower  wavelength for each interval (nm)
+    real, allocatable, save :: wc(:)           ! center wavelength for each interval (nm)
+    real, allocatable, save :: wu(:)           ! upper  wavelength for each interval (nm)
+    real, save :: photoheat_lmax               ! maximum wavelength until photochemical heating is calculated
+  
+    ! solar flux
+  
+    real, allocatable, save :: f(:)            !  solar flux (photon.s-1.nm-1.cm-2) at 1 au
+  
+    ! cross-sections and quantum yields
+  
+    real,    allocatable, save :: qy(:,:)      ! photodissociation yield
+    real,    allocatable, save :: xs(:,:,:)    ! absorption cross-section (cm2)
+    real,    allocatable, save :: sj(:,:,:)    ! general cross-section array by photodissociation yield (cm2)
+    real,    allocatable, save :: xs_temp(:,:) ! absorption cross-section temperature (K)
+    integer, allocatable, save :: tdim(:)      ! absorption cross-section temperature dimension
+    logical, allocatable, save :: jlabelbis(:) ! check in jlabel if the species is included in more than 1 photolysis
+  
+    contains
+  
+    subroutine init_photolysis(nlayer,nreact,three_prod)
+  
+    use tracer_h
+    use chimiedata_h, only: indexchim
+    use ioipsl_getin_p_mod, only: getin_p
+  
+    integer, intent(in) :: nlayer              ! number of atmospheric layers
+    integer, intent(in) :: nreact              ! number of reactions in reactions files
+    logical, intent(in) :: three_prod(nreact)  ! if the reaction have a three defferent products egal .true.
+    integer :: iphot,tdim_max,i3prod,nd,ij,iw,ilay
+    integer :: specheck(nesp)
+  
+    ! initialise on-line photolysis
+  
+    ! mopt = 1 high-resolution
+    ! mopt = 2 low-resolution (recommended for gcm use)
+    ! mopt = 3 input file reading grid
+  
+    mopt = 3
+  
+    ! set wavelength grid
+  
+    call gridw(nw,wl,wc,wu,mopt)
+  
+    allocate(f(nw))
+  
+    ! read and grid solar flux data
+   
+    call rdsolarflux(nw,wl,wc,f)
+  
+    ! read maximum wavelength until photochemical heating is calculated
+    write(*,*) "Maximum wavelength until photochemical heating is calculated"
+    photoheat_lmax=wc(nw-1)         ! default value last point of wavelength grid
+    call getin_p("photoheat_lmax",photoheat_lmax)
+    write(*,*) "photoheat_lmax = ",photoheat_lmax
+  
+    ! calculate nabs number of absorbing gases
+    allocate(jlabelbis(nb_phot_hv_max))
+    nabs = 0
+    specheck(:) = 0
+    jlabelbis(:) = .true.
+    do iphot=1,nb_phot_hv_max
+      if (specheck(indexchim(trim(jlabel(iphot,2)))) .eq. 0) then
+        specheck(indexchim(trim(jlabel(iphot,2)))) = 1
+        nabs = nabs + 1
+      else
+        jlabelbis(iphot) = .false.
+      endif
+    end do
+    nd = nb_hv_max
+  
+    ! Get temperature dimension and allocate
+    allocate(tdim(nd))
+    tdim(:)  = 1
+    tdim_max = 1
+    do iphot=1,nd
+      read(jparamline(iphot),*) tdim(iphot)
+      if (tdim(iphot) > tdim_max) tdim_max = tdim(iphot)
+    end do
+  
+    ! allocation
+    allocate(qy(nw,nd))
+    allocate(xs(tdim_max,nw,nd))
+    allocate(sj(nlayer,nw,nb_phot_hv_max))
+    allocate(xs_temp(tdim_max,nd))
+    xs(:,:,:)    = 0.
+    xs_temp(:,:) = 0.
+  
+    print*, 'WARNING: for all branching photolysis of one specie'
+    print*, '         the cross section files should be the same'
+    print*, '         they are used for optical depths calculation'
+    print*, '         only the quantum yield should be different'
+  
+    i3prod = 0
+  
+    ! read and grid cross-sections (photolysis should be first reactions in monoreact file)
+    do iphot=1,nd
+      call rdxsi(nw,wl,xs(:tdim(iphot),:,iphot),jparamline(iphot),xs_temp(:tdim(iphot),iphot),qy(:,iphot),tdim(iphot),jlabel(iphot+i3prod,2))
+      if (three_prod(iphot)) i3prod = i3prod + 1
+    end do
+  
+    ! init sj for no temperature dependent cross sections (tdim.eq.1)
+    iphot = 0
+    ij    = 0
+    do while(iphot<nb_phot_hv_max)
+       ij = ij + 1
+       iphot = iphot + 1
+       if (tdim(ij).eq.1) then
+         do iw = 1,nw-1
+           do ilay = 1,nlayer
+             sj(ilay,iw,iphot) = xs(1,iw,ij)*qy(iw,ij)
+           end do
+         end do
+       endif
+       if (three_prod(ij)) then
+         iphot = iphot + 1
+         if (tdim(ij).eq.1) then
+           do iw = 1,nw-1
+             do ilay = 1,nlayer
+               sj(ilay,iw,iphot) = sj(ilay,iw,iphot-1)
+             end do
+           end do
+         endif
+       end if
+    enddo
+
+    end subroutine init_photolysis
+  
+    !==============================================================================
+  
+    subroutine gridw(nw,wl,wc,wu,mopt)
+  
+        use datafile_mod, only: datadir
+        use ioipsl_getin_p_mod, only: getin_p
+  
+        !==========================================================================
+        ! Create the wavelength grid for all interpolations and radiative transfer 
+        ! calculations.  Grid may be irregularly spaced.  Wavelengths are in nm.   
+        ! No gaps are allowed within the wavelength grid.                          
+        !==========================================================================
+  
+        implicit none
+  
+        !     input
+   
+        integer :: mopt    ! high-res/low-res switch
+  
+        !     output
+  
+        integer :: nw      ! number of wavelength grid points
+        real, allocatable :: wl(:), wc(:), wu(:)   ! lower, center, upper wavelength for each interval
+  
+        !     local
+  
+        real :: wincr    ! wavelength increment
+        integer :: iw, kw, ierr
+        character(len=200) :: fil
+        character(len=150) :: gridwfile
+  
+        !     mopt = 1    high-resolution mode (3789 intervals)
+        !
+        !                   0-108 nm :  1.0  nm
+        !                 108-124 nm :  0.1  nm
+        !                 124-175 nm :  0.5  nm
+        !                 175-205 nm :  0.01 nm
+        !                 205-365 nm :  0.5  nm
+        !                 365-850 nm :  5.0  nm  
+        !
+        !     mopt = 2    low-resolution mode
+        !
+        !                    0-60 nm :  6.0 nm
+        !                   60-80 nm :  2.0 nm
+        !                   80-85 nm :  5.0 nm
+        !                  85-117 nm :  2.0 nm
+        !                 117-120 nm :  5.0 nm
+        !                 120-123 nm :  0.2 nm
+        !                 123-163 nm :  5.0 nm
+        !                 163-175 nm :  2.0 nm
+        !                 175-205 nm :  0.5 nm
+        !                 205-245 nm :  5.0 nm
+        !                 245-415 nm : 10.0 nm
+        !                 415-815 nm : 50.0 nm
+        !
+        !     mopt = 3    input file reading grid
+        !
+        !                 read "gridw.dat" in datadir/cross_sections/
+  
+        if (mopt == 1) then   ! high-res
+  
+        nw = 3789
+        allocate(wl(nw))
+        allocate(wu(nw))
+        allocate(wc(nw))
+        ! define wavelength intervals of width 1.0 nm from 0 to 108 nm:
+  
+        kw = 0
+        wincr = 1.0
+        do iw = 0, 107
+          kw = kw + 1
+          wl(kw) = real(iw)
+          wu(kw) = wl(kw) + wincr
+          wc(kw) = (wl(kw) + wu(kw))/2.
+        end do
+  
+        ! define wavelength intervals of width 0.1 nm from 108 to 124 nm:
+  
+        wincr = 0.1
+        do iw = 1080, 1239, 1
+          kw = kw + 1
+          wl(kw) = real(iw)/10.
+          wu(kw) = wl(kw) + wincr
+          wc(kw) = (wl(kw) + wu(kw))/2.
+        end do
+  
+        ! define wavelength intervals of width 0.5 nm from 124 to 175 nm:
+  
+        wincr = 0.5
+        do iw = 1240, 1745, 5
+          kw = kw + 1
+          wl(kw) = real(iw)/10.
+          wu(kw) = wl(kw) + wincr
+          wc(kw) = (wl(kw) + wu(kw))/2.
+        end do
+  
+        ! define wavelength intervals of width 0.01 nm from 175 to 205 nm:
+  
+        wincr = 0.01
+        do iw = 17500, 20499, 1
+          kw = kw + 1
+          wl(kw) = real(iw)/100.
+          wu(kw) = wl(kw) + wincr
+          wc(kw) = (wl(kw) + wu(kw))/2.
+        end do
+  
+        ! define wavelength intervals of width 0.5 nm from 205 to 365 nm:
+  
+        wincr = 0.5
+        do iw = 2050, 3645, 5
+          kw = kw + 1
+          wl(kw) = real(iw)/10.
+          wu(kw) = wl(kw) + wincr
+          wc(kw) = (wl(kw) + wu(kw))/2.
+        end do
+  
+        ! define wavelength intervals of width 5.0 nm from 365 to 855 nm:
+  
+        wincr = 5.0
+        do iw = 365, 850, 5
+          kw = kw + 1
+          wl(kw) = real(iw)
+          wu(kw) = wl(kw) + wincr
+          wc(kw) = (wl(kw) + wu(kw))/2.
+        end do
+        wl(kw+1) = wu(kw)
+  
+        !============================================================
+  
+        else if (mopt == 2) then   ! low-res
+  
+        nw = 162
+        allocate(wl(nw))
+        allocate(wu(nw))
+        allocate(wc(nw))
+  
+        ! define wavelength intervals of width 6.0 nm from 0 to 60 nm:
+  
+        kw = 0
+        wincr = 6.0
+        DO iw = 0, 54, 6
+          kw = kw + 1
+          wl(kw) = real(iw)
+          wu(kw) = wl(kw) + wincr
+          wc(kw) = (wl(kw) + wu(kw))/2.
+        END DO
+  
+        ! define wavelength intervals of width 2.0 nm from 60 to 80 nm:
+  
+        wincr = 2.0
+        DO iw = 60, 78, 2
+          kw = kw + 1
+          wl(kw) = real(iw)
+          wu(kw) = wl(kw) + wincr
+          wc(kw) = (wl(kw) + wu(kw))/2.
+        END DO
+  
+        ! define wavelength intervals of width 5.0 nm from 80 to 85 nm:
+  
+        wincr = 5.0
+        DO iw = 80, 80
+          kw = kw + 1
+          wl(kw) = real(iw)
+          wu(kw) = wl(kw) + wincr
+          wc(kw) = (wl(kw) + wu(kw))/2.
+        END DO
+  
+        ! define wavelength intervals of width 2.0 nm from 85 to 117 nm:
+  
+        wincr = 2.0
+        DO iw = 85, 115, 2
+          kw = kw + 1
+          wl(kw) = real(iw)
+          wu(kw) = wl(kw) + wincr
+          wc(kw) = (wl(kw) + wu(kw))/2.
+        END DO
+  
+        ! define wavelength intervals of width 3.0 nm from 117 to 120 nm:
+  
+        wincr = 3.0
+        DO iw = 117, 117
+          kw = kw + 1
+          wl(kw) = real(iw)
+          wu(kw) = wl(kw) + wincr
+          wc(kw) = (wl(kw) + wu(kw))/2.
+        END DO
+  
+        ! define wavelength intervals of width 0.2 nm from 120 to 123 nm:
+  
+        wincr = 0.2
+        DO iw = 1200, 1228, 2
+          kw = kw + 1
+          wl(kw) = real(iw)/10.
+          wu(kw) = wl(kw) + wincr
+          wc(kw) = (wl(kw) + wu(kw))/2.
+        ENDDO
+  
+        ! define wavelength intervals of width 5.0 nm from 123 to 163 nm:
+  
+        wincr = 5.0
+        DO iw = 123, 158, 5
+          kw = kw + 1
+          wl(kw) = real(iw)
+          wu(kw) = wl(kw) + wincr
+          wc(kw) = (wl(kw) + wu(kw))/2.
+        ENDDO
+  
+        ! define wavelength intervals of width 2.0 nm from 163 to 175 nm:
+  
+        wincr = 2.0
+        DO iw = 163, 173, 2
+          kw = kw + 1
+          wl(kw) = real(iw)
+          wu(kw) = wl(kw) + wincr
+          wc(kw) = (wl(kw) + wu(kw))/2.
+        ENDDO
+  
+        ! define wavelength intervals of width 0.5 nm from 175 to 205 nm:
+  
+        wincr = 0.5
+        DO iw = 1750, 2045, 5
+          kw = kw + 1
+          wl(kw) = real(iw)/10.
+          wu(kw) = wl(kw) + wincr
+          wc(kw) = (wl(kw) + wu(kw))/2.
+        ENDDO
+  
+        ! define wavelength intervals of width 5.0 nm from 205 to 245 nm:
+  
+        wincr = 5.
+        DO iw = 205, 240, 5
+          kw = kw + 1
+          wl(kw) = real(iw)
+          wu(kw) = wl(kw) + wincr
+          wc(kw) = (wl(kw) + wu(kw))/2.
+        ENDDO
+  
+        ! define wavelength intervals of width 10.0 nm from 245 to 415 nm:
+  
+        wincr = 10.0
+        DO iw = 245, 405, 10
+          kw = kw + 1
+          wl(kw) = real(iw)
+          wu(kw) = wl(kw) + wincr
+          wc(kw) = (wl(kw) + wu(kw))/2.
+        ENDDO
+  
+        ! define wavelength intervals of width 50.0 nm from 415 to 865 nm:
+  
+        wincr = 50.0
+        DO iw = 415, 815, 50
+          kw = kw + 1
+          wl(kw) = real(iw)
+          wu(kw) = wl(kw) + wincr
+          wc(kw) = (wl(kw) + wu(kw))/2.
+        ENDDO
+  
+        wl(kw+1) = wu(kw)
+  
+        !============================================================
+
+        else if (mopt == 3) then   ! input file
+  
+           ! look for a " gridwfile= ..." option in def files
+           write(*,*) "Input wavelenght grid files for photolysis online is:"
+           gridwfile = "gridw.dat" ! default
+           call getin_p("gridwfile",gridwfile) ! default path
+           write(*,*) " gridwfile = ",trim(gridwfile)
+           write(*,*) 'Please use 1 and only 1 skipping line in ',trim(gridwfile)
+  
+           ! Opening file
+           fil = trim(datadir)//'/cross_sections/'//gridwfile
+           print*, 'wavelenght grid : ', fil
+           OPEN(UNIT=10,FILE=fil,STATUS='old',iostat=ierr)
+  
+           if (ierr /= 0) THEN
+             write(*,*)'Error : cannot open wavelenght grid file ', trim(gridwfile)
+             write(*,*)'It should be in :',trim(datadir),'/cross_sections/'
+             write(*,*)'1) You can change the directory in callphys.def'
+             write(*,*)'   with:'
+             write(*,*)'   datadir=/path/to/the/directory'
+             write(*,*)'2) You can change the input wavelenght grid file name in'
+             write(*,*)'   callphys.def with:'
+             write(*,*)'   gridwfile=filename'
+             stop
+           end if
+  
+           READ(10,*)
+  
+           READ(10,*) nw
+           allocate(wl(nw))
+           allocate(wu(nw))
+           allocate(wc(nw))
+  
+           kw = 0
+           READ(10,*) wl(1)
+           DO iw = 2, nw
+              READ(10,*) wl(iw)
+              wu(iw-1) = wl(iw)
+              wc(iw-1) = (wl(iw-1) + wu(iw-1))/2.
+              kw = kw + 1
+           ENDDO
+  
+           close(10)
+        end if  ! mopt
+  
+        print*, 'number of spectral intervals : ', kw+1
+        
+    end subroutine gridw
+  
+    !==============================================================================
+   
+    subroutine rdsolarflux(nw,wl,wc,f)
+  
+        !     Read and re-grid solar flux data.            
+  
+        use datafile_mod, only: datadir
+        use ioipsl_getin_p_mod, only: getin_p
+  
+        implicit none
+  
+        !     input
+   
+        integer :: nw      ! number of wavelength grid points
+        real, dimension(nw) :: wl, wc   ! lower and central wavelength for each interval
+  
+        !     output
+  
+        real, dimension(nw) :: f  ! solar flux (photon.s-1.nm-1.cm-2)
+  
+        !     local 
+  
+        integer :: iw, nhead, n, i, ierr, kin, naddpnt
+  
+        real, parameter   :: deltax = 1.e-4
+        real, allocatable :: x1(:), y1(:)      ! input solar flux
+        real, dimension(nw)    :: yg1          ! gridded solar flux
+  
+        character(len=200) :: fil
+        character(len=150) :: stellarflux
+  
+        kin     = 10  ! input logical unit
+        naddpnt = 4   ! number of adding point
+        nhead   = 1   ! number of skipping line at the beggining of the file
+  
+        ! look for a " stellarflux= ..." option in def files
+        write(*,*) "Input stellar spectra files for photolysis online is:"
+        stellarflux = "Claire_SunModern_tuv.txt" ! default
+        call getin_p("stellarflux",stellarflux) ! default path
+        write(*,*) " stellarflux = ",trim(stellarflux)
+        write(*,*) 'Please use ',nhead,' and only ',nhead,' skipping line in ',trim(stellarflux)
+  
+        ! Opening file
+        fil = trim(datadir)//'/stellar_spectra/'//stellarflux
+        print*, 'solar flux : ', fil
+        OPEN(UNIT=kin,FILE=fil,STATUS='old',iostat=ierr)
+  
+        if (ierr /= 0) THEN
+          write(*,*)'Error : cannot open stellarflux file ', trim(stellarflux)
+          write(*,*)'It should be in :',trim(datadir),'/stellar_spectra/'
+          write(*,*)'1) You can change the data directory in callphys.def'
+          write(*,*)'   with:'
+          write(*,*)'   datadir=/path/to/the/directory'
+          write(*,*)'2) You can change the input stellarflux file name in'
+          write(*,*)'   callphys.def with:'
+          write(*,*)'   stellarflux=filename'
+          stop
+        end if
+  
+        ! Get number of line in the file
+        DO i = 1, nhead
+           READ(kin,*)
+        ENDDO
+        n = 0
+        do
+          read(kin,*,iostat=ierr)
+          if (ierr<0) exit
+          n = n + 1
+        end do
+        rewind(kin)
+        DO i = 1, nhead
+           READ(kin,*)
+        ENDDO
+        allocate(x1(n+naddpnt))
+        allocate(y1(n+naddpnt))
+  
+        ! Read stellar flux
+        DO i = 1, n
+           READ(kin,*) x1(i), y1(i)  !->  x1 nm and y1 in photon.s-1.nm-1.cm-2
+        ENDDO
+        CLOSE (kin)
+  
+        ! Interpolation on the grid
+        CALL addpnt(x1,y1,n+naddpnt,n,x1(1)*(1.-deltax),0.)
+        CALL addpnt(x1,y1,n+naddpnt-1,n,          0.,0.)
+        CALL addpnt(x1,y1,n+naddpnt-2,n,x1(n)*(1.+deltax),0.)
+        CALL addpnt(x1,y1,n+naddpnt-3,n,      1.e+38,0.)
+        CALL inter2(nw,wl,yg1,n,x1,y1,ierr)
+        IF (ierr .NE. 0) THEN
+           WRITE(*,*) ierr, fil
+           STOP
+        ENDIF
+  
+        ! factor to convert to photon.s-1.nm-1.cm-2 :
+        ! 5.039e11 = 1.e-4*1e-9/(hc = 6.62e-34*2.998e8)
+  
+        ! f need to be in photon.s-1.nm-1.cm-2
+        DO iw = 1, nw-1
+           !f(iw) = yg1(iw)*wc(iw)*5.039e11  ! If yg1 in w.m-2.nm-1
+           f(iw) = yg1(iw)
+        ENDDO
+  
+    end subroutine rdsolarflux
+  
+    !==============================================================================
+  
+    subroutine addpnt ( x, y, ld, n, xnew, ynew )
+  
+    !-----------------------------------------------------------------------------*
+    !=  PURPOSE:                                                                 =*
+    !=  Add a point <xnew,ynew> to a set of data pairs <x,y>.  x must be in      =*
+    !=  ascending order                                                          =*
+    !-----------------------------------------------------------------------------*
+    !=  PARAMETERS:                                                              =*
+    !=  X    - REAL vector of length LD, x-coordinates                       (IO)=*
+    !=  Y    - REAL vector of length LD, y-values                            (IO)=*
+    !=  LD   - INTEGER, dimension of X, Y exactly as declared in the calling  (I)=*
+    !=         program                                                           =*
+    !=  N    - INTEGER, number of elements in X, Y.  On entry, it must be:   (IO)=*
+    !=         N < LD.  On exit, N is incremented by 1.                          =*
+    !=  XNEW - REAL, x-coordinate at which point is to be added               (I)=*
+    !=  YNEW - REAL, y-value of point to be added                             (I)=*
+    !-----------------------------------------------------------------------------*
+  
+    IMPLICIT NONE
+  
+    ! calling parameters
+  
+    INTEGER ld, n
+    REAL x(ld), y(ld)
+    REAL xnew, ynew
+    INTEGER ierr
+  
+    ! local variables
+  
+    INTEGER insert
+    INTEGER i
+  
+    !-----------------------------------------------------------------------
+  
+    ! initialize error flag
+  
+    ierr = 0
+  
+    ! check n<ld to make sure x will hold another point
+  
+    IF (n .GE. ld) THEN
+       WRITE(0,*) '>>> ERROR (ADDPNT) <<<  Cannot expand array '
+       WRITE(0,*) '                        All elements used.'
+       STOP
+    ENDIF
+  
+    insert = 1
+    i = 2
+  
+    ! check, whether x is already sorted.
+    ! also, use this loop to find the point at which xnew needs to be inserted
+    ! into vector x, if x is sorted.
+  
+ 10   CONTINUE
+      IF (i .LT. n) THEN
+        IF (x(i) .LT. x(i-1)) THEN
+           print*, x(i-1), x(i)
+           WRITE(0,*) '>>> ERROR (ADDPNT) <<<  x-data must be in ascending order!'
+           STOP
+        ELSE
+           IF (xnew .GT. x(i)) insert = i + 1
+        ENDIF
+        i = i+1
+        GOTO 10
+      ENDIF
+  
+    ! if <xnew,ynew> needs to be appended at the end, just do so,
+    ! otherwise, insert <xnew,ynew> at position INSERT
+  
+    IF ( xnew .GT. x(n) ) THEN
+   
+        x(n+1) = xnew
+        y(n+1) = ynew
+    
+    ELSE
+  
+    ! shift all existing points one index up
+  
+        DO i = n, insert, -1
+          x(i+1) = x(i)
+          y(i+1) = y(i)
+        ENDDO
+  
+    ! insert new point
+  
+        x(insert) = xnew
+        y(insert) = ynew
+    
+    ENDIF
+  
+    ! increase total number of elements in x, y
+  
+    n = n+1
+  
+    end subroutine addpnt
+  
+    !==============================================================================
+  
+    subroutine inter2(ng,xg,yg,n,x,y,ierr)
+  
+    !-----------------------------------------------------------------------------*
+    !=  PURPOSE:                                                                 =*
+    !=  Map input data given on single, discrete points onto a set of target     =*
+    !=  bins.                                                                    =*
+    !=  The original input data are given on single, discrete points of an       =*
+    !=  arbitrary grid and are being linearly interpolated onto a specified set  =*
+    !=  of target bins.  In general, this is the case for most of the weighting  =*
+    !=  functions (action spectra, molecular cross section, and quantum yield    =*
+    !=  data), which have to be matched onto the specified wavelength intervals. =*
+    !=  The average value in each target bin is found by averaging the trapezoi- =*
+    !=  dal area underneath the input data curve (constructed by linearly connec-=*
+    !=  ting the discrete input values).                                         =*
+    !=  Some caution should be used near the endpoints of the grids.  If the     =*
+    !=  input data set does not span the range of the target grid, an error      =*
+    !=  message is printed and the execution is stopped, as extrapolation of the =*
+    !=  data is not permitted.                                                   =*
+    !=  If the input data does not encompass the target grid, use ADDPNT to      =*
+    !=  expand the input array.                                                  =*
+    !-----------------------------------------------------------------------------*
+    !=  PARAMETERS:                                                              =*
+    !=  NG  - INTEGER, number of bins + 1 in the target grid                  (I)=*
+    !=  XG  - REAL, target grid (e.g., wavelength grid);  bin i is defined    (I)=*
+    !=        as [XG(i),XG(i+1)] (i = 1..NG-1)                                   =*
+    !=  YG  - REAL, y-data re-gridded onto XG, YG(i) specifies the value for  (O)=*
+    !=        bin i (i = 1..NG-1)                                                =*
+    !=  N   - INTEGER, number of points in input grid                         (I)=*
+    !=  X   - REAL, grid on which input data are defined                      (I)=*
+    !=  Y   - REAL, input y-data                                              (I)=*
+    !-----------------------------------------------------------------------------*
+  
+    IMPLICIT NONE
+  
+    ! input:
+    INTEGER ng, n
+    REAL x(n), y(n), xg(ng)
+  
+    ! output:
+    REAL yg(ng)
+  
+    ! local:
+    REAL area, xgl, xgu
+    REAL darea, slope
+    REAL a1, a2, b1, b2
+    INTEGER ngintv
+    INTEGER i, k, jstart
+    INTEGER ierr
+    !_______________________________________________________________________
+  
+    ierr = 0
+  
+    !  test for correct ordering of data, by increasing value of x
+  
+    DO 10, i = 2, n
+       IF (x(i) .LE. x(i-1)) THEN
+          ierr = 1
+          WRITE(*,*)'data not sorted'
+          WRITE(*,*) x(i), x(i-1)
+          RETURN
+       ENDIF
+ 10 CONTINUE     
+
+    DO i = 2, ng
+      IF (xg(i) .LE. xg(i-1)) THEN
+         ierr = 2
+        WRITE(0,*) '>>> ERROR (inter2) <<<  xg-grid not sorted!'
+        RETURN
+      ENDIF
+    ENDDO
+  
+    ! check for xg-values outside the x-range
+  
+    IF ( (x(1) .GT. xg(1)) .OR. (x(n) .LT. xg(ng)) ) THEN
+        WRITE(0,*) '>>> ERROR (inter2) <<<  Data do not span grid.  '
+        WRITE(0,*) '                        Use ADDPNT to expand data and re-run.'
+        STOP
+    ENDIF
+  
+    !  find the integral of each grid interval and use this to 
+    !  calculate the average y value for the interval      
+    !  xgl and xgu are the lower and upper limits of the grid interval
+  
+    jstart = 1
+    ngintv = ng - 1
+    DO 50, i = 1,ngintv
+  
+    ! initialize:
+  
+        area = 0.0
+        xgl = xg(i)
+        xgu = xg(i+1)
+  
+    !  discard data before the first grid interval and after the 
+    !  last grid interval
+    !  for internal grid intervals, start calculating area by interpolating
+    !  between the last point which lies in the previous interval and the
+    !  first point inside the current interval
+  
+        k = jstart
+        IF (k .LE. n-1) THEN
+  
+    !  if both points are before the first grid, go to the next point
+ 30         CONTINUE
+              IF (x(k+1) .LE. xgl) THEN
+                 jstart = k - 1
+                 k = k+1
+                 IF (k .LE. n-1) GO TO 30
+              ENDIF
+  
+  
+    !  if the last point is beyond the end of the grid, complete and go to the next
+    !  grid
+ 40         CONTINUE
+               IF ((k .LE. n-1) .AND. (x(k) .LT. xgu)) THEN          
+
+                  jstart = k-1
+  
+    ! compute x-coordinates of increment
+  
+                  a1 = MAX(x(k),xgl)
+                  a2 = MIN(x(k+1),xgu)
+  
+    ! if points coincide, contribution is zero
+  
+                  IF (x(k+1).EQ.x(k)) THEN
+                     darea = 0.e0
+                  ELSE
+                     slope = (y(k+1) - y(k))/(x(k+1) - x(k))
+                     b1 = y(k) + slope*(a1 - x(k))
+                     b2 = y(k) + slope*(a2 - x(k))
+                     darea = (a2 - a1)*(b2 + b1)/2.
+                  ENDIF
+  
+    !  find the area under the trapezoid from a1 to a2
+  
+                  area = area + darea
+  
+    ! go to next point
+                
+                  k = k+1
+                  GO TO 40
+
+              ENDIF
+          ENDIF
+  
+    !  calculate the average y after summing the areas in the interval
+  
+            yg(i) = area/(xgu - xgl)
+  
+ 50 CONTINUE
+  
+    end subroutine inter2
+  
+    !==============================================================================
+
+    subroutine rdxsi(nw,wl,xsi,jparamlinei,xs_tempi,qyi,tdimi,species)
+  
+    !-----------------------------------------------------------------------------*
+    !=  PURPOSE:                                                                 =*
+    !=  Read molecular absorption cross section.  Re-grid data to match          =*
+    !=  specified wavelength working grid.                                       =*
+    !-----------------------------------------------------------------------------*
+    !=  PARAMETERS:                                                              =*
+    !=  NW     - INTEGER, number of specified intervals + 1 in working        (I)=*
+    !=           wavelength grid                                                 =*
+    !=  WL     - REAL, vector of lower limits of wavelength intervals in      (I)=*
+    !=           working wavelength grid                                         =*
+    !=  XS     - REAL, molecular absoprtion cross section (cm^2) at each      (O)=*
+    !=           specified wavelength                                            =*
+    !-----------------------------------------------------------------------------*
+  
+    use datafile_mod, only: datadir
+  
+    IMPLICIT NONE
+  
+    !     input
+  
+    integer, intent(in) :: nw       ! number of wavelength grid points
+    integer, intent(in) :: tdimi    ! temperature dimension
+    real,    intent(in) :: wl(nw)   ! lower and central wavelength for each interval (nm)
+    character(len = 20) :: species  ! species which is photolysed
+    character(len = 300), intent(in) :: jparamlinei ! line of jonline parameters
+  
+    !     output
+  
+    real, intent(inout) :: qyi(nw)         ! photodissociation yield
+    real, intent(inout) :: xsi(tdimi,nw)   ! absorption cross-section (cm2)
+    real, intent(inout) :: xs_tempi(tdimi) !  absorption cross-section temperature (K)
+  
+    !     local
+  
+    character(len = 50)  :: sigfile(tdimi) ! cross section file name
+    character(len = 50)  :: qyfile         ! quantum yield file name
+    CHARACTER(len = 120) :: fil            ! path files
+    integer :: tdimdummy, ifile, itemp, ierr, nheadxs, nheadqy, i, n, naddpnt
+    integer :: kin                         ! input logical unit
+    real, allocatable :: wlf(:), xsf(:)    ! input cross section
+    real, allocatable :: wlqy(:), qyf(:)   ! input photodissociation yield
+    real, parameter   :: deltax = 1.e-4
+  
+    kin     = 10     ! input logical unit
+    naddpnt = 4      ! number of adding point (careful: same for xs and qy)
+    nheadxs = 1      ! number of skipping line at the beggining of the cross section files
+    nheadqy = 1      ! number of skipping line at the beggining of the quantum yield files
+    sigfile(:) = ''
+    qyfile = ''
+  
+    read(jparamlinei,*) tdimdummy, (xs_tempi(itemp), itemp=1,tdimi), (sigfile(ifile), ifile=1,tdimi), qyfile
+  
+    ! Check if xs_tempi is sorted from low to high values
+    do i = 1,tdimi-1
+      if (xs_tempi(i)>xs_tempi(i+1)) then
+        print*, 'ERROR: temperature cross section file'
+        print*, '       has to be sorted from low to high values'
+        print*, '       Check monoreact file'
+        stop
+      end if
+    end do
+  
+    ! Cross section
+    do itemp=1,tdimi
+
+      fil = trim(datadir)//'/cross_sections/'//trim(sigfile(itemp))
+      print*, 'section efficace '//trim(species)//': ', fil
+
+      OPEN(UNIT=kin,FILE=fil,STATUS='old',iostat=ierr)
+
+      if (ierr /= 0) THEN
+         write(*,*)'Error : cannot open cross_sections file ', trim(sigfile(itemp))
+         write(*,*)'It should be in :',trim(datadir),'/cross_sections/'
+         write(*,*)'1) You can change the datadir directory in callphys.def'
+         write(*,*)'   with:'
+         write(*,*)'   datadir=/path/to/the/directory'
+         write(*,*)'2) You can check if the file is in datadir/cross_sections/'
+         write(*,*)'3) You can change the input cross_sections file name in'
+         write(*,*)'   chemestry/monoreact file for the specie:',trim(species)
+         stop
+      end if
+
+      ! Get number of line in the file
+      DO i = 1, nheadxs
+         READ(kin,*)
+      ENDDO
+      n = 0
+      do
+        read(kin,*,iostat=ierr)
+        if (ierr<0) exit
+        n = n + 1
+      end do
+      rewind(kin)
+      DO i = 1, nheadxs
+         READ(kin,*)
+      ENDDO
+
+      allocate(wlf(n+naddpnt))
+      allocate(xsf(n+naddpnt))
+
+      ! Read cross section
+      DO i = 1, n
+         READ(kin,*) wlf(i), xsf(i)  !-> xsf in cm2 and wlf in nm
+      ENDDO
+      CLOSE (kin)
+
+      CALL addpnt(wlf,xsf,n+naddpnt,n,wlf(1)*(1.-deltax),0.)
+      CALL addpnt(wlf,xsf,n+naddpnt-1,n,               0.,0.)
+      CALL addpnt(wlf,xsf,n+naddpnt-2,n,wlf(n)*(1.+deltax),0.)
+      CALL addpnt(wlf,xsf,n+naddpnt-3,n,           1.e+38,0.)
+      CALL inter2(nw,wl,xsi(itemp,:),n,wlf,xsf,ierr)
+      IF (ierr .NE. 0) THEN
+         WRITE(*,*) ierr, fil
+         STOP
+      ENDIF
+
+      deallocate(wlf)
+      deallocate(xsf)
+
+    end do
+
+    ! Photodissociation yield
+    fil = trim(datadir)//'/cross_sections/'//trim(qyfile)
+    print*, 'photodissociation yield '//trim(species)//': ', fil
+
+    OPEN(UNIT=kin,FILE=fil,STATUS='old',iostat=ierr)
+
+    if (ierr /= 0) THEN
+       write(*,*)'Error : cannot open photodissociation yield file ', trim(qyfile)
+       write(*,*)'It should be in :',trim(datadir),'/cross_sections/'
+       write(*,*)'1) You can change the datadir directory in callphys.def'
+       write(*,*)'   with:'
+       write(*,*)'   datadir=/path/to/the/directory'
+       write(*,*)'2) You can check if the file is in datadir/cross_sections/'
+       write(*,*)'3) You can change the input photodissociation yield file name in'
+       write(*,*)'   chemestry/monoreact file for the specie:',trim(species)
+       stop
+    end if
+
+    ! Get number of line in the file
+    DO i = 1, nheadqy
+       READ(kin,*)
+    ENDDO
+    n = 0
+    do
+      read(kin,*,iostat=ierr)
+      if (ierr<0) exit
+      n = n + 1
+    end do
+    rewind(kin)
+    DO i = 1, nheadqy
+       READ(kin,*)
+    ENDDO
+    allocate(wlqy(n+naddpnt))
+    allocate(qyf(n+naddpnt))
+
+    ! Read photodissociation yield
+    DO i = 1, n
+       READ(kin,*) wlqy(i), qyf(i)  !-> wlqy in nm
+    ENDDO
+    CLOSE (kin)
+
+    CALL addpnt(wlqy,qyf,n+naddpnt,n,wlqy(1)*(1.-deltax),0.)
+    CALL addpnt(wlqy,qyf,n+naddpnt-1,n,                 0.,0.)
+    CALL addpnt(wlqy,qyf,n+naddpnt-2,n,wlqy(n)*(1.+deltax),0.)
+    CALL addpnt(wlqy,qyf,n+naddpnt-3,n,             1.e+38,0.)
+    CALL inter2(nw,wl,qyi,n,wlqy,qyf,ierr)
+    IF (ierr .NE. 0) THEN
+       WRITE(*,*) ierr, fil
+       STOP
+    ENDIF
+
+    end subroutine rdxsi
+   
+end module photolysis_mod
+  
Index: trunk/LMDZ.GENERIC/libf/aeronostd/photolysis_online.F
===================================================================
--- trunk/LMDZ.GENERIC/libf/aeronostd/photolysis_online.F	(revision 2542)
+++ trunk/LMDZ.GENERIC/libf/aeronostd/photolysis_online.F	(revision 2542)
@@ -0,0 +1,1313 @@
+!==============================================================================
+
+      subroutine photolysis_online(nlayer, alt, press, temp,
+     $           zmmean, rm,
+     $           tau, sza, dist_sol, v_phot, e_phot, ig, ngrid,
+     $           nreact, three_prod)
+
+!***********************************************************************
+!
+!   subject:
+!   --------
+!
+!   photolysis online
+!
+!   VERSION: Extracted from LMDZ.MARS work of Franck Lefevre (Yassin Jaziri)
+!   April 2019 - Yassin Jaziri add updates generic input (Yassin Jaziri)
+!
+!***********************************************************************
+
+      use photolysis_mod
+      use tracer_h
+      use chimiedata_h, only: indexchim
+      use types_asis,   only: nb_phot_hv_max, nb_phot_max, jlabel
+
+      implicit none
+
+!     input 
+
+      integer, intent(in) :: nlayer ! number of atmospheric layers
+      integer, intent(in) :: ngrid  ! number of atmospheric columns
+
+      real,    intent(in), dimension(nlayer) :: press, temp, zmmean ! pressure (hpa)/temperature (k)/mean molecular mass (g.mol-1)
+      real,    intent(in), dimension(nlayer) :: alt                 ! altitude (km)
+      real,    intent(in), dimension(nlayer,nesp) :: rm             ! mixing ratios 
+      real,    intent(in) :: tau                                    ! integrated aerosol optical depth at the surface
+      real,    intent(in) :: sza                                    ! solar zenith angle (degrees)
+      real,    intent(in) :: dist_sol                               ! solar distance (au)
+      integer, intent(in) :: ig                                     ! grid point index
+      integer, intent(in) :: nreact                                 ! number of reactions in reactions files
+      logical, intent(in) :: three_prod(nreact)                     ! if the reaction have a three defferent products egal .true.
+
+!     output
+
+      real (kind = 8), dimension(nlayer,nb_phot_max) :: v_phot      ! photolysis rates (s-1)
+      real (kind = 8), dimension(nlayer,nb_phot_max) :: e_phot      ! photolysis rates by energie (J.mol-1.s-1)
+ 
+!     solar flux at mars
+
+      real, dimension(nw) :: fmars                                  ! solar flux (w.m-2.nm-1)
+      real :: factor
+
+!     atmosphere
+
+      real, dimension(nw)             :: albedo_chim                ! Surface albedo calculated on chemistry wavelenght grid
+      real, dimension(nlayer)         :: colinc                     ! air column increment (molecule.cm-2) 
+      real, dimension(nlayer)         :: airlev                     ! air density at each specified altitude (molec/cc)
+      real, dimension(nlayer)         :: edir, edn, eup             ! normalised irradiances
+      real, dimension(nlayer)         :: fdir, fdn, fup             ! normalised actinic fluxes
+      real, dimension(nlayer)         :: saflux                     ! total actinic flux
+      real, dimension(nlayer,nw)      :: dtrl                       ! rayleigh optical depth 
+      real, dimension(nlayer,nw)      :: dtaer                      ! aerosol optical depth 
+      real, dimension(nlayer,nw)      :: omaer                      ! aerosol single scattering albedo 
+      real, dimension(nlayer,nw)      :: gaer                       ! aerosol asymmetry parameter
+      real, dimension(nlayer,nw)      :: dtcld                      ! cloud optical depth 
+      real, dimension(nlayer,nw)      :: omcld                      ! cloud single scattering albedo 
+      real, dimension(nlayer,nw)      :: gcld                       ! cloud asymmetry parameter
+      real, dimension(nlayer,nw)      :: dagas                      ! total gas optical depth
+      real, dimension(nlayer,nw,nabs) :: dtgas                      ! optical depth for each gas 
+
+      integer, dimension(0:nlayer)        :: nid
+      real,    dimension(0:nlayer,nlayer) :: dsdh
+
+      integer :: i, ilay, iw, ialt, iphot, ispe, ij, igas
+      real    :: deltaj
+
+!==== air column increments and rayleigh optical depth
+
+      call setair(nlayer, nw, wl, wc, press, temp, zmmean, colinc, dtrl,
+     $            airlev)
+
+!====  set surface albedo
+
+      call setalb(nw,wl,ig,ngrid,albedo_chim)
+
+!==== set temperature-dependent cross-sections and optical depths
+
+      iphot = 0
+      ij    = 0
+      igas  = 0
+
+      do while(iphot<nb_phot_hv_max)
+        ij = ij + 1
+        iphot = iphot + 1
+
+        if (tdim(ij).eq.1) then
+          ! Avoid to calculate several times dtgas for a same specie
+          if (jlabelbis(iphot)) then
+            ispe = indexchim(trim(jlabel(iphot,2)))
+            do iw = 1,nw-1
+              do ilay = 1,nlayer
+                dtgas(ilay,iw,ij-igas) = colinc(ilay)*rm(ilay,ispe)
+     $                                *xs(1,iw,ij)
+              end do
+            end do
+          else
+            igas = igas + 1
+          end if
+          if (three_prod(ij)) iphot = iphot + 1
+        else
+          call setsj(nb_phot_hv_max,nlayer,nw,temp,tdim(ij),
+     $               xs(:tdim(ij),:,ij),
+     $               xs_temp(:,ij),sj(:,:,iphot))
+  
+          ! Avoid to calculate several times dtgas for a same specie
+          if (jlabelbis(iphot)) then
+            ispe = indexchim(trim(jlabel(iphot,2)))
+            do iw = 1,nw-1
+              do ilay = 1,nlayer
+                dtgas(ilay,iw,ij-igas) = colinc(ilay)*rm(ilay,ispe)
+     $                                *sj(ilay,iw,iphot)
+              end do
+            end do
+          else
+            igas = igas + 1
+          end if
+  
+          do iw = 1,nw-1
+            do ilay = 1,nlayer
+              sj(ilay,iw,iphot) = sj(ilay,iw,iphot)*qy(iw,ij)
+            end do
+          end do
+
+          if (three_prod(ij)) then
+            iphot = iphot + 1
+            do iw = 1,nw-1
+              do ilay = 1,nlayer
+                sj(ilay,iw,iphot) = sj(ilay,iw,iphot-1)
+              end do
+            end do
+          end if
+
+        endif ! end if tdim .eq. 1
+
+      end do ! end while
+
+!     total gas optical depth
+
+      dagas(:,:) = 0.
+
+      do i = 1,nabs
+         do iw = 1,nw-1
+            do ilay = 1,nlayer
+               dagas(ilay,iw) = dagas(ilay,iw) + dtgas(ilay,iw,i)
+            end do
+         end do
+      end do
+
+!==== set aerosol properties and optical depth
+
+      call setaer(nlayer,alt,tau,nw,dtaer,omaer,gaer)
+
+!==== set cloud properties and optical depth
+
+      call setcld(nlayer,nw,dtcld,omcld,gcld)
+
+!==== slant path lengths in spherical geometry
+
+      call sphers(nlayer,alt,sza,dsdh,nid)
+
+!==== solar flux at mars
+
+      factor = (1./dist_sol)**2.
+      do iw = 1,nw-1
+         fmars(iw) = f(iw)*factor
+      end do
+
+!==== initialise photolysis rates
+
+      v_phot(:,1:nb_phot_hv_max) = 0.
+      e_phot(:,1:nb_phot_hv_max) = 0.
+
+!==== start of wavelength lopp
+
+      do iw = 1,nw-1
+
+!     monochromatic radiative transfer. outputs are:
+!     normalized irradiances     edir(nlayer), edn(nlayer), eup(nlayer) 
+!     normalized actinic fluxes  fdir(nlayer), fdn(nlayer), fup(nlayer)
+!     where 
+!     dir = direct beam, dn = down-welling diffuse, up = up-welling diffuse
+
+         call rtlink(nlayer, nw, iw, albedo_chim(iw),
+     $               sza, dsdh, nid, dtrl,
+     $               dagas, dtcld, omcld, gcld, dtaer, omaer, gaer,
+     $               edir, edn, eup, fdir, fdn, fup)
+
+
+!     spherical actinic flux
+
+         do ilay = 1,nlayer
+           saflux(ilay) = fmars(iw)*(fdir(ilay) + fdn(ilay) + fup(ilay))
+         end do
+
+!     photolysis rate integration
+!     (0.12/(wc(iw)*1e-9)) E(wc) en J.mol-1
+
+         do i = 1,nb_phot_hv_max
+            do ilay = 1,nlayer
+               deltaj = saflux(ilay)*sj(ilay,iw,i)
+               v_phot(ilay,i) = v_phot(ilay,i) + deltaj*(wu(iw)-wl(iw))
+               if (wc(iw).le.photoheat_lmax) then
+                  e_phot(ilay,i) = e_phot(ilay,i)
+     $                    + deltaj*(wu(iw)-wl(iw))*(0.12/(wc(iw)*1e-9))
+               end if
+            end do
+         end do
+
+!     eliminate small values
+
+         where (v_phot(:,1:nb_phot_hv_max) < 1.e-30)
+            v_phot(:,1:nb_phot_hv_max) = 0.
+         end where
+         where (e_phot(:,1:nb_phot_hv_max) < 1.e-30)
+            e_phot(:,1:nb_phot_hv_max) = 0.
+         end where
+
+      end do ! iw
+
+      contains
+
+!==============================================================================
+
+      subroutine setair(nlev, nw, wl, wc, press, temp, zmmean, 
+     $                  colinc, dtrl, airlev)
+
+*-----------------------------------------------------------------------------*
+*=  PURPOSE:                                                                 =*
+*=  computes air column increments and rayleigh optical depth                =*
+*-----------------------------------------------------------------------------*
+
+      use comcstfi_mod, only:  g, avocado
+
+      implicit none
+
+!     input:
+
+      integer :: nlev, nw
+
+      real, dimension(nw)   :: wl, wc              ! lower and central wavelength grid (nm)
+      real, dimension(nlev) :: press, temp, zmmean ! pressure (hpa), temperature (k), molecular mass (g.mol-1)
+
+!     output:
+
+      real, dimension(nlev)    :: colinc ! air column increments (molecule.cm-2)
+      real, dimension(nlev)    :: airlev ! air density at each specified altitude (molec/cc)
+      real, dimension(nlev,nw) :: dtrl   ! rayleigh optical depth
+
+!     local:
+
+      real :: dp, nu
+      real, dimension(nw) :: srayl
+      integer :: ilev, iw
+
+!     compute column increments 
+
+      do ilev = 1, nlev-1
+         dp = (press(ilev) - press(ilev+1))*100.
+         colinc(ilev) = avocado*0.1*dp/(zmmean(ilev)*g)
+      end do
+      colinc(nlev) = avocado*0.1*press(nlev)*100./(zmmean(nlev)*g)
+
+      do iw = 1, nw - 1
+
+!        co2 rayleigh cross-section
+!        ityaksov et al., chem. phys. lett., 462, 31-34, 2008
+
+!         nu = 1./(wc(iw)*1.e-7)
+!         srayl(iw) = 1.78e-26*nu**(4. + 0.625)
+!         srayl(iw) = srayl(iw)*1.e-20 ! cm2
+
+!        calcul Ityaksov et al., 2008 pour N2
+
+         nu = 1./(wc(iw)*1.e-7)                     ! cm-1
+         srayl(iw) = 1.8e-26*nu**(4. + 0.534)
+         srayl(iw) = srayl(iw)*1.e-20
+
+         do ilev = 1, nlev
+            dtrl(ilev,iw) = colinc(ilev)*srayl(iw)   ! cm2
+         end do
+      end do
+
+!     compute density
+
+      do ilev = 1, nlev
+         airlev(ilev) = press(ilev)/(1.38e-19*temp(ilev))
+      end do
+
+      end subroutine setair
+
+!==============================================================================
+
+      subroutine setaer(nlayer,alt,tau,nw,dtaer,omaer,gaer)
+
+!-----------------------------------------------------------------------------*
+!=  PURPOSE:                                                                 =*
+!=  Set aerosol properties for each specified altitude layer.  Properties    =*
+!=  may be wavelength dependent.                                             =*
+!-----------------------------------------------------------------------------*
+
+      implicit none
+
+!     input
+
+      integer :: nlayer                              ! number of vertical layers
+      integer :: nw                                  ! number of wavelength grid points
+      real, dimension(nlayer) :: alt                 ! altitude (km)
+      real :: tau                                    ! integrated aerosol optical depth at the surface
+
+!     output 
+
+      real, dimension(nlayer,nw) :: dtaer            ! aerosol optical depth 
+      real, dimension(nlayer,nw) :: omaer            ! aerosol single scattering albedo 
+      real, dimension(nlayer,nw) :: gaer             ! aerosol asymmetry parameter
+
+!     local
+
+      integer :: ilay, iw
+      real, dimension(nlayer) :: aer                                 ! dust extinction
+      real :: omega, g, scaleh, gamma
+      real :: dz, tautot, q0
+
+      omega  = 0.622 ! single scattering albedo : wolff et al.(2010) at 258 nm
+      g      = 0.88  ! asymmetry factor : mateshvili et al. (2007) at 210 nm
+      scaleh = 10.   ! scale height (km)
+      gamma  = 0.03  ! conrath parameter
+
+      dtaer(:,:) = 0.
+      omaer(:,:) = 0.
+      gaer(:,:)  = 0.
+
+!     optical depth profile:
+
+      tautot = 0.
+      do ilay = 1, nlayer-1
+         dz = alt(ilay+1) - alt(ilay)
+         tautot = tautot + exp(gamma*(1. - exp(alt(ilay)/scaleh)))*dz
+      end do
+      
+      q0 = tau/tautot
+      do ilay = 1, nlayer-1
+         dz = alt(ilay+1) - alt(ilay)
+         dtaer(ilay,:) = q0*exp(gamma*(1. - exp(alt(ilay)/scaleh)))*dz
+         omaer(ilay,:) = omega
+         gaer(ilay,:)  = g
+      end do
+
+      end subroutine setaer
+
+!==============================================================================
+
+      subroutine setcld(nlayer,nw,dtcld,omcld,gcld)
+
+!-----------------------------------------------------------------------------*
+!=  PURPOSE:                                                                 =*
+!=  Set cloud properties for each specified altitude layer.  Properties      =*
+!=  may be wavelength dependent.                                             =*
+!-----------------------------------------------------------------------------*
+
+      implicit none
+
+!     input
+
+      integer :: nlayer                              ! number of vertical layers
+      integer :: nw                                  ! number of wavelength grid points
+
+!     output 
+
+      real, dimension(nlayer,nw) :: dtcld            ! cloud optical depth 
+      real, dimension(nlayer,nw) :: omcld            ! cloud single scattering albedo 
+      real, dimension(nlayer,nw) :: gcld             ! cloud asymmetry parameter
+
+!     local
+
+      integer :: ilay, iw
+
+!     dtcld : optical depth
+!     omcld : single scattering albedo
+!     gcld  : asymmetry factor
+
+      do ilay = 1, nlayer - 1
+         do iw = 1, nw - 1
+            dtcld(ilay,iw) = 0.       ! no clouds for the moment
+            omcld(ilay,iw) = 0.99
+            gcld(ilay,iw)  = 0.85
+         end do
+      end do
+
+      end subroutine setcld
+
+!==============================================================================
+
+      subroutine sphers(nlev, z, zen, dsdh, nid)
+
+!-----------------------------------------------------------------------------*
+!=  PURPOSE:                                                                 =*
+!=  Calculate slant path over vertical depth ds/dh in spherical geometry.    =*
+!=  Calculation is based on:  A.Dahlback, and K.Stamnes, A new spheric model =*
+!=  for computing the radiation field available for photolysis and heating   =*
+!=  at twilight, Planet.Space Sci., v39, n5, pp. 671-683, 1991 (Appendix B)  =*
+!-----------------------------------------------------------------------------*
+!=  PARAMETERS:                                                              =*
+!=  NZ      - INTEGER, number of specified altitude levels in the working (I)=*
+!=            grid                                                           =*
+!=  Z       - REAL, specified altitude working grid (km)                  (I)=*
+!=  ZEN     - REAL, solar zenith angle (degrees)                          (I)=*
+!=  DSDH    - REAL, slant path of direct beam through each layer crossed  (O)=*
+!=            when travelling from the top of the atmosphere to layer i;     =*
+!=            DSDH(i,j), i = 0..NZ-1, j = 1..NZ-1                            =*
+!=  NID     - INTEGER, number of layers crossed by the direct beam when   (O)=*
+!=            travelling from the top of the atmosphere to layer i;          =*
+!=            NID(i), i = 0..NZ-1                                            =*
+!-----------------------------------------------------------------------------*
+
+      use comcstfi_mod, only: rad, pi
+
+      implicit none
+
+! input
+
+      integer, intent(in) :: nlev
+      real, dimension(nlev), intent(in) :: z
+      real, intent(in) :: zen
+
+! output
+
+      INTEGER nid(0:nlev)
+      REAL dsdh(0:nlev,nlev)
+
+! more program constants
+
+      REAL re, ze(nlev)
+      REAL  dr
+      real radius ! km
+
+! local 
+
+      real :: zenrad, rpsinz, rj, rjp1, dsj, dhj, ga, gb, sm
+      integer :: i, j, k, id, nlay
+
+      REAL zd(0:nlev-1)
+
+!-----------------------------------------------------------------------------
+
+      radius = rad*1.e-3 ! rad [m] -> radius [km]
+      dr = pi/180.
+      zenrad = zen*dr
+
+! number of layers:
+
+      nlay = nlev - 1
+
+! include the elevation above sea level to the radius of Mars:
+
+      re = radius + z(1)
+
+! correspondingly z changed to the elevation above Mars surface:
+
+      DO k = 1, nlev
+         ze(k) = z(k) - z(1)
+      END DO
+
+! inverse coordinate of z
+
+      zd(0) = ze(nlev)
+      DO k = 1, nlay
+        zd(k) = ze(nlev - k)
+      END DO
+
+! initialise dsdh(i,j), nid(i)
+
+      nid(:) = 0.
+      dsdh(:,:) = 0.
+
+! calculate ds/dh of every layer
+
+      do i = 0,nlay
+         rpsinz = (re + zd(i))*sin(zenrad)
+ 
+        IF ( (zen .GT. 90.0) .AND. (rpsinz .LT. re) ) THEN
+           nid(i) = -1
+        ELSE
+
+! Find index of layer in which the screening height lies
+
+           id = i 
+           if (zen > 90.) then
+              do j = 1,nlay
+                 IF( (rpsinz .LT. ( zd(j-1) + re ) ) .AND.
+     $               (rpsinz .GE. ( zd(j) + re )) ) id = j
+              end do
+           end if
+ 
+           do j = 1,id
+              sm = 1.0
+              IF (j .EQ. id .AND. id .EQ. i .AND. zen .GT. 90.0)
+     $            sm = -1.0
+ 
+              rj = re + zd(j-1)
+              rjp1 = re + zd(j)
+ 
+              dhj = zd(j-1) - zd(j)
+ 
+              ga = rj*rj - rpsinz*rpsinz
+              gb = rjp1*rjp1 - rpsinz*rpsinz
+
+              ga = max(ga, 0.)
+              gb = max(gb, 0.)
+ 
+              IF (id.GT.i .AND. j.EQ.id) THEN
+                 dsj = sqrt(ga)
+              ELSE
+                 dsj = sqrt(ga) - sm*sqrt(gb)
+              END IF
+              dsdh(i,j) = dsj/dhj
+            end do
+            nid(i) = id
+         end if
+      end do ! i = 0,nlay
+
+      end subroutine sphers
+
+!==============================================================================
+
+      SUBROUTINE rtlink(nlev, nw, iw, ag, zen, dsdh, nid, dtrl, 
+     $                  dagas, dtcld, omcld, gcld, dtaer, omaer, gaer,
+     $                  edir, edn, eup, fdir, fdn, fup)
+
+      implicit none
+
+! input
+
+      integer, intent(in) :: nlev, nw, iw                       ! number of wavelength grid points
+      REAL ag
+      REAL zen
+      REAL dsdh(0:nlev,nlev)
+      INTEGER nid(0:nlev)
+
+      REAL dtrl(nlev,nw)
+      REAL dagas(nlev,nw)
+      REAL dtcld(nlev,nw), omcld(nlev,nw), gcld(nlev,nw)
+      REAL dtaer(nlev,nw), omaer(nlev,nw), gaer(nlev,nw)
+
+! output
+
+      REAL edir(nlev), edn(nlev), eup(nlev)
+      REAL fdir(nlev), fdn(nlev), fup(nlev)
+
+! local:
+
+      REAL dt(nlev), om(nlev), g(nlev)
+      REAL dtabs,dtsct,dscld,dsaer,dacld,daaer
+      INTEGER i, ii
+      real, parameter :: largest = 1.e+36
+
+! specific two ps2str
+
+      REAL ediri(nlev), edni(nlev), eupi(nlev)
+      REAL fdiri(nlev), fdni(nlev), fupi(nlev)
+
+      logical, save :: delta = .true.
+
+!_______________________________________________________________________
+
+! initialize:
+
+      do i = 1, nlev
+         fdir(i) = 0.
+         fup(i)  = 0.
+         fdn(i)  = 0.
+         edir(i) = 0.
+         eup(i)  = 0.
+         edn(i)  = 0.
+      end do
+
+      do i = 1, nlev - 1
+         dscld = dtcld(i,iw)*omcld(i,iw)
+         dacld = dtcld(i,iw)*(1.-omcld(i,iw))
+
+         dsaer = dtaer(i,iw)*omaer(i,iw)
+         daaer = dtaer(i,iw)*(1.-omaer(i,iw))
+
+         dtsct = dtrl(i,iw) + dscld + dsaer
+         dtabs = dagas(i,iw) + dacld + daaer
+
+         dtabs = amax1(dtabs,1./largest)
+         dtsct = amax1(dtsct,1./largest)
+
+!     invert z-coordinate:
+
+         ii = nlev - i
+         dt(ii) = dtsct + dtabs
+         om(ii) = dtsct/(dtsct + dtabs)
+         IF(dtsct .EQ. 1./largest) om(ii) = 1./largest
+         g(ii) = (gcld(i,iw)*dscld + 
+     $            gaer(i,iw)*dsaer)/dtsct
+      end do
+
+!     call rt routine:
+
+      call ps2str(nlev, zen, ag, dt, om, g,
+     $            dsdh, nid, delta,
+     $            fdiri, fupi, fdni, ediri, eupi, edni)
+
+!     output (invert z-coordinate)
+
+      do i = 1, nlev
+         ii = nlev - i + 1
+         fdir(i) = fdiri(ii)
+         fup(i) = fupi(ii)
+         fdn(i) = fdni(ii)
+         edir(i) = ediri(ii)
+         eup(i) = eupi(ii)
+         edn(i) = edni(ii)
+      end do
+
+      end subroutine rtlink
+
+*=============================================================================*
+
+      subroutine ps2str(nlev,zen,rsfc,tauu,omu,gu,
+     $                  dsdh, nid, delta,
+     $                  fdr, fup, fdn, edr, eup, edn)
+
+!-----------------------------------------------------------------------------*
+!=  PURPOSE:                                                                 =*
+!=  Solve two-stream equations for multiple layers.  The subroutine is based =*
+!=  on equations from:  Toon et al., J.Geophys.Res., v94 (D13), Nov 20, 1989.=*
+!=  It contains 9 two-stream methods to choose from.  A pseudo-spherical     =*
+!=  correction has also been added.                                          =*
+!-----------------------------------------------------------------------------*
+!=  PARAMETERS:                                                              =*
+!=  NLEVEL  - INTEGER, number of specified altitude levels in the working (I)=*
+!=            grid                                                           =*
+!=  ZEN     - REAL, solar zenith angle (degrees)                          (I)=*
+!=  RSFC    - REAL, surface albedo at current wavelength                  (I)=*
+!=  TAUU    - REAL, unscaled optical depth of each layer                  (I)=*
+!=  OMU     - REAL, unscaled single scattering albedo of each layer       (I)=*
+!=  GU      - REAL, unscaled asymmetry parameter of each layer            (I)=*
+!=  DSDH    - REAL, slant path of direct beam through each layer crossed  (I)=*
+!=            when travelling from the top of the atmosphere to layer i;     =*
+!=            DSDH(i,j), i = 0..NZ-1, j = 1..NZ-1                            =*
+!=  NID     - INTEGER, number of layers crossed by the direct beam when   (I)=*
+!=            travelling from the top of the atmosphere to layer i;          =*
+!=            NID(i), i = 0..NZ-1                                            =*
+!=  DELTA   - LOGICAL, switch to use delta-scaling                        (I)=*
+!=            .TRUE. -> apply delta-scaling                                  =*
+!=            .FALSE.-> do not apply delta-scaling                           =*
+!=  FDR     - REAL, contribution of the direct component to the total     (O)=*
+!=            actinic flux at each altitude level                            =*
+!=  FUP     - REAL, contribution of the diffuse upwelling component to    (O)=*
+!=            the total actinic flux at each altitude level                  =*
+!=  FDN     - REAL, contribution of the diffuse downwelling component to  (O)=*
+!=            the total actinic flux at each altitude level                  =*
+!=  EDR     - REAL, contribution of the direct component to the total     (O)=*
+!=            spectral irradiance at each altitude level                     =*
+!=  EUP     - REAL, contribution of the diffuse upwelling component to    (O)=*
+!=            the total spectral irradiance at each altitude level           =*
+!=  EDN     - REAL, contribution of the diffuse downwelling component to  (O)=*
+*=            the total spectral irradiance at each altitude level           =*
+!-----------------------------------------------------------------------------*
+
+      implicit none
+
+! input:
+
+      INTEGER nlev
+      REAL zen, rsfc
+      REAL tauu(nlev), omu(nlev), gu(nlev)
+      REAL dsdh(0:nlev,nlev)
+      INTEGER nid(0:nlev)
+      LOGICAL delta
+
+! output:
+
+      REAL fup(nlev),fdn(nlev),fdr(nlev)
+      REAL eup(nlev),edn(nlev),edr(nlev)
+
+! local:
+
+      REAL tausla(0:nlev), tauc(0:nlev)
+      REAL mu2(0:nlev), mu, sum
+
+! internal coefficients and matrix
+
+      REAL lam(nlev),taun(nlev),bgam(nlev)
+      REAL e1(nlev),e2(nlev),e3(nlev),e4(nlev)
+      REAL cup(nlev),cdn(nlev),cuptn(nlev),cdntn(nlev)
+      REAL mu1(nlev)
+      INTEGER row
+      REAL a(2*nlev),b(2*nlev),d(2*nlev),e(2*nlev),y(2*nlev)
+
+! other:
+
+      REAL pifs, fdn0
+      REAL gi(nlev), omi(nlev), tempg
+      REAL f, g, om
+      REAL gam1, gam2, gam3, gam4
+      real, parameter :: largest = 1.e+36
+      real, parameter :: precis = 1.e-7
+
+! For calculations of Associated Legendre Polynomials for GAMA1,2,3,4
+! in delta-function, modified quadrature, hemispheric constant,
+! Hybrid modified Eddington-delta function metods, p633,Table1.
+! W.E.Meador and W.R.Weaver, GAS,1980,v37,p.630
+! W.J.Wiscombe and G.W. Grams, GAS,1976,v33,p2440, 
+! uncomment the following two lines and the appropriate statements further
+! down.
+!     REAL YLM0, YLM2, YLM4, YLM6, YLM8, YLM10, YLM12, YLMS, BETA0,
+!    >     BETA1, BETAn, amu1, subd
+
+      REAL expon, expon0, expon1, divisr, temp, up, dn
+      REAL ssfc
+      INTEGER nlayer, mrows, lev
+
+      INTEGER i, j
+
+! Some additional program constants:
+
+      real pi, dr
+      REAL eps
+      PARAMETER (eps = 1.E-3)
+!_______________________________________________________________________
+
+! MU = cosine of solar zenith angle
+! RSFC = surface albedo
+! TAUU =  unscaled optical depth of each layer
+! OMU  =  unscaled single scattering albedo
+! GU   =  unscaled asymmetry factor
+! KLEV = max dimension of number of layers in atmosphere
+! NLAYER = number of layers in the atmosphere
+! NLEVEL = nlayer + 1 = number of levels
+
+! initial conditions:  pi*solar flux = 1;  diffuse incidence = 0
+
+      pifs = 1.      
+      fdn0 = 0.
+
+      nlayer = nlev - 1
+
+      pi = acos(-1.)
+      dr = pi/180.
+      mu = COS(zen*dr)
+
+!************* compute coefficients for each layer:
+! GAM1 - GAM4 = 2-stream coefficients, different for different approximations
+! EXPON0 = calculation of e when TAU is zero
+! EXPON1 = calculation of e when TAU is TAUN
+! CUP and CDN = calculation when TAU is zero
+! CUPTN and CDNTN = calc. when TAU is TAUN
+! DIVISR = prevents division by zero
+
+      do j = 0, nlev
+         tauc(j) = 0.
+         tausla(j) = 0.
+         mu2(j) = 1./SQRT(largest)
+      end do
+
+      IF (.NOT. delta) THEN
+         DO i = 1, nlayer
+            gi(i) = gu(i)
+            omi(i) = omu(i)
+            taun(i) = tauu(i)
+         END DO
+      ELSE 
+
+! delta-scaling. Have to be done for delta-Eddington approximation, 
+! delta discrete ordinate, Practical Improved Flux Method, delta function,
+! and Hybrid modified Eddington-delta function methods approximations
+
+         DO i = 1, nlayer
+            f = gu(i)*gu(i)
+            gi(i) = (gu(i) - f)/(1 - f)
+            omi(i) = (1 - f)*omu(i)/(1 - omu(i)*f)       
+            taun(i) = (1 - omu(i)*f)*tauu(i)
+         END DO
+      END IF
+
+! calculate slant optical depth at the top of the atmosphere when zen>90.
+! in this case, higher altitude of the top layer is recommended.
+
+      IF (zen .GT. 90.0) THEN
+         IF (nid(0) .LT. 0) THEN
+            tausla(0) = largest
+         ELSE
+            sum = 0.0
+            DO j = 1, nid(0)
+               sum = sum + 2.*taun(j)*dsdh(0,j)
+            END DO
+            tausla(0) = sum 
+         END IF
+      END IF
+
+      DO 11, i = 1, nlayer
+          g = gi(i)
+          om = omi(i)
+          tauc(i) = tauc(i-1) + taun(i)
+
+! stay away from 1 by precision.  For g, also stay away from -1
+
+          tempg = AMIN1(abs(g),1. - precis)
+          g = SIGN(tempg,g)
+          om = AMIN1(om,1.-precis)
+
+! calculate slant optical depth
+              
+          IF (nid(i) .LT. 0) THEN
+             tausla(i) = largest
+          ELSE
+             sum = 0.0
+             DO j = 1, MIN(nid(i),i)
+                sum = sum + taun(j)*dsdh(i,j)
+             END DO
+             DO j = MIN(nid(i),i)+1,nid(i)
+                sum = sum + 2.*taun(j)*dsdh(i,j)
+             END DO
+             tausla(i) = sum 
+             IF (tausla(i) .EQ. tausla(i-1)) THEN
+                mu2(i) = SQRT(largest)
+             ELSE
+                mu2(i) = (tauc(i)-tauc(i-1))/(tausla(i)-tausla(i-1))
+                mu2(i) = SIGN( AMAX1(ABS(mu2(i)),1./SQRT(largest)),
+     $                     mu2(i) )
+             END IF
+          END IF
+
+!** the following gamma equations are from pg 16,289, Table 1
+!** save mu1 for each approx. for use in converting irradiance to actinic flux
+
+! Eddington approximation(Joseph et al., 1976, JAS, 33, 2452):
+
+c       gam1 =  (7. - om*(4. + 3.*g))/4.
+c       gam2 = -(1. - om*(4. - 3.*g))/4.
+c       gam3 = (2. - 3.*g*mu)/4.
+c       gam4 = 1. - gam3
+c       mu1(i) = 0.5
+
+* quadrature (Liou, 1973, JAS, 30, 1303-1326; 1974, JAS, 31, 1473-1475):
+
+c          gam1 = 1.7320508*(2. - om*(1. + g))/2.
+c          gam2 = 1.7320508*om*(1. - g)/2.
+c          gam3 = (1. - 1.7320508*g*mu)/2.
+c          gam4 = 1. - gam3
+c          mu1(i) = 1./sqrt(3.)
+         
+* hemispheric mean (Toon et al., 1089, JGR, 94, 16287):
+
+           gam1 = 2. - om*(1. + g)
+           gam2 = om*(1. - g)
+           gam3 = (2. - g*mu)/4.
+           gam4 = 1. - gam3
+           mu1(i) = 0.5
+
+* PIFM  (Zdunkovski et al.,1980, Conrib.Atmos.Phys., 53, 147-166):
+c         GAM1 = 0.25*(8. - OM*(5. + 3.*G))
+c         GAM2 = 0.75*OM*(1.-G)
+c         GAM3 = 0.25*(2.-3.*G*MU)
+c         GAM4 = 1. - GAM3
+c         mu1(i) = 0.5
+
+* delta discrete ordinates  (Schaller, 1979, Contrib.Atmos.Phys, 52, 17-26):
+c         GAM1 = 0.5*1.7320508*(2. - OM*(1. + G))
+c         GAM2 = 0.5*1.7320508*OM*(1.-G)
+c         GAM3 = 0.5*(1.-1.7320508*G*MU)
+c         GAM4 = 1. - GAM3
+c         mu1(i) = 1./sqrt(3.)
+
+* Calculations of Associated Legendre Polynomials for GAMA1,2,3,4
+* in delta-function, modified quadrature, hemispheric constant,
+* Hybrid modified Eddington-delta function metods, p633,Table1.
+* W.E.Meador and W.R.Weaver, GAS,1980,v37,p.630
+* W.J.Wiscombe and G.W. Grams, GAS,1976,v33,p2440
+c      YLM0 = 2.
+c      YLM2 = -3.*G*MU
+c      YLM4 = 0.875*G**3*MU*(5.*MU**2-3.)
+c      YLM6=-0.171875*G**5*MU*(15.-70.*MU**2+63.*MU**4)
+c     YLM8=+0.073242*G**7*MU*(-35.+315.*MU**2-693.*MU**4
+c    *+429.*MU**6)
+c     YLM10=-0.008118*G**9*MU*(315.-4620.*MU**2+18018.*MU**4
+c    *-25740.*MU**6+12155.*MU**8)
+c     YLM12=0.003685*G**11*MU*(-693.+15015.*MU**2-90090.*MU**4
+c    *+218790.*MU**6-230945.*MU**8+88179.*MU**10)
+c      YLMS=YLM0+YLM2+YLM4+YLM6+YLM8+YLM10+YLM12
+c      YLMS=0.25*YLMS
+c      BETA0 = YLMS
+c
+c         amu1=1./1.7320508
+c      YLM0 = 2.
+c      YLM2 = -3.*G*amu1
+c      YLM4 = 0.875*G**3*amu1*(5.*amu1**2-3.)
+c      YLM6=-0.171875*G**5*amu1*(15.-70.*amu1**2+63.*amu1**4)
+c     YLM8=+0.073242*G**7*amu1*(-35.+315.*amu1**2-693.*amu1**4
+c    *+429.*amu1**6)
+c     YLM10=-0.008118*G**9*amu1*(315.-4620.*amu1**2+18018.*amu1**4
+c    *-25740.*amu1**6+12155.*amu1**8)
+c     YLM12=0.003685*G**11*amu1*(-693.+15015.*amu1**2-90090.*amu1**4
+c    *+218790.*amu1**6-230945.*amu1**8+88179.*amu1**10)
+c      YLMS=YLM0+YLM2+YLM4+YLM6+YLM8+YLM10+YLM12
+c      YLMS=0.25*YLMS
+c      BETA1 = YLMS
+c
+c         BETAn = 0.25*(2. - 1.5*G-0.21875*G**3-0.085938*G**5
+c    *-0.045776*G**7)
+
+
+* Hybrid modified Eddington-delta function(Meador and Weaver,1980,JAS,37,630):
+c         subd=4.*(1.-G*G*(1.-MU))
+c         GAM1 = (7.-3.*G*G-OM*(4.+3.*G)+OM*G*G*(4.*BETA0+3.*G))/subd
+c         GAM2 =-(1.-G*G-OM*(4.-3.*G)-OM*G*G*(4.*BETA0+3.*G-4.))/subd
+c         GAM3 = BETA0
+c         GAM4 = 1. - GAM3
+c         mu1(i) = (1. - g*g*(1.- mu) )/(2. - g*g)
+
+*****
+* delta function  (Meador, and Weaver, 1980, JAS, 37, 630):
+c         GAM1 = (1. - OM*(1. - beta0))/MU
+c         GAM2 = OM*BETA0/MU
+c         GAM3 = BETA0
+c         GAM4 = 1. - GAM3
+c         mu1(i) = mu
+*****
+* modified quadrature (Meador, and Weaver, 1980, JAS, 37, 630):
+c         GAM1 = 1.7320508*(1. - OM*(1. - beta1))
+c         GAM2 = 1.7320508*OM*beta1
+c         GAM3 = BETA0
+c         GAM4 = 1. - GAM3
+c         mu1(i) = 1./sqrt(3.)
+
+* hemispheric constant (Toon et al., 1989, JGR, 94, 16287):
+c         GAM1 = 2.*(1. - OM*(1. - betan))
+c         GAM2 = 2.*OM*BETAn
+c         GAM3 = BETA0
+c         GAM4 = 1. - GAM3
+c         mu1(i) = 0.5
+
+*****
+
+* lambda = pg 16,290 equation 21
+* big gamma = pg 16,290 equation 22
+* if gam2 = 0., then bgam = 0. 
+
+         lam(i) = sqrt(gam1*gam1 - gam2*gam2)
+
+         IF (gam2 .NE. 0.) THEN
+            bgam(i) = (gam1 - lam(i))/gam2
+         ELSE
+            bgam(i) = 0.
+         END IF
+
+         expon = EXP(-lam(i)*taun(i))
+
+* e1 - e4 = pg 16,292 equation 44
+         
+         e1(i) = 1. + bgam(i)*expon
+         e2(i) = 1. - bgam(i)*expon
+         e3(i) = bgam(i) + expon
+         e4(i) = bgam(i) - expon
+
+* the following sets up for the C equations 23, and 24
+* found on page 16,290
+* prevent division by zero (if LAMBDA=1/MU, shift 1/MU^2 by EPS = 1.E-3
+* which is approx equiv to shifting MU by 0.5*EPS* (MU)**3
+
+         expon0 = EXP(-tausla(i-1))
+         expon1 = EXP(-tausla(i))
+          
+         divisr = lam(i)*lam(i) - 1./(mu2(i)*mu2(i))
+         temp = AMAX1(eps,abs(divisr))
+         divisr = SIGN(temp,divisr)
+
+         up = om*pifs*((gam1 - 1./mu2(i))*gam3 + gam4*gam2)/divisr
+         dn = om*pifs*((gam1 + 1./mu2(i))*gam4 + gam2*gam3)/divisr
+         
+* cup and cdn are when tau is equal to zero
+* cuptn and cdntn are when tau is equal to taun
+
+         cup(i) = up*expon0
+         cdn(i) = dn*expon0
+         cuptn(i) = up*expon1
+         cdntn(i) = dn*expon1
+ 
+   11 CONTINUE
+
+***************** set up matrix ******
+* ssfc = pg 16,292 equation 37  where pi Fs is one (unity).
+
+      ssfc = rsfc*mu*EXP(-tausla(nlayer))*pifs
+
+* MROWS = the number of rows in the matrix
+
+      mrows = 2*nlayer     
+      
+* the following are from pg 16,292  equations 39 - 43.
+* set up first row of matrix:
+
+      i = 1
+      a(1) = 0.
+      b(1) = e1(i)
+      d(1) = -e2(i)
+      e(1) = fdn0 - cdn(i)
+
+      row=1
+
+* set up odd rows 3 thru (MROWS - 1):
+
+      i = 0
+      DO 20, row = 3, mrows - 1, 2
+         i = i + 1
+         a(row) = e2(i)*e3(i) - e4(i)*e1(i)
+         b(row) = e1(i)*e1(i + 1) - e3(i)*e3(i + 1)
+         d(row) = e3(i)*e4(i + 1) - e1(i)*e2(i + 1)
+         e(row) = e3(i)*(cup(i + 1) - cuptn(i)) + 
+     $        e1(i)*(cdntn(i) - cdn(i + 1))
+   20 CONTINUE
+
+* set up even rows 2 thru (MROWS - 2): 
+
+      i = 0
+      DO 30, row = 2, mrows - 2, 2
+         i = i + 1
+         a(row) = e2(i + 1)*e1(i) - e3(i)*e4(i + 1)
+         b(row) = e2(i)*e2(i + 1) - e4(i)*e4(i + 1)
+         d(row) = e1(i + 1)*e4(i + 1) - e2(i + 1)*e3(i + 1)
+         e(row) = (cup(i + 1) - cuptn(i))*e2(i + 1) - 
+     $        (cdn(i + 1) - cdntn(i))*e4(i + 1)
+   30 CONTINUE
+
+* set up last row of matrix at MROWS:
+
+      row = mrows
+      i = nlayer
+      
+      a(row) = e1(i) - rsfc*e3(i)
+      b(row) = e2(i) - rsfc*e4(i)
+      d(row) = 0.
+      e(row) = ssfc - cuptn(i) + rsfc*cdntn(i)
+
+* solve tri-diagonal matrix:
+
+      CALL tridiag(a, b, d, e, y, mrows)
+
+**** unfold solution of matrix, compute output fluxes:
+
+      row = 1 
+      lev = 1
+      j = 1
+      
+* the following equations are from pg 16,291  equations 31 & 32
+
+      fdr(lev) = EXP( -tausla(0) )
+      edr(lev) = mu * fdr(lev)
+      edn(lev) = fdn0
+      eup(lev) =  y(row)*e3(j) - y(row + 1)*e4(j) + cup(j)
+      fdn(lev) = edn(lev)/mu1(lev)
+      fup(lev) = eup(lev)/mu1(lev)
+
+      DO 60, lev = 2, nlayer + 1
+         fdr(lev) = EXP(-tausla(lev-1))
+         edr(lev) =  mu *fdr(lev)
+         edn(lev) =  y(row)*e3(j) + y(row + 1)*e4(j) + cdntn(j)
+         eup(lev) =  y(row)*e1(j) + y(row + 1)*e2(j) + cuptn(j)
+         fdn(lev) = edn(lev)/mu1(j)
+         fup(lev) = eup(lev)/mu1(j)
+
+         row = row + 2
+         j = j + 1
+   60 CONTINUE
+
+      end subroutine ps2str
+
+*=============================================================================*
+
+      subroutine tridiag(a,b,c,r,u,n)
+
+!_______________________________________________________________________
+! solves tridiagonal system.  From Numerical Recipies, p. 40
+!_______________________________________________________________________
+
+      IMPLICIT NONE
+
+! input:
+
+      INTEGER n
+      REAL a, b, c, r
+      DIMENSION a(n),b(n),c(n),r(n)
+
+! output:
+
+      REAL u
+      DIMENSION u(n)
+
+! local:
+
+      INTEGER j
+
+      REAL bet, gam
+      DIMENSION gam(n)
+!_______________________________________________________________________
+
+      IF (b(1) .EQ. 0.) STOP 1001
+      bet   = b(1)
+      u(1) = r(1)/bet
+      DO 11, j = 2, n   
+         gam(j) = c(j - 1)/bet
+         bet = b(j) - a(j)*gam(j)
+         IF (bet .EQ. 0.) STOP 2002 
+         u(j) = (r(j) - a(j)*u(j - 1))/bet
+   11 CONTINUE
+      DO 12, j = n - 1, 1, -1  
+         u(j) = u(j) - gam(j + 1)*u(j + 1)
+   12 CONTINUE
+!_______________________________________________________________________
+
+      end subroutine tridiag
+
+!==============================================================================
+ 
+      subroutine setalb(nw,wl,ig,ngrid,albedo_chim)
+ 
+!-----------------------------------------------------------------------------*
+!=  PURPOSE:                                                                 =*
+!=  Set the albedo of the surface.  The albedo is assumed to be Lambertian,  =*
+!=  i.e., the reflected light is isotropic, and idependt of the direction    =*
+!=  of incidence of light.  Albedo can be chosen to be wavelength dependent. =*
+!-----------------------------------------------------------------------------*
+!=  PARAMETERS:                                                              =*
+!=  NW      - INTEGER, number of specified intervals + 1 in working       (I)=*
+!=            wavelength grid                                                =*
+!=  WL     - REAL, vector of lower limits of wavelength intervals in      (I)=*
+!=           working wavelength grid                                         =*
+!=  ALBEDO  - REAL, surface albedo at each specified wavelength           (O)=*
+!-----------------------------------------------------------------------------*
+
+      use chimiedata_h,  only: albedo_snow_chim, albedo_co2_ice_chim
+      use slab_ice_h,    only: h_alb_ice, alb_ice_min, alb_ice_max
+      use tracer_h,      only: igcm_h2o_ice, igcm_co2_ice
+      use callkeys_mod,  only: ok_slab_ocean, co2cond, alb_ocean
+      use phys_state_var_mod, only: albedo_bareground, 
+     &                              rnat, qsurf, sea_ice,
+     &                              pctsrf_sic, tsurf, capcal
+      use watercommon_h, only: T_h2O_ice_liq, RLFTT, rhowater
+
+      implicit none
+
+! input: (wavelength working grid data)
+
+      integer, intent(in) :: ngrid  ! number of atmospheric columns
+      INTEGER nw
+      INTEGER ig             ! grid point index
+      REAL wl(nw)
+
+! output:
+
+      REAL albedo_chim(nw)
+
+! local:
+
+      INTEGER iw
+!      REAL alb
+      real zfra, alb_ice, twater, hice
+      real snowlayer
+      parameter (snowlayer=33.0)        ! 33 kg/m^2 of snow, equal to a layer of 3.3 cm
+
+!     0.015: mean value from clancy et al., icarus, 49-63, 1999.
+
+!      alb = 0.015
+!      alb = albedo_phys
+
+!      do iw = 1, nw - 1
+!         albedo_chim(iw) = alb
+!      end do
+
+!     See hydrol.F90 for taking into account new tendencies
+
+      if(nint(rnat(ig)).eq.0)then
+
+        if(ok_slab_ocean) then
+        
+          zfra = MAX(0.0,MIN(1.0,qsurf(ig,igcm_h2o_ice)/45.0))     ! Snow Fraction (Critical height 45kg/m2~15cm)
+          alb_ice=alb_ice_max-(alb_ice_max-alb_ice_min)            ! Ice Albedo
+     &                        *exp(-sea_ice(ig)/h_alb_ice)
+          ! Albedo final calculation :
+          do iw=1,nw - 1
+             albedo_chim(iw) = pctsrf_sic(ig)*
+     &                        (albedo_snow_chim(iw)*zfra
+     &                        + alb_ice*(1.0-zfra))
+     &                        + (1.-pctsrf_sic(ig))*alb_ocean
+          enddo  
+
+        else !ok_slab_ocean
+            
+            
+!     calculate oceanic ice height including the latent heat of ice formation
+!     hice is the height of oceanic ice with a maximum of maxicethick.
+          hice    = qsurf(ig,igcm_h2o_ice)/rhowater ! update hice to include recent snowfall
+          twater  = tsurf(ig) - hice*RLFTT*rhowater/capcal(ig)
+          ! this is temperature water would have if we melted entire ocean ice layer
+
+          if(twater .lt. T_h2O_ice_liq)then
+
+            do iw=1,nw - 1
+              albedo_chim(iw) = albedo_snow_chim(iw) ! Albedo of ice has been replaced by albedo of snow here. MT2015.
+            enddo
+
+          else
+
+            DO iw=1,nw - 1
+              albedo_chim(iw) = alb_ocean
+              if(ngrid.eq.1) then
+                albedo_chim(iw) = albedo_bareground(ig)
+              endif
+            ENDDO
+
+          endif
+
+        endif!(ok_slab_ocean)
+
+
+!     Continent
+!     ---------
+      elseif (nint(rnat(ig)).eq.1) then
+
+!     re-calculate continental albedo
+        if (qsurf(ig,igcm_h2o_ice).ge.snowlayer) then
+          DO iw=1,nw - 1
+            albedo_chim(iw) = albedo_snow_chim(iw)
+          ENDDO
+        else
+          DO iw=1,nw - 1
+            albedo_chim(iw) = albedo_bareground(ig)
+     &                      + (albedo_snow_chim(iw)
+     &                         - albedo_bareground(ig))
+     &                      *qsurf(ig,igcm_h2o_ice)/snowlayer
+          ENDDO
+        endif
+
+      else
+
+        print*,'Surface type not recognised in photolysis_online.F!'
+        print*,'Exiting...'
+        call abort
+
+      endif
+
+!     Re-add the albedo effects of CO2 ice if necessary
+!     -------------------------------------------------
+      if(co2cond)then
+
+          if (qsurf(ig,igcm_co2_ice).gt.1.) then ! Condition changed - Need now ~1 mm CO2 ice coverage. MT2015
+            DO iw=1,nw - 1
+              albedo_chim(iw) = albedo_co2_ice_chim(iw)
+            ENDDO
+          endif
+            
+      endif ! co2cond
+
+      end subroutine setalb
+
+!==============================================================================
+ 
+      subroutine setsj(nd,nlayer,nw,tlay,tdiml,xsl,xs_templ,sjl)
+
+
+      implicit none
+
+! input: (wavelength working grid data)
+
+      integer :: nd                                      ! number of photolysis rates
+      integer :: nlayer                                  ! number of vertical layers
+      integer :: nw                                      ! number of wavelength grid points
+      integer :: tdiml                                   ! number of different temperature cross section file
+      real    :: xsl(tdiml,nw)                           ! cross section (cm2) from reading files
+      real    :: xs_templ(tdiml)                         ! temperature of the cross section (cm2)
+      real    :: tlay(nlayer)                            ! temperature (K)
+
+! output:
+
+      real    :: sjl(nlayer,nw)                          ! output cross section (cm2)
+
+
+! local:
+
+      INTEGER ilay,iw,tpos
+
+        do iw = 1,nw-1
+          do ilay = 1,nlayer
+            tpos = 1
+            do while(tlay(ilay)>xs_templ(tpos) .and. tpos<tdiml)
+              tpos = tpos + 1
+            end do
+            if (tpos.eq.1 .or. tpos.eq.tdiml) then
+              sjl(ilay,iw) = xsl(tpos,iw)
+            else
+              sjl(ilay,iw) = ( (xsl(tpos,iw)-xsl(tpos-1,iw))*
+     $                       (tlay(ilay)-xs_templ(tpos-1))
+     $                       /(xs_templ(tpos)-xs_templ(tpos-1))
+     $                       + xsl(tpos-1,iw) )
+            end if
+          end do
+        end do
+
+      end subroutine setsj
+
+      end subroutine photolysis_online
Index: trunk/LMDZ.GENERIC/libf/aeronostd/read_phototable.F90
===================================================================
--- trunk/LMDZ.GENERIC/libf/aeronostd/read_phototable.F90	(revision 2541)
+++ trunk/LMDZ.GENERIC/libf/aeronostd/read_phototable.F90	(revision 2542)
@@ -13,9 +13,10 @@
 !
 !   Author:   Franck Lefevre
+!   update 06/03/2021 dimension set in table + CH4 dimension + photoheat (Yassin Jaziri)
 !
 !   Arguments:
 !   ----------
 !
-!   The output variable is jphot and is put in common chimiedata.
+!   The output variable is jphot/ephot and is put in common chimiedata.
 !
 !***********************************************************************
@@ -24,7 +25,9 @@
       use ioipsl_getin_p_mod, only: getin_p
       use datafile_mod
+      use callkeys_mod
+      use chimiedata_h
       implicit none
 
-#include "chimiedata.h"
+!#include "chimiedata.h"
 
 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
@@ -32,8 +35,9 @@
 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
 
-      integer :: fic, ij, iozo, isza, itemp, iz, itau, ierr
-      real    :: xsza
+      integer :: fic, ij, iozo, isza, itemp, iz, itau, ich4, ierr
+      real    :: xsza, dummy
 
       character(len = 128) :: phototable ! photolysis table file name
+      character(len = 128) :: ephototable ! energie photolysis table file name
 
 !ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
@@ -73,15 +77,27 @@
       print*, 'read photolysis lookup table ',trim(phototable)
 
+      read(fic,*) nz, nsza, nozo, dummy, ntemp, ntau, nch4, nd
+
+      allocate(jphot(ntemp,nsza,nz,nozo,ntau,nch4,nd))
+      allocate(ephot(ntemp,nsza,nz,nozo,ntau,nch4,nd))
+      allocate(colairtab(nz))
+      allocate(szatab(nsza))
+      allocate(table_ozo(nozo))
+      allocate(tautab(ntau))
+      allocate(table_ch4(nch4))
+
       do itau = 1,ntau
          do itemp = 1,ntemp
             do iozo = 1,nozo
-               do isza = 1,nsza
-                  do iz = nz,1,-1
-                     read(fic,*) colairtab(iz), xsza, table_ozo(iozo)
-                     read(fic,'(7e11.4)') (jphot(itemp,isza,iz,iozo,itau,ij), ij= 1,nd)
-                     do ij = 1,nd
-                        if (jphot(itemp,isza,iz,iozo,itau,ij) == 1.e-30) then
-                           jphot(itemp,isza,iz,iozo,itau,ij) = 0.
-                        end if
+               do ich4 =1,nch4
+                  do isza = 1,nsza
+                     do iz = nz,1,-1
+                        read(fic,*) colairtab(iz), szatab(isza),table_ozo(iozo), dummy, dummy, dummy, table_ch4(ich4)
+                        read(fic,'(7e11.4)') (jphot(itemp,isza,iz,iozo,itau,ich4,ij), ij= 1,nd)
+                        do ij = 1,nd
+                           if (jphot(itemp,isza,iz,iozo,itau,ich4,ij) == 1.e-30) then
+                              jphot(itemp,isza,iz,iozo,itau,ich4,ij) = 0.
+                           end if
+                        end do
                      end do
                   end do
@@ -94,4 +110,65 @@
       close(fic)
 
+      if (photoheat) then 
+!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+! set energie photolysis table input file name
+!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+
+
+
+! look for a " ephototable= ..." option in def files
+     write(*,*) "Directory where external input files are:"
+      ephototable = "zdtearth_N+_CO2_0.0004_O2_0.21_G11" ! default
+     call getin_p("ephototable",ephototable) ! default path
+     write(*,*) " ephototable = ",trim(ephototable)
+
+
+      fic = 81
+
+      open(fic, form = 'formatted', status = 'old',                &
+           file =trim(datadir)//"/"//trim(ephototable),iostat=ierr)
+
+      if (ierr /= 0) THEN
+        write(*,*)'Error : cannot open energie photolysis lookup table ', trim(ephototable)
+        write(*,*)'It should be in :',trim(datadir),'/'
+        write(*,*)'1) You can change this directory in callphys.def'
+        write(*,*)'   with:'
+        write(*,*)'   datadir=/path/to/the/directory'
+        write(*,*)'2) You can change the input ephototable file name in'
+        write(*,*)'   callphys.def with:'
+        write(*,*)'   ephototable=filename'
+        stop
+      end if
+
+!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+! read energie photolys table
+!ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
+
+      print*, 'read energie photolysis lookup table ',trim(ephototable)
+
+      do itau = 1,ntau
+         do itemp = 1,ntemp
+            do iozo = 1,nozo
+               do ich4 =1,nch4
+                  do isza = 1,nsza
+                     do iz = nz,1,-1
+                        read(fic,*) colairtab(iz), xsza,table_ozo(iozo), dummy, dummy, dummy, table_ch4(ich4)
+                        read(fic,'(7e11.4)') (ephot(itemp,isza,iz,iozo,itau,ich4,ij), ij= 1,nd)
+                        do ij = 1,nd
+                           if (ephot(itemp,isza,iz,iozo,itau,ich4,ij) == 1.e-30) then
+                              ephot(itemp,isza,iz,iozo,itau,ich4,ij) = 0.
+                           end if
+                        end do
+                     end do
+                  end do
+               end do
+            end do
+         end do
+      end do
+
+      print*, 'lookup etable...ok'
+      close(fic)
+      end if
+
       return
       end
Index: trunk/LMDZ.GENERIC/libf/aeronostd/types_asis.F90
===================================================================
--- trunk/LMDZ.GENERIC/libf/aeronostd/types_asis.F90	(revision 2541)
+++ trunk/LMDZ.GENERIC/libf/aeronostd/types_asis.F90	(revision 2542)
@@ -7,20 +7,20 @@
 
 type z3spec
-	real(kind=jprb)    :: z1
-        integer(kind=jpim) :: z2
-	real(kind=jprb)    :: z3
-        integer(kind=jpim) :: z4
-	real(kind=jprb)    :: z5
-        integer(kind=jpim) :: z6
+    real(kind=jprb)    :: z1
+    integer(kind=jpim) :: z2
+    real(kind=jprb)    :: z3
+    integer(kind=jpim) :: z4
+    real(kind=jprb)    :: z5
+    integer(kind=jpim) :: z6
 end type z3spec
 type z4spec
-	real(kind=jprb)    :: z1
-        integer(kind=jpim) :: z2
-	real(kind=jprb)    :: z3
-        integer(kind=jpim) :: z4
-	real(kind=jprb)    :: z5
-        integer(kind=jpim) :: z6
-	real(kind=jprb)    :: z7
-        integer(kind=jpim) :: z8
+    real(kind=jprb)    :: z1
+    integer(kind=jpim) :: z2
+    real(kind=jprb)    :: z3
+    integer(kind=jpim) :: z4
+    real(kind=jprb)    :: z5
+    integer(kind=jpim) :: z6
+    real(kind=jprb)    :: z7
+    integer(kind=jpim) :: z8
 end type z4spec
 
@@ -31,3 +31,70 @@
 type(z4spec), allocatable, save :: indice_4(:)
 
+! dimension of indexes variables
+
+integer, save :: nb_phot_max       ! dimension of phot reaction, including photolysis and quenching reaction
+integer, save :: nb_reaction_3_max
+integer, save :: nb_reaction_4_max
+integer, save :: nb_phot_hv_max    ! dimension of photolysis, including three product photolysis
+
+! photolysis reaction rate and label
+
+real (kind = 8),      allocatable, save :: v_phot_3d(:,:,:)
+character(len = 20),  allocatable, save :: jlabel(:,:)        ! photolysis label and species name
+character(len = 300), allocatable, save :: jparamline(:)      ! line of jonline parameters
+
+! pfunc type
+
+type rtype1
+    real(kind=jprb)    :: a
+    real(kind=jprb)    :: b
+    real(kind=jprb)    :: c
+    real(kind=jprb)    :: t0
+    real(kind=jprb)    :: d
+end type rtype1
+
+type rtype2
+    real(kind=jprb)    :: k0
+    real(kind=jprb)    :: n
+    real(kind=jprb)    :: a
+    real(kind=jprb)    :: kinf
+    real(kind=jprb)    :: m
+    real(kind=jprb)    :: b
+    real(kind=jprb)    :: t0
+    real(kind=jprb)    :: fc
+    real(kind=jprb)    :: g
+    real(kind=jprb)    :: h
+    real(kind=jprb)    :: dup
+    real(kind=jprb)    :: ddown
+end type rtype2
+
+type rtype3
+    real(kind=jprb)    :: k0
+    real(kind=jprb)    :: n
+    real(kind=jprb)    :: a
+    real(kind=jprb)    :: kinf
+    real(kind=jprb)    :: m
+    real(kind=jprb)    :: b
+    real(kind=jprb)    :: t0
+    real(kind=jprb)    :: atroe
+    real(kind=jprb)    :: btroe
+    real(kind=jprb)    :: ctroe
+    real(kind=jprb)    :: dtroe
+    real(kind=jprb)    :: dup
+    real(kind=jprb)    :: ddown
+end type rtype3
+
+! pfunc parameters for the reaction rates
+
+type(rtype1), allocatable, save :: pfunc1_param(:)
+type(rtype2), allocatable, save :: pfunc2_param(:)
+type(rtype3), allocatable, save :: pfunc3_param(:)
+
+! dimension of pfunc type variables
+
+integer, save :: nb_hv_max
+integer, save :: nb_pfunc1_max
+integer, save :: nb_pfunc2_max
+integer, save :: nb_pfunc3_max
+
 end module types_asis
Index: trunk/LMDZ.GENERIC/libf/dynphy_lonlat/phystd/inichim_newstart.F90
===================================================================
--- trunk/LMDZ.GENERIC/libf/dynphy_lonlat/phystd/inichim_newstart.F90	(revision 2541)
+++ trunk/LMDZ.GENERIC/libf/dynphy_lonlat/phystd/inichim_newstart.F90	(revision 2542)
@@ -2,9 +2,8 @@
                                   flagh2o, flagthermo)
 
-      use tracer_h
-      USE comvert_mod, ONLY: aps,bps
-      USE mod_grid_phy_lmdz, ONLY: nbp_lon, nbp_lat, nbp_lev
-      use callkeys_mod
-      use datafile_mod
+      use tracer_h,          only: noms, mmol
+      use datafile_mod,      only: datadir
+      use comvert_mod,       only: aps,bps
+      use mod_grid_phy_lmdz, only: nbp_lon, nbp_lat, nbp_lev
 
       implicit none
@@ -26,13 +25,14 @@
 !  Modified 11/2011 Addition of methane Franck Lefevre
 !  Rewritten 04/2012 Franck Lefevre
+!  Rewritten 03/2021 Yassin Jaziri (Use of #Moderntrac-v1 to init thanks traceur.def)
 !
 !  Arguments:
 !  ----------
 !
-!  pq(nbp_lon+1,nbp_lat,nbp_lev,nq)  Advected fields, ie chemical species here
-!  qsurf(ngrid,nq)     Amount of tracer on the surface (kg/m2)
-!  ps(nbp_lon+1,nbp_lat)           Surface pressure (Pa)
-!  flagh2o                 flag for initialisation of h2o (1: yes / 0: no)
-!  flagthermo              flag for initialisation of thermosphere only (1: yes / 0: no)
+!  pq(nbp_lon+1,nbp_lat,nbp_lev,nq)   Advected fields, ie chemical species here
+!  qsurf(ngrid,nq)                    Amount of tracer on the surface (kg/m2)
+!  ps(nbp_lon+1,nbp_lat)              Surface pressure (Pa)
+!  flagh2o                            flag for initialisation of h2o (1: yes / 0: no)
+!  flagthermo                         flag for initialisation of thermosphere only (1: yes / 0: no)
 !
 !=======================================================================
@@ -41,689 +41,178 @@
 ! inputs :
 
-      integer,intent(in) :: ngrid         ! number of atmospheric columns in the physics
-      integer,intent(in) :: nq                    ! number of tracers
-      real,intent(in) :: ps(nbp_lon+1,nbp_lat)            ! surface pressure in the gcm (Pa)   
-      integer,intent(in) :: flagh2o               ! flag for h2o initialisation
-      integer,intent(in) :: flagthermo            ! flag for thermosphere initialisation only
+      integer,intent(in) :: ngrid                  ! number of atmospheric columns in the physics
+      integer,intent(in) :: nq                     ! number of tracers
+      real   ,intent(in) :: ps(nbp_lon+1,nbp_lat)  ! surface pressure in the gcm (Pa)
+      integer,intent(in) :: flagh2o                ! flag for h2o initialisation
+      integer,intent(in) :: flagthermo             ! flag for thermosphere initialisation only
 
 ! outputs :
 
-      real,intent(out) :: pq(nbp_lon+1,nbp_lat,nbp_lev,nq)  ! advected fields, ie chemical species
-      real,intent(out) :: qsurf(ngrid,nq)     ! surface values (kg/m2) of tracers
+      real,intent(out)   :: pq(nbp_lon+1,nbp_lat,nbp_lev,nq) ! advected fields, ie chemical species
+      real,intent(out)   :: qsurf(ngrid,nq)                  ! surface values (kg/m2) of tracers
 
 ! local :
 
-      integer :: iq, i, j, l, n, nbqchem
-      integer :: count, ierr, dummy
-      real    :: mmean(nbp_lon+1,nbp_lat,nbp_lev)             ! mean molecular mass (g)
-      real    :: pgcm                             ! pressure at each layer in the gcm (Pa)
-
-      integer, parameter         :: nalt = 252    ! number of altitudes in the initialization files
-      integer                    :: nspe          ! number of species in the initialization files
-      integer, allocatable       :: niq(:)        ! local index of species in initialization files
-      real, dimension(nalt)      :: tinit, zzfile ! temperature in initialization files
-      real, dimension(nalt)      :: pinit         ! pressure in initialization files
-      real, dimension(nalt)      :: densinit      ! total number density in initialization files
-      real, allocatable          :: vmrinit(:,:)  ! mixing ratios in initialization files
-      real, allocatable          :: vmrint(:)     ! mixing ratio interpolated onto the gcm vertical grid
-      real                       :: vmr
-
-      character(len=20)          :: txt           ! to store some text
-      logical                    :: flagnitro     ! checks if N species present
-
-! 1. identify tracers by their names: (and set corresponding values of mmol)
-
-! 1.1 initialize tracer indexes to zero:
-!      nqmx=nq ! initialize value of nqmx
-
-      do iq = 1,nq
-        igcm_dustbin(iq) = 0
-      end do
-
-!      igcm_dust_mass   = 0
-!      igcm_dust_number = 0
-!      igcm_ccn_mass    = 0
-!      igcm_ccn_number  = 0
-      igcm_h2o_vap     = 0
-      igcm_h2o_ice     = 0
-      igcm_co2         = 0
-      igcm_co          = 0
-      igcm_o           = 0
-      igcm_o1d         = 0
-      igcm_o2          = 0
-      igcm_o3          = 0
-      igcm_h           = 0
-      igcm_h2          = 0
-      igcm_oh          = 0
-      igcm_ho2         = 0
-      igcm_h2o2        = 0
-      igcm_ch4         = 0
-      igcm_n2          = 0
-      igcm_ar          = 0
-      igcm_ar_n2       = 0
-      igcm_ch3         = 0
-      igcm_ch          = 0
-      igcm_3ch2        = 0
-      igcm_1ch2        = 0
-      igcm_cho         = 0
-      igcm_ch2o        = 0
-      igcm_c           = 0
-      igcm_c2          = 0
-      igcm_c2h         = 0
-      igcm_c2h2        = 0
-      igcm_c2h3        = 0
-      igcm_c2h4        = 0
-      igcm_c2h6        = 0
-      igcm_ch2co       = 0
-      igcm_ch3co       = 0
-      igcm_hcaer       = 0
-
-! 1.2 find dust tracers
-      count = 0
-!
-!      if (dustbin > 0) then
-!         do iq = 1,nq
-!            txt = " "
-!            write(txt,'(a4,i2.2)') 'dust', count + 1
-!            if (noms(iq) == txt) then
-!               count = count + 1
-!               igcm_dustbin(count) = iq
-!               mmol(iq) = 100.
-!            end if
-!         end do !do iq=1,nq
-!      end if ! of if (dustbin.gt.0)
-!
-!      if (doubleq) then
-!         do iq = 1,nq
-!            if (noms(iq) == "dust_mass") then
-!               igcm_dust_mass = iq
-!               count = count + 1
-!            end if
-!            if (noms(iq) == "dust_number") then
-!               igcm_dust_number = iq
-!               count = count + 1
-!            end if
-!         end do
-!      end if ! of if (doubleq)
-!
-!      if (scavenging) then
-!         do iq = 1,nq
-!            if (noms(iq) == "ccn_mass") then
-!               igcm_ccn_mass = iq
-!               count = count + 1
-!            end if
-!            if (noms(iq) == "ccn_number") then
-!               igcm_ccn_number = iq
-!               count = count + 1
-!            end if
-!         end do
-!      end if ! of if (scavenging)
-!
-!      if (submicron) then
-!         do iq=1,nq
-!            if (noms(iq) == "dust_submicron") then
-!               igcm_dust_submicron = iq
-!               mmol(iq) = 100.
-!               count = count + 1
-!            end if
-!         end do
-!      end if ! of if (submicron)
-
-! 1.3 find chemistry and water tracers
-
-      nbqchem = 0
-
-      do iq = 1,nq
-         if (noms(iq) == "co2") then
-            igcm_co2 = iq
-            mmol(igcm_co2) = 44.
-            count = count + 1
-            nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "co") then
-           igcm_co = iq
-           mmol(igcm_co) = 28.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "o") then
-           igcm_o = iq
-           mmol(igcm_o) = 16.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "o1d") then
-           igcm_o1d = iq
-           mmol(igcm_o1d) = 16.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "o2") then
-           igcm_o2 = iq
-           mmol(igcm_o2) = 32.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "o3") then
-           igcm_o3 = iq
-           mmol(igcm_o3) = 48.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "h") then
-           igcm_h = iq
-           mmol(igcm_h) = 1.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "h2") then
-           igcm_h2 = iq
-           mmol(igcm_h2) = 2.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "oh") then
-           igcm_oh = iq
-           mmol(igcm_oh) = 17.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "ho2") then
-           igcm_ho2 = iq
-           mmol(igcm_ho2) = 33.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "h2o2") then
-           igcm_h2o2 = iq
-           mmol(igcm_h2o2) = 34.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "ch4") then
-           igcm_ch4 = iq
-           mmol(igcm_ch4) = 16.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "n2") then
-           igcm_n2 = iq
-           mmol(igcm_n2) = 28.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "n") then
-           igcm_n = iq
-           mmol(igcm_n) = 14.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "n2d") then
-           igcm_n2d = iq
-           mmol(igcm_n2d) = 14.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "no") then
-           igcm_no = iq
-           mmol(igcm_no) = 30.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "no2") then
-           igcm_no2 = iq
-           mmol(igcm_no2) = 46.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "h2o_vap") then
-           igcm_h2o_vap = iq
-           mmol(igcm_h2o_vap) = 18.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "h2o_ice") then
-           igcm_h2o_ice = iq
-           mmol(igcm_h2o_ice) = 18.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-
-        if (noms(iq).eq."ch3") then
-          igcm_ch3=iq
-          mmol(igcm_ch3)=15.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."ch") then
-          igcm_ch=iq
-          mmol(igcm_ch)=13.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."3ch2") then
-          igcm_3ch2=iq
-          mmol(igcm_3ch2)=14.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."1ch2") then
-          igcm_1ch2=iq
-          mmol(igcm_1ch2)=14.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."cho") then
-          igcm_cho=iq
-          mmol(igcm_cho)=29.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."ch2o") then
-          igcm_ch2o=iq
-          mmol(igcm_ch2o)=30.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."ch3o") then
-          igcm_ch3o=iq
-          mmol(igcm_ch3o)=31.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."c") then
-          igcm_c=iq
-          mmol(igcm_c)=12.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."c2") then
-          igcm_c2=iq
-          mmol(igcm_c2)=24.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."c2h") then
-          igcm_c2h=iq
-          mmol(igcm_c2h)=25.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."c2h2") then
-          igcm_c2h2=iq
-          mmol(igcm_c2h2)=26.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."c2h3") then
-          igcm_c2h3=iq
-          mmol(igcm_c2h3)=27.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."c2h4") then
-          igcm_c2h4=iq
-          mmol(igcm_c2h4)=28.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."c2h6") then
-          igcm_c2h6=iq
-          mmol(igcm_c2h6)=30.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."ch2co") then
-          igcm_ch2co=iq
-          mmol(igcm_ch2co)=42.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."ch3co") then
-          igcm_ch3co=iq
-          mmol(igcm_ch3co)=43.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."hcaer") then
-          igcm_hcaer=iq
-          mmol(igcm_hcaer)=50.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq) == "ar") then
-           igcm_ar = iq
-           mmol(igcm_ar) = 40.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-
-
-
-! 1.5 find idealized non-condensible tracer
-
-        if (noms(iq) == "Ar_N2") then
-           igcm_ar_n2 = iq
-           mmol(igcm_ar_n2) = 30.
-           count = count + 1
-        end if
-
-      end do ! of do iq=1,nq
-      
-! 1.6 check that we identified all tracers:
-
-      if (count /= nq) then
-         write(*,*) "inichim_newstart: found only ",count," tracers"
-         write(*,*) "                  expected ",nq
-         do iq = 1,count
-            write(*,*) '      ', iq, ' ', trim(noms(iq))
-         end do
+      real, allocatable  :: pf(:)                  ! pressure in vmr profile files set in traceur.def
+      real, allocatable  :: qf(:)                  ! vmr      in vmr profile files set in traceur.def
+
+      real    :: pgcm                              ! pressure at each layer in the gcm (Pa)
+      real    :: mmean(nbp_lev)                    ! mean molecular mass (g)
+      real    :: pqx(nbp_lon+1,nbp_lat,nbp_lev,nq) ! tracers (vmr)
+      real    :: qx(nq)                            ! constant vmr set in traceur.def
+      integer :: ilon, ilat, iq, ilay, iline, nlines, ierr
+
+      CHARACTER(len=100) :: qxf(nq)                ! vmr profile files set in traceur.def
+      CHARACTER(len=100) :: fil                    ! path files
+      character(len=500) :: tracline               ! to store a line of text
+
+      logical :: foundback = .false.
+
+! 1. initialization
+
+      pq(:,:,:,:)  = 0.
+      qsurf(:,:)   = 0.
+      pqx(:,:,:,:) = 0.
+      qx(:)        = 0.
+      qxf(:)       = 'None'
+
+! 2. load in traceur.def chemistry data for initialization:
+
+      ! Skip nq
+      open(90,file='traceur.def',status='old',form='formatted',iostat=ierr)
+      if (ierr.eq.0) then
+        READ(90,'(A)') tracline
+        IF (trim(tracline).eq.'#ModernTrac-v1') THEN ! Test modern traceur.def
+           DO
+             READ(90,'(A)',iostat=ierr) tracline
+             IF (ierr.eq.0) THEN
+               IF (index(tracline,'#').ne.1) THEN ! Allows arbitary number of comments lines in the header
+                 EXIT
+               ENDIF
+             ELSE ! If pb, or if reached EOF without having found number of tracer
+                write(*,*) "calchim: error reading line of tracers"
+                write(*,*) "   (first lines of traceur.def) "
+                stop
+             ENDIF
+           ENDDO
+        ENDIF ! if modern or standard traceur.def
+      else
+         write(*,*) "calchim: error opening traceur.def in inichim_newstart"
          stop
-      else
-         write(*,*) "inichim_newstart: found all expected tracers"
-         do iq = 1,nq
-            write(*,*) '      ', iq, ' ', trim(noms(iq))
-         end do
-      end if
-
-! 1.7 check if nitrogen species are present:
-
-      if(igcm_no == 0) then
-         !check that no N species is in traceur.def
-         if(igcm_n /= 0 .or. igcm_no2 /= 0 .or. igcm_n2d /= 0) then
-            write(*,*)'inichim_newstart error:'
-            write(*,*)'N, NO2 and/or N2D are in traceur.def, but not NO'
-            write(*,*)'stop'
-            stop
-         endif
-         flagnitro = .false.
-         nspe = 14
-      else
-         !check that all N species are in traceur.def
-         if(igcm_n == 0 .or. igcm_no2 == 0 .or. igcm_n2d == 0) then
-            write(*,*)'inichim_newstart error:'
-            write(*,*)'if NO is in traceur.def, N, NO2 and N2D must also be'
-            write(*,*)'stop'
-            stop
-         endif
-         flagnitro = .true.
-         nspe = 18
       endif
 
-! 1.8 allocate arrays
-
-      allocate(niq(nspe))
-      allocate(vmrinit(nalt,nspe))
-      allocate(vmrint(nspe))
-
-! 2. load in chemistry data for initialization:
-
-! order of major species in initialization file:
-!
-!    1: co2 
-!    2: ar
-!    3: n2  
-!    4: o2  
-!    5: co  
-!    6: o   
-!    7: h2
-!
-! order of minor species in initialization file:
-!
-!    1: h  
-!    2: oh 
-!    3: ho2 
-!    4: h2o 
-!    5: h2o2 
-!    6: o1d
-!    7: o3
-!
-! order of nitrogen species in initialization file:
-!
-!    1: n
-!    2: no
-!    3: no2
-!    4: n2d
-
-! major species:
-
-      niq(1) = igcm_co2
-      niq(2) = igcm_ar
-      niq(3) = igcm_n2
-      niq(4) = igcm_o2
-      niq(5) = igcm_co
-      niq(6) = igcm_o
-      niq(7) = igcm_h2
-
-! minor species:
-
-      niq(8)  = igcm_h
-      niq(9)  = igcm_oh
-      niq(10) = igcm_ho2
-      niq(11) = igcm_h2o_vap
-      niq(12) = igcm_h2o2
-      niq(13) = igcm_o1d 
-      niq(14) = igcm_o3
-
-! nitrogen species:
-
-      if (flagnitro) then
-         niq(15) = igcm_n
-         niq(16) = igcm_no
-         niq(17) = igcm_no2
-         niq(18) = igcm_n2d         
-      end if
-
-
-
-
-! carbon species:
-!      niq(18) = igcm_ch4
-!      niq(19) = igcm_ch3
-!      niq(20) = igcm_ch
-!      niq(21) = igcm_1ch2
-!      niq(22) = igcm_3ch2
-!      niq(23) = igcm_cho
-!      niq(24) = igcm_ch2o
-!      niq(25) = igcm_ch3o
-!      niq(26) = igcm_c
-!      niq(27) = igcm_c2
-!      niq(28) = igcm_c2h
-!      niq(29) = igcm_c2h2
-!      niq(30) = igcm_c2h3
-!      niq(31) = igcm_c2h4
-!      niq(32) = igcm_c2h6
-!      niq(33) = igcm_ch2co
-!      niq(34) = igcm_ch3co
-!      niq(35) = igcm_hcaer
-
-
-! 2.1 open initialization files
-      open(210, iostat=ierr,file=trim(datadir)//'/atmosfera_LMD_may.dat')
-      if (ierr /= 0) then
-         write(*,*)'Error : cannot open file atmosfera_LMD_may.dat '
-         write(*,*)'(in aeronomars/inichim_newstart.F)'
-         write(*,*)'It should be in :', trim(datadir),'/'
-         write(*,*)'1) You can change this path in callphys.def with'
-         write(*,*)'   datadir=/path/to/datafiles/'
-         write(*,*)'2) If necessary atmosfera_LMD_may.dat (and others)'
-         write(*,*)'   can be obtained online on:'
-         write(*,*)' http://www.lmd.jussieu.fr/~lmdz/planets/mars/datadir'
+      ! Get data of tracers
+      do iq=1,nq
+         read(90,'(A)') tracline
+         write(*,*)"inichim_newstart: iq=",iq,"noms(iq)=",trim(noms(iq))
+         if (index(tracline,'qx='    ) /= 0) then
+            read(tracline(index(tracline,'qx=')+len('qx='):),*) qx(iq)
+            write(*,*) ' Parameter value (traceur.def) : qx=', qx(iq)
+         else
+            write(*,*) ' Parameter value (default)     : qx=', qx(iq)
+         end if
+         if (index(tracline,'qxf='    ) /= 0) then
+            read(tracline(index(tracline,'qxf=')+len('qxf='):),*) qxf(iq)
+            write(*,*) ' Parameter value (traceur.def) : qxf=', qxf(iq)
+         else
+            write(*,*) ' Parameter value (default)     : qxf=', qxf(iq)
+         end if
+      end do
+
+      close(90)
+
+! 3. initialization of tracers
+
+! 3.1 vertical interpolation
+
+      do iq=1,nq
+         if (qx(iq) /= 0.) then
+            pqx(:,:,:,iq) = qx(iq)
+         else if (qxf(iq) /= 'None') then
+            ! Opening file
+            fil = trim(datadir)//'/chemical_profiles/'//qxf(iq)
+            print*, 'chemical pofile '//trim(noms(iq))//': ', fil
+            open(UNIT=90,FILE=fil,STATUS='old',iostat=ierr)
+            if (ierr.eq.0) then
+               read(90,*) ! read one header line
+               do         ! get number of lines
+                   read(90,*,iostat=ierr)
+                   if (ierr<0) exit
+                   nlines = nlines + 1
+               end do
+               ! allocate reading variable
+               allocate(pf(nlines))
+               allocate(qf(nlines))
+               ! read file
+               rewind(90) ! restart from the beggining of the file
+               read(90,*) ! read one header line
+               do iline=1,nlines
+                  read(90,*) pf(iline), qf(iline) ! pf [Pa], qf [vmr]
+               end do
+               ! interp in gcm grid
+               do ilon = 1,nbp_lon+1
+                  do ilat = 1,nbp_lat
+                     do ilay=1,nbp_lev
+                        pgcm = aps(ilay) + bps(ilay)*ps(ilon,ilat)  ! gcm pressure
+                        call intrplf(log(pgcm),pqx(ilon,ilat,ilay,iq),log(pf),qf,nlines)
+                     end do
+                  end do
+               end do
+               ! deallocate for next tracer
+               deallocate(pf)
+               deallocate(qf)
+            else
+               write(*,*) 'inichim_newstart: error opening ', fil
+               stop
+            endif
+            close(90)
+         end if
+      end do
+
+! 3.2 background gas
+
+      do iq=1,nq
+         if (qx(iq)==1.) then
+            pqx(:,:,:,iq) = 0.
+            do ilon = 1,nbp_lon+1
+               do ilat = 1,nbp_lat
+                  do ilay=1,nbp_lev
+                     pqx(ilon,ilat,ilay,iq) = 1-sum(pqx(ilon,ilat,ilay,:))
+                     if (pqx(ilon,ilat,ilay,iq)<=0.) then
+                        write(*,*) 'inichim_newstart: vmr tot > 1 not possible'
+                        stop
+                     end if
+                  end do
+               end do
+            end do
+            foundback = .true.
+            exit ! you found the background gas you can skip others
+         end if
+      end do
+      if (.not.foundback) then
+         write(*,*) 'inichim_newstart: you need to set a background gas'
+         write(*,*) '            by qx=1. in traceur.def'
          stop
       end if
-      open(220, iostat=ierr,file=trim(datadir)//'/atmosfera_LMD_min.dat')
-      if (ierr /= 0) then
-         write(*,*)'Error : cannot open file atmosfera_LMD_min.dat '
-         write(*,*)'(in aeronomars/inichim_newstart.F)'
-         write(*,*)'It should be in :', trim(datadir),'/'
-         write(*,*)'1) You can change this path in callphys.def with'
-         write(*,*)'   datadir=/path/to/datafiles/'
-         write(*,*)'2) If necessary atmosfera_LMD_min.dat (and others)'
-         write(*,*)'   can be obtained online on:'
-         write(*,*)' http://www.lmd.jussieu.fr/~lmdz/planets/mars/datadir'
-         stop
-      end if
-      if(flagnitro) then
-         open(230, iostat=ierr,file=trim(datadir)//'/atmosfera_LMD_nitr.dat')
-         if (ierr.ne.0) then
-            write(*,*)'Error : cannot open file atmosfera_LMD_nitr.dat '
-            write(*,*)'(in aeronomars/inichim_newstart.F)'
-            write(*,*)'It should be in :', datadir
-            write(*,*)'1) You can change this directory address in '
-            write(*,*)'   file phymars/datafile.h'
-            write(*,*)'2) If necessary atmosfera_LMD_nitr.dat (and others)'
-            write(*,*)'   can be obtained online on:'
-            write(*,*)' http://www.lmd.jussieu.fr/~lmdz/planets/mars/datadir'
-            STOP
-         endif
-      endif   ! Of if(flagnitro)
-
-! 2.2 read initialization files
-
-! major species
-
-      read(210,*)
-      do l = 1,nalt
-         read(210,*) dummy, tinit(l), pinit(l), densinit(l), &
-                     (vmrinit(l,n), n = 1,7)
-         pinit(l) = pinit(l)*100.              ! conversion in Pa
-         pinit(l) = log(pinit(l))              ! for the vertical interpolation
-      end do
-      close(210)
-
-! minor species
-
-      read(220,*)
-      do l = 1,nalt
-         read(220,*) dummy, (vmrinit(l,n), n = 8,14)
-      end do 
-      close(220)
-
-! nitrogen species
-
-      if (flagnitro) then
-         read(230,*)
-         do l = 1,nalt
-            read(230,*) dummy, (vmrinit(l,n), n = 15,18)
-         end do
-         close(230)
-      end if
-
-! initialization for the early eath
-      if (1.eq.0) then
-        do l = 1,nalt
-         vmrinit(l,:)=0.0
-         vmrinit(l,1)=0.01 !co2
-         vmrinit(l,2)=0.989 !n2
-!         vmrinit(l,3)=2.e-17/mmol(niq(3))*28 !o2
-!         vmrinit(l,4)=3.8e-6/mmol(niq(4))*28  !co
-!         vmrinit(l,5)=4.e-14/mmol(niq(5))*28  !o
-!         vmrinit(l,6)=1.3e-7/mmol(niq(6))*28  !h2
-         vmrinit(l,6)=1e-3
-!         vmrinit(l,7)=5.e-16/mmol(niq(7))*28 !h
-!         vmrinit(l,8)=2.e-17/mmol(niq(8))*28 !oh
-!         vmrinit(l,9)=1.e-17/mmol(niq(9))*28 !ho2
-         vmrinit(l,10)=1e-6 !h2o
-!         vmrinit(l,11)=2.e-20/mmol(niq(11))*28 !h2o2
-!         vmrinit(l,12)=0. !o1d
-!         vmrinit(l,13)=3.e-22/mmol(niq(13))*28 !o3
-
-
-         vmrinit(l,18)=1.0e-3 !ch4
-!         vmrinit(l,19)=1.3e-12/mmol(niq(19))*28 !ch3
-!         vmrinit(l,23)=1.e-12/mmol(niq(23))*28 !cho
-!         vmrinit(l,24)=2.7e-11/mmol(niq(24))*28 !ch2o
-!         vmrinit(l,25)=2.e-9/mmol(niq(25))*28 !ch3o
-!         vmrinit(l,32)=2.e-7/mmol(niq(32))*28 !c2h6
-!         vmrinit(l,33)=5.e-12/mmol(niq(33))*28 !ch2co
-!         vmrinit(l,34)=1.e-13/mmol(niq(34))*28 !ch3co
-
-
-
-!         pinit(l)=aps(l) + bps(l)*ps
-!         vmrinit(l,18)=2e-3*min(pinit(l)/100.,1.) ! decrease with scale
-!         height above 1 hpa
-         vmrinit(l,2)=0.0
-         vmrinit(l,2)=1-sum(vmrinit(l,:)) !n2
-!         vmrinit(l,4)=0.1
-!         vmrinit(l,7)=0.001
-        end do
-      endif
-
-      
-! 3. initialization of tracers
-
-      do i = 1,nbp_lon+1
-         do j = 1,nbp_lat
-            do l = 1,nbp_lev
-
-               pgcm = aps(l) + bps(l)*ps(i,j)  ! gcm pressure
-               pgcm = log(pgcm)                ! for the vertical interpolation
-               mmean(i,j,l) = 0.
-
-! 3.1 vertical interpolation
-
-               do n = 1,nspe
-                  call intrplf(pgcm,vmr,pinit,vmrinit(:,n),nalt)
-                  vmrint(n) = vmr
-!                  vmrint(n) = vmrinit(l,n)
-                  iq = niq(n)
-                  mmean(i,j,l) = mmean(i,j,l) + vmrint(n)*mmol(iq)
-               end do
-
-! 3.2 attribute mixing ratio: - all layers or only thermosphere
-!                             - with our without h2o 
-
-
-
-               if (flagthermo == 0 .or. (flagthermo == 1 .and. exp(pgcm) < 0.1)) then
-                  do n = 1,nspe
-                     iq = niq(n)
-                     if (iq /= igcm_h2o_vap .or. flagh2o == 1) then
-                        pq(i,j,l,iq) = vmrint(n)*mmol(iq)/mmean(i,j,l)
-                     end if
-                  end do
-               end if
-
+
+! 3.3 convert vmr to mmr
+
+      do ilon = 1,nbp_lon+1
+         do ilat = 1,nbp_lat
+            mmean(:) = 0.
+            do ilay=1,nbp_lev
+               do iq=1,nq
+                  mmean(ilay) = mmean(ilay) + pqx(ilon,ilat,ilay,iq)*mmol(iq)
+               end do
+               do iq=1,nq
+                  pq(ilon,ilat,ilay,iq) = pqx(ilon,ilat,ilay,iq)*mmol(iq)/mmean(ilay)
+               end do
             end do
          end do
       end do
 
-! set surface values of chemistry tracers to zero
-
-
-      if (flagthermo == 0) then
-         ! NB: no problem for "surface water vapour" tracer which is always 0
-         do n = 1,nspe
-            iq = niq(n)
-            qsurf(1:ngrid,iq) = 0.
-         end do
-      end if
-
-! 3.3 initialization of tracers not contained in the initialization files
-
-! methane : 10 ppbv
-
-!      if (igcm_ch4 /= 0) then
-!         vmr = 10.e-9       
-!         do i = 1,nbp_lon+1
-!            do j = 1,nbp_lat
-!               do l = 1,nbp_lev
-!                  pq(i,j,l,igcm_ch4) = vmr*mmol(igcm_ch4)/mmean(i,j,l)
-!               end do
-!            end do
-!         end do
-!         ! set surface value to zero
-!         qsurf(1:ngrid,igcm_ch4) = 0.
-!      end if
-
-! ions: 0
-
-      
-      ! deallocations
-
-      deallocate(niq)
-      deallocate(vmrinit)
-      deallocate(vmrint)
+! 4. Hard coding
+! Do whatever you want here to specify pq and qsurf
+! Or use #ModernTrac-v1 and add another option section 2.
 
       end
Index: trunk/LMDZ.GENERIC/libf/phystd/callkeys_mod.F90
===================================================================
--- trunk/LMDZ.GENERIC/libf/phystd/callkeys_mod.F90	(revision 2541)
+++ trunk/LMDZ.GENERIC/libf/phystd/callkeys_mod.F90	(revision 2542)
@@ -29,9 +29,8 @@
 !$OMP THREADPRIVATE(newtonian,check_cpp_match,force_cpp,testradtimes,rayleigh)
       logical,save :: stelbbody
-      logical,save :: ozone
       logical,save :: nearco2cond
       logical,save :: tracer
       logical,save :: mass_redistrib
-!$OMP THREADPRIVATE(stelbbody,ozone,nearco2cond,tracer,mass_redistrib)
+!$OMP THREADPRIVATE(stelbbody,nearco2cond,tracer,mass_redistrib)
       logical,save :: varactive
       logical,save :: varfixed
@@ -59,6 +58,9 @@
 !$OMP THREADPRIVATE(ok_slab_ocean,ok_slab_sic,ok_slab_heat_transp,albedo_spectral_mode)
       logical,save :: photochem
+      logical,save :: photoheat
+      logical,save :: jonline
+      logical,save :: depos
       logical,save :: haze
-!$OMP THREADPRIVATE(photochem)
+!$OMP THREADPRIVATE(photochem,photoheat,jonline,depos)
       logical,save :: calllott_nonoro
       logical,save :: gwd_convective_source
Index: trunk/LMDZ.GENERIC/libf/phystd/dyn1d/inichim_1D.F90
===================================================================
--- trunk/LMDZ.GENERIC/libf/phystd/dyn1d/inichim_1D.F90	(revision 2541)
+++ trunk/LMDZ.GENERIC/libf/phystd/dyn1d/inichim_1D.F90	(revision 2542)
@@ -1,10 +1,7 @@
-      subroutine inichim_1D(nq, pq, qsurf, ps, &
+      subroutine inichim_1D(nlayer, nq, pq, qsurf, play, &
                                   flagh2o,flagthermo)
 
-      use tracer_h
-      USE comvert_mod, ONLY: aps,bps
-      USE mod_grid_phy_lmdz, ONLY: nbp_lev
-      use callkeys_mod
-      use datafile_mod
+      use tracer_h, only: noms, mmol
+      use datafile_mod, only: datadir
 
       implicit none
@@ -26,13 +23,15 @@
 !  Modified 11/2011 Addition of methane Franck Lefevre
 !  Rewritten 04/2012 Franck Lefevre
+!  Rewritten 03/2021 Yassin Jaziri (Use of #Moderntrac-v1 to init thanks traceur.def)
 !
 !  Arguments:
 !  ----------
 !
-!  pq(nbp_lon+1,nbp_lat,nbp_lev,nq)  Advected fields, ie chemical species here
-!  qsurf(ngrid,nq)     Amount of tracer on the surface (kg/m2)
-!  ps(nbp_lon+1,nbp_lat)           Surface pressure (Pa)
-!  flagh2o                 flag for initialisation of h2o (1: yes / 0: no)
-!  flagthermo              flag for initialisation of thermosphere only (1: yes / 0: no)
+!  nlayer          Number of atmospheric layers
+!  pq(nlayer,nq)   Advected fields, ie chemical species here
+!  qsurf(nq)       Amount of tracer on the surface (kg/m2)
+!  play(nlayer)    Pressure (Pa)
+!  flagh2o         flag for initialisation of h2o (1: yes / 0: no)
+!  flagthermo      flag for initialisation of thermosphere only (1: yes / 0: no)
 !
 !=======================================================================
@@ -41,677 +40,168 @@
 ! inputs :
 
-      integer,intent(in) :: nq                    ! number of tracers
-      real,intent(in) :: ps            ! surface pressure in the gcm (Pa)   
-      integer,intent(in) :: flagh2o               ! flag for h2o initialisation
-      integer,intent(in) :: flagthermo            ! flag for thermosphere initialisation only
+      integer,intent(in) :: nlayer         ! Number of atmospheric layers.
+      integer,intent(in) :: nq             ! number of tracers
+      real   ,intent(in) :: play(nlayer)   ! Mid-layer pressure (Pa).  
+      integer,intent(in) :: flagh2o        ! flag for h2o initialisation
+      integer,intent(in) :: flagthermo     ! flag for thermosphere initialisation only
 
 ! outputs :
 
-      real,intent(out) :: pq(nbp_lev,nq)  ! advected fields, ie chemical species
-      real,intent(out) :: qsurf(nq)     ! surface values (kg/m2) of tracers
+      real,intent(out)   :: pq(nlayer,nq)  ! tracers (kg/kg_of_air)
+      real,intent(out)   :: qsurf(nq)      ! surface values (kg/m2) of tracers
 
 ! local :
 
-      integer :: iq, l, n, nbqchem
-      integer :: count, ierr, dummy
-      real    :: mmean(nbp_lev)             ! mean molecular mass (g)
-      real    :: pgcm                             ! pressure at each layer in the gcm (Pa)
-
-      integer, parameter         :: nalt = 252    ! number of altitudes in the initialization files
-      integer                    :: nspe          ! number of species in the initialization files
-      integer, allocatable       :: niq(:)        ! local index of species in initialization files
-      real, dimension(nalt)      :: tinit, zzfile ! temperature in initialization files
-      real, dimension(nalt)      :: pinit         ! pressure in initialization files
-      real, dimension(nalt)      :: densinit      ! total number density in initialization files
-      real, allocatable          :: vmrinit(:,:)  ! mixing ratios in initialization files
-      real, allocatable          :: vmrint(:)     ! mixing ratio interpolated onto the gcm vertical grid
-      real                       :: vmr
-
-      character(len=20)          :: txt           ! to store some text
-      logical                    :: flagnitro     ! checks if N species present
-
-! 1. identify tracers by their names: (and set corresponding values of mmol)
-
-! 1.1 initialize tracer indexes to zero:
-!      nqmx=nq ! initialize value of nqmx
-
-!      do iq = 1,nq
-!        igcm_dustbin(iq) = 0
-!      end do
-
-!      igcm_dust_mass   = 0
-!      igcm_dust_number = 0
-!      igcm_ccn_mass    = 0
-!      igcm_ccn_number  = 0
-      igcm_h2o_vap     = 0
-      igcm_h2o_ice     = 0
-      igcm_co2         = 0
-      igcm_co          = 0
-      igcm_o           = 0
-      igcm_o1d         = 0
-      igcm_o2          = 0
-      igcm_o3          = 0
-      igcm_h           = 0
-      igcm_h2          = 0
-      igcm_oh          = 0
-      igcm_ho2         = 0
-      igcm_h2o2        = 0
-      igcm_ch4         = 0
-      igcm_n2          = 0
-      igcm_n           = 0
-      igcm_n2d         = 0
-      igcm_no          = 0
-      igcm_no2         = 0
-      igcm_ar          = 0
-      igcm_ar_n2       = 0
-      igcm_ch3         = 0
-      igcm_ch          = 0
-      igcm_3ch2        = 0
-      igcm_1ch2        = 0
-      igcm_cho         = 0
-      igcm_ch2o        = 0 
-      igcm_c           = 0
-      igcm_c2          = 0
-      igcm_c2h         = 0
-      igcm_c2h2        = 0
-      igcm_c2h3        = 0
-      igcm_c2h4        = 0
-      igcm_c2h6        = 0
-      igcm_ch2co       = 0
-      igcm_ch3co       = 0
-      igcm_hcaer       = 0
-
-! 1.2 find dust tracers
-      count = 0
-!
-!      if (dustbin > 0) then
-!         do iq = 1,nq
-!            txt = " "
-!            write(txt,'(a4,i2.2)') 'dust', count + 1
-!            if (noms(iq) == txt) then
-!               count = count + 1
-!               igcm_dustbin(count) = iq
-!               mmol(iq) = 100.
-!            end if
-!         end do !do iq=1,nq
-!      end if ! of if (dustbin.gt.0)
-!
-!      if (doubleq) then
-!         do iq = 1,nq
-!            if (noms(iq) == "dust_mass") then
-!               igcm_dust_mass = iq
-!               count = count + 1
-!            end if
-!            if (noms(iq) == "dust_number") then
-!               igcm_dust_number = iq
-!               count = count + 1
-!            end if
-!         end do
-!      end if ! of if (doubleq)
-!
-!      if (scavenging) then
-!         do iq = 1,nq
-!            if (noms(iq) == "ccn_mass") then
-!               igcm_ccn_mass = iq
-!               count = count + 1
-!            end if
-!            if (noms(iq) == "ccn_number") then
-!               igcm_ccn_number = iq
-!               count = count + 1
-!            end if
-!         end do
-!      end if ! of if (scavenging)
-!
-!      if (submicron) then
-!         do iq=1,nq
-!            if (noms(iq) == "dust_submicron") then
-!               igcm_dust_submicron = iq
-!               mmol(iq) = 100.
-!               count = count + 1
-!            end if
-!         end do
-!      end if ! of if (submicron)
-
-! 1.3 find chemistry and water tracers
-
-      nbqchem = 0
-
-      do iq = 1,nq
-         if (noms(iq) == "co2") then
-            igcm_co2 = iq
-            mmol(igcm_co2) = 44.
-            count = count + 1
-            nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "co") then
-           igcm_co = iq
-           mmol(igcm_co) = 28.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "o") then
-           igcm_o = iq
-           mmol(igcm_o) = 16.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "o1d") then
-           igcm_o1d = iq
-           mmol(igcm_o1d) = 16.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "o2") then
-           igcm_o2 = iq
-           mmol(igcm_o2) = 32.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "o3") then
-           igcm_o3 = iq
-           mmol(igcm_o3) = 48.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "h") then
-           igcm_h = iq
-           mmol(igcm_h) = 1.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "h2") then
-           igcm_h2 = iq
-           mmol(igcm_h2) = 2.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "oh") then
-           igcm_oh = iq
-           mmol(igcm_oh) = 17.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "ho2") then
-           igcm_ho2 = iq
-           mmol(igcm_ho2) = 33.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "h2o2") then
-           igcm_h2o2 = iq
-           mmol(igcm_h2o2) = 34.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "n2") then
-           igcm_n2 = iq
-           mmol(igcm_n2) = 28.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "ch4") then
-           igcm_ch4 = iq
-           mmol(igcm_ch4) = 16.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "ar") then
-           igcm_ar = iq
-           mmol(igcm_ar) = 40.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "n") then
-           igcm_n = iq
-           mmol(igcm_n) = 14.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "n2d") then
-           igcm_n2d = iq
-           mmol(igcm_n2d) = 14.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "no") then
-           igcm_no = iq
-           mmol(igcm_no) = 30.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "no2") then
-           igcm_no2 = iq
-           mmol(igcm_no2) = 46.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-
-        if (noms(iq) == "h2o_vap") then
-           igcm_h2o_vap = iq
-           mmol(igcm_h2o_vap) = 18.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-        if (noms(iq) == "h2o_ice") then
-           igcm_h2o_ice = iq
-           mmol(igcm_h2o_ice) = 18.
-           count = count + 1
-           nbqchem = nbqchem + 1
-        end if
-
-
-        if (noms(iq).eq."ch3") then
-          igcm_ch3=iq
-          mmol(igcm_ch3)=15.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."ch") then
-          igcm_ch=iq
-          mmol(igcm_ch)=13.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."3ch2") then
-          igcm_3ch2=iq
-          mmol(igcm_3ch2)=14.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."1ch2") then
-          igcm_1ch2=iq
-          mmol(igcm_1ch2)=14.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."cho") then
-          igcm_cho=iq
-          mmol(igcm_cho)=29.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."ch2o") then
-          igcm_ch2o=iq
-          mmol(igcm_ch2o)=30.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."ch3o") then
-          igcm_ch3o=iq
-          mmol(igcm_ch3o)=31.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."c") then
-          igcm_c=iq
-          mmol(igcm_c)=12.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."c2") then
-          igcm_c2=iq
-          mmol(igcm_c2)=24.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."c2h") then
-          igcm_c2h=iq
-          mmol(igcm_c2h)=25.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."c2h2") then
-          igcm_c2h2=iq
-          mmol(igcm_c2h2)=26.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."c2h3") then
-          igcm_c2h3=iq
-          mmol(igcm_c2h3)=27.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."c2h4") then
-          igcm_c2h4=iq
-          mmol(igcm_c2h4)=28.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."c2h6") then
-          igcm_c2h6=iq
-          mmol(igcm_c2h6)=30.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."ch2co") then
-          igcm_ch2co=iq
-          mmol(igcm_ch2co)=42.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."ch3co") then
-          igcm_ch3co=iq
-          mmol(igcm_ch3co)=43.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-        if (noms(iq).eq."hcaer") then
-          igcm_hcaer=iq
-          mmol(igcm_hcaer)=50.
-          count=count+1
-           nbqchem = nbqchem + 1
-        endif
-
-
-
-
-! 1.5 find idealized non-condensible tracer
-
-        if (noms(iq) == "Ar_N2") then
-           igcm_ar_n2 = iq
-           mmol(igcm_ar_n2) = 30.
-           count = count + 1
-        end if
-
-      end do ! of do iq=1,nq
-     
- 
-! 1.6 check that we identified all tracers:
-
-      if (count /= nq) then
-         write(*,*) "inichim_1D: found only ",count," tracers"
-         write(*,*) "                  expected ",nq
-         do iq = 1,count
-            write(*,*) '      ', iq, ' ', trim(noms(iq))
-         end do
+      real, allocatable  :: pf(:)          ! pressure in vmr profile files set in traceur.def
+      real, allocatable  :: qf(:)          ! vmr      in vmr profile files set in traceur.def
+
+      real    :: mmean(nlayer)             ! mean molecular mass (g)
+      real    :: pqx(nlayer,nq)            ! tracers (vmr)
+      real    :: qx(nq)                    ! constant vmr set in traceur.def
+      integer :: iq, ilay, iline, nlines, ierr
+
+      CHARACTER(len=100) :: qxf(nq)        ! vmr profile files set in traceur.def
+      CHARACTER(len=100) :: fil            ! path files
+      character(len=500) :: tracline       ! to store a line of text
+
+      logical :: foundback = .false.
+
+! 1. initialization
+
+      pq(:,:)  = 0.
+      qsurf(:) = 0.
+      pqx(:,:) = 0.
+      qx(:)    = 0.
+      qxf(:)   = 'None'
+
+! 2. load in traceur.def chemistry data for initialization:
+
+      ! Skip nq
+      open(90,file='traceur.def',status='old',form='formatted',iostat=ierr)
+      if (ierr.eq.0) then
+        READ(90,'(A)') tracline
+        IF (trim(tracline).eq.'#ModernTrac-v1') THEN ! Test modern traceur.def
+           DO
+             READ(90,'(A)',iostat=ierr) tracline
+             IF (ierr.eq.0) THEN
+               IF (index(tracline,'#').ne.1) THEN ! Allows arbitary number of comments lines in the header
+                 EXIT
+               ENDIF
+             ELSE ! If pb, or if reached EOF without having found number of tracer
+                write(*,*) "calchim: error reading line of tracers"
+                write(*,*) "   (first lines of traceur.def) "
+                stop
+             ENDIF
+           ENDDO
+        ENDIF ! if modern or standard traceur.def
+      else
+         write(*,*) "calchim: error opening traceur.def in inichim_1D"
          stop
-      else
-         write(*,*) "inichim_1D: found all expected tracers"
-         do iq = 1,nq
-            write(*,*) '      ', iq, ' ', trim(noms(iq))
-         end do
-      end if
-
-! 1.7 check if nitrogen species are present:
-
-      if(igcm_no == 0) then
-         !check that no N species is in traceur.def
-         if(igcm_n /= 0 .or. igcm_no2 /= 0 .or. igcm_n2d /= 0) then
-            write(*,*)'inichim_1D error:'
-            write(*,*)'N, NO2 and/or N2D are in traceur.def, but not NO'
-            write(*,*)'stop'
-            stop
-         endif
-         flagnitro = .false.
-         nspe = 15
-      else
-         !check that all N species are in traceur.def
-         if(igcm_n == 0 .or. igcm_no2 == 0 .or. igcm_n2d == 0) then
-            write(*,*)'inichim_1D error:'
-            write(*,*)'if NO is in traceur.def, N, NO2 and N2D must also be'
-            write(*,*)'stop'
-            stop
-         endif
-         flagnitro = .true.
-         nspe = 18
       endif
 
-! 1.8 allocate arrays
-
-      allocate(niq(nspe))
-      allocate(vmrinit(nalt,nspe))
-      allocate(vmrint(nspe))
-
-! 2. load in chemistry data for initialization:
-
-! order of major species in initialization file:
-!
-!    1: co2 
-!    2: ar
-!    3: n2  
-!    4: o2  
-!    5: co  
-!    6: o   
-!    7: h2
-!
-! order of minor species in initialization file:
-!
-!    1: h  
-!    2: oh 
-!    3: ho2 
-!    4: h2o 
-!    5: h2o2 
-!    6: o1d
-!    7: o3
-!
-! order of nitrogen species in initialization file:
-!
-!    1: n
-!    2: no
-!    3: no2
-!    4: n2d
-
-! major species:
-
-      niq(1) = igcm_co2
-      niq(2) = igcm_ar
-      niq(3) = igcm_n2
-      niq(4) = igcm_o2
-      niq(5) = igcm_co
-      niq(6) = igcm_o
-      niq(7) = igcm_h2
-
-! minor species:
-
-      niq(8)  = igcm_h
-      niq(9)  = igcm_oh
-      niq(10) = igcm_ho2
-      niq(11) = igcm_h2o_vap
-      niq(12) = igcm_h2o2
-      niq(13) = igcm_o1d 
-      niq(14) = igcm_o3
-
-! nitrogen species:
-
-      if (flagnitro) then
-         niq(15) = igcm_n
-         niq(16) = igcm_no
-         niq(17) = igcm_no2
-         niq(18) = igcm_n2d         
-      end if
-
-! carbon species:
-!      niq(18) = igcm_ch4
-!      niq(19) = igcm_ch3
-!      niq(20) = igcm_ch
-!      niq(21) = igcm_1ch2
-!      niq(22) = igcm_3ch2
-!      niq(23) = igcm_cho
-!      niq(24) = igcm_ch2o
-!      niq(25) = igcm_ch3o
-!      niq(26) = igcm_c
-!      niq(27) = igcm_c2
-!      niq(28) = igcm_c2h
-!      niq(29) = igcm_c2h2
-!      niq(30) = igcm_c2h3
-!      niq(31) = igcm_c2h4
-!      niq(32) = igcm_c2h6
-!      niq(33) = igcm_ch2co
-!      niq(34) = igcm_ch3co
-!      niq(35) = igcm_hcaer
-
-
-
-! 2.1 open initialization files
-      if(1.eq.1) then
-      open(210, iostat=ierr,file=trim(datadir)//'/atmosfera_LMD_may.dat')
-      if (ierr /= 0) then
-         write(*,*)'Error : cannot open file atmosfera_LMD_may.dat '
-         write(*,*)'(in aeronomars/inichim_1D.F)'
-         write(*,*)'It should be in :', trim(datadir),'/'
-         write(*,*)'1) You can change this path in callphys.def with'
-         write(*,*)'   datadir=/path/to/datafiles/'
-         write(*,*)'2) If necessary atmosfera_LMD_may.dat (and others)'
-         write(*,*)'   can be obtained online on:'
-         write(*,*)' http://www.lmd.jussieu.fr/~lmdz/planets/mars/datadir'
+      ! Get data of tracers
+      do iq=1,nq
+         read(90,'(A)') tracline
+         write(*,*)"inichim_1D: iq=",iq,"noms(iq)=",trim(noms(iq))
+         if (index(tracline,'qx='    ) /= 0) then
+            read(tracline(index(tracline,'qx=')+len('qx='):),*) qx(iq)
+            write(*,*) ' Parameter value (traceur.def) : qx=', qx(iq)
+         else
+            write(*,*) ' Parameter value (default)     : qx=', qx(iq)
+         end if
+         if (index(tracline,'qxf='    ) /= 0) then
+            read(tracline(index(tracline,'qxf=')+len('qxf='):),*) qxf(iq)
+            write(*,*) ' Parameter value (traceur.def) : qxf=', qxf(iq)
+         else
+            write(*,*) ' Parameter value (default)     : qxf=', qxf(iq)
+         end if
+      end do
+
+      close(90)
+
+! 3. initialization of tracers
+
+! 3.1 vertical interpolation
+
+      do iq=1,nq
+         if (qx(iq) /= 0.) then
+            pqx(:,iq) = qx(iq)
+         else if (qxf(iq) /= 'None') then
+            ! Opening file
+            fil = trim(datadir)//'/chemical_profiles/'//qxf(iq)
+            print*, 'chemical pofile '//trim(noms(iq))//': ', fil
+            open(UNIT=90,FILE=fil,STATUS='old',iostat=ierr)
+            if (ierr.eq.0) then
+               read(90,*) ! read one header line
+               do         ! get number of lines
+                   read(90,*,iostat=ierr)
+                   if (ierr<0) exit
+                   nlines = nlines + 1
+               end do
+               ! allocate reading variable
+               allocate(pf(nlines))
+               allocate(qf(nlines))
+               ! read file
+               rewind(90) ! restart from the beggining of the file
+               read(90,*) ! read one header line
+               do iline=1,nlines
+                  read(90,*) pf(iline), qf(iline) ! pf [Pa], qf [vmr]
+               end do
+               ! interp in gcm grid
+               do ilay=1,nlayer
+                  call intrplf(log(play(ilay)),pqx(ilay,iq),log(pf),qf,nlines)
+               end do
+               ! deallocate for next tracer
+               deallocate(pf)
+               deallocate(qf)
+            else
+               write(*,*) 'inichim_1D: error opening ', fil
+               stop
+            endif
+            close(90)
+         end if
+      end do
+
+! 3.2 background gas
+
+      do iq=1,nq
+         if (all(pqx(:,iq)==1.)) then
+            pqx(:,iq) = 0.
+            do ilay=1,nlayer
+               pqx(ilay,iq) = 1-sum(pqx(ilay,:))
+               if (pqx(ilay,iq)<=0.) then
+                  write(*,*) 'inichim_1D: vmr tot > 1 not possible'
+                  stop
+               end if
+            end do
+            foundback = .true.
+            exit ! you found the background gas you can skip others
+         end if
+      end do
+      if (.not.foundback) then
+         write(*,*) 'inichim_1D: you need to set a background gas'
+         write(*,*) '            by qx=1. in traceur.def'
          stop
       end if
-      open(220, iostat=ierr,file=trim(datadir)//'/atmosfera_LMD_min.dat')
-      if (ierr /= 0) then
-         write(*,*)'Error : cannot open file atmosfera_LMD_min.dat '
-         write(*,*)'(in aeronomars/inichim_1D.F)'
-         write(*,*)'It should be in :', trim(datadir),'/'
-         write(*,*)'1) You can change this path in callphys.def with'
-         write(*,*)'   datadir=/path/to/datafiles/'
-         write(*,*)'2) If necessary atmosfera_LMD_min.dat (and others)'
-         write(*,*)'   can be obtained online on:'
-         write(*,*)' http://www.lmd.jussieu.fr/~lmdz/planets/mars/datadir'
-         stop
-      end if
-
-      print*,'flagnitro=',flagnitro
-      if(flagnitro) then
-         open(230, iostat=ierr,file=trim(datadir)//'/atmosfera_LMD_nitr.dat')
-         if (ierr /= 0) then
-            write(*,*)'Error : cannot open file atmosfera_LMD_nitr.dat '
-            write(*,*)'(in aeronomars/inichim_1D.F)'
-            write(*,*)'It should be in :', datadir
-            write(*,*)'1) You can change this directory address in '
-            write(*,*)'   file phymars/datafile.h'
-            write(*,*)'2) If necessary atmosfera_LMD_nitr.dat (and others)'
-            write(*,*)'   can be obtained online on:'
-            write(*,*)' http://www.lmd.jussieu.fr/~lmdz/planets/mars/datadir'
-            STOP
-         endif
-      endif   ! Of if(flagnitro)
-
-
-! 2.2 read initialization files'
-
-! major species
-
-      read(210,*)
-      do l = 1,nalt
-         read(210,*) dummy, tinit(l), pinit(l), densinit(l), &
-                     (vmrinit(l,n), n = 1,7)
-         pinit(l) = pinit(l)*100.              ! conversion in Pa
-         pinit(l) = log(pinit(l))              ! for the vertical interpolation
-      end do
-      close(210)
-
-! minor species
-
-      read(220,*)
-      do l = 1,nalt
-         read(220,*) dummy, (vmrinit(l,n), n = 8,14)
-      end do 
-      close(220)
-
-! nitrogen species
-
-      if(flagnitro) then
-         read(230,*)
-         do l = 1,nalt
-            read(230,*) dummy, (vmrinit(l,n), n = 15,18)
+
+! 3.3 mmean
+      mmean(:) = 0.
+      do ilay=1,nlayer
+         do iq=1,nq
+            mmean(ilay) = mmean(ilay) + pqx(ilay,iq)*mmol(iq)
          end do
-         close(230)
-      endif
-      endif !if(1.eq.0)
-
-
-! initialization for the early eath
-      if (1.eq.0) then
-        do l = 1,nalt
-         vmrinit(l,:)=0e-7
-         vmrinit(l,1)=0.1 !co2
-         vmrinit(l,2)=0.9 !n2
-         vmrinit(l,3)=0.0 !o2
-         vmrinit(l,6)=4e-3 !h2
-         vmrinit(l,10)=1e-9 !h2o
-         vmrinit(l,18)=0.0e-5 !ch4
-         vmrinit(l,10:13)=0.0e-7 !n
-         vmrinit(l,14)=0.0 !n
-         vmrinit(l,15)=0.0 !no
-         vmrinit(l,16)=0.0 !no2  
-!         pinit(l)=aps(l) + bps(l)*ps
-!        vmrinit(l,18)=2e-3*min(pinit(l)/100.,1.) ! decrease with scale height above 1 hpa
-         vmrinit(l,2)=0.0
-         vmrinit(l,2)=1-sum(vmrinit(l,:)) !n2
-!         vmrinit(l,4)=0.1
-!         vmrinit(l,7)=0.001
-        end do
-      endif
-
-
-      
-! 3. initialization of tracers
-
-            do l = 1,nbp_lev
-
-               pgcm = aps(l) + bps(l)*ps  ! gcm pressure               
-               pgcm = log(pgcm)                ! for the vertical interpolation
-               mmean(l) = 0.
-               
-! 3.1 vertical interpolation
-               do n = 1,nspe
-                  call intrplf(pgcm,vmr,pinit,vmrinit(:,n),nalt)
-                  vmrint(n) = vmr
-                  iq = niq(n)
-                  mmean(l) = mmean(l) + vmrint(n)*mmol(iq)
-!                  mmean(l) = mmean(l) + vmrinit(1,n)*mmol(iq)
-               end do
-
-! 3.2 attribute mixing ratio: - all layers or only thermosphere
-!                             - with our without h2o 
-
-               if (flagthermo == 0 .or. (flagthermo == 1 .and. exp(pgcm) < 0.1)) then
-                  do n = 1,nq
-                    pq(l,iq) = 0.
-                    qsurf(iq) = 0.
-                  enddo
-
-                  do n = 1,nspe
-                     iq = niq(n)
-!                     if (iq /= igcm_h2o_vap .or. flagh2o == 1) then
-                        pq(l,iq) = vmrint(n)*mmol(iq)/mmean(l)
-!                        pq(l,iq) = vmrinit(1,n)*mmol(iq)/mmean(1)
-!                     end if
-                  end do
-!                     pq(l,igcm_ch4) = 2.e-3*min((aps(l) + bps(l)*ps)/100.,1.)*mmol(igcm_ch4)/mmean(l)
-               end if
- 
-            end do
-
-
-! set surface values of chemistry tracers to zero
-
-      if (flagthermo == 0) then
-         ! NB: no problem for "surface water vapour" tracer which is always 0
-         do n = 1,nspe
-            iq = niq(n)
-            qsurf(iq) = 0.
+      end do
+
+! 3.4 convert vmr to mmr
+
+      do ilay=1,nlayer
+         do iq=1,nq
+            pq(ilay,iq) = pqx(ilay,iq)*mmol(iq)/mmean(ilay)
          end do
-      end if
-
-! 3.3 initialization of tracers not contained in the initialization files
-
-! methane : 10 ppbv
-
-!      if (igcm_ch4 /= 0) then
-!         vmr = 10.e-9       
-!               do l = 1,nbp_lev
-!                  pq(l,igcm_ch4) = vmr*mmol(igcm_ch4)/mmean(l)
-!               end do
-!         ! set surface value to zero
-!         qsurf(igcm_ch4) = 0.
-!      end if
-
-      
-      ! deallocations
-
-      deallocate(niq)
-      deallocate(vmrinit)
-      deallocate(vmrint)
+      end do
+
+! 4. Hard coding
+! Do whatever you want here to specify pq and qsurf
+! Or use #ModernTrac-v1 and add another option section 2.
 
       end
Index: trunk/LMDZ.GENERIC/libf/phystd/dyn1d/rcm1d.F
===================================================================
--- trunk/LMDZ.GENERIC/libf/phystd/dyn1d/rcm1d.F	(revision 2541)
+++ trunk/LMDZ.GENERIC/libf/phystd/dyn1d/rcm1d.F	(revision 2542)
@@ -898,5 +898,5 @@
            allocate(nametmp(nq))
            nametmp(1:nq)=tname(1:nq)
-           call inichim_1D(nq, q, qsurf, psurf, 0, 0)
+           call inichim_1D(nlayer, nq, q, qsurf, play, 0, 0)
            tname(1:nq)=nametmp(1:nq)
            noms(1:nq)=nametmp(1:nq)
Index: trunk/LMDZ.GENERIC/libf/phystd/inifis_mod.F90
===================================================================
--- trunk/LMDZ.GENERIC/libf/phystd/inifis_mod.F90	(revision 2541)
+++ trunk/LMDZ.GENERIC/libf/phystd/inifis_mod.F90	(revision 2542)
@@ -422,4 +422,19 @@
      write(*,*) "photochem = ",photochem
 
+     write(*,*) "Use photolysis heat table ?"
+     photoheat=.false.         ! default value
+     call getin_p("photoheat",photoheat)
+     write(*,*) "photoheat = ",photoheat
+
+     write(*,*) "Use photolysis online calculation ?"
+     jonline=.false.         ! default value
+     call getin_p("jonline",jonline)
+     write(*,*) "jonline = ",jonline
+
+     write(*,*) "Use deposition ?"
+     depos=.false.         ! default value
+     call getin_p("depos",depos)
+     write(*,*) "depos = ",depos
+
      write(*,*)"Production of haze ?"
      haze=.false. ! default value
Index: trunk/LMDZ.GENERIC/libf/phystd/initracer.F
===================================================================
--- trunk/LMDZ.GENERIC/libf/phystd/initracer.F	(revision 2541)
+++ trunk/LMDZ.GENERIC/libf/phystd/initracer.F	(revision 2542)
@@ -65,12 +65,12 @@
                ! Temporary not implemented solution
                if (nqtot/=nq) then
-                 call abort_physic('initracer','Different number of&
-     & tracers in dynamics and physics not managed yet',1)
+                 call abort_physic('initracer','Different number of '//
+     & 'tracers in dynamics and physics not managed yet',1)
                endif
                EXIT
              ENDIF
            ELSE ! If pb, or if reached EOF without having found nqtot
-             call abort_physic('initracer','Unable to read numbers&
-     & of tracers in traceur.def',1)
+             call abort_physic('initracer','Unable to read numbers '//
+     & 'of tracers in traceur.def',1)
            ENDIF
          ENDDO
@@ -83,4 +83,6 @@
        IF (.NOT.ALLOCATED(noms))         ALLOCATE(noms(nq))
        IF (.NOT.ALLOCATED(mmol))         ALLOCATE(mmol(nq))
+       IF (.NOT.ALLOCATED(aki))          ALLOCATE(aki(nqtot))
+       IF (.NOT.ALLOCATED(cpi))          ALLOCATE(cpi(nqtot))
        IF (.NOT.ALLOCATED(radius))       ALLOCATE(radius(nq))
        IF (.NOT.ALLOCATED(rho_q))        ALLOCATE(rho_q(nq))
@@ -90,7 +92,12 @@
        IF (.NOT.ALLOCATED(qextrhor))     ALLOCATE(qextrhor(nq))
        IF (.NOT.ALLOCATED(igcm_dustbin)) ALLOCATE(igcm_dustbin(nq))
+       IF (.NOT.ALLOCATED(is_chim))      ALLOCATE(is_chim(nqtot))
        !! initialization
-       alpha_lift(:)=0.
-       alpha_devil(:)=0.
+       alpha_lift(:)  = 0.
+       alpha_devil(:) = 0.
+       mmol(:)        = 0.
+       aki(:)         = 0.
+       cpi(:)         = 0.
+       is_chim(:)     = 0
        
        ! Added by JVO 2017 : these arrays are handled later
@@ -382,4 +389,8 @@
       close(407)
 
+      ! Calculate number of species in the chemistry
+      nesp = sum(is_chim)
+      write(*,*) 'Number of species in the chemistry nesp = ',nesp
+
 c------------------------------------------------------------
 c     Initialisation tracers ....
@@ -469,4 +480,5 @@
           ! JVO 20 : We should add a sanity check aborting when duplicates in names !
           write(*,*)"initracer: iq=",iq,"noms(iq)=",trim(noms(iq))
+          ! option mmol
           if (index(tracline,'mmol='   ) /= 0) then
               read(tracline(index(tracline,'mmol=')+len('mmol='):),*)
@@ -478,4 +490,34 @@
      $             mmol(iq)
           end if
+          ! option aki 
+          if (index(tracline,'aki='   ) /= 0) then
+              read(tracline(index(tracline,'aki=')+len('aki='):),*)
+     $             aki(iq)
+              write(*,*) ' Parameter value (traceur.def) : aki=',
+     $             aki(iq)
+          else
+              write(*,*) ' Parameter value (default)     : aki=',
+     $             aki(iq)
+          end if
+          ! option cpi 
+          if (index(tracline,'cpi='   ) /= 0) then
+              read(tracline(index(tracline,'cpi=')+len('cpi='):),*)
+     $             cpi(iq)
+              write(*,*) ' Parameter value (traceur.def) : cpi=',
+     $             cpi(iq)
+          else
+              write(*,*) ' Parameter value (default)     : cpi=',
+     $             cpi(iq)
+          end if
+          ! option is_chim 
+          if (index(tracline,'is_chim='   ) /= 0) then
+          read(tracline(index(tracline,'is_chim=')+len('is_chim='):),*)
+     $             is_chim(iq)
+              write(*,*) ' Parameter value (traceur.def) : is_chim=',
+     $             is_chim(iq)
+          else
+              write(*,*) ' Parameter value (default)     : is_chim=',
+     $             is_chim(iq)
+          end if
       end subroutine get_tracdat
 
Index: trunk/LMDZ.GENERIC/libf/phystd/physiq_mod.F90
===================================================================
--- trunk/LMDZ.GENERIC/libf/phystd/physiq_mod.F90	(revision 2541)
+++ trunk/LMDZ.GENERIC/libf/phystd/physiq_mod.F90	(revision 2542)
@@ -31,5 +31,5 @@
                           alpha_lift, alpha_devil, qextrhor, &
                           igcm_h2o_ice, igcm_h2o_vap, igcm_dustbin, &
-                          igcm_co2_ice
+                          igcm_co2_ice, nesp, is_chim
       use time_phylmdz_mod, only: ecritphy, iphysiq, nday
       use phyetat0_mod, only: phyetat0
@@ -258,5 +258,5 @@
       real omega(ngrid,nlayer)            ! omega velocity (Pa/s, >0 when downward)
 
-      integer l,ig,ierr,iq,nw,isoil
+      integer l,ig,ierr,iq,nw,isoil,iesp
       
       real zls                       ! Solar longitude (radians).
@@ -300,4 +300,5 @@
       real dt_ekman(ngrid,noceanmx), dt_hdiff(ngrid,noceanmx) ! Slab_ocean routine.
       real zdtsw1(ngrid,nlayer), zdtlw1(ngrid,nlayer)         ! Callcorrk routine.
+      real zdtchim(ngrid,nlayer)                              ! Calchim routine.
                               
       ! For Surface Tracers : (kg/m2/s)
@@ -323,6 +324,6 @@
       real dqvaplscale(ngrid,nlayer)  ! Largescale routine.
       real dqcldlscale(ngrid,nlayer)  ! Largescale routine.
-      REAL zdqchim(ngrid,nlayer,nq)   ! Calchim_asis routine
-      REAL zdqschim(ngrid,nq)         ! Calchim_asis routine
+      REAL,allocatable,save :: zdqchim(:,:,:) ! Calchim_asis routine
+      REAL,allocatable,save :: zdqschim(:,:)  ! Calchim_asis routine
 
       REAL array_zero1(ngrid)
@@ -476,4 +477,6 @@
             if(photochem) then
               call ini_conc_mod(ngrid,nlayer)
+              IF (.NOT.ALLOCATED(zdqchim))  ALLOCATE(zdqchim(ngrid,nlayer,nesp))
+              IF (.NOT.ALLOCATED(zdqschim)) ALLOCATE(zdqschim(ngrid,nesp))
             endif
          endif
@@ -1487,14 +1490,19 @@
                         fract,zzlev,zzlay,zday,pq,pdq,zdqchim,zdqschim, &
                         array_zero1,array_zero1,                        &
-                        pu,pdu,pv,pdv,array_zero2,array_zero2)
+                        pu,pdu,pv,pdv,array_zero2,array_zero2,icount,zdtchim)
 
            ! increment values of tracers:
-           DO iq=1,nq ! loop on all tracers; tendencies for non-chemistry
-                      ! tracers is zero anyways
-             DO l=1,nlayer
-               DO ig=1,ngrid
-                 pdq(ig,l,iq)=pdq(ig,l,iq)+zdqchim(ig,l,iq)
+           iesp = 0
+           DO iq=1,nq   ! loop on all tracers; tendencies for non-chemistry
+                        ! tracers is zero anyways
+                        ! September 2020: flag is_chim to increment only on chemical species
+             IF (is_chim(iq)==1) THEN
+               iesp = iesp + 1
+               DO l=1,nlayer
+                 DO ig=1,ngrid
+                   pdq(ig,l,iq)=pdq(ig,l,iq)+zdqchim(ig,l,iesp)
+                 ENDDO
                ENDDO
-             ENDDO
+             ENDIF
            ENDDO ! of DO iq=1,nq
 
@@ -1507,4 +1515,7 @@
              ENDDO
            ENDDO ! of DO iq=1,nq
+
+           ! increment values of temperature:
+           pdt(1:ngrid,1:nlayer)=pdt(1:ngrid,1:nlayer)+zdtchim(1:ngrid,1:nlayer)
 
          END IF  ! of IF (photochem)
Index: trunk/LMDZ.GENERIC/libf/phystd/tracer_h.F90
===================================================================
--- trunk/LMDZ.GENERIC/libf/phystd/tracer_h.F90	(revision 2541)
+++ trunk/LMDZ.GENERIC/libf/phystd/tracer_h.F90	(revision 2542)
@@ -5,5 +5,6 @@
 
        integer, save :: nqtot ! total number of tracers
-!$OMP THREADPRIVATE(nqtot)
+       integer, save :: nesp  ! number of species in the chemistry
+!$OMP THREADPRIVATE(nqtot,nesp)
 
        logical :: moderntracdef=.false. ! Standard or modern traceur.def
@@ -12,4 +13,6 @@
        character*30, save, allocatable :: noms(:)   ! name of the tracer
        real, save, allocatable :: mmol(:)     ! mole mass of tracer (g/mol-1) 
+       real, save, allocatable :: aki(:)      ! to compute coefficient of thermal concduction if photochem
+       real, save, allocatable :: cpi(:)      ! to compute cpnew in concentration.F if photochem
        real, save, allocatable :: radius(:)   ! dust and ice particle radius (m)
        real, save, allocatable :: rho_q(:)    ! tracer densities (kg.m-3)
@@ -25,6 +28,9 @@
        real,save :: rho_co2     ! CO2 ice density (kg.m-3)
        real,save :: ref_r0        ! for computing reff=ref_r0*r0 (in log.n. distribution)
-!$OMP THREADPRIVATE(noms,mmol,radius,rho_q,qext,alpha_lift,alpha_devil,qextrhor, &
+!$OMP THREADPRIVATE(noms,mmol,aki,cpi,radius,rho_q,qext,alpha_lift,alpha_devil,qextrhor, &
 	!$OMP varian,r3n_q,rho_dust,rho_ice,rho_co2,ref_r0)
+
+       integer, save, allocatable :: is_chim(:) ! 1 if tracer used in chemistry, else 0
+!$OMP THREADPRIVATE(is_chim)
 
 ! tracer indexes: these are initialized in initracer and should be 0 if the
