!-------------------------------------- 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 tstpdyn_ad - ADJ of tstpdyn_tl
*
#include "model_macros_f.h"
*
subroutine tstpdyn_ad ( F_fnitraj ) 2,23
*
implicit none
*
integer F_fnitraj
*
*author
* M.Tanguay
*
*revision
* v2_10 - Tanguay M. - initial MPI version
* v2_21 - Tanguay M. - ADJ of HO option
* - ADJ of vertical sponge layer
* v2_31 - Tanguay M. - adapt ADJ to new advection code,
* hybrid coord., tracer tr3d and
* diffusion in gem_run
* v3_00 - Tanguay M. - adapt to restructured adw_main
* v3_02 - Tanguay M. - ADJ of Eigv_parity_L and Hspng_main done
* v3_03 - Tanguay M. - Adjoint NoHyd configuration
* v3_20 - Tanguay M. - Option of storing instead of redoing TRAJ
* v3_21 - Tanguay M. - Revision Openmp
* v3_30 - Tanguay M. - add parameter iln in sol_main
* v3_31 - Tanguay M. - Introduce time extrapolation
*
*object
* see id section
*
*arguments
* Name I/O Description
*----------------------------------------------------------------
* F_fnitraj I number of iterations to compute upstream
* positions
*----------------------------------------------------------------
*
*implicits
#include "glb_ld.cdk"
#include "lun.cdk"
#include "cstv.cdk"
#include "schm.cdk"
#include "orh.cdk"
#include "sol.cdk"
#include "nl.cdk"
#include "v4dg.cdk"
#include "nlm.cdk"
#include "vt1m.cdk"
#include "vt0m.cdk"
#include "rhscm.cdk"
#include "orhm.cdk"
#include "tr3d.cdk"
#include "lctl.cdk"
#include "v4dr.cdk"
*
*modules
integer vmmlod,vmmuld,vmmget
external vmmlod,vmmuld,vmmget
*
integer pnerr, pnlkey1(10), key0m(Tr3d_ntr), keyorm(Tr3d_ntr),
$ key0m_, keyorm_, err, iln, dim, ilntrj, i, j, k, n
*
real tr0m,orm
pointer (patr0m, tr0m(LDIST_SHAPE,*)),(paorm, orm(LDIST_SHAPE,*))
*
real prdth
*
real*8, parameter :: ZERO_8 = 0.0
* ______________________________________________________
*
prdth = Cstv_dt_8/2.
*
if (Lun_debug_L) write(Lun_out,1000)
*
* ----------------
* START TRAJECTORY
* ----------------
*
* Recover TRAJ predictive variables
* ---------------------------------
if ( (Orh_crank_L .and. Orh_icn.eq.Schm_itcn) .or. .not.Orh_crank_L ) call v4d_rwtraj
(3)
*
call rhs_tr
*
* Recover TRAJ Positions TH
* -------------------------
call v4d_rwtraj
(4)
*
* Recover TRAJ Winds TH
* ---------------------
call v4d_rwtraj
(5)
*
call adw_main_tr
( F_fnitraj )
*
call pre_tr
()
*
dim = (l_maxx-l_minx+1)*(l_maxy-l_miny+1)*l_nk
call hpalloc (nlm_num_ , dim, err,1)
call hpalloc (nlm_nvm_ , dim, err,1)
call hpalloc (nlm_nthm_ , dim, err,1)
call hpalloc (nlm_ncnm_ , dim, err,1)
nlm_n3m_ = 0
nlm_n3pm_ = 0
if (.not. Schm_hydro_L) then
call hpalloc (nlm_n3m_ , dim, err,1)
call hpalloc (nlm_n3pm_ , dim, err,1)
endif
*
* --------------
* END TRAJECTORY
* --------------
if (Lun_debug_L) write (Lun_out,1005) Schm_itnlh
*
* ADJ
* ---
dim = (l_maxx-l_minx+1)*(l_maxy-l_miny+1)*l_nk
call hpalloc (nl_nu_ , dim, err,1)
call hpalloc (nl_nv_ , dim, err,1)
call hpalloc (nl_nth_ , dim, err,1)
call hpalloc (nl_ncn_ , dim, err,1)
nl_n3_ = 0
nl_n3p_ = 0
if (.not. Schm_hydro_L) then
call hpalloc (nl_n3_ , dim, err,1)
call hpalloc (nl_n3p_ , dim, err,1)
endif
*
* Zero adjoint variables
* ----------------------
!$omp parallel
!$omp do
do k = 1,l_nk
do j = l_miny,l_maxy
do i = l_minx,l_maxx
nl_nu (i,j,k) = ZERO_8
nl_nv (i,j,k) = ZERO_8
nl_nth(i,j,k) = ZERO_8
nl_ncn(i,j,k) = ZERO_8
enddo
enddo
enddo
!$omp enddo
if (.not. Schm_hydro_L) then
!$omp do
do k = 1,l_nk
do j = l_miny,l_maxy
do i = l_minx,l_maxx
nl_n3 (i,j,k) = ZERO_8
nl_n3p (i,j,k) = ZERO_8
enddo
enddo
enddo
!$omp enddo
endif
!$omp end parallel
*
do 100 iln=Schm_itnlh,1,-1
*
* ----------------
* START TRAJECTORY
* ----------------
ilntrj = 1
*
if (Orh_icn.ne.1) then
*
* Recover fields at T0 and TX used as INPUT but changed by updating (subr. BAC)
* -----------------------------------------------------------------------------
call v4d_rwtraj
(6)
*
else
*
* Recover fields at T0 used as INPUT but changed by updating (subr. BAC)
* ----------------------------------------------------------------------
call frstgss_tr
*
* Recover fields at TX used as INPUT but changed by updating (subr. BAC)
* ----------------------------------------------------------------------
if (.not. Schm_hydro_L) call v4d_rwtraj
(7)
*
endif
*
if (iln.gt.1) then
*
do ilntrj=1,iln-1
*
call nli_tr
()
*
if ( V4dr_redotr_L ) then
*
call sol_main_tr
(iln)
*
else
*
* Recover TRAJ GPTX at end of SOL_MAIN
* ------------------------------------
V4dr_iln = ilntrj
call v4d_rwtraj
(9)
*
endif
*
call bac_tr
( ilntrj, Schm_itnlh )
*
enddo
*
endif
*
call nli_tr
()
*
if ( V4dr_redotr_L ) then
*
call sol_main_tr
(iln)
*
else
*
* Recover TRAJ GPTX at end of SOL_MAIN
* ------------------------------------
V4dr_iln = iln
call v4d_rwtraj
(9)
*
endif
*
* --------------
* END TRAJECTORY
* --------------
*
call bac_ad
( iln, Schm_itnlh )
*
call sol_main_ad
(iln)
*
call nli_ad
()
*
100 continue
*
* TRAJECTORY
* ----------
call hpdeallc(nlm_num_ , err)
call hpdeallc(nlm_nvm_ , err)
call hpdeallc(nlm_nthm_, err)
call hpdeallc(nlm_ncnm_, err)
if (.not. Schm_hydro_L) then
call hpdeallc(nlm_n3m_ , err)
call hpdeallc(nlm_n3pm_, err)
endif
*
* ADJ
* ---
call hpdeallc(nl_nu_ , err)
call hpdeallc(nl_nv_ , err)
call hpdeallc(nl_nth_, err)
call hpdeallc(nl_ncn_, err)
if (.not. Schm_hydro_L) then
call hpdeallc(nl_n3_ , err)
call hpdeallc(nl_n3p_, err)
endif
*
if (Orh_icn.eq.1) call frstgss_ad
( )
*
* START TRAJECTORY
* ----------------
* Recover TRAJ RHS (RUMW2,RVMW2) before PRE
* -----------------------------------------
pnlkey1(1) = VMM_KEY(ruw2m)
pnlkey1(2) = VMM_KEY(rvw2m)
pnlkey1(3) = VMM_KEY(oruw2m)
pnlkey1(4) = VMM_KEY(orvw2m)
pnerr = vmmlod(pnlkey1,4)
pnerr = VMM_GET_VAR(ruw2m)
pnerr = VMM_GET_VAR(rvw2m)
pnerr = VMM_GET_VAR(oruw2m)
pnerr = VMM_GET_VAR(orvw2m)
*
!$omp parallel do
do k=1,l_nk
do j=1,l_nj
do i=1,l_ni
ruw2m(i,j,k) = oruw2m(i,j,k)
rvw2m(i,j,k) = orvw2m(i,j,k)
end do
end do
end do
!$omp end parallel do
pnerr = vmmuld(-1,0)
*
* END TRAJECTORY
* --------------
*
call pre_ad
()
*
* START TRAJECTORY
* ----------------
* Recover TRAJ RHS (RCNM,RTHM) before ADW_MAIN_AD
* -----------------------------------------------
pnlkey1(1) = VMM_KEY(rcnm)
pnlkey1(2) = VMM_KEY(rthm)
pnlkey1(3) = VMM_KEY(orcnm)
pnlkey1(4) = VMM_KEY(orthm)
if (.not. Schm_hydro_L) then
pnlkey1(5) = VMM_KEY(rwm)
pnlkey1(6) = VMM_KEY(rvvm)
pnlkey1(7) = VMM_KEY(orwm)
pnlkey1(8) = VMM_KEY(orvvm)
pnerr = vmmlod(pnlkey1,8)
else
pnerr = vmmlod(pnlkey1,4)
endif
*
pnerr = VMM_GET_VAR(rcnm)
pnerr = VMM_GET_VAR(rthm)
pnerr = VMM_GET_VAR(orcnm)
pnerr = VMM_GET_VAR(orthm)
if (.not. Schm_hydro_L) then
pnerr = VMM_GET_VAR(rwm)
pnerr = VMM_GET_VAR(rvvm)
pnerr = VMM_GET_VAR(orwm)
pnerr = VMM_GET_VAR(orvvm)
endif
*
!$omp parallel
*
!$omp do
do k=1,l_nk
do j=1,l_nj
do i=1,l_ni
rcnm(i,j,k) = orcnm(i,j,k)
rthm(i,j,k) = orthm(i,j,k)
end do
end do
end do
!$omp end do
if (.not. Schm_hydro_L) then
!$omp do
do k=1,l_nk
do j=1,l_nj
do i=1,l_ni
rwm (i,j,k) = orwm (i,j,k)
rvvm(i,j,k) = orvvm(i,j,k)
end do
end do
end do
!$omp end do
endif
*
!$omp end parallel
*
pnerr = vmmuld(-1,0)
*
* Recover TRAJ ORTR before ADW_MAIN_AD
* ------------------------------------
if ( Orh_icn .eq. Schm_itcn. or. .not.Orh_crank_L ) then
*
key0m_ = VMM_KEY (trt0m)
keyorm_= VMM_KEY (ortrm)
do n=1,Tr3d_ntr
key0m (n) = key0m_ + n
keyorm(n) = keyorm_ + n
end do
if (Tr3d_ntr.gt.0) then
err = vmmlod(key0m, Tr3d_ntr)
err = vmmlod(keyorm,Tr3d_ntr)
do n=1,Tr3d_ntr
err = vmmget(key0m (n),patr0m,tr0m)
err = vmmget(keyorm(n),paorm, orm)
!$omp parallel do
do k=1,l_nk
do j=1,l_nj
do i=1,l_ni
tr0m(i,j,k) = orm(i,j,k)
end do
end do
end do
!$omp end parallel do
end do
err = vmmuld(key0m, Tr3d_ntr)
err = vmmuld(keyorm,Tr3d_ntr)
endif
*
endif
*
* END TRAJECTORY
* --------------
*
call adw_main_ad
( F_fnitraj )
*
call rhs_ad
()
*
* ---------------------------------------------------------------
*
1000 format(
+ 3X,'ADJ of PERFORM A DYNAMICAL STEP: (S/R TSTPDYN_AD)',
+/3X,'=================================================',/)
1005 format(
$3X,'ADJ of ITERATING SCHM_ITNLH=',I3,' TIMES TO SOLVE NON-LINEAR '
$ 'HELMHOLTZ PROBLEM',/)
return
end