!-------------------------------------- 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 uv2tdpsd_ad - ADJ of uv2tdpsd_tl * #include "model_macros_f.h"*
subroutine uv2tdpsd_ad( F_td, F_psd, F_uu, F_vv, F_ss, 3,9 $ F_uum,F_vvm,F_ssm, $ DIST_DIM, Nk ) * implicit none * integer DIST_DIM, Nk * real F_td(DIST_SHAPE,Nk), F_psd(DIST_SHAPE,Nk), $ F_uu(DIST_SHAPE,Nk), F_vv (DIST_SHAPE,Nk), $ F_ss(DIST_SHAPE), $ F_uum(DIST_SHAPE,Nk),F_vvm (DIST_SHAPE,Nk), $ F_ssm(DIST_SHAPE) * *author * M.Tanguay * *revision * v2_10 - Tanguay M. - initial MPI version * v2_31 - Tanguay M. - adapt for vertical hybrid coordinate * v3_00 - Laroche S. - cleanup * v3_02 - Tanguay M. - correct zeroing of winds halo * v3_03 - Tanguay M. - use v4d_zerohalo * - split call to rpn_comm_xch_halo for uv * v3_11 - Tanguay M. - AIXport+Opti+OpenMP for TLM-ADJ * v3_21 - Tanguay M. - Revision Openmp * v3_30 - Tanguay M. - Revision Openmp LAM * *object * see id section * *arguments *_________________________________________________________________________ * | | | | * NAME | DESCRIPTION | DIMENSION |I/O| *----------|---------------------------------------------|-----------|---| * F_td | total divergence | 3D |io | * F_psd | vertical velocity ( pi*-dot ) | 3D |io | *----------|---------------------------------------------|-----------|---| * F_uu | x component of velocity | 3D |io | * F_vv | y component of velocity | 3D |io | * F_ss | ln ( pi / z ) | 2D |io | * | s s | | | * F_uum | traj of x component of velocity | 3D |i | * F_vvm | traj of y component of velocity | 3D |i | * F_ssm | traj of ln ( pi / z ) | 2D |i | * | s s | | | *__________|_____________________________________________|___________|___| * *implicits #include "glb_ld.cdk"
#include "cstv.cdk"
#include "dcst.cdk"
#include "schm.cdk"
#include "geomg.cdk"
#include "intuv.cdk"
#include "inuvl.cdk"
* integer i, j, k, ng real pr1, prsc, pr1m real*8, parameter :: ZERO_8 = 0.0 * real F_psdm(LDIST_SHAPE,l_nk),F_tdm(LDIST_SHAPE,l_nk) real uv(DIST_SHAPE,Nk,2), dvi(DIST_SHAPE,Nk), w1(DIST_SHAPE,Nk) real uvm(DIST_SHAPE,Nk,2),dvim(DIST_SHAPE,Nk),w1m(DIST_SHAPE,Nk) real*8 expfm_8(l_niu+1,l_njv+1), expfm1m_8(l_niu+1,l_njv+1), $ inv_Geomg_hx_8(l_ni), gratio_8(l_nj), inv_Geomg_cy2_8(l_nj), $ dpib1m_8(l_niu+1,l_njv+1), inv1m_8(l_niu+1,l_njv+1,Nk), $ dpib2m_8(l_niu+1,l_njv+1), inv2m_8(l_niu+1,l_njv+1,Nk) * * ________________________________________________________________ * * ZERO adjoint and working variables * ---------------------------------- C pr1 = ZERO_8 * w1 = 0. dvi = 0. uv = 0. * ________________________________________________________________ * * ---------------- * START TRAJECTORY * ---------------- * call rpn_comm_xch_halo( F_ssm, LDIST_DIM, l_ni, l_nj , 1, $ G_halox,G_haloy,G_periodx,G_periody,l_ni,0) * !$omp parallel !$omp do do k=1,Nk * * TRAJECTORY * ---------- F_tdm (:,:,k ) = 0. uvm (:,:,k,:) = 0. * if(k.eq.1) then * do j = 1,l_njv+1 do i = 1,l_niu+1 expfm_8 (i,j) = exp(F_ssm(i,j)) expfm1m_8(i,j) = expfm_8(i,j) - 1.0d0 end do end do do i = 1, l_niu inv_Geomg_hx_8(i) = 1.0d0 / Geomg_hx_8(i) end do * do j = 1, l_nj gratio_8(j) = Geomg_cyv2_8(j) / Geomg_hsy_8(j) inv_Geomg_cy2_8(j) = 1.0d0 / Geomg_cy2_8(j) end do * endif * end do !$omp end do * __ * * b) compute \/ . ( V dpi/dpi ) !$omp do do k=1,G_nk do j = 1, l_nj do i = 1, l_niu uvm(i,j,k,1) = F_uum(i,j,k) * ( $ (1.-intuv_c0xxu_8(i))*(1.+(Geomg_dpib(k)*expfm1m_8(i ,j))) $ + intuv_c0xxu_8(i) *(1.+(Geomg_dpib(k)*expfm1m_8(i+1,j))) ) end do end do do j = 1, l_njv do i = 1, l_ni uvm(i,j,k,2) = F_vvm(i,j,k) * ( $ (1.-intuv_c0yyv_8(j))*(1.+(Geomg_dpib(k)*expfm1m_8(i,j ))) $ + intuv_c0yyv_8(j) *(1.+(Geomg_dpib(k)*expfm1m_8(i,j+1))) ) end do end do end do !$omp end do * !$omp single call rpn_comm_xch_halo (uvm, LDIST_DIM, l_niu,l_nj, $ G_nk,G_halox,G_haloy,G_periodx,G_periody,l_ni,0 ) call rpn_comm_xch_halo (uvm(minx,miny,1,2),LDIST_DIM, l_ni,l_njv, $ G_nk,G_halox,G_haloy,G_periodx,G_periody,l_ni,0 ) !$omp end single * !$omp do do k=1,G_nk call caldiv_2
( F_tdm(minx,miny,k), uvm(minx,miny,k,1), $ uvm(minx,miny,k,2), LDIST_DIM, 1 ) end do !$omp end do !$omp end parallel * * * * pi * / gnk * | __ * * * c) compute | \/ . ( V dpi/dpi ) dpi * | * / * * pi * k * ng = (l_maxx-l_minx+1)*(l_maxy-l_miny+1) call hatoprg
(dvim,F_tdm,1.0,Geomg_hz_8,ng,G_nk) * !$omp parallel private (pr1m) !$omp do do k=1,G_nk do j=1,l_nj do i=1,l_ni * pr1m = 1.0 + Geomg_dpib(k) * expfm1m_8(i,j) F_psdm(i,j,k) = (dvim(i,j,k) + ((Geomg_pib(k)/ $ Geomg_pib(G_nk)) -1) * dvim(i,j,1))/pr1m * end do end do end do !$omp end do * .* * dpi * Compute D + ---- integrated vertically * ------- * * dpi * * compute V . \/ (dpi/dpi ) * !$omp do do k=1,G_nk * do j = 1, l_nj do i = 1, l_niu uvm(i,j,k,1) = (F_ssm(i+1,j)-F_ssm(i,j))*inv_Geomg_hx_8(i)*F_uum(i,j,k) end do end do * do j = 1, l_njv do i = 1, l_ni uvm(i,j,k,2) = (F_ssm(i,j+1) - F_ssm(i,j))*gratio_8(j)*F_vvm(i,j,k) end do end do * end do !$omp end do * !$omp end parallel * call itf_phy_uvgridscal
( uvm(minx,miny,1,1), uvm(minx,miny,1,2), $ LDIST_DIM, l_nk, .true.) * !$omp parallel * * Compute total divergence * ------------------------ * prsc = 1./Geomg_pib(G_nk) * !$omp do do k=1,G_nk do j= 1, l_nj do i= 1, l_ni * pr1m = (uvm(i,j,k,1)+uvm(i,j,k,2))*inv_Geomg_cy2_8(j) F_tdm(i,j,k)= Geomg_dpib(k)* (prsc*dvim(i,j,1) $ -expfm_8(i,j) * pr1m) $ -F_psdm(i,j,k)*expfm1m_8(i,j)*Geomg_dpia(k) * enddo enddo enddo !$omp enddo * * -------------- * END TRAJECTORY * -------------- * ________________________________________________________________ * * --------- * START ADJ * --------- * * ADJ of * Boundary conditions for vertical velocity * !$omp do do j= 1, l_nj do i= 1, l_ni * F_psd(i,j,1) = 0.0 F_psd(i,j,G_nk) = 0.0 * end do end do !$omp end do * * Compute total divergence * ------------------------ * prsc = 1./Geomg_pib(G_nk) * !$omp single do k=G_nk,1,-1 * do j= 1, l_njv+1 do i= 1, l_niu+1 dpib1m_8(i,j) = ( 1.0d0 + Geomg_dpib(k)* expfm1m_8(i,j) ) dpib2m_8(i,j) = dpib1m_8(i,j) * dpib1m_8(i,j) end do end do call vrec ( inv1m_8(1,1,k), dpib1m_8, (l_niu+1)*(l_njv+1) ) call vrec ( inv2m_8(1,1,k), dpib2m_8, (l_niu+1)*(l_njv+1) ) * enddo !$omp end single * !$omp do do j= 1, l_nj do k=G_nk,1,-1 do i= 1, l_ni * pr1m = (uvm(i,j,k,1)+uvm(i,j,k,2))*inv_Geomg_cy2_8(j) * F_ss(i,j) = - (Geomg_dpib(k)*( expfm_8(i,j) *F_td(i,j,k))) * $ (F_tdm(i,j,k)*inv2m_8(i,j,k)) + F_ss(i,j) * F_td(i,j,k) = F_td (i,j,k)* inv1m_8(i,j,k) * dvi(i,j,1) = Geomg_dpib(k)*( prsc *F_td(i,j,k)) + dvi(i,j,1) * F_ss(i,j) = Geomg_dpib(k)*(-expfm_8(i,j) *F_td(i,j,k)*pr1m) + F_ss(i,j) * w1(i,j,k) = Geomg_dpib(k)*(-expfm_8(i,j) *F_td(i,j,k)) + w1(i,j,k) * F_psd(i,j,k) = -F_td (i,j,k)* expfm1m_8(i,j)*Geomg_dpia(k) + F_psd(i,j,k) * F_ss(i,j) = -F_psdm(i,j,k)*(expfm_8(i,j) *F_td(i,j,k))*Geomg_dpia(k) + F_ss(i,j) * F_td(i,j,k) = ZERO_8 * enddo enddo enddo !$omp enddo * * .* * dpi * Compute D + ---- integrated vertically * ------- * * dpi * * * a) compute V . \/ (dpi/dpi ) * !$omp do do k=1,G_nk do j= 1, l_nj do i= 1, l_ni uv(i,j,k,1)= (w1(i,j,k))*inv_Geomg_cy2_8(j) + uv(i,j,k,1) uv(i,j,k,2)= (w1(i,j,k))*inv_Geomg_cy2_8(j) + uv(i,j,k,2) w1(i,j,k)= ZERO_8 end do end do end do !$omp end do * !$omp end parallel * call itf_phy_uvgridscal0_ad
( uv(minx,miny,1,1), uv(minx,miny,1,2), $ LDIST_DIM, l_nk, .true.) * !$omp parallel do do i = 1, l_ni do k=1,G_nk do j = l_njv,1,-1 * F_ss(i,j+1) = ( uv(i,j,k,2)*gratio_8(j))*F_vvm(i,j,k) + F_ss (i,j+1) * F_ss(i,j ) = (-uv(i,j,k,2)*gratio_8(j))*F_vvm(i,j,k) + F_ss (i,j) * F_vv(i,j,k) = uv(i,j,k,2)*gratio_8(j) *(F_ssm(i,j+1)-F_ssm(i,j)) + F_vv (i,j,k) * uv(i,j,k,2) = ZERO_8 * end do end do end do !$omp end parallel do * !$omp parallel do do j = 1, l_nj do k=1,G_nk do i = l_niu, 1,-1 F_ss(i+1,j) = ( uv(i,j,k,1)*inv_Geomg_hx_8(i))*F_uum(i,j,k)+ F_ss (i+1,j) * F_ss(i,j) = (-uv(i,j,k,1)*inv_Geomg_hx_8(i))*F_uum(i,j,k)+ F_ss (i,j) * F_uu(i,j,k) = uv(i,j,k,1)*((F_ssm(i+1,j)-F_ssm(i,j))*inv_Geomg_hx_8(i)) + F_uu (i,j,k) * uv(i,j,k,1) = ZERO_8 * end do end do end do !$omp end parallel do * * .* * d) compute pi * k * !$omp parallel do private (pr1m,pr1) do j=1,l_nj do k=G_nk,1,-1 do i=1,l_ni * pr1m = 1.0 + Geomg_dpib(k) * expfm1m_8(i,j) * dvi(i,j,k) = F_psd(i,j,k)/pr1m + dvi(i,j,k) * dvi(i,j,1) = (((Geomg_pib(k)/Geomg_pib(G_nk))-1)*F_psd(i,j,k))/pr1m + dvi(i,j,1) * C pr1 = - F_psd(i,j,k)*((dvim(i,j,k) + ((Geomg_pib(k)/Geomg_pib(G_nk))-1)*dvim(i,j,1))/pr1m**2) + pr1 * pr1 = - F_psd(i,j,k)*((dvim(i,j,k) + ((Geomg_pib(k)/Geomg_pib(G_nk))-1)*dvim(i,j,1))/pr1m**2) * F_psd(i,j,k) = ZERO_8 * F_ss(i,j) = Geomg_dpib(k) * (expfm_8(i,j)*pr1) + F_ss(i,j) * C pr1 = ZERO_8 * end do end do end do !$omp end parallel do * * * * pi * / gnk * | __ * * * c) compute | \/ . ( V dpi/dpi ) dpi * | * / * * pi * k * * ng = (l_maxx-l_minx+1)*(l_maxy-l_miny+1) call hatoprg0_ad
(dvi,F_td,1.0,Geomg_hz_8,ng,G_nk) * * Zero temporary Work adjoint array * --------------------------------- * * b) compute \/ . ( V dpi/dpi ) * * !$omp parallel do do k=1,G_nk if (k.eq.1) uv(:,:,k,:) = 0. call caldiv_2_ad
( F_td(minx,miny,k), uv(minx,miny,k,1), $ uv(minx,miny,k,2), LDIST_DIM, 1 ) end do !$omp end parallel do * call rpn_comm_adj_halo (uv(minx,miny,1,2), LDIST_DIM, l_ni,l_njv, $ G_nk,G_halox,G_haloy,G_periodx,G_periody,l_ni,0 ) call rpn_comm_adj_halo (uv, LDIST_DIM, l_niu,l_nj, $ G_nk,G_halox,G_haloy,G_periodx,G_periody,l_ni,0 ) * * Zero u,v halo * ------------- call v4d_zerohalo
( uv(minx,miny,1,2), l_ni, l_njv,LDIST_DIM, l_nk) call v4d_zerohalo
( uv, l_niu,l_nj, LDIST_DIM, l_nk) * * b) compute \/ . ( V dpi/dpi ) !$omp parallel do do i = 1, l_ni do k=1,G_nk do j = l_njv,1,-1 * F_ss(i,j) = F_ss(i,j) + $ (1.-intuv_c0yyv_8(j))*(Geomg_dpib(k)*( expfm_8(i,j) *uv(i,j,k,2)))*F_vvm(i,j,k) F_ss(i,j+1) = F_ss(i,j+1) + $ intuv_c0yyv_8(j) *(Geomg_dpib(k)*( expfm_8(i,j+1)*uv(i,j,k,2)))*F_vvm(i,j,k) F_vv(i,j,k) = F_vv(i,j,k) + $ ((1.-intuv_c0yyv_8(j))*(1.+Geomg_dpib(k)*expfm1m_8(i,j) ) $ + intuv_c0yyv_8(j) *(1.+Geomg_dpib(k)*expfm1m_8(i,j+1)))*uv(i,j,k,2) uv(i,j,k,2) = ZERO_8 end do end do end do !$omp end parallel do * !$omp parallel do do j = 1, l_nj do k=1,G_nk do i = l_niu,1,-1 * F_ss(i,j) = F_ss(i,j) + $ (1.-intuv_c0xxu_8(i))*(Geomg_dpib(k)*( expfm_8(i,j) *uv(i,j,k,1)))*F_uum(i,j,k) F_ss(i+1,j) = F_ss(i+1,j) + $ intuv_c0xxu_8(i) *(Geomg_dpib(k)*( expfm_8(i+1,j)*uv(i,j,k,1)))*F_uum(i,j,k) F_uu(i,j,k) = F_uu(i,j,k) + $ ((1.-intuv_c0xxu_8(i))*(1.+Geomg_dpib(k)* expfm1m_8(i,j)) $ + intuv_c0xxu_8(i) *(1.+Geomg_dpib(k)* expfm1m_8(i+1,j)))*uv(i,j,k,1) uv(i,j,k,1) = ZERO_8 end do end do end do !$omp end parallel do * call rpn_comm_adj_halo( F_ss, LDIST_DIM, l_ni, l_nj , 1, $ G_halox,G_haloy,G_periodx,G_periody,l_ni,0) * * Zero F_ss halo * -------------- call v4d_zerohalo
( F_ss, l_ni, l_nj, LDIST_DIM, 1) * * ADJ * --- !$omp parallel do do k=1,Nk * F_td (:,:,k ) = 0. uv (:,:,k,:) = 0. * enddo !$omp end parallel do * return end