! ==============================================================================
! {%CMODEL}_dbl_si
! generated: {%TIMEDATE}
!
! this module is generated by imdouble
!
! inter-configuration driver module
! level: smil si
!
! {$DBL_INFO} ! this is a template for isotopes configuration
!
! [Gromov, MPI-C, 2007-2009]
! ==============================================================================

! - general doubling parameters (as conditional defines) -----------------------

#include "{%CMODEL}_dbl_parameters.inc"

! -----------------------------------------------------------------------------

#ifdef ECHAM5
#define _RI_KN_    jk,jt
#define _RI_YK_    jk,jrow
#endif

#ifdef COSMO
#define _RI_KN_    jt,jk
#define _RI_YK_    jrow,jk
#endif

! -----------------------------------------------------------------------------

MODULE {%CMODEL}_dbl_si

! mecca/kpp
  USE messy_mecca_kpp, ONLY: dp

! ECHAM5/MESSy
  USE messy_main_blather_bi,    ONLY: start_message_bi, end_message_bi
  USE messy_main_data_bi,       ONLY: nproma, ngpblks

! inter-configuration module: common utils, consts
  USE {%CMODEL}_dbl_common
! configurations linked
! {$CONF_LIST} [%  USE {%CMODEL}_@\n  USE {%CMODEL}_@_si\n%]

  IMPLICIT NONE

  INTEGER, PARAMETER      :: is = 1
  PRIVATE is

  PUBLIC mecca_dbl_init_coupling
  PUBLIC mecca_dbl_preprocess       ! routines to be called before mecca operates
  PUBLIC mecca_dbl_postprocess      !                       after
  PUBLIC mecca_dbl_calc_xtte4scav   ! scavenging tendencies adjustment
  PUBLIC mecca_dbl_sub_regtracname  ! dbl->reg tracer name substitution for drydep
  PUBLIC mecca_dbl_sub_regtracno    ! dbl->reg tracer no substitution for drydep
  PUBLIC mecca_dbl_init
  PUBLIC mecca_dbl_result
  
#ifdef dbl_FO17
  INTEGER :: dbl_FO17_top_mdf_H2O_level = 0
#endif

! =============================================================================

CONTAINS

! -----------------------------------------------------------------------------

  SUBROUTINE mecca_dbl_init_coupling

  ! ECHAM5/MESSy
    USE messy_main_mpi_bi,        ONLY: p_parallel_io
    USE messy_main_data_bi,       ONLY: vct, nlev, nlevp1, nvclev

    IMPLICIT NONE

#ifdef dbl_FO17
  ! for the additional dbl_FO17 parameterisation
    REAL(dp) :: alt, hypi(nlevp1), h_a(nvclev), h_b(nvclev), sfpress
    INTEGER  :: jk
#endif

  ! LOCAL
    CHARACTER(len=*), PARAMETER :: substr = 'mecca_dbl_init_coupling'
    CHARACTER(len=1024) :: info
    
    INTEGER :: status

  ! ----------------------------------------------------------------------------

  ! assigning regular to tagged tracers

    CALL start_message_bi(submodstr, 'SCANNING TRACERS', substr)

  ! scanning tracers for each confiuration
! {$CONF_LIST} [%    CALL @_scan_tracs %]

  ! scan PTs if there are any
    CALL mecca_dbl_scanPTs(info)
    IF (p_parallel_io) print *,info

    CALL end_message_bi(submodstr, 'SCANNING TRACERS', substr)

  ! ----------------------------------------------------------------------------

#ifdef dbl_FO17

  ! additional dbl_FO17 parameterisation

  ! borrowed from scav: determining the level of 200hPa (tropopause) for
  ! the D17O tropospheric water approximation 

    CALL start_message_bi(submodstr, 'dbl_FO17 parameterisation', substr)

    alt = 2.E4_dp       ! desired level in Pa, (= 200 hPa)

    DO jk = 1, nvclev
      h_a(jk) = vct(jk)
      h_b(jk) = vct(jk+nvclev)
    ENDDO

    sfpress = 1.E5_dp   ! reference pressure (= 1000 hPa)

    DO jk = 1, nlev+1
      hypi(jk) = h_a(jk) + h_b(jk) * sfpress
    ENDDO

    dbl_FO17_top_mdf_H2O_level = nlev + 1

    DO jk = 1, nlev
      IF (hypi(jk) < alt .AND. hypi(jk+1) >= alt) THEN
        dbl_FO17_top_mdf_H2O_level = jk
        EXIT
      ENDIF
    ENDDO

    IF (p_parallel_io) &
      print*, '  ', substr, ': H2O MIF is reset in the levels located below ', &
        alt/100, ' hPa  (nos. ', dbl_FO17_top_mdf_H2O_level, ' to ', nlev, ')'

    CALL end_message_bi(submodstr, 'dbl_FO17 parameterisation', substr)

#endif

  END SUBROUTINE mecca_dbl_init_coupling


! -----------------------------------------------------------------------------

! routines to be called before mecca operates
  SUBROUTINE mecca_dbl_preprocess(Conc)

    USE messy_main_data_bi,       ONLY: nlev, kproma
#ifndef MESSYTIMER
    USE messy_main_data_bi, & 
#else
    USE messy_main_timer,   &
#endif
      ONLY: lstart, current_time_step

    IMPLICIT NONE

    REAL(dp), INTENT(INOUT) :: Conc(:,:)
    INTEGER                 :: jb, jk, jp    ! counters

    jb = 0
    level_loop: DO jk = 1, nlev
      kproma_loop: DO jp = 1, kproma
        jb = jb + 1

#ifdef INITFAST_E5
      ! fast initializing configurations here at the first timestep
        IF (lstart) THEN
! {$CONF_LIST} [%          CALL @_x1(Conc(jb,:))%]
        ENDIF
#endif

      ! performing mass correction w.r.t. the regular mechanism
! {$CONF_LIST} [%        CALL @_correct(Conc(jb,:)) %]

      ! resetting PTs before integration starts
        CALL mecca_dbl_resetPTs(Conc(jb,:))

#ifdef dbl_FO17
      ! non-anomalously enriched main O reservoirs
      ! O2
        Conc(jb,ind_FO17O2) = 0.0_dp
      ! water in the troposphere
        IF (jk .GT. dbl_FO17_top_mdf_H2O_level) THEN
          Conc(jb,ind_FO17H2O) = 0.0_dp
        ENDIF
#endif

      ENDDO kproma_loop
    ENDDO level_loop

#ifdef INITFAST_E5
    IF (lstart) print *,'mecca_dbl_preprocess(si): INITFAST_E5 triggered initialization'
#endif
#ifdef DEBUG
    print *,'mecca_dbl_preprocess(si): passed'
#endif

  END SUBROUTINE mecca_dbl_preprocess



! -----------------------------------------------------------------------------

! routines to be called after mecca operates
  SUBROUTINE mecca_dbl_postprocess(Conc)

    USE messy_main_mpi_bi,        ONLY: p_pe
    USE messy_main_data_bi,       ONLY: nlev, kproma, nproma, &
                                        time_step_len

    IMPLICIT NONE

    REAL(dp), INTENT(INOUT) :: Conc(:,:)
    INTEGER                 :: jb, jk, jp    ! counters

    jb = 0
    level_loop: DO jk = 1, nlev
      kproma_loop: DO jp = 1, kproma
        jb = jb + 1

      ! skipped: {$zzzCONF_LIST} [%    CALL @_process%] this is to call when iso_si will be ready
      ! skipped: calculating the number of specs falling below THRES

      ! by default, to remove deviation due to KIEs, correcting
      ! performing mass correction w.r.t. the regular mechanism
! {$CONF_LIST} [%        CALL @_correct(Conc(jb,:)) %]

      ! every-configuration totals update
! {$CONF_LIST} [%        CALL @_calctotals(Conc(jb,:)) %]

      ! converting PTs values (integral) into average reaction rates
        CALL mecca_dbl_intPTs2arr(Conc(jb,:), time_step_len)

      ENDDO kproma_loop
    ENDDO level_loop
    
#ifdef DEBUG
    print *,'mecca_dbl_postprocess(si): passed'
#endif 

  END SUBROUTINE mecca_dbl_postprocess



! -----------------------------------------------------------------------------

  SUBROUTINE mecca_dbl_calc_xtte4scav(xtte_scav, max_lev_scav, pxtp1, kproma)

    USE messy_main_data_bi,       ONLY: nlev, nproma
    USE messy_main_tracer_mem_bi, ONLY: ntrac => ntrac_gp

    IMPLICIT NONE

  ! input: calculated tendencies for regulars in scav
    REAL(dp), INTENT(INOUT) :: xtte_scav(:,:,:)   ! scav_e5: ALLOCATE(xtte_scav(nproma,nlev,ntrac)), ntrac=>ntrac_gp
  ! scav. calculation levels constraint, kproma
    INTEGER, INTENT(IN)     :: max_lev_scav, kproma
  ! tracer field provided by scav
    REAL(dp), INTENT(IN)    :: pxtp1(:,:,:)

  ! calling each configuration for tendency update
! {$CONF_LIST} [%    CALL @_calc_xtte4scav(xtte_scav, max_lev_scav, pxtp1, kproma) %]

  END SUBROUTINE mecca_dbl_calc_xtte4scav



! -----------------------------------------------------------------------------

  SUBROUTINE mecca_dbl_sub_regtracname(trindex, reg_trname)

    IMPLICIT NONE

  ! tracer referring index
    INTEGER, INTENT(IN)             :: trindex
  ! tracer name to substitute
    CHARACTER(len=*), INTENT(INOUT) :: reg_trname
  
  ! calling each configuration to try to find the reg tracer name
! {$CONF_LIST} [%    IF (@_sub_regtracname(trindex, reg_trname)) RETURN%]

  END SUBROUTINE mecca_dbl_sub_regtracname


! -----------------------------------------------------------------------------

  SUBROUTINE mecca_dbl_sub_regtracno(trindex, reg_trindex)

    IMPLICIT NONE

  ! tracer referring index
    INTEGER, INTENT(IN)    :: trindex
  ! tracer no to substitute
    INTEGER, INTENT(INOUT) :: reg_trindex
  
  ! calling each configuration to try to find the reg tracer name
! {$CONF_LIST} [%    IF (@_sub_regtracno(trindex, reg_trindex)) RETURN%]

  END SUBROUTINE mecca_dbl_sub_regtracno


! -----------------------------------------------------------------------------

  SUBROUTINE mecca_dbl_init(Conc)

    IMPLICIT NONE

    REAL(dp), INTENT(INOUT) :: Conc(:,:)

  ! some routines for configuration initialization can be called here

  END SUBROUTINE mecca_dbl_init



! -----------------------------------------------------------------------------

  SUBROUTINE mecca_dbl_result(model_time)
  
    IMPLICIT NONE
    
    REAL(dp), INTENT(IN) :: model_time
    
  ! routines for additional data output (si) for configurations to be here

#ifdef DEBUG
    print *,'mecca_dbl_result(si): passed'
#endif 

  END SUBROUTINE mecca_dbl_result



! ---------------------------------------------------------------------------

END MODULE {%CMODEL}_dbl_si

! ***************************************************************************

