!> \file mynnedmf_wrapper.F90
!!  This file contains all of the code related to running the MYNN 
!! eddy-diffusivity mass-flux scheme. 

!> The following references best describe the code within
!!    Olson et al. (2019, NOAA Technical Memorandum)
!!    Nakanishi and Niino (2009) \cite NAKANISHI_2009
      MODULE mynnedmf_wrapper

      contains

!> \section arg_table_mynnedmf_wrapper_init Argument Table
!! \htmlinclude mynnedmf_wrapper_init.html
!!
      subroutine mynnedmf_wrapper_init (          &
        &  con_cp, con_grav, con_rd, con_rv,      &
        &  con_cpv, con_cliq, con_cice, con_rcp,  &
        &  con_XLV, con_XLF, con_p608, con_ep2,   &
        &  con_karman, con_t0c,                   &
        &  do_mynnedmf,                           &
        &  errmsg, errflg                         )

        use machine,  only : kind_phys
        use bl_mynn_common

        implicit none

        logical,        intent(in)  :: do_mynnedmf
        character(len=*),intent(out):: errmsg
        integer,        intent(out) :: errflg

        real(kind_phys),intent(in)  :: con_xlv
        real(kind_phys),intent(in)  :: con_xlf
        real(kind_phys),intent(in)  :: con_rv
        real(kind_phys),intent(in)  :: con_rd
        real(kind_phys),intent(in)  :: con_ep2
        real(kind_phys),intent(in)  :: con_grav
        real(kind_phys),intent(in)  :: con_cp
        real(kind_phys),intent(in)  :: con_cpv
        real(kind_phys),intent(in)  :: con_rcp
        real(kind_phys),intent(in)  :: con_p608
        real(kind_phys),intent(in)  :: con_cliq
        real(kind_phys),intent(in)  :: con_cice
        real(kind_phys),intent(in)  :: con_karman
        real(kind_phys),intent(in)  :: con_t0c

        ! Initialize CCPP error handling variables
        errmsg = ''
        errflg = 0

        xlv    = con_xlv
        xlf    = con_xlf
        r_v    = con_rv
        r_d    = con_rd
        ep_2   = con_ep2
        grav   = con_grav
        cp     = con_cp
        cpv    = con_cpv
        rcp    = con_rcp
        p608   = con_p608
        cliq   = con_cliq
        cice   = con_cice
        karman = con_karman
        t0c    = con_t0c
       
        xls    = xlv+xlf      != 2.85E6 (J/kg) sublimation                                      
        rvovrd = r_v/r_d      != 1.608
        ep_3   = 1.-ep_2      != 0.378
        gtr    = grav/tref
        rk     = cp/r_d
        tv0    = p608*tref
        tv1    = (1.+p608)*tref
        xlscp  = (xlv+xlf)/cp
        xlvcp  = xlv/cp
        g_inv  = 1./grav

        ! Consistency checks
        if (.not. do_mynnedmf) then
          errmsg = 'Logic error: do_mynnedmf = .false.'
          errflg = 1
            return
         end if

      end subroutine mynnedmf_wrapper_init

!>\defgroup gp_mynnedmf MYNN-EDMF PBL and Shallow Convection Module  
!> This scheme (1) performs pre-mynnedmf work, (2) runs the mynnedmf, and (3) performs post-mynnedmf work
!> \section arg_table_mynnedmf_wrapper_run Argument Table
!! \htmlinclude mynnedmf_wrapper_run.html
!!
SUBROUTINE mynnedmf_wrapper_run(        &
     &  im,levs,                        &
     &  flag_init,flag_restart,         &
     &  lssav, ldiag3d, qdiag3d,        &
     &  lsidea, cplflx,                 &
     &  delt,dtf,dx,zorl,               &
     &  phii,u,v,omega,t3d,             &
     &  qgrs_water_vapor,               &
     &  qgrs_liquid_cloud,              &
     &  qgrs_ice,                       &
     &  qgrs_snow,                      &
     &  qgrs_cloud_droplet_num_conc,    &
     &  qgrs_cloud_ice_num_conc,        &
     &  qgrs_ozone,                     &
     &  qgrs_water_aer_num_conc,        &
     &  qgrs_ice_aer_num_conc,          &
     &  qgrs_cccn,                      &
     &  prsl,prsi,exner,                &
     &  slmsk,tsurf,qsfc,ps,            &
     &  ust,ch,hflx,qflx,wspd,rb,       &
     &  dtsfc1,dqsfc1,                  &
     &  dusfc1,dvsfc1,                  &
     &  dusfci_diag,dvsfci_diag,        &
     &  dtsfci_diag,dqsfci_diag,        &
     &  dusfc_diag,dvsfc_diag,          &
     &  dtsfc_diag,dqsfc_diag,          &
     &  dusfc_cice,dvsfc_cice,          &
     &  dtsfc_cice,dqsfc_cice,          &
     &  hflx_wat,qflx_wat,stress_wat,   &
     &  oceanfrac,fice,wet,icy,dry,     &
     &  dusfci_cpl,dvsfci_cpl,          &
     &  dtsfci_cpl,dqsfci_cpl,          &
     &  dusfc_cpl,dvsfc_cpl,            &
     &  dtsfc_cpl,dqsfc_cpl,            &
     &  recmol,                         &
     &  qke,qke_adv,Tsq,Qsq,Cov,        &
     &  el_pbl,sh3d,sm3d,exch_h,exch_m, &
     &  dqke,qwt,qshear,qbuoy,qdiss,    &
     &  Pblh,kpbl,                      &
     &  qc_bl,qi_bl,cldfra_bl,          &
     &  edmf_a,edmf_w,edmf_qt,          &
     &  edmf_thl,edmf_ent,edmf_qc,      &
     &  sub_thl,sub_sqv,det_thl,det_sqv,&
     &  nupdraft,maxMF,ktop_plume,      &
     &  dudt, dvdt, dtdt,                                  &
     &  dqdt_water_vapor,            dqdt_liquid_cloud,    & ! <=== ntqv, ntcw
     &  dqdt_ice,                    dqdt_snow,            & ! <=== ntiw, ntsw
     &  dqdt_ozone,                                        & ! <=== ntoz
     &  dqdt_cloud_droplet_num_conc, dqdt_ice_num_conc,    & ! <=== ntlnc, ntinc
     &  dqdt_water_aer_num_conc,     dqdt_ice_aer_num_conc,& ! <=== ntwa, ntia
     &  dqdt_cccn,                                         & ! <=== ntccn
     &  flag_for_pbl_generic_tend,                         &
     &  dtend, dtidx, index_of_temperature,                &
     &  index_of_x_wind, index_of_y_wind, ntke,            &
     &  ntqv, ntcw, ntiw, ntsw,                            &
     &  ntoz, ntlnc, ntinc, ntwa, ntia,                    &
     &  index_of_process_pbl, htrsw, htrlw, xmu,           &
     &  tke_budget,            bl_mynn_tkeadvect,          &
     &  bl_mynn_cloudpdf,      bl_mynn_mixlength,          &
     &  bl_mynn_edmf,                                      &
     &  bl_mynn_edmf_mom,      bl_mynn_edmf_tke,           &
     &  bl_mynn_cloudmix,      bl_mynn_mixqt,              &
     &  bl_mynn_output,        bl_mynn_closure,            &
     &  icloud_bl, do_mynnsfclay,                          &
     &  imp_physics, imp_physics_gfdl,                     &
     &  imp_physics_thompson, imp_physics_wsm6,            &
     &  imp_physics_fa,                                    &
     &  chem3d, frp, mix_chem, rrfs_sd, enh_mix,           &
     &  nchem, ndvel, vdep, smoke_dbg,                     &
     &  imp_physics_nssl, nssl_ccn_on,                     &
     &  ltaerosol, mraerosol, spp_wts_pbl, spp_pbl,        &
     &  lprnt, huge, errmsg, errflg                        )

! should be moved to inside the mynn:
     use machine,        only: kind_phys
     use bl_mynn_common, only: cp, r_d, grav, g_inv, zero, &
         xlv, xlvcp, xlscp, p608
     use module_bl_mynn, only: mynn_bl_driver

!------------------------------------------------------------------- 
     implicit none
!------------------------------------------------------------------- 

     real(kind_phys)               :: huge
     character(len=*), intent(out) :: errmsg
     integer, intent(out)          :: errflg

     logical, intent(in) :: lssav, ldiag3d, lsidea, qdiag3d
     logical, intent(in) :: cplflx

     !smoke/chem
     integer, intent(in) :: nchem, ndvel
     integer, parameter  :: kdvel=1
     logical, intent(in) :: smoke_dbg

! NAMELIST OPTIONS (INPUT):
     logical, intent(in) ::                                 &
     &       bl_mynn_tkeadvect,                             &
     &       ltaerosol,                                     &
     &       mraerosol,                                     &
     &       lprnt,                                         &
     &       do_mynnsfclay,                                 &
     &       flag_for_pbl_generic_tend,                     &
     &       nssl_ccn_on
      integer, intent(in) ::                                &
     &       bl_mynn_cloudpdf,                              &
     &       bl_mynn_mixlength,                             &
     &       icloud_bl,                                     &
     &       bl_mynn_edmf,                                  &
     &       bl_mynn_edmf_mom,                              &
     &       bl_mynn_edmf_tke,                              &
     &       bl_mynn_cloudmix,                              &
     &       bl_mynn_mixqt,                                 &
     &       bl_mynn_output,                                &
     &       imp_physics, imp_physics_wsm6,                 &
     &       imp_physics_thompson, imp_physics_gfdl,        &
     &       imp_physics_nssl, imp_physics_fa,              &
     &       spp_pbl,                                       &
     &       tke_budget
      real(kind_phys), intent(in) ::                        &
     &       bl_mynn_closure

!TENDENCY DIAGNOSTICS
      real(kind_phys), intent(inout), optional :: dtend(:,:,:)
      integer, intent(in) :: dtidx(:,:)
      integer, intent(in) :: index_of_temperature, index_of_x_wind
      integer, intent(in) :: index_of_y_wind, index_of_process_pbl
      integer, intent(in) :: ntoz, ntqv, ntcw, ntiw, ntsw, ntlnc
      integer, intent(in) :: ntinc, ntwa, ntia, ntke

!MISC CONFIGURATION OPTIONS
      INTEGER, PARAMETER ::                                              &
     &       bl_mynn_mixscalars=1
      LOGICAL ::                                                         &
     &       FLAG_QI, FLAG_QNI, FLAG_QC, FLAG_QS, FLAG_QNC,              &
     &       FLAG_QNWFA, FLAG_QNIFA, FLAG_QNBCA, FLAG_OZONE
      ! Define locally until needed from CCPP
      LOGICAL, PARAMETER :: cycling = .false.

!MYNN-1D
      REAL(kind_phys), intent(in) :: delt, dtf
      INTEGER, intent(in) :: im, levs
      LOGICAL, intent(in) :: flag_init, flag_restart
      INTEGER :: initflag, k, i
      INTEGER :: IDS,IDE,JDS,JDE,KDS,KDE,                                &
     &           IMS,IME,JMS,JME,KMS,KME,                                &
     &           ITS,ITE,JTS,JTE,KTS,KTE

      REAL(kind_phys) :: tem

!MYNN-3D
      real(kind_phys), dimension(:,:), intent(in)    :: phii
      real(kind_phys), dimension(:,:), intent(inout) ::                  &
     &        dtdt, dudt, dvdt,                                          &
     &        dqdt_water_vapor, dqdt_liquid_cloud, dqdt_ice,             &
     &        dqdt_snow,                                                 &
     &        dqdt_cloud_droplet_num_conc, dqdt_ice_num_conc,            &
     &        dqdt_ozone, dqdt_water_aer_num_conc, dqdt_ice_aer_num_conc
      real(kind_phys), dimension(:,:), intent(inout) ::dqdt_cccn
      real(kind_phys), dimension(:,:), intent(inout) ::                  &
     &        qke, qke_adv, EL_PBL, Sh3D, Sm3D,                          &
     &        qc_bl, qi_bl, cldfra_bl
     !These 10 arrays are only allocated when bl_mynn_output > 0
      real(kind_phys), dimension(:,:), intent(inout) ::                  &
     &        edmf_a,edmf_w,edmf_qt,                                     &
     &        edmf_thl,edmf_ent,edmf_qc,                                 &
     &        sub_thl,sub_sqv,det_thl,det_sqv
      real(kind_phys), dimension(:,:), intent(inout) ::                  &
     &        dqke,qWT,qSHEAR,qBUOY,qDISS
      real(kind_phys), dimension(:,:), intent(inout) ::                  &
     &        t3d,qgrs_water_vapor,qgrs_liquid_cloud,qgrs_ice,           &
     &        qgrs_snow
      real(kind_phys), dimension(:,:), intent(in) ::                     &
     &        u,v,omega,                                                 &
     &        exner,prsl,prsi,                                           &
     &        qgrs_cloud_droplet_num_conc,                               &
     &        qgrs_cloud_ice_num_conc,                                   &
     &        qgrs_ozone,                                                &
     &        qgrs_water_aer_num_conc,                                   &
     &        qgrs_ice_aer_num_conc
      real(kind_phys), dimension(:,:), intent(in)  ::qgrs_cccn
      real(kind_phys), dimension(:,:), intent(out) ::                    &
     &        Tsq, Qsq, Cov, exch_h, exch_m
      real(kind_phys), dimension(:), intent(in) :: xmu
      real(kind_phys), dimension(:,:), intent(in) :: htrsw, htrlw
      ! spp_wts_pbl only allocated if spp_pbl == 1
      real(kind_phys), dimension(:,:),       intent(in) :: spp_wts_pbl

     !LOCAL
      real(kind_phys), dimension(im,levs) ::                             &
     &        sqv,sqc,sqi,sqs,qnc,qni,ozone,qnwfa,qnifa,qnbca,           &
     &        dz, w, p, rho, th, qv, delp,                               &
     &        RUBLTEN, RVBLTEN, RTHBLTEN, RQVBLTEN,                      &
     &        RQCBLTEN, RQNCBLTEN, RQIBLTEN, RQNIBLTEN, RQSBLTEN,        &
     &        RQNWFABLTEN, RQNIFABLTEN, RQNBCABLTEN
      real(kind_phys), allocatable :: old_ozone(:,:)

!smoke/chem arrays
      real(kind_phys), dimension(:), intent(inout) :: frp
      logical, intent(in) :: mix_chem, enh_mix, rrfs_sd
      real(kind_phys), dimension(:,:,:), intent(inout) :: chem3d
      real(kind_phys), dimension(:,:  ), intent(inout) :: vdep
      real(kind_phys), dimension(im)   :: emis_ant_no

!MYNN-2D
      real(kind_phys), dimension(:), intent(in) ::                       &
     &        dx,zorl,slmsk,tsurf,qsfc,ps,                               &
     &        hflx,qflx,ust,wspd,rb,recmol

      real(kind_phys), dimension(:), intent(in) ::                       &
     &        dusfc_cice,dvsfc_cice,dtsfc_cice,dqsfc_cice,               &
     &        stress_wat,hflx_wat,qflx_wat,                              &
     &        oceanfrac,fice

      logical, dimension(:), intent(in) ::                               &
     &        wet, dry, icy

      real(kind_phys), dimension(:), intent(inout) ::                    &
     &        pblh,dusfc_diag,dvsfc_diag,dtsfc_diag,dqsfc_diag
      real(kind_phys), dimension(:), intent(out) ::                      &
     &        ch,dtsfc1,dqsfc1,dusfc1,dvsfc1,                            &
     &        dtsfci_diag,dqsfci_diag,dusfci_diag,dvsfci_diag,           &
     &        maxMF
      integer, dimension(:), intent(inout) ::                            &
     &        kpbl,nupdraft,ktop_plume

      real(kind_phys), dimension(:), intent(inout) ::                    &
     &        dusfc_cpl,dvsfc_cpl,dtsfc_cpl,dqsfc_cpl
      real(kind_phys), dimension(:), intent(inout) ::                    &
     &        dusfci_cpl,dvsfci_cpl,dtsfci_cpl,dqsfci_cpl

     !LOCAL
      real(kind_phys), dimension(im) ::                                  &
     &        hfx,qfx,rmol,xland,uoce,voce,znt,ts
      integer :: idtend
      real(kind_phys), dimension(im) :: dusfci1,dvsfci1,dtsfci1,dqsfci1
      real(kind_phys), allocatable :: save_qke_adv(:,:)

      ! Initialize CCPP error handling variables
      errmsg = ''
      errflg = 0

      if (lprnt) then
         write(0,*)"=============================================="
         write(0,*)"in mynn wrapper..."
         write(0,*)"flag_init=",flag_init
         write(0,*)"flag_restart=",flag_restart
      endif

      if (.not. flag_for_pbl_generic_tend .and. ldiag3d) then
         idtend = dtidx(ntke+100,index_of_process_pbl)
         if (idtend>=1) then
            allocate(save_qke_adv(im,levs))
            save_qke_adv=qke_adv
         endif
      endif

      ! DH* TODO: Use flag_restart to distinguish which fields need
      ! to be initialized and which are read from restart files
      if (flag_init) then
         initflag=1
         !print*,"in MYNN, initflag=",initflag
      else
         initflag=0
         !print*,"in MYNN, initflag=",initflag
      endif

      !initialize arrays for test
      EMIS_ANT_NO = 0.

      FLAG_OZONE = ntoz>0

  ! Assign variables for each microphysics scheme
        if (imp_physics == imp_physics_wsm6 .or. imp_physics == imp_physics_fa) then
  ! WSM6 or Ferrier-Aligo
         FLAG_QI = .true.
         FLAG_QNI= .false.
         FLAG_QC = .true.
         FLAG_QNC= .false.
         FLAG_QS = .false.
         FLAG_QNWFA= .false.
         FLAG_QNIFA= .false.
         FLAG_QNBCA= .false.
         do k=1,levs
            do i=1,im
              sqv(i,k)   = qgrs_water_vapor(i,k)
              sqc(i,k)   = qgrs_liquid_cloud(i,k)
              sqi(i,k)   = qgrs_ice(i,k)
              sqs(i,k)   = 0.
              ozone(i,k) = qgrs_ozone(i,k)
              qnc(i,k)   = 0.
              qni(i,k)   = 0.
              qnwfa(i,k) = 0.
              qnifa(i,k) = 0.
              qnbca(i,k) = 0.
            enddo
          enddo
        elseif (imp_physics == imp_physics_nssl ) then
  ! NSSL
         FLAG_QI = .true.
         FLAG_QNI= .true.
         FLAG_QC = .true.
         FLAG_QNC= .true.
         FLAG_QS = .false. !.true.
         FLAG_QNWFA= nssl_ccn_on ! ERM: Perhaps could use this field for CCN field?
         FLAG_QNIFA= .false.
         FLAG_QNBCA= .false.
         do k=1,levs
            do i=1,im
              sqv(i,k)   = qgrs_water_vapor(i,k)
              sqc(i,k)   = qgrs_liquid_cloud(i,k)
              sqi(i,k)   = qgrs_ice(i,k)
              sqs(i,k)   = 0.0 !qgrs_snow(i,k)
              ozone(i,k) = qgrs_ozone(i,k)
              qnc(i,k)   = qgrs_cloud_droplet_num_conc(i,k)
              qni(i,k)   = qgrs_cloud_ice_num_conc(i,k)
              qnwfa(i,k) = 0.
              IF ( nssl_ccn_on ) THEN
                qnwfa(i,k) = qgrs_cccn(i,k)
              ENDIF
              qnifa(i,k) = 0.
              qnbca(i,k) = 0.
            enddo
          enddo
        elseif (imp_physics == imp_physics_thompson) then
  ! Thompson
          if(ltaerosol) then
            FLAG_QI = .true.
            FLAG_QNI= .true.
            FLAG_QC = .true.
            FLAG_QS = .true.
            FLAG_QNC= .true.
            FLAG_QNWFA= .true.
            FLAG_QNIFA= .true.
            FLAG_QNBCA= .false.
            do k=1,levs
              do i=1,im
                sqv(i,k)   = qgrs_water_vapor(i,k)
                sqc(i,k)   = qgrs_liquid_cloud(i,k)
                sqi(i,k)   = qgrs_ice(i,k)
                sqs(i,k)   = qgrs_snow(i,k)
                qnc(i,k)   = qgrs_cloud_droplet_num_conc(i,k)
                qni(i,k)   = qgrs_cloud_ice_num_conc(i,k)
                ozone(i,k) = qgrs_ozone(i,k)
                qnwfa(i,k) = qgrs_water_aer_num_conc(i,k)
                qnifa(i,k) = qgrs_ice_aer_num_conc(i,k)
                qnbca(i,k) = 0.
              enddo
            enddo
          else if(mraerosol) then
            FLAG_QI = .true.
            FLAG_QNI= .true.
            FLAG_QC = .true.
            FLAG_QS = .true.
            FLAG_QNC= .true.
            FLAG_QNWFA= .false.
            FLAG_QNIFA= .false.
            FLAG_QNBCA= .false.
            do k=1,levs
              do i=1,im
                sqv(i,k)   = qgrs_water_vapor(i,k)
                sqc(i,k)   = qgrs_liquid_cloud(i,k)
                sqi(i,k)   = qgrs_ice(i,k)
                sqs(i,k)   = qgrs_snow(i,k)
                qnc(i,k)   = qgrs_cloud_droplet_num_conc(i,k)
                qni(i,k)   = qgrs_cloud_ice_num_conc(i,k)
                ozone(i,k) = qgrs_ozone(i,k)
                qnwfa(i,k) = 0.
                qnifa(i,k) = 0.
                qnbca(i,k) = 0.
              enddo
            enddo
          else
            FLAG_QI = .true.
            FLAG_QNI= .true.
            FLAG_QC = .true.
            FLAG_QS = .true.
            FLAG_QNC= .false.
            FLAG_QNWFA= .false.
            FLAG_QNIFA= .false.
            FLAG_QNBCA= .false.
            do k=1,levs
              do i=1,im
                sqv(i,k)   = qgrs_water_vapor(i,k)
                sqc(i,k)   = qgrs_liquid_cloud(i,k)
                sqi(i,k)   = qgrs_ice(i,k)
                sqs(i,k)   = qgrs_snow(i,k)
                qnc(i,k)   = 0.
                qni(i,k)   = qgrs_cloud_ice_num_conc(i,k)
                ozone(i,k) = qgrs_ozone(i,k)
                qnwfa(i,k) = 0.
                qnifa(i,k) = 0.
                qnbca(i,k) = 0.
              enddo
            enddo
          endif
        elseif (imp_physics == imp_physics_gfdl) then
  ! GFDL MP
          FLAG_QI = .true.
          FLAG_QNI= .false.
          FLAG_QC = .true.
          FLAG_QNC= .false.
          FLAG_QS = .false.
          FLAG_QNWFA= .false.
          FLAG_QNIFA= .false.
          FLAG_QNBCA= .false.
          do k=1,levs
            do i=1,im
                sqv(i,k)   = qgrs_water_vapor(i,k)
                sqc(i,k)   = qgrs_liquid_cloud(i,k)
                sqi(i,k)   = qgrs_ice(i,k)
                qnc(i,k)   = 0.
                qni(i,k)   = 0.
                sqs(i,k)   = 0.
                qnwfa(i,k) = 0.
                qnifa(i,k) = 0.
                qnbca(i,k) = 0.
                ozone(i,k) = qgrs_ozone(i,k)
            enddo
          enddo
        else
          print*,"In MYNN wrapper. Unknown microphysics scheme, imp_physics=",imp_physics
          print*,"Defaulting to qc and qv species only..."
          FLAG_QI = .false.
          FLAG_QNI= .false.
          FLAG_QC = .true.
          FLAG_QNC= .false.
          FLAG_QS = .false.
          FLAG_QNWFA= .false.
          FLAG_QNIFA= .false.
          FLAG_QNBCA= .false.
          do k=1,levs
            do i=1,im
                sqv(i,k)   = qgrs_water_vapor(i,k)
                sqc(i,k)   = qgrs_liquid_cloud(i,k)
                sqi(i,k)   = 0.
                sqs(i,k)   = 0.
                qnc(i,k)   = 0.
                qni(i,k)   = 0.
                qnwfa(i,k) = 0.
                qnifa(i,k) = 0.
                qnbca(i,k) = 0.
                ozone(i,k) = qgrs_ozone(i,k)
            enddo
          enddo
        endif
       if(ldiag3d .and. dtidx(100+ntoz,index_of_process_pbl)>1) then
         allocate(old_ozone(im,levs))
         old_ozone = ozone
       endif

       do k=1,levs
          do i=1,im
             th(i,k)=t3d(i,k)/exner(i,k)
             rho(i,k)=prsl(i,k)/(r_d*t3d(i,k)*(1.+p608*max(sqv(i,k),1e-8)))
             w(i,k) = -omega(i,k)/(rho(i,k)*grav)
          enddo
       enddo

  ! Check incoming moist species to ensure non-negative values
  ! First, create height difference (dz)
      do k=1,levs
         do i=1,im
            dz(i,k)=(phii(i,k+1) - phii(i,k))*g_inv
         enddo
      enddo

      do i=1,im
         do k=1,levs
            delp(i,k) = prsi(i,k) - prsi(i,k+1)
         enddo
      enddo

      do i=1,im
         call moisture_check2(levs, delt,            &
                              delp(i,:), exner(i,:), &
                              sqv(i,:),  sqc(i,:),   &
                              sqi(i,:),  sqs(i,:),   &
                              t3d(i,:)               )
      enddo

      !intialize more variables
      do i=1,im
         if (slmsk(i)==1. .or. slmsk(i)==2.) then !sea/land/ice mask (=0/1/2) in FV3
            xland(i)=1.0                          !but land/water = (1/2) in SFCLAY_mynn
         else
            xland(i)=2.0
         endif
         uoce(i)=0.0
         voce(i)=0.0
         !ust(i) = sqrt(stress(i))
         ch(i)=0.0
         hfx(i)=hflx(i)*rho(i,1)*cp
         qfx(i)=qflx(i)*rho(i,1)
         !filter bad incoming fluxes
         if (hfx(i) > 1200.)hfx(i) = 1200.
         if (hfx(i) < -500.)hfx(i) = -500.
         if (qfx(i) > .0005)qfx(i) = 0.0005
         if (qfx(i) < -.0002)qfx(i) = -0.0002

         dtsfc1(i) = hfx(i)
         dqsfc1(i) = qfx(i)*XLV
         dusfc1(i) = -1.*rho(i,1)*ust(i)*ust(i)*u(i,1)/wspd(i)
         dvsfc1(i) = -1.*rho(i,1)*ust(i)*ust(i)*v(i,1)/wspd(i)

         !BWG: diagnostic surface fluxes for scalars & momentum
         dtsfci_diag(i) = dtsfc1(i)
         dqsfci_diag(i) = dqsfc1(i)
         dtsfc_diag(i)  = dtsfc_diag(i) + dtsfc1(i)*delt
         dqsfc_diag(i)  = dqsfc_diag(i) + dqsfc1(i)*delt
         dusfci_diag(i) = dusfc1(i)
         dvsfci_diag(i) = dvsfc1(i)
         dusfc_diag(i)  = dusfc_diag(i) + dusfci_diag(i)*delt
         dvsfc_diag(i)  = dvsfc_diag(i) + dvsfci_diag(i)*delt

         znt(i)=zorl(i)*0.01 !cm -> m?
         if (do_mynnsfclay) then
           rmol(i)=recmol(i)
         else
           if (hfx(i) .ge. 0.)then
             rmol(i)=-hfx(i)/(200.*dz(i,1)*0.5)
           else
             rmol(i)=ABS(rb(i))*1./(dz(i,1)*0.5)
           endif
         endif
         ts(i)=tsurf(i)/exner(i,1)  !theta
!        qsfc(i)=qss(i)
!        ps(i)=pgr(i)
!        wspd(i)=wind(i)
      enddo

      ! BWG: Coupling insertion
      if (cplflx) then
        do i=1,im
          if (oceanfrac(i) > zero) then ! Ocean only, NO LAKES
            if ( .not. wet(i)) then ! no open water, use results from CICE
              dusfci_cpl(i) = dusfc_cice(i)
              dvsfci_cpl(i) = dvsfc_cice(i)
              dtsfci_cpl(i) = dtsfc_cice(i)
              dqsfci_cpl(i) = dqsfc_cice(i)
            elseif (icy(i) .or. dry(i)) then ! use stress_ocean for opw component at mixed point
              if (wspd(i) > zero) then
                dusfci_cpl(i) = -1.*rho(i,1)*stress_wat(i)*u(i,1)/wspd(i)   ! U-momentum flux
                dvsfci_cpl(i) = -1.*rho(i,1)*stress_wat(i)*v(i,1)/wspd(i)   ! V-momentum flux
              else
                dusfci_cpl(i) = zero
                dvsfci_cpl(i) = zero
              endif
              dtsfci_cpl(i) =  cp*rho(i,1)*hflx_wat(i) ! sensible heat flux over open ocean
              dqsfci_cpl(i) = XLV*rho(i,1)*qflx_wat(i) ! latent heat flux over open ocean
            else                                       ! use results from this scheme for 100% open ocean
              dusfci_cpl(i) = dusfci_diag(i)
              dvsfci_cpl(i) = dvsfci_diag(i)
              dtsfci_cpl(i) = dtsfci_diag(i)
              dqsfci_cpl(i) = dqsfci_diag(i)
            endif
!
            dusfc_cpl (i) = dusfc_cpl(i) + dusfci_cpl(i) * delt
            dvsfc_cpl (i) = dvsfc_cpl(i) + dvsfci_cpl(i) * delt
            dtsfc_cpl (i) = dtsfc_cpl(i) + dtsfci_cpl(i) * delt
            dqsfc_cpl (i) = dqsfc_cpl(i) + dqsfci_cpl(i) * delt
          else ! If no ocean
            dusfc_cpl(i) = huge
            dvsfc_cpl(i) = huge
            dtsfc_cpl(i) = huge
            dqsfc_cpl(i) = huge
          endif ! Ocean only, NO LAKES
        enddo
      endif ! End coupling insertion

      if (lprnt) then
         print*
         write(0,*)"===CALLING mynn_bl_driver; input:"
         print*,"tke_budget=",tke_budget," bl_mynn_tkeadvect=",bl_mynn_tkeadvect
         print*,"bl_mynn_cloudpdf=",bl_mynn_cloudpdf," bl_mynn_mixlength=",bl_mynn_mixlength
         print*,"bl_mynn_edmf=",bl_mynn_edmf," bl_mynn_edmf_mom=",bl_mynn_edmf_mom
         print*,"bl_mynn_edmf_tke=",bl_mynn_edmf_tke
         print*,"bl_mynn_cloudmix=",bl_mynn_cloudmix," bl_mynn_mixqt=",bl_mynn_mixqt
         print*,"icloud_bl=",icloud_bl
         print*,"T:",t3d(1,1),t3d(1,2),t3d(1,levs)
         print*,"TH:",th(1,1),th(1,2),th(1,levs)
         print*,"rho:",rho(1,1),rho(1,2),rho(1,levs)
         print*,"exner:",exner(1,1),exner(1,2),exner(1,levs)
         print*,"prsl:",prsl(1,1),prsl(1,2),prsl(1,levs)
         print*,"dz:",dz(1,1),dz(1,2),dz(1,levs)
         print*,"u:",u(1,1),u(1,2),u(1,levs)
         print*,"v:",v(1,1),v(1,2),v(1,levs)
         print*,"sqv:",sqv(1,1),sqv(1,2),sqv(1,levs)
         print*,"sqc:",sqc(1,1),sqc(1,2),sqc(1,levs)
         print*,"sqi:",sqi(1,1),sqi(1,2),sqi(1,levs)
         print*,"rmol:",rmol(1)," ust:",ust(1)
         print*," dx=",dx(1),"initflag=",initflag
         print*,"Tsurf:",tsurf(1)," Thetasurf:",ts(1)
         print*,"HFX:",hfx(1)," qfx",qfx(1)
         print*,"qsfc:",qsfc(1)," ps:",ps(1)
         print*,"wspd:",wspd(1)," rb=",rb(1)
         print*,"znt:",znt(1)," delt=",delt
         print*,"im=",im," levs=",levs
         print*,"PBLH=",pblh(1)," KPBL=",KPBL(1)," xland=",xland(1)
         print*,"ch=",ch(1)
         !print*,"TKE:",TKE_PBL(1,1),TKE_PBL(1,2),TKE_PBL(1,levs)
         print*,"qke:",qke(1,1),qke(1,2),qke(1,levs)
         print*,"el_pbl:",el_pbl(1,1),el_pbl(1,2),el_pbl(1,levs)
         print*,"Sh3d:",Sh3d(1,1),sh3d(1,2),sh3d(1,levs)
         !print*,"exch_h:",exch_h(1,1),exch_h(1,2),exch_h(1,levs) ! - intent(out)
         !print*,"exch_m:",exch_m(1,1),exch_m(1,2),exch_m(1,levs) ! - intent(out)
         print*,"max cf_bl:",maxval(cldfra_bl(1,:))
      endif


              CALL  mynn_bl_driver(                                    &
     &             initflag=initflag,restart=flag_restart,             &
     &             cycling=cycling,                                    &
     &             delt=delt,dz=dz,dx=dx,znt=znt,                      &
     &             u=u,v=v,w=w,th=th,sqv3D=sqv,sqc3D=sqc,              &
     &             sqi3D=sqi,sqs3D=sqs,qnc=qnc,qni=qni,                &
     &             qnwfa=qnwfa,qnifa=qnifa,qnbca=qnbca,ozone=ozone,    &
     &             p=prsl,exner=exner,rho=rho,T3D=t3d,                 &
     &             xland=xland,ts=ts,qsfc=qsfc,ps=ps,                  &
     &             ust=ust,ch=ch,hfx=hfx,qfx=qfx,rmol=rmol,            &
     &             wspd=wspd,uoce=uoce,voce=voce,                      & !input
     &             qke=QKE,qke_adv=qke_adv,                            & !output
     &             sh3d=Sh3d,sm3d=Sm3d,                                &
!chem/smoke
     &             nchem=nchem,kdvel=kdvel,ndvel=ndvel,                &
     &             Chem3d=chem3d,Vdep=vdep,smoke_dbg=smoke_dbg,        &
     &             FRP=frp,EMIS_ANT_NO=emis_ant_no,                    &
     &             mix_chem=mix_chem,enh_mix=enh_mix,                  &
     &             rrfs_sd=rrfs_sd,                                    &
!-----
     &             Tsq=tsq,Qsq=qsq,Cov=cov,                            & !output
     &             RUBLTEN=RUBLTEN,RVBLTEN=RVBLTEN,RTHBLTEN=RTHBLTEN,  & !output
     &             RQVBLTEN=RQVBLTEN,RQCBLTEN=rqcblten,                &
     &             RQIBLTEN=rqiblten,RQNCBLTEN=rqncblten,              & !output
     &             RQSBLTEN=rqsblten,                                  & !output
     &             RQNIBLTEN=rqniblten,RQNWFABLTEN=RQNWFABLTEN,        & !output
     &             RQNIFABLTEN=RQNIFABLTEN,RQNBCABLTEN=RQNBCABLTEN,    & !output
     &             dozone=dqdt_ozone,                                  & !output
     &             EXCH_H=exch_h,EXCH_M=exch_m,                        & !output
     &             pblh=pblh,KPBL=KPBL,                                & !output
     &             el_pbl=el_pbl,                                      & !output
     &             dqke=dqke,                                          & !output
     &             qWT=qWT,qSHEAR=qSHEAR,qBUOY=qBUOY,qDISS=qDISS,      & !output
     &             bl_mynn_tkeadvect=bl_mynn_tkeadvect,                &
     &             tke_budget=tke_budget,                              & !input parameter
     &             bl_mynn_cloudpdf=bl_mynn_cloudpdf,                  & !input parameter
     &             bl_mynn_mixlength=bl_mynn_mixlength,                & !input parameter
     &             icloud_bl=icloud_bl,                                & !input parameter
     &             qc_bl=qc_bl,qi_bl=qi_bl,cldfra_bl=cldfra_bl,        & !output
     &             closure=bl_mynn_closure,bl_mynn_edmf=bl_mynn_edmf,  & !input parameter
     &             bl_mynn_edmf_mom=bl_mynn_edmf_mom,                  & !input parameter
     &             bl_mynn_edmf_tke=bl_mynn_edmf_tke,                  & !input parameter
     &             bl_mynn_mixscalars=bl_mynn_mixscalars,              & !input parameter
     &             bl_mynn_output=bl_mynn_output,                      & !input parameter
     &             bl_mynn_cloudmix=bl_mynn_cloudmix,                  & !input parameter
     &             bl_mynn_mixqt=bl_mynn_mixqt,                        & !input parameter
     &             edmf_a=edmf_a,edmf_w=edmf_w,edmf_qt=edmf_qt,        & !output
     &             edmf_thl=edmf_thl,edmf_ent=edmf_ent,edmf_qc=edmf_qc,& !output
     &             sub_thl3D=sub_thl,sub_sqv3D=sub_sqv,                &
     &             det_thl3D=det_thl,det_sqv3D=det_sqv,                &
     &             nupdraft=nupdraft,maxMF=maxMF,                      & !output
     &             ktop_plume=ktop_plume,                              & !output
     &             spp_pbl=spp_pbl,pattern_spp_pbl=spp_wts_pbl,        & !input
     &             RTHRATEN=htrlw,                                     & !input
     &             FLAG_QI=flag_qi,FLAG_QNI=flag_qni,                  & !input
     &             FLAG_QC=flag_qc,FLAG_QNC=flag_qnc,FLAG_QS=flag_qs,  & !input
     &             FLAG_QNWFA=FLAG_QNWFA,FLAG_QNIFA=FLAG_QNIFA,        & !input
     &             FLAG_QNBCA=FLAG_QNBCA,FLAG_OZONE=FLAG_OZONE,        & !input
     &             IDS=1,IDE=im,JDS=1,JDE=1,KDS=1,KDE=levs,            & !input
     &             IMS=1,IME=im,JMS=1,JME=1,KMS=1,KME=levs,            & !input
     &             ITS=1,ITE=im,JTS=1,JTE=1,KTS=1,KTE=levs             ) !input


     ! POST MYNN (INTERSTITIAL) WORK:
        !update/save MYNN-only variables
        !do k=1,levs
        !   do i=1,im
        !      gq0(i,k,4)=qke(i,k,1)      !tke*2
        !   enddo
        !enddo
        !For MYNN, convert TH-tend to T-tend
        do k = 1, levs
           do i = 1, im
              dtdt(i,k) = dtdt(i,k) + RTHBLTEN(i,k)*exner(i,k)
              dudt(i,k) = dudt(i,k) + RUBLTEN(i,k)
              dvdt(i,k) = dvdt(i,k) + RVBLTEN(i,k)
           enddo
        enddo
        accum_duvt3dt: if(ldiag3d .or. lsidea) then
          call dtend_helper(index_of_x_wind,RUBLTEN)
          call dtend_helper(index_of_y_wind,RVBLTEN)
          call dtend_helper(index_of_temperature,RTHBLTEN,exner)
          if(ldiag3d) then
            call dtend_helper(100+ntoz,dqdt_ozone)
            ! idtend = dtidx(100+ntoz,index_of_process_pbl)
            ! if(idtend>=1) then
            !   dtend(:,:,idtend) = dtend(:,:,idtend) + (ozone-old_ozone)
            !   deallocate(old_ozone)
            ! endif
          endif
        endif accum_duvt3dt
        !Update T, U and V:
        !do k = 1, levs
        !   do i = 1, im
        !      T3D(i,k) = T3D(i,k) + RTHBLTEN(i,k)*exner(i,k)*delt
        !      u(i,k)   = u(i,k) + RUBLTEN(i,k)*delt
        !      v(i,k)   = v(i,k) + RVBLTEN(i,k)*delt
        !   enddo
        !enddo

        !DO moist/scalar/tracer tendencies:
        if (imp_physics == imp_physics_wsm6 .or. imp_physics == imp_physics_fa) then
           ! WSM6
           do k=1,levs
             do i=1,im
               dqdt_water_vapor(i,k)  = RQVBLTEN(i,k) !/(1.0 + qv(i,k))
               dqdt_liquid_cloud(i,k) = RQCBLTEN(i,k) !/(1.0 + qv(i,k))
               dqdt_ice(i,k)          = RQIBLTEN(i,k) !/(1.0 + qv(i,k))
               dqdt_snow(i,k)         = RQSBLTEN(i,k) !/(1.0 + qv(i,k))
               !dqdt_ozone(i,k)        = 0.0
             enddo
           enddo
           if(ldiag3d .and. .not. flag_for_pbl_generic_tend) then
             call dtend_helper(100+ntqv,RQVBLTEN)
             call dtend_helper(100+ntcw,RQCBLTEN)
             call dtend_helper(100+ntiw,RQIBLTEN)
           endif
           !Update moist species:
           !do k=1,levs
           !  do i=1,im
           !    qgrs_water_vapor(i,k)  = qgrs_water_vapor(i,k)  + (RQVBLTEN(i,k)/(1.0+RQVBLTEN(i,k)))*delt
           !    qgrs_liquid_cloud(i,k) = qgrs_liquid_cloud(i,k) + RQCBLTEN(i,k)*delt
           !    qgrs_ice(i,k)          = qgrs_ice(i,k)          + RQIBLTEN(i,k)*delt
           !    !dqdt_ozone(i,k)        = 0.0
           !  enddo
           !enddo
        elseif (imp_physics == imp_physics_thompson) then
           ! Thompson-Aerosol
           if(ltaerosol) then
             do k=1,levs
               do i=1,im
                 dqdt_water_vapor(i,k)             = RQVBLTEN(i,k) !/(1.0 + qv(i,k))
                 dqdt_liquid_cloud(i,k)            = RQCBLTEN(i,k) !/(1.0 + qv(i,k))
                 dqdt_cloud_droplet_num_conc(i,k)  = RQNCBLTEN(i,k)
                 dqdt_ice(i,k)                     = RQIBLTEN(i,k) !/(1.0 + qv(i,k))
                 dqdt_ice_num_conc(i,k)            = RQNIBLTEN(i,k)
                 dqdt_snow(i,k)                    = RQSBLTEN(i,k) !/(1.0 + qv(i,k))
                 !dqdt_ozone(i,k)                   = 0.0
                 dqdt_water_aer_num_conc(i,k)      = RQNWFABLTEN(i,k)
                 dqdt_ice_aer_num_conc(i,k)        = RQNIFABLTEN(i,k)
               enddo
             enddo
             if(ldiag3d .and. .not. flag_for_pbl_generic_tend) then
               call dtend_helper(100+ntqv,RQVBLTEN)
               call dtend_helper(100+ntcw,RQCBLTEN)
               call dtend_helper(100+ntlnc,RQNCBLTEN)
               call dtend_helper(100+ntiw,RQIBLTEN)
               call dtend_helper(100+ntinc,RQNIBLTEN)
               call dtend_helper(100+ntwa,RQNWFABLTEN)
               call dtend_helper(100+ntia,RQNIFABLTEN)
             endif
             !do k=1,levs
             !  do i=1,im
             !    qgrs_water_vapor(i,k)            = qgrs_water_vapor(i,k)    + (RQVBLTEN(i,k)/(1.0+RQVBLTEN(i,k)))*delt
             !    qgrs_liquid_cloud(i,k)           = qgrs_liquid_cloud(i,k)   + RQCBLTEN(i,k)*delt
             !    qgrs_ice(i,k)                    = qgrs_ice(i,k)            + RQIBLTEN(i,k)*delt
             !    qgrs_cloud_droplet_num_conc(i,k) = qgrs_cloud_droplet_num_conc(i,k) + RQNCBLTEN(i,k)*delt
             !    qgrs_cloud_ice_num_conc(i,k)     = qgrs_cloud_ice_num_conc(i,k)     + RQNIBLTEN(i,k)*delt
             !    !dqdt_ozone(i,k)        = 0.0
             !    !qgrs_water_aer_num_conc(i,k)     = qgrs_water_aer_num_conc(i,k)     + RQNWFABLTEN(i,k)*delt
             !    !qgrs_ice_aer_num_conc(i,k)       = qgrs_ice_aer_num_conc(i,k)       + RQNIFABLTEN(i,k)*delt
             !  enddo
             !enddo
           else if(mraerosol) then
             do k=1,levs
               do i=1,im
                 dqdt_water_vapor(i,k)             = RQVBLTEN(i,k) !/(1.0 + qv(i,k))
                 dqdt_liquid_cloud(i,k)            = RQCBLTEN(i,k) !/(1.0 + qv(i,k))
                 dqdt_cloud_droplet_num_conc(i,k)  = RQNCBLTEN(i,k)
                 dqdt_ice(i,k)                     = RQIBLTEN(i,k) !/(1.0 + qv(i,k))
                 dqdt_ice_num_conc(i,k)            = RQNIBLTEN(i,k)
                 dqdt_snow(i,k)                    = RQSBLTEN(i,k) !/(1.0 + qv(i,k))
               enddo
             enddo
             if(ldiag3d .and. .not. flag_for_pbl_generic_tend) then
               call dtend_helper(100+ntqv,RQVBLTEN)
               call dtend_helper(100+ntcw,RQCBLTEN)
               call dtend_helper(100+ntlnc,RQNCBLTEN)
               call dtend_helper(100+ntiw,RQIBLTEN)
               call dtend_helper(100+ntinc,RQNIBLTEN)
             endif
           else
             !Thompson (2008)
             do k=1,levs
               do i=1,im
                 dqdt_water_vapor(i,k)   = RQVBLTEN(i,k) !/(1.0 + qv(i,k))
                 dqdt_liquid_cloud(i,k)  = RQCBLTEN(i,k) !/(1.0 + qv(i,k))
                 dqdt_ice(i,k)           = RQIBLTEN(i,k) !/(1.0 + qv(i,k))
                 dqdt_ice_num_conc(i,k)  = RQNIBLTEN(i,k)
                 dqdt_snow(i,k)          = RQSBLTEN(i,k) !/(1.0 + qv(i,k))
                 !dqdt_ozone(i,k)         = 0.0
               enddo
             enddo
             if(ldiag3d .and. .not. flag_for_pbl_generic_tend) then
               call dtend_helper(100+ntqv,RQVBLTEN)
               call dtend_helper(100+ntcw,RQCBLTEN)
               call dtend_helper(100+ntiw,RQIBLTEN)
               call dtend_helper(100+ntinc,RQNIBLTEN)
               call dtend_helper(100+ntsw,RQSBLTEN)
             endif
             !do k=1,levs
             !  do i=1,im
             !    qgrs_water_vapor(i,k)            = qgrs_water_vapor(i,k)    + (RQVBLTEN(i,k)/(1.0+RQVBLTEN(i,k)))*delt
             !    qgrs_liquid_cloud(i,k)           = qgrs_liquid_cloud(i,k)   + RQCBLTEN(i,k)*delt
             !    qgrs_ice(i,k)                    = qgrs_ice(i,k)            + RQIBLTEN(i,k)*delt
             !    qgrs_cloud_ice_num_conc(i,k)     = qgrs_cloud_ice_num_conc(i,k)     + RQNIBLTEN(i,k)*delt
             !    !dqdt_ozone(i,k)        = 0.0
             !  enddo
             !enddo
           endif !end thompson choice
        elseif (imp_physics == imp_physics_nssl) then
           ! NSSL
             do k=1,levs
               do i=1,im
                 dqdt_water_vapor(i,k)             = RQVBLTEN(i,k) !/(1.0 + qv(i,k))
                 dqdt_liquid_cloud(i,k)            = RQCBLTEN(i,k) !/(1.0 + qv(i,k))
                 dqdt_cloud_droplet_num_conc(i,k)  = RQNCBLTEN(i,k)
                 dqdt_ice(i,k)                     = RQIBLTEN(i,k) !/(1.0 + qv(i,k))
                 dqdt_ice_num_conc(i,k)            = RQNIBLTEN(i,k)
                 !dqdt_snow(i,k)                    = RQSBLTEN(i,k) !/(1.0 + qv(i,k))
                 IF ( nssl_ccn_on ) THEN ! 
                   dqdt_cccn(i,k)      = RQNWFABLTEN(i,k)
                 ENDIF
               enddo
             enddo

        elseif (imp_physics == imp_physics_gfdl) then
           ! GFDL MP
           do k=1,levs
             do i=1,im
               dqdt_water_vapor(i,k)   = RQVBLTEN(i,k) !/(1.0 + qv(i,k))
               dqdt_liquid_cloud(i,k)  = RQCBLTEN(i,k) !/(1.0 + qv(i,k))
               dqdt_ice(i,k)           = RQIBLTEN(i,k) !/(1.0 + qv(i,k))
               !dqdt_rain(i,k)          = 0.0
               !dqdt_snow(i,k)          = 0.0
               !dqdt_graupel(i,k)       = 0.0
               !dqdt_ozone(i,k)         = 0.0
             enddo
           enddo
           if(ldiag3d .and. .not. flag_for_pbl_generic_tend) then
             call dtend_helper(100+ntqv,RQVBLTEN)
             call dtend_helper(100+ntcw,RQCBLTEN)
             call dtend_helper(100+ntiw,RQIBLTEN)
           endif
           !do k=1,levs
           !  do i=1,im
           !    qgrs_water_vapor(i,k)            = qgrs_water_vapor(i,k)    + (RQVBLTEN(i,k)/(1.0+RQVBLTEN(i,k)))*delt
           !    qgrs_liquid_cloud(i,k)           = qgrs_liquid_cloud(i,k)   + RQCBLTEN(i,k)*delt
           !    qgrs_ice(i,k)                    = qgrs_ice(i,k)            + RQIBLTEN(i,k)*delt
           !    !dqdt_ozone(i,k)        = 0.0
           !  enddo
           !enddo
       else
!          print*,"In MYNN wrapper. Unknown microphysics scheme, imp_physics=",imp_physics
           do k=1,levs
             do i=1,im
               dqdt_water_vapor(i,k)   = RQVBLTEN(i,k) !/(1.0 + qv(i,k))
               dqdt_liquid_cloud(i,k)  = RQCBLTEN(i,k) !/(1.0 + qv(i,k))
               dqdt_ice(i,k)           = 0.0
               !dqdt_rain(i,k)          = 0.0
               !dqdt_snow(i,k)          = 0.0
               !dqdt_graupel(i,k)       = 0.0
               !dqdt_ozone(i,k)         = 0.0
             enddo
           enddo
           if(ldiag3d .and. .not. flag_for_pbl_generic_tend) then
             call dtend_helper(100+ntqv,RQVBLTEN)
             call dtend_helper(100+ntcw,RQCBLTEN)
             call dtend_helper(100+ntiw,RQIBLTEN)
           endif
       endif
       
       if (lprnt) then
          print*
          print*,"===Finished with mynn_bl_driver; output:"
          print*,"T:",t3d(1,1),t3d(1,2),t3d(1,levs)
          print*,"TH:",th(1,1),th(1,2),th(1,levs)
          print*,"rho:",rho(1,1),rho(1,2),rho(1,levs)
          print*,"exner:",exner(1,1),exner(1,2),exner(1,levs)
          print*,"prsl:",prsl(1,1),prsl(1,2),prsl(1,levs)
          print*,"dz:",dz(1,1),dz(1,2),dz(1,levs)
          print*,"u:",u(1,1),u(1,2),u(1,levs)
          print*,"v:",v(1,1),v(1,2),v(1,levs)
          print*,"sqv:",sqv(1,1),sqv(1,2),sqv(1,levs)
          print*,"sqc:",sqc(1,1),sqc(1,2),sqc(1,levs)
          print*,"sqi:",sqi(1,1),sqi(1,2),sqi(1,levs)
          print*,"rmol:",rmol(1)," ust:",ust(1)
          print*,"dx(1)=",dx(1),"initflag=",initflag
          print*,"Tsurf:",tsurf(1)," Thetasurf:",ts(1)
          print*,"HFX:",hfx(1)," qfx",qfx(1)
          print*,"qsfc:",qsfc(1)," ps:",ps(1)
          print*,"wspd:",wspd(1)," rb=",rb(1)
          print*,"znt:",znt(1)," delt=",delt
          print*,"im=",im," levs=",levs
          print*,"PBLH=",pblh(1)," KPBL=",KPBL(1)," xland=",xland(1)
          print*,"ch=",ch(1)
          print*,"qke:",qke(1,1),qke(1,2),qke(1,levs)
          print*,"el_pbl:",el_pbl(1,1),el_pbl(1,2),el_pbl(1,levs)
          print*,"Sh3d:",Sh3d(1,1),sh3d(1,2),sh3d(1,levs)
          print*,"exch_h:",exch_h(1,1),exch_h(1,2),exch_h(1,levs)
          print*,"exch_m:",exch_m(1,1),exch_m(1,2),exch_m(1,levs)
          print*,"max cf_bl:",maxval(cldfra_bl(1,:))
          print*,"max qc_bl:",maxval(qc_bl(1,:))
          print*,"dtdt:",dtdt(1,1),dtdt(1,2),dtdt(1,levs)
          print*,"dudt:",dudt(1,1),dudt(1,2),dudt(1,levs)
          print*,"dvdt:",dvdt(1,1),dvdt(1,2),dvdt(1,levs)
          print*,"dqdt:",dqdt_water_vapor(1,1),dqdt_water_vapor(1,2),dqdt_water_vapor(1,levs)
          print*,"ktop_plume:",ktop_plume(1)," maxmf:",maxmf(1)
          print*,"nup:",nupdraft(1)
          print*
       endif

       if(allocated(save_qke_adv)) then
         if(ldiag3d .and. .not. flag_for_pbl_generic_tend) then
           idtend = dtidx(100+ntke,index_of_process_pbl)
           if(idtend>=1) then
             dtend(:,:,idtend) = dtend(:,:,idtend) + qke_adv-save_qke_adv
           endif
         endif
         deallocate(save_qke_adv)
       endif

  CONTAINS

    SUBROUTINE dtend_helper(itracer,field,mult)
      real(kind_phys), intent(in) :: field(im,levs)
      real(kind_phys), intent(in), optional :: mult(im,levs)
      integer, intent(in) :: itracer
      integer :: idtend
      
      idtend=dtidx(itracer,index_of_process_pbl)
      if(idtend>=1) then
        if(present(mult)) then
          dtend(:,:,idtend) = dtend(:,:,idtend) + field*dtf*mult
        else
          dtend(:,:,idtend) = dtend(:,:,idtend) + field*dtf
        endif
      endif
    END SUBROUTINE dtend_helper

! ==================================================================
  SUBROUTINE moisture_check2(kte, delt, dp, exner, &
                             qv, qc, qi, qs, th    )
  !
  ! If qc < qcmin, qi < qimin, or qv < qvmin happens in any layer,
  ! force them to be larger than minimum value by (1) condensating 
  ! water vapor into liquid or ice, and (2) by transporting water vapor 
  ! from the very lower layer.
  ! 
  ! We then update the final state variables and tendencies associated
  ! with this correction. If any condensation happens, update theta/temperature too.
  ! Note that (qv,qc,qi,th) are the final state variables after
  ! applying corresponding input tendencies and corrective tendencies.

    implicit none
    integer,  intent(in)     :: kte
    real(kind_phys), intent(in)     :: delt
    real(kind_phys), dimension(kte), intent(in)     :: dp, exner
    real(kind_phys), dimension(kte), intent(inout)  :: qv, qc, qi, qs, th
    integer   k
    real ::  dqc2, dqi2, dqs2, dqv2, sum, aa, dum
    real, parameter :: qvmin1= 1e-8,    & !min at k=1
                       qvmin = 1e-20,   & !min above k=1
                       qcmin = 0.0,     &
                       qimin = 0.0

    do k = kte, 1, -1  ! From the top to the surface
       dqc2 = max(0.0, qcmin-qc(k)) !qc deficit (>=0)
       dqi2 = max(0.0, qimin-qi(k)) !qi deficit (>=0)
       dqs2 = max(0.0, qimin-qs(k)) !qs deficit (>=0)

       !update species
       qc(k)  = qc(k)  +  dqc2
       qi(k)  = qi(k)  +  dqi2
       qs(k)  = qs(k)  +  dqs2
       qv(k)  = qv(k)  -  dqc2 - dqi2 - dqs2
       !for theta
       !th(k)  = th(k)  +  xlvcp/exner(k)*dqc2 + &
       !                   xlscp/exner(k)*dqi2
       !for temperature
       th(k)  = th(k)  +  xlvcp*dqc2 + &
                          xlscp*(dqi2+dqs2)

       !then fix qv if lending qv made it negative
       if (k .eq. 1) then
          dqv2   = max(0.0, qvmin1-qv(k)) !qv deficit (>=0)
          qv(k)  = qv(k)  + dqv2
          qv(k)  = max(qv(k),qvmin1)
          dqv2   = 0.0
       else
          dqv2   = max(0.0, qvmin-qv(k)) !qv deficit (>=0)
          qv(k)  = qv(k)  + dqv2
          qv(k-1)= qv(k-1)  - dqv2*dp(k)/dp(k-1)
          qv(k)  = max(qv(k),qvmin)
       endif
       qc(k) = max(qc(k),qcmin)
       qi(k) = max(qi(k),qimin)
       qs(k) = max(qs(k),qimin)
    end do

    ! Extra moisture used to satisfy 'qv(1)>=qvmin' is proportionally
    ! extracted from all the layers that has 'qv > 2*qvmin'. This fully
    ! preserves column moisture.
    if( dqv2 .gt. 1.e-20 ) then
        sum = 0.0
        do k = 1, kte
           if( qv(k) .gt. 2.0*qvmin ) sum = sum + qv(k)*dp(k)
        enddo
        aa = dqv2*dp(1)/max(1.e-20,sum)
        if( aa .lt. 0.5 ) then
            do k = 1, kte
               if( qv(k) .gt. 2.0*qvmin ) then
                   dum    = aa*qv(k)
                   qv(k)  = qv(k) - dum
               endif
            enddo
        else
        ! For testing purposes only (not yet found in any output):
        !    write(*,*) 'Full moisture conservation is impossible'
        endif
    endif

    return

  END SUBROUTINE moisture_check2

  END SUBROUTINE mynnedmf_wrapper_run

!###=================================================================

END MODULE mynnedmf_wrapper