/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 |