| /trunk/lib/libcdfio.f |
|---|
| 0,0 → 1,1648 |
| subroutine clscdf (cdfid, error) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This routine closes an open netCDF file. |
| c Aguments : |
| c cdfid int input the id of the file to be closed. |
| c error int output indicates possible errors found in this |
| c routine. |
| c error = 0 no errors detected. |
| c error = 1 error detected. |
| c History: |
| c Nov. 91 PPM UW Created. |
| c----------------------------------------------------------------------- |
| include "netcdf.inc" |
| c Argument declarations. |
| integer cdfid, error |
| c Local variable declarations. |
| integer ncopts |
| c Get current value of error options. |
| call ncgopt (ncopts) |
| c Make sure netCDF errors do not abort execution. |
| call ncpopt (NCVERBOS) |
| c Close requested file. |
| call ncclos (cdfid, error) |
| c Reset error options. |
| call ncpopt (ncopts) |
| end |
| subroutine cdfwopn(filnam,cdfid,ierr) |
| C------------------------------------------------------------------------ |
| C Opens the NetCDF file 'filnam' and returns its identifier cdfid. |
| C filnam char input name of NetCDF file to open |
| C cdfid int output identifier of NetCDF file |
| C ierr int output error flag |
| C------------------------------------------------------------------------ |
| include 'netcdf.inc' |
| integer cdfid,ierr |
| character*(*) filnam |
| integer strend |
| call ncpopt(NCVERBOS) |
| cdfid=ncopn(filnam(1:strend(filnam)),NCWRITE,ierr) |
| return |
| end |
| subroutine cdfopn(filnam,cdfid,ierr) |
| C------------------------------------------------------------------------ |
| C Opens the NetCDF file 'filnam' and returns its identifier cdfid. |
| C filnam char input name of NetCDF file to open |
| C cdfid int output identifier of NetCDF file |
| C ierr int output error flag |
| C------------------------------------------------------------------------ |
| include 'netcdf.inc' |
| integer cdfid,ierr |
| character*(*) filnam |
| integer strend |
| call ncpopt(NCVERBOS) |
| cdfid=ncopn(filnam(1:strend(filnam)),NCNOWRIT,ierr) |
| return |
| end |
| subroutine crecdf (filnam, cdfid, phymin, phymax, ndim, cfn, |
| & error) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This routine is called to create a netCDF file for use with |
| c the UWGAP plotting package. |
| c Any netCDF file written to must be closed with the call |
| c 'call clscdf(cdfid,error)', where cdfid and error are |
| c as in the argumentlist below. |
| c Arguments: |
| c filnam char input the user-supplied netCDF file name. |
| c cdfid int output the file-identifier |
| c phymin real input the minimum physical dimension of the |
| c entire physical domain along each axis. |
| c phymin is dimensioned (ndim) |
| c phymax real input the maximum physical dimension of the |
| c entire physical domain along each axis. |
| c phymax is dimensioned (ndim) |
| c ndim int input the number of dimensions in the file |
| c (i.e. number of elements in phymin, |
| c phymax) |
| c cfn char input constants file name |
| c ('0' = no constants file). |
| c error int output indicates possible errors found in this |
| c routine. |
| c error = 0 no errors detected. |
| c error = 1 error detected. |
| c History: |
| c Nov. 91 PPM UW Created cr3df. |
| c Jan. 92 CS UW Created crecdf. |
| c----------------------------------------------------------------------- |
| include "netcdf.inc" |
| c Argument declarations. |
| integer MAXDIM |
| parameter (MAXDIM=4) |
| integer ndim, error |
| character *(*) filnam,cfn |
| real phymin(*), phymax(*) |
| c Local variable declarations. |
| character *(20) attnam |
| character *(1) chrid(MAXDIM) |
| integer cdfid, k, ibeg, iend, lenfil, ncopts |
| data chrid/'x','y','z','a'/ |
| c Get current value of error options, and make sure netCDF-errors do |
| c not abort execution |
| call ncgopt (ncopts) |
| call ncpopt(NCVERBOS) |
| c Initially set error to indicate no errors. |
| error = 0 |
| c create the netCDF file |
| cdfid = nccre (trim(filnam), NCCLOB, error) |
| if (error.ne.0) go to 920 |
| c define global attributes |
| do k=1,ndim |
| attnam(1:3)='dom' |
| attnam(4:4)=chrid(k) |
| attnam(5:7)='min' |
| attnam=attnam(1:7) |
| call ncapt(cdfid,NCGLOBAL,attnam,NCFLOAT,1,phymin(k),error) |
| if (error.gt.0) goto 920 |
| attnam(1:3)='dom' |
| attnam(4:4)=chrid(k) |
| attnam(5:7)='max' |
| attnam=attnam(1:7) |
| call ncapt(cdfid,NCGLOBAL,attnam,NCFLOAT,1,phymax(k),error) |
| if (error.gt.0) goto 920 |
| enddo |
| c define constants file name |
| if (cfn.ne.'0') then |
| call ncaptc (cdfid, NCGLOBAL, 'constants_file_name', |
| c & NCCHAR, len_trim(cfn)+1, cfn // char(0) , error) |
| & NCCHAR, len_trim(cfn), cfn , error) |
| if (error.gt.0) goto 920 |
| endif |
| c End variable definitions. |
| call ncendf (cdfid, error) |
| if (error.gt.0) goto 920 |
| c normal exit |
| call ncpopt (ncopts) |
| return |
| c error exit |
| 920 write (6, *) 'ERROR: An error occurred while attempting to ', |
| & 'create the data file in subroutine crecdf.' |
| call ncpopt (ncopts) |
| call ncclos (cdfid, error) |
| end |
| subroutine opncdf(filnam, cdfid, |
| & phymin, phymax, ndim, varnam, nvar, cfn, error) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This routine is called to open a netCDF file for read and write |
| c with the UWGAP plotting package. |
| c Arguments: |
| c filnam char input the user-supplied netCDF file name. |
| c cdfid int output the file-identifier |
| c phymin real output the minimum physical dimension of the |
| c entire physical domain along each axis. |
| c phymin is dimensioned (ndim) |
| c phymax real output the maximum physical dimension of the |
| c entire physical domain along each axis. |
| c phymax is dimensioned (ndim) |
| c ndim int output the number of dimensions in the file |
| c (i.e. number of elements in phymin, |
| c phymax) |
| c varnam char output an array containing the variable names. |
| c varnam is dimensioned (nvar). |
| c nvar int output the number of variables in the file |
| c cfn char output constants file name |
| c ('0'=no constants file). |
| c error int output indicates possible errors found in this |
| c routine. |
| c error = 0 no errors detected. |
| c error = 1 error detected. |
| c History: |
| c Nov. 91 PPM UW Created cr3df. |
| c Jan. 92 CS UW Created opncdf. |
| c----------------------------------------------------------------------- |
| include "netcdf.inc" |
| c Argument declarations. |
| integer MAXDIM |
| parameter (MAXDIM=4) |
| integer ndim, nvar, error |
| character *(*) filnam, varnam(*),cfn |
| real phymin(*), phymax(*) |
| c Local variable declarations. |
| character *(20) attnam,vnam |
| character *(1) chrid(MAXDIM) |
| integer cdfid, i,k |
| integer ncopts, ndims,ngatts,recdim |
| integer nvdims,vartyp,nvatts,vardim(MAXDIM) |
| real attval |
| integer lenstr |
| data chrid/'x','y','z','a'/ |
| data lenstr/80/ |
| c Get current value of error options and make sure netCDF-errors do |
| c not abort execution |
| call ncgopt (ncopts) |
| call ncpopt(NCVERBOS) |
| c Initially set error to indicate no errors. |
| error = 0 |
| c open the netCDF file for write |
| cdfid = ncopn (trim(filnam), NCWRITE, error) |
| if (error.ne.0) then |
| c try to open the netCDF file for read |
| cdfid = ncopn (trim(filnam), NCNOWRIT, error) |
| if (error.ne.0) go to 920 |
| endif |
| c inquire for number of variables |
| call ncinq(cdfid,ndims,nvar,ngatts,recdim,error) |
| if (error.eq.1) goto 920 |
| c read the variables |
| do i=1,nvar |
| call ncvinq(cdfid,i,varnam(i),vartyp,nvdims,vardim, |
| & nvatts,error) |
| if (vartyp.ne.NCFLOAT) error=1 |
| if (error.gt.0) goto 920 |
| enddo |
| c get global attributes |
| k=0 |
| 100 continue |
| k=k+1 |
| attnam(1:3)='dom' |
| attnam(4:4)=chrid(k) |
| attnam(5:7)='min' |
| attnam=attnam(1:7) |
| c switch off error message |
| call ncpopt(0) |
| c check whether dimension k is present |
| call ncagt(cdfid,NCGLOBAL,attnam,attval,error) |
| if (error.gt.0) goto 110 |
| phymin(k)=attval |
| attnam(1:3)='dom' |
| attnam(4:4)=chrid(k) |
| attnam(5:7)='max' |
| attnam=attnam(1:7) |
| call ncagt(cdfid,NCGLOBAL,attnam,attval,error) |
| if (error.gt.0) goto 920 |
| phymax(k)=attval |
| if (k.lt.3) goto 100 |
| k=k+1 |
| c define ndim-parameter |
| 110 continue |
| ndim=k-1 |
| error=0 |
| c switch on error messages |
| call ncpopt(NCVERBOS) |
| c get constants file name |
| c call ncagt(cdfid,NCGLOBAL,'constants_file_name',cfn,error) |
| c ! chrigel |
| call ncagtc(cdfid,NCGLOBAL,'constants_file_name',cfn,lenstr,error) |
| if (error.gt.0) cfn='0' |
| c normal exit |
| call ncpopt (ncopts) |
| return |
| c error exit |
| 920 write (6, *) 'ERROR: An error occurred while attempting to ', |
| & 'read the data file in subroutine opncdf.' |
| call ncclos (cdfid, error) |
| call ncpopt (ncopts) |
| end |
| subroutine readcdf(filnam, cdfid, |
| & phymin, phymax, ndim, varnam, nvar, cfn, error) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This routine is called to open a netCDF file for read |
| c with the UWGAP plotting package. |
| c Arguments: |
| c filnam char input the user-supplied netCDF file name. |
| c cdfid int output the file-identifier |
| c phymin real output the minimum physical dimension of the |
| c entire physical domain along each axis. |
| c phymin is dimensioned (ndim) |
| c phymax real output the maximum physical dimension of the |
| c entire physical domain along each axis. |
| c phymax is dimensioned (ndim) |
| c ndim int output the number of dimensions in the file |
| c (i.e. number of elements in phymin, |
| c phymax) |
| c varnam char output an array containing the variable names. |
| c varnam is dimensioned (nvar). |
| c nvar int output the number of variables in the file |
| c cfn char output constants file name |
| c ('0'=no constants file). |
| c error int output indicates possible errors found in this |
| c routine. |
| c error = 0 no errors detected. |
| c error = 1 error detected. |
| c History: |
| c Nov. 91 PPM UW Created cr3df. |
| c Jan. 92 CS UW Created opncdf. |
| c----------------------------------------------------------------------- |
| include "netcdf.inc" |
| c Argument declarations. |
| integer MAXDIM |
| parameter (MAXDIM=4) |
| integer ndim, nvar, error |
| character *(*) filnam, varnam(*),cfn |
| real phymin(*), phymax(*) |
| c Local variable declarations. |
| character *(20) attnam |
| character *(1) chrid(MAXDIM) |
| integer cdfid, i,k |
| integer ncopts, ndims,ngatts,recdim |
| integer nvdims,vartyp,nvatts,vardim(MAXDIM) |
| real attval |
| integer lenstr |
| data chrid/'x','y','z','a'/ |
| data lenstr/80/ |
| c Get current value of error options. |
| call ncgopt (ncopts) |
| c make sure netCDF-errors do not abort execution |
| call ncpopt(NCVERBOS) |
| c Initially set error to indicate no errors. |
| error = 0 |
| c open the netCDF file for read |
| cdfid = ncopn (trim(filnam), NCNOWRIT, error) |
| if (error.ne.0) go to 920 |
| c inquire for number of variables |
| call ncinq(cdfid,ndims,nvar,ngatts,recdim,error) |
| if (error.eq.1) goto 920 |
| c read the variables |
| do i=1,nvar |
| call ncvinq(cdfid,i,varnam(i),vartyp,nvdims,vardim, |
| & nvatts,error) |
| if (vartyp.ne.NCFLOAT) error=1 |
| c print *,varnam(i),nvdims,nvatts |
| if (error.gt.0) goto 920 |
| enddo |
| c get global attributes |
| k=0 |
| 100 continue |
| k=k+1 |
| attnam(1:3)='dom' |
| attnam(4:4)=chrid(k) |
| attnam(5:7)='min' |
| attnam=attnam(1:7) |
| c switch off error message |
| call ncpopt(0) |
| c check whether dimension k is present |
| call ncagt(cdfid,NCGLOBAL,attnam,attval,error) |
| if (error.gt.0) goto 110 |
| phymin(k)=attval |
| attnam(1:3)='dom' |
| attnam(4:4)=chrid(k) |
| attnam(5:7)='max' |
| attnam=attnam(1:7) |
| call ncagt(cdfid,NCGLOBAL,attnam,attval,error) |
| if (error.gt.0) goto 920 |
| phymax(k)=attval |
| if (k.lt.4) goto 100 |
| k=k+1 |
| c define ndim-parameter |
| 110 continue |
| ndim=k-1 |
| error=0 |
| c switch on error messages |
| call ncpopt(NCVERBOS) |
| c get constants file name |
| c call ncagt(cdfid,NCGLOBAL,'constants_file_name',cfn,error) |
| c ! chrigel |
| call ncagtc(cdfid,NCGLOBAL,'constants_file_name',cfn,lenstr,error) |
| if (error.gt.0) cfn='0' |
| c print *,cfn |
| c normal exit |
| call ncpopt (ncopts) |
| return |
| c error exit |
| 920 write (6, *) 'ERROR: An error occurred while attempting to ', |
| & 'read the data file in subroutine opncdf.' |
| call ncclos (cdfid, error) |
| call ncpopt (ncopts) |
| end |
| subroutine getcdf (cdfid, varnam, ndim, misdat, |
| & vardim, varmin, varmax, stag, dat, error) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This routine is called to get a variable and its attributes |
| c from a netCDF file for use with the UWGAP plotting package. |
| c It is assumed that the data is floating-point data. Prior to |
| c calling this routine, the file must be opened with a call to |
| c opncdf. |
| c Arguments: |
| c cdfid int input file-identifier |
| c (can be obtained by calling routine |
| c opncdf) |
| c varnam char input the user-supplied variable name. |
| c (can be obtained by calling routine |
| c opncdf) |
| c ndim int output the number of dimensions (ndim<=4) |
| c misdat real output missing data value for the variable. |
| c vardim int output the dimensions of the variable. |
| c is dimensioned at least (ndim). |
| c varmin real output the location in physical space of the |
| c origin of each variable. |
| c is dimensioned at least Min(ndim,3). |
| c varmax real output the extent of each variable in physical |
| c space. |
| c is dimensioned at least Min(ndim,3). |
| c stag real output the grid staggering for each variable. |
| c is dimensioned at least Min(ndim,3). |
| c dat real output data-array dimensioned suffiecently |
| c large, at least |
| c vardim(1)* ... vardim(ndim) |
| c error int output indicates possible errors found in this |
| c routine. |
| c error = 0 no errors detected. |
| c error = 1 error detected. |
| c History: |
| c Nov. 91 PPM UW Created cr3df. |
| c Jan. 92 CS UW Created getcdf. |
| c----------------------------------------------------------------------- |
| include "netcdf.inc" |
| c Argument declarations. |
| integer MAXDIM |
| parameter (MAXDIM=4) |
| character *(*) varnam |
| integer vardim(*), ndim, error, cdfid |
| real misdat, stag(*), varmin(*), varmax(*), dat(*) |
| c Local variable declarations. |
| character *(20) dimnam(100),attnam |
| character *(1) chrid(MAXDIM) |
| integer id,i,k,corner(MAXDIM) |
| integer ndims,nvars,ngatts,recdim,dimsiz(100) |
| integer vartyp,nvatts, ncopts |
| data chrid/'x','y','z','a'/ |
| data corner/1,1,1,1/ |
| c Get current value of error options, and make sure netCDF-errors do |
| c not abort execution |
| call ncgopt (ncopts) |
| call ncpopt(NCVERBOS) |
| c Initially set error to indicate no errors. |
| error = 0 |
| c inquire for number of dimensions |
| call ncinq(cdfid,ndims,nvars,ngatts,recdim,error) |
| if (error.eq.1) goto 920 |
| c read dimension-table |
| do i=1,ndims |
| call ncdinq(cdfid,i,dimnam(i),dimsiz(i),error) |
| if (error.gt.0) goto 920 |
| enddo |
| c get id of the variable |
| id=ncvid(cdfid,varnam,error) |
| if (error.eq.1) goto 910 |
| c inquire about variable |
| call ncvinq(cdfid,id,varnam,vartyp,ndim,vardim,nvatts,error) |
| if (vartyp.ne.NCFLOAT) error=1 |
| if (error.gt.0) goto 920 |
| c Make sure ndim <= MAXDIM. |
| if (ndim.gt.MAXDIM) then |
| error = 1 |
| go to 900 |
| endif |
| c get dimensions from dimension-table |
| do k=1,ndim |
| vardim(k)=dimsiz(vardim(k)) |
| enddo |
| c get attributes |
| do k=1,min0(ndim,3) |
| c get staggering |
| attnam(1:1)=chrid(k) |
| attnam(2:5)='stag' |
| attnam=attnam(1:5) |
| call ncagt(cdfid,id,attnam,stag(k),error) |
| if (error.gt.0) goto 920 |
| c get min postion |
| attnam(1:1)=chrid(k) |
| attnam(2:4)='min' |
| attnam=attnam(1:4) |
| call ncagt(cdfid,id,attnam,varmin(k),error) |
| if (error.gt.0) goto 920 |
| c get max position |
| attnam(1:1)=chrid(k) |
| attnam(2:4)='max' |
| attnam=attnam(1:4) |
| call ncagt(cdfid,id,attnam,varmax(k),error) |
| if (error.gt.0) goto 920 |
| enddo |
| c get missing data value |
| call ncagt(cdfid,id,'missing_data',misdat,error) |
| if (error.gt.0) goto 920 |
| c get data |
| call ncvgt(cdfid,id,corner,vardim,dat,error) |
| if (error.gt.0) goto 920 |
| c normal exit |
| call ncpopt (ncopts) |
| return |
| c Error exits. |
| 900 write (6, *) 'ERROR: When calling getcdf, the number of ', |
| & 'variable dimensions must be less or equal 4.' |
| call ncpopt (ncopts) |
| call ncclos (cdfid, error) |
| return |
| 910 write (6, *) 'ERROR: The selected variable could not be found ', |
| & 'in the file by getcdf.' |
| call ncpopt (ncopts) |
| call ncclos (cdfid, error) |
| return |
| 920 write (6, *) 'ERROR: An error occurred while attempting to ', |
| & 'read the data file in subroutine getcdf.' |
| call ncpopt (ncopts) |
| call ncclos (cdfid, error) |
| return |
| end |
| subroutine putcdf (cdfid, varnam, ndim, misdat, |
| & vardim, varmin, varmax, stag, dat, error) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This routine is called to put a variable and its attributes |
| c onto a netCDF file for use with the UWGAP plotting package. |
| c It is assumed that the data is floating-point data. Prior to |
| c calling this routine, the file must be created (crecdf) or |
| c opened (opncdf). |
| c Any netCDF file written to must be closed with the call |
| c call ncclos(cdfid,error), where cdfid and error are |
| c as in the argumentlist below. |
| c Arguments: |
| c cdfid int input file-identifier |
| c (can be obtained by calling routine |
| c opncdf) |
| c varnam char input the user-supplied variable name. |
| c (can be obtained by calling routine |
| c opncdf) |
| c ndim int input the number of dimensions (ndim<=4) |
| c misdat real input missing data value for the variable. |
| c vardim int input the dimensions of the variable. |
| c is dimensioned at least (ndim). |
| c varmin real input the location in physical space of the |
| c origin of each variable. |
| c is dimensioned at least Min(ndim,3). |
| c varmax real input the extent of each variable in physical |
| c space. |
| c is dimensioned at least Min(ndim,3). |
| c stag real input the grid staggering for each variable. |
| c is dimensioned at least Min(ndim,3). |
| c dat real input data-array dimensioned suffiecently |
| c large, at least |
| c vardim(1)* ... vardim(ndim) |
| c error int output indicates possible errors found in this |
| c routine. |
| c error = 0 no errors detected. |
| c error = 1 error detected. |
| c History: |
| c Nov. 91 PPM UW Created cr3df, wr3df. |
| c Jan. 92 CS UW Created putcdf. |
| c----------------------------------------------------------------------- |
| include "netcdf.inc" |
| c Argument declarations. |
| integer MAXDIM |
| parameter (MAXDIM=4) |
| character *(*) varnam |
| integer vardim(*), ndim, error, cdfid |
| real misdat, stag(*), varmin(*), varmax(*), dat(*) |
| c Local variable declarations. |
| character *(20) dimnam,attnam,dimchk |
| character *(1) chrid(MAXDIM) |
| character *(20) dimnams(MAXNCDIM) |
| integer dimvals(MAXNCDIM) |
| integer numdims,numvars,numgats,dimulim |
| integer id,did(MAXDIM),i,k,corner(MAXDIM) |
| integer ncopts |
| integer ibeg,iend |
| data chrid/'x','y','z','t'/ |
| data corner/1,1,1,1/ |
| c Get current value of error options. |
| call ncgopt (ncopts) |
| c make sure netCDF-errors do not abort execution |
| call ncpopt(NCVERBOS) |
| c Initially set error to indicate no errors. |
| error = 0 |
| c Make sure ndim <= MAXDIM. |
| if (ndim.gt.MAXDIM) then |
| error = 1 |
| go to 900 |
| endif |
| c Read existing dimensions-declarations from the file |
| call ncinq(cdfid,numdims,numvars,numgats,dimulim,error) |
| if (error.ne.0) numdims=0 |
| if (numdims.gt.0) then |
| do i=1,numdims |
| call ncdinq(cdfid,i,dimnams(i),dimvals(i),error) |
| c print *,dimnams(i),dimvals(i) |
| enddo |
| endif |
| c put file into define mode |
| call ncredf(cdfid,error) |
| if (error.ne.0) goto 920 |
| c define the dimension |
| do k=1,ndim |
| c define the dimension-name |
| dimnam(1:3)='dim' |
| dimnam(4:4)=chrid(k) |
| dimnam(5:5)='_' |
| dimnam(6:5+len_trim(varnam))=trim(varnam) |
| dimnam=dimnam(1:5+len_trim(varnam)) |
| did(k)=-1 |
| if (numdims.gt.0) then |
| c check if an existing dimension-declaration can be used |
| c instead of defining a nuw dimension |
| do i=1,numdims |
| dimchk=dimnams(i) |
| if ((vardim(k).eq.dimvals(i)).and. |
| & (dimnam(1:4).eq.dimchk(1:4))) then |
| did(k)=i |
| goto 100 |
| endif |
| enddo |
| 100 continue |
| endif |
| if (did(k).lt.0) then |
| c define the dimension |
| did(k)=ncddef(cdfid,dimnam,vardim(k),error) |
| if (error.ne.0) goto 920 |
| endif |
| enddo |
| c define variable |
| id=ncvdef(cdfid,varnam,NCFLOAT,ndim,did,error) |
| if (error.ne.0) goto 920 |
| c define attributes |
| do k=1,min0(ndim,3) |
| c staggering |
| attnam(1:1)=chrid(k) |
| attnam(2:5)='stag' |
| attnam=attnam(1:5) |
| call ncapt(cdfid,id,attnam,NCFLOAT,1,stag(k),error) |
| if (error.gt.0) goto 920 |
| c min postion |
| attnam(1:1)=chrid(k) |
| attnam(2:4)='min' |
| attnam=attnam(1:4) |
| call ncapt(cdfid,id,attnam,NCFLOAT,1,varmin(k),error) |
| if (error.gt.0) goto 920 |
| c max position |
| attnam(1:1)=chrid(k) |
| attnam(2:4)='max' |
| attnam=attnam(1:4) |
| call ncapt(cdfid,id,attnam,NCFLOAT,1,varmax(k),error) |
| if (error.gt.0) goto 920 |
| enddo |
| c define missing data value |
| call ncapt(cdfid,id,'missing_data',NCFLOAT,1,misdat,error) |
| if (error.gt.0) goto 920 |
| c leave define mode |
| call ncendf(cdfid,error) |
| if (error.gt.0) goto 920 |
| c define data |
| call ncvpt(cdfid,id,corner,vardim,dat,error) |
| if (error.gt.0) goto 920 |
| c synchronyse output to disk and exit |
| call ncsnc (cdfid,error) |
| call ncpopt (ncopts) |
| return |
| c Error exits. |
| 900 write (6, *) 'ERROR: When calling putcdf, the number of ', |
| & 'variable dimensions must be less or equal 4.' |
| call ncpopt (ncopts) |
| call ncclos (cdfid, error) |
| return |
| 920 write (6, *) 'ERROR: An error occurred while attempting to ', |
| & 'write the data file in subroutine putcdf.' |
| call ncpopt (ncopts) |
| call ncclos (cdfid, error) |
| return |
| end |
| c |
| c |
| subroutine getdef (cdfid, varnam, ndim, misdat, |
| & vardim, varmin, varmax, stag, error) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This routine is called to get the dimensions and attributes of |
| c a variable from an IVE-NetCDF file for use with the IVE plotting |
| c package. Prior to calling this routine, the file must be opened |
| c with a call to opncdf. |
| c Arguments: |
| c cdfid int input file-identifier |
| c (can be obtained by calling routine |
| c opncdf) |
| c varnam char input the user-supplied variable name. |
| c (can be obtained by calling routine |
| c opncdf) |
| c ndim int output the number of dimensions (ndim<=4) |
| c misdat real output missing data value for the variable. |
| c vardim int output the dimensions of the variable. |
| c Is dimensioned at least (ndim). |
| c varmin real output the location in physical space of the |
| c origin of each variable. |
| c Is dimensioned at least Min(3,ndim). |
| c varmax real output the extend of each variable in physical |
| c space. |
| c Is dimensioned at least Min(3,ndim). |
| c stag real output the grid staggering for each variable. |
| c Is dimensioned at least Min(3,ndim). |
| c error int output indicates possible errors found in this |
| c routine. |
| c error = 0 no errors detected. |
| c error = 1 the variable is not on the file. |
| c error =10 other errors. |
| c History: |
| c Apr. 93 Christoph Schaer (ETHZ) Created. |
| c----------------------------------------------------------------------- |
| include "netcdf.inc" |
| c Argument declarations. |
| integer MAXDIM |
| parameter (MAXDIM=4) |
| character *(*) varnam |
| integer vardim(*), ndim, error, cdfid |
| real misdat, stag(*), varmin(*), varmax(*) |
| c Local variable declarations. |
| character *(20) dimnam(MAXNCDIM),attnam,vnam |
| character *(1) chrid(MAXDIM) |
| integer id,i,k |
| integer ndims,nvars,ngatts,recdim,dimsiz(MAXNCDIM) |
| integer vartyp,nvatts, ncopts |
| data chrid/'x','y','z','t'/ |
| c Get current value of error options. |
| call ncgopt (ncopts) |
| c make sure NetCDF-errors do not abort execution |
| call ncpopt(NCVERBOS) |
| c Initially set error to indicate no errors. |
| error = 0 |
| c inquire for number of dimensions |
| call ncinq(cdfid,ndims,nvars,ngatts,recdim,error) |
| if (error.eq.1) goto 920 |
| c read dimension-table |
| do i=1,ndims |
| call ncdinq(cdfid,i,dimnam(i),dimsiz(i),error) |
| if (error.gt.0) goto 920 |
| enddo |
| c get id of the variable |
| id=ncvid(cdfid,varnam,error) |
| if (error.eq.1) goto 910 |
| c inquire about variable |
| call ncvinq(cdfid,id,vnam,vartyp,ndim,vardim,nvatts,error) |
| if (vartyp.ne.NCFLOAT) error=1 |
| if (error.gt.0) goto 920 |
| c Make sure ndim <= MAXDIM. |
| if (ndim.gt.MAXDIM) then |
| error = 1 |
| go to 900 |
| endif |
| c get dimensions from dimension-table |
| do k=1,ndim |
| vardim(k)=dimsiz(vardim(k)) |
| enddo |
| c get attributes |
| do k=1,min0(3,ndim) |
| c get min postion |
| attnam(1:1)=chrid(k) |
| attnam(2:4)='min' |
| attnam=attnam(1:4) |
| call ncagt(cdfid,id,attnam,varmin(k),error) |
| if (error.gt.0) goto 920 |
| c get max position |
| attnam(1:1)=chrid(k) |
| attnam(2:4)='max' |
| attnam=attnam(1:4) |
| call ncagt(cdfid,id,attnam,varmax(k),error) |
| if (error.gt.0) goto 920 |
| c get staggering |
| attnam(1:1)=chrid(k) |
| attnam(2:5)='stag' |
| attnam=attnam(1:5) |
| call ncagt(cdfid,id,attnam,stag(k),error) |
| if (error.gt.0) goto 920 |
| enddo |
| c get missing data value |
| call ncagt(cdfid,id,'missing_data',misdat,error) |
| if (error.gt.0) goto 920 |
| c normal exit |
| call ncpopt (ncopts) |
| return |
| c Error exits. |
| 900 write (6, *) '*ERROR*: When calling getcdf, the number of ', |
| & 'variable dimensions must be less or equal 4.' |
| call ncpopt (ncopts) |
| call ncclos (cdfid, error) |
| return |
| 910 write (6, *) '*ERROR*: The selected variable could not be found ', |
| & 'in the file by getcdf.' |
| call ncpopt (ncopts) |
| call ncclos (cdfid, error) |
| return |
| 920 write (6, *) '*ERROR*: An error occurred while attempting to ', |
| & 'read the data file in subroutine getcdf.' |
| call ncpopt (ncopts) |
| call ncclos (cdfid, error) |
| end |
| subroutine getdat(cdfid, varnam, time, level, dat, error) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This routine is called to read the data of a variable |
| c from an IVE-NetCDF file for use with the IVE plotting package. |
| c Prior to calling this routine, the file must be opened with |
| c a call to opncdf (for extension) or crecdf (for creation) or |
| c readcdf (for readonly). |
| c Arguments: |
| c cdfid int input file-identifier |
| c (must be obtained by calling routine |
| c opncdf,readcdf or crecdf) |
| c varnam char input the user-supplied variable name (must |
| c previously be defined with a call to |
| c putdef) |
| c time real input the user-supplied time-level of the |
| c data to be read from the file (the time- |
| c levels stored in the file can be obtained |
| c with a call to gettimes). |
| c level int input the horizontal level(s) to be read |
| c to the NetCDF file. Suppose that the |
| c variable is defined as (nx,ny,nz,nt). |
| c level>0: the call reads the subdomain |
| c (1:nx,1:ny,level,itimes) |
| c level=0: the call reads the subdomain |
| c (1:nx,1:ny,1:nz,itimes) |
| c Here itimes is the time-index corresponding |
| c to the value of 'time'. |
| c dat real output data-array dimensioned sufficiently |
| c large. The dimensions (nx,ny,nz) |
| c of the variable must previously be defined |
| c with a call to putdef. No previous |
| c definition of the time-dimension is |
| c required. |
| c error int output indicates possible errors found in this |
| c routine. |
| c error = 0 no errors detected. |
| c error = 1 the variable is not present on |
| c the file. |
| c error = 2 the value of 'time' is not |
| c known.to the file. |
| c error = 3 inconsistent value of level |
| c error =10 another error. |
| c History: |
| c March 93 Heini Wernli (ETHZ) Created wr2cdf. |
| c April 93 Bettina Messmer (ETHZ) Created putdat. |
| c June 93 Christoph Schaer (ETHZ) Created getdat |
| c----------------------------------------------------------------------- |
| include "netcdf.inc" |
| C Declaration of local variables |
| character*(*) varnam |
| character*(20) chars |
| integer cdfid |
| real dat(*) |
| real misdat,varmin(4),varmax(4),stag(4) |
| real time, timeval |
| integer corner(4),edgeln(4),didtim,vardim(4),ndims |
| integer error, ierr |
| integer level,ntime |
| integer idtime,idvar,iflag |
| integer i |
| call ncpopt(NCVERBOS) |
| c access the variable |
| call getdef (cdfid, trim(varnam), ndims, misdat, |
| & vardim, varmin, varmax, stag, ierr) |
| if (ierr.ne.0) then |
| print *,'*ERROR* in getdef in getdat' |
| error=1 |
| return |
| endif |
| idvar=ncvid(cdfid,trim(varnam),ierr) |
| if (ierr.ne.0) then |
| print *,'*ERROR* in ncvid in getdat' |
| error=1 |
| return |
| endif |
| C Get times-array |
| didtim=ncdid(cdfid,'time',ierr) |
| if (ierr.ne.0) then |
| print *,'*ERROR* didtim in getdat' |
| error=10 |
| return |
| endif |
| call ncdinq(cdfid,didtim,chars,ntime,ierr) |
| if (ierr.ne.0) then |
| print *,'*ERROR* in ncdinq in getdat' |
| error=10 |
| return |
| endif |
| idtime=ncvid(cdfid,'time',ierr) |
| if (ierr.ne.0) then |
| print *,'*ERROR* in ncvid for time in getdat' |
| error=10 |
| return |
| endif |
| c find appropriate time-index |
| iflag=0 |
| do i=1,ntime |
| call ncvgt1(cdfid,idtime,i,timeval,ierr) |
| if (ierr.ne.0) print *,'*ERROR* in ncvgt1 in getdat' |
| if (time.eq.timeval) iflag=i |
| enddo |
| if (iflag.eq.0) then |
| error=2 |
| print *,'Error: Unknown time in getdat' |
| return |
| endif |
| C Define data volume to be written (index space) |
| corner(1)=1 |
| corner(2)=1 |
| edgeln(1)=vardim(1) |
| edgeln(2)=vardim(2) |
| if (level.eq.0) then |
| corner(3)=1 |
| edgeln(3)=vardim(3) |
| else if ((level.le.vardim(3)).and.(level.ge.1)) then |
| corner(3)=level |
| edgeln(3)=1 |
| else |
| error=3 |
| return |
| endif |
| corner(4)=iflag |
| edgeln(4)=1 |
| C Read data from NetCDF file |
| c print *,'getdat vor Aufruf ncvgt' |
| c print *,'cdfid ',cdfid |
| c print *,'idvar ',idvar |
| c print *,'corner ',corner |
| c print *,'edgeln ',edgeln |
| call ncvgt(cdfid,idvar,corner,edgeln,dat,error) |
| if (error.ne.0) then |
| print *, '*ERROR* in ncvgt in getdat' |
| error=10 |
| endif |
| end |
| subroutine putdat(cdfid, varnam, time, level, dat, error) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This routine is called to write the data of a variable |
| c to an IVE-NetCDF file for use with the IVE plotting package. |
| c Prior to calling this routine, the file must be opened with |
| c a call to opncdf (for extension) or crecdf (for creation), the |
| c variable must be defined with a call to putdef. |
| c Arguments: |
| c cdfid int input file-identifier |
| c (must be obtained by calling routine |
| c opncdf or crecdf) |
| c varnam char input the user-supplied variable name (must |
| c previously be defined with a call to |
| c putdef) |
| c time real input the user-supplied time-level of the |
| c data to be written to the file (the time- |
| c levels stored in the file can be obtained |
| c with a call to gettimes). If 'time' is not |
| c yet known to the file, a knew time-level is |
| c allocated and appended to the times-array. |
| c level int input the horizontal level(s) to be written |
| c to the NetCDF file. Suppose that the |
| c variable is defined as (nx,ny,nz,nt). |
| c level>0: the call writes the subdomain |
| c (1:nx,1:ny,level,itimes) |
| c level=0: the call writes the subdomain |
| c (1:nx,1:ny,1:nz,itimes) |
| c Here itimes is the time-index corresponding |
| c to the value of 'time'. |
| c dat real output data-array dimensioned sufficiently |
| c large. The dimensions (nx,ny,nz) |
| c of the variable must previously be defined |
| c with a call to putdef. No previous |
| c definition of the time-dimension is |
| c required. |
| c error int output indicates possible errors found in this |
| c routine. |
| c error = 0 no errors detected. |
| c error = 1 the variable is not present on |
| c the file. |
| c error = 2 the value of 'time' is new, but |
| c appending it would yield a non |
| c ascending times-array. |
| c error = 3 inconsistent value of level |
| c error =10 another error. |
| c History: |
| c March 93 Heini Wernli (ETHZ) Created wr2cdf. |
| c April 93 Bettina Messmer (ETHZ) Created putdat. |
| c----------------------------------------------------------------------- |
| include "netcdf.inc" |
| C Declaration of local variables |
| character*(*) varnam |
| character*(20) chars |
| integer cdfid |
| real dat(*) |
| real misdat,varmin(4),varmax(4),stag(4) |
| real time, timeval |
| data stag/0.,0.,0.,0./ |
| integer corner(4),edgeln(4),did(4),vardim(4),ndims |
| integer error, ierr |
| integer level,ntime |
| integer idtime,idvar,iflag |
| integer i |
| call ncpopt(NCVERBOS) |
| c get definitions of data |
| call getdef (cdfid, trim(varnam), ndims, misdat, |
| & vardim, varmin, varmax, stag, ierr) |
| if (ierr.ne.0) print *,'*ERROR* in getdef in putdat' |
| c get id of variable |
| idvar=ncvid(cdfid,trim(varnam),ierr) |
| if (ierr.ne.0) print *,'*ERROR* in ncvid in putdat' |
| c get times-array |
| did(4)=ncdid(cdfid,'time',ierr) |
| if (ierr.ne.0) print *,'*ERROR* did(4) in putdat' |
| call ncdinq(cdfid,did(4),chars,ntime,ierr) |
| if (ierr.ne.0) print *,'*ERROR* in ncdinq in putdat' |
| idtime=ncvid(cdfid,'time',ierr) |
| if (ierr.ne.0) print *,'*ERROR* in ncvid in putdat' |
| C Check if a new time step is starting |
| iflag=0 |
| do i=1,ntime |
| call ncvgt1(cdfid,idtime,i,timeval,ierr) |
| if (ierr.ne.0) print *,'*ERROR* in ncvgt1 in putdat' |
| if (time.eq.timeval) iflag=i |
| enddo |
| if (iflag.eq.0) then ! new time step |
| ntime=ntime+1 |
| iflag=ntime |
| idtime=ncvid(cdfid,'time',ierr) |
| if (ierr.ne.0) print *, '*ERROR* in ncvid in putdat' |
| call ncvpt1(cdfid,idtime,ntime,time,ierr) |
| if (ierr.ne.0) print *, '*ERROR* in ncvpt1 in putdat' |
| endif |
| C Define data volume to write on the NetCDF file in index space |
| corner(1)=1 ! starting corner of data volume |
| corner(2)=1 |
| edgeln(1)=vardim(1) ! edge lengthes of data volume |
| edgeln(2)=vardim(2) |
| if (level.eq.0) then |
| corner(3)=1 |
| edgeln(3)=vardim(3) |
| else |
| corner(3)=level |
| edgeln(3)=1 |
| endif |
| corner(4)=iflag |
| edgeln(4)=1 |
| C Put data on NetCDF file |
| c print *,'vor Aufruf ncvpt d.h. Daten schreiben in putdat ' |
| c print *,'cdfid ',cdfid |
| c print *,'idvar ',idvar |
| c print *,'corner ',corner |
| c print *,'edgeln ',edgeln |
| call ncvpt(cdfid,idvar,corner,edgeln,dat,error) |
| if (error.ne.0) then |
| print *, '*ERROR* in ncvpt in putdat - Put data on NetCDF file' |
| endif |
| C Synchronize output to disk and close the files |
| call ncsnc(cdfid,ierr) |
| if (ierr.ne.0) print *, '*ERROR* in ncsnc in putdat' |
| end |
| subroutine putdef (cdfid, varnam, ndim, misdat, |
| & vardim, varmin, varmax, stag, error) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This routine is called to define the dimensions and the |
| c attributes of a variable on an IVE-NetCDF file for use with the |
| c IVE plotting package. Prior to calling this routine, the file must |
| c be opened with a call to opncdf (extend an existing file) or |
| c crecdf (create a new file). |
| c Arguments: |
| c cdfid int input file-identifier |
| c (can be obtained by calling routine |
| c opncdf) |
| c varnam char input the user-supplied variable name. |
| c ndim int input the number of dimensions (ndim<=4). |
| c Upon ndim=4, the fourth dimension of the |
| c variable is specified as 'unlimited' |
| c on the file (time-dimension). It can |
| c later be extended to arbitrary length. |
| c misdat real input missing data value for the variable. |
| c vardim int input the dimensions of the variable. |
| c Is dimensioned at least Min(3,ndim). |
| c varmin real input the location in physical space of the |
| c origin of each variable. |
| c Is dimensioned at least Min(3,ndim). |
| c varmax real input the extent of each variable in physical |
| c space. |
| c Is dimensioned at least Min(ndim). |
| c stag real input the grid staggering for each variable. |
| c Is dimensioned at least Min(3,ndim). |
| c error int output indicates possible errors found in this |
| c routine. |
| c error = 0 no errors detected. |
| c error =10 other errors detected. |
| c History: |
| c Apr. 93 Christoph Schaer (ETHZ) Created. |
| c----------------------------------------------------------------------- |
| include "netcdf.inc" |
| c Argument declarations. |
| integer MAXDIM |
| parameter (MAXDIM=4) |
| character *(*) varnam |
| integer vardim(*), ndim, error, cdfid |
| real misdat, stag(*), varmin(*), varmax(*) |
| c Local variable declarations. |
| character *(20) dimnam,attnam,dimchk |
| character *(1) chrid(MAXDIM) |
| character *(20) dimnams(MAXNCDIM) |
| integer dimvals(MAXNCDIM) |
| integer numdims,numvars,numgats,dimulim |
| integer id,did(MAXDIM),idtime,i,k,ierr |
| integer ncopts |
| integer ibeg,iend |
| data chrid/'x','y','z','t'/ |
| c Get current value of error options. |
| call ncgopt (ncopts) |
| c make sure NetCDF-errors do not abort execution |
| call ncpopt(NCVERBOS) |
| c Initially set error to indicate no errors. |
| error = 0 |
| c Make sure ndim <= MAXDIM. |
| if (ndim.gt.MAXDIM) then |
| error = 10 |
| go to 900 |
| endif |
| c Read existing dimensions-declarations from the file |
| call ncinq(cdfid,numdims,numvars,numgats,dimulim,error) |
| if (numdims.gt.0) then |
| do i=1,numdims |
| call ncdinq(cdfid,i,dimnams(i),dimvals(i),error) |
| c print *,dimnams(i),dimvals(i) |
| enddo |
| endif |
| c put file into define mode |
| call ncredf(cdfid,error) |
| if (error.ne.0) goto 920 |
| c define spatial dimensions |
| do k=1,min0(3,ndim) |
| c define the default dimension-name |
| dimnam(1:3)='dim' |
| dimnam(4:4)=chrid(k) |
| dimnam(5:5)='_' |
| dimnam(6:5+len_trim(varnam))=trim(varnam) |
| dimnam=dimnam(1:5+len_trim(varnam)) |
| did(k)=-1 |
| if (numdims.gt.0) then |
| c check if an existing dimension-declaration can be used |
| c instead of defining a new dimension |
| do i=1,numdims |
| dimchk=dimnams(i) |
| if ((vardim(k).eq.dimvals(i)).and. |
| & (dimnam(1:4).eq.dimchk(1:4))) then |
| did(k)=i |
| goto 100 |
| endif |
| enddo |
| 100 continue |
| endif |
| if (did(k).lt.0) then |
| c define the dimension |
| did(k)=ncddef(cdfid,dimnam,vardim(k),error) |
| if (error.ne.0) goto 920 |
| endif |
| enddo |
| c define the times-array |
| if (ndim.eq.4) then |
| c define dimension and variable 'time' |
| if (numdims.ge.4) then |
| did(4)=ncdid(cdfid,'time',ierr) |
| idtime=ncvid(cdfid,'time',ierr) |
| else |
| c this dimension must first be defined |
| did(4) = ncddef (cdfid,'time',NCUNLIM,ierr) |
| idtime = ncvdef (cdfid,'time',NCFLOAT,1,did(4),ierr) |
| endif |
| endif |
| c define variable |
| id=ncvdef(cdfid,varnam,NCFLOAT,ndim,did,error) |
| if (error.ne.0) goto 920 |
| c define attributes |
| do k=1,min0(ndim,3) |
| c min postion |
| attnam(1:1)=chrid(k) |
| attnam(2:4)='min' |
| attnam=attnam(1:4) |
| call ncapt(cdfid,id,attnam,NCFLOAT,1,varmin(k),error) |
| if (error.gt.0) goto 920 |
| c max position |
| attnam(1:1)=chrid(k) |
| attnam(2:4)='max' |
| attnam=attnam(1:4) |
| call ncapt(cdfid,id,attnam,NCFLOAT,1,varmax(k),error) |
| if (error.gt.0) goto 920 |
| c staggering |
| attnam(1:1)=chrid(k) |
| attnam(2:5)='stag' |
| attnam=attnam(1:5) |
| call ncapt(cdfid,id,attnam,NCFLOAT,1,stag(k),error) |
| if (error.gt.0) goto 920 |
| enddo |
| c define missing data value |
| call ncapt(cdfid,id,'missing_data',NCFLOAT,1,misdat,error) |
| if (error.gt.0) goto 920 |
| c leave define mode |
| call ncendf(cdfid,error) |
| if (error.gt.0) goto 920 |
| c synchronyse output to disk and exit |
| call ncsnc (cdfid,error) |
| call ncpopt (ncopts) |
| return |
| c Error exits. |
| 900 write (6, *) '*ERROR*: When calling putcdf, the number of ', |
| & 'variable dimensions must be less or equal 4.' |
| call ncpopt (ncopts) |
| call ncclos (cdfid, error) |
| return |
| 920 write (6, *) '*ERROR*: An error occurred while attempting to ', |
| & 'write the data file in subroutine putcdf.' |
| call ncpopt (ncopts) |
| call ncclos (cdfid, error) |
| return |
| end |
| subroutine gettimes(cdfid,times,ntimes,ierr) |
| C------------------------------------------------------------------------ |
| C Purpose: |
| C Get all times on the specified NetCDF file |
| C Arguments: |
| C cdfid int input identifier for NetCDF file |
| C times real output array contains all time values on the file, |
| C dimensioned at least times(ntimes) |
| C ntimes int output number of times on the file |
| C error int output errorflag |
| C History: |
| C Heini Wernli, ETHZ |
| C------------------------------------------------------------------------ |
| include "netcdf.inc" |
| integer ierr,i |
| real times(*) |
| integer didtim,ntimes |
| integer cdfid,idtime |
| integer ncopts |
| character*(20) dimnam |
| c Get current value of error options, and make sure netCDF-errors do |
| c not abort execution |
| call ncgopt (ncopts) |
| call ncpopt(NCVERBOS) |
| didtim=ncdid(cdfid,'time',ierr) ! inquire id for time dimension |
| if (ierr.ne.0) goto 900 |
| idtime=ncvid(cdfid,'time',ierr) ! inquire id for time array |
| if (ierr.ne.0) goto 900 |
| call ncdinq(cdfid,didtim,dimnam,ntimes,ierr) ! inquire # of times |
| if (ierr.ne.0) goto 900 |
| do 10 i=1,ntimes |
| call ncvgt1(cdfid,idtime,i,times(i),ierr) ! get times |
| if (ierr.ne.0) goto 900 |
| 10 continue |
| c normal exit |
| call ncpopt (ncopts) |
| return |
| c error exit |
| 900 ntimes=1 |
| times(1)=0. |
| call ncpopt (ncopts) |
| end |
| subroutine puttimes(cdfid,times,ntimes,ierr) |
| C------------------------------------------------------------------------ |
| C Purpose: |
| C Get all times on the specified NetCDF file |
| C Arguments: |
| C cdfid int input identifier for NetCDF file |
| C times real input array contains all time values on the file, |
| C dimensioned at least times(ntimes) |
| C ntimes int input number of times on the file |
| C error int output errorflag |
| C History: |
| C Heini Wernli, ETHZ |
| C Christoph Schaer, ETHZ |
| C Note: |
| C This preliminary version does not define the times-array, but only |
| C overwrites or extends an existing times-array. |
| C------------------------------------------------------------------------ |
| integer ierr,i |
| real times(*) |
| integer didtim,ntimes |
| integer cdfid,idtime,nfiltim |
| integer ncdid,ncvid |
| idtime=ncvid(cdfid,'time',ierr) ! inquire id for time array |
| if (ierr.ne.0) return |
| didtim=ncdid(cdfid,'time',ierr) ! inquire id for time dimension |
| if (ierr.ne.0) return |
| call ncdinq(cdfid,didtim,'time',nfiltim,ierr) ! inquire # of times |
| if (ierr.ne.0) return |
| if (nfiltim.lt.ntimes) then |
| print *,'Warning: puttimes is extending times-array' |
| else if (nfiltim.gt.ntimes) then |
| print *,'Warning: puttimes does not cover range of times-array' |
| endif |
| do 10 i=1,ntimes |
| call ncvpt1(cdfid,idtime,i,times(i),ierr) |
| if (ierr.ne.0) return |
| 10 continue |
| end |
| subroutine cpp_crecdf(filnam,filnam_len,cdfid,phymin,phymax,ndim, |
| & cfn,cfn_len,error) |
| C------------------------------------------------------------------------ |
| C Purpose: |
| C allows to call crecdf from c++ |
| C Arguments: |
| C see crecdf |
| C additionally: fname_len and cfn_len, the length of the |
| C strings |
| C |
| C |
| C History: |
| C 981221 Mark A. Liniger ETHZ |
| C |
| C Note: |
| C |
| C |
| C------------------------------------------------------------------------ |
| integer filnam_len,ndim,cfn_len,error,cdfid |
| character *(*) filnam,cfn |
| real phymin(*),phymax(*) |
| call crecdf (filnam(1:filnam_len),cdfid,phymin,phymax,ndim, |
| & cfn(1:cfn_len),error) |
| end |
| subroutine cpp_putdef(cdfid,varnam,varnam_len,ndim,misdat, |
| & vardim,varmin,varmax,stag,error) |
| C------------------------------------------------------------------------ |
| C Purpose: |
| C allows to call putdef from c++ |
| C Arguments: |
| C see crecdf |
| C additionally: varnam_len, the length of the |
| C strings |
| C |
| C |
| C History: |
| C 981221 Mark A. Liniger ETHZ |
| C |
| C Note: |
| C |
| C |
| C------------------------------------------------------------------------ |
| integer varnam_len,ndim,error,vardim(*),cdfid |
| character *(*) varnam |
| real misdat,stag(*),varmin(*),varmax(*) |
| call putdef (cdfid, varnam(1:varnam_len), ndim, misdat, |
| & vardim, varmin, varmax, stag, error) |
| end |
| subroutine cpp_putdat(cdfid, varnam,varnam_len, |
| & time, level, dat, error) |
| C------------------------------------------------------------------------ |
| C Purpose: |
| C allows to call putdef from c++ |
| C Arguments: |
| C see crecdf |
| C additionally: varnam_len, the length of the |
| C strings |
| C |
| C |
| C History: |
| C 981221 Mark A. Liniger ETHZ |
| C |
| C Note: |
| C |
| C |
| C------------------------------------------------------------------------ |
| integer varnam_len,cdfid,error,level |
| character *(*) varnam |
| real dat(*) |
| real time |
| call putdat(cdfid, varnam(1:varnam_len), time, level, dat, error) |
| end |
| FUNCTION strbeg (string) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This function returns the position of the first nonblank |
| c character in the input string. Returns 0 if the entire |
| c string is blank. |
| c Arguments: |
| c string char input string to be examined. |
| c History: |
| c----------------------------------------------------------------------- |
| IMPLICIT NONE |
| c Function declaration |
| INTEGER strbeg |
| c Argument declarations |
| CHARACTER*(*) string |
| c Local variable declarations. |
| INTEGER i |
| c External function declarations. |
| INTEGER len |
| DO i = 1, len(string) |
| strbeg = i |
| IF (string(i:i) .NE. ' ' .AND. string(i:i) .NE. char(0)) THEN |
| RETURN |
| ENDIF |
| ENDDO |
| strbeg = 0 |
| END |
| FUNCTION strend (string) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This function returns the position of the last nonblank |
| c character in the input string. Returns 0 if the entire |
| c string is blank. |
| c Arguments: |
| c string char input string to be examined. |
| c History: |
| c----------------------------------------------------------------------- |
| IMPLICIT NONE |
| c Function declaration |
| INTEGER strend |
| c Argument declarations |
| CHARACTER*(*) string |
| c Local variable declarations. |
| INTEGER i |
| c External function declarations. |
| INTEGER len |
| DO i = len(string), 1, -1 |
| strend = i |
| IF (string(i:i) .NE. ' ' .AND. string(i:i) .NE. char(0)) THEN |
| RETURN |
| ENDIF |
| ENDDO |
| strend = 0 |
| END |
| /trunk/lib/libcdfplus.f |
|---|
| 0,0 → 1,1128 |
| subroutine wricst(cstnam,datar,aklev,bklev,aklay,bklay,stdate) |
| C------------------------------------------------------------------------ |
| C Creates the constants file for NetCDF files containing ECMWF |
| C data. The constants file is compatible with the one created |
| C for EM data (with subroutine writecst). |
| C |
| C Input parameters: |
| C |
| C cstnam name of constants file |
| C datar array contains all required parameters to write file |
| C datar(1): number of points along x |
| C datar(2): number of points along y |
| C datar(3): maximum latitude of data region (ymax) |
| C datar(4): minimum longitude of data region (xmin) |
| C datar(5): minimum latitude of data region (ymin) |
| C datar(6): maximum longitude of data region (xmax) |
| C datar(7): grid increment along x |
| C datar(8): grid increment along y |
| C datar(9): number of levels |
| C datar(10): data type (forecast or analysis) |
| C datar(11): data version |
| C datar(12): constants file version |
| C datar(13): longitude of pole of coordinate system |
| C datar(14): latitude of pole of coordinate system |
| C aklev array contains the aklev values |
| C bklev array contains the bklev values |
| C aklay array contains the aklay values |
| C bklay array contains the bklay values |
| C stdate array contains date (year,month,day,time,step) of first |
| C field on file (start-date), dimensionised as stdate(5) |
| C------------------------------------------------------------------------ |
| include "netcdf.inc" |
| integer nchar,maxlev |
| parameter (nchar=20,maxlev=32) |
| real aklev(maxlev),bklev(maxlev) |
| real aklay(maxlev),bklay(maxlev) |
| real pollat,latmin,latmax |
| integer datar(14) |
| integer stdate(5) |
| character*80 cstnam |
| C declarations for constants-variables |
| integer nz |
| integer dattyp, datver, cstver |
| C further declarations |
| integer ierr ! error flag |
| integer cdfid ! NetCDF id |
| integer xid,yid,zid ! dimension ids |
| integer pollonid, pollatid, ! variable ids |
| > aklevid, bklevid, aklayid, bklayid, |
| > lonminid, lonmaxid, latminid, latmaxid, |
| > dellonid, dellatid, |
| > startyid, startmid, startdid, starthid, startsid, |
| > dattypid, datverid, cstverid |
| nz=datar(9) ! number of levels |
| C Set data-type and -version, version of cst-file-format |
| dattyp=datar(10) |
| datver=datar(11) |
| cstver=datar(12) |
| C Initially set error to false |
| ierr=0 |
| C Create constants file |
| cdfid=nccre(trim(cstnam),NCCLOB,ierr) |
| C Define the dimensions |
| xid = ncddef (cdfid,'nx',datar(1),ierr) |
| yid = ncddef (cdfid,'ny',datar(2),ierr) |
| zid = ncddef (cdfid,'nz',datar(9),ierr) |
| C Define integer constants |
| pollonid = ncvdef(cdfid,'pollon', NCFLOAT,0,0,ierr) |
| pollatid = ncvdef(cdfid,'pollat', NCFLOAT,0,0,ierr) |
| aklevid = ncvdef (cdfid, 'aklev', NCFLOAT, 1, zid, ierr) |
| bklevid = ncvdef (cdfid, 'bklev', NCFLOAT, 1, zid, ierr) |
| aklayid = ncvdef (cdfid, 'aklay', NCFLOAT, 1, zid, ierr) |
| bklayid = ncvdef (cdfid, 'bklay', NCFLOAT, 1, zid, ierr) |
| lonminid = ncvdef (cdfid, 'lonmin', NCFLOAT, 0, 0, ierr) |
| lonmaxid = ncvdef (cdfid, 'lonmax', NCFLOAT, 0, 0, ierr) |
| latminid = ncvdef (cdfid, 'latmin', NCFLOAT, 0, 0, ierr) |
| latmaxid = ncvdef (cdfid, 'latmax', NCFLOAT, 0, 0, ierr) |
| dellonid = ncvdef (cdfid, 'dellon', NCFLOAT, 0, 0, ierr) |
| dellatid = ncvdef (cdfid, 'dellat', NCFLOAT, 0, 0, ierr) |
| startyid = ncvdef (cdfid, 'starty', NCLONG, 0, 0, ierr) |
| startmid = ncvdef (cdfid, 'startm', NCLONG, 0, 0, ierr) |
| startdid = ncvdef (cdfid, 'startd', NCLONG, 0, 0, ierr) |
| starthid = ncvdef (cdfid, 'starth', NCLONG, 0, 0, ierr) |
| startsid = ncvdef (cdfid, 'starts', NCLONG, 0, 0, ierr) |
| dattypid = ncvdef (cdfid, 'dattyp', NCLONG, 0, 0, ierr) |
| datverid = ncvdef (cdfid, 'datver', NCLONG, 0, 0, ierr) |
| cstverid = ncvdef (cdfid, 'cstver', NCLONG, 0, 0, ierr) |
| C Leave define mode |
| call ncendf(cdfid,ierr) |
| C Store levels |
| call ncvpt(cdfid, aklevid, 1, nz, aklev, ierr) |
| call ncvpt(cdfid, bklevid, 1, nz, bklev, ierr) |
| call ncvpt(cdfid, aklayid, 1, nz, aklay, ierr) |
| call ncvpt(cdfid, bklayid, 1, nz, bklay, ierr) |
| C Store position of pole (trivial for ECMWF data) |
| call ncvpt1(cdfid, pollonid, 1, real(datar(13))/1000., ierr) |
| if (datar(14).gt.0) then |
| pollat=min(real(datar(14))/1000.,90.) |
| else |
| pollat=max(real(datar(14))/1000.,-90.) |
| endif |
| call ncvpt1(cdfid, pollatid, 1, pollat, ierr) |
| C Store horizontal data borders and grid increments |
| call ncvpt1(cdfid, lonminid, 1, real(datar(4))/1000., ierr) |
| call ncvpt1(cdfid, lonmaxid, 1, real(datar(6))/1000., ierr) |
| latmin=max(real(datar(5))/1000.,-90.) |
| latmax=min(real(datar(3))/1000.,90.) |
| call ncvpt1(cdfid, latminid, 1, latmin, ierr) |
| call ncvpt1(cdfid, latmaxid, 1, latmax, ierr) |
| call ncvpt1(cdfid, dellonid, 1, real(datar(7))/1000., ierr) |
| call ncvpt1(cdfid, dellatid, 1, real(datar(8))/1000., ierr) |
| C Store date of first field on file (start-date) |
| call ncvpt1(cdfid, startyid, 1, stdate(1), ierr) |
| call ncvpt1(cdfid, startmid, 1, stdate(2), ierr) |
| call ncvpt1(cdfid, startdid, 1, stdate(3), ierr) |
| call ncvpt1(cdfid, starthid, 1, stdate(4), ierr) |
| call ncvpt1(cdfid, startsid, 1, stdate(5), ierr) |
| C Store datatype and version |
| call ncvpt1(cdfid, dattypid, 1, dattyp, ierr) |
| call ncvpt1(cdfid, datverid, 1, datver, ierr) |
| C Store version of the constants file format |
| call ncvpt1(cdfid, cstverid, 1, cstver, ierr) |
| C Store strings |
| call ncclos(cdfid,ierr) |
| return |
| end |
| subroutine writelmcst(cdfid,nx,ny,nz,pollon,pollat,lonmin, |
| &lonmax,latmin,latmax,dellon,dellat,dattyp,datver,cstver, |
| &psref,tstar,tbeta,pintf,p0top,idate) |
| c ------------------------------------------------------------------ |
| implicit none |
| integer cdfid |
| c deklarationen der constants-variablen |
| real pollon,pollat |
| real lonmin,lonmax,latmin,latmax,dellon,dellat |
| integer idate(5) |
| integer nx,ny,nz |
| integer dattyp, datver, cstver |
| real psref, tstar, tbeta, pintf, p0top |
| include 'netcdf.inc' |
| * netcdf declaration |
| integer iret, k |
| * dimension ids |
| integer nxdim, nydim, nzdim |
| * variable ids |
| integer startyid, startmid, startdid, starthid |
| * variable shapes, corners and edge lengths |
| integer dims(1), corner(1), edges(1) |
| * enter define mode |
| call ncredf(cdfid, iret) |
| startyid = ncvdef (cdfid, 'starty', NCLONG, 0, 0, iret) |
| startmid = ncvdef (cdfid, 'startm', NCLONG, 0, 0, iret) |
| startdid = ncvdef (cdfid, 'startd', NCLONG, 0, 0, iret) |
| starthid = ncvdef (cdfid, 'starth', NCLONG, 0, 0, iret) |
| * store the rest as global attributes |
| * store nx,ny,nz |
| call ncapt(cdfid,NCGLOBAL,'nx',NCLONG,1,nx,iret) |
| call ncapt(cdfid,NCGLOBAL,'ny',NCLONG,1,ny,iret) |
| call ncapt(cdfid,NCGLOBAL,'nz',NCLONG,1,nz,iret) |
| * store pollon, pollat |
| call ncapt(cdfid,NCGLOBAL,'pollon',NCFLOAT,1,pollon,iret) |
| call ncapt(cdfid,NCGLOBAL,'pollat',NCFLOAT,1,pollat,iret) |
| * store lonmin, etc |
| call ncapt(cdfid,NCGLOBAL,'lonmin',NCFLOAT,1,lonmin,iret) |
| call ncapt(cdfid,NCGLOBAL,'lonmax',NCFLOAT,1,lonmax,iret) |
| call ncapt(cdfid,NCGLOBAL,'latmin',NCFLOAT,1,latmin,iret) |
| call ncapt(cdfid,NCGLOBAL,'latmax',NCFLOAT,1,latmax,iret) |
| call ncapt(cdfid,NCGLOBAL,'dellon',NCFLOAT,1,dellon,iret) |
| call ncapt(cdfid,NCGLOBAL,'dellat',NCFLOAT,1,dellat,iret) |
| * store data type and version |
| call ncapt(cdfid,NCGLOBAL,'dattyp',NCLONG,1,dattyp,iret) |
| call ncapt(cdfid,NCGLOBAL,'datver',NCLONG,1,datver,iret) |
| call ncapt(cdfid,NCGLOBAL,'cstver',NCLONG,1,cstver,iret) |
| * store information of lm model vertical grid |
| call ncapt(cdfid,NCGLOBAL,'psref',NCFLOAT,1,psref,iret) |
| call ncapt(cdfid,NCGLOBAL,'tstar',NCFLOAT,1,tstar,iret) |
| call ncapt(cdfid,NCGLOBAL,'tbeta',NCFLOAT,1,tbeta,iret) |
| call ncapt(cdfid,NCGLOBAL,'pintf',NCFLOAT,1,pintf,iret) |
| call ncapt(cdfid,NCGLOBAL,'p0top',NCFLOAT,1,p0top,iret) |
| * leave define mode |
| call ncendf(cdfid, iret) |
| * store starty, etc |
| corner(1) = 1 |
| edges(1) = 1 |
| call ncvpt(cdfid, startyid, corner, edges, idate(1), iret) |
| call ncvpt(cdfid, startmid, corner, edges, idate(2), iret) |
| call ncvpt(cdfid, startdid, corner, edges, idate(3), iret) |
| call ncvpt(cdfid, starthid, corner, edges, idate(4), iret) |
| end |
| subroutine globcst(cdfnam,datar,aklev,bklev,aklay,bklay,stdate) |
| C------------------------------------------------------------------------ |
| C+ |
| C NAME: |
| C subroutine globcst |
| C |
| C PURPOSE: |
| C instead of writing a constants-file (*_cst), the information |
| C is added to the netCDF file as global variables |
| C the data format is compatible with the one requested by |
| C the IVE ETH/MIT version, contact author about details |
| C |
| C CATEGORY: |
| C model,netCDF |
| C |
| C CALLING SEQUENCE: |
| C subroutine globcst(cdfnam,datar,aklev,bklev,aklay,bklay,stdate) |
| C |
| C INPUTS: |
| C cdfnam name of netCDF file |
| C The file needs to exist, otherwise an ERROR occurs, |
| C i.e. nothing is done |
| C datar array contains all required parameters to write file |
| C datar(1): number of points along x |
| C datar(2): number of points along y |
| C datar(3): maximum latitude of data region (ymax) |
| C datar(4): minimum longitude of data region (xmin) |
| C datar(5): minimum latitude of data region (ymin) |
| C datar(6): maximum longitude of data region (xmax) |
| C datar(7): grid increment along x |
| C datar(8): grid increment along y |
| C datar(9): number of levels |
| C datar(10): data type (forecast or analysis) |
| C datar(11): data version |
| C datar(12): constants file version |
| C datar(13): longitude of pole of coordinate system |
| C datar(14): latitude of pole of coordinate system |
| C aklev array contains the aklev values |
| C bklev array contains the bklev values |
| C aklay array contains the aklay values |
| C bklay array contains the bklay values |
| C stdate array contains date (year,month,day,time,step) of first |
| C field on file (start-date), dimensionised as stdate(5) |
| C list the griblist-ASCII-file |
| C varno the GRIB code number |
| C |
| C OUTPUTS: |
| C Adds cdf-information to EXISTING netCDF-file |
| C |
| C MODIFICATION HISTORY: |
| C |
| C June 93 Christoph Schaer (ETHZ) created |
| C Nov 93 Heini Wernli (ETHZ) wricst |
| C Nov 98 David N. Bresch (MIT) wricst to globcst |
| C- |
| C Sun include statement. |
| include "netcdf.inc" |
| integer nchar,maxlev |
| parameter (nchar=20,maxlev=32) |
| real aklev(maxlev),bklev(maxlev) |
| real aklay(maxlev),bklay(maxlev) |
| integer datar(14) |
| integer stdate(5) |
| character*80 cdfnam |
| C declarations for constants-variables |
| integer nz |
| integer dattyp, datver, cstver |
| C further declarations |
| integer ierr ! error flag |
| integer cdfid ! NetCDF id |
| integer xid,yid,zid ! dimension ids |
| integer pollonid, pollatid, ! variable ids |
| > aklevid, bklevid, aklayid, bklayid, |
| > lonminid, lonmaxid, latminid, latmaxid, |
| > dellonid, dellatid, |
| > startyid, startmid, startdid, starthid, startsid, |
| > dattypid, datverid, cstverid |
| nz=datar(9) ! number of levels |
| C Set data-type and -version, version of cst-file-format |
| dattyp=datar(10) |
| datver=datar(11) |
| cstver=datar(12) |
| C Initially set error to false |
| ierr=0 |
| C open the netCDF-file: |
| call cdfwopn(cdfnam,cdfid,ierr) |
| if (ierr.ne.0) then |
| print*,'ERROR opening netCDF-file ',cdfnam |
| return |
| endif |
| C Put file into define mode |
| call ncredf(cdfid,ierr) |
| if (ierr.ne.0) then |
| print*,'ERROR switching to netCDF redefine mode' |
| return |
| endif |
| C Define the dimensions |
| xid = ncddef (cdfid,'nx',datar(1),ierr) |
| yid = ncddef (cdfid,'ny',datar(2),ierr) |
| zid = ncddef (cdfid,'nz',datar(9),ierr) |
| C Define integer constants |
| pollonid = ncvdef(cdfid,'pollon', NCFLOAT,0,0,ierr) |
| pollatid = ncvdef(cdfid,'pollat', NCFLOAT,0,0,ierr) |
| aklevid = ncvdef (cdfid, 'aklev', NCFLOAT, 1, zid, ierr) |
| bklevid = ncvdef (cdfid, 'bklev', NCFLOAT, 1, zid, ierr) |
| aklayid = ncvdef (cdfid, 'aklay', NCFLOAT, 1, zid, ierr) |
| bklayid = ncvdef (cdfid, 'bklay', NCFLOAT, 1, zid, ierr) |
| lonminid = ncvdef (cdfid, 'lonmin', NCFLOAT, 0, 0, ierr) |
| lonmaxid = ncvdef (cdfid, 'lonmax', NCFLOAT, 0, 0, ierr) |
| latminid = ncvdef (cdfid, 'latmin', NCFLOAT, 0, 0, ierr) |
| latmaxid = ncvdef (cdfid, 'latmax', NCFLOAT, 0, 0, ierr) |
| dellonid = ncvdef (cdfid, 'dellon', NCFLOAT, 0, 0, ierr) |
| dellatid = ncvdef (cdfid, 'dellat', NCFLOAT, 0, 0, ierr) |
| startyid = ncvdef (cdfid, 'starty', NCLONG, 0, 0, ierr) |
| startmid = ncvdef (cdfid, 'startm', NCLONG, 0, 0, ierr) |
| startdid = ncvdef (cdfid, 'startd', NCLONG, 0, 0, ierr) |
| starthid = ncvdef (cdfid, 'starth', NCLONG, 0, 0, ierr) |
| startsid = ncvdef (cdfid, 'starts', NCLONG, 0, 0, ierr) |
| dattypid = ncvdef (cdfid, 'dattyp', NCLONG, 0, 0, ierr) |
| datverid = ncvdef (cdfid, 'datver', NCLONG, 0, 0, ierr) |
| cstverid = ncvdef (cdfid, 'cstver', NCLONG, 0, 0, ierr) |
| C Leave define mode |
| call ncendf(cdfid,ierr) |
| if (ierr.ne.0) then |
| print*,'ERROR exiting define mode' |
| return |
| endif |
| C Store levels |
| call ncvpt(cdfid, aklevid, 1, nz, aklev, ierr) |
| call ncvpt(cdfid, bklevid, 1, nz, bklev, ierr) |
| call ncvpt(cdfid, aklayid, 1, nz, aklay, ierr) |
| call ncvpt(cdfid, bklayid, 1, nz, bklay, ierr) |
| C Store position of pole (trivial for ECMWF data) |
| call ncvpt1(cdfid, pollonid, 1, real(datar(13))/1000., ierr) |
| call ncvpt1(cdfid, pollatid, 1, real(datar(14))/1000., ierr) |
| C Store horizontal data borders and grid increments |
| call ncvpt1(cdfid, lonminid, 1, real(datar(4))/1000., ierr) |
| call ncvpt1(cdfid, lonmaxid, 1, real(datar(6))/1000., ierr) |
| call ncvpt1(cdfid, latminid, 1, real(datar(5))/1000., ierr) |
| call ncvpt1(cdfid, latmaxid, 1, real(datar(3))/1000., ierr) |
| call ncvpt1(cdfid, dellonid, 1, real(datar(7))/1000., ierr) |
| call ncvpt1(cdfid, dellatid, 1, real(datar(8))/1000., ierr) |
| C Store date of first field on file (start-date) |
| call ncvpt1(cdfid, startyid, 1, stdate(1), ierr) |
| call ncvpt1(cdfid, startmid, 1, stdate(2), ierr) |
| call ncvpt1(cdfid, startdid, 1, stdate(3), ierr) |
| call ncvpt1(cdfid, starthid, 1, stdate(4), ierr) |
| call ncvpt1(cdfid, startsid, 1, stdate(5), ierr) |
| C Store datatype and version |
| call ncvpt1(cdfid, dattypid, 1, dattyp, ierr) |
| call ncvpt1(cdfid, datverid, 1, datver, ierr) |
| C Store version of the constants file format |
| call ncvpt1(cdfid, cstverid, 1, cstver, ierr) |
| if (ierr.ne.0) then |
| print*,'ERROR adding cst-date as global variables' |
| return |
| endif |
| C Store strings |
| call ncclos(cdfid,ierr) |
| if (ierr.ne.0) then |
| print*,'ERROR closing netCDF file' |
| endif |
| return |
| end |
| subroutine getsdat(cdfid,varnam,time,ix,iy,iz,sx,sy,sz,dat,error) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This routine is called to read the data within a selected |
| c domain of a variable from an IVE-NetCDF file. |
| c Prior to calling this routine, the file must be opened with |
| c a call to opncdf (for extension) or crecdf (for creation) or |
| c readcdf (for readonly). |
| c Arguments: |
| c cdfid int input file-identifier |
| c (must be obtained by calling routine |
| c opncdf,readcdf or crecdf) |
| c varnam char input the user-supplied variable name |
| c time real input the user-supplied time-level of the |
| c data to be read from the file (the time- |
| c levels stored in the file can be obtained |
| c with a call to gettimes). |
| c ix/y/z int input indices of lower left corner of selected |
| c data volume. |
| c sx/y/z int input size of selected data volume |
| c dat real output data-array with dimensions (sx,sy,sz). |
| c error int output indicates possible errors found in this |
| c routine. |
| c error = 0 no errors detected. |
| c error = 1 the variable is not present on |
| c the file. |
| c error = 2 the value of 'time' is not |
| c known.to the file. |
| c error = 6,7,8 data volume too large |
| c error =10 another error. |
| c History: |
| c June 93 Christoph Schaer (ETHZ) Created getdat |
| c Nov 93 Heini Wernli (ETHZ) Created getsdat |
| c----------------------------------------------------------------------- |
| include "netcdf.inc" |
| C Declaration of local variables |
| character*(*) varnam |
| character*(20) chars |
| integer cdfid |
| integer ix,iy,iz,sx,sy,sz |
| real dat(sx,sy,sz) |
| real misdat,varmin(4),varmax(4),stag(4) |
| real time, timeval |
| integer corner(4),edgeln(4),didtim,vardim(4),ndims |
| integer error, ierr |
| integer ntime |
| integer idtime,idvar,iflag |
| integer i |
| call ncpopt(NCVERBOS) |
| c access the variable |
| call getdef (cdfid, trim(varnam), ndims, misdat, |
| & vardim, varmin, varmax, stag, ierr) |
| if (ierr.ne.0) then |
| print *,'*ERROR* in getdef in getdat' |
| error=1 |
| return |
| endif |
| idvar=ncvid(cdfid,trim(varnam),ierr) |
| if (ierr.ne.0) then |
| print *,'*ERROR* in ncvid in getsdat' |
| error=1 |
| return |
| endif |
| C Get times-array |
| didtim=ncdid(cdfid,'time',ierr) |
| if (ierr.ne.0) then |
| print *,'*ERROR* didtim in getsdat' |
| error=10 |
| return |
| endif |
| call ncdinq(cdfid,didtim,chars,ntime,ierr) |
| if (ierr.ne.0) then |
| print *,'*ERROR* in ncdinq in getsdat' |
| error=10 |
| return |
| endif |
| idtime=ncvid(cdfid,'time',ierr) |
| if (ierr.ne.0) then |
| print *,'*ERROR* in ncvid for time in getsdat' |
| error=10 |
| return |
| endif |
| c find appropriate time-index |
| iflag=0 |
| do i=1,ntime |
| call ncvgt1(cdfid,idtime,i,timeval,ierr) |
| if (ierr.ne.0) print *,'*ERROR* in ncvgt1 in getsdat' |
| if (time.eq.timeval) iflag=i |
| enddo |
| if (iflag.eq.0) then |
| error=2 |
| print *,'Error: Unknown time in getsdat' |
| print *,time,timeval |
| return |
| endif |
| C Define data volume to be written (index space) |
| corner(1)=ix |
| corner(2)=iy |
| corner(3)=iz |
| corner(4)=iflag |
| edgeln(1)=sx |
| edgeln(2)=sy |
| edgeln(3)=sz |
| edgeln(4)=1 |
| C Check if data volume is within data domain |
| if (ix+sx-1.gt.vardim(1)) then |
| error=7 |
| print *,'Error: data volume too large in x-direction' |
| print *,ix,sx,vardim(1) |
| return |
| endif |
| if (iy+sy-1.gt.vardim(2)) then |
| error=8 |
| print *,'Error: data volume too large in y-direction' |
| return |
| endif |
| if (iz+sz-1.gt.vardim(3)) then |
| error=9 |
| print *,'Error: data volume too large in z-direction' |
| return |
| endif |
| C Read data from NetCDF file |
| call ncvgt(cdfid,idvar,corner,edgeln,dat,error) |
| if (error.ne.0) then |
| print *, 'corner ',corner(1),corner(2),corner(3) |
| print *, 'edgeln ',edgeln(1),edgeln(2),edgeln(3) |
| print *, '*ERROR* in ncvgt in getsdat' |
| error=10 |
| endif |
| end |
| subroutine getlevs(cstid,nlev,aklev,bklev,aklay,bklay,error) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This routine is called to get the level arrays aklev and |
| c bklev from a NetCDF constants file. |
| c Arguments: |
| c cstid int input identifier for NetCDF constants file |
| c nlev int input number of levels |
| c aklev real output array contains all aklev values |
| c bklev real output array contains all bklev values |
| c aklay real output array contains all aklay values |
| c bklay real output array contains all bklay values |
| c error int output error flag |
| c error = 0 no errors detected |
| c error = 1 error detected |
| c History: |
| c Aug. 93 Heini Wernli Created. |
| c----------------------------------------------------------------------- |
| integer error |
| integer cstid |
| integer ncdid,ncvid ! NetCDF functions |
| integer didz,idak,idbk,idaky,idbky |
| integer nlev |
| real aklev(nlev),bklev(nlev),aklay(nlev),bklay(nlev) |
| character*(20) dimnam |
| integer i |
| didz =ncdid(cstid,'nz',error) |
| if (error.ne.0) goto 920 |
| idak =ncvid(cstid,'aklev',error) |
| if (error.ne.0) goto 920 |
| idbk =ncvid(cstid,'bklev',error) |
| if (error.ne.0) goto 920 |
| idaky =ncvid(cstid,'aklay',error) |
| if (error.ne.0) goto 920 |
| idbky =ncvid(cstid,'bklay',error) |
| if (error.ne.0) goto 920 |
| call ncdinq(cstid,didz,dimnam,nlev,error) ! read number of levels |
| if (error.ne.0) goto 920 |
| do 10 i=1,nlev |
| call ncvgt1(cstid,idak,i,aklev(i),error) ! get aklev |
| call ncvgt1(cstid,idbk,i,bklev(i),error) ! get bklev |
| call ncvgt1(cstid,idaky,i,aklay(i),error) ! get aklay |
| call ncvgt1(cstid,idbky,i,bklay(i),error) ! get bklay |
| if (error.ne.0) goto 920 |
| 10 continue |
| return |
| c Error exits. |
| 920 write(*,*)'*ERROR*: An error occured in subroutine getlevs' |
| return |
| end |
| subroutine getntim(cdfid,ntimes,ierr) |
| C------------------------------------------------------------------------ |
| C Purpose: |
| C Get number of times on the specified NetCDF file |
| C Arguments: |
| C cdfid int input identifier for NetCDF file |
| C ntimes int output number of times on the file |
| C error int output errorflag |
| C History: |
| C Heini Wernli, ETHZ |
| C------------------------------------------------------------------------ |
| include "netcdf.inc" |
| integer ierr |
| integer didtim,ntimes |
| integer cdfid,idtime |
| integer ncopts |
| character*(20) dimnam |
| c Get current value of error options, and make sure netCDF-errors do |
| c not abort execution |
| call ncgopt (ncopts) |
| call ncpopt(NCVERBOS) |
| didtim=ncdid(cdfid,'time',ierr) ! inquire id for time dimension |
| if (ierr.ne.0) goto 900 |
| idtime=ncvid(cdfid,'time',ierr) ! inquire id for time array |
| if (ierr.ne.0) goto 900 |
| call ncdinq(cdfid,didtim,dimnam,ntimes,ierr) ! inquire # of times |
| if (ierr.ne.0) goto 900 |
| c normal exit |
| call ncpopt (ncopts) |
| return |
| c error exit |
| 900 ntimes=1 |
| call ncpopt (ncopts) |
| end |
| subroutine getstart(cdfid,idate,ierr) |
| C------------------------------------------------------------------------ |
| C Purpose: |
| C Get start date for fields on specified NetCDF file |
| C Arguments: |
| C cdfid int input identifier for NetCDF file |
| C idate int output array contains date (year,month,day,time,step) |
| C dimensioned as idate(5) |
| C ierr int output error flag |
| C------------------------------------------------------------------------ |
| include "netcdf.inc" |
| c variable declarations |
| integer ierr |
| integer idate(5) |
| integer cdfid,ncopts,idvar,nvars |
| integer ndims,ngatts,recdim,i,vartyp,nvatts,vardim(4) |
| character*20 vnam(100) |
| c Get current value of error options, and make sure NetCDF-errors do |
| c not abort execution |
| call ncgopt (ncopts) |
| call ncpopt (NCVERBOS) |
| idvar=ncvid(cdfid,'starty',ierr) |
| if (ierr.ne.0) goto 930 |
| call ncvgt1(cdfid,idvar,1,idate(1),ierr) |
| if (ierr.ne.0) goto 920 |
| idvar=ncvid(cdfid,'startm',ierr) |
| if (ierr.ne.0) goto 920 |
| call ncvgt1(cdfid,idvar,1,idate(2),ierr) |
| if (ierr.ne.0) goto 920 |
| idvar=ncvid(cdfid,'startd',ierr) |
| if (ierr.ne.0) goto920 |
| call ncvgt1(cdfid,idvar,1,idate(3),ierr) |
| if (ierr.ne.0) goto 920 |
| idvar=ncvid(cdfid,'starth',ierr) |
| if (ierr.ne.0) goto 920 |
| call ncvgt1(cdfid,idvar,1,idate(4),ierr) |
| if (ierr.ne.0) goto 920 |
| C Starts is not defined on all files |
| C Only ask for it if it exists |
| C Inquire number of dimensions, variables and attributes |
| idate(5)=0 |
| call ncinq(cdfid,ndims,nvars,ngatts,recdim,ierr) |
| do i=1,nvars |
| call ncvinq(cdfid,i,vnam(i),vartyp,ndims,vardim,nvatts,ierr) |
| if (vnam(i).eq.'starts') then |
| idvar=ncvid(cdfid,'starts',ierr) |
| call ncvgt1(cdfid,idvar,1,idate(5),ierr) |
| if (ierr.ne.0) goto 920 |
| endif |
| enddo |
| c normal exit |
| call ncpopt (ncopts) |
| return |
| c error exit |
| 920 continue |
| write (6, *) 'ERROR: An error occurred while attempting to ', |
| & 'read the starting-time in subroutine putstart.' |
| 930 continue |
| call ncpopt (ncopts) |
| end |
| subroutine putstart(cdfid,idate,ierr) |
| C---------------------------------------------------------------------- |
| C Purpose: |
| C Puts the 'starting-time' on the specified NetCDF file. |
| C Arguments: |
| C cdfid int input identifier for NetCDF file |
| C idate int input array contains date (year,month,day,time,step) |
| C dimensioned as idate(5) |
| C ierr int output error flag |
| C------------------------------------------------------------------------ |
| include "netcdf.inc" |
| c variable declarations |
| integer ierr,idate(5),startid(5),cdfid,ncopts,i |
| c Get current value of error options, and make sure NetCDF-errors do |
| c not abort execution |
| call ncgopt (ncopts) |
| call ncpopt (NCVERBOS) |
| c define variables |
| call ncredf(cdfid,ierr) |
| if (ierr.ne.0) goto 920 |
| startid(1) = ncvdef (cdfid, 'starty', NCLONG, 0, 0, ierr) |
| if (ierr.ne.0) goto 920 |
| startid(2) = ncvdef (cdfid, 'startm', NCLONG, 0, 0, ierr) |
| if (ierr.ne.0) goto 920 |
| startid(3) = ncvdef (cdfid, 'startd', NCLONG, 0, 0, ierr) |
| if (ierr.ne.0) goto 920 |
| startid(4) = ncvdef (cdfid, 'starth', NCLONG, 0, 0, ierr) |
| if (ierr.ne.0) goto 920 |
| startid(5) = ncvdef (cdfid, 'starts', NCLONG, 0, 0, ierr) |
| if (ierr.ne.0) goto 920 |
| call ncendf(cdfid, ierr) |
| if (ierr.ne.0) goto 920 |
| c store variables |
| do i=1,5 |
| call ncvpt1(cdfid,startid(i),1,idate(i),ierr) |
| if (ierr.ne.0) goto 920 |
| enddo |
| c synchronyse output to disk, revert to previous error-mode, and exit |
| call ncsnc (cdfid,ierr) |
| call ncpopt (ncopts) |
| return |
| c error exit |
| 920 write (6, *) 'ERROR: An error occurred while attempting to ', |
| & 'write the starting-time in subroutine putstart.' |
| call ncpopt (ncopts) |
| call ncclos (cdfid, ierr) |
| end |
| subroutine getgrid(cdfid,dx,dy,ierr) |
| C------------------------------------------------------------------------ |
| C Purpose: |
| C Get grid increments for fields on specified NetCDF file |
| C Arguments: |
| C cdfid int input identifier for NetCDF file |
| C dx real output grid increment along latitude |
| C dy real output grid increment along longitude |
| C ierr int output error flag |
| C------------------------------------------------------------------------ |
| integer ierr |
| integer cdfid |
| integer ncvid |
| integer idilon,idilat |
| real dx,dy |
| idilon =ncvid(cdfid,'dellon',ierr) |
| if (ierr.ne.0) return |
| idilat =ncvid(cdfid,'dellat',ierr) |
| if (ierr.ne.0) return |
| call ncvgt1(cdfid,idilon,1,dx,ierr) |
| if (ierr.ne.0) return |
| call ncvgt1(cdfid,idilat,1,dy,ierr) |
| if (ierr.ne.0) return |
| end |
| subroutine getdattyp(cdfid,typ,ierr) |
| C------------------------------------------------------------------------ |
| C Purpose: |
| C Get data type for specified NetCDF file |
| C Arguments: |
| C cdfid int input identifier for NetCDF file |
| C typ int output data type: 1 (52) for pressure (theta) coord |
| C ierr int output error flag |
| C------------------------------------------------------------------------ |
| integer ierr |
| integer cdfid |
| integer ncvid |
| integer idtyp,typ |
| idtyp =ncvid(cdfid,'dattyp',ierr) |
| if (ierr.ne.0) return |
| call ncvgt1(cdfid,idtyp,1,typ,ierr) |
| if (ierr.ne.0) return |
| end |
| subroutine getpole(cdfid,pollon,pollat,ierr) |
| C------------------------------------------------------------------------ |
| C Purpose: |
| C Get physical coordinates of pole of coordinate system |
| C Arguments: |
| C cdfid int input identifier for NetCDF file |
| C pollon real output longitude of pole |
| C pollat real output latitude of pole |
| C ierr int output error flag |
| C------------------------------------------------------------------------ |
| integer ierr |
| integer cdfid |
| integer ncvid |
| integer idplon,idplat |
| real pollon,pollat |
| idplon =ncvid(cdfid,'pollon',ierr) |
| if (ierr.ne.0) return |
| idplat =ncvid(cdfid,'pollat',ierr) |
| if (ierr.ne.0) return |
| call ncvgt1(cdfid,idplon,1,pollon,ierr) |
| if (ierr.ne.0) return |
| call ncvgt1(cdfid,idplat,1,pollat,ierr) |
| if (ierr.ne.0) return |
| end |
| subroutine getmc2grid(cdfid,polx,poly,delx,shem,phi0,lam0,ierr) |
| C------------------------------------------------------------------------ |
| C Purpose: |
| C Get physical coordinates of pole of coordinate system |
| C Arguments: |
| C cdfid int input identifier for NetCDF file |
| C ierr int output error flag |
| C------------------------------------------------------------------------ |
| integer ierr |
| integer cdfid |
| integer ncvid |
| integer idpolx,idpoly,iddelx,idshem,idphi0,idlam0 |
| real polx,poly,delx,shem,phi0,lam0 |
| idpolx =ncvid(cdfid,'polx',ierr) |
| if (ierr.ne.0) return |
| idpoly =ncvid(cdfid,'poly',ierr) |
| if (ierr.ne.0) return |
| iddelx =ncvid(cdfid,'delx',ierr) |
| if (ierr.ne.0) return |
| idshem =ncvid(cdfid,'shem',ierr) |
| if (ierr.ne.0) return |
| idphi0 =ncvid(cdfid,'phi0',ierr) |
| if (ierr.ne.0) return |
| idlam0 =ncvid(cdfid,'lam0',ierr) |
| if (ierr.ne.0) return |
| call ncvgt1(cdfid,idpolx,1,polx,ierr) |
| if (ierr.ne.0) return |
| call ncvgt1(cdfid,idpoly,1,poly,ierr) |
| if (ierr.ne.0) return |
| call ncvgt1(cdfid,iddelx,1,delx,ierr) |
| if (ierr.ne.0) return |
| call ncvgt1(cdfid,idshem,1,shem,ierr) |
| if (ierr.ne.0) return |
| call ncvgt1(cdfid,idphi0,1,phi0,ierr) |
| if (ierr.ne.0) return |
| call ncvgt1(cdfid,idlam0,1,lam0,ierr) |
| if (ierr.ne.0) return |
| end |
| subroutine getcfn(cdfid,cfn,ierr) |
| C------------------------------------------------------------------------ |
| C Purpose: |
| C Get name of constants file |
| C Arguments: |
| C cdfid int input identifier for NetCDF file |
| C cfn char output name of constants file |
| C ierr int output error flag |
| C------------------------------------------------------------------------ |
| include 'netcdf.inc' |
| integer ierr |
| integer cdfid,lenstr |
| character*80 cfn |
| lenstr=80 |
| call ncagtc(cdfid,NCGLOBAL,"constants_file_name",cfn,lenstr,ierr) |
| if (ierr.ne.0) write(*,*)'error in SR getcfn' |
| end |
| subroutine getdim (cdfid, varnam, nx, ny, nz, error) |
| c------------------------------------------------------------------------- |
| c Purpose: |
| c This routine is called to get the dimensions of |
| c a variable from an IVE-NetCDF file for use with the IVE plotting |
| c package. Prior to calling this routine, the file must be opened |
| c with a call to opncdf. |
| c Arguments: |
| c cdfid int input file-identifier |
| c (can be obtained by calling routine |
| c opncdf) |
| c varnam char input the user-supplied variable name. |
| c (can be obtained by calling routine |
| c opncdf) |
| c nx int output the zonal dimension of the variable. |
| c ny int output the meridional dimension of the variable. |
| c nz int output the vertical dimension of the variable. |
| c |
| c error int output indicates possible errors found in this |
| c routine. |
| c error = 0 no errors detected. |
| c error = 1 the variable is not on the file. |
| c error =10 other errors. |
| c History: |
| c March 2000 Heini Wernli (ETHZ) Created. |
| c----------------------------------------------------------------------- |
| include "netcdf.inc" |
| c Argument declarations. |
| character *(*) varnam |
| integer vardim(4), ndim, error, cdfid |
| integer nx,ny,nz |
| c Local variable declarations. |
| character *(20) dimnam(MAXNCDIM),vnam |
| integer id,i,k |
| integer ndims,nvars,ngatts,recdim,dimsiz(MAXNCDIM) |
| integer vartyp,nvatts, ncopts |
| c Get current value of error options. |
| call ncgopt (ncopts) |
| c make sure NetCDF-errors do not abort execution |
| call ncpopt(NCVERBOS) |
| c Initially set error to indicate no errors. |
| error = 0 |
| c inquire for number of dimensions |
| call ncinq(cdfid,ndims,nvars,ngatts,recdim,error) |
| if (error.eq.1) goto 920 |
| c read dimension-table |
| do i=1,ndims |
| call ncdinq(cdfid,i,dimnam(i),dimsiz(i),error) |
| if (error.gt.0) goto 920 |
| enddo |
| c get id of the variable |
| id=ncvid(cdfid,varnam,error) |
| if (error.eq.1) goto 910 |
| c inquire about variable |
| call ncvinq(cdfid,id,vnam,vartyp,ndim,vardim,nvatts,error) |
| if (vartyp.ne.NCFLOAT) error=1 |
| if (error.gt.0) goto 920 |
| c get dimensions from dimension-table |
| do k=1,ndim |
| vardim(k)=dimsiz(vardim(k)) |
| enddo |
| nx=vardim(1) |
| ny=vardim(2) |
| nz=vardim(3) |
| c normal exit |
| call ncpopt (ncopts) |
| return |
| c Error exits. |
| 910 write (6, *) '*ERROR*: The selected variable could not be found ', |
| & 'in the file by getdim.' |
| call ncpopt (ncopts) |
| call ncclos (cdfid, error) |
| return |
| 920 write (6, *) '*ERROR*: An error occurred while attempting to ', |
| & 'read the data file in subroutine getcdf.' |
| call ncpopt (ncopts) |
| call ncclos (cdfid, error) |
| end |
| subroutine new_gettra(cdfid,varnam,ix,ntimes,array,ierr) |
| C------------------------------------------------------------------------ |
| C |
| C Reads the time-evolution for one grid-point of the variable |
| C indicated by varnam. |
| C |
| C cdfid int input identifier for NetCDF file |
| C varnam char input name of variable |
| C ix int input index for trajectory to read |
| C ntimes int input number of time-indices to read |
| C array real output array contains the readed values |
| C ierr int output error flag |
| C------------------------------------------------------------------------ |
| C Declaration of attributes |
| integer cdfid |
| character*(*) varnam |
| integer ix |
| integer ntimes |
| real array(ntimes) |
| C Declaration of local variables |
| integer corner(4),edgeln(4) |
| integer idvar,ierr |
| integer ncvid |
| integer strend |
| corner(1)=ix |
| corner(2)=1 |
| corner(3)=1 |
| corner(4)=1 |
| edgeln(1)=1 |
| edgeln(2)=1 |
| edgeln(3)=1 |
| edgeln(4)=ntimes |
| idvar =ncvid(cdfid,varnam(1:strend(varnam)),ierr) |
| call ncvgt(cdfid,idvar,corner,edgeln,array,ierr) |
| if (ierr.ne.0) goto 991 |
| return |
| 991 stop 'Variable not found on NetCDF file in SR new_gettra' |
| end |
| subroutine getvars(cdfid,nvars,vnam,ierr) |
| C------------------------------------------------------------------------ |
| C Opens the NetCDF file 'filnam' and returns its identifier cdfid. |
| C filnam char input name of NetCDF file to open |
| C nvars int output number of variables on file |
| C vnam char output array with variable names |
| C ierr int output error flag |
| C------------------------------------------------------------------------ |
| include 'netcdf.inc' |
| integer cdfid,ierr,nvars |
| character*(*) vnam(*) |
| integer ndims,ngatts,recdim,i,vartyp,nvatts,vardim(4) |
| call ncpopt(NCVERBOS) |
| C Inquire number of dimensions, variables and attributes |
| call ncinq(cdfid,ndims,nvars,ngatts,recdim,ierr) |
| C Inquire variable names from NetCDF file |
| do i=1,nvars |
| call ncvinq(cdfid,i,vnam(i),vartyp,ndims,vardim,nvatts,ierr) |
| enddo |
| return |
| end |
| /trunk/lib/libgm2em.f |
|---|
| 0,0 → 1,229 |
| 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 |
| REAL FUNCTION PHSTOPH (PHIS, LAMS, POLPHI, POLLAM) |
| C |
| C%Z% Modul %M%, V%I% vom %G%, extrahiert am %H% |
| C |
| C**** PHSTOPH - FC:BERECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE FUER |
| C**** EINEN PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) IM |
| C**** ROTIERTEN SYSTEM. DER NORDPOL DIESES SYSTEMS HAT |
| C**** DIE WAHREN KOORDINATEN (POLPHI, POLLAM) |
| C** AUFRUF : PHI = PHSTOPH (PHIS, LAMS, POLPHI, POLLAM) |
| C** ENTRIES : KEINE |
| C** ZWECK : BERECHNUNG DER WAHREN GEOGRAPHISCHEN BREITE FUER |
| C** EINEN 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: PHIS REAL GEOGR. BREITE DES PUNKTES IM ROT.SYS. |
| C** LAMS REAL GEOGR. LAENGE DES PUNKTES IM ROT.SYS. |
| C** POLPHI REAL WAHRE GEOGR. BREITE DES NORDPOLS |
| C** POLLAM REAL WAHRE GEOGR. LAENGE DES NORDPOLS |
| C** AUSGABE- |
| C** PARAMETER: WAHRE GEOGRAPHISCHE BREITE 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: D.MAJEWSKI |
| REAL LAMS,PHIS,POLPHI,POLLAM |
| DATA ZRPI18 , ZPIR18 / 57.2957795 , 0.0174532925 / |
| SINPOL = SIN(ZPIR18*POLPHI) |
| COSPOL = COS(ZPIR18*POLPHI) |
| ZPHIS = ZPIR18*PHIS |
| ZLAMS = LAMS |
| IF(ZLAMS.GT.180.0) ZLAMS = ZLAMS - 360.0 |
| ZLAMS = ZPIR18*ZLAMS |
| ARG = COSPOL*COS(ZPHIS)*COS(ZLAMS) + SINPOL*SIN(ZPHIS) |
| PHSTOPH = ZRPI18*ASIN(ARG) |
| RETURN |
| END |
| 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 LMSTOLM (PHIS, LAMS, POLPHI, POLLAM) |
| C |
| C%Z% Modul %M%, V%I% vom %G%, extrahiert am %H% |
| C |
| C**** LMSTOLM - FC:BERECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE FUER |
| C**** EINEN PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) |
| C**** IM ROTIERTEN SYSTEM. DER NORDPOL DES SYSTEMS HAT |
| C**** DIE WAHREN KOORDINATEN (POLPHI, POLLAM) |
| C** AUFRUF : LAM = LMSTOLM (PHIS, LAMS, POLPHI, POLLAM) |
| C** ENTRIES : KEINE |
| C** ZWECK : BERECHNUNG DER WAHREN GEOGRAPHISCHEN LAENGE FUER |
| C** EINEN PUNKT MIT DEN KOORDINATEN (PHIS, LAMS) |
| C** IM 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: PHIS REAL GEOGR. BREITE DES PUNKTES IM ROT.SYS. |
| C** LAMS REAL GEOGR. LAENGE DES PUNKTES IM ROT.SYS. |
| C** POLPHI REAL WAHRE GEOGR. BREITE DES NORDPOLS |
| C** POLLAM REAL WAHRE GEOGR. LAENGE DES NORDPOLS |
| 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: D.MAJEWSKI |
| REAL LAMS,PHIS,POLPHI,POLLAM |
| DATA ZRPI18 , ZPIR18 / 57.2957795 , 0.0174532925 / |
| ZSINPOL = SIN(ZPIR18*POLPHI) |
| ZCOSPOL = COS(ZPIR18*POLPHI) |
| ZLAMPOL = ZPIR18*POLLAM |
| ZPHIS = ZPIR18*PHIS |
| ZLAMS = LAMS |
| IF(ZLAMS.GT.180.0) ZLAMS = ZLAMS - 360.0 |
| ZLAMS = ZPIR18*ZLAMS |
| ZARG1 = SIN(ZLAMPOL)*(- ZSINPOL*COS(ZLAMS)*COS(ZPHIS) + |
| 1 ZCOSPOL* SIN(ZPHIS)) - |
| 2 COS(ZLAMPOL)* SIN(ZLAMS)*COS(ZPHIS) |
| ZARG2 = COS(ZLAMPOL)*(- ZSINPOL*COS(ZLAMS)*COS(ZPHIS) + |
| 1 ZCOSPOL* SIN(ZPHIS)) + |
| 2 SIN(ZLAMPOL)* SIN(ZLAMS)*COS(ZPHIS) |
| IF (ABS(ZARG2).LT.1.E-30) THEN |
| IF (ABS(ZARG1).LT.1.E-30) THEN |
| LMSTOLM = 0.0 |
| ELSEIF (ZARG1.GT.0.) THEN |
| LMSTOLAM = 90.0 |
| ELSE |
| LMSTOLAM = -90.0 |
| ENDIF |
| ELSE |
| LMSTOLM = ZRPI18*ATAN2(ZARG1,ZARG2) |
| ENDIF |
| RETURN |
| END |
| /trunk/lib/libipo.f |
|---|
| 0,0 → 1,1368 |
| real function int2d(ar,n1,n2,rid,rjd) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This subroutine interpolates a 2d-array to an arbitrary |
| c location within the grid. |
| c Arguments: |
| c ar real input surface pressure, define as ar(n1,n2) |
| c n1,n2 int input dimensions of ar |
| c ri,rj real input grid location to be interpolated to |
| c History: |
| c----------------------------------------------------------------------- |
| c argument declarations |
| integer n1,n2 |
| real ar(n1,n2), rid,rjd |
| c local declarations |
| integer i,j,ip1,jp1,ih,jh |
| real frac0i,frac0j,frac1i,frac1j,ri,rj |
| c do linear interpolation |
| ri=amax1(1.,amin1(float(n1),rid)) |
| rj=amax1(1.,amin1(float(n2),rjd)) |
| ih=nint(ri) |
| jh=nint(rj) |
| c Check for interpolation in i |
| * if (abs(float(ih)-ri).lt.1.e-3) then |
| * i =ih |
| * ip1=ih |
| * else |
| i =min0(int(ri),n1-1) |
| ip1=i+1 |
| * endif |
| c Check for interpolation in j |
| * if (abs(float(jh)-rj).lt.1.e-3) then |
| * j =jh |
| * jp1=jh |
| * else |
| j =min0(int(rj),n2-1) |
| jp1=j+1 |
| * endif |
| if ((i.eq.ip1).and.(j.eq.jp1)) then |
| c no interpolation at all |
| int2d=ar(i,j) |
| else |
| frac0i=ri-float(i) |
| frac0j=rj-float(j) |
| frac1i=1.-frac0i |
| frac1j=1.-frac0j |
| int2d = ar(i ,j ) * frac1i * frac1j |
| & + ar(i ,jp1) * frac1i * frac0j |
| & + ar(ip1,j ) * frac0i * frac1j |
| & + ar(ip1,jp1) * frac0i * frac0j |
| endif |
| end |
| real function int2dm(ar,n1,n2,rid,rjd,misdat) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This subroutine interpolates a 2d-array to an arbitrary |
| c location within the grid. The interpolation includes the |
| c testing of the missing data flag 'misdat'. |
| c Arguments: |
| c ar real input surface pressure, define as ar(n1,n2) |
| c n1,n2 int input dimensions of ar |
| c ri,rj real input grid location to be interpolated to |
| c misdat real input missing data flag (on if misdat<>0) |
| c Warning: |
| c This routine has not yet been seriously tested |
| c History: |
| c----------------------------------------------------------------------- |
| c argument declarations |
| integer n1,n2 |
| real ar(n1,n2), rid,rjd, misdat |
| c local declarations |
| integer i,j,ip1,jp1,ih,jh |
| real frac0i,frac0j,frac1i,frac1j,ri,rj,int2d |
| c check if routine without missing data checking can be called instead |
| if (misdat.eq.0.) then |
| int2dm=int2d(ar,n1,n2,rid,rjd) |
| return |
| endif |
| c do linear interpolation |
| ri=amax1(1.,amin1(float(n1),rid)) |
| rj=amax1(1.,amin1(float(n2),rjd)) |
| ih=nint(ri) |
| jh=nint(rj) |
| c Check for interpolation in i |
| * if (abs(float(ih)-ri).lt.1.e-3) then |
| * i =ih |
| * ip1=ih |
| * else |
| i =min0(int(ri),n1-1) |
| ip1=i+1 |
| * endif |
| c Check for interpolation in j |
| * if (abs(float(jh)-rj).lt.1.e-3) then |
| * j =jh |
| * jp1=jh |
| * else |
| j =min0(int(rj),n2-1) |
| jp1=j+1 |
| * endif |
| if ((i.eq.ip1).and.(j.eq.jp1)) then |
| c no interpolation at all |
| int2dm=ar(i,j) |
| else |
| if ((misdat.eq.ar(i ,j )).or. |
| & (misdat.eq.ar(i ,jp1)).or. |
| & (misdat.eq.ar(ip1,j )).or. |
| & (misdat.eq.ar(ip1,jp1))) then |
| int2dm=misdat |
| else |
| frac0i=ri-float(i) |
| frac0j=rj-float(j) |
| frac1i=1.-frac0i |
| frac1j=1.-frac0j |
| int2dm = ar(i ,j ) * frac1i * frac1j |
| & + ar(i ,jp1) * frac1i * frac0j |
| & + ar(ip1,j ) * frac0i * frac1j |
| & + ar(ip1,jp1) * frac0i * frac0j |
| endif |
| endif |
| end |
| real function int2dp(ar,n1,n2,rid,rjd) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This subroutine interpolates a 2d-array to an arbitrary |
| c location within the grid. The 2d-array is periodic in the |
| c i-direction: ar(0,.)=ar(n1,.) and ar(1,.)=ar(n1+1,.). |
| c Therefore rid can take values in the range 0,...,n1+1 |
| c Arguments: |
| c ar real input surface pressure, define as ar(n1,n2) |
| c n1,n2 int input dimensions of ar |
| c ri,rj real input grid location to be interpolated to |
| c History: |
| c----------------------------------------------------------------------- |
| c argument declarations |
| integer n1,n2 |
| real ar(0:n1+1,n2), rid,rjd |
| c local declarations |
| integer i,j,ip1,jp1,ih,jh |
| real frac0i,frac0j,frac1i,frac1j,ri,rj |
| c do linear interpolation |
| ri=amax1(0.,amin1(float(n1+1),rid)) |
| rj=amax1(1.,amin1(float(n2),rjd)) |
| ih=nint(ri) |
| jh=nint(rj) |
| c Check for interpolation in i |
| * if (abs(float(ih)-ri).lt.1.e-5) then |
| * i =ih |
| * ip1=ih |
| * else |
| i =min0(int(ri),n1-1) |
| ip1=i+1 |
| * endif |
| c Check for interpolation in j |
| * if (abs(float(jh)-rj).lt.1.e-5) then |
| * j =jh |
| * jp1=jh |
| * else |
| j =min0(int(rj),n2-1) |
| jp1=j+1 |
| * endif |
| if ((i.eq.ip1).and.(j.eq.jp1)) then |
| c no interpolation at all |
| int2dp=ar(i,j) |
| else |
| frac0i=ri-float(i) |
| frac0j=rj-float(j) |
| frac1i=1.-frac0i |
| frac1j=1.-frac0j |
| int2dp = ar(i ,j ) * frac1i * frac1j |
| & + ar(i ,jp1) * frac1i * frac0j |
| & + ar(ip1,j ) * frac0i * frac1j |
| & + ar(ip1,jp1) * frac0i * frac0j |
| endif |
| end |
| real function cint2d(ar,n1,n2,n3,rid,rjd,ikd) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This subroutine interpolates a 3d-array to an arbitrary |
| c location in the horizontal. ikd specifies the level (must |
| c be an integer). A bicubic method is applied (following |
| c the Numerical Recipes). |
| c Arguments: |
| c ar real input field, define as ar(n1,n2,n3) |
| c n1,n2 int input dimensions of ar |
| c rid,rjd real input grid location to be interpolated to |
| c ikd int input level for interpolation |
| c History: |
| c----------------------------------------------------------------------- |
| c argument declarations |
| integer n1,n2,n3,ikd |
| real ar(n1,n2,n3), rid,rjd |
| c local declarations |
| integer i,j,k |
| real y(4),y1(4),y2(4),y12(4) |
| c indices of lower left corner of interpolation grid |
| i=int(rid) |
| j=int(rjd) |
| k=ikd |
| c do not interpolate if i or j are at the boundaries |
| if ((i.eq.1).or.(j.eq.1).or.(i.eq.n1).or.(j.eq.n2)) then |
| cint2d=ar(i,j,k) |
| return |
| endif |
| c define the arrays y,y1,y2,y12 necessary for the bicubic |
| c interpolation (following the Numerical Recipes). |
| y(1)=ar(i,j,k) |
| y(2)=ar(i+1,j,k) |
| y(3)=ar(i+1,j+1,k) |
| y(4)=ar(i,j+1,k) |
| y1(1)=-(ar(i-1,j,k)-ar(i+1,j,k))/2. |
| y1(2)=-(ar(i,j,k)-ar(i+2,j,k))/2. |
| y1(3)=-(ar(i,j+1,k)-ar(i+2,j+1,k))/2. |
| y1(4)=-(ar(i-1,j+1,k)-ar(i+1,j+1,k))/2. |
| y2(1)=-(ar(i,j-1,k)-ar(i,j+1,k))/2. |
| y2(2)=-(ar(i+1,j-1,k)-ar(i+1,j+1,k))/2. |
| y2(3)=-(ar(i+1,j,k)-ar(i+1,j+2,k))/2. |
| y2(4)=-(ar(i,j,k)-ar(i,j+2,k))/2. |
| y12(1)=(ar(i+1,j+1,k)-ar(i+1,j-1,k)-ar(i-1,j+1,k)+ar(i-1,j-1,k))/4. |
| y12(2)=(ar(i+2,j+1,k)-ar(i+2,j-1,k)-ar(i,j+1,k)+ar(i,j-1,k))/4. |
| y12(3)=(ar(i+2,j+2,k)-ar(i+2,j,k)-ar(i,j+2,k)+ar(i,j,k))/4. |
| y12(4)=(ar(i+1,j+2,k)-ar(i+1,j,k)-ar(i-1,j+2,k)+ar(i-1,j,k))/4. |
| call bcuint(y,y1,y2,y12,i,j,rid,rjd,cint2d) |
| return |
| end |
| real function int3d(ar,n1,n2,n3,rid,rjd,rkd) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This subroutine interpolates a 3d-array to an arbitrary |
| c location within the grid. |
| c Arguments: |
| c ar real input surface pressure, define as ar(n1,n2,n3) |
| c n1,n2,n3 int input dimensions of ar |
| c ri,rj,rk real input grid location to be interpolated to |
| c History: |
| c----------------------------------------------------------------------- |
| c argument declarations |
| integer n1,n2,n3 |
| real ar(n1,n2,n3), rid,rjd,rkd |
| c local declarations |
| integer i,j,k,ip1,jp1,kp1,ih,jh,kh |
| real frac0i,frac0j,frac0k,frac1i,frac1j,frac1k,ri,rj,rk |
| c do linear interpolation |
| ri=amax1(1.,amin1(float(n1),rid)) |
| rj=amax1(1.,amin1(float(n2),rjd)) |
| rk=amax1(1.,amin1(float(n3),rkd)) |
| ih=nint(ri) |
| jh=nint(rj) |
| kh=nint(rk) |
| c Check for interpolation in i |
| * if (abs(float(ih)-ri).lt.1.e-3) then |
| * i =ih |
| * ip1=ih |
| * else |
| i =min0(int(ri),n1-1) |
| ip1=i+1 |
| * endif |
| c Check for interpolation in j |
| if (abs(float(jh)-rj).lt.1.e-3) then |
| j =jh |
| jp1=jh |
| else |
| j =min0(int(rj),n2-1) |
| jp1=j+1 |
| endif |
| c Check for interpolation in k |
| * if (abs(float(kh)-rk).lt.1.e-3) then |
| * k =kh |
| * kp1=kh |
| * else |
| k =min0(int(rk),n3-1) |
| kp1=k+1 |
| * endif |
| if (k.eq.kp1) then |
| c no interpolation in k |
| if ((i.eq.ip1).and.(j.eq.jp1)) then |
| c no interpolation at all |
| int3d=ar(i,j,k) |
| c print *,'int3d 00: ',rid,rjd,rkd,int3d |
| else |
| c horizontal interpolation only |
| frac0i=ri-float(i) |
| frac0j=rj-float(j) |
| frac1i=1.-frac0i |
| frac1j=1.-frac0j |
| int3d = ar(i ,j ,k ) * frac1i * frac1j |
| & + ar(i ,jp1,k ) * frac1i * frac0j |
| & + ar(ip1,j ,k ) * frac0i * frac1j |
| & + ar(ip1,jp1,k ) * frac0i * frac0j |
| c print *,'int3d 10: ',rid,rjd,rkd,int3d |
| endif |
| else |
| frac0k=rk-float(k) |
| frac1k=1.-frac0k |
| if ((i.eq.ip1).and.(j.eq.jp1)) then |
| c vertical interpolation only |
| int3d = ar(i ,j ,k ) * frac1k |
| & + ar(i ,j ,kp1) * frac0k |
| c print *,'int3d 01: ',rid,rjd,rkd,int3d |
| else |
| c full 3d interpolation |
| frac0i=ri-float(i) |
| frac0j=rj-float(j) |
| frac1i=1.-frac0i |
| frac1j=1.-frac0j |
| int3d = ar(i ,j ,k ) * frac1i * frac1j * frac1k |
| & + ar(i ,jp1,k ) * frac1i * frac0j * frac1k |
| & + ar(ip1,j ,k ) * frac0i * frac1j * frac1k |
| & + ar(ip1,jp1,k ) * frac0i * frac0j * frac1k |
| & + ar(i ,j ,kp1) * frac1i * frac1j * frac0k |
| & + ar(i ,jp1,kp1) * frac1i * frac0j * frac0k |
| & + ar(ip1,j ,kp1) * frac0i * frac1j * frac0k |
| & + ar(ip1,jp1,kp1) * frac0i * frac0j * frac0k |
| c print *,'int3d 11: ',rid,rjd,rkd,int3d |
| endif |
| endif |
| end |
| real function int3dm(ar,n1,n2,n3,rid,rjd,rkd,misdat) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This subroutine interpolates a 3d-array to an arbitrary |
| c location within the grid. The interpolation includes the |
| c testing of the missing data flag 'misdat'. |
| c Arguments: |
| c ar real input surface pressure, define as ar(n1,n2,n3) |
| c n1,n2,n3 int input dimensions of ar |
| c ri,rj,rk real input grid location to be interpolated to |
| c misdat real input missing data flag (on if misdat<>0) |
| c Warning: |
| c This routine has not yet been seriously tested |
| c History: |
| c----------------------------------------------------------------------- |
| c argument declarations |
| integer n1,n2,n3 |
| real ar(n1,n2,n3), rid,rjd,rkd, misdat |
| c local declarations |
| integer i,j,k,ip1,jp1,kp1,ih,jh,kh |
| real frac0i,frac0j,frac0k,frac1i,frac1j,frac1k,ri,rj,rk,int3d |
| c check if routine without missing data checking can be called instead |
| if (misdat.eq.0.) then |
| int3dm=int3d(ar,n1,n2,n3,rid,rjd,rkd) |
| return |
| endif |
| c do linear interpolation |
| ri=amax1(1.,amin1(float(n1),rid)) |
| rj=amax1(1.,amin1(float(n2),rjd)) |
| rk=amax1(1.,amin1(float(n3),rkd)) |
| ih=nint(ri) |
| jh=nint(rj) |
| kh=nint(rk) |
| c Check for interpolation in i |
| * if (abs(float(ih)-ri).lt.1.e-3) then |
| * i =ih |
| * ip1=ih |
| * else |
| i =min0(int(ri),n1-1) |
| ip1=i+1 |
| * endif |
| c Check for interpolation in j |
| * if (abs(float(jh)-rj).lt.1.e-3) then |
| * j =jh |
| * jp1=jh |
| * else |
| j =min0(int(rj),n2-1) |
| jp1=j+1 |
| * endif |
| c Check for interpolation in k |
| * if (abs(float(kh)-rk).lt.1.e-3) then |
| * k =kh |
| * kp1=kh |
| * else |
| k =min0(int(rk),n3-1) |
| kp1=k+1 |
| * endif |
| if (k.eq.kp1) then |
| c no interpolation in k |
| if ((i.eq.ip1).and.(j.eq.jp1)) then |
| c no interpolation at all |
| if (misdat.eq.ar(i,j,k)) then |
| int3dm=misdat |
| else |
| int3dm=ar(i,j,k) |
| endif |
| c print *,'int3dm 00: ',rid,rjd,rkd,int3dm |
| else |
| c horizontal interpolation only |
| if ((misdat.eq.ar(i ,j ,k )).or. |
| & (misdat.eq.ar(i ,jp1,k )).or. |
| & (misdat.eq.ar(ip1,j ,k )).or. |
| & (misdat.eq.ar(ip1,jp1,k ))) then |
| int3dm=misdat |
| else |
| frac0i=ri-float(i) |
| frac0j=rj-float(j) |
| frac1i=1.-frac0i |
| frac1j=1.-frac0j |
| int3dm = ar(i ,j ,k ) * frac1i * frac1j |
| & + ar(i ,jp1,k ) * frac1i * frac0j |
| & + ar(ip1,j ,k ) * frac0i * frac1j |
| & + ar(ip1,jp1,k ) * frac0i * frac0j |
| c print *,'int3dm 10: ',rid,rjd,rkd,int3dm |
| endif |
| endif |
| else |
| frac0k=rk-float(k) |
| frac1k=1.-frac0k |
| if ((i.eq.ip1).and.(j.eq.jp1)) then |
| c vertical interpolation only |
| if ((misdat.eq.ar(i ,j ,k )).or. |
| & (misdat.eq.ar(i ,j ,kp1))) then |
| int3dm=misdat |
| else |
| int3dm = ar(i ,j ,k ) * frac1k |
| & + ar(i ,j ,kp1) * frac0k |
| c print *,'int3dm 01: ',rid,rjd,rkd,int3dm |
| endif |
| else |
| c full 3d interpolation |
| if ((misdat.eq.ar(i ,j ,k )).or. |
| & (misdat.eq.ar(i ,jp1,k )).or. |
| & (misdat.eq.ar(ip1,j ,k )).or. |
| & (misdat.eq.ar(ip1,jp1,k )).or. |
| & (misdat.eq.ar(i ,j ,kp1)).or. |
| & (misdat.eq.ar(i ,jp1,kp1)).or. |
| & (misdat.eq.ar(ip1,j ,kp1)).or. |
| & (misdat.eq.ar(ip1,jp1,kp1))) then |
| int3dm=misdat |
| else |
| frac0i=ri-float(i) |
| frac0j=rj-float(j) |
| frac1i=1.-frac0i |
| frac1j=1.-frac0j |
| int3dm = ar(i ,j ,k ) * frac1i * frac1j * frac1k |
| & + ar(i ,jp1,k ) * frac1i * frac0j * frac1k |
| & + ar(ip1,j ,k ) * frac0i * frac1j * frac1k |
| & + ar(ip1,jp1,k ) * frac0i * frac0j * frac1k |
| & + ar(i ,j ,kp1) * frac1i * frac1j * frac0k |
| & + ar(i ,jp1,kp1) * frac1i * frac0j * frac0k |
| & + ar(ip1,j ,kp1) * frac0i * frac1j * frac0k |
| & + ar(ip1,jp1,kp1) * frac0i * frac0j * frac0k |
| c print *,'int3dm 11: ',rid,rjd,rkd,int3dm |
| endif |
| endif |
| endif |
| end |
| real function int3dmlog(ar,n1,n2,n3,rid,rjd,rkd,misdat) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This subroutine interpolates a 3d-array to an arbitrary |
| c location within the grid. The interpolation includes the |
| c testing of the missing data flag 'misdat'. |
| c Prior to vertical interpolations the log is taken from the array. |
| c Arguments: |
| c ar real input surface pressure, define as ar(n1,n2,n3) |
| c n1,n2,n3 int input dimensions of ar |
| c ri,rj,rk real input grid location to be interpolated to |
| c misdat real input missing data flag (on if misdat<>0) |
| c Warning: |
| c This routine has not yet been seriously tested |
| c History: |
| c----------------------------------------------------------------------- |
| c argument declarations |
| integer n1,n2,n3 |
| real ar(n1,n2,n3), rid,rjd,rkd, misdat |
| c local declarations |
| integer i,j,k,ip1,jp1,kp1,ih,jh,kh |
| real frac0i,frac0j,frac0k,frac1i,frac1j,frac1k,ri,rj,rk,int3d |
| c print*,'hallo in SR int3dmlog' |
| c check if routine without missing data checking can be called instead |
| if (misdat.eq.0.) then |
| int3dmlog=int3d(ar,n1,n2,n3,rid,rjd,rkd) |
| return |
| endif |
| c do linear interpolation |
| ri=amax1(1.,amin1(float(n1),rid)) |
| rj=amax1(1.,amin1(float(n2),rjd)) |
| rk=amax1(1.,amin1(float(n3),rkd)) |
| ih=nint(ri) |
| jh=nint(rj) |
| kh=nint(rk) |
| c Check for interpolation in i |
| * if (abs(float(ih)-ri).lt.1.e-3) then |
| * i =ih |
| * ip1=ih |
| * else |
| i =min0(int(ri),n1-1) |
| ip1=i+1 |
| * endif |
| c Check for interpolation in j |
| * if (abs(float(jh)-rj).lt.1.e-3) then |
| * j =jh |
| * jp1=jh |
| * else |
| j =min0(int(rj),n2-1) |
| jp1=j+1 |
| * endif |
| c Check for interpolation in k |
| * if (abs(float(kh)-rk).lt.1.e-3) then |
| * k =kh |
| * kp1=kh |
| * else |
| k =min0(int(rk),n3-1) |
| kp1=k+1 |
| * endif |
| if (k.eq.kp1) then |
| c no interpolation in k |
| if ((i.eq.ip1).and.(j.eq.jp1)) then |
| c no interpolation at all |
| if (misdat.eq.ar(i,j,k)) then |
| int3dmlog=misdat |
| else |
| int3dmlog=ar(i,j,k) |
| endif |
| c print *,'int3dmlog 00: ',rid,rjd,rkd,int3dmlog |
| else |
| c horizontal interpolation only |
| if ((misdat.eq.ar(i ,j ,k )).or. |
| & (misdat.eq.ar(i ,jp1,k )).or. |
| & (misdat.eq.ar(ip1,j ,k )).or. |
| & (misdat.eq.ar(ip1,jp1,k ))) then |
| int3dmlog=misdat |
| else |
| frac0i=ri-float(i) |
| frac0j=rj-float(j) |
| frac1i=1.-frac0i |
| frac1j=1.-frac0j |
| int3dmlog = ar(i ,j ,k ) * frac1i * frac1j |
| & + ar(i ,jp1,k ) * frac1i * frac0j |
| & + ar(ip1,j ,k ) * frac0i * frac1j |
| & + ar(ip1,jp1,k ) * frac0i * frac0j |
| c print *,'int3dmlog 10: ',rid,rjd,rkd,int3dmlog |
| endif |
| endif |
| else |
| frac0k=rk-float(k) |
| frac1k=1.-frac0k |
| if ((i.eq.ip1).and.(j.eq.jp1)) then |
| c vertical interpolation only |
| if ((misdat.eq.ar(i ,j ,k )).or. |
| & (misdat.eq.ar(i ,j ,kp1))) then |
| int3dmlog=misdat |
| else |
| int3dmlog = log(ar(i ,j ,k )) * frac1k |
| & + log(ar(i ,j ,kp1)) * frac0k |
| int3dmlog = exp(int3dmlog) |
| c print *,'int3dmlog 01: ',rid,rjd,rkd,int3dmlog |
| endif |
| else |
| c full 3d interpolation |
| if ((misdat.eq.ar(i ,j ,k )).or. |
| & (misdat.eq.ar(i ,jp1,k )).or. |
| & (misdat.eq.ar(ip1,j ,k )).or. |
| & (misdat.eq.ar(ip1,jp1,k )).or. |
| & (misdat.eq.ar(i ,j ,kp1)).or. |
| & (misdat.eq.ar(i ,jp1,kp1)).or. |
| & (misdat.eq.ar(ip1,j ,kp1)).or. |
| & (misdat.eq.ar(ip1,jp1,kp1))) then |
| int3dmlog=misdat |
| else |
| frac0i=ri-float(i) |
| frac0j=rj-float(j) |
| frac1i=1.-frac0i |
| frac1j=1.-frac0j |
| int3dmlog = log(ar(i ,j ,k )) * frac1i * frac1j * frac1k |
| & + log(ar(i ,jp1,k )) * frac1i * frac0j * frac1k |
| & + log(ar(ip1,j ,k )) * frac0i * frac1j * frac1k |
| & + log(ar(ip1,jp1,k )) * frac0i * frac0j * frac1k |
| & + log(ar(i ,j ,kp1)) * frac1i * frac1j * frac0k |
| & + log(ar(i ,jp1,kp1)) * frac1i * frac0j * frac0k |
| & + log(ar(ip1,j ,kp1)) * frac0i * frac1j * frac0k |
| & + log(ar(ip1,jp1,kp1)) * frac0i * frac0j * frac0k |
| int3dmlog = exp(int3dmlog) |
| c print *,'int3dmlog 11: ',rid,rjd,rkd,int3dmlog |
| endif |
| endif |
| endif |
| end |
| real function int3dmvc(ar,n1,n2,n3,rid,rjd,rkd,misdat) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This subroutine interpolates a 3d-array to an arbitrary |
| c location within the grid. The interpolation includes the |
| c testing of the missing data flag 'misdat'. |
| c In the vertical a Lagrangian cubic interpolation is |
| c performed. |
| c Arguments: |
| c ar real input surface pressure, define as ar(n1,n2,n3) |
| c n1,n2,n3 int input dimensions of ar |
| c ri,rj,rk real input grid location to be interpolated to |
| c misdat real input missing data flag (on if misdat<>0) |
| c Warning: |
| c This routine has not yet been seriously tested |
| c History: |
| c----------------------------------------------------------------------- |
| c argument declarations |
| integer n1,n2,n3 |
| real ar(n1,n2,n3), rid,rjd,rkd, misdat |
| c local declarations |
| integer i,j,k,ip1,jp1,kp1,ih,jh,kh,klow,n |
| real frac0i,frac0j,frac1i,frac1j,ri,rj,rk |
| real int2d(4) |
| real int3dm |
| c if n3 < 4 then do call linear interpolation in the vertical |
| if (n3.lt.4) then |
| int3dmvc=int3dm(ar,n1,n2,n3,rid,rjd,rkd,misdat) |
| return |
| endif |
| c do linear interpolation in the horizontal |
| ri=amax1(1.,amin1(float(n1),rid)) |
| rj=amax1(1.,amin1(float(n2),rjd)) |
| rk=amax1(1.,amin1(float(n3),rkd)) |
| ih=nint(ri) |
| jh=nint(rj) |
| kh=nint(rk) |
| c Check for interpolation in i |
| * if (abs(float(ih)-ri).lt.1.e-3) then |
| * i =ih |
| * ip1=ih |
| * else |
| i =min0(int(ri),n1-1) |
| ip1=i+1 |
| * endif |
| c Check for interpolation in j |
| * if (abs(float(jh)-rj).lt.1.e-3) then |
| * j =jh |
| * jp1=jh |
| * else |
| j =min0(int(rj),n2-1) |
| jp1=j+1 |
| * endif |
| c Check for interpolation in k |
| * if (abs(float(kh)-rk).lt.1.e-3) then |
| * k =kh |
| * kp1=kh |
| * else |
| k =min0(int(rk),n3-1) |
| kp1=k+1 |
| * endif |
| if (k.eq.kp1) then |
| c no interpolation in k |
| if ((i.eq.ip1).and.(j.eq.jp1)) then |
| c no interpolation at all |
| int3dmvc=ar(i,j,k) |
| c print *,'int3dmvc 00: ',rid,rjd,rkd,int3dmvc |
| else |
| c horizontal interpolation only |
| if ((misdat.eq.ar(i ,j ,k )).or. |
| & (misdat.eq.ar(i ,jp1,k )).or. |
| & (misdat.eq.ar(ip1,j ,k )).or. |
| & (misdat.eq.ar(ip1,jp1,k ))) then |
| int3dmvc=misdat |
| else |
| frac0i=ri-float(i) |
| frac0j=rj-float(j) |
| frac1i=1.-frac0i |
| frac1j=1.-frac0j |
| int3dmvc = ar(i ,j ,k ) * frac1i * frac1j |
| & + ar(i ,jp1,k ) * frac1i * frac0j |
| & + ar(ip1,j ,k ) * frac0i * frac1j |
| & + ar(ip1,jp1,k ) * frac0i * frac0j |
| c print *,'int3dmvc 10: ',rid,rjd,rkd,int3dmvc |
| endif |
| endif |
| else |
| if ((i.eq.ip1).and.(j.eq.jp1)) then |
| c vertical interpolation only |
| if ((misdat.eq.ar(i ,j ,k )).or. |
| & (misdat.eq.ar(i ,j ,kp1))) then |
| int3dmvc=misdat |
| else |
| if (k-1.lt.1) then |
| klow=1 |
| else if (k+2.gt.n3) then |
| klow=n3-3 |
| else |
| klow=k-1 |
| endif |
| call cubint(ar(i,j,klow),ar(i,j,klow+1),ar(i,j,klow+2), |
| & ar(i,j,klow+3),klow,rk,int3dmvc) |
| endif |
| else |
| c full 3d interpolation |
| if ((misdat.eq.ar(i ,j ,k )).or. |
| & (misdat.eq.ar(i ,jp1,k )).or. |
| & (misdat.eq.ar(ip1,j ,k )).or. |
| & (misdat.eq.ar(ip1,jp1,k )).or. |
| & (misdat.eq.ar(i ,j ,kp1)).or. |
| & (misdat.eq.ar(i ,jp1,kp1)).or. |
| & (misdat.eq.ar(ip1,j ,kp1)).or. |
| & (misdat.eq.ar(ip1,jp1,kp1))) then |
| int3dmvc=misdat |
| else |
| frac0i=ri-float(i) |
| frac0j=rj-float(j) |
| frac1i=1.-frac0i |
| frac1j=1.-frac0j |
| if (k-1.lt.1) then |
| klow=1 |
| else if (k+2.gt.n3) then |
| klow=n3-3 |
| else |
| klow=k-1 |
| endif |
| do n=1,4 |
| int2d(n) = ar(i ,j ,klow-1+n ) * frac1i * frac1j |
| & + ar(i ,jp1,klow-1+n ) * frac1i * frac0j |
| & + ar(ip1,j ,klow-1+n ) * frac0i * frac1j |
| & + ar(ip1,jp1,klow-1+n ) * frac0i * frac0j |
| enddo |
| call cubint(int2d(1),int2d(2),int2d(3),int2d(4), |
| & klow,rk,int3dmvc) |
| endif |
| endif |
| endif |
| end |
| real function int4d(ar,n1,n2,n3,n4,rid,rjd,rkd,rld) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This subroutine interpolates a 4d-array to an arbitrary |
| c location within the grid. |
| c Arguments: |
| c ar real input surface pressure, define as ar(n1,n2,n3) |
| c n1,..,n4 int input dimensions of ar |
| c ri,..,rl real input grid location to be interpolated to |
| c History: |
| c----------------------------------------------------------------------- |
| c argument declarations |
| integer n1,n2,n3,n4 |
| real ar(n1,n2,n3,n4), rid,rjd,rkd,rld |
| c local declarations |
| integer l,lp1,lh |
| real frac0l,frac1l,rl,int3d |
| c do linear interpolation in l-direction |
| rl=amax1(1.,amin1(float(n4),rld)) |
| lh=nint(rl) |
| c Check for interpolation in l |
| * if (abs(float(lh)-rl).lt.1.e-3) then |
| * l =lh |
| * lp1=lh |
| * else |
| l =min0(int(rl),n4-1) |
| lp1=l+1 |
| * endif |
| if (l.eq.lp1) then |
| c no interpolation in l |
| int4d=int3d(ar(1,1,1,l),n1,n2,n3,rid,rjd,rkd) |
| else |
| c interpolation in l |
| frac0l=rl-float(l) |
| frac1l=1.-frac0l |
| int4d = int3d(ar(1,1,1,l ),n1,n2,n3,rid,rjd,rkd) * frac1l |
| & + int3d(ar(1,1,1,lp1),n1,n2,n3,rid,rjd,rkd) * frac0l |
| endif |
| end |
| real function int4dm(ar,n1,n2,n3,n4,rid,rjd,rkd,rld,misdat) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This subroutine interpolates a 4d-array to an arbitrary |
| c location within the grid. The interpolation includes the |
| c testing of the missing data flag 'misdat'. |
| c Arguments: |
| c ar real input surface pressure, define as ar(n1,n2,n3) |
| c n1,..,n4 int input dimensions of ar |
| c ri,..,rl real input grid location to be interpolated to |
| c misdat real input missing data flag (on if misdat<>0) |
| c Warning: |
| c This routine has not yet been seriously tested. |
| c History: |
| c----------------------------------------------------------------------- |
| c argument declarations |
| integer n1,n2,n3,n4 |
| real ar(n1,n2,n3,n4), rid,rjd,rkd,rld, misdat |
| c local declarations |
| integer l,lp1,lh |
| real frac0l,frac1l,rl,rint0,rint1,int4d,int3dm |
| c check whether missing data checking is required |
| if (misdat.eq.0.) then |
| int4dm=int4d(ar,n1,n2,n3,n4,rid,rjd,rkd,rld) |
| return |
| endif |
| c do linear interpolation in l-direction |
| rl=amax1(1.,amin1(float(n4),rld)) |
| lh=nint(rl) |
| c Check for interpolation in l |
| * if (abs(float(lh)-rl).lt.1.e-3) then |
| * l =lh |
| * lp1=lh |
| * else |
| l =min0(int(rl),n4-1) |
| lp1=l+1 |
| * endif |
| if (l.eq.lp1) then |
| c no interpolation in l |
| int4dm = int3dm(ar(1,1,1,l),n1,n2,n3,rid,rjd,rkd,misdat) |
| else |
| c interpolation in l |
| frac0l=rl-float(l) |
| frac1l=1.-frac0l |
| rint0 = int3dm(ar(1,1,1,l ),n1,n2,n3,rid,rjd,rkd,misdat) |
| rint1 = int3dm(ar(1,1,1,lp1),n1,n2,n3,rid,rjd,rkd,misdat) |
| if ((rint0.eq.misdat).or.(rint1.eq.misdat)) then |
| int4dm = misdat |
| else |
| int4dm = rint0*frac1l + rint1*frac0l |
| endif |
| endif |
| end |
| real function int3dl(ar,n1,n2,n3,levels,rid,rjd,rkd) |
| c----------------------------------------------------------------------- |
| c Purpose: |
| c This subroutine interpolates a 3d-array to an arbitrary |
| c location within the grid. The vertical interpolation is linear |
| c in log(pressure). |
| c Arguments: |
| c ar real input surface pressure, define as ar(n1,n2,n3) |
| c n1,n2,n3 int input dimensions of ar |
| c levels real input array contains pressure levels for ar |
| c ri,rj,rk real input grid location to be interpolated to |
| c History: |
| c Based on int3d July 93 |
| c----------------------------------------------------------------------- |
| c argument declarations |
| integer n1,n2,n3 |
| real ar(n1,n2,n3), rid,rjd,rkd |
| real levels(n3) |
| c local declarations |
| real pval |
| integer i,j,k,ip1,jp1,kp1,ih,jh,kh |
| real frac0i,frac0j,frac0k,frac1i,frac1j,frac1k,ri,rj,rk |
| c do linear interpolation |
| ri=amax1(1.,amin1(float(n1),rid)) |
| rj=amax1(1.,amin1(float(n2),rjd)) |
| rk=amax1(1.,amin1(float(n3),rkd)) |
| ih=nint(ri) |
| jh=nint(rj) |
| kh=nint(rk) |
| c Check for interpolation in i |
| * if (abs(float(ih)-ri).lt.1.e-3) then |
| * i =ih |
| * ip1=ih |
| * else |
| i =min0(int(ri),n1-1) |
| ip1=i+1 |
| * endif |
| c Check for interpolation in j |
| * if (abs(float(jh)-rj).lt.1.e-3) then |
| * j =jh |
| * jp1=jh |
| * else |
| j =min0(int(rj),n2-1) |
| jp1=j+1 |
| * endif |
| c Check for interpolation in k |
| * if (abs(float(kh)-rk).lt.1.e-3) then |
| * k =kh |
| * kp1=kh |
| * else |
| k =min0(int(rk),n3-1) |
| kp1=k+1 |
| * endif |
| if (k.eq.kp1) then |
| c no interpolation in k |
| if ((i.eq.ip1).and.(j.eq.jp1)) then |
| c no interpolation at all |
| int3dl=ar(i,j,k) |
| c print *,'int3dl 00: ',rid,rjd,rkd,int3dl |
| else |
| c horizontal interpolation only |
| frac0i=ri-float(i) |
| frac0j=rj-float(j) |
| frac1i=1.-frac0i |
| frac1j=1.-frac0j |
| int3dl = ar(i ,j ,k ) * frac1i * frac1j |
| & + ar(i ,jp1,k ) * frac1i * frac0j |
| & + ar(ip1,j ,k ) * frac0i * frac1j |
| & + ar(ip1,jp1,k ) * frac0i * frac0j |
| c print *,'int3dl 10: ',rid,rjd,rkd,int3dl |
| endif |
| else |
| * frac0k=rk-float(k) |
| c calculate the pressure value to be interpolated to |
| pval=levels(int(rk)) |
| > -(rk-aint(rk))*(levels(int(rk))-levels(int(rk)+1)) |
| frac0k=log(levels(int(rk))/pval) |
| & /log(levels(int(rk))/levels(int(rk)+1)) |
| frac1k=1.-frac0k |
| if ((i.eq.ip1).and.(j.eq.jp1)) then |
| c vertical interpolation only |
| int3dl = ar(i ,j ,k ) * frac1k |
| & + ar(i ,j ,kp1) * frac0k |
| c print *,'int3dl 01: ',rid,rjd,rkd,int3dl |
| else |
| c full 3d interpolation |
| frac0i=ri-float(i) |
| frac0j=rj-float(j) |
| frac1i=1.-frac0i |
| frac1j=1.-frac0j |
| int3dl = ar(i ,j ,k ) * frac1i * frac1j * frac1k |
| & + ar(i ,jp1,k ) * frac1i * frac0j * frac1k |
| & + ar(ip1,j ,k ) * frac0i * frac1j * frac1k |
| & + ar(ip1,jp1,k ) * frac0i * frac0j * frac1k |
| & + ar(i ,j ,kp1) * frac1i * frac1j * frac0k |
| & + ar(i ,jp1,kp1) * frac1i * frac0j * frac0k |
| & + ar(ip1,j ,kp1) * frac0i * frac1j * frac0k |
| & + ar(ip1,jp1,kp1) * frac0i * frac0j * frac0k |
| c print *,'int3dl 11: ',rid,rjd,rkd,int3dl |
| endif |
| endif |
| end |
| subroutine bcucof(y,y1,y2,y12,c) |
| c----------------------------------------------------------------------- |
| c Given arrays y,y1,y2 and y12, each of length 4, containing the |
| c function, gradients, and cross derivative at the four grid points |
| c of a rectangular grid cell (numbered counterclockwise from the |
| c lower left), and given d1 and d2, the length of the grid cell in |
| c the 1- and 2-directions, this routine returns the table c that is |
| c used by routine bcuint for biqubic interpolation. |
| c Source: Numerical Recipes, Fortran Version, p.99 |
| c----------------------------------------------------------------------- |
| real c(4,4),y(4),y1(4),y2(4),y12(4),cl(16),x(16) |
| integer wt(16,16) |
| data wt/1,0,-3,2,4*0,-3,0,9,-6,2,0,-6,4, |
| > 8*0,3,0,-9,6,-2,0,6,-4, |
| > 10*0,9,-6,2*0,-6,4,2*0,3,-2,6*0,-9,6,2*0,6,-4, |
| > 4*0,1,0,-3,2,-2,0,6,-4,1,0,-3,2,8*0,-1,0,3,-2,1,0,-3,2, |
| > 10*0,-3,2,2*0,3,-2,6*0,3,-2,2*0,-6,4,2*0,3,-2, |
| > 0,1,-2,1,5*0,-3,6,-3,0,2,-4,2,9*0,3,-6,3,0,-2,4,-2, |
| > 10*0,-3,3,2*0,2,-2,2*0,-1,1,6*0,3,-3,2*0,-2,2, |
| > 5*0,1,-2,1,0,-2,4,-2,0,1,-2,1,9*0,-1,2,-1,0,1,-2,1, |
| > 10*0,1,-1,2*0,-1,1,6*0,-1,1,2*0,2,-2,2*0,-1,1/ |
| real xx |
| integer i,j,k,l |
| do i=1,4 ! pack a temporary vector x |
| x(i)=y(i) |
| x(i+4)=y1(i) |
| x(i+8)=y2(i) |
| x(i+12)=y12(i) |
| enddo |
| do i=1,16 ! matrix multiply by the stored table |
| xx=0. |
| do k=1,16 |
| xx=xx+wt(i,k)*x(k) |
| enddo |
| cl(i)=xx |
| enddo |
| l=0 |
| do i=1,4 ! unpack the result into the output table |
| do j=1,4 |
| l=l+1 |
| c(i,j)=cl(l) |
| enddo |
| enddo |
| return |
| end |
| subroutine bcuint(y,y1,y2,y12,x1l,x2l,x1,x2,ansy) |
| c----------------------------------------------------------------------- |
| c Bicubic interpolation within a grid square. Input quantities are |
| c y,y1,y2,y12 (as described in bcucof); x1l and x1u, the lower and |
| c upper coordinates of the grid square in the 1-direction; x2l and |
| c x2u likewise for the 2-direction; and x1,x2, the coordinates of |
| c the desired point for the interpolation. The interplated function |
| c value is returned as ansy. This routine calls bcucof. |
| c Source: Numerical Recipes, Fortran Version, p.99/100 |
| c !!! changed the proposed code !!! |
| c----------------------------------------------------------------------- |
| real y(4),y1(4),y2(4),y12(4),c(4,4) |
| real ansy,x1,x2,t,u |
| integer i,x1l,x2l |
| call bcucof(y,y1,y2,y12,c) |
| t=x1-real(x1l) |
| u=x2-real(x2l) |
| ansy=0. |
| do i=4,1,-1 |
| ansy=t*ansy+((c(i,4)*u+c(i,3))*u+c(i,2))*u+c(i,1) |
| enddo |
| return |
| end |
| subroutine cubint(ya1,ya2,ya3,ya4,k,x,y) |
| c----------------------------------------------------------------------- |
| c Interface routine for SR polint for special case of cubic |
| c interpolation in index space, with xa=k,k+1,k+2,k+3 |
| c----------------------------------------------------------------------- |
| integer k |
| real ya1,ya2,ya3,ya4,x,y |
| integer n |
| real xa(4),ya(4),dy |
| do n=1,4 |
| xa(1)=real(k) |
| xa(2)=real(k+1) |
| xa(3)=real(k+2) |
| xa(4)=real(k+3) |
| ya(1)=ya1 |
| ya(2)=ya2 |
| ya(3)=ya3 |
| ya(4)=ya4 |
| enddo |
| call polint(xa,ya,4,x,y,dy) |
| return |
| end |
| subroutine polint(xa,ya,n,x,y,dy) |
| c----------------------------------------------------------------------- |
| c Given arrays xa and ya, each of length n, and given a value x, this |
| c routine returns a value y, and an error estimate dy. If P(x) is the |
| c polynomial of degree n-1 such that p(xa(i))=ya(i),i=1,...,n, then |
| c the returned value y=p(x) |
| c Source: Numerical Recipes, Fortran Version, p.82 |
| c----------------------------------------------------------------------- |
| integer nmax,n |
| parameter(nmax=10) |
| real xa(n),ya(n),x,y,dy |
| integer i,m,ns |
| real c(nmax),d(nmax),den,dif,dift,ho,hp,w |
| ns=1 |
| dif=abs(x-xa(1)) |
| do i=1,n |
| dift=abs(x-xa(i)) |
| if (dift.lt.dif) then |
| ns=i |
| dif=dift |
| endif |
| c(i)=ya(i) |
| d(i)=ya(i) |
| enddo |
| y=ya(ns) |
| ns=ns-1 |
| do m=1,n-1 |
| do i=1,n-m |
| ho=xa(i)-x |
| hp=xa(i+m)-x |
| w=c(i+1)-d(i) |
| den=ho-hp |
| den=w/den |
| d(i)=hp*den |
| c(i)=ho*den |
| enddo |
| if (2*ns.lt.n-m) then |
| dy=c(ns+1) |
| else |
| dy=d(ns) |
| ns=ns-1 |
| endif |
| y=y+dy |
| enddo |
| return |
| end |
| subroutine filt2d (a,af,f1,f2,nx,ny,fil,misdat, |
| & iperx,ipery,ispol,inpol) |
| c ============================================================= |
| c Apply a conservative diffusion operator onto the 2d field a, |
| c with full missing data checking. |
| c |
| c a real inp array to be filtered, dimensioned (nx,ny) |
| c af real out filtered array, dimensioned (nx,ny), can be |
| c equivalenced with array a in the calling routine |
| c f1 real workarray, dimensioned (nx+1,ny) |
| c f2 real workarray, dimensioned (nx,ny+1) |
| c fil real inp filter-coeff., 0<afil<=1. Maximum filtering with afil=1 |
| c corresponds to one application of the linear filter. |
| c misdat real inp missing-data value, a(i,j)=misdat indicates that |
| c the corresponding value is not available. The |
| c misdat-checking can be switched off with with misdat=0. |
| c iperx int inp periodic boundaries in the x-direction (1=yes,0=no) |
| c ipery int inp periodic boundaries in the y-direction (1=yes,0=no) |
| c inpol int inp northpole at j=ny (1=yes,0=no) |
| c ispol int inp southpole at j=1 (1=yes,0=no) |
| c |
| c Christoph Schaer, 1993 |
| c argument declaration |
| integer nx,ny |
| real a(nx,ny),af(nx,ny),f1(nx+1,ny),f2(nx,ny+1),fil,misdat |
| integer iperx,ipery,inpol,ispol |
| c local variable declaration |
| integer i,j,is |
| real fh |
| c compute constant fh |
| fh=0.125*fil |
| c compute fluxes in x-direction |
| if (misdat.eq.0.) then |
| do j=1,ny |
| do i=2,nx |
| f1(i,j)=a(i-1,j)-a(i,j) |
| enddo |
| enddo |
| else |
| do j=1,ny |
| do i=2,nx |
| if ((a(i,j).eq.misdat).or.(a(i-1,j).eq.misdat)) then |
| f1(i,j)=0. |
| else |
| f1(i,j)=a(i-1,j)-a(i,j) |
| endif |
| enddo |
| enddo |
| endif |
| if (iperx.eq.1) then |
| c do periodic boundaries in the x-direction |
| do j=1,ny |
| f1(1,j)=f1(nx,j) |
| f1(nx+1,j)=f1(2,j) |
| enddo |
| else |
| c set boundary-fluxes to zero |
| do j=1,ny |
| f1(1,j)=0. |
| f1(nx+1,j)=0. |
| enddo |
| endif |
| c compute fluxes in y-direction |
| if (misdat.eq.0.) then |
| do j=2,ny |
| do i=1,nx |
| f2(i,j)=a(i,j-1)-a(i,j) |
| enddo |
| enddo |
| else |
| do j=2,ny |
| do i=1,nx |
| if ((a(i,j).eq.misdat).or.(a(i,j-1).eq.misdat)) then |
| f2(i,j)=0. |
| else |
| f2(i,j)=a(i,j-1)-a(i,j) |
| endif |
| enddo |
| enddo |
| endif |
| c set boundary-fluxes to zero |
| do i=1,nx |
| f2(i,1)=0. |
| f2(i,ny+1)=0. |
| enddo |
| if (ipery.eq.1) then |
| c do periodic boundaries in the x-direction |
| do i=1,nx |
| f2(i,1)=f2(i,ny) |
| f2(i,ny+1)=f2(i,2) |
| enddo |
| endif |
| if (iperx.eq.1) then |
| if (ispol.eq.1) then |
| c do south-pole |
| is=(nx-1)/2 |
| do i=1,nx |
| f2(i,1)=-f2(mod(i-1+is,nx)+1,2) |
| enddo |
| endif |
| if (inpol.eq.1) then |
| c do north-pole |
| is=(nx-1)/2 |
| do i=1,nx |
| f2(i,ny+1)=-f2(mod(i-1+is,nx)+1,ny) |
| enddo |
| endif |
| endif |
| c compute flux-convergence -> filter |
| if (misdat.eq.0.) then |
| do j=1,ny |
| do i=1,nx |
| af(i,j)=a(i,j)+fh*(f1(i,j)-f1(i+1,j)+f2(i,j)-f2(i,j+1)) |
| enddo |
| enddo |
| else |
| do j=1,ny |
| do i=1,nx |
| if (a(i,j).eq.misdat) then |
| af(i,j)=misdat |
| else |
| af(i,j)=a(i,j)+fh*(f1(i,j)-f1(i+1,j)+f2(i,j)-f2(i,j+1)) |
| endif |
| enddo |
| enddo |
| endif |
| end |
| subroutine pipo(var3d,p3d,lev,var,nx,ny,nz,mdv,mode) |
| C ==================================================== |
| C Interpolates the 3d variable var3d on the pressure surface |
| C defined by lev. The interpolated field is returned as var. |
| C p3d denotes the 3d pressure array. |
| C mode determines the way of vertical interpolation: |
| C mode=0 is for linear interpolation |
| C mode=1 is for logarithmic interpolation |
| integer nx,ny,nz,mode |
| real lev,mdv |
| real var3d(nx,ny,nz),p3d(nx,ny,nz),var(nx,ny) |
| integer i,j,k |
| real kind |
| real int3dm |
| do i=1,nx |
| do j=1,ny |
| kind=0. |
| do k=1,nz-1 |
| if ((p3d(i,j,k).ge.lev).and.(p3d(i,j,k+1).le.lev)) then |
| kind=float(k)+(p3d(i,j,k)-lev)/ |
| > (p3d(i,j,k)-p3d(i,j,k+1)) |
| goto 100 |
| endif |
| enddo |
| 100 continue |
| if (kind.eq.0.) then |
| var(i,j)=mdv |
| else |
| var(i,j)=int3dm(var3d,nx,ny,nz,float(i),float(j),kind,mdv) |
| endif |
| enddo |
| enddo |
| return |
| end |
| subroutine thipo(var3d,th3d,lev,var,nx,ny,nz,mdv,mode) |
| C ====================================================== |
| C Interpolates the 3d variable var3d on the isentropic surface |
| C defined by lev. The interpolated field is returned as var. |
| C th3d denotes the 3d theta array. |
| C mode determines the way of vertical interpolation: |
| C mode=0 is for linear interpolation |
| C mode=1 is for logarithmic interpolation |
| integer nx,ny,nz,mode |
| real lev,mdv |
| real var3d(nx,ny,nz),th3d(nx,ny,nz),var(nx,ny) |
| integer i,j,k |
| real kind |
| real int3dm |
| do i=1,nx |
| do j=1,ny |
| kind=0 |
| do k=1,nz-1 |
| if ((th3d(i,j,k).le.lev).and.(th3d(i,j,k+1).ge.lev)) then |
| kind=float(k)+(th3d(i,j,k)-lev)/ |
| > (th3d(i,j,k)-th3d(i,j,k+1)) |
| goto 100 |
| endif |
| enddo |
| 100 continue |
| if (kind.eq.0) then |
| var(i,j)=mdv |
| else |
| var(i,j)=int3dm(var3d,nx,ny,nz,float(i),float(j),kind,mdv) |
| endif |
| enddo |
| enddo |
| return |
| end |