subroutine smoothrf(work,nsc,nlevs) 1,18 !$$$ subprogram documentation block ! . . . . ! subprogram: smoothrf perform horizontal part of background error ! prgmmr: wu org: np22 date: 2000-03-15 ! ! abstract: smoothrf perform horizontal part of background error ! ! program history log: ! 2000-03-15 wu ! 2004-05-06 derber - combine regional, add multiple layers ! 2004-08-27 kleist - new berror variable ! 2004-10-26 wu - give smallest RF half weight for regional wind variables ! 2004-11-03 treadon - pass horizontal scale weighting factors through berror ! 2004-11-22 derber - add openMP ! 2005-03-09 wgu/kleist - square hzscl in totwgt calculation ! 2005-05-27 kleist/parrish - add option to use new patch interpolation ! if (norsp==0) will default to polar cascade ! 2005-11-16 wgu - set nmix=nr+1+(ny-nlat)/2 to make sure ! nmix+nrmxb=nr no matter what number nlat is. ! input argument list: ! work - horizontal fields to be smoothed ! nsc - number of horizontal scales to smooth over ! nlevs - number of vertical levels for smoothing ! ! output argument list: ! work - smoothed horizontal field ! ! attributes: ! language: f90 ! machine: ibm RS/6000 SP !$$$ use kinds, only: r_kind,i_kind use gridmod, only: nlat,nlon,nsig1o,regional use constants, only: zero,half use berror, only: wtaxs,wtxrs,inaxs,inxrs,bl,bl2,ii,jj,ii1,jj1,& ii2,jj2,slw,slw1,slw2,norh,nx,ny,mr,nr,nf,hzscl,nlath,hswgt use mpimod, only: levs_id,nvar_id use smooth_polcarf, only: norsp,smooth_polcas,smooth_polcasa implicit none ! Declare passed variables integer(i_kind),intent(in):: nsc,nlevs real(r_kind),dimension(nlat,nlon,nsig1o),intent(inout):: work ! Declare local variables integer(i_kind) ndx,ndy,nxe,nmix,narx,nfg integer(i_kind) j,naxr,i,nrmxb,nmixp,nymx,norm,nxem integer(i_kind) ndx2,nlatxb,mmm,nfnf integer(i_kind) ix,iy,i1,i2,j1,k real(r_kind),dimension(nsc):: totwgt real(r_kind),dimension(ny,nx):: p1all real(r_kind),dimension(nlon+1,mr:nr):: p2all,p3all real(r_kind),dimension(-nf:nf,-nf:nf):: afg1 ! Regional case if(regional)then !$omp parallel do schedule(dynamic,1) private(k,j,totwgt) do k=1,nlevs ! apply horizontal recursive filters do j=1,nsc totwgt(j)=hswgt(j)*hzscl(j)*hzscl(j) end do if(nvar_id(k)<3)then totwgt(3)=half*totwgt(3) end if call rfxyyx(work(1,1,k),ny,nx,ii(1,1,1,k),& jj(1,1,1,k),slw(1,k),nsc,totwgt) end do ! Global case else do j=1,nsc totwgt(j)=hswgt(j)*hzscl(j)*hzscl(j) end do ndx=(nx-nlon)/2 ndy=(nlat-ny)/2 ndx2=2*ndx norm=norh*2-1 nxe=nlon/8 nxem=nxe-1 nmix=nr+1+(ny-nlat)/2 naxr=nlon+1 nfg=nf*2+1 nrmxb=ndy-1 nlatxb=nlat-nrmxb nmixp=nmix+1 nymx=ny-nmix nfnf=(2*nf+1)*(2*nf+1) !$omp parallel do schedule(dynamic,1) private(k) & !$omp private(i,j,i1,i2,j1,p1all,p2all,p3all,afg1) do k=1,nlevs ! Zero p1, p2, and p3 do j=1,nx do i=1,ny p1all(i,j)=zero end do end do ! Extract central patch (band) from full grid (work --> p1) ! Blending zones do i=1,ndx i1=i-ndx+nlon i2=nx-ndx+i do j=1,ny j1=j+ndy p1all(j,i) =work(j1,i1,k) ! left (west) blending zone p1all(j,i2)=work(j1,i,k) ! right (east) blending zone enddo enddo ! Middle zone (no blending) do i=ndx+1,nx-ndx i1=i-ndx do j=1,ny p1all(j,i)=work(j+ndy,i1,k) enddo enddo ! Apply blending coefficients to central patch do i=1,ndx2 i1=ndx2+1-i i2=nx-ndx2+i do j=1,ny p1all(j,i) =p1all(j,i) *bl(i1) ! left (west) blending zone p1all(j,i2)=p1all(j,i2)*bl(i) ! right (east) blending zone enddo enddo ! bl2 of p1 do i=1,nx do j=1,nmix p1all(j,i)=p1all(j,i)*bl2(nmixp-j) enddo do j=nymx+1,ny p1all(j,i)=p1all(j,i)*bl2(j-nymx) enddo enddo ! Handle polar patches do j=mr,nr do i=1,naxr p2all(i,j)=zero p3all(i,j)=zero end do end do ! North pole patch(p2) -- blending and transfer to grid ! South pole patch(p3) -- blending and transfer to grid do i=1,nlon ! Load field into patches do j=mr,nrmxb+nmix p2all(i,j)=work(nlat-j,i,k) p3all(i,j)=work(j+1,i,k) enddo enddo ! Apply blending coefficients do j=nrmxb+1,nrmxb+nmix j1=j-nrmxb do i=1,nlon p2all(i,j)=p2all(i,j)*bl2(j1) p3all(i,j)=p3all(i,j)*bl2(j1) enddo enddo ! Recursive filter applications ! First do equatorial/mid-latitude band call rfxyyx(p1all,ny,nx,ii(1,1,1,k),jj(1,1,1,k),slw(1,k),nsc,totwgt) ! North pole patch --interpolate - recursive filter - adjoint interpolate if(norsp.gt.0) then call smooth_polcasa(afg1,p2all) else call polcasa(afg1,p2all,nxem,norm,nlon,wtaxs,wtxrs,inaxs,inxrs,nf,mr,nr) end if call rfxyyx(afg1,nfg,nfg,ii1(1,1,1,k),jj1(1,1,1,k),slw1(1,k),nsc,totwgt) if(norsp.gt.0) then call smooth_polcas(afg1,p2all) else call polcas(afg1,p2all,nxem,norm,nlon,wtaxs,wtxrs,inaxs,inxrs,nf,mr,nr) end if ! South pole patch --interpolate - recursive filter - adjoint interpolate if(norsp.gt.0) then call smooth_polcasa(afg1,p3all) else call polcasa(afg1,p3all,nxem,norm,nlon,wtaxs,wtxrs,inaxs,inxrs,nf,mr,nr) end if call rfxyyx(afg1,nfg,nfg,ii2(1,1,1,k),jj2(1,1,1,k),slw2(1,k),nsc,totwgt) if(norsp.gt.0) then call smooth_polcas(afg1,p3all) else call polcas(afg1,p3all,nxem,norm,nlon,wtaxs,wtxrs,inaxs,inxrs,nf,mr,nr) end if ! Equatorial patch ! Adjoint of central patch blending on left/right sides of patch do i=1,ndx2 i1=ndx2+1-i i2=nx-ndx2+i do j=1,ny p1all(j,i) =p1all(j,i) *bl(i1) ! left (west) blending zone p1all(j,i2)=p1all(j,i2)*bl(i) ! right (east) blending zone enddo enddo ! bl2 of p1 do i=1,nx do j=1,nmix p1all(j,i)=p1all(j,i)*bl2(nmixp-j) enddo do j=nymx+1,ny p1all(j,i)=p1all(j,i)*bl2(j-nymx) enddo enddo ! zero output array do i=1,nlon do j=1,nlat work(j,i,k)=zero end do end do ! Adjoint of transfer between central band and full grid (p1 --> work) do i=1,ndx i1=i-ndx+nlon i2=nx-ndx+i do j=1,ny j1=j+ndy work(j1,i1,k)=work(j1,i1,k)+p1all(j,i) ! left (west) blending zone work(j1,i,k) =work(j1,i,k) +p1all(j,i2) ! right (east) blending zone enddo enddo ! Middle zone (no blending) do i=ndx+1,nx-ndx i1=i-ndx do j=1,ny j1=j+ndy work(j1,i1,k)=work(j1,i1,k)+p1all(j,i) enddo enddo ! Adjoint of North pole patch(p2) -- blending and transfer to grid ! Adjoint of South pole patch(p3) -- blending and transfer to grid do j=nlatxb-nmix,nlatxb-1 ! Adjoint of blending do i=1,nlon p2all(i,nlat-j)=p2all(i,nlat-j)*bl2(nlatxb-j) enddo end do do j=nrmxb+1,nrmxb+nmix ! Adjoint of blending do i=1,nlon p3all(i,j)=p3all(i,j)*bl2(j-nrmxb) enddo enddo do i=1,nlon ! Adjoint of transfer do j=mr,nrmxb+nmix work(j+1,i,k)=work(j+1,i,k)+p3all(i,j) enddo do j=nlatxb-nmix,nlat-mr work(j,i,k)=work(j,i,k)+p2all(i,nlat-j) enddo enddo ! End of k loop over nlevs end do ! End of global block end if return end subroutine smoothrf subroutine rfxyyx(p1,nx,ny,iix,jjx,dssx,nsc,totwgt) 4,7 !$$$ subprogram documentation block ! . . . . ! subprogram: rfxyyx perform horizontal smoothing ! prgmmr: wu org: np22 date: 2000-03-15 ! ! abstract: smoothrf perform self-adjoint horizontal smoothing. nsloop ! smoothing fields. ! ! program history log: ! 2000-03-15 wu ! 2004-08-24 derber - change indexing add rfhyt to speed things up ! ! input argument list: ! p1 - horizontal field to be smoothed ! nx - first dimension of p1 ! ny - second dimension of p1 ! iix - array of pointers for smoothing table (first dimension) ! jjx - array of pointers for smoothing table (second dimension) ! dssx - renormalization constants including variance ! wgt - weight (empirical*expected) ! ! output argument list: ! all after horizontal smoothing ! p1 - horizontal field which has been smoothed ! ! attributes: ! language: f90 ! machine: ibm RS/6000 SP !$$$ use kinds, only: r_kind,i_kind use constants, only: zero use berror, only: be,table,ndeg implicit none ! Declare passed variables integer(i_kind),intent(in):: nx,ny,nsc integer(i_kind),dimension(nx,ny,nsc),intent(in):: iix,jjx real(r_kind),dimension(nx,ny),intent(inout):: p1 real(r_kind),dimension(nx,ny),intent(in):: dssx real(r_kind),dimension(nsc),intent(in):: totwgt ! Declare local variables integer(i_kind) ix,iy,i,j,im,n real(r_kind),dimension(nx,ny):: p2,p1out,p1t real(r_kind),dimension(ndeg,ny):: gax1,dex1,gax2,dex2 real(r_kind),dimension(nx,ny,ndeg):: alx,aly real(r_kind) wgt ! Zero local arrays do iy=1,ny do ix=1,nx p1out(ix,iy)=zero enddo enddo ! Loop over number of scales do n=1,nsc do j=1,ny do i=1,ndeg gax2(i,j)=zero dex2(i,j)=zero end do end do do iy=1,ny do ix=1,nx p2(ix,iy)=zero enddo enddo do im=1,ndeg do j=1,ny do i=1,nx alx(i,j,im)=table(iix(i,j,n),im) aly(i,j,im)=table(jjx(i,j,n),im) enddo enddo enddo ! IX < 0 | | IX > NX ! --------------------------------------- ! . | . | . <-- IY > NY ! . | P1 | . ! . | . | . <-- IY < 0 ! --------------------------------------- call rfhx0(p1,p2,gax2,dex2,nx,ny,ndeg,alx,be) ! IX < 0 | | IX > NX ! --------------------------------------- ! . | . | . <-- IY > NY ! DEX2 | P2 | GAX2 ! . | . | . <-- IY < 0 ! --------------------------------------- call rfhyt(p2,p1t,nx,ny,ndeg,ndeg,aly,be) ! IX < 0 | | IX > NX ! --------------------------------------- ! DEGAXY1 | GAY1 |GAGAXY1 <-- IY > NY ! DEX1 | P1 | GAX1 ! DEDEXY1 | DEY1 |GADEXY1 <-- IY < 0 ! --------------------------------------- do iy=1,ny do ix=1,nx p1t(ix,iy)=p1t(ix,iy)*dssx(ix,iy)*totwgt(n) enddo enddo ! IX < 0 | | IX > NX ! --------------------------------------- ! GADEXY1 | DEY1 |DEDEXY1 <-- IY > NY ! GAX1 | P1 | DEX1 ! GAGAXY1 | GAY1 |DEGAXY1 <-- IY < 0 ! --------------------------------------- call rfhy(p1t,p2,dex2,gax2,nx,ny,ndeg,ndeg,aly,be) ! IX < 0 | | IX > NX ! --------------------------------------- ! . | . | . <-- IY > NY ! GAX2 | P2 | DEX2 ! . | . | . <-- IY < 0 ! --------------------------------------- call rfhx0(p2,p1out,gax2,dex2,nx,ny,ndeg,alx,be) ! IX < 0 | | IX > NX ! --------------------------------------- ! . | . | . <-- IY > NY ! . | P1 | . ! . | . | . <-- IY < 0 ! --------------------------------------- ! end loop over number of horizontal scales end do do iy=1,ny do ix=1,nx p1(ix,iy)=p1out(ix,iy) enddo enddo return end subroutine rfxyyx subroutine rfhx0(p1,p2,gap,dep,nx,ny,ndeg,alx,be) 2,1 !$$$ subprogram documentation block ! . . . . ! subprogram: rfhx0 performs x component of recursive filter ! prgmmr: wu org: np22 date: 2000-03-15 ! ! abstract: performs x component of recursive filter ! ! program history log: ! 2000-03-15 wu ! 2004-05-06 derber combine regional, add multiple layers ! 2004-08-24 derber change indexing to 1-nx,1-ny ! ! input argument list: ! p1 - field to be smoothed ! nx - first dimension of p1 ! ny - second dimension of p1 ! ndeg - degree of smoothing ! alx - smoothing coefficients ! be - smoothing coefficients ! gap - boundary field (see rfxyyx) ! dep - boundary field (see rfxyyx) ! ! output argument list: ! p2 - field after smoothing ! ! attributes: ! language: f90 ! machine: ibm RS/6000 SP !$$$ use kinds, only: r_kind,i_kind implicit none integer(i_kind),intent(in):: nx,ny,ndeg real(r_kind),intent(inout),dimension(ndeg,ny):: gap,dep real(r_kind),intent(in),dimension(nx,ny):: p1 real(r_kind),intent(in),dimension(ndeg):: be real(r_kind),intent(in),dimension(nx,ny,ndeg):: alx real(r_kind),intent(out),dimension(nx,ny):: p2 integer(i_kind) kmod2,ix,iy,kr,ki real(r_kind) gakr,gaki,dekr,deki,bekr,beki kmod2=mod(ndeg,2) if (kmod2 == 1) then ! Advancing filter: do ix=1,nx do iy=1,ny gap(1,iy)=alx(ix,iy,1)*gap(1,iy)+be(1)*p1(ix,iy) p2(ix,iy)=p2(ix,iy)+gap(1,iy) enddo ! treat remaining complex roots: do kr=kmod2+1,ndeg,2 ! <-- index of "real" components ki=kr+1 ! <-- index of "imag" components bekr=be(kr) beki=be(ki) do iy=1,ny gakr=gap(kr,iy) gaki=gap(ki,iy) gap(kr,iy)=alx(ix,iy,kr)*gakr& -alx(ix,iy,ki)*gaki+bekr*p1(ix,iy) gap(ki,iy)=alx(ix,iy,ki)*gakr& +alx(ix,iy,kr)*gaki+beki*p1(ix,iy) p2(ix,iy)=p2(ix,iy)+gap(kr,iy) enddo enddo enddo ! Backing filter: do ix=nx,1,-1 ! treat real roots do iy=1,ny p2(ix,iy)=p2(ix,iy)+dep(1,iy) dep(1,iy)=alx(ix,iy,1)*(dep(1,iy)+be(1)*p1(ix,iy)) enddo ! treat remaining complex roots: do kr=kmod2+1,ndeg,2 ! <-- index of "real" components ki=kr+1 ! <-- index of "imag" components do iy=1,ny p2(ix,iy)=p2(ix,iy)+dep(kr,iy) dekr=dep(kr,iy)+bekr*p1(ix,iy) deki=dep(ki,iy)+beki*p1(ix,iy) dep(kr,iy)=alx(ix,iy,kr)*dekr-alx(ix,iy,ki)*deki dep(ki,iy)=alx(ix,iy,ki)*dekr+alx(ix,iy,kr)*deki enddo enddo enddo else do iy=1,ny ! Advancing filter ! treat remaining complex roots: do kr=kmod2+1,ndeg,2 ! <-- index of "real" components ki=kr+1 ! <-- index of "imag" components bekr=be(kr) beki=be(ki) do ix=1,nx gakr=gap(kr,iy) gaki=gap(ki,iy) gap(kr,iy)=alx(ix,iy,kr)*gakr& -alx(ix,iy,ki)*gaki+bekr*p1(ix,iy) gap(ki,iy)=alx(ix,iy,ki)*gakr& +alx(ix,iy,kr)*gaki+beki*p1(ix,iy) p2(ix,iy)=p2(ix,iy)+gap(kr,iy) end do ! Backing filter: ! treat remaining complex roots: do ix=nx,1,-1 p2(ix,iy)=p2(ix,iy)+dep(kr,iy) dekr=dep(kr,iy)+bekr*p1(ix,iy) deki=dep(ki,iy)+beki*p1(ix,iy) dep(kr,iy)=alx(ix,iy,kr)*dekr-alx(ix,iy,ki)*deki dep(ki,iy)=alx(ix,iy,ki)*dekr+alx(ix,iy,kr)*deki enddo end do end do endif return end subroutine rfhx0 subroutine rfhyt(p1,p2,nx,ny,ndegx,ndegy,aly,be) 1,2 !$$$ subprogram documentation block ! . . . . ! subprogram: rfhyt performs x component of recursive filter ! prgmmr: wu org: np22 date: 2000-03-15 ! ! abstract: performs x component of recursive filter ! ! program history log: ! 2000-03-15 wu ! 2004-05-06 derber combine regional, add multiple layers ! 2004-08-24 derber create rfhyt from rfhy - remove unnecessary computations ! remove unused parameters - change indexing ! ! input argument list: ! p1 - field to be smoothed ! nx - first dimension of p1 ! ny - second dimension of p1 ! ndegx - degree of smoothing x direction ! ndegy - degree of smoothing y direction ! aly - smoothing coefficients y direction ! be - smoothing coefficients ! ! output argument list: ! p2 - field after smoothing ! ! attributes: ! language: f90 ! machine: ibm RS/6000 SP !$$$ use kinds, only: r_kind,i_kind use constants, only: zero implicit none integer(i_kind),intent(in):: nx,ny,ndegx,ndegy real(r_kind),intent(in),dimension(nx,ny):: p1 real(r_kind),intent(in),dimension(nx,ny,ndegy):: aly real(r_kind),intent(in),dimension(ndegy):: be real(r_kind),intent(out),dimension(nx,ny):: p2 integer(i_kind) kmod2,ix,iy,lx,kr,ki,ly real(r_kind),dimension(nx,ndegy):: gap,dep real(r_kind) gakr,gaki,dekr,deki real(r_kind) beki,bekr kmod2=mod(ndegy,2) do iy=1,ny do ix=1,nx p2(ix,iy)=zero enddo enddo do ly=1,ndegy do ix=1,nx gap(ix,ly)=zero dep(ix,ly)=zero enddo enddo if (kmod2 == 1) then ! Advancing filter: do iy=1,ny ! treat the real root: do ix=1,nx gap(ix,1)=aly(ix,iy,1)*gap(ix,1)+be(1)*p1(ix,iy) p2(ix,iy)=p2(ix,iy)+gap(ix,1) enddo ! treat remaining complex roots: do kr=kmod2+1,ndegy,2 ! <-- index of "real" components ki=kr+1 ! <-- index of "imag" components bekr=be(kr) beki=be(ki) do ix=1,nx gakr=gap(ix,kr) gaki=gap(ix,ki) gap(ix,kr)=aly(ix,iy,kr)*gakr& -aly(ix,iy,ki)*gaki+bekr*p1(ix,iy) gap(ix,ki)=aly(ix,iy,ki)*gakr& +aly(ix,iy,kr)*gaki+beki*p1(ix,iy) p2(ix,iy)=p2(ix,iy)+gap(ix,kr) enddo enddo enddo ! Backing filter: do iy=ny,1,-1 ! treat the real root: do ix=1,nx p2(ix,iy)=p2(ix,iy)+dep(ix,1) dep(ix,1)=aly(ix,iy,1)*(dep(ix,1)+be(1)*p1(ix,iy)) enddo ! treat remaining complex roots: do kr=kmod2+1,ndegy,2 ! <-- index of "real" components ki=kr+1 ! <-- index of "imag" components bekr=be(kr) beki=be(ki) do ix=1,nx p2(ix,iy)=p2(ix,iy)+dep(ix,kr) dekr=dep(ix,kr)+bekr*p1(ix,iy) deki=dep(ix,ki)+beki*p1(ix,iy) dep(ix,kr)=aly(ix,iy,kr)*dekr-aly(ix,iy,ki)*deki dep(ix,ki)=aly(ix,iy,ki)*dekr+aly(ix,iy,kr)*deki enddo enddo enddo else ! Advancing filter: do iy=1,ny ! treat remaining complex roots: do kr=kmod2+1,ndegy,2 ! <-- index of "real" components ki=kr+1 ! <-- index of "imag" components bekr=be(kr) beki=be(ki) do ix=1,nx gakr=gap(ix,kr) gaki=gap(ix,ki) gap(ix,kr)=aly(ix,iy,kr)*gakr& -aly(ix,iy,ki)*gaki+bekr*p1(ix,iy) gap(ix,ki)=aly(ix,iy,ki)*gakr& +aly(ix,iy,kr)*gaki+beki*p1(ix,iy) p2(ix,iy)=p2(ix,iy)+gap(ix,kr) enddo enddo enddo ! Backing filter: do iy=ny,1,-1 ! treat remaining complex roots: do kr=kmod2+1,ndegy,2 ! <-- index of "real" components ki=kr+1 ! <-- index of "imag" components bekr=be(kr) beki=be(ki) do ix=1,nx p2(ix,iy)=p2(ix,iy)+dep(ix,kr) dekr=dep(ix,kr)+bekr*p1(ix,iy) deki=dep(ix,ki)+beki*p1(ix,iy) dep(ix,kr)=aly(ix,iy,kr)*dekr-aly(ix,iy,ki)*deki dep(ix,ki)=aly(ix,iy,ki)*dekr+aly(ix,iy,kr)*deki enddo enddo enddo endif return end subroutine rfhyt subroutine rfhy(p1,p2,en2,e02,nx,ny,ndegx,ndegy,aly,be) 1,2 !$$$ subprogram documentation block ! . . . . ! subprogram: rfhy performs x component of recursive filter ! prgmmr: wu org: np22 date: 2000-03-15 ! ! abstract: performs x component of recursive filter ! ! program history log: ! 2000-03-15 wu ! 2004-05-06 derber combine regional, add multiple layers ! 2004-08-24 derber remove unused parameters and unnecessary computation ! change indexing ! ! input argument list: ! p1 - field to be smoothed ! nx - first dimension of p1 ! ny - second dimension of p1 ! ndegx - degree of smoothing x direction ! ndegy - degree of smoothing y direction ! aly - smoothing coefficients y direction ! be - smoothing coefficients ! ! output argument list: ! p2 - field after smoothing ! en2 - boundary field (see rfxyyx) ! e02 - boundary field (see rfxyyx) ! ! attributes: ! language: f90 ! machine: ibm RS/6000 SP !$$$ use kinds, only: r_kind,i_kind use constants, only: zero implicit none integer(i_kind),intent(in):: nx,ny,ndegx,ndegy real(r_kind),intent(in),dimension(nx,ny):: p1 real(r_kind),intent(in),dimension(nx,ny,ndegy):: aly real(r_kind),intent(in),dimension(ndegy):: be real(r_kind),intent(out),dimension(nx,ny):: p2 real(r_kind),intent(out),dimension(ndegx,ny):: e02,en2 integer(i_kind) kmod2,ix,iy,lx,kr,ki,ly real(r_kind) al0kr,al0ki,gakr,gaki,dekr,deki,alnkr,alnki real(r_kind) al01,aln1,be1,beki,bekr real(r_kind),dimension(nx,ndegy):: gap,dep real(r_kind),dimension(ndegx,ndegy):: gae0,dee0,gaen,deen kmod2=mod(ndegy,2) do iy=1,ny do ix=1,nx p2(ix,iy)=zero enddo enddo do iy=1,ny do lx=1,ndegx e02(lx,iy)=zero en2(lx,iy)=zero enddo enddo do ly=1,ndegy do ix=1,nx gap(ix,ly)=zero dep(ix,ly)=zero enddo enddo do ly=1,ndegy do lx=1,ndegx gae0(lx,ly)=zero dee0(lx,ly)=zero gaen(lx,ly)=zero deen(lx,ly)=zero end do end do if (kmod2 == 1) then ! Advancing filter: do iy=1,ny ! treat the real root: do ix=1,nx gap(ix,1)=aly(ix,iy,1)*gap(ix,1)+be(1)*p1(ix,iy) p2(ix,iy)=p2(ix,iy)+gap(ix,1) enddo al01=aly( 1,iy,1) aln1=aly(nx,iy,1) do lx=1,ndegx gae0(lx,1)=al01*gae0(lx,1) e02(lx,iy)=e02(lx,iy)+gae0(lx,1) gaen(lx,1)=aln1*gaen(lx,1) en2(lx,iy)=en2(lx,iy)+gaen(lx,1) enddo ! treat remaining complex roots: do kr=kmod2+1,ndegy,2 ! <-- index of "real" components ki=kr+1 ! <-- index of "imag" components bekr=be(kr) beki=be(ki) do ix=1,nx gakr=gap(ix,kr) gaki=gap(ix,ki) gap(ix,kr)=aly(ix,iy,kr)*gakr& -aly(ix,iy,ki)*gaki+bekr*p1(ix,iy) gap(ix,ki)=aly(ix,iy,ki)*gakr& +aly(ix,iy,kr)*gaki+beki*p1(ix,iy) p2(ix,iy)=p2(ix,iy)+gap(ix,kr) enddo al0kr=aly( 1,iy,kr) al0ki=aly( 1,iy,ki) alnkr=aly(nx,iy,kr) alnki=aly(nx,iy,ki) do lx=1,ndegx gakr=gae0(lx,kr) gaki=gae0(lx,ki) gae0(lx,kr)=al0kr*gakr-al0ki*gaki gae0(lx,ki)=al0ki*gakr+al0kr*gaki e02(lx,iy)=e02(lx,iy)+gae0(lx,kr) gakr=gaen(lx,kr) gaki=gaen(lx,ki) gaen(lx,kr)=alnkr*gakr-alnki*gaki gaen(lx,ki)=alnki*gakr+alnkr*gaki en2(lx,iy)=en2(lx,iy)+gaen(lx,kr) enddo enddo enddo ! Backing filter: do iy=ny,1,-1 ! treat the real root: do ix=1,nx p2(ix,iy)=p2(ix,iy)+dep(ix,1) dep(ix,1)=aly(ix,iy,1)*(dep(ix,1)+be(1)*p1(ix,iy)) enddo al01=aly( 1,iy,1) aln1=aly(nx,iy,1) do lx=1,ndegx e02(lx,iy)=e02(lx,iy)+dee0(lx,1) dee0(lx,1)=al01*dee0(lx,1) en2(lx,iy)=en2(lx,iy)+deen(lx,1) deen(lx,1)=aln1*deen(lx,1) enddo ! treat remaining complex roots: do kr=kmod2+1,ndegy,2 ! <-- index of "real" components ki=kr+1 ! <-- index of "imag" components bekr=be(kr) beki=be(ki) do ix=1,nx p2(ix,iy)=p2(ix,iy)+dep(ix,kr) dekr=dep(ix,kr)+bekr*p1(ix,iy) deki=dep(ix,ki)+beki*p1(ix,iy) dep(ix,kr)=aly(ix,iy,kr)*dekr-aly(ix,iy,ki)*deki dep(ix,ki)=aly(ix,iy,ki)*dekr+aly(ix,iy,kr)*deki enddo al0kr=aly( 1,iy,kr) al0ki=aly( 1,iy,ki) alnkr=aly(nx,iy,kr) alnki=aly(nx,iy,ki) do lx=1,ndegx e02(lx,iy)=e02(lx,iy)+dee0(lx,kr) dekr=dee0(lx,kr) deki=dee0(lx,ki) dee0(lx,kr)=al0kr*dekr-al0ki*deki dee0(lx,ki)=al0ki*dekr+al0kr*deki en2(lx,iy)=en2(lx,iy)+deen(lx,kr) dekr=deen(lx,kr) deki=deen(lx,ki) deen(lx,kr)=alnkr*dekr-alnki*deki deen(lx,ki)=alnki*dekr+alnkr*deki enddo enddo enddo else ! Advancing filter: do iy=1,ny ! treat remaining complex roots: do kr=kmod2+1,ndegy,2 ! <-- index of "real" components ki=kr+1 ! <-- index of "imag" components bekr=be(kr) beki=be(ki) do ix=1,nx gakr=gap(ix,kr) gaki=gap(ix,ki) gap(ix,kr)=aly(ix,iy,kr)*gakr& -aly(ix,iy,ki)*gaki+bekr*p1(ix,iy) gap(ix,ki)=aly(ix,iy,ki)*gakr& +aly(ix,iy,kr)*gaki+beki*p1(ix,iy) p2(ix,iy)=p2(ix,iy)+gap(ix,kr) enddo al0kr=aly( 1,iy,kr) al0ki=aly( 1,iy,ki) alnkr=aly(nx,iy,kr) alnki=aly(nx,iy,ki) do lx=1,ndegx gakr=gae0(lx,kr) gaki=gae0(lx,ki) gae0(lx,kr)=al0kr*gakr-al0ki*gaki gae0(lx,ki)=al0ki*gakr+al0kr*gaki e02(lx,iy)=e02(lx,iy)+gae0(lx,kr) gakr=gaen(lx,kr) gaki=gaen(lx,ki) gaen(lx,kr)=alnkr*gakr-alnki*gaki gaen(lx,ki)=alnki*gakr+alnkr*gaki en2(lx,iy)=en2(lx,iy)+gaen(lx,kr) enddo enddo enddo ! Backing filter: do iy=ny,1,-1 ! treat remaining complex roots: do kr=kmod2+1,ndegy,2 ! <-- index of "real" components ki=kr+1 ! <-- index of "imag" components bekr=be(kr) beki=be(ki) do ix=1,nx p2(ix,iy)=p2(ix,iy)+dep(ix,kr) dekr=dep(ix,kr)+bekr*p1(ix,iy) deki=dep(ix,ki)+beki*p1(ix,iy) dep(ix,kr)=aly(ix,iy,kr)*dekr-aly(ix,iy,ki)*deki dep(ix,ki)=aly(ix,iy,ki)*dekr+aly(ix,iy,kr)*deki enddo al0kr=aly( 1,iy,kr) al0ki=aly( 1,iy,ki) alnkr=aly(nx,iy,kr) alnki=aly(nx,iy,ki) do lx=1,ndegx e02(lx,iy)=e02(lx,iy)+dee0(lx,kr) dekr=dee0(lx,kr) deki=dee0(lx,ki) dee0(lx,kr)=al0kr*dekr-al0ki*deki dee0(lx,ki)=al0ki*dekr+al0kr*deki en2(lx,iy)=en2(lx,iy)+deen(lx,kr) dekr=deen(lx,kr) deki=deen(lx,ki) deen(lx,kr)=alnkr*dekr-alnki*deki deen(lx,ki)=alnki*dekr+alnkr*deki enddo enddo enddo endif return end subroutine rfhy