!-------------------------------------- LICENCE BEGIN ------------------------------------
!Environment Canada - Atmospheric Science and Technology License/Disclaimer, 
!                     version 3; Last Modified: May 7, 2008.
!This is free but copyrighted software; you can use/redistribute/modify it under the terms 
!of the Environment Canada - Atmospheric Science and Technology License/Disclaimer 
!version 3 or (at your option) any later version that should be found at: 
!http://collaboration.cmc.ec.gc.ca/science/rpn.comm/license.html 
!
!This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; 
!without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
!See the above mentioned License/Disclaimer for more details.
!You should have received a copy of the License/Disclaimer along with this software; 
!if not, you can write to: EC-RPN COMM Group, 2121 TransCanada, suite 500, Dorval (Quebec), 
!CANADA, H9P 1J3; or send e-mail to service.rpn@ec.gc.ca
!-------------------------------------- LICENCE END --------------------------------------
***s/r adw_main_2_pos_settls - Same as dw_main_2_pos but with SETTLS option 
*
#include "model_macros_f.h"
*

      subroutine adw_main_2_pos_settls ( F_it, F_u, F_v, F_w ) 1,24
*
      implicit none
*
      integer F_it
      real F_u(*),F_v(*),F_w(*)
*
*author
*     alain patoine
*
*revision
* v2_31 - Desgagne M.    - removed stkmemw
* v2_31 - Tanguay M.     - gem_stop if Adw_fro_a.gt.0.and.V4dg_conf.ne.0
* v3_00 - Desgagne & Lee - Lam configuration
* v3_02 - Lee V.         - revert adw_exch_1 for GLB only, added adw_ckbd_lam
* v3_10 - Corbeil & Desgagne & Lee - AIXport+Opti+OpenMP
* v3_20 - Valin & Tanguay - Optimized SETINT/TRILIN 
* v3_20 - Gravel S.       - Change test a lower and upper boundaries
* v3_20 - Tanguay M.      - Improve alarm when points outside advection grid
* v3_20 - Dugas B.        - correct calculation for LAM when Glb_pil gt 7
* v3_21 - Lee V.          - bug correction, yth should not be modified.
* v3_31 - Desgagne M.     - new scope for operator + adw_cliptraj (LAM)
* v3_31 - Tanguay M.      - SETTLS option
*
*language
*     fortran 77
*
*object
*     see id section
*
*arguments
*______________________________________________________________________
*        |                                                       |     |
* NAME   | DESCRIPTION                                           | I/O |
*--------|-------------------------------------------------------|-----|
* F_it   | total number of iterations for trajectory             |  i  |
*        |                                                       |     |
* F_u,F_v| input:  3 components of wind on advection grid        |  io |
* F_w    | output: 3 components of upstream positions at t1      |     |
*________|_______________________________________________________|_____|
*
*implicits
#include "glb_ld.cdk"
#include "glb_pil.cdk"
#include "lun.cdk"
#include "geomg.cdk"
#include "adw.cdk"
#include "dcst.cdk"
#include "cstv.cdk"
#include "vth.cdk"
#include "vt1.cdk"
#include "v4dg.cdk"
#include "lctl.cdk"
#include "step.cdk"
#include "orh.cdk"
#include "schm.cdk"
#include "ptopo.cdk"
*
*modules
      integer  vmmlod, vmmget, vmmuld
      external vmmlod, vmmget, vmmuld
************************************************************************
      logical doh
*
      integer pnerr, pnlkey1(30), pnlod
*
      integer i, j, k, n, ij, ijk, nij, nijk, it
      integer i1,j1,k1,nn
*
      integer outside,sum_outside,ier
*
      integer, dimension(l_ni*l_nj*l_nk) :: n1
      real,    dimension(l_ni*l_nj*l_nk) :: capx1,capy1,capz1
      real,    dimension(l_ni*l_nj*l_nk) :: wrkx1,wrky1,wrkz1,wrkc1,wrk_yt1
      integer, dimension(:), allocatable :: n2
      real,    dimension(:), allocatable :: capx2,capy2,capz2
      real,    dimension(:), allocatable :: xpos2,ypos2,zpos2
*
      real dummy, dth
      real*8 r2pi_8,two,half,pdp,pdm
      parameter (two = 2.0,half=0.5)
*
      integer i0,in,j0,jn,indice
*
      logical done_once_L
      save done_once_L
      data done_once_L /.false./
*
************************************************************************
      if( .not. Adw_nosetint_L ) call gem_stop ('ADW_MAIN_2_POS_SETTLS 1 not done',-1) 
************************************************************************
*
      if (Lun_debug_L) write (Lun_out,1000)
*
      nij    = l_ni   *l_nj
      nijk   = l_ni   *l_nj   *l_nk
*
      r2pi_8 = two * Dcst_pi_8
      dth    = Cstv_dt_8/2.
      pdp    = 1.d0 + 1.d-6
      pdm    = 1.d0 - 1.d-6
*
      pnlkey1(1) = VMM_KEY(xth)
      pnlkey1(2) = VMM_KEY(yth)
      pnlkey1(3) = VMM_KEY(zth)
      pnlkey1(4) = VMM_KEY(xcth)
      pnlkey1(5) = VMM_KEY(ycth)
      pnlkey1(6) = VMM_KEY(zcth)
      pnlkey1(7) = VMM_KEY(xt1)
      pnlkey1(8) = VMM_KEY(yt1)
      pnlkey1(9) = VMM_KEY(zt1)
      pnlkey1(10)= VMM_KEY(xct1)
      pnlkey1(11)= VMM_KEY(yct1)
      pnlkey1(12)= VMM_KEY(zct1)
      pnlkey1(13)= VMM_KEY(uth)
      pnlkey1(14)= VMM_KEY(vth)
      pnlkey1(15)= VMM_KEY(psdth)
*
      pnerr = vmmlod(pnlkey1,15)
*
      pnerr = VMM_GET_VAR(xth)
      pnerr = VMM_GET_VAR(yth)
      pnerr = VMM_GET_VAR(zth)
      pnerr = VMM_GET_VAR(xcth)
      pnerr = VMM_GET_VAR(ycth)
      pnerr = VMM_GET_VAR(zcth)
      pnerr = VMM_GET_VAR(xt1)
      pnerr = VMM_GET_VAR(yt1)
      pnerr = VMM_GET_VAR(zt1)
      pnerr = VMM_GET_VAR(xct1)
      pnerr = VMM_GET_VAR(yct1)
      pnerr = VMM_GET_VAR(zct1)
      pnerr = VMM_GET_VAR(uth)
      pnerr = VMM_GET_VAR(vth)
      pnerr = VMM_GET_VAR(psdth)
*
      i0=1
      in=l_ni
      j0=1
      jn=l_nj
      if (G_lam) then
          if (l_west)  i0=pil_w
          if (l_east)  in=l_niu - pil_e + 2
          if (l_south) j0=pil_s
          if (l_north) jn=l_njv - pil_n + 2
      endif
*
************************************************************************
      do it=1,F_it
************************************************************************
                     doh = .false.
      if (it .eq. 1) doh = .true.
*
      do n = 1,nijk
      wrk_yt1(n) = yt1(n)
      enddo

      if (G_lam) then
*
          call adw_cliptraj ( xt1, wrk_yt1, i0, in, j0, jn, 'IN1POS' )
*
      else
*
          call adw_exch_1 ( wrkx1, wrky1, wrkz1, wrkc1,xt1,wrk_yt1,zt1 )
*
          if ( V4dg_conf.ne.0.0 ) then
*
               outside = 0
*
               if ( Adw_fro_a .gt. 0 ) outside = 1
*
               sum_outside = 0
               call rpn_comm_Allreduce(outside,sum_outside,1,"MPI_INTEGER",
     $                                 "MPI_SUM","grid",ier)
*
            if(sum_outside.ne.0.and..not.done_once_L.and.Ptopo_myproc.eq.0) then
                write(Lun_out,*) 'NUMBER OF PE WITH OUTSIDERS IN ADW_MAIN_2_POS_SETTLS AT current TIME-CN-IT = ',sum_outside
                call flush(Lun_out)
            endif
*
          endif
*
          allocate(capx2(max(1,Adw_fro_a)),
     %             capy2(max(1,Adw_fro_a)),
     %             capz2(max(1,Adw_fro_a)),
     %             xpos2 (max(1,Adw_fro_a)),
     %             ypos2 (max(1,Adw_fro_a)),
     %             zpos2 (max(1,Adw_fro_a)),
     %             n2 (max(1,Adw_fro_a)) )
          call adw_exch_2 ( xpos2, ypos2, zpos2,
     %                  wrkx1, wrky1, wrkz1,
     %                  Adw_fro_n, Adw_fro_s, Adw_fro_a,
     %                  Adw_for_n, Adw_for_s, Adw_for_a, 3 )
*
      endif
*
*     Part  I of interpolated wind at xth,yth,zth: Interpolate F_u,F_v_F_w at xt1,yt1,zt1
*     -----------------------------------------------------------------------------------
      Adw_hor_L = doh 
      Adw_ver_L = .true. 
      call adw_trilin_turbo (wrkx1,F_u,1.0,xt1,wrk_yt1,zt1,capz1,
     %                       Adw_Fn_I,nijk,i0,in,j0,jn,l_nk)
      call adw_trilin_turbo (wrky1,F_v,1.0,xt1,wrk_yt1,zt1,capz1,
     %                       Adw_Fn_I,nijk,i0,in,j0,jn,l_nk)
*
      if (.not.G_lam) then

         if ( Adw_fro_a .gt. 0 ) then
*
*
              if ( Adw_ckbd_L ) call adw_ckbd ( ypos2 )
*
              call adw_setint ( n2, capx2, dummy, dummy, capy2, dummy,
     %                     dummy, capz2, dummy, xpos2, ypos2, zpos2,
     %                    .true., .true., .true., Adw_fro_a,1,Adw_fro_a,1,1,1)
*
              call adw_trilin ( xpos2, F_u, 1.0, n2, capx2, capy2, capz2,
     %                     Adw_fro_a,1,Adw_fro_a,1,1,1)
              call adw_trilin ( ypos2, F_v, 1.0, n2, capx2, capy2, capz2,
     %                     Adw_fro_a,1,Adw_fro_a,1,1,1)
*
         endif
*
         call adw_exch_2 ( wrkz1, wrk_yt1, dummy,
     %                  xpos2, ypos2, dummy,
     %                  Adw_for_n, Adw_for_s, Adw_for_a,
     %                  Adw_fro_n, Adw_fro_s, Adw_fro_a, 2)
*
         if ( Adw_for_a .gt. 0 )
     %         call adw_exch_3 ( wrkx1, wrky1, wrkz1, wrk_yt1, wrkc1, 2 )
*
         deallocate(capx2,capy2,capz2,xpos2,ypos2,zpos2,n2)
      endif
*
*     Part II of interpolated wind at xth,yth,zth: Add to uth,vth
*     -----------------------------------------------------------
      do k=1,l_nk
      do j=1,l_nj
      do i=1,l_ni
         indice = l_ni*l_nj*(k-1) + l_ni*(j-1) + i
         wrkx1(indice) = .5*(wrkx1(indice) + uth(i,j,k))
         wrky1(indice) = .5*(wrky1(indice) + vth(i,j,k))
      enddo
      enddo
      enddo
*
************************************************************************
      call adw_trajsp ( xth, yth, xcth, ycth, zcth, wrkx1, wrky1, dth,
     %                  i0,in,j0,jn)
************************************************************************
      call adw_trajex (xt1, yt1, xct1, yct1, zct1, xcth, ycth, zcth,
     %                  i0,in,j0,jn)
*
      do n = 1,nijk
         wrk_yt1(n) = yt1(n)
      enddo
*
      if (G_lam) then
*
          call adw_cliptraj ( xt1, wrk_yt1, i0, in, j0, jn, 'IN2POS' )
*
      else
*
          call adw_exch_1 ( wrkx1, wrky1, wrkz1, wrkc1,xt1,wrk_yt1,zt1 )
*
          allocate(capx2(max(1,Adw_fro_a)),
     %             capy2(max(1,Adw_fro_a)),
     %             capz2(max(1,Adw_fro_a)),
     %             xpos2 (max(1,Adw_fro_a)),
     %             ypos2 (max(1,Adw_fro_a)),
     %             zpos2 (max(1,Adw_fro_a)),
     %             n2 (max(1,Adw_fro_a)) )
*
          call adw_exch_2 ( xpos2, ypos2, zpos2,
     %                  wrkx1, wrky1, wrkz1,
     %                  Adw_fro_n, Adw_fro_s, Adw_fro_a,
     %                  Adw_for_n, Adw_for_s, Adw_for_a, 3 )
*
      endif
*
      Adw_hor_L = .true. 
      Adw_ver_L = .false. 
      call adw_trilin_turbo (wrkz1,F_w,-dth,xt1,wrk_yt1,zt1,capz1,
     %                       Adw_Fn_I,nijk,i0,in,j0,jn,l_nk)
*
      if (.not.G_lam) then
         if ( Adw_fro_a .gt. 0 ) then
*
              if ( Adw_ckbd_L ) call adw_ckbd ( ypos2 )
*
              call adw_setint ( n2, capx2, dummy, dummy, capy2, dummy,
     %                     dummy, capz2, dummy, xpos2, ypos2, zpos2,
     %                    .true., .true., .true., Adw_fro_a,1,Adw_fro_a,1,1,1)
*
              call adw_trilin ( xpos2, F_w, -dth, n2, capx2,capy2,capz2,
     %                     Adw_fro_a,1,Adw_fro_a,1,1,1)
*
         endif
*
         call adw_exch_2 ( wrkx1, dummy, dummy,
     %                  xpos2, dummy, dummy,
     %                  Adw_for_n, Adw_for_s, Adw_for_a,
     %                  Adw_fro_n, Adw_fro_s, Adw_fro_a, 1)
*
         if ( Adw_for_a .gt. 0 )
     %        call adw_exch_3 ( wrkz1, dummy, wrkx1, dummy, wrkc1, 1 )
*
         deallocate(capx2,capy2,capz2,xpos2,ypos2,zpos2,n2)
      endif
*
*     Part II of interpolated wind at xth,yth,zth: Add to psdth
*     ---------------------------------------------------------
      do k=1,l_nk
      do j=1,l_nj
      do i=1,l_ni
         indice = l_ni*l_nj*(k-1) + l_ni*(j-1) + i
         wrkz1(indice) = .5*(wrkz1(indice) - dth*psdth(i,j,k))
      enddo
      enddo
      enddo
*
************************************************************************
!$omp parallel private(n)
!$omp do
      do k = 2,l_nk-1
      do j = j0,jn
      do i = i0,in
         n = (k-1)*nij + ((j-1)*l_ni) + i
         zt1(n) = Geomg_z_8(k) + two*wrkz1(n)
         zt1(n) = min( pdm*Geomg_z_8(l_nk), 
     %                max( 1.0d0*zt1(n), pdp*Geomg_z_8(1) ) )
         zth(n) = half*(zt1(n) + Geomg_z_8(k))
      enddo
      enddo
      enddo
!$omp enddo
!$omp end parallel
************************************************************************
      enddo ! end of iterations loop
************************************************************************
      call adw_trajex (xt1, yt1, xct1, yct1, zct1, xcth, ycth, zcth,
     %                  i0,in,j0,jn)
*
*     Store xt1,yt1,zt1 positions in F_u,F_v,F_w (used in adw_main_3_int)
*     -------------------------------------------------------------------
      do i=1,l_ni*l_nj*l_nk
         F_u(i) = xt1(i)
         F_v(i) = yt1(i)
      enddo
*
!$omp parallel private(n)
!$omp do
      do j = j0,jn
      do i = i0,in
         n = ((j-1)*l_ni) + i   !for k=1
         F_w(n) = Geomg_z_8(1)
         n = (l_nk-1)*nij+((j-1)*l_ni) + i !for k=l_nk
         F_w(n) = Geomg_z_8(l_nk)
      enddo
      enddo
!$omp enddo
!$omp do
      do k = 2,l_nk-1
         do j = j0,jn
         do i = i0,in
            n=(k-1)*nij+((j-1)*l_ni) + i
            F_w(n) = zth(n) - Geomg_z_8(k)
            F_w(n) = Geomg_z_8(k) + 2.0 * F_w(n)
         enddo
         enddo
      enddo
!$omp enddo
!$omp end parallel
*
      pnerr = vmmuld(-1,0)
*
      if (V4dg_conf.ne.0.and.Lctl_step.eq.Step_total) done_once_L = .true.
*
 1000 format(3X,'CALC UPSTREAM POSITIONS: (S/R ADW_MAIN_2_POS_SETTLS)')
      return
      end