subroutine ugwp_triggers
        implicit none
        write(6,*) ' physics-based triggers for UGWP ' 
        end subroutine ugwp_triggers
!	
     SUBROUTINE  subs_diag_geo(nx, ny,  lat, lon, rlat, rlon, dy, dx,  &
                               cosv, rlatc, brcos, brcos2, dlam1, dlam2, dlat, divJp, divJm)
      use ugwp_common , only : deg_to_rad
      
      implicit none
       integer :: nx, ny
       real    :: lon(nx), lat(ny)
       real    :: rlon(nx), rlat(ny) , cosv(ny), tanlat(ny)  
       real    :: rlatc(ny-1), brcos(ny), brcos2(ny)              
       real    :: earth_r, ra1, ra2, dx, dy, dlat
       real    :: dlam1(ny), dlam2(ny),  divJp(ny), divJm(ny)
       integer :: j
!
!    specify common constants and
!    geometric factors to compute deriv-es etc ...
!    coriolis coslat tan etc...
!
      earth_r = 6370.e3
      ra1     = 1.0 / earth_r
      ra2     = ra1*ra1
!
      rlat   = lat*deg_to_rad
      rlon   = lon*deg_to_rad
      tanlat = atan(rlat)
      cosv   =  cos(rlat)     
      dy     = rlat(2)-rlat(1)
      dx     = rlon(2)-rlon(1)
!
      do j=1, ny-1
        rlatc(j) = 0.5 * (rlat(j)+rlat(j+1))
      enddo
!
      do j=2, ny-1
        brcos(j) = 1.0 / cos(rlat(j))*ra1
      enddo       
       
      brcos(1)  = brcos(2)
      brcos(ny) = brcos(ny-1)
      brcos2    = brcos*brcos
!
      dlam1 = brcos  / (dx+dx)
      dlam2 = brcos2 / (dx*dx)
  
      dlat = ra1 / (dy+dy)
  
      divJp = dlat*cosv
      divJM = dlat*cosv
!
      do  j=2, ny-1 
        divJp(j) = dlat*cosv(j+1)/cosv(j) 
        divJM(j) = dlat*cosv(j-1)/cosv(j) 
      enddo
      divJp(1)  = divjp(2)   !*divjp(1)/divjp(2)
      divJp(ny) = divjp(1)
      divJM(1)  = divjM(2)   !*divjM(1)/divjM(2)
      divJM(ny) = divjM(1)
!
      return
      end SUBROUTINE  subs_diag_geo
!      
      subroutine get_xy_pt(V, Vx, Vy, nx, ny, dlam1, dlat)
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
! compute for each Vert-column: grad(V)
! periodic in X and central diff ...
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
      implicit none
      integer :: nx, ny
      real    :: V(nx, ny), dlam1(ny), dlat
      real    :: Vx(nx, ny), Vy(nx, ny)      
      integer :: i, j
      do i=2, nx-1 
        Vx(i,:) = dlam1(:)*(V(i+1,:)-V(i-1,:))
      enddo
      Vx(1,:)  =  dlam1(:)*(V(2,:)-V(nx,:))
      Vx(nx,:) =  dlam1(:)*(V(1,:)-V(nx-1,:))

      do j=2, ny-1
        Vy(:,j) = dlat*(V(:,j+1)-V(:, j-1))
      enddo 
      Vy(:, 1) = dlat*2.*(V(:,2)-V(:,1))
      Vy(:,ny) = dlat*2.*(V(:,ny)-V(:,ny-1))

    end subroutine get_xy_pt
    
    subroutine get_xyd_wind( V, Vx, Vy, Vyd, nx, ny, dlam1, dlat, divJp, divJm)
!    
! compute for each Vert-column: grad(V)
!~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
      implicit none
      integer :: nx, ny
      real    :: V(nx, ny), dlam1(ny), dlat
      real    :: Divjp(ny), Divjm(ny)
      real    :: Vx(nx, ny), Vy(nx, ny), Vyd(nx, ny)      
      integer :: i, j
      do i=2, nx-1 
        Vx(i,:) = dlam1(:)*(V(i+1,:)-V(i-1,:))
      enddo
      Vx(1,:)  =  dlam1(:)*(V(2,:)-V(nx,:))
      Vx(nx,:) =  dlam1(:)*(V(1,:)-V(nx-1,:))

      do j=2, ny-1
        Vy(:,j) = dlat*(V(:,j+1)-V(:, j-1))
      enddo 
       Vy(:, 1) = dlat*2.*(V(:,2)-V(:,1))
       Vy(:,ny) = dlat*2.*(V(:,ny)-V(:,ny-1))
!~~~~~~~~~~~~~~~~~~~~
! 1/cos*d(vcos)/dy
!~~~~~~~~~~~~~~~~~~~~
      do j=2, ny-1      
        Vyd(:,j) = divJP(j)*V(:,j+1)-V(:, j-1)*divJM(j)
      enddo
      Vyd(:, 1) =  Vyd(:,2) 
      Vyd(:,ny) = Vyd(:,ny-1) 

      end  subroutine get_xyd_wind

      subroutine trig3d_fjets( nx, ny, nz, U, V, T, Q, P3D, PS, delp, delz, lon, lat, pmid, trig3d_fgf)
      implicit none
      integer ::  nx, ny, nz
      real    ::  lon(nx), lat(ny)
!      
      real, dimension(nz)          :: pmid
      real, dimension(nx, ny, nz)  :: U, V, T, Q, delp, delz, p3d
      real, dimension(nx, ny    )  :: PS                
      real, dimension(nx, ny, nz)  :: trig3d_fgf
!
! locals
!      
      real, dimension(nx, ny)  ::   ux, uy, uyd, vy, vx, vyd, ptx, pty     
      integer :: k, i, j
      
      real, parameter :: cappa=2./7., pref=1.e5
      real, dimension(nx, ny)  :: pt, w1, w2      
      
      real    :: rlon(nx), rlat(ny) , cosv(ny), tanlat(ny)  
      real    :: rlatc(ny-1), brcos(ny), brcos2(ny)              

      real    ::  dx, dy, dlat
       real    :: dlam1(ny), dlam2(ny),  divJp(ny), divJm(ny)  
       
            
      call subs_diag_geo(nx, ny,  lat, lon, rlat, rlon, dy, dx,  &
           cosv, rlatc, brcos, brcos2, dlam1, dlam2, dlat, divJp, divJm)

      do k=1, nz 
        w1(:,:)  = P3d(:,:,k)
        w2(:,:)  = T(:,:,k)

        pt = w2*(pref/w1)**cappa
        call get_xy_pt(Pt, ptx, pty, nx, ny, dlam1, dlat)
        w1(:,:) = V(:,:, K)
        call get_xyd_wind( w1, Vx, Vy, Vyd, nx, ny, dlam1, dlat, divJp, divJm)
        w1(:,:) = U(:,:, K)
        call get_xyd_wind( w1, Ux, Uy, Uyd, nx, ny, dlam1, dlat, divJp, divJm)

        trig3d_fgf(:,:,k) =   -ptx*ptx*ux - pty*pty*vy -(vx+uyd)*ptx*pty

      enddo
      end  subroutine trig3d_fjets
      
      subroutine trig3d_okubo( nx, ny, nz, U, V, T, Q, P3d, PS, delp, delz, lon, lat, pmid, trig3d_okw)
      implicit none
      integer ::  nx, ny, nz
      real    ::  lon(nx), lat(ny)
!      
      real, dimension(nz)          :: pmid
      real, dimension(nx, ny, nz)  :: U, V, T, Q, delp, delz, p3d
      real, dimension(nx, ny    )  :: PS                
      real, dimension(nx, ny, nz)  :: trig3d_okw
!
! locals
!      
      real, dimension(nx, ny)  ::   ux, uy, uyd, vy, vx, vyd, ptx, pty     
      integer :: k, i, j
      
      real, parameter :: cappa=2./7., pref=1.e5
      real, dimension(nx, ny)  :: pt, w1, w2, d1     
      
      real    :: rlon(nx), rlat(ny) , cosv(ny), tanlat(ny)  
      real    :: rlatc(ny-1), brcos(ny), brcos2(ny)              

      real    ::  dx, dy, dlat
      real    :: dlam1(ny), dlam2(ny),  divJp(ny), divJm(ny) 
             
      call subs_diag_geo(nx, ny,  lat, lon, rlat, rlon, dy, dx,  &
           cosv, rlatc, brcos, brcos2, dlam1, dlam2, dlat, divJp, divJm)

      do k=1, nz 
        w1(:,:)  = P3d(:,:,k)
        w2(:,:)  = T(:,:,k)

        pt = w2*(pref/w1)**cappa
        call get_xy_pt(Pt, ptx, pty, nx, ny, dlam1, dlat)
        w1(:,:) = V(:,:, K)
        call get_xyd_wind( w1, Vx, Vy, Vyd, nx, ny, dlam1, dlat, divJp, divJm)
        w1(:,:) = U(:,:, K)
        call get_xyd_wind( w1, Ux, Uy, Uyd, nx, ny, dlam1, dlat, divJp, divJm)

        trig3d_okw(:,:,k) =   -ptx*ptx*ux - pty*pty*vy -(vx+uyd)*ptx*pty
        w1 = (Ux -Vy)*(Ux-Vy) + (Vx +Uy)*(Vx+Uy)      ! S2
        W2 =  (Vx - Uyd)*(Vx - Uyd)
        D1 =  Ux + Vyd
     trig3d_okw(:,:,k) = W1 -W2
!    trig3d_okw(:, :, k)  =S2 -W2
!    trig3d_okw(:, :, k)  =D1*D1 + 4*(Vx*Uyd -Ux*Vyd)                         !  ocean
!    trig3d_okw(:, :, k) = trig3d_okw(:,:,k) + D1*D1 + 2.*D1*sqrt(abs(W1-W2)) !  S2 =W1Ted-luk	
      enddo   
      end  subroutine trig3d_okubo     
!      
      subroutine trig3d_dconv(nx, ny, nz, U, V, T, Q, P3d, PS, delp, delz, lon, lat, pmid, trig3d_conv, &
                              dcheat3d, precip2d, cld_klevs2d, scheat3d)

      implicit none
      integer ::  nx, ny, nz
      real    ::  lon(nx), lat(ny)
!      
      real, dimension(nz)          :: pmid
      real, dimension(nx, ny, nz)  :: U, V, T, Q, delp, delz, p3d
      real, dimension(nx, ny    )  :: PS                
      real, dimension(nx, ny, nz)  :: trig3d_conv
      
      real, dimension(nx, ny, nz)  :: dcheat3d, scheat3d                       
      real, dimension(nx, ny    )  :: precip2d
      integer,dimension(nx, ny, 3 ):: cld_klevs2d
      integer :: k
      end subroutine trig3d_dconv

      subroutine cires_3d_triggers( nx, ny, nz, lon, lat, pmid,          &
        U, V, W, T, Q, delp, delz, p3d, PS, HS, Hyam, Hybm, Hyai, Hybi,  &
        trig3d_okw, trig3d_fgf, trig3d_conv,                             &
        dcheat3d, precip2d, cld_klevs2d, scheat3d) 

      implicit none
      integer ::  nx, ny, nz
      real    ::  lon(nx), lat(ny)
!
! reversed ???  Hyai, Hybi , pmid
!      
      real, dimension(nz+2)        :: Hyai, Hybi
      real, dimension(nz+1)        :: Hyam, Hybm
!      
      real, dimension(nz)          :: pmid
      real, dimension(nx, ny, nz)  :: U, V, W, T, Q, delp, delz, p3d
      real, dimension(nx, ny    )  :: PS, HS                 
      real, dimension(nx, ny, nz)  :: trig3d_okw, trig3d_fgf, trig3d_conv
      real, dimension(nx, ny, nz)  :: dcheat3d, scheat3d                       
      real, dimension(nx, ny    )  :: precip2d
      integer,dimension(nx, ny, 3 ):: cld_klevs2d
      real    :: dzkm, zkm
      integer :: k
!==================================================================================      
! fgf and OW-triggers
! read PRECIP + SH/DC conv heating  + cloud-top-bot-middle from "separate" file !!!
!
!===================================================================================  

      call trig3d_fjets( nx, ny, nz, U, V, T, Q, P3D, PS, delp, delz, lon, lat, pmid, trig3d_fgf) 
      call trig3d_okubo( nx, ny, nz, U, V, T, Q, P3D, PS, delp, delz, lon, lat, pmid, trig3d_okw)
      call trig3d_dconv(nx, ny, nz, U, V, T, Q,   P3D, PS, delp, delz, lon, lat, pmid, trig3d_conv, &
         dcheat3d, precip2d, cld_klevs2d, scheat3d)  
!=====================================================================================================
! output of triggers: trig3d_fgf, trig3d_okw, trig3d_conv, cheat3d, precip2d, cld_klevs2d, scheat3d
!
! Bulk momentum flux=/ 0 and levels for launches
!
!=====================================================================================================	                
 111  format(i6, 4(3x, F8.3),  '  trigger-grid ')     
 
      do k=1, nz-1
       zkm  = -7.*alog(pmid(k)*1.e-3)
       dzkm = zkm +7.*alog(pmid(k+1)*1.e-3)
       write(6,111) k, hybi(k), pmid(k), zkm, dzkm !' triggers '
      enddo
      
      end subroutine cires_3d_triggers
!==================================================================================      
!                              tot-flux  launch  0 or 1 # of Launches 
! specify time-dep bulk sources:   taub, klev,  if_src, nf_src
!
!==================================================================================
      subroutine get_spectra_tau_convgw &
      (nw, im, levs, dcheat,  scheat, precip, icld, xlatd, sinlat, coslat,taub, klev, if_src, nf_src)
!
! temporarily can put GEOS-5/MERRA-2 GW-lat dependent function
!      
      integer                   :: nw, im, levs 
      integer,dimension(im,3)   :: icld   
      real, dimension(im, levs) :: dcheat,  scheat   
      real, dimension(im)       :: precip, xlatd, sinlat, coslat      
      real, dimension(im)       :: taub
      integer, dimension(im)    :: klev, if_src
      integer ::  nf_src
!
! locals
      real, parameter           ::  precip_max = 100.   ! mm/day
      real, parameter           ::  tau_amp    = 35.e-3  ! 35 mPa   
       
      integer  :: i, k, klow, ktop, kmid
      real     :: dtot, dmax, daver
!      
      nf_src = 0
      if_src(1:im) = 0 
      taub(1:im)   = 0.0
      do i=1, im
        klow = icld(i,1)
        ktop = icld(i,2)
        kmid=  icld(i,3)
        if (klow == -99 .and.  ktop == -99) then 
          cycle
        else 
          klev(i) = ktop
          k = klow
          klev(i) = k
          dmax = abs(dcheat(i,k) + scheat(i,k))
          do k=klow+1, ktop
            dtot =abs(dcheat(i,k) + scheat(i,k))
            if ( dtot >  dmax) then
              klev(i) = k
              dmax =  dtot
            endif  
          enddo
!	  
! klev  as  max( dcheat(i,k) + scheat)
!	vertical width of conv-heating
!  
! counts/triiger=1   & taub(i) 
!
          nf_src = nf_src +1
          if_src(i) = 1          
          taub(i) = tau_amp* precip(i)/precip_max*coslat(i)
        endif 

      enddo
!	
!  100 mb launch  and MERRA-2 slat-forcing
!      
      call Slat_geos5(im, xlatd, taub)
      nf_src =im
      do i=1, im
        if_src(i) = 1
        klev(i)   = 127-45
      enddo
    
! with info on precip/clouds/dc_heat create Bulk 
!        taub(im), klev(im)      
!   
!      print *, '   get_spectra_tau_convgw '  
      end subroutine get_spectra_tau_convgw
!
      subroutine get_spectra_tau_nstgw(nw, im, levs, trig_fgf, xlatd, sinlat, coslat, taub, klev, if_src, nf_src)
      integer                      :: nw, im, levs 
      real, dimension(im, levs)    :: trig_fgf
!      real, dimension(im, levs+1)  :: pint      
      real, dimension(im)          :: xlatd, sinlat, coslat        
      real, dimension(im)          :: taub
      integer, dimension(im)          :: klev, if_src
      integer ::  nf_src
! locals
      real, parameter           ::  tlim_fgf = 100.     ! trig_fgf > tlim_fgf, launch waves should scale-dependent
      real, parameter           ::  tau_amp   = 35.e-3  ! 35 mPa
      real, parameter           ::  pmax = 750.e2,  pmin = 100.e2  
      integer, parameter        ::  klow =127-92,   ktop=127-45
      integer, parameter        ::  kwidth = ktop-klow+1   
      integer  :: i, k,  kex
      real     :: dtot, dmax, daver      
      real     :: fnorm, tau_min     
      nf_src = 0      
      if_src(1:im) = 0 
      taub(1:im)   = 0.0
      fnorm = 1.0 / float(kwidth)
      tau_min = tau_amp*fnorm
      do i=1, im
!
! only trop-c fjets so find max(trig_fgf) => klev
!                      use abs-values to scale tau_amp
!
  
        k = klow
        klev(i) = k
        dmax = abs(trig_fgf(i,k))
        kex  = 0
        if (dmax >= tlim_fgf) kex = kex+1 
        do k=klow+1, ktop
          dtot = abs(trig_fgf(i,k))
          if (dtot >= tlim_fgf) kex = kex+1 
          if ( dtot >  dmax) then
            klev(i) = k
            dmax    =  dtot
          endif  
        enddo

        if (dmax .ge. tlim_fgf) then
          nf_src = nf_src +1
          if_src(i) = 1          
          taub(i) = tau_min*float(kex)          !* precip(i)/precip_max*coslat(i)
        endif 

      enddo
!     
!      print *, '   get_spectra_tau_nstgw '
      call Slat_geos5(im, xlatd, taub)
      nf_src =im
      do i=1, im
        if_src(i) = 1
        klev(i) = 127-45     
      enddo
!                 
      end subroutine get_spectra_tau_nstgw   
! 
      subroutine get_spectra_tau_okw(nw, im, levs,  trig_okw, xlatd, sinlat, coslat, taub, klev, if_src, nf_src)
      integer                      :: nw, im, levs 
      real, dimension(im, levs)    :: trig_okw
!      real, dimension(im, levs+1)  :: pint    
      real, dimension(im)          :: xlatd, sinlat, coslat     
      real, dimension(im)          :: taub
      integer, dimension(im)       :: klev, if_src
      integer ::  nf_src
! locals
      real, parameter           ::  tlim_okw = 100.     ! trig_fgf > tlim_fgf, launch waves should scale-dependent
      real, parameter           ::  tau_amp   = 35.e-3  ! 35 mPa  
      real, parameter           ::  pmax = 750.e2,  pmin = 100.e2  
      integer, parameter        ::  klow =127-92,   ktop=127-45
      integer, parameter        ::  kwidth = ktop-klow+1   
      integer  :: i, k,  kex
      real     :: dtot, dmax, daver      
      real     :: fnorm, tau_min       
      
      nf_src = 0  
      if_src(1:im) = 0    
      taub(1:im) = 0.0    
       fnorm = 1./float(kwidth)
      tau_min = tau_amp*fnorm 
      print *, '   get_spectra_tau_okwgw '   
      do i=1, im
        k = klow
        klev(i) = k	     
        dmax = abs(trig_okw(i,k))
        kex = 0
        if (dmax >= tlim_okw) kex = kex+1 
        do k=klow+1, ktop
          dtot = abs(trig_okw(i,k))
          if (dtot >= tlim_fgf ) kex = kex+1 
          if ( dtot >  dmax) then
            klev(i) = k
            dmax =  dtot
          endif  
        enddo
!	  
        if (dmax >= tlim_okw) then
          nf_src = nf_src + 1
          if_src(i) = 1          
          taub(i) = tau_min*float(kex)          !* precip(i)/precip_max*coslat(i)
        endif 

      enddo 
      print *, '   get_spectra_tau_okwgw '           
      end subroutine get_spectra_tau_okw   
!
!
!      
      subroutine slat_geos5_tamp(im, tau_amp, xlatdeg, tau_gw)
!=================
! GEOS-5 & MERRA-2 lat-dependent GW-source function  tau(z=Zlaunch) =rho*<u'w'>
!=================
      implicit none
      integer :: im     
      real    :: tau_amp, xlatdeg(im), tau_gw(im)
      real    :: latdeg, flat_gw, tem
      integer :: i
      
!
! if-lat
!
      do i=1, im
        latdeg = abs(xlatdeg(i))    
        if (latdeg < 15.3) then
          tem = (latdeg-3.0) / 8.0
          flat_gw = 0.75 * exp(-tem * tem)
          if (flat_gw < 1.2 .and. latdeg <= 3.0) flat_gw = 0.75
        elseif (latdeg <  31.0 .and. latdeg >=  15.3) then
           flat_gw =  0.10
        elseif (latdeg <  60.0 .and. latdeg >=  31.0) then
          tem = (latdeg-60.0) / 23.0
          flat_gw =  0.50 * exp(- tem * tem)
        elseif (latdeg >=  60.0) then
          tem = (latdeg-60.0) / 70.0
          flat_gw =  0.50 * exp(- tem * tem)
        endif
        tau_gw(i) = tau_amp*flat_gw 
      enddo
!      
      end subroutine slat_geos5_tamp
      
      subroutine slat_geos5(im, xlatdeg, tau_gw)
!=================
! GEOS-5 & MERRA-2 lat-dependent GW-source function  tau(z=Zlaunch) =rho*<u'w'>
!=================
      implicit none
      integer :: im     
      real  :: xlatdeg(im)          
      real  :: tau_gw(im)
      real  :: latdeg
      real, parameter  :: tau_amp = 100.e-3
      real             :: trop_gw,  flat_gw 
      integer :: i
!
! if-lat
!
      trop_gw = 0.75
      do i=1, im
      latdeg = xlatdeg(i)    
      if (-15.3 < latdeg .and. latdeg < 15.3) then
          flat_gw = trop_gw*exp(-( (abs(latdeg)-3.)/8.0)**2)
          if (flat_gw < 1.2 .and. abs(latdeg) <= 3.) flat_gw = trop_gw
      else if (latdeg > -31. .and. latdeg <= -15.3) then
          flat_gw =  0.10
      else if (latdeg <  31. .and. latdeg >=  15.3) then
           flat_gw =  0.10
      else if (latdeg > -60. .and. latdeg <= -31.) then
        flat_gw =  0.50*exp(-((abs(latdeg)-60.)/23.)**2)
      else if (latdeg <  60. .and. latdeg >=  31.) then
        flat_gw =  0.50*exp(-((abs(latdeg)-60.)/23.)**2)
      else if (latdeg <= -60.) then
         flat_gw =  0.50*exp(-((abs(latdeg)-60.)/70.)**2)
      else if (latdeg >=  60.) then
         flat_gw =  0.50*exp(-((abs(latdeg)-60.)/70.)**2)
      end if
      tau_gw(i) = tau_amp*flat_gw 
      enddo
!      
      end subroutine slat_geos5
      subroutine init_nazdir(naz,  xaz,  yaz)
      use ugwp_common , only : pi2
      implicit none
      integer :: naz
      real, dimension(naz) :: xaz,  yaz
      integer :: idir
      real    :: phic, drad
      drad  = pi2/float(naz)
      if (naz.ne.4) then     
        do idir =1, naz
         Phic = drad*(float(idir)-1.0)
         xaz(idir) = cos(Phic)
         yaz(idir) = sin(Phic)
        enddo
      else 
!                         if (naz.eq.4) then
          xaz(1) = 1.0     !E
          yaz(1) = 0.0
          xaz(2) = 0.0     
          yaz(2) = 1.0     !N
          xaz(3) =-1.0     !W
          yaz(3) = 0.0
          xaz(4) = 0.0
          yaz(4) =-1.0     !S
      endif      
      end  subroutine init_nazdir