Subversion Repositories pvinversion.ecmwf

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

      PROGRAM coastline
      
c     *********************************************************************
c     * Add the coastline and land sea mask to the REF file               *
c     * Michael Sprenger / Winter 2006,07                                 *
c     *********************************************************************

      implicit none

c     --------------------------------------------------------------------
c     Declaration of parameters and variables
c     --------------------------------------------------------------------

c     Input parameters
      character*80 coastfile
      character*80 reffile
      real         clon,clat,crot
      
c     Output arrays
      integer      nmax
      parameter    (nmax=100000)
      real,allocatable, dimension (:,:)   :: landsea
      real,allocatable, dimension (:,:)   :: xcor,ycor
      real         xpos(nmax),ypos(nmax)
      real         lon(nmax), lat(nmax)
      real         rlon(nmax),rlat(nmax)
      integer      ncoast
      integer      rnx,rny
      real         rxmin,rymin,rxmax,rymax
      real         rdx,rdy

c     Auxiliary variables
      integer      i,j
      character*80 name
      integer      cdfid,cstid
      character*80 cfn
      integer      ierr,stat
      character*80 varname
      real         varmin(4),varmax(4),stag(4)
      integer      vardim(4),ndim  
      real         mdv
      integer      isok
      integer      nvars
      integer      ntimes
      real         time
      character*80 vnam(100)

c     --------------------------------------------------------------------
c     Preparations
c     --------------------------------------------------------------------

      print*,'*********************************************************'
      print*,'* coastline                                             *'
      print*,'*********************************************************'


c     Read parameter file
      open(10,file='fort.10')
       read(10,*) reffile
       read(10,*) coastfile
       read(10,*) name,clon
       if ( trim(name).ne.'CLON' ) stop
       read(10,*) name,clat
       if ( trim(name).ne.'CLAT' ) stop      
       read(10,*) name,crot
       if ( trim(name).ne.'CROT' ) stop    
      close(10)

      print*
      print*,trim(reffile)
      print*,trim(coastfile)
      print*,clon,clat,crot

c     Read grid parameters
      call cdfopn(reffile,cdfid,ierr)
      if (ierr.ne.0) goto 998
      call getvars(cdfid,nvars,vnam,ierr)
      if (ierr.ne.0) goto 998     
      varname='X'      
      call getdef(cdfid,varname,ndim,mdv,vardim,
     >            varmin,varmax,stag,ierr)
      if (ierr.ne.0) goto 998
      call gettimes(cdfid,time,ntimes,ierr)
      if (ierr.ne.0) goto 998
      call clscdf(cdfid,ierr)
      rnx=vardim(1)
      rny=vardim(2)
      rxmin=varmin(1)
      rymin=varmin(2)
      rxmax=varmax(1)
      rymax=varmax(2)
      rdx=(rxmax-rxmin)/real(rnx-1)
      rdy=(rymax-rymin)/real(rny-1)

c     Allocate memory
      allocate(landsea(rnx,rny),stat=stat)
      if (stat.ne.0) print*,'*** error allocating array landsea ***'
      allocate(xcor(rnx,rny),stat=stat)
      if (stat.ne.0) print*,'*** error allocating array xcor ***'
      allocate(ycor(rnx,rny),stat=stat)
      if (stat.ne.0) print*,'*** error allocating array ycor ***'

c     Read data
      call cdfopn(reffile,cdfid,ierr)
      if (ierr.ne.0) goto 998
      varname='X'
      call getdat(cdfid,varname,time,1,xcor,ierr)
      if (ierr.ne.0) goto 998
      varname='Y'
      call getdat(cdfid,varname,time,1,ycor,ierr)
      if (ierr.ne.0) goto 998
      call clscdf(cdfid,ierr)

c     Read the coastfile
      open(10,file=coastfile)
      
       ncoast=1
 100   read(10,*,end=200) lon(ncoast),lat(ncoast)
       ncoast=ncoast+1
       goto 100

 200  close(10)
      ncoast=ncoast-1

c     Handle missing data values
      mdv=-100000.
      do i=ncoast,nmax
         lon(i)=mdv
         lat(i)=mdv
      enddo

c     --------------------------------------------------------------------
c     Transform coast(lat/lon) to coast(x/y)
c     --------------------------------------------------------------------
      
      call  getenvir (clon,clat,crot,
     >                xcor,ycor,rnx,rny,rxmin,rymin,rdx,rdy,mdv,
     >                lon,lat,rlon,rlat,xpos,ypos,nmax)

c     --------------------------------------------------------------------
c     Write output 
c     --------------------------------------------------------------------

c     Open output file and set some general parameters
      call cdfwopn(reffile,cdfid,ierr)
      if (ierr.ne.0) goto 998
      vardim(1)=1
      vardim(2)=1
      vardim(3)=nmax
      ndim=3

c     Write LAT
      isok=0
      varname='COAST_LAT'
      call check_varok(isok,varname,vnam,nvars)
      if (isok.eq.0) then
         call putdef(cdfid,varname,ndim,mdv,vardim,
     >               varmin,varmax,stag,ierr)
         if (ierr.ne.0) goto 998
      endif
      call putdat(cdfid,varname,time,0,lat,ierr)
      if (ierr.ne.0) goto 998
      print*,'W ',trim(varname),' ',trim(reffile)

c     Write LON
      isok=0
      varname='COAST_LON'
      call check_varok(isok,varname,vnam,nvars)
      if (isok.eq.0) then
         call putdef(cdfid,varname,ndim,mdv,vardim,
     >               varmin,varmax,stag,ierr)
         if (ierr.ne.0) goto 998
      endif
      call putdat(cdfid,varname,time,0,lon,ierr)
      if (ierr.ne.0) goto 998
      print*,'W ',trim(varname),' ',trim(reffile)

c     Write RLAT
      isok=0
      varname='COAST_RLAT'
      call check_varok(isok,varname,vnam,nvars)
      if (isok.eq.0) then
         call putdef(cdfid,varname,ndim,mdv,vardim,
     >               varmin,varmax,stag,ierr)
         if (ierr.ne.0) goto 998
      endif
      call putdat(cdfid,varname,time,0,rlat,ierr)
      if (ierr.ne.0) goto 998
      print*,'W ',trim(varname),' ',trim(reffile)

c     Write RLON
      isok=0
      varname='COAST_RLON'
      call check_varok(isok,varname,vnam,nvars)
      if (isok.eq.0) then
         call putdef(cdfid,varname,ndim,mdv,vardim,
     >               varmin,varmax,stag,ierr)
         if (ierr.ne.0) goto 998
      endif
      call putdat(cdfid,varname,time,0,rlon,ierr)
      if (ierr.ne.0) goto 998
      print*,'W ',trim(varname),' ',trim(reffile)

c     Write Y
      isok=0
      varname='COAST_Y'
      call check_varok(isok,varname,vnam,nvars)
      if (isok.eq.0) then
         call putdef(cdfid,varname,ndim,mdv,vardim,
     >               varmin,varmax,stag,ierr)
         if (ierr.ne.0) goto 998
      endif
      call putdat(cdfid,varname,time,0,ypos,ierr)
      if (ierr.ne.0) goto 998
      print*,'W ',trim(varname),' ',trim(reffile)

c     Write X
      isok=0
      varname='COAST_X'
      call check_varok(isok,varname,vnam,nvars)
      if (isok.eq.0) then
         call putdef(cdfid,varname,ndim,mdv,vardim,
     >               varmin,varmax,stag,ierr)
         if (ierr.ne.0) goto 998
      endif
      call putdat(cdfid,varname,time,0,xpos,ierr)
      if (ierr.ne.0) goto 998
      print*,'W ',trim(varname),' ',trim(reffile)

c     Close output file
      call clscdf(cdfid,ierr)
      if (ierr.ne.0) goto 998


c     --------------------------------------------------------------------
c     Exception handling
c     --------------------------------------------------------------------
      
      stop

 998  print*,'Problems with input netcdf file'
      stop

      END

      
c     --------------------------------------------------------------------------------
c     Subroutine to get environment of strcof
c     --------------------------------------------------------------------------------

      SUBROUTINE getenvir (clon,clat,rotation,
     >                     xcor,ycor,rnx,rny,rxmin,rymin,rdx,rdy,mdv,
     >                     lon,lat,rlon,rlat,xpos,ypos,n)

c     Rotate from a local quasi-cartesian coordiante system into lat/lon coordinate 
c     system.

      implicit none

c     Declaration of input and output parameters
      integer     n
      real        clon,clat,rotation
      real        lon(n), lat(n)
      real        rlon(n),rlat(n)
      real        xpos(n),ypos(n)
      integer     rnx,rny
      real        xcor(rnx,rny),ycor(rnx,rny)
      real        rxmin,rymin,rdx,rdy
      real        mdv

c     Set numerical and physical constants
      real        g2r
      parameter   (g2r=0.0174533)
      real        pi180
      parameter   (pi180=3.14159265359/180.)
      real        eps
      parameter   (eps=0.0001)

c     Auxiliary variables 
      real         pollon,pollat
      integer      i,j
      real         xind,yind
      real         rindx,rindy
      integer      indx,indy,indr,indu
      real         frac0i,frac0j,frac1i,frac1j
      real         rlon1(n),rlat1(n)

c     Externals
      real     lmtolms,phtophs
      external lmtolms,phtophs

c     First rotation
      pollon=clon-180.
      if (pollon.lt.-180.) pollon=pollon+360.
      pollat=90.-clat
      do i=1,n

         if ( (abs(lon(i)-mdv).gt.eps).and.
     >        (abs(lat(i)-mdv).gt.eps) ) then

c           First rotation
            pollon=clon-180.
            if (pollon.lt.-180.) pollon=pollon+360.
            pollat=90.-clat
            rlon1(i)=lmtolms(lat(i),lon(i),pollat,pollon)
            rlat1(i)=phtophs(lat(i),lon(i),pollat,pollon)            

c           Second coordinate transformation
            pollon=-180.
            pollat=90.+rotation
            rlon(i)=90.+lmtolms(rlat1(i),rlon1(i)-90.,pollat,pollon)
            rlat(i)=phtophs(rlat1(i),rlon1(i)-90.,pollat,pollon)   

c           Get rotated latitude and longitude
 100        if (rlon(i).lt.rxmin) then
               rlon(i)=rlon(i)+360.
               goto 100
            endif
 102        if (rlon(i).gt.(rxmin+real(rnx-1)*rdx)) then
               rlon(i)=rlon(i)-360.
               goto 102
            endif
            if ( (rlon(i).lt.rxmin).or.
     >           (rlon(i).gt.(rxmin+real(rnx-1)*rdx)).or.
     >           (rlat(i).lt.rymin).or.
     >           (rlat(i).gt.(rymin+real(rny-1)*rdy)) ) then
               
               rlon(i)=mdv
               rlat(i)=mdv
            endif

c           Get x and y coordinates
            rindx=(rlon(i)-rxmin)/rdx+1.
            rindy=(rlat(i)-rymin)/rdy+1.
            indx=int(rindx)
            indy=int(rindy)
            if ((indx.gt.1).and.(indx.lt.rnx).and.
     >          (indy.gt.1).and.(indy.lt.rny)) then

               indr=indx+1
               if (indr.gt.rnx) indr=1
               indu=indy+1
               if (indu.gt.rny) indu=rny

               frac0i=rindx-float(indx)
               frac0j=rindy-float(indy)
               frac1i=1.-frac0i
               frac1j=1.-frac0j
               xpos(i) = xcor(indx ,indy) * frac1i * frac1j
     &                 + xcor(indx ,indu) * frac1i * frac0j
     &                 + xcor(indr ,indy) * frac0i * frac1j
     &                 + xcor(indr ,indu) * frac0i * frac0j
               ypos(i) = ycor(indx ,indy) * frac1i * frac1j
     &                 + ycor(indx ,indu) * frac1i * frac0j
     &                 + ycor(indr ,indy) * frac0i * frac1j
     &                 + ycor(indr ,indu) * frac0i * frac0j

            else

               xpos(i)=mdv
               ypos(i)=mdv

            endif

         else
            
            rlon(i)=mdv
            rlat(i)=mdv
            xpos(i)=mdv
            ypos(i)=mdv
            
         endif

      enddo

      END    

      
c     --------------------------------------------------------------------------------
c     Transformation routine: LMSTOLM and PHSTOPH from library gm2em
c     --------------------------------------------------------------------------------

      REAL FUNCTION LMTOLMS (PHI, LAM, POLPHI, POLLAM)
C
C%Z% Modul %M%, V%I% vom %G%, extrahiert am %H%
C
C**** LMTOLMS  -   FC:UMRECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE LAM
C****                 AUF EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS)
C****                 IM ROTIERTEN SYSTEM. DER NORDPOL DES SYSTEMS HAT
C****                 DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
C**   AUFRUF   :   LAM = LMTOLMS (PHI, LAM, POLPHI, POLLAM)
C**   ENTRIES  :   KEINE
C**   ZWECK    :   UMRECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE LAM AUF
C**                EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) IM
C**                ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT
C**                DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
C**   VERSIONS-
C**   DATUM    :   03.05.90
C**
C**   EXTERNALS:   KEINE
C**   EINGABE-
C**   PARAMETER:   PHI    REAL BREITE DES PUNKTES IM GEOGR. SYSTEM
C**                LAM    REAL LAENGE DES PUNKTES IM GEOGR. SYSTEM
C**                POLPHI REAL GEOGR.BREITE DES N-POLS DES ROT. SYSTEMS
C**                POLLAM REAL GEOGR.LAENGE DES N-POLS DES ROT. SYSTEMS
C**   AUSGABE-
C**   PARAMETER:   WAHRE GEOGRAPHISCHE LAENGE ALS WERT DER FUNKTION
C**                ALLE WINKEL IN GRAD (NORDEN>0, OSTEN>0)
C**
C**   COMMON-
C**   BLOECKE  :   KEINE
C**
C**   FEHLERBE-
C**   HANDLUNG :   KEINE
C**   VERFASSER:   G. DE MORSIER
 
      REAL        LAM,PHI,POLPHI,POLLAM
 
      DATA        ZRPI18 , ZPIR18  / 57.2957795 , 0.0174532925 /
 
      ZSINPOL = SIN(ZPIR18*POLPHI)
      ZCOSPOL = COS(ZPIR18*POLPHI)
      ZLAMPOL =     ZPIR18*POLLAM
      ZPHI    =     ZPIR18*PHI
      ZLAM    = LAM
      IF(ZLAM.GT.180.0) ZLAM = ZLAM - 360.0
      ZLAM    = ZPIR18*ZLAM
 
      ZARG1   = - SIN(ZLAM-ZLAMPOL)*COS(ZPHI)
      ZARG2   = - ZSINPOL*COS(ZPHI)*COS(ZLAM-ZLAMPOL)+ZCOSPOL*SIN(ZPHI)
      IF (ABS(ZARG2).LT.1.E-30) THEN
        IF (ABS(ZARG1).LT.1.E-30) THEN
          LMTOLMS =   0.0
        ELSEIF (ZARG1.GT.0.) THEN
              LMTOLMS =  90.0
            ELSE
              LMTOLMS = -90.0
            ENDIF
      ELSE
        LMTOLMS = ZRPI18*ATAN2(ZARG1,ZARG2)
      ENDIF
 
      RETURN
      END


      REAL FUNCTION PHTOPHS (PHI, LAM, POLPHI, POLLAM)
C
C%Z% Modul %M%, V%I% vom %G%, extrahiert am %H%
C
C**** PHTOPHS  -   FC:UMRECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE PHI
C****                 AUF EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS)
C****                 IM ROTIERTEN SYSTEM. DER NORDPOL DES SYSTEMS HAT
C****                 DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
C**   AUFRUF   :   PHI = PHTOPHS (PHI, LAM, POLPHI, POLLAM)
C**   ENTRIES  :   KEINE
C**   ZWECK    :   UMRECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE PHI AUF
C**                EINEM PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) IM
C**                ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT
C**                DIE WAHREN KOORDINATEN (POLPHI, POLLAM)
C**   VERSIONS-
C**   DATUM    :   03.05.90
C**
C**   EXTERNALS:   KEINE
C**   EINGABE-
C**   PARAMETER:   PHI    REAL BREITE DES PUNKTES IM GEOGR. SYSTEM
C**                LAM    REAL LAENGE DES PUNKTES IM GEOGR. SYSTEM
C**                POLPHI REAL GEOGR.BREITE DES N-POLS DES ROT. SYSTEMS
C**                POLLAM REAL GEOGR.LAENGE DES N-POLS DES ROT. SYSTEMS
C**   AUSGABE-
C**   PARAMETER:   ROTIERTE BREITE PHIS ALS WERT DER FUNKTION
C**                ALLE WINKEL IN GRAD (NORDEN>0, OSTEN>0)
C**
C**   COMMON-
C**   BLOECKE  :   KEINE
C**
C**   FEHLERBE-
C**   HANDLUNG :   KEINE
C**   VERFASSER:   G. DE MORSIER
 
      REAL        LAM,PHI,POLPHI,POLLAM
 
      DATA        ZRPI18 , ZPIR18  / 57.2957795 , 0.0174532925 /
 
      ZSINPOL = SIN(ZPIR18*POLPHI)
      ZCOSPOL = COS(ZPIR18*POLPHI)
      ZLAMPOL = ZPIR18*POLLAM
      ZPHI    = ZPIR18*PHI
      ZLAM    = LAM
      IF(ZLAM.GT.180.0) ZLAM = ZLAM - 360.0
      ZLAM    = ZPIR18*ZLAM
      ZARG    = ZCOSPOL*COS(ZPHI)*COS(ZLAM-ZLAMPOL) + ZSINPOL*SIN(ZPHI)
 
      PHTOPHS = ZRPI18*ASIN(ZARG)
 
      RETURN
      END

     
c     ----------------------------------------------------------------
c     Check whether variable is found on netcdf file
c     ----------------------------------------------------------------

      subroutine check_varok (isok,varname,varlist,nvars)

c     Check whether the variable <varname> is in the list <varlist(nvars)>.
c     If this is the case, <isok> is incremented by 1. Otherwise <isok>
c     keeps its value.

      implicit none

c     Declaraion of subroutine parameters
      integer      isok
      integer      nvars
      character*80 varname
      character*80 varlist(nvars)

c     Auxiliary variables
      integer      i

c     Main
      do i=1,nvars
         if (trim(varname).eq.trim(varlist(i))) isok=isok+1
      enddo

      end