! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ! + + ! + glimmer_routing.f90 - part of the Glimmer-CISM ice model + ! + + ! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ! ! Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010 ! Glimmer-CISM contributors - see AUTHORS file for list of contributors ! ! This file is part of Glimmer-CISM. ! ! Glimmer-CISM is free software: you can redistribute it and/or modify ! it under the terms of the GNU General Public License as published by ! the Free Software Foundation, either version 2 of the License, or (at ! your option) any later version. ! ! Glimmer-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 ! GNU General Public License for more details. ! ! You should have received a copy of the GNU General Public License ! along with Glimmer-CISM. If not, see . ! ! Glimmer-CISM is hosted on BerliOS.de: ! https://developer.berlios.de/projects/glimmer-cism/ ! ! +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ #ifdef HAVE_CONFIG_H #include "config.inc" #endif module glimmer_routing use glimmer_global,only: rk,sp private public flow_router contains subroutine flow_router(surface,input,output,mask,dx,dy) !*FD Routes water from input field to its destination, !*FD according to a surface elevation field. The method used !*FD is by Quinn et. al. (1991) real(sp),dimension(:,:),intent(in) :: surface !*FD Surface elevation real(rk),dimension(:,:),intent(in) :: input !*FD Input water field real(rk),dimension(:,:),intent(out) :: output !*FD Output water field integer, dimension(:,:),intent(in) :: mask !*FD Masked points real(rk), intent(in) :: dx !*FD $x$ grid-length real(rk), intent(in) :: dy !*FD $y$ grid-length ! Internal variables -------------------------------------- integer :: nx,ny,k,nn,cx,cy,px,py,x,y integer, dimension(:,:),allocatable :: sorted real(rk),dimension(:,:),allocatable :: flats,surfcopy real(rk),dimension(-1:1,-1:1) :: slopes real(rk),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,:)=(/4d0,2d0*dx/dy,4d0/) dists(0,:)=(/2d0*dy/dx,0d0,2d0*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.0 ! 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) continue ! 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.ne.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.ne.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 glimmer_routing