#include "rundeck_opts.h"

c******************   TRACERS             ******************************
#ifdef TRACERS_ON

      module ghy_tracers 4,48

      use sle001, only :
#ifdef TRACERS_WATER
     &    tr_w,tr_wsn,trpr,trdd,tr_surf,ntg,ntgm,atr_evap,atr_rnff,atr_g
#endif
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM) || (defined TRACERS_AMP)
      use sle001,ONLY : aevap
#endif
      use tracer_com, only : ntm,itime_tr0,needtrs,trm,trmom,ntsurfsrc
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM) || (defined TRACERS_AMP)
     &     ,Ntm_dust
#endif
#ifdef TRACERS_DRYDEP
     &     ,dodrydep
#endif
#ifdef TRACERS_WATER
     *     ,nWATER,nGAS,nPART,tr_wd_TYPE
#endif
#if (defined TRACERS_WATER) || (defined TRACERS_AEROSOLS_Koch) ||\
    (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM) || (defined TRACERS_AMP)
     &     ,trname
#endif
#ifdef TRACERS_DUST
     &     ,n_clay,imDust
#else
#ifdef TRACERS_MINERALS
     &     ,n_clayilli
#else
#ifdef TRACERS_QUARZHEM
     &     ,n_sil1quhe
#endif
#endif
#endif
      use trdiag_com, only : taijn=>taijn_loc,tij_surf, tij_surfbv,
     *   taijs=>taijs_loc,ijts_isrc,jls_isrc,tajls=>tajls_loc,
     *   itcon_surf
#ifdef TRACERS_WATER
     *     ,tij_evap,tij_grnd,tij_soil,tij_snow
#endif
#ifdef TRACERS_DRYDEP
     *     ,tij_drydep,tij_gsdep,itcon_dd,dtr_dd
#endif
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
     &     ,nDustEmij,nDustEmjl
     &     ,ijts_spec,nDustEv1ij,nDustEv2ij,nDustWthij
     &     ,jls_spec,nDustEv1jl,nDustEv2jl,nDustWthjl
#endif
#ifdef TRACERS_DUST
     &     ,nDustEm2ij,nDustEm2jl
#endif
      use fluxes, only : trsource,trsrfflx
#ifdef TRACERS_WATER
     *     ,trevapor,trunoe,gtracer,trprec
#endif
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM) || (defined TRACERS_AMP)
     &     ,prec,pprec,pevap,dust_flux_glob,trs_glob
#ifdef TRACERS_DRYDEP
     &     ,depo_turb_glob,depo_grav_glob
#endif
#endif
#ifdef TRACERS_DUST
     &     ,dust_flux2_glob
#endif
#ifdef TRACERS_DRYDEP
     *     ,trdrydep
#endif

#ifdef TRACERS_WATER
      use ghy_com, only : tr_w_ij,tr_wsn_ij, ntixw
#endif

ccc extra stuff which was present in "earth" by default
#ifdef TRACERS_WATER
      use ghy_com, only : ngm,nlsn
      use constant, only : rhow
#endif
      use dynamics, only : byam
      use geom, only : bydxyp

      implicit none
      private

      public ghy_tracers_set_step
      public ghy_tracers_set_cell
      public ghy_tracers_save_cell

      real*8 totflux(ntm)
      integer ntx,ntix(ntm)
      integer, parameter :: itype=4

      common /ghy_tracers_tp/ totflux
!$OMP  THREADPRIVATE (/ghy_tracers_tp/)

      contains



      subroutine ghy_tracers_set_step 2,4
!@sum tracers stuff to be called at the beginning of ghy time step
!@+   i.e. before the i,j loop
ccc set i,j - independent stuff for tracers
      use model_com, only : itime
      implicit none
      integer n

      ntx=0
#ifdef TRACERS_WATER
      ntg=0
#endif
      do n=1,ntm
        if (itime_tr0(n).le.itime .and. needtrs(n)) then
          ntx=ntx+1
          ntix(ntx) = n
#ifdef TRACERS_WATER
          if ( tr_wd_TYPE(n)==nWATER .or. tr_wd_TYPE(n)==nPART ) then
            ntg = ntg + 1
            if ( ntg > ntgm ) then
               print *,"ntgm too small. maybe set it to ntm=",ntm
               call stop_model("ghy_drv: ntg > ntgm",255)
            endif
            ntixw(ntg) = n
          endif
#endif
        end if
      end do

      end subroutine ghy_tracers_set_step



      subroutine ghy_tracers_set_cell(i,j,ptype,qg,evap_max,pbl_args) 2,16
!@sum tracers code to be called before the i,j cell is processed
      use model_com, only : dtsrc
      use pbl_drv, only : t_pbl_args
      
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM) || (defined TRACERS_AMP)
      USE constant,ONLY : sday
      USE model_com,ONLY : jday,jmon,wfcs
      USE geom,ONLY : dxyp
      USE ghy_com,ONLY : snowe,wearth,aiearth
      USE tracers_dust,ONLY : d_dust,ers_data,hbaij,ricntd,src_fnct
     &     ,frclay,frsilt,dryhr,vtrsh
#if (defined TRACERS_MINERALS) || (defined TRACERS_QUARZHEM)
     &     ,minfr
#endif
#endif
#ifdef TRACERS_WATER
      use sle001, only : qm1
#endif
      implicit none
      integer, intent(in) :: i,j
      real*8, intent(in) :: qg,evap_max,ptype
      type (t_pbl_args), intent(inout) :: pbl_args
      integer n,nx,nsrc

c**** pass indices of tracer arrays to PBL
      pbl_args%ntix(:) = ntix(:)
      pbl_args%ntx = ntx
C**** Set up tracers for PBL calculation if required
      do nx=1,ntx
        n = ntix(nx)
C**** Calculate first layer tracer concentration
        pbl_args%trtop(nx)=trm(i,j,1,n)*byam(1,i,j)*bydxyp(j)
      end do

ccc tracers variables
#ifdef TRACERS_WATER
      do nx=1,ntg
        n = ntixw(nx)
        ! prognostic vars
        tr_w(nx,0,1) = 0.d0
        tr_w(nx,1:ngm,1) = tr_w_ij(n,1:ngm,1,i,j)
        tr_w(nx,0:ngm,2) = tr_w_ij(n,0:ngm,2,i,j)
        tr_wsn(nx,1:nlsn,1:2) = tr_wsn_ij(n,1:nlsn, 1:2, i, j)
        ! flux in
        trpr(nx) = (trprec(n,i,j)*bydxyp(j))/dtsrc ! kg/m^2 s (in precip)
#ifdef TRACERS_DRYDEP
        trdd(nx) = trdrydep(n,itype,i,j)/dtsrc   ! kg/m^2 s (dry dep.)
#else
        trdd(nx) = 0
#endif
        ! concentration of tracers in atm. water at the surface
        if (qm1.gt.0 .and. tr_wd_TYPE(n)==nWATER) then
          tr_surf(nx) = trm(i,j,1,n)*bydxyp(j)*rhow/qm1 ! kg/m^3
        else
          tr_surf(nx) = 0.
        end if
      enddo
#endif

      do nx=1,ntx
        n=ntix(nx)
C**** set defaults
        pbl_args%trsfac(nx)=0.
        totflux(nx)=0.
        pbl_args%trconstflx(nx)=0.
#ifdef TRACERS_WATER
C**** Set surface boundary conditions for tracers depending on whether
C**** they are water or another type of tracer
C**** The select is used to distinguish water from gases or particle
! select removed because of OMP compiler bug
!        select case (tr_wd_TYPE(n))
!        case (nWATER)
        if (tr_wd_TYPE(n) .eq. nWATER) then
C**** no fractionation from ground (yet)
C**** trsfac and trconstflx are multiplied by cq*ws and QG in PBL
          pbl_args%trsfac(nx)=1.
          pbl_args%trconstflx(nx)=gtracer(n,itype,i,j)
!        case (nGAS, nPART)
        elseif (tr_wd_TYPE(n).eq.nGAS .or. tr_wd_TYPE(n).eq.nPART) then
#endif
C**** For non-water tracers (i.e. if TRACERS_WATER is not set, or there
C**** is a non-soluble tracer mixed in.)
C**** Calculate trsfac (set to zero for const flux)
#ifdef TRACERS_DRYDEP
          if(dodrydep(n)) pbl_args%trsfac(nx) = 1.
          !then multiplied by deposition velocity in PBL
#endif
C**** Calculate trconstflx (m/s * conc) (could be dependent on itype)
          do nsrc=1,ntsurfsrc(n)
            totflux(nx) = totflux(nx)+trsource(i,j,nsrc,n)
          end do
          pbl_args%trconstflx(nx)=totflux(nx)*bydxyp(j)   ! kg/m^2/s
#ifdef TRACERS_WATER
!        end select
        end if
#endif
      end do

#ifdef TRACERS_WATER
c**** water tracers are also flux limited
      do nx=1,ntx
        n=ntix(nx)
C       pbl_args%tr_evap_max(nx) = evap_max * trsoil_rat(nx)
        pbl_args%tr_evap_max(nx) = evap_max * gtracer(n,itype,i,j)
#ifdef TRACERS_DRYDEP
        if(dodrydep(n)) pbl_args%tr_evap_max(nx) = 1.d30
#endif
      end do
#endif

#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM) || (defined TRACERS_AMP)
      pbl_args%snowe=snowe(i,j)
      pbl_args%wearth=wearth(i,j)
      pbl_args%aiearth=aiearth(i,j)
      pbl_args%wfcs=wfcs(i,j)
      pbl_args%ers_data=ers_data(i,j,jmon)
      pbl_args%src_fnct=src_fnct(i,j)
      pbl_args%frclay=frclay(i,j)
      pbl_args%frsilt=frsilt(i,j)
      pbl_args%vtrsh=vtrsh(i,j)
      pbl_args%dryhr=dryhr(i,j)
      pbl_args%hbaij=hbaij(i,j)
      pbl_args%ricntd=ricntd(i,j)
      pbl_args%pprec=pprec(i,j)
      pbl_args%pevap=pevap(i,j,itype)
c**** prescribed dust emission
      pbl_args%d_dust(1:Ntm_dust)=d_dust(i,j,1:Ntm_dust,jday)/Sday
     &     /dxyp(j)/ptype
#endif
#if (defined TRACERS_MINERALS) || (defined TRACERS_QUARZHEM)
      pbl_args%minfr(:)=minfr(i,j,:)
#endif

      end subroutine ghy_tracers_set_cell



      subroutine ghy_tracers_save_cell(i,j,ptype,dtsurf,rhosrf,pbl_args 2,28
#ifdef INTERACTIVE_WETLANDS_CH4
     & ,ra_temp,ra_sat,ra_gwet
#endif
     & )
!@sum tracers code to be called after the i,j cell is processed
      use model_com, only : itime,qcheck,nisurf
      use pbl_drv, only : t_pbl_args
      use ghy_com, only : tearth
      use somtq_com, only : mz
#ifdef TRACERS_COSMO
      USE COSMO_SOURCES, only : BE7D_acc
#endif
      USE TRACER_COM
 !     use socpbl, only : dtsurf
      use geom, only : dxyp
      use sle001, only : nsn,fb,fv
#if (defined TRACERS_DUST) && (defined TRACERS_DRYDEP)
      USE trdiag_com,ONLY : rts_save
#endif
#ifdef INTERACTIVE_WETLANDS_CH4
      use constant, only : tf
      use tracer_sources, only : n__temp,n__sat,n__gwet
#endif
#ifdef TRACERS_AMP
      USE AMP_AEROSOL, only: DTR_AMPe
#endif
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM) || (defined TRACERS_AMP)
      USE tracers_dust,ONLY : hbaij,ricntd
#endif
      implicit none
      integer, intent(in) :: i,j
      real*8, intent(in) :: ptype,dtsurf,rhosrf
      type (t_pbl_args), intent(in) :: pbl_args
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM) || (defined TRACERS_AMP)
      integer :: n1
#endif
      integer n,nx
#ifdef TRACERS_DRYDEP
      real*8 tdryd,tdd,td1,rtsdt,rts
#endif
#if (defined TRACERS_AEROSOLS_Koch) || (defined TRACERS_AMP)
      real*8 trc_flux
#endif
#ifdef INTERACTIVE_WETLANDS_CH4
      real*8, intent(IN) :: ra_temp,ra_sat,ra_gwet
#endif

ccc tracers
#ifdef TRACERS_WATER
      do nx=1,ntg
        n = ntixw(nx)
        tr_w_ij(n,1:ngm,1,i,j) = tr_w(nx,1:ngm,1)
        tr_w_ij(n,0:ngm,2,i,j) = tr_w(nx,0:ngm,2)
        tr_wsn_ij(n,1:nlsn, 1:2, i, j) = tr_wsn(nx,1:nlsn,1:2)
      enddo
#endif
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM) || (defined TRACERS_AMP)
      hbaij(i,j)=pbl_args%hbaij
      ricntd(i,j)=pbl_args%ricntd
c     saves precipitation for dust emission calculation at next time step
      pprec(i,j)=prec(i,j)
c     saves evaporation for dust emission calculation at next time step
      pevap(i,j,itype)=aevap
#endif
#ifdef TRACERS_WATER
ccc accumulate tracer evaporation and runoff
      do nx=1,ntg
        n=ntixw(nx)
        trevapor(n,itype,i,j) = trevapor(n,itype,i,j) + atr_evap(nx)
        !trevapor(n,itype,i,j) = trevapor(n,itype,i,j) + aevap  !*rhow
        trunoe(n,i,j) = trunoe(n,i,j) + atr_rnff(nx)
        !trunoe(n,i,j) = trunoe(n,i,j) + (aruns+arunu)  !*rhow
        gtracer(n,itype,i,j) = atr_g(nx)   ! /dtsurf
        trsrfflx(i,j,n)=trsrfflx(i,j,n)+
     &       atr_evap(nx)/dtsurf *dxyp(j)*ptype
      enddo
#endif
      DO nx=1,ntx
        n=ntix(nx)

#if (defined TRACERS_AEROSOLS_Koch) || (defined TRACERS_AMP)
C**** technicallly some of these are ocean emissions, but if 
C**** fixed datasets are used, it can happen over land as well.

        select case (trname(n))
        case ('DMS')
          trc_flux=pbl_args%DMS_flux
        case ('seasalt1', 'M_SSA_SS')
          trc_flux=pbl_args%ss1_flux
        case ('seasalt2', 'M_SSC_SS')
          trc_flux=pbl_args%ss2_flux
        case ('M_SSS_SS')
          trc_flux=(pbl_args%ss1_flux+pbl_args%ss2_flux)
#ifdef TRACERS_AMP
        case ('M_DD1_DU')
          trc_flux=sum(pbl_args%dust_flux(1:2))
        case ('M_DD2_DU')
          trc_flux=sum(pbl_args%dust_flux(3:4))
        case ('M_DDD_DU')
          trc_flux=sum(pbl_args%dust_flux(1:4))
#endif
        case default
          trc_flux=0
        end select

        trsrfflx(i,j,n)=trsrfflx(i,j,n)+
     &       trc_flux*dxyp(j)*ptype
        taijs(i,j,ijts_isrc(1,n))=taijs(i,j,ijts_isrc(1,n)) +
     &       trc_flux*dxyp(j)*ptype*dtsurf

#ifdef TRACERS_AMP
        DTR_AMPe(j,n)=DTR_AMPe(j,n)+trc_flux*dxyp(j)*ptype*dtsurf
#else
        tajls(j,1,jls_isrc(1,n)) = tajls(j,1,jls_isrc(1,n))+
     *       trc_flux*dxyp(j)*ptype*dtsurf   ! why not for all aerosols?
#endif

#endif

#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
ccc dust emission from earth
        SELECT CASE (trname(n))
#ifdef TRACERS_DUST
        CASE ('Clay','Silt1','Silt2','Silt3','Silt4')
          n1=n-n_clay+1
#else
#ifdef TRACERS_MINERALS
        CASE ('ClayIlli','ClayKaol','ClaySmec','ClayCalc','ClayQuar',
     &        'Sil1Quar','Sil1Feld','Sil1Calc','Sil1Hema','Sil1Gyps',
     &        'Sil2Quar','Sil2Feld','Sil2Calc','Sil2Hema','Sil2Gyps',
     &        'Sil3Quar','Sil3Feld','Sil3Calc','Sil3Hema','Sil3Gyps',
     &        'Sil1QuHe','Sil2QuHe','Sil3QuHe')
          n1=n-n_clayilli+1
#else
#ifdef TRACERS_QUARZHEM
        CASE ('Sil1QuHe','Sil2QuHe','Sil3QuHe')
          n1=n-n_sil1quhe+1
#endif
#endif
#endif
          trsrfflx(i,j,n)=trsrfflx(i,j,n)
     &         +pbl_args%dust_flux(n1)*dxyp(j)*ptype
          taijs(i,j,ijts_isrc(nDustEmij,n))
     &         =taijs(i,j,ijts_isrc(nDustEmij,n))
     &         +pbl_args%dust_flux(n1)
     &         *dxyp(j)*ptype*dtsurf
          tajls(j,1,jls_isrc(nDustEmjl,n))
     &         =tajls(j,1,jls_isrc(nDustEmjl,n))
     &         +pbl_args%dust_flux(n1)*dxyp(j)
     &         *ptype*dtsurf
#ifdef TRACERS_DUST
          IF (imDust == 0) THEN
            taijs(i,j,ijts_isrc(nDustEm2ij,n))
     &           =taijs(i,j,ijts_isrc(nDustEm2ij,n))
     &           +pbl_args%dust_flux2(n1)
     &           *dxyp(j)*ptype*dtsurf
            tajls(j,1,jls_isrc(nDustEm2jl,n))
     &           =tajls(j,1,jls_isrc(nDustEm2jl,n))
     &           +pbl_args%dust_flux2(n1)*dxyp(j)*ptype*dtsurf
          END IF
#endif

        END SELECT
#endif

#ifdef TRACERS_DRYDEP

ccc accumulate tracer dry deposition
        if(dodrydep(n)) then
          rts=rhosrf*pbl_args%trs(nx)
          rtsdt=rts*dtsurf                             ! kg*s/m^3
          tdryd=-rtsdt*(pbl_args%dep_vel(n)+pbl_args%gs_vel(n))          ! kg/m2
          tdd = tdryd*dxyp(j)*ptype                    ! kg
          td1 = (trsrfflx(i,j,n)+totflux(nx))*dtsurf   ! kg
          if (trm(i,j,1,n)+td1+tdd.le.0.and.tdd.lt.0) then
            if (qcheck) write(99,*) "limiting tdryd earth",i,j,n,tdd
     *           ,trm(i,j,1,n),td1,pbl_args%trs(nx),pbl_args%trtop(nx)
            tdd= -max(trm(i,j,1,n)+td1,0d0)
            tdryd= tdd/(dxyp(j)*ptype)
            trsrfflx(i,j,n)= - trm(i,j,1,n)/dtsurf
          else
            trsrfflx(i,j,n)=trsrfflx(i,j,n)+tdd/dtsurf
          end if
#ifdef TRACERS_DUST
          rts_save(i,j)=rts
#endif
! trdrydep downward flux by surface type (kg/m^2)
          trdrydep(n,itype,i,j)=trdrydep(n,itype,i,j) - tdryd
! diagnose turbulent and settling fluxes separately
          taijn(i,j,tij_drydep,n)=taijn(i,j,tij_drydep,n) +
     &         ptype*rtsdt*pbl_args%dep_vel(n)
          taijn(i,j,tij_gsdep ,n)=taijn(i,j,tij_gsdep ,n) +
     &         ptype*rtsdt* pbl_args%gs_vel(n)
#ifdef TRACERS_COSMO
          if (n .eq. n_Be7) BE7D_acc(i,j)=BE7D_acc(i,j)+ptype*rtsdt
     *         *pbl_args%dep_vel(n)+ptype*rtsdt* pbl_args%gs_vel(n)
#endif
          dtr_dd(j,n,1)=dtr_dd(j,n,1)-
     &         ptype*rtsdt*dxyp(j)*pbl_args%dep_vel(n)
          dtr_dd(j,n,2)=dtr_dd(j,n,2)-
     &         ptype*rtsdt*dxyp(j)* pbl_args%gs_vel(n)
        end if
#endif
      end do

C**** Save surface tracer concentration whether calculated or not
      nx=0
      do n=1,ntm
        if (itime_tr0(n).le.itime) then
          if (needtrs(n)) then
            nx=nx+1
            taijn(i,j,tij_surf  ,n) = taijn(i,j,tij_surf  ,n)+
     &           pbl_args%trs(nx)*ptype
            taijn(i,j,tij_surfbv,n) = taijn(i,j,tij_surfbv,n)+
     &           pbl_args%trs(nx)*ptype*rhosrf
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM) || (defined TRACERS_AMP)
            trs_glob(i,j,itype,n)=pbl_args%trs(nx)*ptype
#endif
          else
            taijn(i,j,tij_surf  ,n) = taijn(i,j,tij_surf  ,n)
     *           +max((trm(i,j,1,n)-trmom(mz,i,j,1,n))*byam(1,i,j)
     *           *bydxyp(j),0d0)*ptype
            taijn(i,j,tij_surfbv,n) = taijn(i,j,tij_surfbv,n)
     *           +max((trm(i,j,1,n)-trmom(mz,i,j,1,n))*byam(1,i,j)
     *           *bydxyp(j),0d0)*ptype*rhosrf
          end if
        end if
      end do

ccc not sure about the code below. hopefully that''s what is meant above
#ifdef TRACERS_WATER
      do nx=1,ntg
        n=ntixw(nx)
        taijn(i,j,tij_evap,n)=taijn(i,j,tij_evap,n)+
     *       trevapor(n,itype,i,j)*ptype
        taijn(i,j,tij_grnd,n)=taijn(i,j,tij_grnd,n)+
     *         gtracer(n,itype,i,j)*ptype
        taijn(i,j,tij_soil,n)=taijn(i,j,tij_soil,n) + (
     &       fb*(sum( tr_w(nx,1:ngm,1) ))+
     &       fv*(sum( tr_w(nx,0:ngm,2) ))
     *       )
        taijn(i,j,tij_snow,n)=taijn(i,j,tij_snow,n) + (
     &       fb*(sum( tr_wsn(nx,1:nsn(1),1) ))+
     &       fv*(sum( tr_wsn(nx,1:nsn(2),2) ))
     *       )
        if (tr_wd_TYPE(n).eq.nWATER) tajls(j,1,jls_isrc(1,n))=
     *       tajls(j,1,jls_isrc(1,n))+trevapor(n,itype,i,j)*ptype
      enddo
#endif
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
c ..........
c Accumulates dust events. One diagnostic field for all dust tracers
c ..........
      taijs(i,j,ijts_spec(nDustEv1ij))=taijs(i,j,ijts_spec(nDustEv1ij))
     &     +pbl_args%dust_event1
      tajls(j,1,jls_spec(nDustEv1jl))=tajls(j,1,jls_spec(nDustEv1jl))
     &     +pbl_args%dust_event1
      taijs(i,j,ijts_spec(nDustEv2ij))=taijs(i,j,ijts_spec(nDustEv2ij))
     &     +pbl_args%dust_event2
      tajls(j,1,jls_spec(nDustEv2jl))=tajls(j,1,jls_spec(nDustEv2jl))
     &     +pbl_args%dust_event2
      taijs(i,j,ijts_spec(nDustWthij))=taijs(i,j,ijts_spec(nDustWthij))
     &     +pbl_args%wtrsh*ptype
      tajls(j,1,jls_spec(nDustWthjl))=tajls(j,1,jls_spec(nDustWthjl))
     &     +pbl_args%wtrsh*ptype
#endif

c     ..........
c     save global variables for subdaily diagnostics
c     ..........

#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
      DO n=1,Ntm_dust
        dust_flux_glob(i,j,n)=pbl_args%dust_flux(n)*ptype
#ifdef TRACERS_DUST
        dust_flux2_glob(i,j,n)=pbl_args%dust_flux2(n)*ptype
#endif
      END DO
#endif

#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
#ifdef TRACERS_DRYDEP
      DO n=1,Ntm
        IF (dodrydep(n)) THEN
          depo_turb_glob(i,j,itype,n)=ptype*rts*pbl_args%dep_vel(n)
          depo_grav_glob(i,j,itype,n)=ptype*rts*pbl_args%gs_vel(n)
        END IF
      END DO
#endif
#endif

#ifdef INTERACTIVE_WETLANDS_CH4
C**** update running-average of ground temperature:
      call running_average(ra_temp,I,J,dble(nisurf),n__temp)
      call running_average(ra_sat,I,J,dble(nisurf),n__sat)
      call running_average(ra_gwet,I,J,dble(nisurf),n__gwet)
#endif
      end subroutine ghy_tracers_save_cell

      end module ghy_tracers
#endif
c******************   END   TRACERS             ************************


c***********************************************************************
c***********************************************************************
c***********************************************************************
c***********************************************************************
c***********************************************************************
c***********************************************************************



      module soil_drv 8,8
!@sum soil_drv contains variables and routines for the ground
!@+   hydrology driver
!@auth I. Alienov/F. Abramopolous
      use model_com, only : im,jm
      use socpbl, only : npbl=>n
      use veg_drv, only : cosday,sinday
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
!      USE pbl_drv,ONLY : dust_flux,dust_flux2,z,km,gh,gm,zhat,lmonin,
!     &     wsubtke,wsubwd,wsubwm,dust_event1,dust_event2,wtrsh
#endif
      
      use diag_com, only : idd_ts,idd_tg1,idd_qs
     *     ,idd_qg,idd_swg,idd_lwg,idd_sh,idd_lh,idd_hz0,idd_ug,idd_vg
     *     ,idd_wg,idd_us,idd_vs,idd_ws,idd_cia,idd_cm,idd_ch,idd_cq
     *     ,idd_eds,idd_dbl,idd_ev
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
     *     ,idd_wtke,idd_wd,idd_wm,idd_wsgcm,idd_wspdf,idd_wtrsh
#endif
#ifdef TRACERS_DUST
     *     ,idd_ws2,idd_ustar,idd_us3,idd_stress,idd_lmon
     *     ,idd_rifl,idd_zpbl1,idd_uabl1,idd_vabl1,idd_uvabl1,idd_tabl1
     *     ,idd_qabl1,idd_zhat1,idd_e1,idd_km1,idd_ri1,idd_emis
     *     ,idd_emis2,idd_grav,idd_turb
#endif
      implicit none
      private
      save

      public daily_earth
      public ground_e
      public init_gh
      public earth
      public conserv_wtg
      public conserv_htg
      public conserv_wtg_1
      public checke
      public snow_cover

      !real*8 cosday,sinday
      !real*8 cosdaym1, sindaym1               !nyk TEMPORARY for jday-1
      real*8 adlmass          ! accumulator for dleafmass in daily_earth

      real*8 spgsn !@var spgsn specific gravity of snow
!@dbparam snow_cover_coef coefficient for topography variance in
!@+       snow cover parameterisation for albedo
      real*8 :: snow_cover_coef = .15d0

      integer variable_lk

      ! Indexes used for adiurn and hdiurn
      INTEGER, PARAMETER :: n_idx = 22
#if (defined TRACERS_MINERALS) || (defined TRACERS_QUARZHEM)
      INTEGER,PARAMETER :: n_idxd=6
#else
#ifdef TRACERS_DUST
      INTEGER,PARAMETER :: n_idxd=12+10*npbl
#endif
#endif

      contains


      subroutine earth (ns,moddsf,moddd) 1,76
!@sum EARTH calculates surface fluxes of sensible heat,
!@+   evaporation, thermal radiation, and momentum drag over earth.
!@auth I. Alienov/F. Abramopolous
c****
      use constant, only : grav,rgas,lhe,lhs
     *     ,sha,tf,rhow,deltx,stbo
      use model_com, only : t,p,q,dtsrc,nisurf,jdate
     *     ,jday,jhour,nday,itime,jeq,u,v
     *     ,im,jm
      use DOMAIN_DECOMP, only : GRID, GET
      use DOMAIN_DECOMP, only : HALO_UPDATE, CHECKSUM, NORTH
      use DOMAIN_DECOMP, only : GLOBALSUM, AM_I_ROOT
      use geom, only : imaxj
      use dynamics, only : pmid,pk,pek,pedn,am
      use rad_com, only : trhr,fsf, cosz1,trsurf

      !use surf_albedo, only: albvnh   ! added 5/23/03 from RADIATION.f
      !albvnh(9,6,2)=albvnh(sand+8veg,6bands,2hemi) - only need 1st band
      use sle001, only : advnc,evap_limits,
     &    pr,htpr,prs,htprs,w,snowd,tp,fice,
     &    fv,fb,ashg,alhg,
     &    aevap,abetad,
     &    aruns,arunu,aeruns,aerunu,
     &    tbcs,af0dt,af1dt,
     &    qm1,qs,
     &    pres,rho,ts,ch,srht,trht
     &   ,vs,vs0,tprime,qprime

      use veg_drv, only: veg_save_cell,veg_set_cell

      use fluxes, only : dth1,dq1,uflux1,vflux1,e0,e1,evapor,prec,eprec
     *     ,runoe,erunoe,gtemp,precss,gtempr
      use ghy_com, only : snowbv, fearth,
     &     fr_snow_ij,
     *     canopy_temp_ij,snowe,tearth,wearth,aiearth,
     &     evap_max_ij, fr_sat_ij, qg_ij, fr_snow_rad_ij,top_dev_ij

      use vegetation, only :
     &    veg_srht=>srht,veg_pres=>pres,veg_ch=>ch,veg_ws=>vsm !ia

      use pbl_drv, only : pbl, t_pbl_args

      use snow_drvm, only : snow_cover_same_as_rad

      use diag_com , only : HR_IN_DAY,HR_IN_MONTH,NDIUVAR
     &     ,adiurn,NDIUPT,adiurn_dust
#ifndef NO_HDIURN
     &     ,hdiurn
#endif
#ifdef TRACERS_ON
      use ghy_tracers, only : ghy_tracers_set_step,ghy_tracers_set_cell,
     &     ghy_tracers_save_cell
#endif
      implicit none

      integer, intent(in) :: ns,moddsf,moddd
      integer i,j,itype,ibv
      real*8 shdt,evhdt,rcdmws,rcdhws
     *     ,cdq,cdm,cdh,elhx,tg,srheat,tg1,ptype,trheat    !,dhgs
     *     ,rhosrf,ma1,tfs,th1,thv1,p1k,psk,ps,pij
     *     ,spring,q1,dlwdt

!@var rhosrf0 estimated surface air density
      real*8 rhosrf0


      real*8 qsat
      integer jr
!@var qg rel. humidity at the ground, defined: total_evap = Cq V (qg-qs)
!@var qg_nsat rel. humidity at non-saturated fraction of soil
      real*8 qg, qg_nsat
c****
c**** fearth    soil covered land fraction (1)
c****
c**** snowe     earth snow amount (kg/m**2)
c**** tearth    earth temperature of first layer (c)
c**** wearth    earth water of first layer (kg/m**2)
c**** aiearth   earth ice of first layer (kg/m**2)
c****
c**** wbare  1-6 water of bare soil layer 1-6 (m)
c**** wvege   0  water of vegetation canopy (m)
c****        1-6 water of vegetated soil layer 1-6 (m)
c**** htbare  0  bare soil layer 0 is unused
c****        1-6 heat content of bare soil layer 1-6 (j m-2)
c**** htvege  0  heat content of vegetation canopy (j m-2)
c****        1-6 heat content of vegetated soil layer 1-6 (j m-2)
c**** snowbv  1  snow depth over bare soil (m)
c****         2  snow depth over vegetated soil (m)
c****

c**** input/output for PBL
      type (t_pbl_args) pbl_args
      real*8 qg_sat

      REAL*8, DIMENSION(grid%J_STRT_HALO:grid%J_STOP_HALO,
     &     NDIUVAR, NDIUPT) :: adiurn_part
#ifndef NO_HDIURN
      REAL*8, DIMENSION(grid%J_STRT_HALO:grid%J_STOP_HALO,
     &     NDIUVAR, NDIUPT) :: hdiurn_part
#endif
      REAL*8, DIMENSION(N_IDX,grid%J_STRT_HALO:grid%J_STOP_HALO,
     &     NDIUPT) :: adiurn_temp
#ifndef NO_HDIURN
      REAL*8, DIMENSION(N_IDX,grid%J_STRT_HALO:grid%J_STOP_HALO,
     &     NDIUPT) :: hdiurn_temp
#endif
      REAL*8, DIMENSION(N_IDX, NDIUPT) :: ADIURNSUM
#ifndef NO_HDIURN
     *     ,HDIURNSUM
#endif
      INTEGER :: idx(n_idx)
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
      REAL*8, DIMENSION(n_idxd,grid%J_STRT_HALO:grid%J_STOP_HALO,
     &     NDIUPT) :: adiurn_tempd
#ifndef NO_HDIURN
      REAL*8, DIMENSION(n_idxd,grid%J_STRT_HALO:grid%J_STOP_HALO,
     &     NDIUPT) :: hdiurn_tempd
#endif
      REAL*8, DIMENSION(n_idxd, NDIUPT) :: ADIURNSUMd
#ifndef NO_HDIURN
     *     ,HDIURNSUMd
#endif
      INTEGER :: idxd(n_idxd)
#endif
      INTEGER :: ih, ihm, ii, ivar, kr
#ifdef TRACERS_DUST
      INTEGER :: n,n1
#endif
      REAL*8 :: tmp(NDIUVAR)

C****   define local grid
      integer J_0, J_1, J_0H, J_1H

C****
C**** Extract useful local domain parameters from "grid"
C****
      CALL GET(grid, J_STRT=J_0, J_STOP=J_1)

    ! dtsurf=dtsrc/nisurf

      spring=-1.
      if((jday.ge.32).and.(jday.le.212)) spring=1.

c****
c**** outside loop over time steps, executed nisurf times every hour
c****
ccc set i,j - independent stuff for tracers
#ifdef TRACERS_ON
      call ghy_tracers_set_step
#endif

c****
c**** outside loop over j and i, executed once for each grid point
c****
C**** halo update u and v for distributed parallelization
       call halo_update(grid, U, from=NORTH)
       call halo_update(grid, V, from=NORTH)

       adiurn_part = 0
#ifndef NO_HDIURN
       hdiurn_part = 0
#endif

       idx =
     &     (/ idd_ts,  idd_tg1, idd_qs,  idd_qg,  idd_swg,
     &        idd_lwg, idd_sh,  idd_lh,  idd_hz0, idd_ug,
     &        idd_vg,  idd_wg,  idd_us,  idd_vs,  idd_ws,
     &        idd_cia, idd_cm,  idd_ch,  idd_cq,  idd_eds,
     &        idd_dbl, idd_ev /)
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
      IF (adiurn_dust == 1) THEN
        idxd=(/ idd_wsgcm,idd_wspdf,idd_wtke,idd_wd,idd_wm,idd_wtrsh
#ifdef TRACERS_DUST
     &      ,idd_emis,   idd_emis2,  idd_turb,   idd_grav,   idd_ws2
     &      ,idd_ustar,  idd_us3,    idd_stress, idd_lmon,   idd_rifl,
     &       (idd_zpbl1+i-1,i=1,npbl), (idd_uabl1+i-1,i=1,npbl),
     *       (idd_vabl1+i-1,i=1,npbl), (idd_uvabl1+i-1,i=1,npbl),
     *       (idd_tabl1+i-1,i=1,npbl), (idd_qabl1+i-1,i=1,npbl),  
     *       (idd_zhat1+i-1,i=1,npbl-1), (idd_e1+i-1,i=1,npbl-1),
     *       (idd_km1+i-1,i=1,npbl-1), (idd_ri1+i-1,i=1,npbl-1)
#endif
     &      /)
      END IF
#endif

!$OMP  PARALLEL DO PRIVATE
!$OMP*  (ELHX,EVHDT, CDM,CDH,CDQ,
!$OMP*   I,ITYPE,ibv, J, MA1,PIJ,PSK,PS,P1K,PTYPE, QG,
!$OMP*   QG_NSAT, RHOSRF,RHOSRF0,RCDMWS,RCDHWS,SRHEAT,SHDT,dlwdt,
!$OMP*   TRHEAT, TH1,TFS,THV1,TG1,TG,q1,pbl_args,qg_sat,jr,kr,tmp
#ifdef TRACERS_DUST
!$OMP*   ,n,n1
#endif
!$OMP*   )
!$OMP*   SHARED(ns,moddsf,moddd)
!$OMP*   SCHEDULE(DYNAMIC,2)

      loop_j: do j=J_0,J_1
  !    hemi=1.
  !    if(j.le.jm/2) hemi=-1.

c**** conditions at the south/north pole
  !    pole= ( j.eq.1 .or. j.eq.jm )

      loop_i: do i=1,imaxj(j)

      pbl_args%dtsurf=dtsrc/nisurf
      pbl_args%hemi=1.
      if(j.le.jm/2) pbl_args%hemi=-1.
      pbl_args%pole= ( j.eq.1 .or. j.eq.jm )

c****
c**** determine surface conditions
c****
      ptype=fearth(i,j)
      pij=p(i,j)
      ps=pedn(1,i,j)
      psk=pek(1,i,j)
      p1k=pk(1,i,j)
      th1=t(i,j,1)
      q1=q(i,j,1)
      thv1=th1*(1.+q1*deltx)
      pbl_args%tkv=thv1*psk
  !    tkv=thv1*psk

      tfs=tf*ptype
      ma1=am(1,i,j)
      qm1=q1*ma1
c     rhosrf=100.*ps/(rgas*tsv)
c     rhosrf=100.*ps/(rgas*tkv)
c****
c**** earth
c****
      if (ptype.le.0.) then
  !      ipbl(i,j,4)=0
        cycle loop_i
      endif
      itype=4

      pr=prec(i,j)/(dtsrc*rhow)
C**** This variable was originally assoicated with super-saturated
C**** large-scale precip, but has not worked for many moons.
C**** If you want to reinstate it, uncomment this calculation.
c      prs=precss(i,j)/(dtsrc*rhow)
      prs=0.
      htpr=eprec(i,j)/dtsrc

ccc tracers variables

      tg1 = tearth(i,j)
      srheat=fsf(itype,i,j)*cosz1(i,j)
c****
c**** boundary layer interaction
c****
      pbl_args%zs1=.5d-2*rgas*pbl_args%tkv*ma1/pmid(1,i,j)
  !    zs1=.5d-2*rgas*tkv*ma1/pmid(1,i,j)

c**** loop over ground time steps
      tg=tg1+tf
      elhx=lhe
      if(tg1.lt.0.)  elhx=lhs
      pbl_args%qg_sat=qsat(tg,elhx,ps)  !  replacing with qs from prev step
      pbl_args%tg=tg
      pbl_args%elhx=elhx
      pbl_args%qsol=srheat   ! solar heating
  !    qg_sat=qsat(tg,elhx,ps)  !  replacing with qs from prev step

      qg = qg_ij(i,j)
      ! if ( qg > 999.d0 ) qg = qg_sat
      pbl_args%qg_aver = qg
  !    qg_aver = qg

      pbl_args%tgv=tg*(1.+qg*deltx)
  !    tgv=tg*(1.+qg*deltx)

      pbl_args%psurf=ps
  !    psurf=ps

      pbl_args%trhr0 = TRHR(0,I,J)
  !    trhr0 = TRHR(0,I,J)

      rhosrf0=100.*ps/(rgas*pbl_args%tgv) ! estimated surface density
C**** Obviously there are no ocean currents for earth points, but
C**** variables set for consistency with surfce
      pbl_args%uocean=0 ; pbl_args%vocean=0
      pbl_args%ocean = .FALSE.
  !    uocean=0 ; vocean=0

c***********************************************************************
c****
ccc actually PBL needs evap (kg/m^2*s) / rho_air
      pbl_args%evap_max = evap_max_ij(i,j) * 1000.d0 / rhosrf0
      pbl_args%fr_sat = fr_sat_ij(i,j)
  !    evap_max = evap_max_ij(i,j) * 1000.d0 / rhosrf0
  !    fr_sat = fr_sat_ij(i,j)

c**** call tracers stuff
#ifdef TRACERS_ON
      call ghy_tracers_set_cell(i,j,ptype,pbl_args%qg_sat
     &     ,pbl_args%evap_max,pbl_args)
#endif
      call pbl(i,j,itype,ptype,pbl_args)
c****
      cdm = pbl_args%cm ! cmgs(i,j,itype)
      cdh = pbl_args%ch ! chgs(i,j,itype)
      cdq = pbl_args%cq ! cqgs(i,j,itype)
c***********************************************************************
c**** calculate qs
      qs=pbl_args%qsrf
      ts=pbl_args%tsv/(1.+qs*deltx)
c**** calculate rhosrf*cdm*ws
      rhosrf=100.*ps/(rgas*pbl_args%tsv)
      rcdmws=cdm*pbl_args%ws*rhosrf
      rcdhws=cdh*pbl_args%ws*rhosrf
      trheat=trhr(0,i,j)
c***********************************************************************
c****
c  define extra variables to be passed in surfc:
      pres   = ps
      veg_pres = ps
      rho    = rhosrf
      vs     = pbl_args%ws
      vs0    = pbl_args%ws0
      tprime = pbl_args%tprime
      qprime = pbl_args%qprime
      veg_ws = pbl_args%ws
      ch     = cdh
      veg_ch = cdh
      srht   = srheat
      veg_srht = srheat
      trht   = trheat
c***********************************************************************
c****
c**** calculate ground fluxes
c     call qsbal
!!! insert htprs here ???

      call ghinij (i,j)
      call veg_set_cell(i,j)
! snow / var lakes problem at this cell (underwater snow in initial data)
!      if (i==47 .and. j==33) then
!        print *,i,j
!      endif
      call advnc
      call evap_limits( .false., evap_max_ij(i,j), fr_sat_ij(i,j) )

      call veg_save_cell(i,j)
      call ghy_save_cell(i,j)

      tg1=tbcs

c**** computing ground humidity to be used on next time step
      !qg_ij(i,j) = qs  !!! - this seemed to work ok
      !! trying more precise value for qg :  qsat(tg1+tf,elhx,ps)
      qg_sat = qsat(tg1+tf,elhx,ps) ! saturated soil
      qg_nsat = qs              ! non-sat soil, no evap
      if ( rcdhws > 1.d-30 ) then   ! correction to non-sat, due to evap
        qg_nsat = qg_nsat + evap_max_ij(i,j)/(0.001*rcdhws)
      endif
      qg_nsat = min( qg_nsat, qg_sat )
      qg_ij(i,j) = fr_sat_ij(i,j) * qg_sat
     &     + (1.d0 -fr_sat_ij(i,j)) * qg_nsat

ccc Save canopy temperature.
ccc canopy_temp_ij is not used so far... do we need it?
      canopy_temp_ij(i,j) = tp(0,2)  !nyk

c**** set snow fraction for albedo computation (used by RAD_DRV.f)
      if ( snow_cover_same_as_rad == 0 ) then
        ! recompute snow fraction using different formula
        do ibv=1,2
          call snow_cover(fr_snow_rad_ij(ibv,i,j),
     &         snowbv(ibv,i,j), top_dev_ij(i,j) )
          fr_snow_rad_ij(ibv,i,j) = min (
     &         fr_snow_rad_ij(ibv,i,j), fr_snow_ij(ibv, i, j) )
        enddo
      else
        ! snow fraction same as in snow model
        fr_snow_rad_ij(:,i,j) = fr_snow_ij(:, i, j)
      endif

c**** snowe used in RADIATION
      snowe(i,j)=1000.*(snowd(1)*fb+snowd(2)*fv)
c**** tearth used only internaly in GHY_DRV
      tearth(i,j)=tg1
c**** wearth+aiearth are used in radiation only
      wearth(i,j)=1000.*( fb*w(1,1)*(1.-fice(1,1)) +
     &     fv*(w(1,2)*(1.-fice(1,2))+w(0,2)*(1.-fice(0,2))) )
      aiearth(i,j)=1000.*( fb*w(1,1)*fice(1,1) +
     &     fv*(w(1,2)*fice(1,2)+w(0,2)*fice(0,2)) )
      gtemp(1,4,i,j)=tearth(i,j)
      gtempr(4,i,j) =tearth(i,j)+tf
c**** calculate fluxes using implicit time step for non-ocean points
      uflux1(i,j)=uflux1(i,j)+ptype*rcdmws*(pbl_args%us) !-uocean)
      vflux1(i,j)=vflux1(i,j)+ptype*rcdmws*(pbl_args%vs) !-vocean)
c**** accumulate surface fluxes and prognostic and diagnostic quantities
      evapor(i,j,4)=evapor(i,j,4)+aevap
      shdt=-ashg
C**** calculate correction for different TG in radiation and surface
      dLWDT = pbl_args%dtsurf*(TRSURF(ITYPE,I,J)-STBO*(tearth(i,j)+TF)
     *     **4)
      dth1(i,j)=dth1(i,j)-(SHDT+dLWDT)*ptype/(sha*ma1*p1k)
      dq1(i,j) =dq1(i,j)+aevap*ptype/ma1
  !    qsavg(i,j)=qsavg(i,j)+qs*ptype
c**** save runoff for addition to lake mass/energy resevoirs
      runoe (i,j)=runoe (i,j)+ aruns+ arunu
      erunoe(i,j)=erunoe(i,j)+aeruns+aerunu
c****
      e0(i,j,4)=e0(i,j,4)+af0dt
      e1(i,j,4)=e1(i,j,4)+af1dt

      call ghy_diag(i,j,jr,kr,tmp,ns,moddsf,moddd
     &     ,rcdmws,cdm,cdh,cdq,qg
     &     ,pbl_args, pbl_args%dtsurf
     &     ,adiurn_part
     &     ,idx
#ifndef NO_HDIURN
     &     ,hdiurn_part
#endif
#ifdef TRACERS_DUST
     &     ,n,n1
#endif
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
     &     ,idxd
#endif
     &     )

c**** update tracers
#ifdef TRACERS_ON
      call ghy_tracers_save_cell(i,j,ptype,pbl_args%dtsurf,rhosrf
     &   ,pbl_args
#ifdef INTERACTIVE_WETLANDS_CH4
     & ,tg1,ts-tf,1.d2*abetad/real(nisurf)
#endif
     & )
#endif

      end do loop_i
      end do loop_j
!$OMP  END PARALLEL DO

      ! land water deficit for changing lake fractions
      call compute_water_deficit

! Accumulate contributions to ADIURN and HDIURN
      ih=1+jhour
      ihm = ih+(jdate-1)*24


      DO kr = 1, ndiupt
        DO ii = 1, N_IDX
          ivar = idx(ii)
          ADIURN_temp(ii,:,kr)=ADIURN_part(:,ivar,kr)
#ifndef NO_HDIURN
          HDIURN_temp(ii,:,kr)=HDIURN_part(:,ivar,kr)
#endif
        END DO
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
        IF (adiurn_dust == 1) THEN
          DO ii=1,n_idxd
            ivar=idxd(ii)
            ADIURN_tempd(ii,:,kr)=ADIURN_part(:,ivar,kr)
#ifndef NO_HDIURN
            HDIURN_tempd(ii,:,kr)=HDIURN_part(:,ivar,kr)
#endif
          END DO
        END IF
#endif
      END DO
      CALL GLOBALSUM(grid, ADIURN_temp(1:N_IDX,:,1:ndiupt),
     &    ADIURNSUM(1:N_IDX,1:ndiupt))
#ifndef NO_HDIURN
      CALL GLOBALSUM(grid, HDIURN_temp(1:N_IDX,:,1:ndiupt),
     &    HDIURNSUM(1:N_IDX,1:ndiupt))
#endif
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
      IF (adiurn_dust == 1) THEN
        CALL GLOBALSUM(grid,ADIURN_tempd(1:n_idxd,:,1:ndiupt),
     &       ADIURNSUMd(1:n_idxd,1:ndiupt))
#ifndef NO_HDIURN
        CALL GLOBALSUM(grid,HDIURN_tempd(1:n_idxd,:,1:ndiupt),
     &       HDIURNSUMd(1:n_idxd,1:ndiupt))
#endif
      END IF
#endif
      DO kr = 1, ndiupt
        DO ii = 1, N_IDX
          ivar = idx(ii)
          IF (AM_I_ROOT()) THEN
            ADIURN(ih,ivar,kr)=ADIURN(ih,ivar,kr) + ADIURNSUM(ii,kr)
#ifndef NO_HDIURN
            HDIURN(ihm,ivar,kr)=HDIURN(ihm,ivar,kr) + HDIURNSUM(ii,kr)
#endif
          END IF
        END DO
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
        IF (adiurn_dust == 1) THEN
          DO ii=1,n_idxd
            ivar=idxd(ii)
            IF (AM_I_ROOT()) THEN
              ADIURN(ih,ivar,kr)=ADIURN(ih,ivar,kr)+ADIURNSUMd(ii,kr)
#ifndef NO_HDIURN
              HDIURN(ihm,ivar,kr)=HDIURN(ihm,ivar,kr)+HDIURNSUMd(ii,kr)
#endif
            END IF
          END DO
        END IF
#endif
      END DO
C
      return
      end subroutine earth

c***********************************************************************
c***********************************************************************
c***********************************************************************
c***********************************************************************
c***********************************************************************
c***********************************************************************


      subroutine ghy_diag(i,j,jr,kr,tmp,ns,moddsf,moddd 2,28
     &     ,rcdmws,cdm,cdh,cdq,qg, pbl_args, dtsurf
     &     ,adiurn_part,idx
#ifndef NO_HDIURN
     &     ,hdiurn_part
#endif
#ifdef TRACERS_DUST
     &     ,n,n1
#endif
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
     &     ,idxd
#endif
     &     )

      use diag_com , only : aij=>aij_loc
     *     ,tsfrez=>tsfrez_loc,tdiurn,aj=>aj_loc,aregj=>aregj_loc,jreg
     *     ,ij_rune, ij_arunu, ij_pevap, ij_shdt, ij_beta, ij_trnfp0
     *     ,ij_srtr, ij_neth, ij_ws, ij_ts, ij_us, ij_vs, ij_taus
     *     ,ij_tauus, ij_tauvs, ij_qs, ij_tg1, ij_evap, j_trhdt, j_shdt
     *     ,j_evhdt,j_evap,j_erun,j_run,j_tsrf,j_type,j_tg1,j_tg2,ij_g05
     *     ,ij_g06,ij_g11,ij_g12,ij_g13,ij_g14,ij_g15,ij_g16,ij_g17
     *     ,ij_gpp,ij_pblht,ij_g18,ij_g19,ij_g20,ij_g21,ij_g22,ij_g23
     *     ,ij_g24,ij_g25,ij_g26,ij_g27,ijdd,idd_ts,idd_tg1,idd_qs
     *     ,idd_qg,idd_swg,idd_lwg,idd_sh,idd_lh,idd_hz0,idd_ug,idd_vg
     *     ,idd_wg,idd_us,idd_vs,idd_ws,idd_cia,idd_cm,idd_ch,idd_cq
     *     ,idd_eds,idd_dbl,idd_ev,tf_day1,tf_last,ndiupt
     *     ,HR_IN_DAY,HR_IN_MONTH,NDIUVAR
     &     ,ij_aflmlt,ij_aeruns,ij_aerunu,ij_fveg
     &     ,ij_htsoil,ij_htsnow,ij_aintrcp,ij_trsdn,ij_trsup,adiurn_dust
     &     ,ij_gusti,ij_mccon
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
     &     ,ij_wdry,ij_wtke,ij_wmoist,ij_wsgcm,ij_wspdf
#endif
#ifdef TRACERS_DUST
      USE PBLCOM,ONLY : eabl,uabl,vabl,tabl,qabl
#endif
      use constant, only : tf
#ifdef TRACERS_DUST
     &     ,grav
#endif
      use model_com, only : dtsrc,nisurf,jdate
     *     ,jday,jhour,nday,itime,jeq,modrd,itearth
      use DOMAIN_DECOMP, only : grid
      use geom, only : dxyp
      use rad_com, only : trhr,fsf, cosz1

      use sle001, only :
     &     tp
     &    ,fv,fb,atrg,ashg,alhg
     &    ,abetad,abetav,abetat
     &    ,abetap,abetab,abeta
     &    ,acna,acnc,agpp
     &    ,aevap,aevapw,aevapd,aevapb
     &    ,aruns,arunu,aeruns,aerunu,aflmlt,aintercep
     &    ,aepc,aepb,aepp,zw,tbcs
     &    ,qs,ts,ngr=>n,ht,hsn,fr_snow,nsn

      use ghy_com, only : gdeep, fearth
      USE CLOUDS_COM, only : DDMS

      use pbl_drv, only : t_pbl_args

#ifdef TRACERS_DUST
      USE tracer_com,ONLY : Ntm_dust,n_clay
#ifdef TRACERS_DRYDEP
     &     ,dodrydep
#endif
#endif
#if (defined TRACERS_DUST) && (defined TRACERS_DRYDEP)
      USE trdiag_com,ONLY : rts_save
#endif

      implicit none
      integer, intent(in) :: i,j,ns,moddsf,moddd
      real*8, intent(in) :: rcdmws,cdm,cdh,cdq,qg
      type (t_pbl_args) :: pbl_args
      real*8, intent(in) :: dtsurf
      REAL*8, DIMENSION(grid%J_STRT_HALO:grid%J_STOP_HALO,
     &     NDIUVAR, NDIUPT) :: adiurn_part
#ifndef NO_HDIURN
      REAL*8, DIMENSION(grid%J_STRT_HALO:grid%J_STOP_HALO,
     &     NDIUVAR, NDIUPT) :: hdiurn_part
#endif
      INTEGER, INTENT(IN) :: idx(:)
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
      INTEGER,INTENT(IN) :: idxd(:)
#endif

      real*8 timez
      real*8 trhdt,tg2av,wtr2av,ace2av,tg1,shdt,ptype,srheat,srhdt
      real*8 warmer,spring,trheat,evhdt
      integer, parameter :: itype=4
      integer :: kr,jr
#ifdef TRACERS_DUST
      INTEGER :: n,n1
#endif
      REAL*8 :: tmp(:)

ccc the following values are returned by PBL
      real*8 us,vs,ws,psi,dbl,khs,ug,vg,wg,gusti
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
     &     ,wsgcm,wspdf
#endif
      us = pbl_args%us
      vs = pbl_args%vs
      ws = pbl_args%ws
      psi = pbl_args%psi
      dbl = pbl_args%dbl
      khs = pbl_args%khs
      ug = pbl_args%ug
      vg = pbl_args%vg
      wg = pbl_args%wg
      gusti = pbl_args%gusti
#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
      wsgcm=pbl_args%wsgcm
      wspdf=pbl_args%wspdf
#endif

      timez=jday+(mod(itime,nday)+(ns-1.)/nisurf)/nday ! -1 ??
      if(jday.le.31) timez=timez+365.


      spring=-1.
      if((jday.ge.32).and.(jday.le.212)) spring=1.

      if(j.lt.jeq)  then
         warmer=-spring
       else
         warmer=spring
      end if

      ptype=fearth(i,j)
      jr=jreg(i,j)

      srheat=fsf(itype,i,j)*cosz1(i,j)
      srhdt=srheat*dtsurf
      trheat=trhr(0,i,j)

      tg1=tbcs
      shdt=-ashg
      evhdt=-alhg

      aij(i,j,ij_fveg)=aij(i,j,ij_fveg)+fv/nisurf
      aij(i,j,ij_g18)=aij(i,j,ij_g18)+aevapb
      aij(i,j,ij_g19)=aij(i,j,ij_g19)+aevapd
      aij(i,j,ij_g20)=aij(i,j,ij_g20)+aevapw
      aij(i,j,ij_g05)=aij(i,j,ij_g05)+abetab/nisurf
      aij(i,j,ij_g06)=aij(i,j,ij_g06)+abetap/nisurf
      aij(i,j,ij_g11)=aij(i,j,ij_g11)+abeta/nisurf
      aij(i,j,ij_g12)=aij(i,j,ij_g12)+acna/nisurf
      aij(i,j,ij_g13)=aij(i,j,ij_g13)+acnc/nisurf
      aij(i,j,ij_gpp)=aij(i,j,ij_gpp)+agpp
      aij(i,j,ij_g26)=aij(i,j,ij_g26)+abetav/nisurf
      aij(i,j,ij_g27)=aij(i,j,ij_g27)+abetat/nisurf
      aij(i,j,ij_g14)=aij(i,j,ij_g14)+aepp
      if (moddsf.eq.0) then
        aij(i,j,ij_g15)=aij(i,j,ij_g15)+tp(1,1)
        aij(i,j,ij_g16)=aij(i,j,ij_g16)+tp(2,1)
        aij(i,j,ij_g17)=aij(i,j,ij_g17)+tp(6,1)
        aij(i,j,ij_g21)=aij(i,j,ij_g21)+tp(0,2)
        aij(i,j,ij_g22)=aij(i,j,ij_g22)+tp(1,2)
        aij(i,j,ij_g23)=aij(i,j,ij_g23)+tp(2,2)
        aij(i,j,ij_g24)=aij(i,j,ij_g24)+tp(6,2)
        aij(i,j,ij_g25)=aij(i,j,ij_g25)+fb*zw(1)+fv*zw(2)
      end if
ccc accumulate total heat storage
      if (moddsf.eq.0) then
        aij(i,j,ij_htsoil)=aij(i,j,ij_htsoil) +
     &       fb*sum(ht(1:ngr,1)) + fv*sum(ht(0:ngr,2))
        aij(i,j,ij_htsnow)=aij(i,j,ij_htsnow)
     &       + fb*fr_snow(1)*sum(hsn(1:nsn(1),1))
     &       + fv*fr_snow(2)*sum(hsn(1:nsn(2),2))
      endif
      trhdt=trheat*dtsurf-atrg
c           for radiation find composite values over earth
c           for diagnostic purposes also compute gdeep 1 2 3
      call retp2 (tg2av,wtr2av,ace2av)
      gdeep(i,j,1)=tg2av
      gdeep(i,j,2)=wtr2av
      gdeep(i,j,3)=ace2av

      aij(i,j,ij_rune)=aij(i,j,ij_rune)+aruns
      aij(i,j,ij_arunu)=aij(i,j,ij_arunu)+arunu
      aij(i,j,ij_aeruns)=aij(i,j,ij_aeruns)+aeruns
      aij(i,j,ij_aerunu)=aij(i,j,ij_aerunu)+aerunu
      aij(i,j,ij_pevap)=aij(i,j,ij_pevap)+(aepc+aepb)
      aij(i,j,ij_aflmlt)=aij(i,j,ij_aflmlt)+aflmlt
      aij(i,j,ij_aintrcp)= aij(i,j,ij_aintrcp)+aintercep

      if ( warmer >= 0 ) then
        if(ts.lt.tf) tsfrez(i,j,tf_day1)=timez
        tsfrez(i,j,tf_last)=timez
      else
        if ( tsfrez(i,j,tf_last)+.03 >= timez .and. ts >= tf )
     $       tsfrez(i,j,tf_last)=timez
      endif

      if(tg1.lt.tdiurn(i,j,1)) tdiurn(i,j,1)=tg1
      if(tg1.gt.tdiurn(i,j,2)) tdiurn(i,j,2)=tg1
      if(ts.lt.tdiurn(i,j,3)) tdiurn(i,j,3)=ts
      if(ts.gt.tdiurn(i,j,4)) tdiurn(i,j,4)=ts

c**** quantities accumulated for regions in diagj
      aregj(jr,j,j_trhdt)=aregj(jr,j,j_trhdt)+trhdt*ptype*dxyp(j)
      aregj(jr,j,j_shdt )=aregj(jr,j,j_shdt )+shdt*ptype*dxyp(j)
      aregj(jr,j,j_evhdt)=aregj(jr,j,j_evhdt)+evhdt*ptype*dxyp(j)
      aregj(jr,j,j_evap )=aregj(jr,j,j_evap )+aevap*ptype*dxyp(j)
      aregj(jr,j,j_erun)=aregj(jr,j,j_erun)+(aeruns+aerunu)*ptype*dxyp(j
     *     )
      aregj(jr,j,j_run )=aregj(jr,j,j_run )+(aruns+arunu)*ptype*dxyp(j)
      if ( moddsf == 0 ) then
        aregj(jr,j,j_tsrf )=aregj(jr,j,j_tsrf )+(ts-tf)*ptype*dxyp(j)
        aregj(jr,j,j_tg1 ) =aregj(jr,j,j_tg1 ) + tg1   *ptype*dxyp(j)
        aregj(jr,j,j_tg2 ) =aregj(jr,j,j_tg2 ) + tg2av *ptype*dxyp(j)
      end if

c**** quantities accumulated for latitude-longitude maps in diagij
      aij(i,j,ij_shdt)=aij(i,j,ij_shdt)+shdt*ptype
      aij(i,j,ij_beta)=aij(i,j,ij_beta)+abetad/nisurf
      IF (MODDSF.EQ.0) THEN
        AIJ(I,J,IJ_TRSDN)=AIJ(I,J,IJ_TRSDN)+TRHR(0,I,J)*PTYPE
        AIJ(I,J,IJ_TRSUP)=AIJ(I,J,IJ_TRSUP)+(TRHR(0,I,J)-TRHDT/DTSURF)
     *       *PTYPE
      END IF
      if(modrd.eq.0)aij(i,j,ij_trnfp0)=aij(i,j,ij_trnfp0)+trhdt*ptype
     *     /dtsrc
      aij(i,j,ij_srtr)=aij(i,j,ij_srtr)+(srhdt+trhdt)*ptype
      aij(i,j,ij_neth)=aij(i,j,ij_neth)+(srhdt+trhdt+shdt+evhdt)*ptype
      aij(i,j,ij_evap)=aij(i,j,ij_evap)+aevap*ptype
      if ( moddsf == 0 ) then
        aij(i,j,ij_ws)=aij(i,j,ij_ws)+ws*ptype
        aij(i,j,ij_ts)=aij(i,j,ij_ts)+(ts-tf)*ptype
        aij(i,j,ij_us)=aij(i,j,ij_us)+us*ptype
        aij(i,j,ij_vs)=aij(i,j,ij_vs)+vs*ptype
        aij(i,j,ij_taus)=aij(i,j,ij_taus)+rcdmws*ws*ptype
        aij(i,j,ij_tauus)=aij(i,j,ij_tauus)+rcdmws*(us)*ptype !-uocean
        aij(i,j,ij_tauvs)=aij(i,j,ij_tauvs)+rcdmws*(vs)*ptype !-vocean
        aij(i,j,ij_qs)=aij(i,j,ij_qs)+qs*ptype
        aij(i,j,ij_tg1)=aij(i,j,ij_tg1)+tg1*ptype
        aij(i,j,ij_pblht)=aij(i,j,ij_pblht)+dbl*ptype
        if(DDMS(I,J).lt.0.)   ! ddms < 0 for down draft
     *     AIJ(I,J,ij_mccon)=AIJ(I,J,ij_mccon)+ptype
        aij(i,j,ij_gusti)=aij(i,j,ij_gusti)+gusti*ptype
chyd       aij(i,j,ij_arunu)=aij(i,j,ij_arunu)
chyd      *  +   (40.6*psoil+.72*(2.*(tss-tfs)-(qsatss-qss)*lhe/sha))

#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
        aij(i,j,ij_wsgcm)=aij(i,j,ij_wsgcm)+wsgcm*ptype
        aij(i,j,ij_wspdf)=aij(i,j,ij_wspdf)+wspdf*ptype
        aij(i,j,ij_wdry)=aij(i,j,ij_wdry)+pbl_args%wsubwd*ptype
        aij(i,j,ij_wtke)=aij(i,j,ij_wtke)+pbl_args%wsubtke*ptype
        aij(i,j,ij_wmoist)=aij(i,j,ij_wmoist)+pbl_args%wsubwm*ptype
#endif

      endif

c**** quantities accumulated hourly for diagDD
      if ( moddd == 0 ) then
        do kr=1,ndiupt
          if(i.eq.ijdd(1,kr).and.j.eq.ijdd(2,kr)) then

            tmp(idd_ts)=+ts*ptype
            tmp(idd_tg1)=+(tg1+tf)*ptype
            tmp(idd_qs)=+qs*ptype
            tmp(idd_qg)=+qg*ptype
            tmp(idd_swg)=+srhdt*ptype
            tmp(idd_lwg)=+trhdt*ptype
            tmp(idd_sh)=+shdt*ptype
            tmp(idd_lh)=+evhdt*ptype
            tmp(idd_hz0)=
     *           +(srhdt+trhdt+shdt+evhdt)*ptype
            tmp(idd_ug)=+ug*ptype
            tmp(idd_vg)=+vg*ptype
            tmp(idd_wg)=+wg*ptype
            tmp(idd_us)=+us*ptype
            tmp(idd_vs)=+vs*ptype
            tmp(idd_ws)=+ws*ptype
            tmp(idd_cia)=+psi*ptype
            tmp(idd_cm)=+cdm*ptype
            tmp(idd_ch)=+cdh*ptype
            tmp(idd_cq)=+cdq*ptype
            tmp(idd_eds)=+khs*ptype
            tmp(idd_dbl)=+dbl*ptype
            tmp(idd_ev)=+aevap*ptype

            ADIURN_part(J,idx(:),kr)=ADIURN_part(J,idx(:),kr) +
     *           tmp(idx(:))
#ifndef NO_HDIURN
            HDIURN_part(J,idx(:),kr)=HDIURN_part(J,idx(:),kr) +
     *           tmp(idx(:))
#endif

#if (defined TRACERS_DUST) || (defined TRACERS_MINERALS) ||\
    (defined TRACERS_QUARZHEM)
            IF (adiurn_dust == 1) THEN
              tmp(idd_wsgcm)=+wsgcm*ptype
              tmp(idd_wspdf)=+wspdf*ptype
              tmp(idd_wtke)=+pbl_args%wsubtke*ptype
              tmp(idd_wd)=+pbl_args%wsubwd*ptype
              tmp(idd_wm)=+pbl_args%wsubwm*ptype
              tmp(idd_wtrsh)=+pbl_args%wtrsh*ptype
#ifdef TRACERS_DUST
              tmp(idd_emis)=0.D0
              tmp(idd_emis2)=0.D0
              tmp(idd_turb)=0.D0
              tmp(idd_grav)=0.D0
              DO n=1,Ntm_dust
                n1=n_clay+n-1
                tmp(idd_emis)=tmp(idd_emis)+pbl_args%dust_flux(n)*ptype
                tmp(idd_emis2)=tmp(idd_emis2)
     &               +pbl_args%dust_flux2(n)*ptype
#ifdef TRACERS_DRYDEP
                IF (dodrydep(n1)) THEN
                  tmp(idd_turb)=tmp(idd_turb)+ptype*rts_save(i,j)
     &                 *pbl_args%dep_vel(n1)
                  tmp(idd_grav)=tmp(idd_grav)+ptype*rts_save(i,j)
     &                 *pbl_args%gs_vel(n1)
                END IF
#endif
              END DO
              tmp(idd_ws2)=+ws*ws*ptype
              tmp(idd_ustar)=+pbl_args%ustar*ptype
              tmp(idd_us3)=+ptype*pbl_args%ustar*pbl_args%ustar
     &             *pbl_args%ustar
              tmp(idd_stress)=+rcdmws*ws*ptype
              tmp(idd_lmon)=+pbl_args%lmonin*ptype
              tmp(idd_rifl)=
     &             +ptype*grav*(ts-(tg1+tf))*pbl_args%zgs
     &             /(ws*ws*(tg1+tf))

              tmp(idd_zpbl1:idd_zpbl1+npbl-1)=ptype*pbl_args%z(1:npbl)
              tmp(idd_uabl1:idd_uabl1+npbl-1)=ptype*uabl(1:npbl,i,j
     *             ,itype)
              tmp(idd_vabl1:idd_vabl1+npbl-1)=ptype*vabl(1:npbl,i,j
     *             ,itype)
              tmp(idd_uvabl1:idd_uvabl1+npbl-1)=ptype*sqrt(
     *             uabl(1:npbl,i,j,itype)*uabl(1:npbl,i,j,itype)+
     *             vabl(1:npbl,i,j,itype)*vabl(1:npbl,i,j,itype))
              tmp(idd_tabl1:idd_tabl1+npbl-1)=ptype*tabl(1:npbl,i,j
     *             ,itype)
              tmp(idd_qabl1:idd_qabl1+npbl-1)=ptype*qabl(1:npbl,i,j
     *             ,itype)
              tmp(idd_zhat1:idd_zhat1+npbl-2)=ptype
     *             *pbl_args%zhat(1:npbl-1)
              tmp(idd_e1:idd_e1+npbl-2)=eabl(1:npbl-1,i,j,itype)*ptype
              tmp(idd_km1:idd_km1+npbl-2)=ptype*pbl_args%km(1:npbl-1)
              tmp(idd_ri1:idd_ri1+npbl-2)=ptype*pbl_args%gh(1:npbl-1)
     *             /(pbl_args%gm(1:npbl-1)+1d-20)
#endif

              ADIURN_part(J,idxd(:),kr)=ADIURN_part(J,idxd(:),kr) +
     *             tmp(idxd(:))
#ifndef NO_HDIURN
              HDIURN_part(J,idxd(:),kr)=HDIURN_part(J,idxd(:),kr) +
     *             tmp(idxd(:))
#endif
            END IF
#endif
          end if
        end do
      endif
c**** quantities accumulated for surface type tables in diagj
      aj(j,j_evap ,itearth)=aj(j,j_evap ,itearth)+ aevap*ptype
      aj(j,j_trhdt,itearth)=aj(j,j_trhdt,itearth)+trhdt*ptype
      aj(j,j_evhdt,itearth)=aj(j,j_evhdt,itearth)+evhdt*ptype
      aj(j,j_shdt ,itearth)=aj(j,j_shdt ,itearth)+ shdt*ptype
      aj(j,j_erun ,itearth)=aj(j,j_erun ,itearth)+(aeruns+aerunu)*ptype
      aj(j,j_run  ,itearth)=aj(j,j_run  ,itearth)+(aruns+arunu)*ptype
      if(moddsf.eq.0) then
        aj(j,j_tsrf,itearth)=aj(j,j_tsrf,itearth)+(ts-tf)*ptype
        aj(j,j_tg1 ,itearth)=aj(j,j_tg1 ,itearth)+    tg1*ptype
        aj(j,j_tg2 ,itearth)=aj(j,j_tg2 ,itearth)+  tg2av*ptype
        aj(j,j_type,itearth)=aj(j,j_type,itearth)+        ptype
      end if

      end subroutine ghy_diag

c***********************************************************************
c***********************************************************************
c***********************************************************************
c***********************************************************************
c***********************************************************************


      subroutine snow_cover( fract_snow, snow_water, top_dev ) 6,4
!@sum computes snow cover from snow water eq. and topography
!@var fract_snow snow cover fraction (0-1)
!@var snow_water snow water equivalent (m)
!@var top_dev standard deviation of the surface elevation
      use DOMAIN_DECOMP, only : GRID, GET
      use constant, only : teeny
      real*8, intent(out) :: fract_snow
      real*8, intent(in) :: snow_water, top_dev

      ! using formula from the paper by A. Roesch et al
      ! (Climate Dynamics (2001), 17: 933-946)
      fract_snow =
ccc     $     .95d0 * tanh( 100.d0 * snow_water ) *
ccc                               currently using only topography part
     $     sqrt ( 1000.d0 * snow_water /
     $     (1000.d0 * snow_water + teeny + snow_cover_coef * top_dev) )

      end subroutine snow_cover



      subroutine init_gh(dtsurf,redogh,inisnow,istart,nl_soil) 1,105
c**** modifications needed for split of bare soils into 2 types
      use filemanager
      use param
      use constant, only : twopi,rhow,edpery,sha,lhe,tf
      use DOMAIN_DECOMP, only : GRID, DIST_GRID
      use DOMAIN_DECOMP, only : GET,READT_PARALLEL, DREAD_PARALLEL
      use DOMAIN_DECOMP, only : CHECKSUM, HERE, CHECKSUM_COLUMN
      use DOMAIN_DECOMP, only : GLOBALSUM
      use model_com, only : fearth0,itime,nday,jeq,jyear,fland,flice
     &     ,focean
      use lakes_com, only : flake
      use diag_com, only : npts,icon_wtg,icon_htg,conpt0
      use sle001
#ifdef TRACERS_WATER
      use tracer_com, only : ntm,tr_wd_TYPE,nwater,itime_tr0,needtrs
      use fluxes, only : gtracer
      use veg_com, only:  afb, avh
#endif
      use fluxes, only : gtemp,gtempr
      use ghy_com
      use dynamics, only : pedn
      use snow_drvm, only : snow_cover_coef2=>snow_cover_coef
     &     ,snow_cover_same_as_rad
      use veg_drv, only : init_vegetation
      use veg_com, only : vdata

      implicit none

      real*8, intent(in) :: dtsurf
      integer, intent(in) :: istart
      logical, intent(in) :: redogh, inisnow
      integer, intent(out) :: nl_soil
      integer iu_soil,iu_top_index
      integer jday
      real*8 snowdp,wtr1,wtr2,ace1,ace2,tg1,tg2
      logical :: qcon(npts)
      integer i, j, ibv
      logical ghy_data_missing
      character conpt(npts)*10
#ifdef TRACERS_WATER
      real*8 trsoil_tot,wsoil_tot,fm
#endif
c****
cgsfc      REAL*8::TEMP_LOCAL(IM,GRID%J_STRT_HALO:GRID%J_STOP_HALO,11*NGM+1)
      REAL*8, Allocatable, DIMENSION(:,:,:) :: TEMP_LOCAL
c**** contents of TEMP_LOCAL used for reading the following in a block:
c****       1 -   ngm   dz(ngm)
c****   ngm+1 - 6*ngm   q(is,ngm)
c**** 6*ngm+1 - 11*ngm   qk(is,ngm)
c**** 11*ngm+1           sl
      real*8, external :: qsat
!@dbparam ghy_default_data if == 1 reset all GHY data to defaults
!@+ (do not read it from files)
      integer :: ghy_default_data = 0

      real*8 :: evap_max_ij_sum
C**** define local grid
      integer J_0, J_1
      integer J_0H, J_1H
      logical present_land
      integer init_flake
      integer kk

C****
C**** Extract useful local domain parameters from "grid"
C****
      CALL GET(grid, J_STRT=J_0, J_STOP=J_1,
     *               J_STRT_HALO=J_0H, J_STOP_HALO=J_1H)

c**** set conservation diagnostics for ground water mass and energy
      conpt=conpt0
      conpt(4)="EARTH"
      qcon=(/ .false., .false., .false., .true., .false., .false.
     $     , .false., .false., .true., .false., .false./)
      call set_con(qcon,conpt,"GRND WTR","(kg/m^2)        ",
     *     "(10^-9 kg/s/m^2)",1d0,1d9,icon_wtg)
      qcon=(/ .false., .false., .false., .true., .false., .false.
     $     , .false., .false., .true., .false., .false./)
      call set_con(qcon,conpt,"GRND ENG","(10**6 J/m^2)   ",
     *     "(10^-3 W/m^2)   ",1d-6,1d3,icon_htg)

c**** read rundeck parameters
      call sync_param( "snow_cover_coef", snow_cover_coef )
! hack. snow_cover_coef should be moved to snow_drvm
      snow_cover_coef2 = snow_cover_coef
      call sync_param( "snow_cover_same_as_rad", snow_cover_same_as_rad)
      call sync_param( "snoage_def", snoage_def )
      call sync_param( "wsn_max", wsn_max )
      call sync_param( "ghy_default_data", ghy_default_data )
      call  get_param( "variable_lk", variable_lk )
      call  get_param( "init_flake", init_flake )

c**** set number of layers for vegetation module
      nl_soil = ngm

c**** read land surface parameters or use defaults
      if ( ghy_default_data == 0 ) then ! read from files

        !!!if (istart.le.0) return ! avoid reading unneeded files
c**** read soils parameters
        call openunit("SOIL",iu_SOIL,.true.,.true.)
        ALLOCATE(TEMP_LOCAL(IM,J_0H:J_1H,11*NGM+1))
        call DREAD_PARALLEL(grid,iu_SOIL,NAMEUNIT(iu_SOIL),TEMP_LOCAL)
        DZ_IJ(:,:,:)   = TEMP_LOCAL(:,:,1:NGM)
         Q_IJ(:,J_0:J_1,:,:) = RESHAPE( TEMP_LOCAL(:,J_0:J_1,1+NGM:) ,
     *                   (/im,J_1-J_0+1,imt,ngm/) )
        QK_IJ(:,J_0:J_1,:,:) =
     *                 RESHAPE( TEMP_LOCAL(:,J_0:J_1,1+NGM+NGM*IMT:) ,
     *                   (/im,J_1-J_0+1,imt,ngm/) )
        SL_IJ(:,J_0:J_1)  = TEMP_LOCAL(:,J_0:J_1,1+NGM+NGM*IMT+NGM*IMT)
        DEALLOCATE(TEMP_LOCAL)
        call closeunit (iu_SOIL)
c**** read topmodel parameters
        call openunit("TOP_INDEX",iu_TOP_INDEX,.true.,.true.)
        call READT_PARALLEL
     *    (grid,iu_TOP_INDEX,NAMEUNIT(iu_TOP_INDEX),0,top_index_ij,1)
        call READT_PARALLEL
     *    (grid,iu_TOP_INDEX,NAMEUNIT(iu_TOP_INDEX),0,top_dev_ij  ,1)
        call closeunit (iu_TOP_INDEX)
      else  ! reset to default data
        if ( istart>0 .and. istart<8 ) then ! reset all
          call reset_gh_to_defaults( .true. )
        else   ! do not reset ghy prognostic variables
          call reset_gh_to_defaults( .false. )
        endif
        !!!if (istart.le.0) return
      endif

c****
c**** initialize constants
c****
c**** time step for ground hydrology
      dt=dtsurf
c spgsn is the specific gravity of snow
      spgsn=.1d0

c**** cosday, sinday should be defined (reset once a day in daily_earth)
      jday=1+mod(itime/nday,365)
      cosday=cos(twopi/edpery*jday)
      sinday=sin(twopi/edpery*jday)

ccc read and initialize vegetation here
      call init_vegetation(redogh,istart)

      ! no need to continue computations for postprocessing
      if (istart.le.0) return

c**** check whether ground hydrology data exist at this point.
      ghy_data_missing = .false.
      do j=J_0,J_1
        do i=1,im
          present_land = .false.
          if (variable_lk==0) then
            if ( fearth(i,j) > 0.d0 ) present_land = .true.
          else
            if ( focean(i,j) < 1.d0 ) present_land = .true.
          endif
          if ( present_land ) then
            if ( top_index_ij(i,j).eq.-1. ) then
              print *,"No top_index data: i,j=",i,j,top_index_ij(i,j)
              ghy_data_missing = .true.
            end if
            if ( sum(dz_ij(i,j,1:ngm)).eq.0 ) then
              print *, "No soil data: i,j=",i,j,dz_ij(i,j,1:ngm)
              ghy_data_missing = .true.
            endif
            if (w_ij(1,1,i,j)<1.d-10 .and. w_ij(1,2,i,j)<1.d-10) then
              print*,"No gh data in restart file: i,j=",i,j,
     &             w_ij(:,1,i,j),w_ij(:,2,i,j)
              ghy_data_missing = .true.
            endif
          end if
        enddo
      enddo
      if ( ghy_data_missing ) then
        write(6,*) 'Ground Hydrology data is missing at some pts'
        write(6,*) 'If you have a non-standard land mask, please'
        write(6,*) 'consider using extended GH data and rfs file.'
        call stop_model(
     &       'Ground Hydrology data is missing at some cells',255)
      endif


      call hl0

c****
c      print *,' '
c      print *,'soils parameters'
c      sdstnc=100.
c      print *,'interstream distance (m) sdstnc:',sdstnc
c      c1=90.
c      print *,'canopy conductance related parameter c1:',c1
c      prfr=.1d0
c      print *,'fraction (by area) of precipitation prfr:',prfr
c      print *,' '
c****
c code transplanted from subroutine input
c**** recompute ground hydrology data if necessary (new soils data)
      if (redogh) then
        !jday=1+mod(itime/nday,365)
        !cosday=cos(twopi/edpery*jday)
        !sinday=sin(twopi/edpery*jday)

        do j=J_0,J_1
        do i=1,im
          present_land = .false.
          if (variable_lk==0) then
            if ( fearth(i,j) > 0.d0 ) present_land = .true.
          else
            if ( focean(i,j) < 1.d0 ) present_land = .true.
          endif

          if( .not. present_land ) then

            w_ij(:,:,i,j)=0.
            ht_ij(:,:,i,j)=0.
            snowbv(:,i,j)=0.

          else
ccc   ??? remove next 5 lines? -check the old version
            !w(1:ngm,1) =   wbare(1:ngm,i,j)
            !w(0:ngm,2) =   wvege(0:ngm,i,j)
            !ht(0:ngm,1) = htbare(0:ngm,i,j)
            !ht(0:ngm,2) = htvege(0:ngm,i,j)
            w(0:ngm,1:LS_NFRAC) = w_ij(0:ngm,1:LS_NFRAC,i,j)
            ht(0:ngm,1:LS_NFRAC) = ht_ij(0:ngm,1:LS_NFRAC,i,j)
            snowd(1:2) =  snowbv(1:2,i,j)

c**** compute soil heat capacity and ground water saturation gws
            call ghinij (i,j)
c**** fill in soils common blocks
            snowdp=snowe(i,j)/rhow
            wtr1=wearth(i,j)
            ace1=aiearth(i,j)
            tg1 =tearth(i,j)
            wtr2=wtr1
            ace2=ace1
            tg2 =tg1
c           wtr2=gdata(i,j,9)   ! this cannot be right
c           ace2=gdata(i,j,10)
c           tg2 =gdata(i,j,8)
            call ghinht (snowdp, tg1,tg2, wtr1,wtr2, ace1,ace2)

c**** copy soils prognostic quantities to model variables
            w_ij(0:ngm,1:LS_NFRAC,i,j) = w(0:ngm,1:LS_NFRAC)
            ht_ij(0:ngm,1:LS_NFRAC,i,j) = ht(0:ngm,1:LS_NFRAC)
            snowbv(1:2,i,j)   = snowd(1:2)
          end if
        end do
        end do
        write (*,*) 'ground hydrology data was made from ground data'
      end if
c**** set gtemp array
      do j=J_0,J_1
        do i=1,im
          if (fearth(i,j).gt.0) then
            gtemp(1,4,i,j)=tearth(i,j)
            gtempr(4,i,j) =tearth(i,j)+tf
          end if
        end do
      end do

C GISS-ESMF EXCEPTIONAL CASE
C-BMP Global sum on evap_max_ij

ccc if not initialized yet, set evap_max_ij, fr_sat_ij, qg_ij
ccc to something more appropriate

      call globalsum(grid, evap_max_ij,evap_max_ij_sum,
     &                all=.true.)
      if ( evap_max_ij_sum > im-1.d0 ) then ! old default
        do j=J_0,J_1
          do i=1,im
            if ( fearth(i,j) .le. 0.d0 ) cycle
            qg_ij(i,j) = qsat(tearth(i,j)+tf,lhe,pedn(1,i,j))
          enddo
        enddo
        fr_sat_ij(:,:) = 0.d0
        evap_max_ij(:,:) = 0.d0
      endif

ccc   init snow here
ccc hope this is the right place to split first layer into soil
ccc and snow  and to set snow arrays
ccc!!! this should be done only when restarting from an old
ccc!!! restart file (without snow model data)

      if (inisnow) then
        do j=J_0,J_1
        do i=1,im
          present_land = .false.
          if (variable_lk==0) then
            if ( fearth(i,j) > 0.d0 ) present_land = .true.
          else
            if ( focean(i,j) < 1.d0 ) present_land = .true.
          endif
          if( .not. present_land ) then
            nsn_ij(:,i,j)     = 1
            !isn_ij(:,i,j)     = 0
            dzsn_ij(:,:,i,j)  = 0.
            wsn_ij(:,:,i,j)   = 0.
            hsn_ij(:,:,i,j)   = 0.
            fr_snow_ij(:,i,j) = 0.
          else
            !jday=1+mod(itime/nday,365)
            !cosday=cos(twopi/edpery*jday)
            !sinday=sin(twopi/edpery*jday)

            !w(1:ngm,1) =   wbare(1:ngm,i,j)
            !w(0:ngm,2) =   wvege(0:ngm,i,j)
            !ht(0:ngm,1) = htbare(0:ngm,i,j)
            !ht(0:ngm,2) = htvege(0:ngm,i,j)
            w(0:ngm,1:LS_NFRAC) = w_ij(0:ngm,1:LS_NFRAC,i,j)
            ht(0:ngm,1:LS_NFRAC) = ht_ij(0:ngm,1:LS_NFRAC,i,j)
            snowd(1:2) =  snowbv(1:2,i,j)

            call ghinij (i,j)
            call set_snow

!!!! hack
!            do kk=1,6
!              do ibv=1,LS_NFRAC
!                if ( w(kk,ibv) < thetm(kk,ibv)*dz(kk) ) then
!                  print *,"corrected w ",i,j,kk,ibv, w(kk,ibv)
!                  w(kk,ibv) = thetm(kk,ibv)*dz(kk)
!                endif
!                print *,i,j,kk,ibv, w(kk,ibv),thetm(kk,ibv)*dz(kk)
!              enddo
!            enddo

            nsn_ij    (1:2, i, j)         = nsn(1:2)
            !isn_ij    (1:2, i, j)         = isn(1:2)
            dzsn_ij   (1:nlsn, 1:2, i, j) = dzsn(1:nlsn,1:2)
            wsn_ij    (1:nlsn, 1:2, i, j) = wsn(1:nlsn,1:2)
            hsn_ij    (1:nlsn, 1:2, i, j) = hsn(1:nlsn,1:2)
            fr_snow_ij(1:2, i, j)         = fr_snow(1:2)

c****     copy soils prognostic quantities to model variables
            ! wbare(1:ngm,i,j) = w(1:ngm,1)
            ! wvege(0:ngm,i,j) = w(0:ngm,2)
            !htbare(0:ngm,i,j) = ht(0:ngm,1)
            !htvege(0:ngm,i,j) = ht(0:ngm,2)
            w_ij (0:ngm,1:LS_NFRAC,i,j) = w (0:ngm,1:LS_NFRAC)
            ht_ij(0:ngm,1:LS_NFRAC,i,j) = ht(0:ngm,1:LS_NFRAC)
            snowbv(1:2,i,j)   = snowd(1:2)

          end if
        end do
        end do
      end if

!!! hack - remove underwater snow
!!! (should not be present in restart file in the first place!)
      do j=J_0,J_1
        do i=1,im
          if ( fearth(i,j) == 0.d0 ) then
            if ( maxval(fr_snow_ij(:,i,j)) > 0.d0 ) then
              print *,"removing snow from ",i,j," : cell under water"
            endif
            nsn_ij(:, i, j) = 1
            wsn_ij(:, :, i, j) = 0.d0
            hsn_ij(:, :, i, j) = 0.d0
            dzsn_ij(:, :, i, j) = 0.d0
            fr_snow_ij(:, i, j) = 0.d0
          endif
        enddo
      enddo

c**** set snow fraction for albedo computation (used by RAD_DRV.f)
      fr_snow_rad_ij(:,:,:) = 0.d0
      do j=J_0,J_1
        do i=1,im
          if ( fearth(i,j) > 0.d0 ) then
            do ibv=1,2
              call snow_cover(fr_snow_rad_ij(ibv,i,j),
     &             snowbv(ibv,i,j), top_dev_ij(i,j) )
              fr_snow_rad_ij(ibv,i,j) = min (
     &             fr_snow_rad_ij(ibv,i,j), fr_snow_ij(ibv, i, j) )
            enddo
          endif
        enddo
      enddo

      jday=1+mod(itime/nday,365)
      ! initialize underwater fraction for variable lakes
      if ( init_flake > 0 .and. variable_lk > 0 .and. istart < 9 )
     &     call init_underwater_soil

      ! land water deficit for changing lake fractions
      call compute_water_deficit

#ifdef TRACERS_WATER
ccc still not quite correct (assumes fw=1)
      do j=J_0,J_1
        do i=1,im
          gtracer(:,4,i,j)=0.  ! default
          if (fearth(i,j).le.0.d0) cycle
          fb=afb(i,j) ; fv=1.-fb
          fm=1.d0-exp(-snowbv(2,i,j)/((avh(i,j)*spgsn) + 1d-12))
          if ( fm < 1.d-3 ) fm=0.d0
          wsoil_tot=fb*( w_ij(1,1,i,j)*(1.d0-fr_snow_ij(1,i,j))
     &     + wsn_ij(1,1,i,j)*fr_snow_ij(1,i,j) )
     &     + fv*( w_ij(0,2,i,j)*(1.d0-fm*fr_snow_ij(2,i,j))   !*1.d0
     &     + wsn_ij(1,2,i,j)*fm*fr_snow_ij(2,i,j) )
          do n=1,ntm
            if (itime_tr0(n).gt.itime) cycle
            if ( .not. needtrs(n) ) cycle
            ! should also restrict to TYPE=nWATER ?
            if ( wsoil_tot > 1.d-30 ) then
            gtracer(n,4,i,j) = (
     &           fb*( tr_w_ij(n,1,1,i,j)*(1.d0-fr_snow_ij(1,i,j))
     &           + tr_wsn_ij(n,1,1,i,j) )         !*fr_snow_ij(1,i,j)
     &           + fv*( tr_w_ij(n,0,2,i,j)*(1.d0-fm*fr_snow_ij(2,i,j))
     &           + tr_wsn_ij(n,1,2,i,j)*fm ) )    !*fr_snow_ij(2,i,j)
     &           /(rhow*wsoil_tot)
            else
              gtracer(n,4,i,j) = 0.
            end if
          enddo
        end do
      end do
#endif

      return
      end subroutine init_gh



      subroutine reset_gh_to_defaults( reset_prognostic ) 4,9
      !use model_com, only: vdata
      USE DOMAIN_DECOMP, ONLY : GRID, GET
      use ghy_com
      use veg_drv, only : reset_veg_to_defaults
      logical, intent(in) :: reset_prognostic
      integer i,j

C**** define local grid
      integer J_0, J_1

C****
C**** Extract useful local domain parameters from "grid"
C****
      CALL GET(grid, J_STRT=J_0, J_STOP=J_1)

ccc ugly, should fix later
      call reset_veg_to_defaults( reset_prognostic )

      do j=J_0,J_1
      do i=1,im

      dz_ij(i,j,1:ngm)= (/  0.99999964d-01,  0.17254400d+00,
     &     0.29771447d+00,  0.51368874d+00,  0.88633960d+00,
     &     0.15293264d+01 /)
      q_ij(i,j,1:imt,1:ngm)=
     &     reshape( (/  0.33491623d+00,  0.52958947d+00,
     &     0.13549370d+00,  0.00000000d+00,  0.00000000d+00,
     &     0.32995611d+00,  0.52192056d+00,  0.14812243d+00,
     &     0.00000000d+00,  0.00000000d+00,  0.32145596d+00,
     &     0.48299056d+00,  0.19555295d+00,  0.00000000d+00,
     &     0.00000000d+00,  0.47638881d+00,  0.40400982d+00,
     &     0.11959970d+00,  0.00000000d+00,  0.00000000d+00,
     &     0.99985123d-01,  0.95771909d-01,  0.41175738d-01,
     &     0.00000000d+00,  0.76306665d+00,  0.00000000d+00,
     &     0.00000000d+00,  0.00000000d+00,  0.00000000d+00,
     &     0.10000000d+01 /), (/imt,ngm/) )
      qk_ij(i,j,1:imt,1:ngm)=
     &     reshape( (/  0.34238762d+00,  0.52882469d+00,
     &     0.12878728d+00,  0.00000000d+00,  0.00000000d+00,
     &     0.32943058d+00,  0.52857041d+00,  0.14199871d+00,
     &     0.00000000d+00,  0.00000000d+00,  0.30698991d+00,
     &     0.52528000d+00,  0.16772974d+00,  0.00000000d+00,
     &     0.00000000d+00,  0.39890009d+00,  0.43742162d+00,
     &     0.16367787d+00,  0.00000000d+00,  0.00000000d+00,
     &     0.46536058d+00,  0.39922065d+00,  0.13541836d+00,
     &     0.00000000d+00,  0.00000000d+00,  0.00000000d+00,
     &     0.00000000d+00,  0.00000000d+00,  0.00000000d+00,
     &     0.10000000d+01 /), (/imt,ngm/) )
      sl_ij(i,j)= 0.22695422d+00
      top_index_ij(i,j)= 0.10832934d+02
      top_dev_ij(i,j)= 0.21665636d+03

      if ( .not. reset_prognostic ) cycle

      snowe(i,j)= 0.65458111d-01
      tearth(i,j)= -0.12476520d+00
      wearth(i,j)=  0.29203081d+02
      aiearth(i,j)=  0.93720329d-01
      w_ij(:,1,i,j) = (/0.d0,  0.17837750d-01,  0.40924843d-01,
     &     0.77932012d-01,  0.11919649d+00,  0.57237469d-01,
     &     0.10000000d-11 /)
      w_ij(:,2,i,j) = (/  0.10000000d-11,  0.29362259d-01,
     &     0.50065177d-01,  0.82533140d-01,  0.10383620d+00,
     &     0.31552459d-01,  0.10000000d-11 /)
      ht_ij(:,1,i,j)= (/  0.00000000d+00, -0.15487181d+07,
     &     -0.50720067d+07,  0.18917623d+07,  0.77174974d+07,
     &     0.21716040d+08,  0.44723067d+08 /)
      ht_ij(:,2,i,j)= (/ -0.13991376d+05, -0.53165599d+05,
     &     0.65443775d+06,  0.29276050d+07,  0.81455096d+07,
     &     0.21575081d+08,  0.45952255d+08 /)
      snowbv(:,i,j)= (/  0.00000000d+00,  0.65458111d-04 /)

      enddo
      enddo

      end subroutine reset_gh_to_defaults



      subroutine ghinij (i0,j0) 8,14
c**** input:
c**** avh(i,j) - array of vegetation heights
c**** spgsn - specific gravity of snow
c**** output:
c**** vh - vegetation height
c**** snowm - snow masking depth
c**** wfcap - water field capacity of top soil layer, m
c****
      use snow_model, only : i_earth,j_earth
      use sle001, only : dz,qk,ng,zb,zc,q,sl,xklh !spgsn,
     *     ,fb,fv,prs,ijdebug,n
     *     ,thets,thetm,ws,thm,nth,shc,shw,htprs,pr !shcap,shtpr,
     *     ,htpr
     *     ,top_index,top_stdev
     &     ,w,ht,snowd,nsn,dzsn,wsn,hsn,fr_snow
      use ghy_com, only : ngm,imt,nlsn,LS_NFRAC,dz_ij,sl_ij,q_ij,qk_ij
     *     ,top_index_ij,top_dev_ij
     &     ,w_ij,ht_ij,snowbv,nsn_ij,dzsn_ij,wsn_ij
     &     ,hsn_ij,fr_snow_ij,shc_soil_texture
      use veg_com, only: afb
      USE DOMAIN_DECOMP, ONLY : GRID, GET
!      use veg_drv, only : veg_set_cell

      implicit none
      integer i0,j0
!      real*8 wfcap
      integer k,ibv,i
      real*8 shtpr
!----------------------------------------------------------------------!
      !real*8, parameter :: shcap(imt) = (/2d6,2d6,2d6,2.5d6,2.4d6/)


      ijdebug=i0*1000+j0
      i_earth = i0
      j_earth = j0

ccc extracting ghy prognostic vars
      !w(1:ngm,1) =  wbare(1:ngm,i0,j0)
      !w(0:ngm,2) =  wvege(0:ngm,i0,j0)
      !ht(0:ngm,1) = htbare(0:ngm,i0,j0)
      !ht(0:ngm,2) = htvege(0:ngm,i0,j0)
      w(0:ngm,1:LS_NFRAC) = w_ij(0:ngm,1:LS_NFRAC,i0,j0)
      ht(0:ngm,1:LS_NFRAC) = ht_ij(0:ngm,1:LS_NFRAC,i0,j0)
      snowd(1:2)  = snowbv(1:2,i0,j0)
ccc extracting snow variables
      nsn(1:2)          = nsn_ij    (1:2, i0, j0)
      !isn(1:2)          = isn_ij    (1:2, i0, j)
      dzsn(1:nlsn, 1:2) = dzsn_ij   (1:nlsn, 1:2, i0, j0)
      wsn(1:nlsn, 1:2)  = wsn_ij    (1:nlsn, 1:2, i0, j0)
      hsn(1:nlsn, 1:2)  = hsn_ij    (1:nlsn, 1:2, i0, j0)
      fr_snow(1:2)      = fr_snow_ij(1:2, i0, j0)

ccc setting vegetation
 !     call veg_set_cell(i0,j0)

ccc passing topmodel parameters
      top_index = top_index_ij(i0, j0)
      top_stdev = top_dev_ij(i0, j0)
c**** set up layers
      dz(1:ngm)=dz_ij(i0,j0,1:ngm)
      q(1:imt,1:ngm)=q_ij(i0,j0,1:imt,1:ngm)
      qk(1:imt,1:ngm)=qk_ij(i0,j0,1:imt,1:ngm)
      sl=sl_ij(i0,j0)

      n=0
      do k=1,ngm
        if(dz(k).le.0.) exit
        n=k
      end do

      if(n.le.0) then
         write (99,*) 'ghinij:  n <= 0:  i,j,n=',i0,j0,n,(dz(k),k=1,43)
         call stop_model('stopped in GHY_DRV.f',255)
      end if

c**** calculate the boundaries, based on the thicknesses.
      zb(1)=0.
      do k=1,n
        zb(k+1)=zb(k)-dz(k)
      end do
c**** calculate the layer centers, based on the boundaries.
      do k=1,n
        zc(k)=.5*(zb(k)+zb(k+1))
      end do
c**** fb,fv: bare, vegetated fraction (1=fb+fv)
      fb=afb(i0,j0)
      fv=1.-fb

c****
      do ibv=1,2
        do k=1,n
          thets(k,ibv)=0.
          thetm(k,ibv)=0.
          do i=1,imt-1
            thets(k,ibv)=thets(k,ibv)+q(i,k)*thm(0,i)
            thetm(k,ibv)=thetm(k,ibv)+q(i,k)*thm(nth,i)
          end do
          ws(k,ibv)=thets(k,ibv)*dz(k)
        end do
      end do
!veg      ws(0,2)=.0001d0*alai  ! from call veg_set_cell above
  !    wfcap=fb*ws(1,1)+fv*(ws(0,2)+ws(1,2))
c****
      call xklh(1)
c****

      do ibv=1,2
        do k=1,n
          shc(k,ibv)=0.
          do i=1,imt
            shc(k,ibv)=shc(k,ibv)+q(i,k)*shc_soil_texture(i)
          end do
          shc(k,ibv)=(1.-thets(k,ibv))*shc(k,ibv)*dz(k)
        end do
      end do
c****
c shc(0,2) is the heat capacity of the canopy
!veg      aa=ala(1,i0,j0)
!veg      shc(0,2)=(.010d0+.002d0*aa+.001d0*aa**2)*shw
c****
c htpr is the heat of precipitation.
c shtpr is the specific heat of precipitation.
      shtpr=0.
      if(pr.gt.0.)shtpr=htpr/pr
c htprs is the heat of large scale precipitation
      htprs=shtpr*prs
c****
      return
      end subroutine ghinij



      subroutine ghy_save_cell(i,j) 2,4
      use sle001, only : w,ht,snowd,nsn,dzsn,wsn,hsn,fr_snow
      use ghy_com, only : ngm,nlsn,LS_NFRAC
     &     ,dz_ij,w_ij,ht_ij,snowbv
     &     ,nsn_ij,dzsn_ij,wsn_ij,hsn_ij,fr_snow_ij
      implicit none
      integer, intent(in) :: i,j

      !wbare(1:ngm,i,j) = w(1:ngm,1)
      !wvege(0:ngm,i,j) = w(0:ngm,2)
      !htbare(0:ngm,i,j) = ht(0:ngm,1)
      !htvege(0:ngm,i,j) = ht(0:ngm,2)
      w_ij (0:ngm,1:LS_NFRAC,i,j) = w (0:ngm,1:LS_NFRAC)
      ht_ij(0:ngm,1:LS_NFRAC,i,j) = ht(0:ngm,1:LS_NFRAC)
      snowbv(1:2,i,j)   = snowd(1:2)
ccc copy snow variables back to storage
      nsn_ij    (1:2, i, j)         = nsn(1:2)
      !isn_ij    (1:2, i, j)         = isn(1:2)
      dzsn_ij   (1:nlsn, 1:2, i, j) = dzsn(1:nlsn,1:2)
      wsn_ij    (1:nlsn, 1:2, i, j) = wsn(1:nlsn,1:2)
      hsn_ij    (1:nlsn, 1:2, i, j) = hsn(1:nlsn,1:2)
      fr_snow_ij(1:2, i, j)         = fr_snow(1:2)

      end subroutine ghy_save_cell



      subroutine ghinht (snowdp,tg1,tg2,wtr1,wtr2,ace1,ace2) 2,4
c**** initializes new ground (w,ht,snw) from old (t,w,ice,snw)
c**** evaluates the heat in the soil layers based on the
c**** temperatures.
c**** input:
c**** w - water in soil layers, m
c**** tp - temperature of layers, c
c**** fice - fraction of ice of layers
c**** fsn - heat of fusion of water
c**** shc - specific heat capacity of soil
c**** shi - specific heat capacity of ice
c**** shw - specific heat capcity of water
c**** snowd - snow depth, equivalent water m
c**** output:
c**** ht - heat in soil layers
c**** add calculation of wfc2
c**** based on combination of layers 2-n, as in retp2
      use sle001, only : tp, ht, w, shc, fice, snowd, ws, fb, fv,
     &    n, dz, fsn, thetm, shi, shw, ijdebug
      USE DOMAIN_DECOMP, ONLY : GRID, GET
      implicit none

      real*8 snowdp,tg1,tg2,wtr1,wtr2,ace1,ace2
      real*8 wfc1, wfc2, wet1, wet2, wmin, fbv
      integer k, ibv, ll

      wfc1=fb*ws(1,1)+fv*(ws(0,2)+ws(1,2))
      wfc2=0.
      fbv=fb
      do 30 ibv=1,2
      do 20 k=2,n
      wfc2=wfc2+fbv*ws(k,ibv)
   20 continue
      fbv=fv
   30 continue
      wfc1=1000.*wfc1
      wfc2=1000.*wfc2
      fice(0,2)=1.
      fice(1,1)=(ace1+snowdp*1000.)/(wtr1+ace1+snowdp*1000.+1.d-20)
      fice(1,2)=fice(1,1)
      tp(0,2)=tg1
c**** w = snow(if top layer) + wmin + (wmax-wmin)*(wtr+ice)/wfc
      w(0,2)=0.
      do ibv=1,2
        w(1,ibv)=snowdp
        wmin=thetm(1,ibv)*dz(1)
        wet1=(wtr1+ace1)/(wfc1+1.d-20)
        if(wet1.gt.1.) wet1=1.
        w(1,ibv)=w(1,ibv)+wmin+(ws(1,ibv)-wmin)*wet1
        snowd(ibv)=snowdp
        tp(1,ibv)=tg1
        do k=2,n
          fice(k,ibv)=ace2/(wtr2+ace2+1.d-20)
          wmin=thetm(k,ibv)*dz(k)
          wet2=(wtr2+ace2)/(wfc2+1.d-20)
          if(wet2.gt.1.) wet2=1.
          w(k,ibv)=wmin+(ws(k,ibv)-wmin)*wet2
          tp(k,ibv)=tg2
        end do
      end do
c****
!!!      entry ghexht
c****
c**** compute ht (heat w/m+2)
      do ibv=1,2
        ll=2-ibv
        do k=ll,n
          if(tp(k,ibv)) 2,4,6
 2        ht(k,ibv)=tp(k,ibv)*(shc(k,ibv)+w(k,ibv)*shi)-w(k,ibv)*fsn
          cycle
 4        ht(k,ibv)=-fice(k,ibv)*w(k,ibv)*fsn
          cycle
 6        ht(k,ibv)=tp(k,ibv)*(shc(k,ibv)+w(k,ibv)*shw)
        end do
      end do
      if(ijdebug.eq.0)then
       write(99,*)'ghinht id check',ijdebug
       write(99,*)'tg1,tg2',tg1,tg2
       write(99,*)'tp',tp
       write(99,*)'ht',ht
       write(99,*)'w',w
       write(99,*)'wtr1,wtr2',wtr1,wtr2
       write(99,*)'ace1,ace2',ace1,ace2
       write(99,*)'wfc1,wfc2',wfc1,wfc2
       write(99,*)'shc',shc
       write(99,*)'fice',fice
      endif
      return
      end subroutine ghinht


      subroutine retp2 (tg2av,wtr2av,ace2av) 2,4
c**** evaluates the mean temperature in the soil layers 2-ngm
c**** as well as the water and ice content.
c**** input:
c**** w - water in soil layers, m
c**** ht - heat in soil layers
c**** fsn - heat of fusion of water
c**** shc - specific heat capacity of soil
c**** shi - specific heat capacity of ice
c**** shw - specific heat capcity of water
c**** output:
c**** tg2av - temperature of layers 2 to ngm, c
c**** ice2av - ice amount in layers 2 to ngm, kg/m+2
c**** wtr2av - water in layers 2 to ngm, kg/m+2
      USE DOMAIN_DECOMP, ONLY : GRID, GET
      use sle001
      implicit none
      real*8 tg2av,wtr2av,ace2av, wc,htc,shcc,tpc,ficec,ftp
      integer k, ibv
      tg2av=0.
      wtr2av=0.
      ace2av=0.
      do 3500 ibv=1,2
      wc=0.
      htc=0.
      shcc=0.
      do k=2,n
        wc=wc+w(k,ibv)
        htc=htc+ht(k,ibv)
        shcc=shcc+shc(k,ibv)
      end do
      tpc=0.
      ficec=0.
      if(wc.ne.0.)  ficec=-htc/(fsn*wc)
      if(fsn*wc+htc.ge.0.)go to 3430
      tpc=(htc+wc*fsn)/(shcc+wc*shi)
      ficec=1.
      go to 3440
 3430 if(htc.le.0.) go to 3440
      tpc=htc/(shcc+wc*shw)
      ficec=0.
 3440 continue
      ftp=fb
      if(ibv.eq.2) ftp=fv
      tg2av=tg2av+tpc*ftp
      wtr2av=wtr2av+wc*ftp*1000.*(1.-ficec)
      ace2av=ace2av+wc*ftp*1000.*ficec
 3500 continue
      return
      end subroutine retp2


      subroutine checke(subr) 1,22
!@sum  checke checks whether arrays are reasonable over earth
!@auth original development team
!@ver  1.0
      use model_com, only : itime,wfcs
      use geom, only : imaxj
      use constant, only : rhow
      use veg_com, only : afb
      use ghy_com, only : tearth,wearth,aiearth,snowe,w_ij,ht_ij
     *     ,snowbv,ngm,fearth,wsn_ij,fr_snow_ij,nsn_ij,LS_NFRAC
#ifdef TRACERS_WATER
     &     ,tr_w_ij,tr_wsn_ij
      USE TRACER_COM, only : ntm, trname, t_qlimit
#endif
      USE DOMAIN_DECOMP, ONLY : GRID, GET
      implicit none
!@var subr identifies where check was called from
      character*6, intent(in) :: subr

      real*8 x,tgl,wtrl,acel
      integer i,j,imax,jmax,n,nsb,nsv
      real*8, parameter :: EPS=1.d-12
      logical QCHECKL
      real*8 relerr, errmax, fb, fv

C**** define local grid
      integer I_0, I_1
      integer J_0, J_1

      QCHECKL = .false.
C****
C**** Extract useful local domain parameters from "grid"
C****
      CALL GET(grid, I_STRT=I_0, I_STOP=I_1, J_STRT=J_0, J_STOP=J_1)

c**** check for nan/inf in earth data
c      call check3b(w_ij(1,1,1,1 ,ngm  ,
c     *                 IM,J_0,J_1,JM,subr,'wb')
c      call check3b(w_ij(0,2,I_0:I_1,J_0:J_1) ,ngm+1,
c     *                 IM,J_0,J_1,JM,subr,'wv')
c      call check3b(ht_ij(0,1,1,J_0),ngm+1,
c     *                 IM,J_0,J_1,JM,subr,'hb')
c      call check4b(ht_ij(0,2,1,J_0),ngm+1,2,
c     *                 IM,J_0,J_1,JM,subr,'hv')
c      call check3b(snowbv(1,1,J_0),LS_NFRAC,
c     *                 IM,J_0,J_1,JM,subr,'sn')

c**** check for reasonable temperatures over earth
      x=1.001
      do j=J_0,J_1
        do i=1,imaxj(j)
          if (fearth(i,j).gt.0.) then
            tgl=tearth(i,j)
            wtrl=wearth(i,j)
            acel=aiearth(i,j)
            if ((tgl+60.)*(60.-tgl).le.0.) write (6,901) subr,i,j,itime
     *           ,fearth(i,j),'tg1 ',snowe(i,j),tgl,wtrl,acel
            if (wtrl.lt.0..or.acel.lt.0..or.(wtrl+acel).gt.x*wfcs(i
     *           ,j)) write(6,901) subr,i,j,itime,fearth(i,j),'wtr '
     *           ,snowe(i,j),tgl,wtrl,acel,wfcs(i,j)
          end if
        end do
      end do

      !print *,"checke: w(51,33) ", w_ij(:,:,51,33)
      !print *,"checke: fearth(51,33) ", fearth(51,33),afb(51,33)


c**** check tracers
#ifdef TRACERS_WATER
      do n=1,ntm
        ! check for neg tracers
        if (t_qlimit(n)) then
          do j=J_0, J_1
            do i=1,imaxj(j)
              if ( fearth(i,j) <= 0.d0 ) cycle
              if ( minval( tr_w_ij(n,:,:,i,j)   ) < -1.d15 .or.
     &             minval( tr_wsn_ij(n,:,:,i,j) ) < -1.d15 ) then
                print*,"Neg tracer in earth after ",SUBR,i,j,trname(n)
     &               , "tr_soil= ", tr_w_ij(n,:,:,i,j)
     &               , "TR_SNOW= ", tr_wsn_ij(n,:,:,i,j)
                QCHECKL=.TRUE.
              end if

            end do
          end do
        end if

        ! check if water == water
        if (trname(n) == 'Water') then
          errmax = 0. ; imax=1 ; jmax=1
          do j=J_0, J_1
            do i=1,imaxj(j)
              if ( fearth(i,j) <= 0.d0 ) cycle
              fb = afb(i,j)
              fv = 1.d0 - fb
              relerr= ( fb*sum(abs(
     &             tr_w_ij(n,1:ngm,1,i,j) - w_ij(1:ngm,1,i,j)*rhow))
     &             + fv*sum(abs(
     &             tr_w_ij(n,0:ngm,2,i,j) - w_ij(0:ngm,2,i,j)*rhow)) )
     &             /(  rhow*( fb*sum(w_ij(1:ngm,1,i,j))
     &             + fv*sum(w_ij(0:ngm,2,i,j)) ) + EPS  )
              if (relerr > errmax) then
                imax=i ; jmax=j ; errmax=relerr
              end if
            enddo
          enddo
          fb = afb(imax,jmax)
          fv = 1.d0 - fb
          print*,"Relative error in soil after ",trim(subr),":"
     &         ,imax,jmax,errmax
     &         ,( tr_w_ij(n,1:ngm,1,imax,jmax)
     &         - w_ij(1:ngm,1,imax,jmax)*rhow )*fb
     &         ,( tr_w_ij(n,0:ngm,2,imax,jmax)
     &         - w_ij(0:ngm,2,imax,jmax)*rhow )*fv
     &         , rhow*( fb*sum(w_ij(1:ngm,1,imax,jmax))
     &         +        fv*sum(w_ij(0:ngm,2,imax,jmax)) )
cddd     &         ,w_ij(1:ngm,1,imax,jmax)*rhow
cddd     &         ,w_ij(0:ngm,2,imax,jmax)*rhow

          errmax = 0. ; imax=1 ; jmax=1
          do j=J_0, J_1
            do i=1,imaxj(j)
              if ( fearth(i,j) <= 0.d0 ) cycle
              fb = afb(i,j)
              fv = 1.d0 - fb
              nsb = nsn_ij(1,i,j)
              nsv = nsn_ij(2,i,j)
              relerr= ( fb*sum(abs( tr_wsn_ij(n,1:nsb,1,i,j)
     &             - wsn_ij(1:nsb,1,i,j)*rhow*fr_snow_ij(1,i,j) ))
     &             + fv*sum(abs( tr_wsn_ij(n,1:nsv,2,i,j)
     &             - wsn_ij(1:nsv,2,i,j)*rhow*fr_snow_ij(2,i,j))) )
     &             /(rhow*(
     &             fb*sum(wsn_ij(1:nsb,1,i,j))*fr_snow_ij(1,i,j) +
     &             fv*sum(wsn_ij(1:nsv,2,i,j))*fr_snow_ij(2,i,j) ) +EPS)
              if (relerr > errmax) then
                imax=i ; jmax=j ; errmax=relerr
              end if
            enddo
          enddo
          fb = afb(imax,jmax)
          fv = 1.d0 - fb
          nsb = nsn_ij(1,imax,jmax)
          nsv = nsn_ij(2,imax,jmax)
          print*,"Relative error in snow after ",trim(subr),":"
     &         ,imax,jmax,errmax
     &         ,( tr_wsn_ij(n,1:nsb,1,imax,jmax)
     &         - wsn_ij(1:nsb,1,imax,jmax)*rhow
     &         *fr_snow_ij(1,imax,jmax) )*fb
     &         ,( tr_wsn_ij(n,1:nsv,2,imax,jmax)
     &         - wsn_ij(1:nsv,2,imax,jmax)*rhow
     &         *fr_snow_ij(2,imax,jmax) )*fv
     &         ,rhow*( fb*sum(wsn_ij(1:nsb,1,imax,jmax))
     &         * fr_snow_ij(1,imax,jmax)
     &         +       fv*sum(wsn_ij(1:nsv,2,imax,jmax))
     &         * fr_snow_ij(2,imax,jmax) )

cddd     &         ,wsn_ij(1:nsn_ij(1,imax,jmax),1,imax,jmax)*rhow
cddd     &         *fr_snow_ij(1,imax,jmax)
cddd     &         ,wsn_ij(1:nsn_ij(1,imax,jmax),2,imax,jmax)*rhow
cddd     &         *fr_snow_ij(2,imax,jmax)



        endif
      enddo
#endif

      IF (QCHECKL)
     &     call stop_model('CHECKL: Earth variables out of bounds',255)

      return
 901  format ('0gdata off, subr,i,j,i-time,pearth,',a7,2i4,i10,f5.2,1x
     *     ,a4/' snw,x,tg1,wtr1,ice1, wfc1 ',6f12.4)

      end subroutine checke


      subroutine daily_earth(end_of_day) 2,40
!@sum  daily_earth performs daily tasks for earth related functions
!@auth original development team
!@ver  1.0
!@calls RDLAI
      use constant, only : rhow,twopi,edpery,tf
      use model_com, only : nday,nisurf,jday,jyear,wfcs,focean
      use veg_com, only : vdata                 !nyk
      use geom, only : imaxj
      use diag_com, only : aij=>aij_loc
     *     ,tdiurn,ij_strngts,ij_dtgdts,ij_tmaxe
     *     ,ij_tdsl,ij_tmnmx,ij_tdcomp, ij_dleaf
      use ghy_com, only : snoage, snoage_def,fearth, wsn_max
      use veg_com, only : almass,aalbveg       !nyk
      use vegetation, only: crops_yr,cond_scheme,vegCO2X_off !nyk
      use surf_albedo, only: albvnh, updsur  !nyk
      USE DOMAIN_DECOMP, ONLY : GRID, GET
      use sle001, only : fb,fv,ws
      use veg_drv, only : veg_set_cell

      implicit none
      real*8 tsavg,wfc1
      real*8 aleafmass, aalbveg0, fvp, sfv  !nyk veg ! , aleafmasslast
      integer i,j,itype
      integer northsouth,iv  !nyk
      logical, intent(in) :: end_of_day

C**** define local grid
      integer J_0, J_1

C**** Extract useful local domain parameters from "grid"
      CALL GET(grid, J_STRT=J_0, J_STOP=J_1)

      ! update water and heat in land surface fractions if
      ! lake fraction changed
      if (end_of_day .and. variable_lk > 0) call update_land_fractions

      if (end_of_day .and. wsn_max>0) call remove_extra_snow_to_ocean

!!! testing
!!!      aalbveg(:,:) = 0.08D0
!!!      return

C**** Update vegetation file if necessary  (i.e. if crops_yr=0)
      if(crops_yr.eq.0) call updveg(jyear,.true.)

c**** find leaf-area index & water field capacity for ground layer 1
      if(cond_scheme.eq.2) call updsur (0,jday) ! Update vegn albedos
            !albvnh(9,6,2)=albvnh(1+8veg,6bands,2hemi), band 1 is VIS.
      cosday=cos(twopi/edpery*jday)
      sinday=sin(twopi/edpery*jday)
      do j=J_0,J_1
        if(j.le.jm/2) then      !nyk added northsouth
          northsouth=1          !southern hemisphere
        else
          northsouth=2          !northern hemisphere
        end if
        do i=1,im
          wfcs(i,j)=24.
          ! if (fearth(i,j).gt.0.) then
          !if (focean(i,j) < 1.d0 ) then
          if (variable_lk==0) then
            if ( fearth(i,j) <= 0.d0 ) cycle
          else
            if ( focean(i,j) >= 1.d0 ) cycle
          endif
            if (cond_scheme.eq.2) then
              aalbveg0 = 0.d0
              sfv=0.d0
              do iv=1,11
                if ( iv==9 .or. iv==10 ) cycle
                fvp=vdata(i,j,iv+1)
                sfv=sfv+fvp
                aalbveg0 = aalbveg0 + fvp*(ALBVNH(iv+1,1,northsouth))
                !write (99,*) 'fvp',fvp
                !write (99,*) 'ALBVNH',ALBVNH(iv+1,1,northsouth)
              end do
              aalbveg(i,j) = 0.08D0
              if(sfv.gt.0.) aalbveg(i,j) = aalbveg0/sfv !nyk
             !write (99,*) 'daily aalbveg', aalbveg(i,j)
            end if

            call ghinij(i,j)
            call veg_set_cell(i,j,.true.)
            wfc1=fb*ws(1,1)+fv*(ws(0,2)+ws(1,2))
            wfcs(i,j)=rhow*wfc1 ! canopy part changes

            !-----------------------------------------------------------
            !nyk - TEMPORARY calculate change in leaf mass per day
            !get aleafmass(i,j) at jday
            aleafmass=
     $           almass(1,i,j)+cosday*almass(2,i,j)+sinday*almass(3,i,j)

            !Calculate dlmass(i,j) increment from last jday
            !cosdaym1=cos(twopi/edpery*(jday-1))
            !sindaym1=sin(twopi/edpery*(jday-1))
            !aleafmasslast=almass(1,i,j)+cosdaym1*almass(2,i,j)+
!     $      !     sindaym1*almass(3,i,j)
            !accumulate dlmass
            !adlmass = aleafmass - aleafmasslast
            adlmass = aleafmass
            !aij(i,j,ij_dleaf)=aij(i,j,ij_dleaf)+adlmass
            aij(i,j,ij_dleaf)=adlmass  !accumulate just instant. value
            !PRINT '(F4.4)',adlmass                            !DEBUG
            !call stop_model('Just did adlmass',255)           !DEBUG
          !end if
        end do
      end do

      if (end_of_day) then
        do j=J_0,J_1
        do i=1,imaxj(j)
c****
c**** increase snow age depending on snoage_def
c****
          if (snoage_def.eq.0) then ! update indep. of ts
            do itype=1,3
              snoage(itype,i,j)=1.+.98d0*snoage(itype,i,j)
            end do
          elseif (snoage_def.eq.1) then ! update if max T>0
            if (tdiurn(i,j,7).gt.0) snoage(1,i,j)=1.+.98d0
     *           *snoage(1,i,j) ! ocean ice (not currently used)
            if (tdiurn(i,j,8).gt.0) snoage(2,i,j)=1.+.98d0
     *           *snoage(2,i,j) ! land ice
            if (tdiurn(i,j,2).gt.0) snoage(3,i,j)=1.+.98d0
     *           *snoage(3,i,j) ! land
          else
            write(6,*) "This snoage_def is not defined: ",snoage_def
            write(6,*) "Please use: 0 (update indep of T)"
            write(6,*) "            1 (update if T>0)"
            call stop_model('stopped in GHY_DRV.f',255)
          end if
          tsavg=tdiurn(i,j,5)/(nday*nisurf)
          if(32.+1.8*tsavg.lt.65.)
     *         aij(i,j,ij_strngts)=aij(i,j,ij_strngts)+(33.-1.8*tsavg)
          aij(i,j,ij_dtgdts)=aij(i,j,ij_dtgdts)+18.*((tdiurn(i,j,2)-
     *         tdiurn(i,j,1))/(tdiurn(i,j,4)-tdiurn(i,j,3)+1.d-20)-1.)
          aij(i,j,ij_tdsl)=aij(i,j,ij_tdsl)+
     *         (tdiurn(i,j,4)-tdiurn(i,j,3))
          aij(i,j,ij_tdcomp)=aij(i,j,ij_tdcomp)+
     *         (tdiurn(i,j,6)-tdiurn(i,j,9))
          aij(i,j,ij_tmaxe)=aij(i,j,ij_tmaxe)+(tdiurn(i,j,4)-tf)
          if (tdiurn(i,j,6).lt.aij(i,j,ij_tmnmx))
     *         aij(i,j,ij_tmnmx)=tdiurn(i,j,6)
        end do
        end do
      end if


#ifdef TRACERS_DRYDEP
      CALL RDLAI ! read leaf area indices for tracer dry deposition
#endif

      return
      end subroutine daily_earth


      subroutine ground_e 1,18
!@sum  ground_e driver for applying surface fluxes to land fraction
!@auth original development team
!@ver  1.0
      use model_com, only : itearth
      use geom, only : imaxj,dxyp
      USE DOMAIN_DECOMP, ONLY : GRID, GET
      use DOMAIN_DECOMP, only : GLOBALSUM
      use ghy_com, only : snowe, tearth,wearth,aiearth,w_ij
     *     ,snowbv,fr_snow_ij,fr_snow_rad_ij, gdeep, dzsn_ij, nsn_ij,
     *     fearth
      use veg_com, only : afb
      use diag_com, only : aj=>aj_loc,aregj=>aregj_loc,aij=>aij_loc
     *     ,jreg,ij_evap,ij_f0e,ij_evape
     *     ,ij_gwtr,ij_tg1,j_wtr1,j_ace1,j_wtr2,j_ace2
     *     ,j_snow,j_evap,j_type,ij_g01,ij_g07,ij_g04,ij_g10,ij_g28
     *     ,ij_g29,j_rsnow,ij_rsnw,ij_rsit,ij_snow,ij_gice, ij_gwtr1
     &     ,ij_zsnow
      use fluxes, only : e0,e1,evapor,eprec
      implicit none

      real*8 snow,tg1,tg2,f0dt,f1dt,evap,wtr1,wtr2,ace1,ace2
     *     ,pearth,enrgp,scove
      integer i,j,jr,k

C**** define local grid
      integer J_0, J_1, J_0H, J_1H

C****
C**** Extract useful local domain parameters from "grid"
C****
      CALL GET(grid, J_STRT=J_0      , J_STOP=J_1,
     &               J_STRT_HALO=J_0H, J_STOP_HALO=J_1H )

      do j=J_0,J_1
      do i=1,imaxj(j)
      pearth=fearth(i,j)
      jr=jreg(i,j)
      if (pearth.gt.0) then

        snow=snowe(i,j)
        tg1 = tearth(i,j)
        wtr1= wearth(i,j)
        ace1=aiearth(i,j)
        tg2=gdeep(i,j,1)
        wtr2=gdeep(i,j,2)
        ace2=gdeep(i,j,3)
        f0dt=e0(i,j,4)
        f1dt=e1(i,j,4)
        evap=evapor(i,j,4)
        enrgp=eprec(i,j)      ! including latent heat

c**** accumulate diagnostics
c**** the following is the actual snow cover of the snow model
c        scove = pearth *
c     *       ( afb(i,j)*fr_snow_ij(1,i,j)
c     *       + (1.-afb(i,j))*fr_snow_ij(2,i,j) )
c**** the following computes the snow cover as it is used in RAD_DRV.f
        scove = pearth *
     *       ( afb(i,j)*fr_snow_rad_ij(1,i,j)
     *       + (1.-afb(i,j))*fr_snow_rad_ij(2,i,j) )

        !if (snowe(i,j).gt.0.) scove=pearth
        aj(j,j_rsnow,itearth)=aj(j,j_rsnow,itearth)+scove
        aregj(jr,j,j_rsnow)=aregj(jr,j,j_rsnow)+scove*dxyp(j)
        aij(i,j,ij_rsnw)=aij(i,j,ij_rsnw)+scove
        aij(i,j,ij_snow)=aij(i,j,ij_snow)+snow*pearth
        aij(i,j,ij_rsit)=aij(i,j,ij_rsit)+scove

        aj(j,j_wtr1,itearth)=aj(j,j_wtr1,itearth)+wtr1*pearth
        aj(j,j_ace1,itearth)=aj(j,j_ace1,itearth)+ace1*pearth
        aj(j,j_wtr2,itearth)=aj(j,j_wtr2,itearth)+wtr2*pearth
        aj(j,j_ace2,itearth)=aj(j,j_ace2,itearth)+ace2*pearth
        aj(j,j_snow,itearth)=aj(j,j_snow,itearth)+snow*pearth
        aregj(jr,j,j_snow)=aregj(jr,j,j_snow)+snow*pearth*dxyp(j)
        aregj(jr,j,j_wtr1)=aregj(jr,j,j_wtr1)+wtr1*pearth*dxyp(j)
        aregj(jr,j,j_ace1)=aregj(jr,j,j_ace1)+ace1*pearth*dxyp(j)
        aregj(jr,j,j_wtr2)=aregj(jr,j,j_wtr2)+wtr2*pearth*dxyp(j)
        aregj(jr,j,j_ace2)=aregj(jr,j,j_ace2)+ace2*pearth*dxyp(j)

        aij(i,j,ij_f0e)  =aij(i,j,ij_f0e)  +f0dt+enrgp
        aij(i,j,ij_gwtr) =aij(i,j,ij_gwtr)+(wtr1+ace1+wtr2+ace2)
        aij(i,j,ij_gwtr1) =aij(i,j,ij_gwtr1)+(wtr1+ace1)
        aij(i,j,ij_gice) =aij(i,j,ij_gice)+(ace1+ace2)
        aij(i,j,ij_evape)=aij(i,j,ij_evape)+evap
        do k=1,3
          aij(i,j,ij_g01+k-1)=aij(i,j,ij_g01+k-1)+w_ij(k,1,i,j)
          aij(i,j,ij_g07+k-1)=aij(i,j,ij_g07+k-1)+w_ij(k-1,2,i,j)
        end do
        aij(i,j,ij_g04)=aij(i,j,ij_g04)+w_ij(6,1,i,j)
        aij(i,j,ij_g10)=aij(i,j,ij_g10)+w_ij(6,2,i,j)
        aij(i,j,ij_g28)=aij(i,j,ij_g28)+snowbv(1,i,j)
        aij(i,j,ij_g29)=aij(i,j,ij_g29)+snowbv(2,i,j)
        aij(i,j,ij_zsnow)=aij(i,j,ij_zsnow) + pearth *
     &       ( afb(i,j)*fr_snow_ij(1,i,j)
     &           * sum( dzsn_ij(1:nsn_ij(1,i,j),1,i,j) )
     &       + (1.-afb(i,j))*fr_snow_ij(2,i,j)
     &           * sum( dzsn_ij(1:nsn_ij(2,i,j),2,i,j) ) )
      end if
c****
      end do
      end do

      end subroutine ground_e


      subroutine conserv_wtg(waterg),18
!@sum  conserv_wtg calculates zonal ground water incl snow
!@auth Gavin Schmidt
!@ver  1.0
      use constant, only : rhow
      use model_com, only : fim, focean
      use geom, only : imaxj,DXYP
      use ghy_com, only : ngm,w_ij,wsn_ij,fr_snow_ij,nsn_ij,fearth
      use veg_com, only : afb
      use LAKES_COM, only : flake
      use LANDICE_COM,only : MDWNIMP
      USE DOMAIN_DECOMP, ONLY : GRID, GET, HERE
      implicit none
!@var waterg zonal ground water (kg/m^2)
      real*8, dimension(GRID%J_STRT_HALO:GRID%J_STOP_HALO),intent(out)::
     &     waterg

      integer i,j,n
      real*8 wij,fb,fv

C**** define local grid
      integer :: J_0, J_1
      logical :: HAVE_SOUTH_POLE, HAVE_NORTH_POLE

C****
C**** Extract useful local domain parameters from "grid"
C****
      CALL GET(grid, J_STRT=J_0, J_STOP=J_1,
     &               HAVE_SOUTH_POLE = HAVE_SOUTH_POLE,
     &               HAVE_NORTH_POLE = HAVE_NORTH_POLE)

      do j=J_0,J_1
        waterg(j)=0
        do i=1,imaxj(j)
          !if (fearth(i,j).gt.0) then
          if( focean(i,j) < 1.d0 ) then
            fb=afb(i,j)
            fv=(1.d0-fb)
            wij=fb*sum( w_ij(1:ngm,1,i,j) )
     &       +  fv*sum( w_ij(0:ngm,2,i,j) )
     &       +  fb*fr_snow_ij(1,i,j)*sum( wsn_ij(1:nsn_ij(1,i,j),1,i,j))
     &       +  fv*fr_snow_ij(2,i,j)*sum( wsn_ij(1:nsn_ij(2,i,j),2,i,j))
            waterg(j)=waterg(j)+fearth(i,j)*wij*rhow
     &           + flake(i,j)*sum( w_ij(0:ngm,3,i,j) )*rhow
!!! hack to check remove_extra_snow
!!!            waterg(j)=waterg(j)+MDWNIMP(i,j)/DXYP(j)
          end if
       end do
      end do
      if (HAVE_SOUTH_POLE) waterg(1) =fim*waterg(1)
      if (HAVE_NORTH_POLE) waterg(jm)=fim*waterg(jm)
c****
      end subroutine conserv_wtg



      subroutine conserv_wtg_1(waterg,fearth,flake),14
!@sum  conserv_wtg calculates zonal ground water incl snow
!@auth Gavin Schmidt
!@ver  1.0
      use constant, only : rhow
      use model_com, only : fim, focean, im
      use geom, only : imaxj
      use ghy_com, only : ngm,w_ij,wsn_ij,fr_snow_ij,nsn_ij
      use veg_com, only : afb
      !use LAKES_COM, only : flake
      USE DOMAIN_DECOMP, ONLY : GRID, GET, HERE
      implicit none
      real*8,dimension(im,GRID%J_STRT_HALO:GRID%J_STOP_HALO),
     &     intent(in) :: fearth, flake
!@var waterg zonal ground water (kg/m^2)
      real*8, dimension(GRID%J_STRT_HALO:GRID%J_STOP_HALO),intent(out)::
     &     waterg

      integer i,j,n
      real*8 wij,fb,fv

C**** define local grid
      integer :: J_0, J_1
      logical :: HAVE_SOUTH_POLE, HAVE_NORTH_POLE

C****
C**** Extract useful local domain parameters from "grid"
C****
      CALL GET(grid, J_STRT=J_0, J_STOP=J_1,
     &               HAVE_SOUTH_POLE = HAVE_SOUTH_POLE,
     &               HAVE_NORTH_POLE = HAVE_NORTH_POLE)

      do j=J_0,J_1
        waterg(j)=0
        do i=1,imaxj(j)
          !if (fearth(i,j).gt.0) then
          if( focean(i,j) < 1.d0 ) then
            fb=afb(i,j)
            fv=(1.d0-fb)
            wij=fb*sum( w_ij(1:ngm,1,i,j) )
     &       +  fv*sum( w_ij(0:ngm,2,i,j) )
     &       +  fb*fr_snow_ij(1,i,j)*sum( wsn_ij(1:nsn_ij(1,i,j),1,i,j))
     &       +  fv*fr_snow_ij(2,i,j)*sum( wsn_ij(1:nsn_ij(2,i,j),2,i,j))
            waterg(j)=waterg(j)+fearth(i,j)*wij*rhow
     &           + flake(i,j)*sum( w_ij(0:ngm,3,i,j) )*rhow
          end if
       end do
      end do

      if (HAVE_SOUTH_POLE) waterg(1) =fim*waterg(1)
      if (HAVE_NORTH_POLE) waterg(jm)=fim*waterg(jm)
c****
      end subroutine conserv_wtg_1




      subroutine conserv_htg(heatg),14
!@sum  conserv_htg calculates zonal ground energy incl. snow energy
!@auth Gavin Schmidt
!@ver  1.0
      use model_com, only : fim, focean
      use geom, only : imaxj, dxyp
      use ghy_com, only : ngm,ht_ij,fr_snow_ij,nsn_ij,hsn_ij
     *     ,fearth
      use veg_com, only : afb
      use LAKES_COM, only : flake
      USE DOMAIN_DECOMP, ONLY : GRID, GET, HERE
      implicit none
!@var heatg zonal ground heat (J/m^2)
      real*8, dimension(grid%j_strt_halo:grid%j_stop_halo) :: heatg

      integer i,j
      real*8 hij,fb,fv

C**** define local grid
      integer J_0, J_1
      logical :: HAVE_SOUTH_POLE, HAVE_NORTH_POLE

C****
C**** Extract useful local domain parameters from "grid"
C****
      CALL GET(grid, J_STRT=J_0, J_STOP=J_1,
     &               HAVE_SOUTH_POLE = HAVE_SOUTH_POLE,
     &               HAVE_NORTH_POLE = HAVE_NORTH_POLE)

      do j=J_0,J_1
        heatg(j)=0
        do i=1,imaxj(j)
          !if (fearth(i,j).le.0) cycle
          if ( focean(i,j) >= 1.d0 ) cycle
          fb=afb(i,j)
          fv=(1.d0-fb)
          hij=fb*sum( ht_ij(1:ngm,1,i,j) )
     &       +  fv*sum( ht_ij(0:ngm,2,i,j) )
     &       +  fb*fr_snow_ij(1,i,j)*sum( hsn_ij(1:nsn_ij(1,i,j),1,i,j))
     &       +  fv*fr_snow_ij(2,i,j)*sum( hsn_ij(1:nsn_ij(2,i,j),2,i,j))
          heatg(j)=heatg(j)+fearth(i,j)*hij
     &           + flake(i,j)*sum( ht_ij(0:ngm,3,i,j) )
        end do
      end do
      if (HAVE_SOUTH_POLE) heatg(1) =fim*heatg(1)
      if (HAVE_NORTH_POLE) heatg(jm)=fim*heatg(jm)
c****
ccc debugging ...
ccc      print *,'conserv_htg energy ',
ccc     &     sum(heatg(1:jm)*dxyp(1:jm))/(sum(dxyp(1:jm))*im)
      end subroutine conserv_htg


      end module soil_drv


      subroutine check_ghy_conservation( flag ),20
ccc debugging program: cam be put at the beginning and at the end
ccc of the 'surface' to check water conservation
      use constant, only : rhow
      use geom, only : imaxj
      use model_com, only : im,jm
      use DOMAIN_DECOMP, only : GRID, GET
      use fluxes, only : prec,evapor,runoe
      use ghy_com, only : ngm,w_ij,ht_ij,snowbv,dz_ij
     *     ,fearth
      use veg_com, only : afb
      implicit none
      integer flag
      real*8 total_water(im,jm), error_water
      real*8, save :: old_total_water(im,jm)
!      real*8 total_energy(im,jm), error_energy
!      real*8, save :: old_total_energy(im,jm)
      integer i,j,n
      real*8 fb,fv
ccc enrgy check not implemented yet ...

C**** define local grid
      integer J_0, J_1

C****
C**** Extract useful local domain parameters from "grid"
C****
      CALL GET(grid, J_STRT=J_0, J_STOP=J_1)

      do j=J_0,J_1
        do i=1,imaxj(j)
          if ( fearth(i,j) <= 0.d0 ) cycle

ccc just checking ...
          do n = 1,ngm
            if ( dz_ij(i,j,n) .le. 0.d0 )
     &           call stop_model('incompatible dz',255)
          enddo

          fb = afb(i,j)
          fv = 1.d0 - fb
          total_water(i,j) = fb*sum( w_ij(1:ngm,1,i,j) )
     &         + fv*sum( w_ij(0:ngm,2,i,j) )
     &         + fb*snowbv(1,i,j) + fv*snowbv(2,i,j)
        end do
      end do

      ! call stop_model('just testing...',255)

      if ( flag == 0 ) then
        old_total_water(:,:) = total_water(:,:)
        return
      endif

      do j=J_0,J_1
        do i=1,imaxj(j)

          !print *,'fearth = ', i, j, fearth(i,j)

          if ( fearth(i,j) <= 0.d0 ) cycle
          fb = afb(i,j)
          fv = 1.d0 - fb
          error_water = ( total_water(i,j) - old_total_water(i,j) )*rhow
     &         - prec(i,j) + evapor(i,j,4) + runoe(i,j)

          !print *, 'err H2O: ', i, j, error_water

  !        if ( abs( error_water ) > 1.d-9 ) print *, 'error'
          if ( abs( error_water ) > 1.d-9 ) call stop_model(  ! was -15
     &         'check_ghy_conservation: water conservation problem',255)

        end do
      end do

      end subroutine check_ghy_conservation



      subroutine compute_water_deficit 2,16
      use constant, only : twopi,edpery,rhow
      use ghy_com, only : ngm,imt,LS_NFRAC,dz_ij,q_ij
     &     ,w_ij,fearth
      use veg_com, only : ala,afb
      use model_com, only : focean
      use sle001, only : thm
      use fluxes, only : DMWLDF
      USE DOMAIN_DECOMP, ONLY : GRID, GET

      implicit none
cddd      integer, intent(in) :: jday
      !---
      integer i,j,I_0,I_1,J_0,J_1
      integer k,ibv,m
      real*8 :: w_tot(2),w_stor(2)
      real*8 :: w(0:ngm,2),dz(ngm),q(imt,ngm)
cddd      real*8 :: cosday,sinday,alai
      real*8 :: fb,fv

      CALL GET(grid, I_STRT=I_0, I_STOP=I_1, J_STRT=J_0, J_STOP=J_1)

cddd      cosday=cos(twopi/edpery*jday)
cddd      sinday=sin(twopi/edpery*jday)

      DMWLDF(:,:) = 0.d0

      do j=J_0,J_1
        do i=I_0,I_1

          !if( focean(i,j) >= 1.d0 ) then
          ! this condition should be switched to focean(i,j) >= 1.d0
          ! once all ground arrays are properly initialized for focean(i,j)<1
          if( fearth(i,j) <= 0.d0 ) then
            DMWLDF(i,j) = 0.d0
            cycle
          endif

          w(0:ngm,1:2) = w_ij(0:ngm,1:2,i,j)
          dz(1:ngm) = dz_ij(i,j,1:ngm)
          q(1:imt,1:ngm) = q_ij(i,j,1:imt,1:ngm)

          fb = afb(i,j)
          fv=1.-fb

          w_stor(:) = 0.d0
          w_tot(:) = 0.d0
          do ibv=1,2
            do k=1,ngm
              do m=1,imt-1
                w_stor(ibv) = w_stor(ibv) + q(m,k)*thm(0,m)*dz(k)
              end do
              w_tot(ibv) = w_tot(ibv) + w(k,ibv)
            end do
          end do

          ! include canopy water here
cddd          alai=ala(1,i,j)+cosday*ala(2,i,j)+sinday*ala(3,i,j)
cddd          alai=max(alai,1.d0)
cddd          w_stor(2) = w_stor(2) + .0001d0*alai
          w_tot(2) = w_tot(2) + w(0,2)

          ! total water deficit on kg/m^2
          DMWLDF(i,j) = fb*(w_stor(1) - w_tot(1))
     &         + fv*(w_stor(2) - w_tot(2))
          DMWLDF(i,j) = max( DMWLDF(i,j), 0.d0 )
        enddo
      enddo


      !print *,"DMWLDF=",DMWLDF

      end subroutine compute_water_deficit



      subroutine init_underwater_soil 2,26

!!!! UNFINISHED
      use constant, only : twopi,edpery,rhow,shw_kg=>shw
      use ghy_com, only : ngm,imt,LS_NFRAC,dz_ij,q_ij
     &     ,w_ij,ht_ij,fearth,shc_soil_texture
#ifdef TRACERS_WATER
     &     ,tr_w_ij
      use TRACER_COM, only : ntm,needtrs,itime_tr0
      use model_com, only : itime
#endif
      use veg_com, only : ala,afb
      use model_com, only : focean
      use sle001, only : thm
      use fluxes, only : DMWLDF
      USE DOMAIN_DECOMP, ONLY : GRID, GET

      implicit none
cddd      integer, intent(in) :: jday
      !---
      integer i,j,I_0,I_1,J_0,J_1
      integer k,ibv,m
      real*8 :: w_stor(0:ngm), ht_cap(0:ngm)
      real*8 :: w(0:ngm,2),dz(ngm),q(imt,ngm)
      !!real*8 :: cosday,sinday,alai
      real*8 :: fb,fv
      real*8 shc_layer, aa, tp, tpb, tpv, ficeb, ficev, fice
#ifdef TRACERS_WATER
      integer n
      real*8 wsoil_tot
#endif

      CALL GET(grid, I_STRT=I_0, I_STOP=I_1, J_STRT=J_0, J_STOP=J_1)


cddd      cosday=cos(twopi/edpery*jday)
cddd      sinday=sin(twopi/edpery*jday)

      do j=J_0,J_1
        do i=I_0,I_1

          if( focean(i,j) >= 1.d0 ) then
            w_ij (0:ngm,3,i,j) = 0.d0
            ht_ij(0:ngm,3,i,j) = 0.d0
            cycle
          endif

          !w(0:ngm,1:2) = w_ij(0:ngm,1:2,i,j)
          dz(1:ngm) = dz_ij(i,j,1:ngm)
          q(1:imt,1:ngm) = q_ij(i,j,1:imt,1:ngm)

          fb = afb(i,j)
          fv=1.-fb

          ! compute max water storage and heat capacity
          do k=1,ngm
            w_stor(k) = 0.d0
            do m=1,imt-1
              w_stor(k) = w_stor(k) + q(m,k)*thm(0,m)*dz(k)
            enddo
            shc_layer = 0.d0
            do m=1,imt
              shc_layer = shc_layer + q(m,k)*shc_soil_texture(m)
            enddo
            ht_cap(k) = (dz(k)-w_stor(k)) * shc_layer
          enddo

          ! include canopy water here
          !!alai=ala(1,i,j)+cosday*ala(2,i,j)+sinday*ala(3,i,j)
          !!alai=max(alai,1.d0)
          !!w_stor(0) = .0001d0*alai*fv
          w_stor(0) = 0.d0
          aa=ala(1,i,j)
          ht_cap(0)=(.010d0+.002d0*aa+.001d0*aa**2)*shw_kg*rhow

          ! we will use as a reference average temperature of the
          ! lowest layer
          call heat_to_temperature( tpb, ficeb,
     &         ht_ij(ngm,1,i,j), w_ij(ngm,1,i,j), ht_cap(ngm) )
          call heat_to_temperature( tpv, ficev,
     &         ht_ij(ngm,2,i,j), w_ij(ngm,2,i,j), ht_cap(ngm) )
          tp   = fb*tpb + fv*tpv
          fice = fb*ficeb + fv*ficev

          ! set underground fraction to tp, fice and saturated water
          !! nothing in canopy layer (ie. temp = 0C)
          w_ij(0,3,i,j) = 0.d0
          ht_ij(0,3,i,j) = 0.d0
          do k=1,ngm
            w_ij(k,3,i,j) = w_stor(k)
            call temperature_to_heat( ht_ij(k,3,i,j),
     &           tp, fice, w_ij(k,3,i,j), ht_cap(k) )
          enddo

#ifdef TRACERS_WATER
      ! set underwater tracers to average land tracers (ignore canopy)
          do k=1,ngm
            wsoil_tot = fb*w_ij(k,1,i,j) + fv*w_ij(k,2,i,j)
            do n=1,ntm
              if (itime_tr0(n).gt.itime) cycle
              if ( .not. needtrs(n) ) cycle
              tr_w_ij(n,k,3,i,j) = 0.d0
              if ( wsoil_tot > 1.d-30 ) then
                tr_w_ij(n,k,3,i,j) = (
     &               fb*tr_w_ij(n,k,1,i,j) + fv*tr_w_ij(n,k,2,i,j)
     &               ) / (wsoil_tot) * w_ij(k,3,i,j) !!! removed /rhow
              end if
            enddo
          enddo
#endif


        enddo
      enddo

      end subroutine init_underwater_soil



      subroutine heat_to_temperature(tp, fice, ht, w, ht_cap) 8,2
      use constant, only : rhow, lhm, shw_kg=>shw, shi_kg=>shi
      real*8, intent(out) :: tp, fice
      real*8, intent(in) :: ht, w, ht_cap
      ! volumetric quantities
      real*8, parameter :: lhmv=lhm*rhow, shwv=shw_kg*rhow,
     &     shiv=shi_kg*rhow

      fice = 0.d0
      if( lhmv*w+ht < 0.d0 ) then ! all frozen
        tp = ( ht + w*lhmv )/( ht_cap + w*shiv )
        fice = 1.d0
      else if( ht > 0.d0 ) then ! all melted
        tp = ht /( ht_cap + w*shwv )
      else  ! part frozen
        tp = 0.d0
        if( w > 1d-12 ) fice = -ht /( lhmv*w )
      endif

      end subroutine heat_to_temperature



      subroutine temperature_to_heat(ht, tp, fice, w, ht_cap) 2,2
      use constant, only : rhow, lhm, shw_kg=>shw, shi_kg=>shi
      real*8, intent(in) :: tp, fice, w, ht_cap
      real*8, intent(out) :: ht
      ! volumetric quantities
      real*8, parameter :: lhmv=lhm*rhow, shwv=shw_kg*rhow,
     &     shiv=shi_kg*rhow
      real*8 lht_ice

      lht_ice = fice*w*lhmv

      if( tp > 0.d0 ) then
        ht = tp*( ht_cap + w*shwv ) - lht_ice
      else
        ht = tp*( ht_cap + w*shiv ) - lht_ice
      endif

      end subroutine temperature_to_heat



      subroutine update_land_fractions !(jday) 2,34

!!!! UNFINISHED
      use constant, only : twopi,edpery,rhow,shw_kg=>shw
      use ghy_com, only : ngm,imt,dz_ij,q_ij
     &     ,w_ij,ht_ij,fr_snow_ij,fearth
     &     ,fr_snow_rad_ij,snowbv,top_dev_ij
#ifdef TRACERS_WATER
     &     ,tr_w_ij,tr_wsn_ij
      use TRACER_COM, only : ntm
#endif
      use veg_com, only : ala,afb
      use model_com, only : focean,im
      use LAKES_COM, only : flake, svflake
      use sle001, only : thm
      use fluxes, only : DMWLDF, DGML
#ifdef TRACERS_WATER
     &     ,DTRL
#endif
      use GEOM, only : BYDXYP
      USE DOMAIN_DECOMP, ONLY : GRID, GET
      use soil_drv, only : conserv_wtg_1,snow_cover
      use snow_drvm, only : snow_cover_same_as_rad

      implicit none
      !! integer, intent(in) :: jday
      !---
      integer i,j,I_0,I_1,J_0,J_1,ibv
      integer k,m
      real*8 :: w_stor(0:ngm)
      real*8 :: dz(ngm),q(imt,ngm)
      !!real*8 :: cosday,sinday,alai
      real*8 :: fb,fv
      real*8 :: dw, dw_soil, dw_lake, dht, dht_soil, dht_lake
      real*8 :: sum_water, ht_per_m3

      real*8 dfrac
#ifdef TRACERS_WATER
      real*8 dtr_soil(ntm),dtr_lake(ntm),dtr(ntm),tr_per_m3(ntm)
#endif
      real*8 tmp_before(0:ngm), tmp_after(0:ngm)
      real*8, dimension(GRID%J_STRT_HALO:GRID%J_STOP_HALO) ::
     &     w_before_j, w_after_j
      real*8, dimension(im,GRID%J_STRT_HALO:GRID%J_STOP_HALO) ::
     &     fearth_old

      CALL GET(grid, I_STRT=I_0, I_STOP=I_1, J_STRT=J_0, J_STOP=J_1)


cddd      cosday=cos(twopi/edpery*jday)
cddd      sinday=sin(twopi/edpery*jday)

!!!   testing
!!!      w_ij(0:ngm,3,:,:) = 0.d0

!!! testing
!!!      DGML(:,:) = 0.d0

      fearth_old = fearth + (flake - svflake)

      ! call conserv_wtg_1(w_before_j,fearth_old,svflake)

      do j=J_0,J_1
        do i=I_0,I_1

          if( focean(i,j) >= 1.d0 ) cycle

          if ( svflake(i,j) == flake(i,j) ) cycle

          fb = afb(i,j)
          fv=1.d0-fb

          !print *,"UPDATING FRACTIONS: i,j= ",i,j
          !print *,"fb, fv = ", fb, fv

          if ( flake(i,j) < svflake(i,j) ) then ! lake shrunk
            ! no external fluxes, just part of underwater fraction
            ! is transformed into a land fraction

            ! no changes to underwater fraction
            ! just redistribute added quantities over lan fractions


            dfrac = svflake(i,j) - flake(i,j)

            tmp_before = ( ht_ij(0:ngm,3,i,j) )*svflake(i,j) +
     &           ( ht_ij(0:ngm,1,i,j) )*fb*(fearth(i,j)-dfrac) +
     &           ( ht_ij(0:ngm,2,i,j) )*fv*(fearth(i,j)-dfrac)

            !print *,"before", sum(tmp_before)
!     &           ,fr_snow_ij(1,i,j)*fb*fearth(i,j) +
!     &           fr_snow_ij(2,i,j)*fv*fearth(i,j)

            !print *,"shrinkrd"
            !print *,"flake(i,j),svflake(i,j)", flake(i,j),svflake(i,j)
            do k=1,ngm
              dw  = dfrac*w_ij(k,3,i,j)
              dht = dfrac*ht_ij(k,3,i,j)
              !print *,"w3", w_ij(k,3,i,j)
              !print *,"ht3", ht_ij(k,3,i,j)
              !print *,"w before", w_ij(k,1:2,i,j)
              !print *,"ht before", ht_ij(k,1:2,i,j)
              w_ij(k,1:2,i,j) =
     &             (w_ij(k,1:2,i,j)*(fearth(i,j)-dfrac) + dw)
     &             / fearth(i,j)
              ht_ij(k,1:2,i,j) =
     &             (ht_ij(k,1:2,i,j)*(fearth(i,j)-dfrac) + dht)
     &             / fearth(i,j)
              !print *,"w after", w_ij(k,1:2,i,j)
              !print *,"ht after", ht_ij(k,1:2,i,j)
#ifdef TRACERS_WATER
              dtr(:) = dfrac*tr_w_ij(:,k,3,i,j)
              do ibv=1,2
                tr_w_ij(:,k,ibv,i,j) =
     &               (tr_w_ij(:,k,ibv,i,j)*(fearth(i,j)-dfrac) + dtr(:))
     &               / fearth(i,j)
              enddo
#endif
            enddo
            !vegetation:
cddd            if ( fv > 0.d0 ) then
cddd              print *,"w3", w_ij(0,3,i,j)
cddd              print *,"ht3", ht_ij(0,3,i,j)
cddd              print *,"w before", w_ij(0,1:2,i,j)
cddd              print *,"ht before", ht_ij(0,1:2,i,j)
cddd              w_ij(0,2,i,j) =
cddd     &             (w_ij(0,2,i,j)*(fearth(i,j)-dfrac) + dw/fv)
cddd     &             / fearth(i,j)
cddd              ht_ij(0,2,i,j) =
cddd     &             (ht_ij(0,2,i,j)*(fearth(i,j)-dfrac) + dht/fv)
cddd     &             / fearth(i,j)
cddd              print *,"w after", w_ij(0,1:2,i,j)
cddd              print *,"ht after", ht_ij(0,1:2,i,j)
cddd            endif
              w_ij(0,2,i,j) =
     &             (w_ij(0,2,i,j)*(fearth(i,j)-dfrac))
     &             / fearth(i,j)
              ht_ij(0,2,i,j) =
     &             (ht_ij(0,2,i,j)*(fearth(i,j)-dfrac))
     &             / fearth(i,j)
#ifdef TRACERS_WATER
              tr_w_ij(:,0,2,i,j) =
     &             (tr_w_ij(:,0,2,i,j)*(fearth(i,j)-dfrac))
     &             / fearth(i,j)
#endif

            ! change snow fraction
            fr_snow_ij(1:2,i,j) =
     &           fr_snow_ij(1:2,i,j)*(1.d0-dfrac/fearth(i,j))
#ifdef TRACERS_WATER
            ! tr_wsn is spread over entire cell (i.e. *fr_snow)
            tr_wsn_ij(:,:,1:2,i,j) = tr_wsn_ij(:,:,1:2,i,j) *
     &           (1.d0 - dfrac/fearth(i,j))
#endif

            tmp_after = ( ht_ij(0:ngm,3,i,j) )*flake(i,j) +
     &           ( ht_ij(0:ngm,1,i,j) )*fb*(fearth(i,j)) +
     &           ( ht_ij(0:ngm,2,i,j) )*fv*(fearth(i,j))
            !print *,"after", (tmp_after), (tmp_after-tmp_before)

          else if ( flake(i,j) > svflake(i,j) ) then ! lake expanded
          !else if ( .false. ) then ! comment out for now

            !print *,"expanded"

            ! no need to change land values
            ! for underwater fraction:

            dz(1:ngm) = dz_ij(i,j,1:ngm)
            q(1:imt,1:ngm) = q_ij(i,j,1:imt,1:ngm)

            ! compute max water storage and heat capacity
            do k=1,ngm
              w_stor(k) = 0.d0
              do m=1,imt-1
                w_stor(k) = w_stor(k) + q(m,k)*thm(0,m)*dz(k)
              enddo
            enddo
            ! include canopy water here
!!!cddd            alai=ala(1,i,j)+cosday*ala(2,i,j)+sinday*ala(3,i,j)
!!!cddd            alai=max(alai,1.d0)
!!!cddd            w_stor(0) = .0001d0*alai*fv
            ! no uderlake water in canopy
            w_stor(0) = 0.d0
            ! allow any amount of water in upper soil layer
            w_stor(1) = 1.d30

            dfrac = flake(i,j) - svflake(i,j)

            tmp_before = ( ht_ij(0:ngm,3,i,j) )*svflake(i,j) +
     &           ( ht_ij(0:ngm,1,i,j) )*fb*(fearth(i,j)+dfrac) +
     &           ( ht_ij(0:ngm,2,i,j) )*fv*(fearth(i,j)+dfrac)

            !print *,"exp_before", sum(tmp_before)

            !print *,"flake(i,j),svflake(i,j)", flake(i,j),svflake(i,j)
            !print *,"WLDF(i,j),dfrac/", i,j,DMWLDF(i,j),dfrac
            sum_water = DMWLDF(i,j)*dfrac/rhow
            !!!!test sum_water = 0.d0
            if ( sum_water > 1.d-30 ) then
              ht_per_m3 = DGML(i,j)*BYDXYP(J)/sum_water
            else
              ht_per_m3 = 0.d0
            endif
#ifdef TRACERS_WATER
            if ( sum_water > 1.d-30 ) then
              tr_per_m3(:) = DTRL(:,i,j)*BYDXYP(J)/sum_water
            else
              tr_per_m3(:) = 0.d0
            endif
#endif
            !print *,"DGML, sum_water, ht_per_m3 ",
   !  &           DGML(i,j),sum_water,ht_per_m3
            do k=ngm,1,-1  ! do not loop over canopy
              ! dw, dht - total amounts of water and heat added to
              ! underwater fraction
              dw_soil = dfrac*( fb*w_ij(k,1,i,j) + fv*w_ij(k,2,i,j) )
              dw  = min( dfrac*w_stor(k), sum_water + dw_soil )
              dw_lake = dw - dw_soil
              !print *,"dw, dw_soil, dw_lake", dw, dw_soil, dw_lake
              dht_soil = dfrac*( fb*ht_ij(k,1,i,j) + fv*ht_ij(k,2,i,j) )
              dht_lake = dw_lake*ht_per_m3
              dht = dht_soil + dht_lake
              !print *,"dht_soil, dht_lake, dht", dht_soil, dht_lake, dht
              sum_water = sum_water - dw_lake
              !print *,"w before", w_ij(k,3,i,j)
              !print *,"ht before", ht_ij(k,3,i,j)

              w_ij(k,3,i,j) =
     &             (w_ij(k,3,i,j)*svflake(i,j) + dw)/flake(i,j)
              ht_ij(k,3,i,j) =
     &             (ht_ij(k,3,i,j)*svflake(i,j) + dht)/flake(i,j)
              !print *,"w after", w_ij(k,3,i,j)
              !print *,"ht after", ht_ij(k,3,i,j)
#ifdef TRACERS_WATER
              dtr_soil(:) =
     &             dfrac*(fb*tr_w_ij(:,k,1,i,j) + fv*tr_w_ij(:,k,2,i,j))
              dtr_lake(:) = dw_lake*tr_per_m3(:)
              dtr(:) = dtr_soil(:) + dtr_lake(:)
              tr_w_ij(:,k,3,i,j) =
     &             (tr_w_ij(:,k,3,i,j)*svflake(i,j) + dtr(:))/flake(i,j)
#endif
            enddo

            ! dump canopy water into first layer (underwater canopy is 0C)
            dw = dfrac*( fv*w_ij(0,2,i,j) )
            dht = dfrac*( fv*ht_ij(0,2,i,j) )
              w_ij(1,3,i,j) =
     &             w_ij(1,3,i,j) + dw/flake(i,j)
              ht_ij(1,3,i,j) =
     &             ht_ij(1,3,i,j) + dht/flake(i,j)
#ifdef TRACERS_WATER
            dtr(:) = dfrac*( fv*tr_w_ij(:,0,2,i,j) )
            tr_w_ij(:,1,3,i,j) =
     &             tr_w_ij(:,1,3,i,j) + dtr(:)/flake(i,j)
#endif
            tmp_after = ( ht_ij(0:ngm,3,i,j) )*flake(i,j) +
     &           ( ht_ij(0:ngm,1,i,j) )*fb*(fearth(i,j)) +
     &           ( ht_ij(0:ngm,2,i,j) )*fv*(fearth(i,j))
            !print *,"exp_after",(tmp_after),(tmp_after-tmp_before)



            ! change snow fraction
            if ( fearth(i,j) <= 0.d0 ) then
              print *, "farctions:",i,j,
     &             focean(i,j), fearth(i,j), flake(i,j), svflake(i,j)
              call stop_model("update_land_fractions: fearth<=0",255)
            endif

            !print *,"FR_SNOW before",i,j,fr_snow_ij(1:2,i,j)

            fr_snow_ij(1:2,i,j) =
     &           fr_snow_ij(1:2,i,j)*(1.d0+dfrac/fearth(i,j))
#ifdef TRACERS_WATER
            ! tr_wsn is spread over entire cell (i.e. *fr_snow)
            tr_wsn_ij(:,:,1:2,i,j) = tr_wsn_ij(:,:,1:2,i,j) *
     &           (1.d0 + dfrac/fearth(i,j))
#endif


            ! hack to deal with snow in empty fractions (fb, fv)
            if( fb <= 0.d0 )
     &           fr_snow_ij(1,i,j) = min( .95d0, fr_snow_ij(1,i,j) )
            if( fv <= 0.d0 )
     &           fr_snow_ij(2,i,j) = min( .95d0, fr_snow_ij(2,i,j) )

            !print *,"FR_SNOW  after" ,i,j,fr_snow_ij(1:2,i,j)
            if ( fr_snow_ij(1,i,j) > 1.d0 .or.
     &           fr_snow_ij(2,i,j) > 1.d0 ) call stop_model(
     &           "update_land_fractions: fr_snow_ij > 1",255)

          endif

c**** Also reset snow fraction for albedo computation
          if ( snow_cover_same_as_rad == 0 ) then
            ! recompute snow fraction using different formula
            do ibv=1,2
               call snow_cover(fr_snow_rad_ij(ibv,i,j),
     &                snowbv(ibv,i,j), top_dev_ij(i,j) )
               fr_snow_rad_ij(ibv,i,j) = min (
     &            fr_snow_rad_ij(ibv,i,j), fr_snow_ij(ibv, i, j) )
            enddo
          else
            ! snow fraction same as in snow model
            fr_snow_rad_ij(:,i,j) = fr_snow_ij(:, i, j)
          endif

          call set_new_ghy_cells_outputs

          ! reset "FLUXES" arrays
          svflake(i,j) = flake(i,j)
          DMWLDF(i,j) = 0.d0
          DGML(i,j) = 0.d0
        enddo
      enddo

      !call conserv_wtg_1(w_after_j,fearth,flake)

      !print *,"UPDATE_LF CONS_WTRG ", w_after_j-w_before_j


      end subroutine update_land_fractions



      subroutine set_new_ghy_cells_outputs 2,28
!@sum set output data for newly created earth cells (when lake shrinks)
      use constant, only : rhow,tf,lhe,lhs
      use ghy_com, only : ngm,imt,dz_ij,q_ij
     &     ,w_ij,ht_ij,fr_snow_ij,fearth,qg_ij,fr_snow_rad_ij
     &     ,shc_soil_texture,canopy_temp_ij,snowe,tearth,wearth,aiearth
#ifdef TRACERS_WATER
     &     ,tr_w_ij
      use TRACER_COM, only : ntm,needtrs,itime_tr0
      use model_com, only : itime
#endif
      use FLUXES, only : gtemp,gtempr
#ifdef TRACERS_WATER
     &     ,gtracer
#endif
      use veg_com, only : afb
      use sle001, only : thm
      use LAKES_COM, only : flake, svflake
      use dynamics, only : pedn
      USE DOMAIN_DECOMP, ONLY : GRID, GET

      implicit none
      !---
      real*8, external :: qsat
      real*8 :: EPS=1.d-12
      integer i,j,I_0,I_1,J_0,J_1
      real*8 :: dz(ngm), q(imt,ngm), w_stor(ngm), ht_cap(ngm)
      real*8 tg1, fice, fb, fv, tpb, tpv, ficeb, ficev, shc_layer
      real*8 dfrac, elhx, ps
      integer k, m
#ifdef TRACERS_WATER
      integer n
      real*8 wsoil_tot
#endif

      CALL GET(grid, I_STRT=I_0, I_STOP=I_1, J_STRT=J_0, J_STOP=J_1)

      do j=J_0,J_1
        do i=I_0,I_1

          dfrac = svflake(i,j) - flake(i,j)
          if ( fearth(i,j) < EPS .or. fearth(i,j)-dfrac > EPS ) cycle

          dz(1:ngm) = dz_ij(i,j,1:ngm)
          q(1:imt,1:ngm) = q_ij(i,j,1:imt,1:ngm)

          fb = afb(i,j)
          fv=1.-fb

      ! compute max water storage and heat capacity
          do k=1,ngm
            w_stor(k) = 0.d0
            do m=1,imt-1
              w_stor(k) = w_stor(k) + q(m,k)*thm(0,m)*dz(k)
            enddo
            shc_layer = 0.d0
            do m=1,imt
              shc_layer = shc_layer + q(m,k)*shc_soil_texture(m)
            enddo
            ht_cap(k) = (dz(k)-w_stor(k)) * shc_layer
          enddo

          call heat_to_temperature( tpb, ficeb,
     &         ht_ij(1,1,i,j), w_ij(1,1,i,j), ht_cap(ngm) )
          call heat_to_temperature( tpv, ficev,
     &         ht_ij(1,2,i,j), w_ij(1,2,i,j), ht_cap(ngm) )
          tg1   = fb*tpb + fv*tpv
          fice = fb*ficeb + fv*ficev

          elhx=lhe
          if(tg1.lt.0.)  elhx=lhs
          ps=pedn(1,i,j)
      ! ground humidity to be used on next time step
          qg_ij(i,j) = qsat(tg1+tf,elhx,ps) ! all saturated
      ! snow fraction same as in snow model
          fr_snow_rad_ij(:,i,j) = 0.d0 ! no snow in new cell
      ! canopy_temp_ij is not used so far... do we need it?
          canopy_temp_ij(i,j) = 0.d0 ! canopy at 0C

c**** snowe used in RADIATION
          snowe(i,j) = 1000.*0.d0
c**** tearth used only internaly in GHY_DRV
          tearth(i,j)=tg1
c**** wearth+aiearth are used in radiation only
          wearth(i,j)=1000.*( fb*w_ij(1,1,i,j)*(1.-ficeb) +
     &         fv*(w_ij(1,2,i,j)*(1.-ficev)) )
          aiearth(i,j)=1000.*( fb*w_ij(1,1,i,j)*ficeb +
     &         fv*w_ij(1,2,i,j)*ficev )
          gtemp(1,4,i,j)=tearth(i,j)
          gtempr(4,i,j) =tearth(i,j)+tf

#ifdef TRACERS_WATER
      ! I use vegetated ground insted of canopy since canopy has 0 H2O
          wsoil_tot = fb*w_ij(1,1,i,j) + fv*w_ij(1,2,i,j)
          do n=1,ntm
            if (itime_tr0(n).gt.itime) cycle
            if ( .not. needtrs(n) ) cycle
            ! should also restrict to TYPE=nWATER ?
            if ( wsoil_tot > 1.d-30 ) then
              gtracer(n,4,i,j) = (
     &             fb*tr_w_ij(n,1,1,i,j) + fv*tr_w_ij(n,1,2,i,j)
     &             ) / (rhow*wsoil_tot)
            else
              gtracer(n,4,i,j) = 0.
            end if
         !!! test
            gtracer(n,4,i,j) = 1.d0
          enddo
#endif
        enddo
      enddo

      end subroutine set_new_ghy_cells_outputs



      subroutine remove_extra_snow_to_ocean ! bad idea ? 2,24
      use constant, only : rhow
      use ghy_com, only : nsn_ij, dzsn_ij, wsn_ij, hsn_ij,
     &     fr_snow_ij,fearth,w_ij,ngm,wsn_max
#ifdef TRACERS_WATER
     &     ,tr_wsn_ij
      use TRACER_COM, only : ntm
#endif
      use veg_com, only : afb
      use LAKES_COM, only : flake
      use LANDICE_COM, only : MDWNIMP, EDWNIMP
#ifdef TRACERS_WATER
     &     ,TRDWNIMP
#endif
      use GEOM, only : DXYP
      use MODEL_COM, only : ITEARTH
      USE DIAG_COM, only : aj=>aj_loc,aregj=>aregj_loc,j_implh,j_implm
     *     ,JREG
      USE DOMAIN_DECOMP, ONLY : GRID, GET, GLOBALSUM

      implicit none
      !! integer, intent(in) :: jday
      !---
      integer i,j,I_0,I_1,J_0,J_1,J_0H,J_1H
      real*8 fbv(2),wsn(3),hsn(3),dzsn(3),fr_snow,wsn_tot,d_wsn,eta
      real*8 dw,dh   ! ,tot0
      integer ibv,nsn,JR

      CALL GET(grid, I_STRT=I_0, I_STOP=I_1, J_STRT=J_0, J_STOP=J_1
     &        ,J_STRT_HALO=J_0H,J_STOP_HALO=J_1H)

      do j=J_0,J_1
        do i=I_0,I_1

          if( fearth(i,j) <= 0.d0 ) cycle

          JR=JREG(I,J)

          fbv(1) = afb(i,j)
          fbv(2) =1.d0 - fbv(1)

c          tot0=(fbv(1)*sum( w_ij(1:ngm,1,i,j) )
c     &         +  fbv(2)*sum( w_ij(0:ngm,2,i,j) )
c     &         +  fbv(1)*fr_snow_ij(1,i,j)*sum( wsn_ij(1:nsn_ij(1,i,j),1
c     *         ,i,j))+  fbv(2)*fr_snow_ij(2,i,j)*sum( wsn_ij(1:nsn_ij(2
c     *         ,i,j),2,i,j)))*fearth(i,j)*rhow+flake(i,j)*sum(
c     *         w_ij(0:ngm,3,i,j) )*rhow


          do ibv=1,2
            if ( fbv(ibv) <= 0.d0 ) cycle

            nsn = nsn_ij(ibv, i, j)
            wsn = 0 ; hsn = 0 ; dzsn = 0
            wsn(1:nsn) = wsn_ij(1:nsn, ibv, i, j)
            hsn(1:nsn) = hsn_ij(1:nsn, ibv, i, j)
            dzsn(1:nsn) = dzsn_ij(1:nsn, ibv, i, j)
            fr_snow = fr_snow_ij(ibv, i, j)
            wsn_tot = sum( wsn(1:nsn) )
            if ( wsn_tot > WSN_MAX ) then
              ! check if snow structure ok for thick snow
              if ( nsn < 3)
     &             call stop_model("remove_extra_snow: nsn<3",255)
              d_wsn = wsn_tot - WSN_MAX
              ! fraction of snow to be removed:
              eta = d_wsn/(wsn(2)+wsn(3))
              wsn_ij(2:3, ibv, i, j)  = (1.d0-eta)*wsn(2:3)
              hsn_ij(2:3, ibv, i, j)  = (1.d0-eta)*hsn(2:3)
              dzsn_ij(2:3, ibv, i, j) = (1.d0-eta)*dzsn(2:3)
              ! extra water and energy
              dw = eta*(wsn(2)+wsn(3))*fr_snow*fbv(ibv)*rhow
              MDWNIMP(i,j) = MDWNIMP(i,j) + dw*fearth(i,j)*DXYP(j)
              dh = eta*(hsn(2)+hsn(3))*fr_snow*fbv(ibv)
              EDWNIMP(i,j) = EDWNIMP(i,j) + dh*fearth(i,j)*DXYP(j)
#ifdef TRACERS_WATER
              TRDWNIMP(1:ntm,i,j) = TRDWNIMP(1:ntm,i,j) +
     &             eta*(
     &             tr_wsn_ij(1:ntm,2,ibv,i,j)+tr_wsn_ij(1:ntm,3,ibv,i,j)
     &             )*fbv(ibv)*fearth(i,j)*DXYP(j)
              tr_wsn_ij(1:ntm,2:3,ibv,i,j) =
     &             (1.d0-eta)*tr_wsn_ij(1:ntm,2:3,ibv,i,j)
#endif
              AJ(J,J_IMPLH,ITEARTH) =
     &             AJ(J,J_IMPLH,ITEARTH) + dh*fearth(i,j)
              AJ(J,J_IMPLM,ITEARTH) =
     &             AJ(J,J_IMPLM,ITEARTH) + dw*fearth(i,j)
              AREGJ(JR,J,J_IMPLH) =
     &             AREGJ(JR,J,J_IMPLH) + dh*fearth(i,j)*DXYP(j)
              AREGJ(JR,J,J_IMPLM) =
     &             AREGJ(JR,J,J_IMPLM) + dw*fearth(i,j)*DXYP(j)

              !print *,"remove_extra_snow", i,j,ibv,wsn_tot,eta,dw,dh

            endif
          enddo
c          print
c     *         *,i,j,tot0,(fbv(1)*sum( w_ij(1:ngm,1,i,j) )+  fbv(2)*sum(
c     *         w_ij(0:ngm,2,i,j) )+  fbv(1)*fr_snow_ij(1,i,j)*sum(
c     *         wsn_ij(1:nsn_ij(1,i,j),1,i,j))+  fbv(2)*fr_snow_ij(2,i,j)
c     *         *sum( wsn_ij(1:nsn_ij(2,i,j),2,i,j)))*fearth(i,j)*rhow
c     *         +flake(i,j)*sum(w_ij(0:ngm,3,i,j) )*rhow

        enddo
      enddo

      end subroutine remove_extra_snow_to_ocean