!-------------------------------------- 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 --------------------------------------
!
subroutine getdjdx 1,35
c||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
c----------------------------------------------------------------------
c Author: JF Caron, ARMA / MRD, Decembre 2006
c----------------------------------------------------------------------
c
c Purpose: Get sensitivity gradients (in RPN Standard file format)
c from adjoint model for OSV
c----------------------------------------------------------------------
c Revisions
c Simon Pellerin, mars 2009
c .Lecture des sommes de djdx: retrait de l'argument
c .Changement du nom du fichier a djdx.fst
c .Unite logique de fichier standard dynamique (fnom)
c
*
use modstag
, only: r1qm2_s, lstagwinds
implicit none
*
#include "comlun.cdk"
#include "comdim.cdk"
#include "comgd0.cdk"
#include "pardim.cdk"
#include "comgem.cdk"
#include "comleg.cdk"
#include "comcst.cdk"
*
character(len=1) :: CDTLMADJ
*
* Local variables
*
integer nivmax
parameter (nivmax=500)
integer niv(nivmax)
integer :: jlev,jlat, jlon, jgl, imax, jstag
integer :: ig1gem,ig2gem,ig3gem,ig4gem,iun01
integer :: ig1gauss,ig2gauss,ig3gauss,ig4gauss
integer :: nigem,njgem,nkgem,nigauss,njgauss,njgauss_vv,i,j,k
integer :: dateo,deet,npas,nbits,datyp
integer :: ip1,ip2,ip3,swa,lng,dltf,ubc,ip3grad
integer :: extra1,extra2,extra3
integer :: fnom, fstouv, fclos, fstopc, fstfrm
integer :: dimgrid,fstinf,fstprm,key
integer :: ier, fstlir3d_eta,fstlir,irec,icount
integer :: nrecs
character (len=4) :: nomvar
character (len=1) :: typvar, grtypgem
character (len=12) :: etiket
character (len=128) :: infile
character*8 nul
data nul /" "/
real,allocatable,dimension(:,:,:) :: buf3di, buf3do, buf3do_vv
real,allocatable,dimension(:,:) :: wki, buf2do
c----------------------------------------------------------------------
c Opening RPN STD File
c----------------------------------------------------------------------
write(nulout,*)
write(nulout,*)
write(nulout,*) '////////////////////////////////////////////////'
infile = 'djdx.fst'
write(nulout,*)'GETDJDX: Reading sensitivity vector'
call vflush
(nulout)
iun01 = 0
ier = fnom(iun01, infile, 'RND', 0)
nrecs = fstouv(iun01, 'RND')
c----------------------------------------------------------------------
c Set ip3 value of input gradient
c----------------------------------------------------------------------
ip3grad = 19
c----------------------------------------------------------------------
c Get grid size and level of input data
c----------------------------------------------------------------------
dimgrid = fstinf(iun01,nigem,njgem,k,-1,' ',-1, -1,ip3grad,
$ ' ','TPT1')
if (dimgrid.lt.0) then
call abort3d
(nulout
$ ,'GETDJDX: field TPT1 not found')
endif
call get_niv_eta
(niv, nkgem, dimgrid, iun01)
if (nkgem.ne.nflev) then
call abort3d
(nulout
$ ,'GETDJDX: the number of level for in the input file is not
$ equal to NFLEV')
endif
c----------------------------------------------------------------------
c Destination grid parameters (3DVar Gaussian Grid)
c----------------------------------------------------------------------
nigauss = ni
njgauss = nj
ig1gauss = 0
ig2gauss = 0
ig3gauss = 0
ig4gauss = 0
allocate(buf3do(nigauss,njgauss,nflev))
allocate(buf2do(nigauss,njgauss))
c----------------------------------------------------------------------
c Reading of sensitivity gradients
c----------------------------------------------------------------------
* -----------------------
c < Gradients of U-Wind >
* -----------------------
key = fstinf(iun01,nigem,njgem,k,-1,' ',-1, -1,ip3grad,
$ ' ','UT1')
if (key.lt.0) then
call abort3d
(nulout
$ ,'GETDJDX: field UT1 not found')
endif
allocate(buf3di(nigem,njgem,nflev))
allocate(wki(nigem,njgem))
ier = fstprm(key,dateo,deet,npas,nigem,njgem,k,nbits,datyp,
$ ip1,ip2,ip3,typvar,nomvar,etiket,grtypgem,ig1gem,ig2gem,
$ ig3gem,ig4gem,swa,lng,dltf,ubc,extra1,extra2,extra3)
irec=fstlir3d_eta
(buf3di,wki,iun01,nigem,njgem,nkgem,
$ -1,' ',niv,ip2,ip3grad,nul,'UT1 ')
if (lstagwinds.eqv.(.false.)) then
c 3DVar u-wind grid not staggered
if( (nigem.eq.nigauss).and.(njgem.eq.njgauss).and.
$ (grtypgem.eq.'G').and.(ig1gem.eq.ig1gauss).and.
$ (ig2gem.eq.ig2gauss).and.(ig3gem.eq.ig3gauss).and.
$ (ig4gem.eq.ig4gauss) ) then
write(nulout,*)'--> UT1 is already on 3DVar gauss grid'
write(nulout,*)
call vflush
(nulout)
buf3do(:,:,:) = buf3di(:,:,:)
else
write(nulout,*)'--> UT1 is interpolated on 3DVar gauss grid'
write(nulout,*)
call vflush
(nulout)
call gem2gauss3d
(buf3do,buf3di,nigem,njgem,ig1gem,ig2gem,
$ ig3gem,ig4gem,grtypgem,iun01,nigauss,njgauss,ig1gauss,
$ ig2gauss,ig3gauss,ig4gauss,nflev)
endif
*
else
c 3DVar u-wind grid staggered
if( (nigem-1.eq.nigauss).and.(njgem.eq.njgauss).and.
$ (grtypgem.eq.'Z') ) then
write(nulout,*)'--> UT1 is already on 3DVar stag gauss grid'
write(nulout,*)
call vflush
(nulout)
call chop3d
(buf3do,buf3di,nigem,njgem,nigauss,njgauss,nflev)
else
call abort3d
(nulout
$ ,'GETDJDX: Grid type not supported for UT1')
endif
endif
do jlev = 1, nflev
do jlat = 1, njgauss
do jlon = 1, nigauss
ut0(jlon,jlev,jlat) = buf3do(jlon,njgauss -jlat+1,jlev)
$ * conphy(jlat)
end do
end do
end do
deallocate(buf3di)
deallocate(wki)
* -----------------------
c < Gradients of V-Wind >
* -----------------------
key = fstinf(iun01,nigem,njgem,k,-1,' ',-1, -1,ip3grad,
$ ' ','VT1')
if (key.lt.0) then
call abort3d
(nulout
$ ,'GETDJDX: field VT1 not found')
endif
allocate(buf3di(nigem,njgem,nflev))
allocate(wki(nigem,njgem))
ier = fstprm(key,dateo,deet,npas,nigem,njgem,k,nbits,datyp,
$ ip1,ip2,ip3,typvar,nomvar,etiket,grtypgem,ig1gem,ig2gem,
$ ig3gem,ig4gem,swa,lng,dltf,ubc,extra1,extra2,extra3)
irec=fstlir3d_eta
(buf3di,wki,iun01,nigem,njgem,nkgem,
$ -1,' ',niv,ip2,ip3grad,nul,'VT1 ')
if (lstagwinds.eqv.(.false.)) then
c 3DVar v-wind grid not staggered
njgauss_vv = njgauss
if( (nigem.eq.nigauss).and.(njgem.eq.njgauss).and.
$ (grtypgem.eq.'G').and.(ig1gem.eq.ig1gauss).and.
$ (ig2gem.eq.ig2gauss).and.(ig3gem.eq.ig3gauss).and.
$ (ig4gem.eq.ig4gauss) ) then
write(nulout,*)'--> VT1 is already on 3DVar gauss grid'
write(nulout,*)
call vflush
(nulout)
buf3do(:,:,:) = buf3di(:,:,:)
else
write(nulout,*)'--> VT1 is interpolated on 3DVar gauss grid'
write(nulout,*)
call vflush
(nulout)
call gem2gauss3d
(buf3do,buf3di,nigem,njgem,ig1gem,ig2gem,
$ ig3gem,ig4gem,grtypgem,iun01,nigauss,njgauss,ig1gauss,
$ ig2gauss,ig3gauss,ig4gauss,nflev)
endif
*
else
c 3DVar v-wind grid staggered
njgauss_vv = njgauss-1
allocate(buf3do_vv(nigauss,njgauss_vv,nflev))
if( (nigem-1.eq.nigauss).and.(njgem.eq.njgauss_vv).and.
$ (grtypgem.eq.'Z') ) then
write(nulout,*)'--> VT1 is already on 3DVar stag gauss grid'
write(nulout,*)
call vflush
(nulout)
call chop3d
(buf3do_vv,buf3di,nigem,njgem,nigauss,njgauss_vv
& ,nflev)
else
call abort3d
(nulout
$ ,'GETDJDX: Grid not supported for VT1')
endif
endif
do jlev = 1, nflev
do jlat = 1, njgauss_vv
do jlon = 1, nigauss
if (lstagwinds.eqv.(.false.)) then
vt0(jlon,jlev,jlat) = buf3do(jlon,njgauss_vv -jlat+1,jlev)
$ * conphy(jlat)
else
vt0(jlon,jlev,jlat) = buf3do_vv(jlon,njgauss_vv -jlat+1
& ,jlev)* ra*r1qm2_s(jlat)
endif
end do
end do
end do
if (allocated(buf3do_vv)) deallocate(buf3do_vv)
deallocate(buf3di)
deallocate(wki)
* ----------------------------
c < Gradients of Temperature >
* ----------------------------
key = fstinf(iun01,nigem,njgem,k,-1,' ',-1, -1,ip3grad,
$ ' ','TPT1')
if (key.lt.0) then
call abort3d
(nulout
$ ,'GETDJDX: field TPT1 not found')
endif
allocate(buf3di(nigem,njgem,nflev))
allocate(wki(nigem,njgem))
ier = fstprm(key,dateo,deet,npas,nigem,njgem,k,nbits,datyp,
$ ip1,ip2,ip3,typvar,nomvar,etiket,grtypgem,ig1gem,ig2gem,
$ ig3gem,ig4gem,swa,lng,dltf,ubc,extra1,extra2,extra3)
irec=fstlir3d_eta
(buf3di,wki,iun01,nigem,njgem,nkgem,
$ -1,' ',niv,ip2,ip3grad,nul,'TPT1 ')
if( (nigem.eq.nigauss).and.(njgem.eq.njgauss).and.
$ (grtypgem.eq.'G').and.(ig1gem.eq.ig1gauss).and.
$ (ig2gem.eq.ig2gauss).and.(ig3gem.eq.ig3gauss).and.
$ (ig4gem.eq.ig4gauss) ) then
write(nulout,*)'--> TPT1 is already on 3DVar gauss grid'
write(nulout,*)
call vflush
(nulout)
buf3do(:,:,:) = buf3di(:,:,:)
else
write(nulout,*)'--> TPT1 is interpolated on 3DVar gauss grid'
write(nulout,*)
call vflush
(nulout)
call gem2gauss3d
(buf3do,buf3di,nigem,njgem,ig1gem,ig2gem,
$ ig3gem,ig4gem,grtypgem,iun01,nigauss,njgauss,ig1gauss,
$ ig2gauss,ig3gauss,ig4gauss,nflev)
endif
do jlev = 1, nflev
do jlat = 1, njgauss
do jlon = 1, nigauss
tt0(jlon,jlev,jlat) = buf3do(jlon,njgauss -jlat+1,jlev)
end do
end do
end do
deallocate(buf3di)
deallocate(wki)
* ----------------------------------
c < Gradients of Specific Humidity >
* ----------------------------------
key = fstinf(iun01,nigem,njgem,k,-1,' ',-1, -1,ip3grad,
$ ' ','HUT1')
if (key.lt.0) then
call abort3d
(nulout
$ ,'GETDJDX: field HUT1 not found')
endif
allocate(buf3di(nigem,njgem,nflev))
allocate(wki(nigem,njgem))
ier = fstprm(key,dateo,deet,npas,nigem,njgem,k,nbits,datyp,
$ ip1,ip2,ip3,typvar,nomvar,etiket,grtypgem,ig1gem,ig2gem,
$ ig3gem,ig4gem,swa,lng,dltf,ubc,extra1,extra2,extra3)
irec=fstlir3d_eta
(buf3di,wki,iun01,nigem,njgem,nkgem,
$ -1,' ',niv,ip2,ip3grad,nul,'HUT1 ')
if( (nigem.eq.nigauss).and.(njgem.eq.njgauss).and.
$ (grtypgem.eq.'G').and.(ig1gem.eq.ig1gauss).and.
$ (ig2gem.eq.ig2gauss).and.(ig3gem.eq.ig3gauss).and.
$ (ig4gem.eq.ig4gauss) ) then
write(nulout,*)'--> HUT1 is already on 3DVar gauss grid'
write(nulout,*)
call vflush
(nulout)
buf3do(:,:,:) = buf3di(:,:,:)
else
write(nulout,*)'--> HUT1 is interpolated on 3DVar gauss grid'
write(nulout,*)
call vflush
(nulout)
call gem2gauss3d
(buf3do,buf3di,nigem,njgem,ig1gem,ig2gem,
$ ig3gem,ig4gem,grtypgem,iun01,nigauss,njgauss,ig1gauss,
$ ig2gauss,ig3gauss,ig4gauss,nflev)
endif
do jlev = 1, nflev
do jlat = 1, njgauss
do jlon = 1, nigauss
q0(jlon,jlev,jlat) = buf3do(jlon,njgauss -jlat+1,jlev)
end do
end do
end do
deallocate(buf3di)
deallocate(wki)
deallocate(buf3do)
* ----------------------------------
c < Gradients of Surface pressure >
* ----------------------------------
key = fstinf(iun01,nigem,njgem,k,-1,' ',-1, -1,ip3grad,
$ ' ','ST1')
if (key.lt.0) then
call abort3d
(nulout
$ ,'GETDJDX: field ST1 not found')
endif
allocate(wki(nigem,njgem))
ier = fstprm(key,dateo,deet,npas,nigem,njgem,k,nbits,datyp,
$ ip1,ip2,ip3,typvar,nomvar,etiket,grtypgem,ig1gem,ig2gem,
$ ig3gem,ig4gem,swa,lng,dltf,ubc,extra1,extra2,extra3)
irec=fstlir(wki,iun01,i,j,k,-1,' ',0,ip2,ip3grad,nul,'ST1 ')
if( (nigem.eq.nigauss).and.(njgem.eq.njgauss).and.
$ (grtypgem.eq.'G').and.(ig1gem.eq.ig1gauss).and.
$ (ig2gem.eq.ig2gauss).and.(ig3gem.eq.ig3gauss).and.
$ (ig4gem.eq.ig4gauss) ) then
write(nulout,*)'--> ST1 is already on 3DVar gauss grid'
write(nulout,*)
call vflush
(nulout)
buf2do(:,:) = wki(:,:)
else
write(nulout,*)'--> ST1 is interpolated on 3DVar gauss grid'
write(nulout,*)
call vflush
(nulout)
call gem2gauss2d
(buf2do,wki,nigem,njgem,ig1gem,ig2gem,
$ ig3gem,ig4gem,grtypgem,iun01,nigauss,njgauss,ig1gauss,
$ ig2gauss,ig3gauss,ig4gauss)
endif
do jlat = 1, njgauss
do jlon = 1, nigauss
gps0(jlon,1,jlat) = buf2do(jlon,njgauss -jlat+1)
end do
end do
deallocate(wki)
deallocate(buf2do)
c----------------------------------------------------------------------
c Add adjustment for change of norm as in BILINAD
c----------------------------------------------------------------------
c
do jgl = 1, nj
imax = nilon(jgl)
do jlev = 1, nkgdim
do jlon = 1, imax
gd(jlon,jlev,jgl) = gd(jlon,jlev,jgl) *
$ nilon(jgl) / rwt(jgl)
enddo
enddo
enddo
c----------------------------------------------------------------------
c Closing RPN STD File
c----------------------------------------------------------------------
ier=fstopc('MSGLVL','INFORM',.false.)
ier = fstfrm(iun01)
ier = fclos(iun01)
c call abort3d(nulout,'Modifs OK')
*
end subroutine getdjdx
c######################################################################
c#################### #######################
c#################### Sous-routines locales #######################
c#################### #######################
c######################################################################
*----------------------------------------------------------------------
c GET_NIV_ETA
*----------------------------------------------------------------------
subroutine get_niv_eta(NIV, NK, key, iun) 1,1
implicit none
c ----------------------------------------------------------
c Ecrite par Christian Page -
c version eta par JF Caron -
c Janvier 2004 -
c Departement des Sciences de la Terre et de l'Atmosphere -
c UQAM -
c ----------------------------------------------------------
c ----------------------------------------------------------
c ---------- Definition des vecteurs utilises -----------
c
c niv ---> champ(nk) des niveaux eta encodes (ip1) -
c
c ----------------------------------------------------------
integer nivmax
parameter (nivmax=500)
integer nk, key, iun
integer niv(nivmax)
integer ier
integer dateo,deet,npas,ni,nj,nnk,nbits,datyp
integer ip1,ip2,dumip3,swa,lng,dltf,ubc
integer ig1,ig2,ig3,ig4,extra1,extra2,extra3
integer liste(nivmax),infon
character*4 nomvar
character*1 typvar, grtyp
character*12 etiket
c integer work(1)
c integer ibwork
real,allocatable,dimension(:) :: work
integer fstprm, fstinl
integer i, k, ip1_vco,ipmode,jlev
character(len=1) :: clstring
*
c On recupere l'information des parametres RPN
*
ier = fstprm(key,dateo,deet,npas,ni,nj,nnk,nbits,
$ datyp,ip1,ip2,dumip3,typvar,nomvar,etiket,grtyp,ig1,ig2,
$ ig3,ig4,swa,lng,dltf,ubc,extra1,extra2,extra3)
*
c On definit notre vecteur des niveaux pour le fichier d'entree
*
ier =fstinl(iun, ni, nj, nnk, -1, etiket, -1, ip2, dumip3, typvar,
$ nomvar, liste, infon, NIVMAX)
k = 1
do i=1,infon
ier = fstprm(liste(i),dateo,deet,npas,ni,nj,nnk,nbits,
$ datyp,ip1,ip2,dumip3,typvar,nomvar,etiket,grtyp,ig1,ig2,
$ ig3,ig4,swa,lng,dltf,ubc,extra1,extra2,extra3)
c if(ip1.ge.2000.and.ip1.le.12000.) then
call ins_unique_vect
(niv, ip1, k, NIVMAX)
c endif
enddo
nk = k - 1
if (nk.gt.0) then
c-------- Decode, sort levels from top to bottom
ipmode = -1
allocate(work(nk))
do jlev = 1,nk
call CONVIP(niv(jlev),WORK(jlev),IP1_VCO
& ,ipmode,clstring, .false. )
enddo
c
call sort(work,nk)
c
c---------Encode iip1s_trl to match the sorted zlev
if(niv(1) .le. 32767) then
ipmode = 3
else
ipmode = 2
endif
do jlev = 1,nk
call CONVIP(niv(jlev),work(jlev),ip1_vco
& ,ipmode,clstring, .false. )
enddo
deallocate(work)
else
print*
print*,'Nombre de niveaux egal a zero.'
print*,'Impossible de continuer.'
print*
stop
endif
return
end
*----------------------------------------------------------------------
c GEM2GAUSS3D
*----------------------------------------------------------------------
subroutine gem2gauss3d(bufgauss,bufgem,nigem,njgem,ig1gem,ig2gem, 4,2
$ ig3gem,ig4gem,grtypgem,iun01,nigauss,njgauss,ig1gauss,
$ ig2gauss,ig3gauss,ig4gauss,nk)
implicit none
c ----------------------------------------------------------
c Ecrite par JF Caron -
c Decembre 2006 -
c ARMA / MRD -
c ----------------------------------------------------------
c ----------------------------------------------------------
c ---------- Definition des vecteurs utilises -----------
c
c bufgem ---> champ(ni,nj,nk) d'entree sur grille GEM -
c bufgauss --> champ(ni,nj,nk) de sortie sur grille GAUSS -
c
c ----------------------------------------------------------
integer nigem,njgem,nk,k,nigauss,njgauss
real bufgauss(nigauss,njgauss,nk),bufgem(nigem,njgem,nk)
integer ig1gem,ig2gem,ig3gem,ig4gem,iun01
integer ig1gauss,ig2gauss,ig3gauss,ig4gauss
integer gdgem,gdgauss,iset,ier
integer ezqkdef,ezdefset,ezsint
character*1 grtypgem
real,allocatable,dimension(:,:) :: zgem, zgauss
allocate(zgem(nigem,njgem))
allocate(zgauss(nigauss,njgauss))
gdgem = ezqkdef(nigem,njgem,grtypgem,ig1gem,ig2gem,ig3gem,
$ ig4gem,iun01)
gdgauss = ezqkdef(nigauss,njgauss,'G',ig1gauss,ig2gauss,ig3gauss,
$ ig4gauss,-1)
iset = ezdefset(gdgauss, gdgem)
do k = 1,nk
call vec3d2d
(zgem,bufgem,k,nigem,njgem,nk)
ier = ezsint(zgauss, zgem)
call vec2d3d
(bufgauss,zgauss,k,nigauss,njgauss,nk)
enddo
deallocate(zgem)
deallocate(zgauss)
return
end
*----------------------------------------------------------------------
c GEM2GAUSS2D
*----------------------------------------------------------------------
subroutine gem2gauss2d(bufgauss,bufgem,nigem,njgem,ig1gem,ig2gem, 1
$ ig3gem,ig4gem,grtypgem,iun01,nigauss,njgauss,ig1gauss,
$ ig2gauss,ig3gauss,ig4gauss)
implicit none
c ----------------------------------------------------------
c Ecrite par JF Caron -
c Decembre 2006 -
c ARMA / MRD -
c ----------------------------------------------------------
c ----------------------------------------------------------
c ---------- Definition des vecteurs utilises -----------
c
c bufgem ---> champ(ni,nj) d'entree sur grille GEM -
c bufgauss --> champ(ni,nj) de sortie sur grille GAUSS -
c
c ----------------------------------------------------------
integer nigem,njgem,nigauss,njgauss
real bufgauss(nigauss,njgauss),bufgem(nigem,njgem)
integer ig1gem,ig2gem,ig3gem,ig4gem,iun01
integer ig1gauss,ig2gauss,ig3gauss,ig4gauss
integer gdgem,gdgauss,iset,ier
integer ezqkdef,ezdefset,ezsint
character*1 grtypgem
gdgem = ezqkdef(nigem,njgem,grtypgem,ig1gem,ig2gem,ig3gem,
$ ig4gem,iun01)
gdgauss = ezqkdef(nigauss,njgauss,'G',ig1gauss,ig2gauss,ig3gauss,
$ ig4gauss,-1)
iset = ezdefset(gdgauss, gdgem)
ier = ezsint(bufgauss, bufgem)
return
end
*----------------------------------------------------------------------
c CHOP3D
*----------------------------------------------------------------------
subroutine chop3d(bufgauss,bufgem,nigem,njgem,nigauss,njgauss, 2
$ nflev)
implicit none
c ----------------------------------------------------------
c Ecrite par JF Caron -
c Decembre 2006 -
c ARMA / MRD -
c ----------------------------------------------------------
c ----------------------------------------------------------
c ---------- Definition des vecteurs utilises -----------
c
c bufgem ---> champ(ni,nj,nk) d'entree sur grille -
c GAUSS de GEM -
c bufgauss --> champ(ni-1,nj,nk) de sortie sur grille -
c GAUSS du 3D-Var -
c
c ----------------------------------------------------------
integer nigem,njgem,nigauss,njgauss,i,j,k,nflev
real bufgauss(nigauss,njgauss,nflev)
real bufgem(nigem,njgem,nflev)
do k=1,nflev
do j=1,njgauss
do i=1,nigauss
bufgauss(i,j,k) = bufgem(i,j,k)
enddo
enddo
enddo
return
end
*----------------------------------------------------------------------
c FSTLIR3D_ETA
*----------------------------------------------------------------------
integer function fstlir3d_eta(D,WORK,iun,ni,nj,nk,datev,etiket, 4
$ niv,ip2,ip3,typvar,nomvar)
implicit none
c *****************************
c Auteur : Christian Page
c Departement de physique UQAM
c Juillet 1993
c *****************************
c Sous-routine pour lire un champ en 3 dimensions d'un fichier
c standard
c
c D Vecteur destination 3 dimensions ni x nj x nk
c WORK Vecteur 2 dimensions de travail ni x nj
c iun Unite fortran
c ni, nj, nk 3 dimensions du vecteur destination D
c datev Date de validite du champ. (MMDDYYHHR) DATE TIME
c STAMP CMC sans le premier chiffre
c etiket Etiquette du champ
c niv Vecteurs des niveaux de pression
c ip2 Heure de la prevision (0 a 32767)
c ip3 Descripteur (generalement 1) (0 a 4095)
c typvar Type de champ (1 caractere)
c nomvar Nom du champ (2 caracteres)
integer ni,nj,nk,i,j,k,niv(nk)
integer ip2,ip3,datev,iun,n1,n2,n3
integer irec,fstlir
integer ip1rpn
character*4 nomvar
character*1 typvar
character*(*) etiket
real d(ni,nj,nk),work(ni,nj)
do k=1,nk
irec=fstlir(work,iun,n1,n2,n3,datev,etiket,
$ niv(k), ip2, ip3, typvar,nomvar)
if (irec.lt.0) then
write(*,600) iun, datev, etiket, nomvar, typvar,
$ niv(k), niv(k), ip2, ip3, irec
endif
fstlir3d_eta=irec
do j=1,nj
do i=1,ni
d(i,j,k)=work(i,j)
enddo
enddo
enddo
600 format(' FSTLIR-IUN=',I3,' , PAS TROUVE CHAMP --> DATE=',I10,
$ ' ETIQUETTE=',A8,' NOM=',A2,' TYPE= ',A1,' IP1RPN=',I5,
$ ' IP1=',I5, ' IP2=',I5,
$ ' IP3=',I4,' IREC=',I4)
return
end
*???????????????????????????????????????????????????????????????????????
subroutine vec2d3d (D,s,k,ni,nj,nk) 1
implicit none
c *****************************
c Auteur : Michel Desgagne
c *****************************
*
c Transcrit un vecteur 2d au niveau k d'un vecteur 3d.
*
c D vecteur de destination de dimension ni x nj x nk
c s vecteur source de dimension ni x nj
c k niveau (indice)
*
integer ni,nj,nk,i,j,k
real d(ni,nj,nk),s(ni,nj)
*
do j=1,nj
do i=1,ni
d(i,j,k) = s(i,j)
enddo
enddo
*
return
end
*
*???????????????????????????????????????????????????????????????????????
subroutine vec3d2d (D,s,k,ni,nj,nk) 1
implicit none
c *****************************
c Auteur : Michel Desgagne
c *****************************
*
c Transcrit le niveau k d'un vecteur 3d dans un vecteur 2d.
*
c D vecteur de destination de dimension ni x nj
c s vecteur source de dimension ni x nj x nk
c k niveau (indice)
*
integer ni,nj,nk,i,j,k
real d(ni,nj),s(ni,nj,nk)
*
do j=1,nj
do i=1,ni
d(i,j) = s(i,j,k)
enddo
enddo
*
return
end
*
*??????????????????????????????????????????????????????????????????????
subroutine c_sort(D,work,ni)
implicit none
*
c Tri un vecteur en ordre croissant
*
c D vecteur de source et de destination de dimension ni
c work vecteur de travail de dimension ni
c ni dimension des vecteurs
*
integer i,j,k,l,m,ni
integer D(ni),work(ni),s,t
i = 1
10 k = i
20 j = i
i = i + 1
if ( j .eq. ni ) goto 30
if ( D(i) .ge. D(j) ) goto 20
work(k) = i
goto 10
30 if ( k .eq. 1 ) return
work(k) = ni + 1
40 m = 1
l = 1
50 i = l
if ( i .gt. ni ) goto 120
s = D(i)
j = work(i)
k = j
if ( j .gt. ni ) goto 100
t = D(j)
l = work(j)
D(i) = l
60 if ( s .gt. t ) goto 70
work(m) = s
m = m + 1
i = i + 1
if ( i .eq. k ) goto 80
s = D(i)
goto 60
70 work(m)= t
m = m + 1
j = j + 1
if ( j .eq. l ) goto 110
t = D(j)
goto 60
80 work(m) = t
k = m + l - j
i = j - m
90 m = m + 1
if ( m .eq. k ) goto 50
work(m) = D(m+i)
goto 90
100 D(i) = j
l = j
110 work(m) = s
k = m + k - i
i = i - m
goto 90
120 i = 1
130 k = i
j = D(i)
140 D(i) = work(i)
i = i + 1
if ( i .lt. j ) goto 140
work(k) = i
if ( i .le. ni ) goto 130
if ( k .eq. 1 ) return
goto 40
end
*
*??????????????????????????????????????????????????????????????????????
subroutine ins_unique_vect(S,val,elem,nk) 1
implicit none
c Sous-routine qui insere un element dans un vecteur 1D si cette
c valeur n'existe pas deja : val + vecteur => integer
c s Vecteur source de dimension nk
c val Valeur a inserer si necessaire
c elem Element a remplir
c nk Dimension
*
c *****************************************
c Auteur : Christian Page
c Departement des sciences de la Terre UQAM
c Mars 1996
c *****************************************
*
integer nk,k,elem,trouve
integer s(nk), val
trouve = 0
do k=1,(elem-1)
if (val.eq.s(k)) then
trouve = 1
endif
enddo
if (trouve.eq.0) then
s(elem) = val
elem = elem + 1
endif
return
end
*