!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
!
! glint_routing.F90 - part of the Community Ice Sheet Model (CISM)
!
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
!
! Copyright (C) 2005-2014
! CISM contributors - see AUTHORS file for list of contributors
!
! This file is part of CISM.
!
! CISM is free software: you can redistribute it and/or modify it
! under the terms of the Lesser GNU General Public License as published
! by the Free Software Foundation, either version 3 of the License, or
! (at your option) any later version.
!
! CISM 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
! Lesser GNU General Public License for more details.
!
! You should have received a copy of the Lesser GNU General Public License
! along with CISM. If not, see .
!
!+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#ifdef HAVE_CONFIG_H
#include "config.inc"
#endif
module glint_routing
use glimmer_global,only: dp
implicit none
private
public flow_router
contains
subroutine flow_router(surface,input,output,mask,dx,dy)
! Routes water from input field to its destination,
! according to a surface elevation field. The method used
! is by Quinn et. al. (1991)
!NOTE: This subroutine will *not* work for multiple tasks.
real(dp),dimension(:,:),intent(in) :: surface ! Surface elevation
real(dp),dimension(:,:),intent(in) :: input ! Input water field
real(dp),dimension(:,:),intent(out) :: output ! Output water field
integer, dimension(:,:),intent(in) :: mask ! Masked points
real(dp), intent(in) :: dx ! $x$ grid-length
real(dp), intent(in) :: dy ! $y$ grid-length
! Internal variables --------------------------------------
integer :: nx,ny,k,nn,cx,cy,px,py,x,y
integer, dimension(:,:),allocatable :: sorted
real(dp),dimension(:,:),allocatable :: flats,surfcopy
real(dp),dimension(-1:1,-1:1) :: slopes
real(dp),dimension(-1:1,-1:1) :: dists
logical :: flag
! Set up grid dimensions ----------------------------------
nx=size(surface,1) ; ny=size(surface,2)
nn=nx*ny
dists(-1,:)= (/4.d0, 2.d0*dx/dy, 4.d0/)
dists(0,:) = (/2.d0*dy/dx, 0.d0, 2.d0*dy/dx/)
dists(1,:) = dists(-1,:)
! Allocate internal arrays and copy data ------------------
allocate(sorted(nn,2),flats(nx,ny),surfcopy(nx,ny))
surfcopy=surface
! Fill holes in data, and sort heights --------------------
call fillholes(surfcopy,flats,mask)
call heights_sort(surfcopy,sorted)
! Initialise output with input, which will then be redistributed
output=input
! Begin loop over points, highest first -------------------
do k=nn,1,-1
! Get location of current point -------------------------
x=sorted(k,1)
y=sorted(k,2)
! Reset flags and slope arrays --------------------------
flag=.true.
slopes=0.d0
! Loop over adjacent points, and calculate slopes -------
do cx=-1,1,1
do cy=-1,1,1
! If this is the centre point, ignore
if (cx == 0 .and. cy == 0) then
continue
else
! Otherwise do slope calculation
px=x+cx ; py=y+cy
if (px > 0 .and. px <= nx .and. py > 0 .and. py <= ny) then
if (surfcopy(px,py)= pivot) .and. (ll < rr))) exit
rr=rr-1
enddo
if (ll /= rr) then
index(ll) = index(rr)
ll=ll+1
endif
do
if (.not.((numbers(index(ll)) <= pivot) .and. (ll < rr))) exit
ll=ll+1
enddo
if (ll /= rr) then
index(rr) = index(ll)
rr=rr-1
endif
enddo
index(ll) = pivpos
pv_int = ll
ll = l_hold
rr = r_hold
if (ll < pv_int) call q_sort_index(numbers, index,ll, pv_int-1)
if (rr > pv_int) call q_sort_index(numbers, index,pv_int+1, rr)
end subroutine q_sort_index
end module glint_routing