!-------------------------------------- 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_hcr_ad - ADJ of sol_hcr * #include "model_macros_f.h"*
subroutine sol_hcr_ad (F_sol_8,F_rhs_8,F_w1_8,F_w2_8,F_dg1_8,F_dg2_8,F_dwfft_8, 1,4 % iln,Minx,Maxx,Miny,Maxy,Ni,Nj,Nk) * implicit none * integer iln,Minx,Maxx,Miny,Maxy,Ni,Nj,Nk real*8 F_sol_8 (Minx:Maxx,Miny:Maxy,Nk), $ F_rhs_8 (Minx:Maxx,Miny:Maxy,Nk), $ F_w1_8 (Minx:Maxx,Miny:Maxy,Nk), $ F_w2_8 (Minx:Maxx,Miny:Maxy,Nk), $ F_dg1_8(*),F_dg2_8(*),F_dwfft_8(*) * *author * M.Tanguay * *revision * v2_10 - Tanguay M. - initial MPI version * v2_31 - Tanguay M. - adapt to f90 native dynamic memory allocation * v3_00 - Tanguay M. - adapt to restructured sol_hcr * v3_02 - Tanguay M. - ADJ of Eigv_parity_L done * v3_03 - Tanguay M. - Adjoint Lam configuration * v3_11 - Tanguay M. - AIXport+Opti+OpenMP for TLM-ADJ * v3_21 - Tanguay M. - Revision Openmp * v3_30 - Tanguay M. - adjust OPENMP * v3_30 - Tanguay M. - add parameter iln in sol_main * *object * see id section * *arguments * Name I/O Description *---------------------------------------------------------------- * F_sol_8 I/O *---------------------------------------------------------------- * *implicits #include "glb_ld.cdk"
#include "glb_pil.cdk"
#include "ldnh.cdk"
#include "sol.cdk"
#include "opr.cdk"
#include "eigv.cdk"
#include "ptopo.cdk"
#include "fft.cdk"
#include "cstv.cdk"
#include "schm.cdk"
#include "trp.cdk"
* integer i, j, k, k0, offi, offj, Gni, Gnj,NSTOR,nev real*8 abpt((maxy-miny+1)*(trp_12smax-trp_12smin+1)*G_ni) real*8 con(G_nk) real*8, dimension(:),allocatable :: wk_evec_8 * real*8 ZERO_8 parameter( ZERO_8 = 0.0 ) * * Zero adjoint variables * ---------------------- if (.not.Fft_fast_L.and.Eigv_parity_L) then do k=1,(maxy-miny+1)*(trp_12smax-trp_12smin+1)*G_ni abpt(k) = ZERO_8 enddo endif * * Calculate length of working vector without pilot region Gni=G_ni-Lam_pil_w-Lam_pil_e Gnj=G_nj-Lam_pil_s-Lam_pil_n * if (.not.Fft_fast_L) then allocate ( wk_evec_8(Gni*Gni) ) do j=1,Gni do i=1,Gni wk_evec_8((j-1)*Gni+i)=Opr_xevec_8((j+Lam_pil_w-1)*G_ni+i+Lam_pil_w) enddo enddo endif * * TRAJECTORY * ---------- do k=1,G_nk con(k) = 1. enddo con(G_nk) = -1./Cstv_hco0_8 * * ADJ of * inverse projection * !$omp parallel shared( G_nk ) !$omp do do j=1+pil_s,Nj-pil_n call dgemm('N','N', (ni-pil_w-pil_e), G_nk, G_nk, 1.0D0, $ F_sol_8(1+pil_w,j,1), (Maxy-Miny+1)*(Maxx-Minx+1), $ Opr_zevec_8,g_nk,0.0d0, $ F_w2_8 (1+pil_w,j,1), (Maxy-Miny+1)*(Maxx-Minx+1)) * F_w1_8(1+pil_w:Ni-pil_e,j,G_nk) = $ con(G_nk)*F_w2_8(1+pil_w:Ni-pil_e,j,G_nk) + F_w1_8(1+pil_w:Ni-pil_e,j,G_nk) F_w2_8(1+pil_w:Ni-pil_e,j,G_nk) = ZERO_8 enddo !$omp enddo !$omp end parallel * c!$omp parallel c!$omp do c do k=1,G_nk c do k0=1,G_nk c do j=1+pil_s,Nj-pil_n c do i=1+pil_w,Ni-pil_e c F_w2_8(i,j,k) = con(k)*F_sol_8(i,j,k0)*Opr_zevec_8((k-1)*G_nk+k0) c % + F_w2_8(i,j,k) c enddo c enddo c enddo c enddo c!$omp enddo c* c!$omp do c do j=1+pil_s,Nj-pil_n c do i=1+pil_w,Ni-pil_e c F_w1_8(i,j,G_nk) = F_w2_8(i,j,G_nk) + F_w1_8(i,j,G_nk) c F_w2_8(i,j,G_nk) = ZERO_8 c end do c end do c!$omp end do c!$omp end parallel * if (Fft_fast_L) then if (G_lam) then * call sol_fft8_lam_ad
( F_w2_8, F_w1_8, Fft_pri_8, $ Minx, Maxx, Miny, Maxy, ldnh_nj, $ trp_12smin, trp_12smax, Schm_nith, trp_12sn , $ G_ni, G_nj, trp_22min , trp_22max, trp_22n , $ trp_12smin, trp_12smax, trp_22min, trp_22max,G_nj, $ Ptopo_npex, Ptopo_npey, Sol_ai_8,Sol_bi_8,Sol_ci_8, $ F_dg2_8,F_dwfft_8) else * call sol_fft8_2_ad
( F_w2_8, F_w1_8, Fft_pri_8, $ Minx, Maxx, Miny, Maxy, ldnh_nj, $ trp_12smin, trp_12smax, Schm_nith, trp_12sn , $ G_ni, G_nj, trp_22min , trp_22max, trp_22n , $ trp_12smin, trp_12smax, trp_22min, trp_22max,G_nj, $ Ptopo_npex, Ptopo_npey, Sol_ai_8,Sol_bi_8,Sol_ci_8, $ F_dg2_8,F_dwfft_8) * endif else if(.not. Eigv_parity_L) then * call sol_mxma8_2_ad
( F_w2_8, F_w1_8, wk_evec_8, $ Minx, Maxx, Miny, Maxy, ldnh_nj, $ trp_12smin, trp_12smax, Schm_nith, trp_12sn , $ G_ni, G_nj, trp_22min , trp_22max, trp_22n , $ trp_12smin, trp_12smax, trp_22min, trp_22max,G_nj, $ Ptopo_npex, Ptopo_npey, Sol_ai_8,Sol_bi_8,Sol_ci_8, $ F_dg1_8,F_dg2_8,F_dwfft_8) else * nev= (G_ni+2)/2 NSTOR = nev + ( 1 - mod(nev,2) ) * call sol_parite_2_ad
( F_w2_8, F_w1_8, Opr_evvec_8, Opr_odvec_8, $ Minx, Maxx, Miny, Maxy, l_nj, $ trp_12smin, trp_12smax, Schm_nith, trp_12sn , $ G_ni, G_nj, trp_22min , trp_22max, trp_22n , $ trp_12smin, trp_12smax, trp_22min, trp_22max,G_nj, $ Ptopo_npex, Ptopo_npey, Sol_ai_8,Sol_bi_8,Sol_ci_8, $ F_dg1_8,F_dg2_8,F_dwfft_8,Abpt,NSTOR,nev) endif * endif * !$omp parallel shared( offi,offj,G_nk ) * offi = Ptopo_gindx(1,Ptopo_myproc+1)-1 offj = Ptopo_gindx(3,Ptopo_myproc+1)-1 * !$omp do do j=1+pil_s,Nj-pil_n do k=1,Schm_nith do i = 1+pil_w, Ni-pil_e F_w1_8(i,j,k)= Opr_opsxp0_8(G_ni+offi+i) * $ Opr_opsyp0_8(G_nj+offj+j) * F_w1_8(i,j,k) enddo end do call dgemm('N','T', (ni-pil_w-pil_e), G_nk, G_nk, 1.0D0, $ F_w1_8 (1+pil_w,j,1), (Maxy-Miny+1)*(Maxx-Minx+1), $ Opr_zevec_8,g_nk,0.0d0, $ F_rhs_8(1+pil_w,j,1), (Maxy-Miny+1)*(Maxx-Minx+1)) end do !$omp enddo * c!$omp do c do k = 1, Schm_nith c do j = 1+pil_s, Nj-pil_n c do i = 1+pil_w, Ni-pil_e c F_w1_8(i,j,k) = Opr_opsxp0_8(G_ni+offi+i) * c $ Opr_opsyp0_8(G_nj+offj+j) * F_w1_8(i,j,k) c enddo c enddo c enddo c!$omp enddo * c!$omp do c do k0=1,G_nk c do k=1,G_nk c do j=1+pil_s,Nj-pil_n c do i=1+pil_w,Ni-pil_e c F_rhs_8(i,j,k0)=F_w1_8(i,j,k)*Opr_zevec_8((k-1)*G_nk+k0)+F_rhs_8(i,j,k0) c enddo c enddo c enddo c enddo c!$omp enddo * c!$omp do c do 101 k=1,G_nk c do j=1,Nj c do i=1,Ni c F_sol_8(i,j,k) = ZERO_8 c F_w1_8 (i,j,k) = ZERO_8 c F_w2_8 (i,j,k) = ZERO_8 c enddo c enddo c101 continue c!$omp enddo * !$omp end parallel * if (.not. Fft_fast_L) deallocate (wk_evec_8) * * --------------------------------------------------------------- * return end