!-------------------------------------- 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 geodata - FROM MC2 - read in geophy file created by gengeo
* ?_gfilemap.txt must accompany this ?geophy file
#include "model_macros_f.h"
*
subroutine geodata (dimgx,dimgy,listgeonm) 1,5
implicit none
*
character* (*) listgeonm(2,*)
integer dimgx,dimgy
*
*author M. Desgagne (MC2 2001)
*
*revision
* v3_30 Lee/Desgagne - initial GEM LAM version
* v3_31 Lee V. - to check for rotation of data, search ME or MF in file
*
#include "glb_ld.cdk"
#include "hgc.cdk"
#include "grd.cdk"
#include "ifd.cdk"
#include "ptopo.cdk"
#include "filename.cdk"
#include "schm.cdk"
#include "lun.cdk"
#include "geomg.cdk"
#include "geomn.cdk"
#include "itf_phy_buses.cdk"
#include "itf_phy_config.cdk"
#include "lctl.cdk"
#include "path.cdk"
*
integer fnom,fstouv,fstinf,fstprm,fstluk,fstfrm,fclos,
$ fstopc,nav_3df,fstrhint
external fnom,fstouv,fstinf,fstprm,fstluk,fstfrm,fclos,
$ fstopc,nav_3df,samegrid,fstrhint
*
character*1 typ, grd
character*2 var
character*8 lab, inttyp, h_inttyp, varname
character*8, dimension (:), allocatable :: geop_name
character*512 fn
integer dte, det, ipas, p1, p2, p3, g1, g2, g3, g4, bit,
$ dty, swa, lng, dlf, ubc, ex1, ex2, ex3, longueur,
$ g1o,g2o,g3o,g4o,nvar,errtot,unf,location
logical interpo_L,samegrid
*
integer dgid,ezgdef_fmem,gdll,gdrls,dummy
integer unf2,err,ier,ni1,nj1,nk1,key,ni,nj,n,nia,nja,last,
$ i,j,mgi,z0i,lhi,y7i,y8i,y9i,gai,vgi,vfi,id,gid,ic,
$ lai,loi,mti,nti,mfi,errrot,cnt,offg,mul,i0,j0,in,jn
integer, dimension (:), allocatable :: idxl,idyl,idxn,idyn
real xlat1,xlon1,xlat2,xlon2,epsil,deg2rad
real , dimension (: ) , allocatable :: xps,yps
real*8, dimension (: ) , allocatable :: xpaq,ypaq,
$ cxal,cxbl,cxcl,cxdl,cyal,cybl,cycl,cydl,
$ cxan,cxbn,cxcn,cxdn,cyan,cybn,cycn,cydn
real*8 xpxext(0:dimgx), ypxext(0:dimgy)
data epsil /1.0e-5/
real*8 deg2rad_8,CLXXX_8,ONE_8
parameter ( CLXXX_8 = 180.0d0, ONE_8 = 1.0d0 )
*-----------------------------------------------------------------------
*
nvar = 11
if (P_pbl_schsl_S.eq.'ISBA') nvar = 13
allocate (geop_name(nvar))
*
geop_name (1) = 'MGEN'
geop_name (2) = 'Z0EN'
geop_name (3) = 'LHTGEN'
geop_name (4) = 'DHDXEN'
geop_name (5) = 'DHDYEN'
geop_name (6) = 'DHDXDYEN'
geop_name (7) = 'GLACEN'
geop_name (8) = 'VEGINDEN'
geop_name (9) = 'VEGFEN'
geop_name(10) = 'MF'
geop_name(11) = 'MT'
if (P_pbl_schsl_S.eq.'ISBA') then
geop_name (12) = 'SANDEN'
geop_name (13) = 'CLAYEN'
endif
*
do id =1,nvar
do gid=1,P_bgeo_top
if (listgeonm(1,gid).eq.geop_name(id)) listgeonm(2,gid) = 'NIL'
end do
end do
*
fn = trim(Path_input_S)//'/LAM_geophy/'//trim(prefgeo)
*
unf = 91
open (unf,file=trim(fn)//'_gfilemap.txt',access='SEQUENTIAL',
$ status='OLD',iostat=err,form='FORMATTED')
if (err.ne.0) then
if (Lun_out.gt.0) write (Lun_out,1002) trim(fn)//'_gfilemap.txt'
return
else
if (Lun_out.gt.0) write (Lun_out,1000) trim(fn)//'_gfilemap.txt'
endif
*
deg2rad = acos(-1.0)/180.
inttyp = 'LINEAR'
interpo_L=.true.
if (Ptopo_myproc.ne.0) ier = fstopc('MSGLVL','SYSTEM',.false.)
*
do i=1,dimgx
xpxext(i) = G_xg_8(i)
end do
do i=1,dimgy
ypxext(i) = G_yg_8(i)
end do
xpxext(0) = xpxext(1) - (xpxext(2)-xpxext(1))
ypxext(0) = ypxext(1) - (ypxext(2)-ypxext(1))
*
unf2 = 0
*
errrot = 0
deg2rad_8 = acos( -ONE_8 ) / CLXXX_8
ier = nav_3df
(unf,1.2,deg2rad_8)
call gem_stop
('geodata',ier)
nia = ifd_niaf - ifd_niad + 1
nja = ifd_njaf - ifd_njad + 1
close (unf)
*
do gid=1,P_bgeo_top
if (geonm(gid,1).eq.'MT') geonm(gid,2)='ME '
if (geonm(gid,1).eq.'MF') geonm(gid,2)='MF '
end do
do n=1,ifd_nf
if (ifd_needit(n)) then
ier = fnom (unf2,trim(fn)//'_'//ifd_fnext(n),'RND+OLD+R/O',0)
ier = fstouv (unf2,'RND')
*
* Use first file to establish geo-references
*
allocate ( xpaq(nia), ypaq(nja) )
key = fstinf(unf2,ni1,nj1,nk1,-1,' ',-1,-1,-1,' ','>>')
allocate (xps(ni1))
ier = fstluk ( xps, key, ni,nj1,nk1 )
key = fstinf(unf2,ni1,nj1,nk1,-1,' ',-1,-1,-1,' ','^^')
allocate (yps(nj1))
ier = fstluk ( yps, key, ni1,nj,nk1 )
do i=1,nia
xpaq(i) = xps(ifd_niad+i-1) * deg2rad
end do
do j=1,nja
ypaq(j) = yps(ifd_njad+j-1) * deg2rad
end do
deallocate (xps,yps)
*
call cxgaig ('E',g1o,g2o,g3o,g4o,Grd_xlat1,Grd_xlon1,
$ Grd_xlat2,Grd_xlon2)
ier= fstprm (key, DTE, DET, IPAS, ni1, nj1, nk1, BIT, DTY,
$ P1, P2, P3, TYP, VAR, LAB, GRD, G1, G2, G3, G4,
$ SWA, LNG, DLF, UBC, EX1, EX2, EX3)
if (Lun_debug_L) then
write(Lun_out,*)
$ 'geodata: g1,g2,g3,g4 should be:',g1o,g2o,g3o,g4o
write(Lun_out,*) 'ni1=',ni1,'nj1=',nj1,'p1=',p1,
$ 'p2=',p2,'p3=',p3
endif
if (g1.ne.g1o.or.g2.ne.g2o.or.g3.ne.g3o.or.g4.ne.g4o) then
if (Lun_out.gt.0) then
write(Lun_out,*) 'Grid rotation from',trim(fn),' is not the same as target grid'
write(Lun_out,*)
$ 'geodata: g1,g2,g3,g4',g1,g2,g3,g4, 'should be:',g1o,g2o,g3o,g4o
endif
call gem_stop
('geodata',-1)
else
if (nia.eq.dimgx.and.nja.eq.dimgy) then
interpo_L = samegrid
(unf2,nia,nja,p1,p2,p3,
$ g1o,g2o,g3o,g4o,xpxext(1),ypxext(1))
if (.not.interpo_L) inttyp='NEAREST'
endif
endif
if (Lun_debug_L)
$ write(Lun_out,*)'interpo_L=',interpo_L, 'errtot=',errtot
ier = fstfrm (unf2)
ier = fclos (unf2)
goto 57
endif
enddo
*
57 if ((errrot.lt.0).and.(Ptopo_myproc.eq.0)) write (6,1001)
call gem_stop
('GEODATA',errrot)
* Check tic tacs to see if they are the same
*
allocate (idxl(l_ni), idyl(l_nj), idxn(l_ni), idyn(l_nj))
allocate (cxal(l_ni),cxbl(l_ni),cxcl(l_ni),cxdl(l_ni),
$ cyal(l_nj),cybl(l_nj),cycl(l_nj),cydl(l_nj),
$ cxan(l_ni),cxbn(l_ni),cxcn(l_ni),cxdn(l_ni),
$ cyan(l_nj),cybn(l_nj),cycn(l_nj),cydn(l_nj))
*
* for linear interpolation
*
call grid_to_grid_coef (xpxext(l_i0),l_ni,xpaq,
$ nia,idxl,cxal,cxbl,cxcl,cxdl,inttyp)
call grid_to_grid_coef (ypxext(l_j0),l_nj,ypaq,
$ nja,idyl,cyal,cybl,cycl,cydl,inttyp)
*
i0 = 1
j0 = 1
in = l_ni
jn = l_nj
ni1 = in - i0 + 1
nj1 = jn - j0 + 1
if (Lun_debug_L)
$ write(Lun_out,*)
$ 'geodata: ni1=',ni1,'nj1=',nj1,'l_i0=',l_i0,'l_j0=',l_j0
call grid_to_grid_coef
$ (xpxext(l_i0),ni1,xpaq,nia,idxl,cxal,cxbl,cxcl,cxdl,'LINEAR')
call grid_to_grid_coef
$ (ypxext(l_j0),nj1,ypaq,nja,idyl,cyal,cybl,cycl,cydl,'LINEAR')
call grid_to_grid_coef
$ (xpxext(l_i0),ni1,xpaq,nia,idxn,cxan,cxbn,cxcn,cxdn,'NEAREST')
call grid_to_grid_coef
$ (ypxext(l_j0),nj1,ypaq,nja,idyn,cyan,cybn,cycn,cydn,'NEAREST')
*
do 101 id=1,nvar
location = -1
do gid=1,P_bgeo_top
if (geonm(gid,1).eq.geop_name(id)) location = gid
end do
if (location.lt.0) goto 101
offg = geopar(location,1)
mul = geopar(location,3)
varname = geonm (location,2)
h_inttyp = inttyp
*
if ( (geop_name(id).eq.'VEGINDEN').or.
$ (geop_name(id).eq.'VEGFEN' ) ) h_inttyp = 'NEAREST'
*
err = 0
if (h_inttyp.eq.'LINEAR') then
err = fstrhint (geofld(offg),varname,ni1,nj1,mul,
$ nia,nja,idxl,idyl,cxal,cxbl,cxcl,cxdl,
$ cyal,cybl,cycl,cydl,h_inttyp,fn)
else
err = fstrhint (geofld(offg),varname,ni1,nj1,mul,
$ nia,nja,idxn,idyn,cxan,cxbn,cxcn,cxdn,
$ cyan,cybn,cycn,cydn,h_inttyp,fn)
endif
if (err.eq.0) listgeonm(2,location) = 'OK'
101 continue
*
** Post treatment
*
do gid=1,p_bgeo_top
if (geonm(gid,1).eq.'DLATEN') lai = geopar(gid,1)
if (geonm(gid,1).eq.'DLATEN') listgeonm(2,gid) = 'OK'
if (geonm(gid,1).eq.'DLONEN') loi = geopar(gid,1)
if (geonm(gid,1).eq.'DLONEN') listgeonm(2,gid) = 'OK'
if (geonm(gid,1).eq.'MGEN' ) mgi = geopar(gid,1)
if (geonm(gid,1).eq.'Z0EN' ) z0i = geopar(gid,1)
if (geonm(gid,1).eq.'LHTGEN') lhi = geopar(gid,1)
if (geonm(gid,1).eq.'GLACEN') gai = geopar(gid,1)
if (geonm(gid,1).eq.'MT' ) mti = geopar(gid,1)
if (geonm(gid,1).eq.'MF' ) mfi = geopar(gid,1)
c if (geonm(gid,1).eq.'MF' ) listgeonm(2,gid) = 'OK'
end do
*
call cxgaig ('E',g1,g2,g3,g4,Grd_xlat1,Grd_xlon1,
$ Grd_xlat2,Grd_xlon2)
gid = ezgdef_fmem (ni1,nj1,'Z','E',g1,g2,g3,g4,
$ Geomn_longs(l_i0),Geomn_latgs(l_j0))
err = gdll (gid,geofld(lai),geofld(loi))
err = gdrls (gid)
*
do i=1,ni1*nj1
geofld(mfi +i-1) = max(0.,geofld(mfi+i-1))
geofld(mti +i-1) = geofld(mti+i-1)
geofld(mgi +i-1) = min(max(0.,geofld(mgi +i-1)),1.)
geofld(gai +i-1) = min(max(0.,geofld(gai +i-1)),1.)
geofld(lhi +i-1) = max(0.,geofld(lhi+i-1))
geofld(z0i +i-1) = exp(geofld(z0i+i-1))
geofld(lai +i-1) = geofld(lai +i-1) * deg2rad
geofld(loi +i-1) = geofld(loi +i-1) * deg2rad
end do
*
deallocate (idxl,idyl,cxal,cxbl,cxcl,cxdl,cyal,cybl,cycl,cydl,
$ idxn,idyn,cxan,cxbn,cxcn,cxdn,cyan,cybn,cycn,cydn,
$ xpaq,ypaq,geop_name)
*
if (Ptopo_myproc.ne.0) ier = fstopc('MSGLVL','INFORM',.false.)
*
1000 format (4X,'GEODATA: geophy file description from ',A/)
1001 format (/' INPUT DATA NOT ON SAME GRID ROTATION AS MODEL ',
$ '- ABORT IN geodata -'/)
1002 format (4X,'GEODATA: problem with opening geophy file: ',A/)
*
*-----------------------------------------------------------------------
*
return
end
*
integer function fstrhint (f,nv,ni,nj,nk,nia,nja,idx,idy,cxa,cxb,,2
$ cxc,cxd,cya,cyb,cyc,cyd,inttyp,path)
implicit none
*
character* (*) nv,inttyp,path
integer ni,nj,nk,nia,nja,idx(*),idy(*)
real f(ni*nj,*)
real*8 cxa(*),cxb(*),cxc(*),cxd(*),cya(*),cyb(*),cyc(*),cyd(*)
*
#include "filename.cdk"
#include "ifd.cdk"
*
integer filsfc
external filsfc
integer fnom,fstouv,fstfrm,fclos
character*512 fn
integer k,n,ier,unf,ofi,ofj,i,j
real wk1(nia*nja)
*
*-----------------------------------------------------------------------
*
fstrhint = 0
unf = 0
*
wk1 = 0.
*
do k=1,nk
*
do n=1,ifd_nf
if (ifd_needit(n)) then
fn = trim(path)//'_'//ifd_fnext(n)
ier = fnom (unf,fn,'RND+OLD+R/O',0)
ier = fstouv (unf,'RND')
ofi = ifd_minx(n)-1
ofj = ifd_miny(n)-1
fstrhint = filsfc
(wk1,nv,ifd_niad,ifd_niaf,ifd_njad,ifd_njaf,
$ k,nk,unf,ofi,ofj)
ier = fstfrm (unf)
ier = fclos (unf)
endif
end do
*
call hinterpo
(f(1,k),ni,nj,wk1,nia,nja,1,
$ idx,idy,cxa,cxb,cxc,cxd,cya,cyb,cyc,cyd,inttyp)
*
end do
*
*-----------------------------------------------------------------------
*
return
end
*
integer function filsfc ( f,nv,n1,n2,n3,n4,ki,nk,unf,ofi,ofj ) 1
implicit none
#include "lun.cdk"
*
character* (*) nv
integer n1,n2,n3,n4,ki,nk,unf,ofi,ofj
real f(n1:n2,n3:n4)
*
integer fstinf,fstluk
external fstinf,fstluk
*
character*8 dum
integer key,ni1,nj1,nk1,ip1,ier,i,j
real, dimension (:,:), allocatable :: tr1
*
*-----------------------------------------------------------------------
*
filsfc = -1
*
ip1 = 0
if (nk.gt.1) call convip ( ip1, real(ki), 3, 1, dum, .false.)
if (nv.eq.'ME') then
call convip ( ip1, 0.0,3,1,dum,.false.)
endif
key = fstinf(unf,ni1,nj1,nk1,-1,' ',ip1,-1,-1,' ',nv)
*
if (key.ge.0) then
*
allocate (tr1(ni1,nj1))
ier = fstluk ( tr1, key, ni1,nj1,nk1 )
if (ier.ge.0) then
do j=1,nj1
do i=1,ni1
f(ofi+i,ofj+j) = tr1(i,j)
end do
end do
filsfc = 0
endif
deallocate (tr1)
*
endif
*
*-----------------------------------------------------------------------
*
return
end