|
new file 100644
|
|
|
!
|
|
|
! file fish.f
|
|
|
!
|
|
|
! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
|
! . .
|
|
|
! . copyright (c) 2004 by UCAR .
|
|
|
! . .
|
|
|
! . UNIVERSITY CORPORATION for ATMOSPHERIC RESEARCH .
|
|
|
! . .
|
|
|
! . all rights reserved .
|
|
|
! . .
|
|
|
! . .
|
|
|
! . FISHPACK version 5.0 .
|
|
|
! . .
|
|
|
! . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
|
|
!
|
|
|
!
|
|
|
! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
! * *
|
|
|
! * F I S H P A C K *
|
|
|
! * *
|
|
|
! * *
|
|
|
! * A PACKAGE OF FORTRAN SUBPROGRAMS FOR THE SOLUTION OF *
|
|
|
! * *
|
|
|
! * SEPARABLE ELLIPTIC PARTIAL DIFFERENTIAL EQUATIONS *
|
|
|
! * *
|
|
|
! * (Version 5.0 , JUNE 2004) *
|
|
|
! * *
|
|
|
! * BY *
|
|
|
! * *
|
|
|
! * JOHN ADAMS, PAUL SWARZTRAUBER AND ROLAND SWEET *
|
|
|
! * *
|
|
|
! * OF *
|
|
|
! * *
|
|
|
! * THE NATIONAL CENTER FOR ATMOSPHERIC RESEARCH *
|
|
|
! * *
|
|
|
! * BOULDER, COLORADO (80307) U.S.A. *
|
|
|
! * *
|
|
|
! * WHICH IS SPONSORED BY *
|
|
|
! * *
|
|
|
! * THE NATIONAL SCIENCE FOUNDATION *
|
|
|
! * *
|
|
|
! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
|
|
|
!
|
|
|
!
|
|
|
|
|
|
! this module is used by all fishpack solvers to allocate
|
|
|
! real and complex work space
|
|
|
MODULE fish
|
|
|
|
|
|
TYPE fishworkspace
|
|
|
DOUBLE PRECISION,DIMENSION(:),ALLOCATABLE :: rew
|
|
|
COMPLEX,DIMENSION(:),ALLOCATABLE :: cxw
|
|
|
END TYPE fishworkspace
|
|
|
|
|
|
CONTAINS
|
|
|
SUBROUTINE allocatfish(irwk,icwk,wsave,ierror)
|
|
|
IMPLICIT NONE
|
|
|
TYPE (fishworkspace) :: wsave
|
|
|
! irwk is the required real work space length
|
|
|
! icwk is the required integer work space length
|
|
|
INTEGER, INTENT(IN) :: irwk,icwk
|
|
|
! ierror is set to 20 if the dynamic allocation is unsuccessful
|
|
|
! (e.g., this would happen if m,n are too large for the computers memory
|
|
|
INTEGER, INTENT(INOUT) :: ierror
|
|
|
INTEGER :: istatus
|
|
|
! first deallocate to avoid memory leakage
|
|
|
write(*,*) 'fish.F: allocatfish'
|
|
|
if(allocated(wsave%rew)) then
|
|
|
write(*,*) 'allocated wsave%rew, size= ',size(wsave%rew)
|
|
|
DEALLOCATE(wsave%rew,STAT=istatus)
|
|
|
write(*,*) 'deallocate wsave%rew, istatus=',istatus
|
|
|
end if
|
|
|
! allocate irwk words of real work space
|
|
|
if (irwk > 0) then
|
|
|
ALLOCATE(wsave%rew(irwk),STAT = istatus)
|
|
|
write(*,*) 'fish.F: allocatfish, irwk:',irwk
|
|
|
end if
|
|
|
!
|
|
|
if(allocated(wsave%cxw)) then
|
|
|
write(*,*) 'allocated wsave%cxw, size=',size(wsave%cxw)
|
|
|
DEALLOCATE(wsave%cxw,STAT=istatus)
|
|
|
write(*,*) 'deallocate wsave%cxw, istatus=',istatus
|
|
|
end if
|
|
|
! allocate icwk words of complex work space
|
|
|
if (icwk > 0) then
|
|
|
ALLOCATE(wsave%cxw(icwk),STAT = istatus)
|
|
|
write(*,*) 'fish.F: allocatfish, icrk:',icwk
|
|
|
end if
|
|
|
ierror = 0
|
|
|
! flag fatal error if allocation fails
|
|
|
if (istatus .ne. 0 ) then
|
|
|
ierror = 20
|
|
|
END IF
|
|
|
RETURN
|
|
|
END SUBROUTINE allocatfish
|
|
|
|
|
|
SUBROUTINE BLK_space(N,M,irwk,icwk)
|
|
|
! this subroutine computes the real and complex work space
|
|
|
! requirements (generous estimate) of blktri for N,M values
|
|
|
IMPLICIT NONE
|
|
|
INTEGER,INTENT(IN) :: N,M
|
|
|
INTEGER,INTENT(OUT) :: irwk,icwk
|
|
|
INTEGER :: L,log2n
|
|
|
! compute nearest integer greater than or equal to
|
|
|
! log base 2 of n+1, i.e., log2n is smallest integer
|
|
|
! such that 2**log2n >= n+1
|
|
|
log2n = 1
|
|
|
do
|
|
|
log2n = log2n+1
|
|
|
if (n+1 <= 2**log2n) EXIT
|
|
|
end do
|
|
|
L = 2**(log2n+1)
|
|
|
irwk = (log2n-2)*L+5+MAX0(2*N,6*M)+log2n+2*n
|
|
|
icwk = ((log2n-2)*L+5+log2n)/2+3*M+N
|
|
|
RETURN
|
|
|
END SUBROUTINE BLK_space
|
|
|
|
|
|
SUBROUTINE GEN_space(N,M,irwk)
|
|
|
! this subroutine computes the real work space
|
|
|
! requirement (generously) of genbun for the current N,M
|
|
|
IMPLICIT NONE
|
|
|
INTEGER,INTENT(IN) :: N,M
|
|
|
INTEGER,INTENT(OUT) :: irwk
|
|
|
INTEGER :: log2n
|
|
|
! compute nearest integer greater than or equal to
|
|
|
! log base 2 of n+1, i.e., log2n is smallest integer
|
|
|
! such that 2**log2n >= n+1
|
|
|
log2n = 1
|
|
|
do
|
|
|
log2n = log2n+1
|
|
|
if (n+1 <= 2**log2n) EXIT
|
|
|
end do
|
|
|
irwk = 4*N + (10 + log2n)*M
|
|
|
RETURN
|
|
|
END SUBROUTINE GEN_space
|
|
|
|
|
|
SUBROUTINE fishfin(wsave,ierror)
|
|
|
! this subroutine releases allocated work space
|
|
|
! fishfin should be called after a fishpack solver has finished
|
|
|
! TYPE (fishworkspace) variable wsave.
|
|
|
IMPLICIT NONE
|
|
|
TYPE (fishworkspace) :: wsave
|
|
|
INTEGER,intent(out) :: ierror
|
|
|
INTEGER :: istatus
|
|
|
!
|
|
|
write(*,*) 'fish.F: fishfin'
|
|
|
if(allocated(wsave%rew)) then
|
|
|
write(*,*) 'deallocated wsave%rew, size= ',size(wsave%rew)
|
|
|
DEALLOCATE(wsave%rew,STAT=istatus)
|
|
|
end if
|
|
|
if(allocated(wsave%cxw)) then
|
|
|
write(*,*) 'deallocated wsave%cxw, size=',size(wsave%cxw)
|
|
|
DEALLOCATE(wsave%cxw,STAT=istatus)
|
|
|
end if
|
|
|
! #ifndef G95
|
|
|
! if(associated(wsave%rew))DEALLOCATE(wsave%rew)
|
|
|
! if(associated(wsave%cxw))DEALLOCATE(wsave%cxw)
|
|
|
! #endif
|
|
|
if (istatus .ne. 0 ) then
|
|
|
ierror = 20
|
|
|
END IF
|
|
|
|
|
|
END SUBROUTINE fishfin
|
|
|
|
|
|
END MODULE fish
|