!-------------------------------------- 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 v4d_putdx - Prepare and Write increments or adjoint increments
* to be read by 3D-Var
*
#include "model_macros_f.h"
*
subroutine v4d_putdx(kstatus) 4,24
*
use v4d_prof
, only: Pr_mode_S, Pr_nsim4d
use v4dz
, only: V4dzgauss_ni,V4dzgauss_nj
*
implicit none
*
integer, intent(inout):: kstatus
*
*author
* P. Gauthier
*
*revision
* v3_00 - P. Gauthier - initial MPI version
* v3_00 - M. Tanguay - add v4d_gauss2gem_ad/Simon's exchange
* v3_01 - Tanguay/Buehner - introduce gem2gauss for singular vectors
* v3_02 - Tanguay M. - locate HU in tracers
* v3_30 - Fillion/Tanguay - Adapt diagnostics for LAM
*
*object
* -------------------------
* If V4dg_di_L or V4dg_tl_L
* -------------------------
* 1) All processors: Conversion from GEM units and Staggering to 3D-Var units
* 2) Proc0: Transfert from GEM scalar grid to Gaussian grid
* 3) Proc0: Write increments to be read by 3D-Var
*
* ------------
* If V4dg_ad_L
* ------------
* 1) All processors: Adjoint of [Conversion from 3D-Var units to GEM units and Staggering]
* 2) Proc0: Adjoint of [Transfert from Gaussian grid to GEM scalar grid]
* 3) Proc0: Write adjoint increments to be read by 3D-Var
*
*arguments
* Name I/O Description
*----------------------------------------------------------------
* kstatus I Status of the job
*----------------------------------------------------------------
*
*implicits
#include "glb_ld.cdk"
#include "v4dg.cdk"
#include "lun.cdk"
#include "vt1.cdk"
#include "vt1m.cdk"
#include "ptopo.cdk"
#include "geomg.cdk"
#include "tr3d.cdk"
#include "lctl.cdk"
#include "path.cdk"
#include <clib_interface.cdk>
#include <prof_f.h>
*
* Local variables
* ---------------
integer istat,ihdlout,icount,jlev,jlat,jlon,ierr,
% pnerr,pnlkey1(8),nigauss,njgauss,inn
*
real*8,allocatable:: dlbuff_8(:,:), dlbuff2d_8(:)
real, allocatable:: zbuff(:,:,:),zbuff2d(:,:)
real, allocatable:: gut1 (:,:,:),gvt1(:,:,:),gtpt1(:,:,:),
% ghut1(:,:,:),gst1(:,:)
*
character*256 pathdwga_S,pathdwgf_S
*
integer vmmlod,vmmget,vmmuld,prof_wrrec
external vmmlod,vmmget,vmmuld,prof_wrrec
*
integer key1(Tr3d_ntr), key1_, key1m(Tr3d_ntr), key1m_, n, err
real hut1, hut1m
pointer (pahu1, hut1(LDIST_SHAPE,*)), (pahu1m, hut1m(LDIST_SHAPE,*))
*
real*8, parameter :: ZERO_8 = 0.0
*
logical plpr_L
* ______________________________________________________
*
if ( V4dg_di_L ) call gem_stop
('v4d_putdx',-1)
* ______________________________________________________
*
write(Lun_out,2000)
* Flag for diagnostics
* --------------------
plpr_L=.false.
*
* Recall dimensions of 3D-Var Gaussian grid
* -----------------------------------------
nigauss = V4dzgauss_ni
njgauss = V4dzgauss_nj
*
if (Ptopo_myproc.eq.0) then
if(.not.allocated(gut1 )) allocate(gut1 (nigauss,njgauss,G_nk))
if(.not.allocated(gvt1 )) allocate(gvt1 (nigauss,njgauss,G_nk))
if(.not.allocated(gtpt1)) allocate(gtpt1(nigauss,njgauss,G_nk))
if(.not.allocated(ghut1)) allocate(ghut1(nigauss,njgauss,G_nk))
if(.not.allocated(gst1 )) allocate(gst1 (nigauss,njgauss) )
*
* Zero adjoint variables
* ----------------------
gut1 (:,:,:) = ZERO_8
gvt1 (:,:,:) = ZERO_8
gtpt1(:,:,:) = ZERO_8
ghut1(:,:,:) = ZERO_8
gst1 (:,: ) = ZERO_8
endif
*
* Get fields in memory
* --------------------
pnlkey1(1) = VMM_KEY(ut1)
pnlkey1(2) = VMM_KEY(vt1)
pnlkey1(3) = VMM_KEY(tpt1)
pnlkey1(4) = VMM_KEY(st1)
*
if(V4dg_tl_L.or.V4dg_ad_L) then
pnlkey1(5) = VMM_KEY(tpt1m)
pnlkey1(6) = VMM_KEY(st1m)
*
pnerr = vmmlod(pnlkey1,6)
*
pnerr = VMM_GET_VAR(tpt1m)
pnerr = VMM_GET_VAR(st1m)
elseif(V4dg_di_L) then
pnerr = vmmlod(pnlkey1,4)
endif
*
pnerr = VMM_GET_VAR(ut1)
pnerr = VMM_GET_VAR(vt1)
pnerr = VMM_GET_VAR(tpt1)
pnerr = VMM_GET_VAR(st1)
*
if(V4dg_tl_L.or.V4dg_ad_L) then
*
* Load PERT and TRAJ humidity fields
* ----------------------------------
key1_ = VMM_KEY (trt1 )
key1m_= VMM_KEY (trt1m)
do n=1,Tr3d_ntr
key1 (n) = key1_ + n
key1m(n) = key1m_ + n
end do
err = vmmlod(key1, Tr3d_ntr)
err = vmmlod(key1m,Tr3d_ntr)
do n=1,Tr3d_ntr
if (Tr3d_name_S(n).eq.'HU') then
err = vmmget(key1 (n),pahu1, hut1 )
err = vmmget(key1m(n),pahu1m,hut1m)
endif
end do
*
elseif(V4dg_di_L) then
*
* Load humidity fields
* --------------------
key1_ = VMM_KEY (trt1 )
do n=1,Tr3d_ntr
key1 (n) = key1_ + n
end do
err = vmmlod(key1, Tr3d_ntr)
do n=1,Tr3d_ntr
if (Tr3d_name_S(n).eq.'HU') err = vmmget(key1 (n),pahu1, hut1 )
end do
*
endif
*
if(plpr_L) then
inn= 0
if (G_lam) then
inn=1
endif
write(Lun_out,*) 'BEFORE VARCONV OR VARCONV_AD'
call glbstat
(ut1 ,'UU',LDIST_DIM,G_nk,1,G_ni-inn,1,G_nj, 1,G_nk)
call glbstat
(vt1 ,'VV',LDIST_DIM,G_nk,1,G_ni,1,G_nj-1,1,G_nk)
call glbstat
(tpt1,'TP',LDIST_DIM,G_nk,1,G_ni,1,G_nj, 1,G_nk)
call glbstat
(st1 ,'4S',LDIST_DIM, 1,1,G_ni,1,G_nj, 1, 1)
call glbstat
(hut1,'HU',LDIST_DIM,G_nk,1,G_ni,1,G_nj, 1,G_nk)
write(Lun_out,*) '-----------------------'
endif
*
if(V4dg_di_L.or.V4dg_tl_L) then
* --------------------------------------------------------
* Conversion from GEM units and Staggering to 3D-Var units
* --------------------------------------------------------
*
* Direct (nonlinear)
* ------------------
if(V4dg_di_L) then
call v4d_varconv
(ut1,vt1,tpt1,hut1,st1,LDIST_DIM,l_nk,.FALSE.)
*
* TLM
* ---
elseif(V4dg_tl_L) then
call v4d_varconv_tl
(ut1,vt1,tpt1,hut1,st1,
$ tpt1m,hut1m,st1m,LDIST_DIM,l_nk,.FALSE.)
end if
*
elseif(V4dg_ad_L) then
* ---------------------------------------------------------------------
* Adjoint of [Conversion from 3D-Var units to GEM units and Staggering]
* ---------------------------------------------------------------------
call v4d_varconv_ad
(ut1,vt1,tpt1,hut1,st1,
% tpt1m,hut1m,st1m,LDIST_DIM,l_nk,.TRUE.)
endif
*
if(Ptopo_myproc.eq.0) then
*
if(V4dg_di_L.or.V4dg_tl_L) then
*
* 1A.Opening dwgf PROF file
* ----------------------
write(Lun_out,*) 'Opening file dwgf PROF file'
*
pathdwgf_S = trim(Path_xchg_S)//'/dwgf1.prof'
ihdlout = prof_open(pathdwgf_S,'WRITE',Pr_mode_S)
*
if(ihdlout.le.0) then
write(Lun_out,*) 'Problem opening dwgf PROF file'
kstatus = -99
goto 1001
end if
*
elseif(V4dg_ad_L) then
*
* 1B.Opening dwga PROF file
* ----------------------
write(Lun_out,*) 'Opening file dwga PROF file'
*
pathdwga_S = trim(Path_xchg_S)//'/dwga.prof'
ihdlout = prof_open(pathdwga_S,'WRITE',Pr_mode_S)
*
if(ihdlout.le.0) then
write(Lun_out,*) 'Problem opening dwga PROF file'
kstatus = -99
goto 1001
end if
*
end if
*
end if
*
1001 call rpn_comm_bcast(kstatus,1,"MPI_INTEGER",0,"GRID",ierr)
*
if(kstatus.ne.0) return
*
* 2. Collect and write all 3D and 2D dynamical fields
* ------------------------------------------------
*
* -----------------------------------------------------------------
* Allocate local 3D and 2D global buffer (one real and one real*8)
* -----------------------------------------------------------------
if(Ptopo_myproc.eq.0) then
*
allocate( zbuff(nigauss,njgauss,G_nk))
allocate(dlbuff_8(nigauss*njgauss,G_nk))
*
allocate( zbuff2d(nigauss,njgauss))
allocate(dlbuff2d_8(nigauss*njgauss))
*
* Zero adjoint variables
* ----------------------
zbuff(:,:,:) = ZERO_8
zbuff2d(:,:) = ZERO_8
*
end if
*
if(plpr_L) then
write(Lun_out,*) 'BEFORE GAUSS2GEM_AD OR GEM2GAUSS'
if(G_lam) then
call glbstat
(ut1 ,'UU',LDIST_DIM,G_nk,1,G_ni-1,1,G_nj, 1,G_nk)
else
call glbstat
(ut1 ,'UU',LDIST_DIM,G_nk,1,G_ni, 1,G_nj, 1,G_nk)
endif
call glbstat
(vt1 ,'VV',LDIST_DIM,G_nk,1,G_ni,1,G_nj-1,1,G_nk)
call glbstat
(tpt1,'TP',LDIST_DIM,G_nk,1,G_ni,1,G_nj, 1,G_nk)
call glbstat
(st1 ,'4S',LDIST_DIM, 1,1,G_ni,1,G_nj, 1, 1)
call glbstat
(hut1,'HU',LDIST_DIM,G_nk,1,G_ni,1,G_nj, 1,G_nk)
write(Lun_out,*) '-----------------------'
endif
*
if(V4dg_di_L.or.V4dg_tl_L) then
* -----------------------------------------------
* Transfert from GEM scalar grid to Gaussian grid
* -----------------------------------------------
call v4d_gem2gauss
( ut1, vt1, tpt1, hut1, st1, LDIST_DIM,
% gut1,gvt1,gtpt1,ghut1,gst1,nigauss,njgauss,G_nk)
*
elseif(V4dg_ad_L) then
* ------------------------------------------------------------
* Adjoint of [Transfert from Gaussian grid to GEM scalar grid]
* ------------------------------------------------------------
call v4d_gauss2gem_ad
( ut1, vt1, tpt1, hut1, st1, LDIST_DIM,
% gut1,gvt1,gtpt1,ghut1,gst1,nigauss,njgauss,G_nk)
*
endif
*
if(Ptopo_myproc.eq.0) then
*
* -----------------------------
* Write all 3D dynamical fields
* -----------------------------
zbuff(:,:,:) = gut1 (:,:,:)
call v4d_putfld
('UU',kstatus)
*
if(kstatus.ne.0) goto 1002
*
zbuff(:,:,:) = gvt1 (:,:,:)
call v4d_putfld
('VV',kstatus)
*
if(kstatus.ne.0) goto 1002
*
zbuff(:,:,:) = gtpt1(:,:,:)
call v4d_putfld
('TT',kstatus)
*
if(kstatus.ne.0) goto 1002
*
zbuff(:,:,:) = ghut1(:,:,:)
call v4d_putfld
('HU',kstatus)
*
if(kstatus.ne.0) goto 1002
*
write(Lun_out,*) 'Write first record with 3D fields...'
*
istat = prof_wrrec(ihdlout)
*
if(istat.ne.0) then
write(Lun_out,*) 'Problem writing first record with 3D fields'
kstatus = -99
goto 1002
endif
*
* -----------------------------
* Write all 2D dynamical fields
* -----------------------------
zbuff2d(:,:) = gst1(:,:)
call v4d_putfld
('PS',kstatus)
*
if(kstatus.ne.0) goto 1002
*
write(Lun_out,*) 'Write second record with 2D fields...'
*
istat = prof_wrrec(ihdlout)
*
if(istat.ne.0) then
write(Lun_out,*) 'Problem writing second record with 2D fields'
kstatus = -99
goto 1002
endif
*
endif
*
1002 call rpn_comm_bcast(kstatus,1,"MPI_INTEGER",0,"GRID",ierr)
*
if(kstatus.ne.0) return
*
* -------------
* Deallocations
* -------------
if(Ptopo_myproc.eq.0) then
*
deallocate(zbuff, dlbuff_8 )
deallocate(zbuff2D,dlbuff2d_8)
*
if(allocated (gut1 )) deallocate(gut1 )
if(allocated (gvt1 )) deallocate(gvt1 )
if(allocated (gtpt1 )) deallocate(gtpt1 )
if(allocated (ghut1 )) deallocate(ghut1 )
if(allocated (gst1 )) deallocate(gst1 )
*
endif
*
pnerr = vmmuld(-1,0)
*
if(Ptopo_myproc.eq.0) then
*
if(V4dg_di_L.or.V4dg_tl_L) then
*
* 3A.Closing dwgf PROF file
* ----------------------
write(Lun_out,*) 'Closing file dwgf PROF file'
*
istat = prof_close(ihdlout)
*
if(istat.ne.0) then
write(Lun_out,*) 'Problem closing file dwgf PROF file'
kstatus = -99
goto 1003
endif
*
elseif(V4dg_ad_L) then
*
* 3B.Closing dwga PROF file
* ----------------------
write(Lun_out,*) 'Closing file dwga PROF file'
*
istat = prof_close(ihdlout)
*
if(istat.ne.0) then
write(Lun_out,*) 'Problem closing file dwga PROF file'
kstatus = -99
goto 1003
endif
*
end if
*
end if
*
1003 call rpn_comm_bcast(kstatus,1,"MPI_INTEGER",0,"GRID",ierr)
*
if(kstatus.ne.0) return
*
write(Lun_out,2001) kstatus
*
2000 format(/,'V4D_PUTDX: Prepare Model state to be sent to 3D-Var ',
+ /,'====================================================')
2001 format(/,'V4D_PUTDX: Model state sent to 3D-Var --- Status = ',I8,
+ /,'===================================================')
*
return
*
* Local Host subroutine
* ---------------------
*
contains
subroutine v4d_putfld(cdvar,kstatus) 10,1
*
implicit none
*
character*2, intent(in) :: cdvar
integer, intent(inout) :: kstatus
*
*author
* P. Gauthier
*
*revision
* v3_00 - P. Gauthier - initial MPI version
* v3_01 - M. Tanguay - introduce gem2gauss for singular vectors
* v3_11 - P. Gauthier - Adjust latitude reversing when V4dg_vstag_L
* v3_30 - Fillion/Tanguay - Allow Limited-Area option
*
*object
*
*arguments
* Name I/O Description
*----------------------------------------------------------------
* cdvar I Type of profile
* kstatus I Status of the job
*----------------------------------------------------------------
*
*implicits
#include "v4dg.cdk"
*
integer njx
*
write(Lun_out,*)' ... collecting variable ',cdvar
*
* Adjoint of
* Change accuracy and reverse latitude if 3D field
* ------------------------------------------------
select case (cdvar)
case('UU','VV','TT','HU')
dlbuff_8(:,:) = 0.
*
if(.not.G_lam) then
njx = njgauss
if(cdvar.eq.'VV'.and.V4dg_vstag_L) njx = njgauss -1
do jlev = 1, G_nk
icount = 0
do jlat = 1,njx
do jlon = 1,nigauss
icount = icount+1
dlbuff_8(icount,jlev) = zbuff(jlon,njx -jlat+1,jlev)
end do
end do
end do
else
njx = njgauss
if(cdvar.eq.'VV'.and.V4dg_vstag_L) njx = njgauss -1
do jlev = 1, G_nk
icount = 0
do jlat = 1,njx
do jlon = 1,nigauss
icount = icount+1
dlbuff_8(icount,jlev) = zbuff(jlon,jlat,jlev)
end do
end do
end do
endif
*
* Adjoint of
* Change accuracy and reverse latitude if 2D field
* ------------------------------------------------
case('PS')
dlbuff2d_8(:) = 0.
if(.not.G_lam) then
icount = 0
do jlat = 1,njgauss
do jlon = 1,nigauss
icount = icount+1
dlbuff2d_8(icount) = zbuff2d(jlon,njgauss -jlat+1)
end do
end do
else
icount = 0
do jlat = 1,njgauss
do jlon = 1,nigauss
icount = icount+1
dlbuff2d_8(icount) = zbuff2d(jlon,jlat)
end do
end do
endif
end select
*
* Store 4D-Var simulation no.
* ---------------------------
istat = prof_pvar(ihdlout,Pr_nsim4d,PRM_EVNT)
*
* Write it in Prof Record
* -----------------------
select case (cdvar)
case('UU')
istat = prof_pvar(ihdlout,dlbuff_8,v3d_utru) + istat
case('VV')
istat = prof_pvar(ihdlout,dlbuff_8,v3d_vtru) + istat
case('TT')
istat = prof_pvar(ihdlout,dlbuff_8,v3d_temp) + istat
case('HU')
istat = prof_pvar(ihdlout,dlbuff_8,v3d_sphu) + istat
case('PS')
istat = prof_pvar(ihdlout,dlbuff2d_8,v2d_psur) + istat
end select
*
kstatus = 0
*
if(istat.ne.0) then
write(Lun_out,*)'Problem in writing ',cdvar
kstatus = -99
return
endif
*
write(Lun_out,*)' Transfer of ',cdvar,' completed ...Status = ',kstatus
*
end subroutine v4d_putfld
end subroutine v4d_putdx