!-------------------------------------- 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 -------------------------------------- !subroutine qsfft8( a, inc, jump, lot, isign ) 2 implicit none #include "taglam4d.cdk"
integer inc, jump, lot, isign real*8 a(*) real*8 ai, as, ya, ys, c, s, rr integer i, j, k, is, k1, kk integer n, m, nstore real*8 ssin, ccos, qsin pointer ( ptss,ssin(n-m-1) ), ( ptcc,ccos(n-m-1) ) pointer ( ptqs,qsin(0:m-1) ) common / comfft8x / ptss, ptcc, ptqs, n, m, nstore integer iwrd external stkmemw, unstakw integer j0, jlot real*8 w pointer ( pw, w(511*nstore) ) real*8 pdwrd(2) real prwrd(2) real*8 zero, half, one, two, four parameter( zero = 0.0 ) parameter( half = 0.5 ) parameter( one = 1.0 ) parameter( two = 2.0 ) parameter( four = 4.0 ) integer ijg, ijf, ijw ijg(i,j) = 1 + (j0+j-1)*jump + i*inc ijf(i,j) = 1 + (j0+j-1)*jump + (i-1)*inc ijw(i,j) = j + i*511 C C allocate w work array C iwrd = ( loc( pdwrd(2) ) - loc( pdwrd(1) ) )/ % ( loc( prwrd(2) ) - loc( prwrd(1) ) ) call stkmemw( iwrd*511*nstore , pw ) do 100 j0=0,lot-1,511 jlot = min( 511, lot - j0 ) if ( isign .eq. -1 ) then C C transform from gridpoint to Fourier C do i=0,m-1 is = n - i - 1 do j=1,jlot ai = a( ijg(i ,j) ) as = a( ijg(is,j) ) ya = as - ai ys = two * qsin( i ) * ( as + ai ) w( ijw(i ,j) ) = ys + ya w( ijw(is,j) ) = ys - ya enddo enddo if ( n .ne. 2 * m ) then do j=1,jlot w( ijw(m,j) ) = four * a( ijg(m,j) ) enddo endif call ffft8( w, 511, 1, jlot, -1 ) do k=1,m if ( k .lt. m .or. n .ne. 2*m ) then c = ccos( k ) s = ssin( k ) else c = zero s = one endif kk = 2 * k k1 = kk + 1 do j=1,jlot rr = w( ijw(kk,j) ) w( ijw(kk,j) ) = c * rr + s * w( ijw(k1,j) ) w( ijw(k1,j) ) = - s * rr + c * w( ijw(k1,j) ) enddo enddo do j=1,jlot a( ijf(1,j) ) = half * w( ijw(0,j) ) enddo do k=2,n-1,2 do j=1,jlot a( ijf(k+1,j) ) = w( ijw(k ,j) ) + a( ijf(k-1,j) ) a( ijf(k ,j) ) = w( ijw(k+1,j) ) enddo enddo if ( n .eq. 2 * m ) then do j=1,jlot a( ijf(n,j) ) = w( ijw(n+1,j) ) enddo endif do j=1,jlot a( ijf(n,j) ) = half * a( ijf(n,j) ) enddo elseif ( isign .eq. +1 ) then C C transform from Fourier to gridpoint C do j=1,jlot w( ijw(0,j) ) = a( ijf(1,j) ) w( ijw(1,j) ) = zero enddo do k=2,n-1,2 do j=1,jlot w( ijw(k ,j) ) = half * ( a( ijf(k+1,j) ) - % a( ijf(k-1,j) ) ) w( ijw(k+1,j) ) = half * a( ijf(k,j) ) enddo enddo if ( n .eq. 2 * m ) then do j=1,jlot w( ijw(n+1,j) ) = a( ijf(n,j) ) enddo else do j=1,jlot w( ijw(n-1,j) ) = w( ijw(n-1,j) ) + half * a( ijf(n,j) ) enddo endif do k = 1 , m if ( k .lt. m .or. n .ne. 2*m ) then c = ccos( k ) s = ssin( k ) else c = zero s = one endif kk = 2 * k k1 = kk + 1 do j=1,jlot rr = w( ijw(kk,j) ) w( ijw(kk,j) ) = c * rr - s * w( ijw(k1,j) ) w( ijw(k1,j) ) = s * rr + c * w( ijw(k1,j) ) enddo enddo call ffft8( w, 511, 1, jlot, +1 ) do i=0,m-1 is = n - i - 1 do j=1,jlot ys = ( w( ijw(i ,j) ) + w( ijw(is,j) ) )/ % ( four * qsin( i ) ) ya = ( w( ijw(is,j) ) - w( ijw(i ,j) ) ) * half a( ijg(i, j) ) = ys + ya a( ijg(is,j) ) = ys - ya enddo enddo if ( n .ne. 2 * m ) then do j=1,jlot a( ijg(m,j) ) = w( ijw(m,j) ) * half enddo endif endif 100 continue C C deallocate w work array C call unstakw( pw ) return end