Index: /trunk/LMDZ.PLUTO/libf/phypluto/callkeys_mod.F90
===================================================================
--- /trunk/LMDZ.PLUTO/libf/phypluto/callkeys_mod.F90	(revision 3556)
+++ /trunk/LMDZ.PLUTO/libf/phypluto/callkeys_mod.F90	(revision 3557)
@@ -209,5 +209,12 @@
       real,save    :: deltap    ! width of transition to alpha_top (Pa)
 !$OMP THREADPRIVATE(alpha_top,pref,deltap)
-
+      
+!! Microphysics-specific variables
+      logical,save :: callmufi, call_haze_prod_pCH4
+!$OMP THREADPRIVATE(callmufi,call_haze_prod_pCH4)
+      real,save :: haze_p_prod, haze_tx_prod, haze_rc_prod
+      real,save :: haze_rm, haze_df, haze_rho
+      real,save :: air_rad
+!$OMP THREADPRIVATE(haze_p_prod,haze_tx_prod,haze_rc_prod,haze_rm,haze_df,haze_rho,air_rad)
 
       integer,save :: iddist
Index: /trunk/LMDZ.PLUTO/libf/phypluto/datafile_mod.F90
===================================================================
--- /trunk/LMDZ.PLUTO/libf/phypluto/datafile_mod.F90	(revision 3556)
+++ /trunk/LMDZ.PLUTO/libf/phypluto/datafile_mod.F90	(revision 3557)
@@ -10,8 +10,13 @@
 !      character(len=300) :: datadir='/san/home/rdword/gcm/datagcm'
       ! Default for LMD machines:
-      character(len=300),save :: datadir='/u/lmdz/WWW/planets/LMDZ.GENERIC/datagcm'
+      character(len=300),save :: datadir='datagcm'
 !$OMP THREADPRIVATE(datadir)
 
       ! Subdirectories of 'datadir':
+
+      ! Default directory for microphysics
+      ! Set in inifis_mod
+      character(LEN=100),save :: config_mufi ='datagcm/microphysics/config.cfg'
+!$OMP THREADPRIVATE(config_mufi)
 
       ! surfdir stores planetary topography, albedo, etc. (surface.nc files)
@@ -27,5 +32,4 @@
       character(len=300),save :: hazedens_file
 
-
       end module datafile_mod
 !-----------------------------------------------------------------------
Index: /trunk/LMDZ.PLUTO/libf/phypluto/inifis_mod.F90
===================================================================
--- /trunk/LMDZ.PLUTO/libf/phypluto/inifis_mod.F90	(revision 3556)
+++ /trunk/LMDZ.PLUTO/libf/phypluto/inifis_mod.F90	(revision 3557)
@@ -13,5 +13,5 @@
   use radcommon_h, only: ini_radcommon_h
   use radii_mod, only: radfixed, Nmix_n2
-  use datafile_mod, only: datadir,hazeprop_file,hazerad_file,hazemmr_file,hazedens_file
+  use datafile_mod, only: datadir,config_mufi,hazeprop_file,hazerad_file,hazemmr_file,hazedens_file
   use comdiurn_h, only: sinlat, coslat, sinlon, coslon
   use comgeomfi_h, only: totarea, totarea_planet
@@ -669,4 +669,65 @@
      !! Haze options
 
+     ! Microphysical moment model
+     ! ~~~~~~~~~~~~~~~~~~~~~~~~~~
+     if (is_master) write(*,*) "Run with or without microphysics?"
+     callmufi=.false. ! default value
+     call getin_p("callmufi",callmufi)
+     if (is_master) write(*,*)" callmufi = ",callmufi
+     
+     ! sanity check
+     if (callmufi.and.(.not.tracer)) then
+       print*,"You are running microphysics without tracer"
+       print*,"Please start again with tracer =.true."
+       stop
+     endif
+ 
+     if (is_master) write(*,*) "Path to microphysical config file?"
+     config_mufi='datagcm/microphysics/config.cfg' ! default value
+     call getin_p("config_mufi",config_mufi)
+     if (is_master) write(*,*)" config_mufi = ",config_mufi
+ 
+     if (is_master) write(*,*) "Use haze production from CH4 photolysis or production rate?"
+     call_haze_prod_pCH4=.false. ! default value
+     call getin_p("call_haze_prod_pCH4",call_haze_prod_pCH4)
+     if (is_master) write(*,*)" call_haze_prod_pCH4 = ",call_haze_prod_pCH4
+ 
+     if (is_master) write(*,*) "Pressure level of aerosols production (Pa)?"
+     haze_p_prod=1.0e-2 ! default value
+     call getin_p("haze_p_prod",haze_p_prod)
+     if (is_master) write(*,*)" haze_p_prod = ",haze_p_prod
+     
+     if (is_master) write(*,*) "Aerosol production rate (kg.m-2.s-1)?"
+     haze_tx_prod=9.8e-14 ! default value
+     call getin_p("haze_tx_prod",haze_tx_prod)
+     if (is_master) write(*,*)" haze_tx_prod = ",haze_tx_prod
+ 
+     if (is_master) write(*,*) "Equivalent radius production (m)?"
+     haze_rc_prod=1.0e-9 ! default value
+     call getin_p("haze_rc_prod",haze_rc_prod)
+     if (is_master) write(*,*)" haze_rc_prod = ",haze_rc_prod
+ 
+     if (is_master) write(*,*) "Monomer radius (m)?"
+     haze_rm=1.0e-8 ! default value
+     call getin_p("haze_rm",haze_rm)
+     if (is_master) write(*,*)" haze_rm = ",haze_rm
+ 
+     if (is_master) write(*,*) "Aerosol's fractal dimension?"
+     haze_df=2.0 ! default value
+     call getin_p("haze_df",haze_df)
+     if (is_master) write(*,*)" haze_df = ",haze_df
+ 
+     if (is_master) write(*,*) "Aerosol density (kg.m-3)?"
+     haze_rho=800.0 ! default value
+     call getin_p("haze_rho",haze_rho)
+     if (is_master) write(*,*)" haze_rho = ",haze_rho
+ 
+     if (is_master) write(*,*) "Radius of air molecule (m)?"
+     air_rad=1.75e-10 ! default value
+     call getin_p("air_rad",air_rad)
+     if (is_master) write(*,*)" air_rad = ",air_rad
+     
+     ! Pluto haze model
+     ! ~~~~~~~~~~~~~~~~
      if (is_master)write(*,*)trim(rname)//&
      "Production of haze ?"
Index: /trunk/LMDZ.PLUTO/libf/phypluto/initracer.F90
===================================================================
--- /trunk/LMDZ.PLUTO/libf/phypluto/initracer.F90	(revision 3556)
+++ /trunk/LMDZ.PLUTO/libf/phypluto/initracer.F90	(revision 3557)
@@ -3,5 +3,5 @@
       use surfdat_h, ONLY: dryness
       USE tracer_h
-      USE callkeys_mod, only: aerohaze,nb_monomer,haze,fractal,fasthaze,rad_haze
+      USE callkeys_mod, only: aerohaze,nb_monomer,haze,fractal,fasthaze,rad_haze,callmufi
       USE recombin_corrk_mod, ONLY: ini_recombin
       USE mod_phys_lmdz_para, only: is_master, bcast
@@ -23,8 +23,7 @@
 !   author: F.Forget
 !   ------
-!            Ehouarn Millour (oct. 2008) identify tracers by their names
-!            Y Jaziri & J. Vatant d'Ollone (2020) : Modern traceur.def
-!            L Teinturier (2022): Tracer names are now read here instead of
-!                                  inside interfaces
+!            Ehouarn Millour (oct. 2008): identify tracers by their names
+!            Y. Jaziri & J. Vatant d'Ollone (2020) : modern traceur.def
+!            B. de Batz de Trenquelléon (2024): specific microphysical tracers   
 !=======================================================================
 
@@ -36,7 +35,8 @@
       real r0_lift , reff_lift, rho_haze
       integer nqhaze(nq)               ! to store haze tracers
-      integer i, ia, block
+      integer i, ia, block, j
       character(len=20) :: txt ! to store some text
-      CHARACTER(LEN=20) :: tracername ! to temporarily store text
+      character(LEN=20) :: tracername ! to temporarily store text
+      character(LEN=20) :: str
 
 !-----------------------------------------------------------------------
@@ -350,4 +350,43 @@
         enddo
       endif
+      
+      ! Compute number of microphysics tracers:
+      ! By convention they all have the prefix "mu_" (case sensitive !)
+      nmicro = 0
+      IF (callmufi) THEN
+         DO iq=1,nq
+            str = noms(iq)
+            IF (str(1:3) == "mu_") THEN
+               nmicro = nmicro+1
+               count = count+1
+            ENDIF
+         ENDDO
+
+         ! Checking the expected number of tracers:
+         ! Microphysics moment model: nmicro = 4
+         IF (nmicro < 4) THEN
+            WRITE(*,*) "initracer:error:"," Inconsistent number of microphysical tracers"
+            WRITE(*,*) "expected at least 4 tracers,", nmicro, " given"
+            CALL abort
+         ELSE IF (nmicro > 4) THEN
+            WRITE(*,*) "!!! WARNING !!! initracer: I was expecting only four tracers, you gave me more."
+            CALL abort
+         ENDIF
+
+         ! microphysics indexes share the same values than original tracname.
+         IF (.NOT.ALLOCATED(micro_indx)) ALLOCATE(micro_indx(nmicro))
+         j = 1
+         DO i=1,nq
+            str = noms(i)
+            IF (str(1:3) == "mu_") THEN
+               micro_indx(j) = i 
+               j=j+1
+            ENDIF
+         ENDDO
+      
+      ELSE
+         IF (.NOT.ALLOCATED(micro_indx)) ALLOCATE(micro_indx(nmicro))
+      
+      ENDIF ! end of callmufi
 
       ! Get data of tracers. Need to rewind traceur.def first
@@ -406,4 +445,10 @@
       endif
 
+      ! Calculate number of microphysical tracer
+      write(*,*) 'Number of microphysical tracer nmicro = ',nmicro
+      IF (callmufi) THEN
+         call dumptracers(micro_indx)
+      ENDIF
+
 !     Processing modern traceur options
       if(moderntracdef) then
@@ -429,5 +474,5 @@
         else
            nmono=1
-        endif
+        endif ! end fractal
 
         ia=0
@@ -445,13 +490,11 @@
                block=1
                write(*,*) "i_haze=",i_haze
-               write(*,*) "Careful: if you set many haze traceurs in&
-     traceur.def,only ",tracername," will be radiatively active&
-     (first one in traceur.def)"
+               write(*,*) "Careful: if you set many haze traceurs in &
+                traceur.def,only ",tracername," will be radiatively active &
+                (first one in traceur.def)"
              endif
            enddo
-        endif
-     endif
-
-!     Initialization for water vapor !AF24: removed
+        endif ! end aerohaze
+      endif ! end haze
 
 !     Output for records:
Index: /trunk/LMDZ.PLUTO/libf/phypluto/physiq_mod.F90
===================================================================
--- /trunk/LMDZ.PLUTO/libf/phypluto/physiq_mod.F90	(revision 3556)
+++ /trunk/LMDZ.PLUTO/libf/phypluto/physiq_mod.F90	(revision 3557)
@@ -65,5 +65,6 @@
                               startphy_file, testradtimes,                    &
                               tracer, UseTurbDiff,                            &
-                              global1d, szangle
+                              global1d, szangle,                              &
+                              callmufi
       use generic_tracer_index_mod, only: generic_tracer_index
       use check_fields_mod, only: check_physics_fields
@@ -82,4 +83,7 @@
       use mod_phys_lmdz_omp_data, ONLY: is_omp_master
       USE mod_grid_phy_lmdz, ONLY: regular_lonlat, grid_type, unstructured
+      ! Microphysical model (mp2m)
+      use mp2m_calmufi
+      use mp2m_diagnostics
 
 #ifdef CPP_XIOS
@@ -105,5 +109,5 @@
 !     depending on the value of "tracer" in file "callphys.def".
 !
-!   It includes:
+!     It includes:
 !
 !      I. Initialization :
@@ -113,6 +117,6 @@
 !      II.1 Thermosphere
 !      II.2 Compute radiative transfer tendencies (longwave and shortwave) :
-!         II.a Option 1 : Call correlated-k radiative transfer scheme.
-!         II.b Option 2 : Atmosphere has no radiative effect.
+!         II.2.a Option 1 : Call correlated-k radiative transfer scheme.
+!         II.2.b Option 2 : Atmosphere has no radiative effect.
 !
 !      III. Vertical diffusion (turbulent mixing) 
@@ -124,5 +128,5 @@
 !
 !      VI. Tracers
-!         VI.1. Aerosols and particles.
+!         VI.1. Microphysics / Aerosols and particles.
 !         VI.2. Updates (pressure variations, surface budget).
 !         VI.3. Surface Tracer Update.
@@ -196,4 +200,5 @@
 !           Purge for Pluto model : A. Falco (2024)
 !           Adapting to Pluto : A. Falco, T. Bertrand (2024)
+!           Microphysical moment model: B. de Batz de Trenquelléon (2024)
 !==================================================================
 
@@ -394,4 +399,11 @@
       real zdpsrfmr(ngrid)        ! Pressure tendency for mass_redistribution routine (Pa/s).
 
+      ! Local variables for MICROPHYSICS:
+      ! ---------------------------------
+      real gzlat(ngrid,nlayer)           ! Altitude-Latitude-dependent gravity (this should be stored elsewhere...).
+      real pdqmufi(ngrid,nlayer,nq)      ! Microphysical tendency (X/kg_of_air/s).
+      real pdqmufi_prod(ngrid,nlayer,nq) ! Aerosols production tendency (kg/kg_of_air/s).
+      real int2ext(ngrid,nlayer)         ! Intensive to extensive factor (kg_air/m3: X/kg_air --> X/m3).
+
 ! Local variables for LOCAL CALCULATIONS:
 ! ---------------------------------------
@@ -464,6 +476,4 @@
 
       real reffrad_generic_zeros_for_wrf(ngrid,nlayer) !  !!! this is temporary, it is only a list of zeros, it will be replaced when a generic aerosol will be implemented
-
-      ! For Clear Sky Case. (AF24: deleted)
 
       real nconsMAX, vdifcncons(ngrid), cadjncons(ngrid) ! Vdfic water conservation test. By RW
@@ -645,7 +655,4 @@
          call getin_p("metallicity",metallicity) ! --- is not used here but necessary to call function Psat_generic
 
-!        Set some parameters for the thermal plume model !AF24: removed
-!        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
          if (ngrid.ne.1) then ! Note : no need to create a restart file in 1d.
             call physdem0("restartfi.nc",longitude,latitude,nsoilmx,ngrid,nlayer,nq, &
@@ -654,4 +661,6 @@
          endif
 
+!        Initialize correlated-k.
+!        ~~~~~~~~~~~~~~~~~~~~~~~~
          if (corrk) then
             ! We initialise the spectral grid here instead of
@@ -672,4 +681,11 @@
             endif
          endif
+
+!        Initialize microphysics.
+!        ~~~~~~~~~~~~~~~~~~~~~~~~
+         IF (callmufi) THEN
+            ! Initialize microphysics arrays.
+            call inimufi(ptimestep)
+         ENDIF ! end callmufi
 
 !!         call WriteField_phy("post_corrk_firstcall_qsurf",qsurf(1:ngrid,igcm_h2o_gas),1)
@@ -816,4 +832,18 @@
          call testconservmass(ngrid,nlayer,pplev(:,1),qsurf(:,1))
       endif
+
+      !  Compute variations of g with latitude (to do).
+      ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+      gzlat(:,:) = g
+
+      ! Initialize microphysical diagnostics.
+      ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+      IF (callmufi) THEN
+         ! Initialize intensive to extensive factor (kg_air/m3: X/kg_air --> X/m3).
+         int2ext(:,:) = (pplev(:,1:nlayer)-pplev(:,2:nlayer+1)) / gzlat(:,1:nlayer) / (zzlev(:,2:nlayer+1)-zzlev(:,1:nlayer))
+
+         ! Initialize microphysics diagnostics arrays.
+         call inimufi_diag(ngrid,nlayer,nq,pq,int2ext)
+      ENDIF ! end callmufi
 
 ! --------------------------------------------------------
@@ -1446,5 +1476,4 @@
       if (tracer) then
 
-!   7a. Methane, CO, and ice
 !      ---------------------------------------
 !      Methane ice condensation in the atmosphere
@@ -1516,56 +1545,92 @@
          END IF  ! of IF (carbox)
 
-!   7b. Haze particle production
-!     -------------------
-      IF (haze) THEN
-
-         zdqphot_prec(:,:)=0.
-         zdqphot_ch4(:,:)=0.
-         zdqhaze(:,:,:)=0
-         ! Forcing to a fixed haze profile if haze_proffix
-         if (haze_proffix.and.i_haze.gt.0.) then
-            call haze_prof(ngrid,nlayer,zzlay,pplay,pt,  &
-                           reffrad,profmmr)
-            zdqhaze(:,:,i_haze)=(profmmr(:,:)-pq(:,:,igcm_haze))  &
-                                 /ptimestep
-         else
-            call hazecloud(ngrid,nlayer,nq,ptimestep, &
-               pplay,pplev,pq,pdq,dist_star,mu0,zfluxuv,zdqhaze,   &
-               zdqphot_prec,zdqphot_ch4,zdqconv_prec,declin)
-         endif
-
-         DO iq=1, nq ! should be updated
-            DO l=1,nlayer
+         ! ----------------------------------------
+         !   VI.1. Microphysics / Aerosol particles
+         ! ----------------------------------------
+         ! Production for microphysics
+         IF (callmufi .and. call_haze_prod_pCH4) THEN
+            zdqphot_prec(:,:)   = 0.
+            zdqphot_ch4(:,:)    = 0.
+            pdqmufi_prod(:,:,:) = 0.
+
+            call hazecloud(ngrid,nlayer,nq,ptimestep,                             &
+                           pplay,pplev,pq,pdq,dist_star,mu0,zfluxuv,pdqmufi_prod, &
+                           zdqphot_prec,zdqphot_ch4,zdqconv_prec,declin)
+         ENDIF ! end callmufi .and. .and.call_haze_prod_pCH4
+
+         ! Call of microphysics
+         IF (callmufi) THEN
+
+            pdqmufi(:,:,:) = 0.
+   
+            call calmufi(ptimestep,pplev,zzlev,pplay,zzlay,gzlat,pt,pq,pdq,pdqmufi_prod,pdqmufi)
+   
+            pdq(:,:,:) = pdq(:,:,:) + pdqmufi(:,:,:)
+   
+            ! [BBT: Temporal tests]
+            ! >>>>>>>>>>>>>>>>>>>>>
+            !write(*,*) 'pdqmufi_prod', MAXVAL(pdqmufi_prod(1,:,11)), 'i', MAXLOC(pdqmufi_prod(1,:,11))
+            open(187,file='Mufi_tracers.out')
+            write(187,*) "Pressure (Pa) - Alt (m) - M0as (X/m3) - M3as (m3/m3) - M0af (X/m3) - M3af (m3/m3)"
+            do l=1,nlayer
+               write(187,*) pplay(1,l),zzlay(1,l), &
+               (pq(1,l,micro_indx(1))+pdq(1,l,micro_indx(1))*ptimestep)*int2ext(1,l), &
+               (pq(1,l,micro_indx(2))+pdq(1,l,micro_indx(2))*ptimestep)*int2ext(1,l), &
+               (pq(1,l,micro_indx(3))+pdq(1,l,micro_indx(3))*ptimestep)*int2ext(1,l), &
+               (pq(1,l,micro_indx(4))+pdq(1,l,micro_indx(4))*ptimestep)*int2ext(1,l)
+            enddo
+            close(187)
+            open(188,file='Mufi_tendencies.out')
+            write(188,*) "Pressure (Pa) - Alt (m) - dM0as (X/kg_air/s) - dM3as (m3/kg_air/s) - dM0af (X/kg_air/s) - dM3af (m3/kg_air/s)"
+            do l=1,nlayer
+               write(188,*) pplay(1,l),zzlay(1,l),pdqmufi(1,l,micro_indx(1)),pdqmufi(1,l,micro_indx(2)),pdqmufi(1,l,micro_indx(3)),pdqmufi(1,l,micro_indx(4))
+            enddo
+            close(188)
+            open(189,file='Mufi_diags.out')
+            write(189,*) "Pressure (Pa) - Alt (m) - rc_sph (m) - rc_fra (m) - aer_w_sph (m/s) - aer_w_fra (m/s) - aer_prec_sph (kg/m2/s) - aer_prec_fra (kg/m2/s)"
+            do l=1,nlayer
+               write(189,*) pplay(1,l),zzlay(1,l),mp2m_rc_sph(1,l),mp2m_rc_fra(1,l),mp2m_aer_s_w(1,l),mp2m_aer_f_w(1,l),mp2m_aer_s_prec(1),mp2m_aer_f_prec(1)
+            enddo
+            close(189)
+            ! <<<<<<<<<<<<<<<<<<<<<
+         ENDIF ! end callmufi
+
+         IF (haze) THEN
+            zdqphot_prec(:,:) = 0.
+            zdqphot_ch4(:,:)  = 0.
+            zdqhaze(:,:,:)    = 0.
+            
+            ! Forcing to a fixed haze profile if haze_proffix
+            if (haze_proffix.and.i_haze.gt.0.) then
+               call haze_prof(ngrid,nlayer,zzlay,pplay,pt,  &
+                              reffrad,profmmr)
+               zdqhaze(:,:,i_haze)=(profmmr(:,:)-pq(:,:,igcm_haze))/ptimestep
+            else
+               call hazecloud(ngrid,nlayer,nq,ptimestep,            &
+                  pplay,pplev,pq,pdq,dist_star,mu0,zfluxuv,zdqhaze, &
+                  zdqphot_prec,zdqphot_ch4,zdqconv_prec,declin)
+            endif
+
+            pdq(:,:,:) = pdq(:,:,:) + zdqhaze(:,:,:) ! Should be updated
+         ENDIF ! end haze
+
+         IF (fast.and.fasthaze) THEN
+            call prodhaze(ngrid,nlayer,nq,ptimestep,pplev,pq,pdq,dist_star, &
+                     mu0,declin,zdqprodhaze,zdqsprodhaze,gradflux,fluxbot,   &
+                     fluxlym_sol_bot,fluxlym_ipm_bot,flym_sol,flym_ipm)
+
             DO ig=1,ngrid
-                  pdq(ig,l,iq)=pdq(ig,l,iq)+ zdqhaze(ig,l,iq)
+               pdq(ig,1,igcm_ch4_gas)=pdq(ig,1,igcm_ch4_gas)+  &
+                                             zdqprodhaze(ig,igcm_ch4_gas)
+               pdq(ig,1,igcm_prec_haze)=pdq(ig,1,igcm_prec_haze)+ &
+                                          zdqprodhaze(ig,igcm_prec_haze)
+               pdq(ig,1,igcm_haze)=abs(pdq(ig,1,igcm_haze)+ &
+                                          zdqprodhaze(ig,igcm_haze))
+               qsurf(ig,igcm_haze)= qsurf(ig,igcm_haze)+ &
+                                             zdqsprodhaze(ig)*ptimestep
             ENDDO
-            ENDDO
-         ENDDO
-
-      ENDIF
-
-      IF (fast.and.fasthaze) THEN
-      call prodhaze(ngrid,nlayer,nq,ptimestep,pplev,pq,pdq,dist_star, &
-                mu0,declin,zdqprodhaze,zdqsprodhaze,gradflux,fluxbot,   &
-                fluxlym_sol_bot,fluxlym_ipm_bot,flym_sol,flym_ipm)
-
-      DO ig=1,ngrid
-         pdq(ig,1,igcm_ch4_gas)=pdq(ig,1,igcm_ch4_gas)+  &
-                                       zdqprodhaze(ig,igcm_ch4_gas)
-         pdq(ig,1,igcm_prec_haze)=pdq(ig,1,igcm_prec_haze)+ &
-                                     zdqprodhaze(ig,igcm_prec_haze)
-         pdq(ig,1,igcm_haze)=abs(pdq(ig,1,igcm_haze)+ &
-                                     zdqprodhaze(ig,igcm_haze))
-         qsurf(ig,igcm_haze)= qsurf(ig,igcm_haze)+ &
-                                         zdqsprodhaze(ig)*ptimestep
-      ENDDO
-
-      ENDIF
-
-  ! -------------------------
-  !   VI.3. Aerosol particles
-  ! -------------------------
-
-         !Generic Condensation
+         ENDIF ! end fast.and.fasthaze
+
+         ! Generic Condensation
          if (generic_condensation) then
             call condensation_generic(ngrid,nlayer,nq,ptimestep,pplev,pplay,   &
@@ -1626,5 +1691,5 @@
 
   ! ---------------
-  !   VI.4. Updates
+  !   VI.2. Updates
   ! ---------------
 
@@ -1664,5 +1729,5 @@
 
   ! -----------------------------
-  !   VI.6. Surface Tracer Update
+  !   VI.3. Surface Tracer Update
   ! -----------------------------
 
@@ -1709,5 +1774,4 @@
              ENDDO
       ENDIF
-
 
 !------------------------------------------------
Index: /trunk/LMDZ.PLUTO/libf/phypluto/tracer_h.F90
===================================================================
--- /trunk/LMDZ.PLUTO/libf/phypluto/tracer_h.F90	(revision 3556)
+++ /trunk/LMDZ.PLUTO/libf/phypluto/tracer_h.F90	(revision 3557)
@@ -1,10 +1,17 @@
 
        module tracer_h
-
+       !!------------------------------------------------------------------------------------------------------
+       !! Stores data related to physics tracers.
+       !!
+       !! The module provides additional methods: 
+       !!   - indexoftracer : search for the index of a tracer in the global table (tracers_h:noms) by name.
+       !!   - nameoftracer  : get the name of tracer from a given index (of the global table).
+       !!   - dumptracers   : print the names of all tracers indexes given in argument.
+       !!------------------------------------------------------------------------------------------------------
        implicit none
 
-       integer, save :: nqtot ! total number of tracers
-       integer, save :: nesp  ! number of species in the chemistry
-       integer, save :: ngt   ! number of generic tracers
+       integer, save :: nqtot  ! total number of tracers
+       integer, save :: nesp   ! number of species in the chemistry
+       integer, save :: ngt    ! number of generic tracers
        integer, save :: n_rgcs ! number of Radiative Generic Condensable Species
 !$OMP THREADPRIVATE(nqtot,nesp,ngt,n_rgcs)
@@ -13,25 +20,25 @@
 !$OMP THREADPRIVATE(moderntracdef)
 
-       character*30, save, allocatable :: noms(:)   ! name of the tracer
-       real, save, allocatable :: mmol(:)     ! mole mass of tracer (g/mol)
-       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)
-       real, save, allocatable :: qext(:)     ! Single Scat. Extinction coeff at 0.67 um
+       character*30, save, allocatable :: noms(:)! name of the tracer
+       real, save, allocatable :: mmol(:)        ! mole mass of tracer (g/mol)
+       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)
+       real, save, allocatable :: qext(:)        ! Single Scat. Extinction coeff at 0.67 um
        real, save, allocatable :: alpha_lift(:)  ! saltation vertical flux/horiz flux ratio (m-1)
        real, save, allocatable :: alpha_devil(:) ! lifting coeeficient by dust devil
-       real, save, allocatable :: qextrhor(:) ! Intermediate for computing opt. depth from q
+       real, save, allocatable :: qextrhor(:)    ! Intermediate for computing opt. depth from q
 
        real,save :: varian      ! Characteristic variance of log-normal distribution
-       real,save :: r3n_q     ! used to compute r0 from number and mass mixing ratio
-       real,save :: rho_dust     ! Mars dust density (kg.m-3)
+       real,save :: r3n_q       ! used to compute r0 from number and mass mixing ratio
+       real,save :: rho_dust    ! Mars dust density (kg.m-3)
        real,save :: rho_ice     ! Water ice density (kg.m-3)
-       real,save :: rho_ch4_ice     ! ch4 ice density (kg.m-3)
-       real,save :: rho_co_ice     ! co ice density (kg.m-3)
-       real,save :: rho_n2     ! N2 ice density (kg.m-3)
-       real,save :: lw_ch4     ! Latent heat CH4 gas -> solid
-       real,save :: lw_co      ! Latent heat CO gas -> solid
-       real,save :: lw_n2      ! Latent heat N2 gas -> solid
+       real,save :: rho_ch4_ice ! ch4 ice density (kg.m-3)
+       real,save :: rho_co_ice  ! co ice density (kg.m-3)
+       real,save :: rho_n2      ! N2 ice density (kg.m-3)
+       real,save :: lw_ch4      ! Latent heat CH4 gas -> solid
+       real,save :: lw_co       ! Latent heat CO gas -> solid
+       real,save :: lw_n2       ! Latent heat N2 gas -> solid
        integer,save :: nmono
        real,save :: ref_r0        ! for computing reff=ref_r0*r0 (in log.n. distribution)
@@ -49,30 +56,32 @@
        integer, save, allocatable :: is_condensable(:)      ! 1 if tracer is generic, else 0 (added LT)
        integer,save,allocatable :: is_rgcs(:)               ! 1 if tracer is a radiative generic condensable specie, else 0 (added LT 2022)
+!$OMP THREADPRIVATE(is_condensable,is_rgcs)   !also added by LT
        ! Lists of constants for condensable tracers
-       real, save, allocatable :: constants_mass(:)                    ! molecular mass of the specie (g/mol)
+       real, save, allocatable :: constants_mass(:)                 ! molecular mass of the specie (g/mol)
        real, save, allocatable :: constants_delta_gasH(:)           ! Enthalpy of vaporization (J/mol)
        real, save, allocatable :: constants_Tref(:)                 ! Ref temperature for Clausis-Clapeyron (K)
        real, save, allocatable :: constants_Pref(:)                 ! Reference pressure for Clausius Clapeyron (Pa)
-       real, save, allocatable :: constants_epsi_generic(:)                 ! fractionnal molecular mass (m/mugaz)
-       real, save, allocatable :: constants_RLVTT_generic(:)                ! Latent heat of vaporization (J/kg)
+       real, save, allocatable :: constants_epsi_generic(:)         ! fractionnal molecular mass (m/mugaz)
+       real, save, allocatable :: constants_RLVTT_generic(:)        ! Latent heat of vaporization (J/kg)
        real, save, allocatable :: constants_metallicity_coeff(:)    ! Coefficient to take into account the metallicity
-       real, save, allocatable :: constants_RCPV_generic(:)                   ! specific heat capacity of the tracer vapor at Tref
+       real, save, allocatable :: constants_RCPV_generic(:)         ! specific heat capacity of the tracer vapor at Tref
 !$OMP THREADPRIVATE(constants_mass,constants_delta_gasH,constants_Tref)
 !$OMP THREADPRIVATE(constants_Pref,constants_epsi_generic)
 !$OMP THREADPRIVATE(constants_RLVTT_generic,constants_metallicity_coeff,constants_RCPV_generic)
 
-!$OMP THREADPRIVATE(is_condensable,is_rgcs)   !also added by LT
 ! tracer indexes: these are initialized in initracer and should be 0 if the
 !                 corresponding tracer does not exist
 
-       !Pluto chemistry
+       ! Pluto chemistry
        integer,save :: igcm_co_gas
        integer,save :: igcm_n2
        integer,save :: igcm_ar
        integer,save :: igcm_ch4_gas ! methane gas
-       ! other tracers
-       integer,save :: igcm_ar_n2 ! for simulations using co2 +neutral gaz
+!$OMP THREADPRIVATE(igcm_co_gas,igcm_n2,igcm_ar,igcm_ch4_gas)
+       ! Other tracers
+       integer,save :: igcm_ar_n2   ! for simulations using co2 + neutral gaz
        integer,save :: igcm_ch4_ice ! methane ice
-       integer,save :: igcm_co_ice ! methane ice
+       integer,save :: igcm_co_ice  ! CO ice
+!$OMP THREADPRIVATE(igcm_ar_n2,igcm_ch4_ice,igcm_co_ice)
        integer,save :: igcm_prec_haze
        integer,save :: igcm_haze
@@ -81,4 +90,5 @@
        integer,save :: igcm_haze50
        integer,save :: igcm_haze100
+!$OMP THREADPRIVATE(igcm_prec_haze,igcm_haze,igcm_haze10,igcm_haze30,igcm_haze50,igcm_haze100)
        integer,save :: igcm_eddy1e6
        integer,save :: igcm_eddy1e7
@@ -86,7 +96,98 @@
        integer,save :: igcm_eddy1e8
        integer,save :: igcm_eddy5e8
+!$OMP THREADPRIVATE(igcm_eddy1e6,igcm_eddy1e7,igcm_eddy5e7,igcm_eddy1e8,igcm_eddy5e8)
 
-!$OMP THREADPRIVATE(igcm_co_gas,igcm_n2,igcm_ar,igcm_ch4_gas,igcm_ar_n2,igcm_ch4_ice,igcm_co_ice,igcm_prec_haze,igcm_haze,igcm_haze10,igcm_haze30,igcm_haze50,igcm_haze100,igcm_eddy1e6,igcm_eddy1e7,igcm_eddy5e7,igcm_eddy1e8,igcm_eddy5e8)
+       ! Microphysical model
+       integer, save :: nmicro = 0                 !! Number of microphysics tracers.
+       integer, save, allocatable :: micro_indx(:) !! Indexes of all microphysical tracers
+!$OMP THREADPRIVATE(nmicro)
+
+       CONTAINS
+
+       FUNCTION indexoftracer(name, sensitivity) RESULT(idx)
+          !! Get the index of a tracer by name.
+          !!
+          !! The function searches in the global tracer table (tracer_h:noms)
+          !! for the given name and returns the first index matching "name".
+          !! 
+          !! If no name in the table matches the given one, -1 is returned !
+          IMPLICIT NONE
+          CHARACTER(len=*), INTENT(in)  :: name         !! Name of the tracer to search.
+          LOGICAL, OPTIONAL, INTENT(in) :: sensitivity  !! Case sensitivity (true by default).
+          INTEGER                       :: idx          !! Index of the first tracer matching name or -1 if not found.
+          LOGICAL                       :: zsens
+          INTEGER                       :: j
+          CHARACTER(len=LEN(name))      :: zname
+          zsens = .true. ; IF(PRESENT(sensitivity)) zsens = sensitivity
+          idx = -1
+          IF (.NOT.ALLOCATED(noms)) RETURN
+          IF (zsens) THEN
+             DO j=1,SIZE(noms) 
+                IF (TRIM(noms(j)) == TRIM(name)) THEN
+                   idx = j ; RETURN 
+                ENDIF 
+             ENDDO
+          ELSE
+             zname = to_lower(name)
+             DO j=1,SIZE(noms) 
+                IF (TRIM(to_lower(noms(j))) == TRIM(zname)) THEN
+                   idx = j ; RETURN 
+                ENDIF 
+             ENDDO
+          ENDIF
+
+          CONTAINS
+
+          FUNCTION to_lower(istr) RESULT(ostr)
+             !! Lower case conversion function.
+             IMPLICIT NONE
+             CHARACTER(len=*), INTENT(in) :: istr
+             CHARACTER(len=LEN(istr))     :: ostr
+             INTEGER                      :: i,ic
+             ostr = istr
+             DO i = 1, LEN_TRIM(istr)
+                ic = ICHAR(istr(i:i))
+                IF (ic >= 65 .AND. ic < 90) ostr(i:i) = char(ic + 32)
+             ENDDO 
+          END FUNCTION to_lower
+       END FUNCTION indexoftracer
+
+       FUNCTION nameoftracer(indx) RESULT(name)
+          !! Get the name of a tracer by index.
+          !!
+          !! The function searches in the global tracer table (tracer_h:noms)
+          !! and returns the name of the tracer at given index.
+          !!
+          !! If the index is out of range an empty string is returned.
+          IMPLICIT NONE
+          INTEGER, INTENT(in) :: indx   !! Index of the tracer name to retrieve.
+          CHARACTER(len=30)   :: name   !! Name of the tracer at given index.
+          name = '' 
+          IF (.NOT.ALLOCATED(noms)) RETURN
+          IF (indx <= 0 .OR. indx > SIZE(noms)) RETURN
+          name = noms(indx)
+       END FUNCTION nameoftracer
+
+       SUBROUTINE dumptracers(indexes)
+          !! Print the names of the given list of tracers indexes.
+          INTEGER, DIMENSION(:), INTENT(in) :: indexes
+          INTEGER :: i,idx
+          CHARACTER(len=:), ALLOCATABLE :: suffix
+
+          IF (.NOT.ALLOCATED(noms)) THEN
+             WRITE(*,'(a)') "[tracers_h:dump_tracers] warning: 'noms' is not allocated, initracer has not be called yet"
+             RETURN
+          ENDIF
+
+          DO i=1,size(indexes)
+             idx = indexes(i)
+             IF (ANY(micro_indx == idx)) THEN
+                suffix = ' (micro)'
+             ELSE 
+                suffix=" ()"
+             ENDIF
+             WRITE(*,'(I5,(a),I6,(a))') i," -> ",idx ," : "//TRIM(noms(idx))//suffix
+          ENDDO
+       END SUBROUTINE dumptracers
 
        end module tracer_h
-
