|
dtopo_mod.f90.html |
|
|
Source file: dtopo_mod.f90
|
|
Directory: /home/rjl/git/rjleveque/clawpack-4.x/geoclaw/2d/lib
|
|
Converted: Sun May 15 2011 at 19:15:42
using clawcode2html
|
|
This documentation file will
not reflect any later changes in the source file.
|
! ============================================================================
! Program: /Users/mandli/src/claw44/branches/ktm-geoclaw-mod/2dxy/lib
! File: dtopo_mod
! Created: 2010-04-22
! Author: Kyle Mandli
! ============================================================================
! Copyright (C) 2010-04-22 Kyle Mandli
!
! Distributed under the terms of the Berkeley Software Distribution (BSD)
! license
! http://www.opensource.org/licenses/
! ============================================================================
! Module containing changing topography data
! ============================================================================
module dtopo_module
implicit none
! Work array
double precision, allocatable :: dtopowork(:)
! File data parameters
character*150, allocatable :: dtopofname(:)
double precision, allocatable :: xlowdtopo(:),ylowdtopo(:),xhidtopo(:)
double precision, allocatable :: yhidtopo(:),t0dtopo(:),tfdtopo(:)
double precision, allocatable :: dxdtopo(:),dydtopo(:),dtdtopo(:)
integer, allocatable :: mxdtopo(:),mydtopo(:),mtdtopo(:),mdtopo(:)
integer, allocatable :: minleveldtopo(:),maxleveldtopo(:),dtopotype(:)
integer, allocatable :: i0dtopo(:)
integer :: num_dtopo
double precision dz
logical, allocatable :: topoaltered(:)
contains
! ========================================================================
! set_dtopo(fname)
! ========================================================================
! Read moving topography info from setdtopo.data
! Time-dependend topography is used to initiate tsunami, for example.
!
! If num_dtopo = 0, no movement of topography specified.
!
! If num_dtopo = 1, the topo changes dynamically.
! the topofile can then be formated in the following ways
! dtopotype > 1: file contains a header, with a line for each record
! my; mx; mt; xlower; ylower; t0; dx; dy; dt;
! dtopotype = 1:
! Then the dtopofile should have 4 columns:
! time,longitude,latitude,vertical displacement(m) since t0
!
! Longitude and latitude advance in the standard GIS way from
! upper left corner across in x and then down in y.
! Time column advances most slowly.
! ========================================================================
subroutine set_dtopo(fname)
use geoclaw_module
use topo_module
implicit none
! Input arguments
character*25, optional, intent(in) :: fname
! Locals
character*25 :: file_name
integer, parameter :: iunit = 79
logical :: found_file
double precision :: xcell, xim, xip, ycell, yjm, yjp, ztopoij
double precision :: capac_area, deg2rad
integer :: i,m,ib,jb,ij,ijdtopo,jbr
! Function
double precision :: topointegral
! Common block
double precision :: tstart
common /ctstart/ tstart
write(GEO_PARM_UNIT,*) ' '
write(GEO_PARM_UNIT,*) '--------------------------------------------'
write(GEO_PARM_UNIT,*) 'SETDTOPO:'
write(GEO_PARM_UNIT,*) '-------------'
if (present(fname)) then
file_name = fname
else
file_name = 'setdtopo.data'
endif
inquire(file=file_name,exist=found_file)
if (.not. found_file) then
print *,'You must provide a file ', file_name
stop
endif
call opendatafile(iunit, file_name)
read(iunit,*) num_dtopo
write(GEO_PARM_UNIT,*) ' num dtopo files = ',num_dtopo
if (num_dtopo == 0) then
return
endif
! Allocate and read in dtopo info
allocate(dtopofname(num_dtopo),minleveldtopo(num_dtopo))
allocate(maxleveldtopo(num_dtopo),mxdtopo(num_dtopo))
allocate(mydtopo(num_dtopo),mtdtopo(num_dtopo),mdtopo(num_dtopo))
allocate(xlowdtopo(num_dtopo),ylowdtopo(num_dtopo),t0dtopo(num_dtopo))
allocate(xhidtopo(num_dtopo),yhidtopo(num_dtopo),tfdtopo(num_dtopo))
allocate(dtopotype(num_dtopo),i0dtopo(num_dtopo))
allocate(dxdtopo(num_dtopo),dydtopo(num_dtopo),dtdtopo(num_dtopo))
allocate(topoaltered(num_dtopo))
do i=1,num_dtopo
read(iunit,*) dtopofname(i)
read(iunit,*) dtopotype(i),minleveldtopo(i), maxleveldtopo(i)
write(GEO_PARM_UNIT,*) ' fname:',dtopofname(i)
write(GEO_PARM_UNIT,*) ' topo type:',dtopotype(i)
write(GEO_PARM_UNIT,*) ' minlevel, maxlevel:'
write(GEO_PARM_UNIT,*) minleveldtopo(i),maxleveldtopo(i)
! Read in header data
call read_dtopo_header(dtopofname(i),dtopotype(i),mxdtopo(i), &
mydtopo(i),mtdtopo(i),xlowdtopo(i),ylowdtopo(i),t0dtopo(i), &
xhidtopo(i),yhidtopo(i),tfdtopo(i),dxdtopo(i),dydtopo(i), &
dtdtopo(i))
mdtopo(i) = mxdtopo(i) * mydtopo(i) * mtdtopo(i)
enddo
! Indexing into work array
i0dtopo(1) = 1
if (num_dtopo > 1) then
do i=2,num_dtopo
i0dtopo(i) = i0dtopo(i-1) + mdtopo(i-1)
enddo
endif
! Allocate and read dtopo files
allocate(dtopowork(sum(mdtopo)))
do i=1,num_dtopo
call read_dtopo(mxdtopo(i),mydtopo(i),mtdtopo(i),dtopotype(i), &
dtopofname(i),dtopowork(i0dtopo(i):i0dtopo(i)+mdtopo(i)-1))
enddo
! ==============Fix topography for a restart==========================
! topoaltered is ordinarily initialized as .false.
! this variable indicates when topo arrays have been altered
! based on a dtopo model. For restarts after the end of motion,
! the topo arrays are altered here to match the final topo + dtopo.
! ====================================================================
do i=1,num_dtopo
if (tstart <= tfdtopo(i)) then
topoaltered(i) = .false.
elseif (tstart > tfdtopo(i)) then
topoaltered(i) = .true.
write(GEO_PARM_UNIT,*) ' Altering topo arrays at t=', tstart
print *, 'SETDTOPO Resetting topo arrays at t=',tstart
do m=1,mtopofiles
if ((xlowtopo(m) <= xhidtopo(i)).and. &
(xhitopo(m) >= xlowdtopo(i)).and. &
(ylowtopo(m) <= yhidtopo(i)).and. &
(yhitopo(m) >= ylowdtopo(i))) then
do ib=1,mxtopo(m)
xcell=xlowtopo(m) + (ib-0.5d0)*dxtopo(m)
xim=xlowtopo(m) + (ib-1.d0)*dxtopo(m)
xip=xlowtopo(m) + ib*dxtopo(m)
if ((xim >= xlowdtopo(i)).and. &
(xip <= xhidtopo(i))) then
do jb=1,mytopo(m)
ycell=ylowtopo(m) + (jb-.5d0)*dytopo(m)
yjm=ylowtopo(m) + (jb-1.d0)*dytopo(m)
yjp=ylowtopo(m) + jb*dytopo(m)
if ((yjm >= ylowdtopo(i)).and. &
(yjp <= yhidtopo(i))) then
ztopoij = 0.d0
ijdtopo = i0dtopo(i)+(mtdtopo(i)-1) &
*mxdtopo(i)*mydtopo(i)
ztopoij= topointegral(xim,xcell,xip, &
yjm,ycell,yjp,xlowdtopo(i), &
ylowdtopo(i),dxdtopo(i), &
dydtopo(i),mxdtopo(i), &
mydtopo(i),dtopowork(ijdtopo),1)
ztopoij=ztopoij/((yjp-yjm)*(xip-xim))
if (icoordsys == 2) then
deg2rad = pi/180.d0
capac_area = deg2rad*Rearth**2 &
* (sin(yjp*deg2rad) &
- sin(yjm*deg2rad))/(yjp-yjm)
ztopoij = ztopoij / capac_area
endif
jbr=mytopo(m)-jb+1
ij=i0topo(m) + (jbr-1)*mxtopo(m)+ib-1
topowork(ij)=topowork(ij)+ztopoij
endif
enddo
endif
enddo
endif
enddo
endif
enddo
end subroutine set_dtopo
! ========================================================================
! ========================================================================
! read_dtopo(fname)
! ========================================================================
subroutine read_dtopo(mx,my,mt,dtopo_type,fname,dtopo)
implicit none
! Arguments
integer, intent(in) :: mx,my,mt,dtopo_type
character*150, intent(in) :: fname
double precision, intent(inout) :: dtopo(1:mx*my*mt)
! Local
integer, parameter :: iunit = 29
integer :: i,j,k,dtopo_size,status
double precision :: t,x,y
open(unit=iunit, file=fname, status = 'unknown',form='formatted')
select case(abs(dtopo_type))
case(1)
! ASCII file with 4 columns
do i = 1,mx*my*mt
read(iunit,fmt=*,iostat=status) t,x,y, dtopo(i)
enddo
case(2)
! read header
do i = 1,9
read(iunit,*)
enddo
! read the data
do i = 1,mx*my*mt
read(iunit,*) dtopo(i)
enddo
case(3)
! read header
do i = 1,9
read(iunit,*)
enddo
do k = 1,mt
do j = 1,my
read(iunit,*) (dtopo((k-1)*mx*my + (j-1)*mx + i) , i=1,mx)
enddo
enddo
end select
end subroutine read_dtopo
! ========================================================================
! subroutine read_dtopo_header(fname,topo_type,mx,my,mt,xlow,ylow,t0,xhi,
! yhi,tf,dx,dy,dt)
! ========================================================================
! Read in dtopo file header and either read or calculate the grid info
!
! :Input:
! - fname - (char) Name of the dtopo file
! - topo_type - (int) Topography file type (1-3 are valid)
!
! :Output:
! - mx,my,mt - (int) Number of grid point in space (mx,my) and time (mt)
! - xlow,ylow - (dp) Lower corner spatial coordinate of grid
! - xhi,yhi - (dp) Upper corner spatial coodinate of grid
! - t0,tf - (dp) Beginning and end times for the file
! - dx,dy,dt - (dp) Distance between space (dx,dy) and time (dt) points
! ========================================================================
subroutine read_dtopo_header(fname,topo_type,mx,my,mt,xlow,ylow,t0,xhi, &
yhi,tf,dx,dy,dt)
implicit none
! Input Arguments
character*150, intent(in) :: fname
integer, intent(in) :: topo_type
! Output Arguments
integer, intent(out) :: mx,my,mt
double precision, intent(out) :: xlow,ylow,t0,xhi,yhi,tf,dx,dy,dt
! Locals
integer, parameter :: iunit = 7
integer :: topo_size,status
double precision :: x,y,t,y_old,t_old
logical :: found_file
! Open file
inquire(file=fname,exist=found_file)
if (.not.found_file) then
print *, 'Missing dtopo file:'
print *, ' ', fname
stop
endif
open(unit=iunit,file=fname,status='unknown',form='formatted')
select case(topo_type)
! Old style ASCII dtopo files
case(1)
! Initial size variables
topo_size = 0
my = 1
mt = 1
! Read in first values, determines xlow, yhi and t0
read(iunit,*) t0,xlow,yhi
topo_size = topo_size + 1
t = t0
y_old = yhi
! Go through entire file figuring out my, mt and topo_size
status = 0
do while (status == 0.and. t.eq.t0)
read(iunit,fmt=*,iostat=status) t,x,y
topo_size = topo_size + 1
if (y /= y_old .and. t.eq.t0 ) then
my = my + 1
y_old = y
endif
enddo
mx = (topo_size-1)/my
do while (status == 0)
read(iunit,fmt=*,iostat=status) t,x,y
topo_size = topo_size + 1
enddo
if (status > 0) then
print *, "IO error occured in ",fname,", aborting!"
stop
endif
! Calculate remaining values
mt = (topo_size-1)/ (my*mx)
xhi = x
ylow = y
tf = t
dx = (xhi-xlow) / (mx-1)
dy = (yhi-ylow) / (my-1)
dt = (tf - t0) / (mt-1)
! New ASCII headered dtopo files, similar to topography files type
! 2 and 3
case(2:3)
! Read in header directly
read(iunit,*) mx
read(iunit,*) my
read(iunit,*) mt
read(iunit,*) xlow
read(iunit,*) ylow
read(iunit,*) t0
read(iunit,*) dx
read(iunit,*) dy
read(iunit,*) dt
xhi = xlow + dx*(mx-1)
yhi = ylow + dy*(my-1)
tf = t0 + dt*(mt-1)
case default
print *, 'ERROR: Unrecognized topography type'
print *, ' topo_type = ',topo_type
print *, ' for dtopo file:'
print *, ' ', fname
stop
end select
close(iunit)
end subroutine read_dtopo_header
end module dtopo_module