!-------------------------------------- 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 -------------------------------------- ***s/r sol_parite_2_ad - ADJ of sol_parite_2 * #include "model_macros_f.h"*
subroutine sol_parite_2_ad ( Sol, Rhs, evxevec,oddxevec, 1 $ Minx, Maxx, Miny, Maxy, njl, $ Minz, Maxz, Nk, Nkl, $ Gni, Gnj, Minij, Maxij, L_nij, $ minx1, maxx1, minx2, maxx2,nx3, $ F_npex1, F_npey1, ai, bi, ci, $ fdg1,fdg2,fdwfft,fdg12,NSTOR,nev) * implicit none * integer F_npex1 , F_npey1 integer minx1, maxx1, minx2, maxx2,nx3 Real*8 ai(minx1:maxx1,minx2:maxx2,nx3), $ bi(minx1:maxx1,minx2:maxx2,nx3), $ ci(minx1:maxx1,minx2:maxx2,nx3) * integer Minx, Maxx, Miny, Maxy, njl, $ Minz, Maxz, Nk , Nkl , $ Gni , Gnj , Minij, Maxij, L_nij,NSTOR,nev real*8 Rhs(Minx:Maxx,Miny:Maxy,Nk), Sol(Minx:Maxx,Miny:Maxy,Nk) real*8 evxevec(NSTOR*NSTOR),oddxevec(NSTOR*NSTOR) real*8 fdwfft(Miny:Maxy,Minz:Maxz,Gni) real*8 fdg1(Miny:Maxy,Minz:Maxz,Gni+F_npex1) real*8 fdg2(Minz:Maxz,Minij:Maxij,Gnj+F_npey1) real*8 fdg12(Miny:Maxy,Minz:Maxz,Gni) * *author M.Tanguay * *revision * v3_02 - Tanguay M. - initial version * v3_11 - Tanguay M. - AIXport+Opti+OpenMP for TLM-ADJ * v3_20 - Tanguay M. - Correction OpenMP * *object * see id section * *ADJ of *arguments * o - Sol - result * i - Rhs - r.h.s. of elliptic equation * i - ev-Xevec - Even eigenvectors * i - odd-Xevec- Odd eigenvectors * i - Gni - number of points in x-direction * i - Gnj - number of points in y-direction * #include "ptopo.cdk"
* integer i,k,nevi,gnii,ki0,kin,kkii,kilon,kitotal,ki,jr,j * real*8 ZERO_8, ONE_8 parameter( ZERO_8 = 0.0 ) parameter( ONE_8 = 1.0 ) * ___________________________________________________ * *ADJ of * combine even and odd parts * call rpn_comm_transpose( Sol, Minx, Maxx, Gni, (Maxy-Miny+1), % Minz, Maxz, Nk, fdg1, 1, 2) * !$omp parallel !$omp% * if( Gni.eq.(2*(Gni/2)) ) then !$omp do do k= 1,Nkl do j= 1,njl fdg12(j,k,nev) = fdg1(j,k,nev) + fdg12(j,k,nev) fdg1 (j,k,nev) = ZERO_8 enddo enddo !$omp enddo endif * !$omp end parallel * * --------------------------------------- * This loop has to be removed from OPENMP * but the reason is unknown * --------------------------------------- * C!$omp parallel private(nevi,gnii) * C!$omp do do k= Nkl,1,-1 do i= (Gni+1)/2,2,-1 gnii=Gni+2-i nevi=nev-1+i do j= njl,1,-1 * fdg12(j,k,i) = fdg1(j,k,gnii) + fdg12(j,k,i) fdg12(j,k,nevi) = -fdg1(j,k,gnii) + fdg12(j,k,nevi) fdg1 (j,k,gnii) = ZERO_8 * fdg12(j,k,i) = fdg1(j,k,i) + fdg12(j,k,i) fdg12(j,k,nevi) = fdg1(j,k,i) + fdg12(j,k,nevi) fdg1 (j,k,i) = ZERO_8 * enddo enddo enddo C!$omp enddo * C!$omp end parallel * !$omp parallel private(ki0,kin,kkii,jr) !$omp% shared(kitotal,kilon,ai,bi,ci) * !$omp do do k= 1,Nkl do j= 1,njl fdg12(j,k,1) = fdg1(j,k,1) + fdg12(j,k,1) fdg1 (j,k,1) = ZERO_8 enddo enddo !$omp enddo * * ADJ of * inverse projection ( r = x * w ) * c call mxma8( oddxevec, NSTOR,1, c % fdg12 (1,1,nev+1),(Maxy-Miny+1) * (Maxz-Minz+1), 1, c % fdwfft(1,1,nev+1),(Maxy-Miny+1) * (Maxz-Minz+1), 1, c % Gni-nev, Gni-nev, (Maxy-Miny+1) * Nkl ) * !$omp do do k=1,Nkl call dgemm('N','N', (Maxy-Miny+1), Gni-nev, Gni-nev, . 1._8, fdg12(1,k,nev+1), . (Maxy-Miny+1)* (Maxz-Minz+1),oddxevec, NSTOR, . 0._8, fdwfft(1,k,nev+1), . (Maxy-Miny+1)* (Maxz-Minz+1)) enddo !$omp enddo * c call mxma8( evxevec, NSTOR,1, c % fdg12 (1,1,1), (Maxy-Miny+1) * (Maxz-Minz+1), 1, c % fdwfft(1,1,1), (Maxy-Miny+1) * (Maxz-Minz+1), 1, c % nev, nev, (Maxy-Miny+1) * Nkl ) * !$omp do do k=1,Nkl call dgemm('N','N', (Maxy-Miny+1), nev, nev, . 1._8, fdg12(1,k,1), . (Maxy-Miny+1)* (Maxz-Minz+1),evxevec, NSTOR, . 0._8, fdwfft(1,k,1), . (Maxy-Miny+1)* (Maxz-Minz+1)) enddo !$omp enddo * !$omp single call rpn_comm_transpose $ ( fdwfft, Miny, Maxy, Gnj, (Maxz-Minz+1), $ Minij, Maxij, Gni, fdg2, 2, 2 ) !$omp end single * kitotal = (Maxz-Minz+1)*L_nij kilon = (kitotal + Ptopo_npeOpenMP)/ Ptopo_npeOpenMP * !$omp do do kkii = Ptopo_npeOpenMP,1,-1 * ki0 = 1 + kilon*(kkii-1) kin = min(kitotal, kilon*kkii) * do j = 1,Gnj-1 jr = j + 1 C do ki= (Maxz-Minz+1)*L_nij,1,-1 do ki= kin, ki0, -1 fdg2(ki,i,jr) = - ci(ki,i,j) * fdg2(ki,i,j) + fdg2(ki,i,jr) enddo enddo * do j =Gnj,2,-1 jr = j - 1 C do ki= (Maxz-Minz+1)*L_nij,1,-1 do ki= kin, ki0, -1 fdg2(ki,i,jr) = - ai(ki,i,j) * fdg2(ki,i,j) + fdg2(ki,i,jr) fdg2(ki,i,j) = bi(ki,i,j) * fdg2(ki,i,j) enddo enddo * j =1 C do ki= (Maxz-Minz+1) *L_nij,1,-1 do ki= kin, ki0, -1 fdg2(ki,1,j) = bi(ki,1,j)*fdg2(ki,1,j) enddo enddo !$omp enddo * !$omp single call rpn_comm_transpose $ ( fdwfft, Miny, Maxy, Gnj, (Maxz-Minz+1), $ Minij, Maxij, Gni, fdg2, -2, 2 ) !$omp end single * * ADJ of * projection ( wfft = x transposed * g ) * C call mxma8( oddxevec, 1,NSTOR, C % fdwfft(1,1,nev+1),(Maxy-Miny+1) * (Maxz-Minz+1), 1, C % fdg12 (1,1,nev+1),(Maxy-Miny+1) * (Maxz-Minz+1), 1, C % Gni-nev, Gni-nev, (Maxy-Miny+1) * Nkl ) * !$omp do do k=1,Nkl call dgemm('N','T', (Maxy-Miny+1),Gni-nev,Gni-nev, . 1._8, fdwfft(1,k,nev+1), . (Maxy-Miny+1) * (Maxz-Minz+1),oddxevec, NSTOR, . 0._8, fdg12(1,k,nev+1), . (Maxy-Miny+1) * (Maxz-Minz+1)) enddo !$omp end do * C call mxma8( evxevec, 1,NSTOR, C % fdwfft(1,1,1), (Maxy-Miny+1) * (Maxz-Minz+1), 1, C % fdg12 (1,1,1), (Maxy-Miny+1) * (Maxz-Minz+1), 1, C % nev, nev, (Maxy-Miny+1) * Nkl ) * !$omp do do k=1,Nkl call dgemm('N','T', (Maxy-Miny+1), nev, nev, . 1._8, fdwfft(1,k,1), . (Maxy-Miny+1) * (Maxz-Minz+1),evxevec, NSTOR, . 0._8, fdg12(1,k,1), . (Maxy-Miny+1) * (Maxz-Minz+1)) enddo !$omp end do * * ADJ of * odd part of rhs * !$omp do do k=Nkl,1,-1 do i=Gni-nev,1,-1 do j=njl,1,-1 fdg1 (j,k,i+1) = fdg12(j,k,i+nev) + fdg1(j,k,i+1) fdg1 (j,k,Gni+1-i) = -fdg12(j,k,i+nev) + fdg1(j,k,Gni+1-i) fdg12(j,k,i+nev) = ZERO_8 enddo enddo enddo !$omp enddo * * ADJ of * even part of rhs * if(Gni.eq.(2*(Gni/2)) ) then !$omp do do k=Nkl,1,-1 do j=njl,1,-1 fdg1 (j,k,nev) = fdg12(j,k,nev) + fdg1(j,k,nev) fdg12(j,k,nev) = ZERO_8 enddo enddo !$omp enddo endif * !$omp do do i= (Gni+1)/2,2,-1 do k=Nkl,1,-1 do j=njl,1,-1 fdg1 (j,k,i) = fdg12(j,k,i) + fdg1(j,k,i) fdg1 (j,k,Gni+2-i) = fdg12(j,k,i) + fdg1(j,k,Gni+2-i) fdg12(j,k,i) = ZERO_8 enddo enddo enddo !$omp enddo * !$omp do do k=1,Nkl do j=1,njl fdg1 (j,k,1) = fdg12(j,k,1) + fdg1(j,k,1) fdg12(j,k,1) = ZERO_8 enddo enddo !$omp enddo * !$omp do do i= 1,Gni do k= Nkl+1,Maxz do j= Miny,Maxy fdwfft(j,k,i)=ZERO_8 enddo enddo * do k= Minz,Maxz do j= njl+1,Maxy fdg1 (j,k,i)=ZERO_8 fdg12(j,k,i)=ZERO_8 enddo enddo enddo !$omp enddo * !$omp end parallel * call rpn_comm_transpose( Rhs, Minx, Maxx, Gni, (Maxy-Miny+1), % Minz, Maxz, Nk, fdg1, -1,2 ) * return end