| 0,0 → 1,513 |
| PROGRAM prep_iteration |
| |
| c ************************************************************************ |
| c * Prepare the next step for the PV inversion * |
| c * Michael Sprenger / Summer, Autumn 2006 * |
| c ************************************************************************ |
| |
| implicit none |
| |
| c ------------------------------------------------------------------------ |
| c Declaration of variables and parameters |
| c ------------------------------------------------------------------------ |
| |
| c Input and output file |
| character*80 anomafile |
| character*80 iterafile |
| |
| c Grid parameters |
| integer nx,ny,nz |
| real xmin,ymin,zmin,xmax,ymax,zmax |
| real dx,dy,dz |
| real mdv |
| |
| c Numerical epsilon and other variables |
| real eps |
| parameter (eps=0.01) |
| real alpha |
| |
| c 3d arrays |
| real,allocatable,dimension (:,:,:) :: v_iter,v_anom |
| real,allocatable,dimension (:,:,:) :: u_iter,u_anom |
| real,allocatable,dimension (:,:,:) :: t_iter,t_anom |
| real,allocatable,dimension (:,:,:) :: p_iter,p_anom |
| |
| c Auciliary variables |
| integer i,j,k |
| integer stat |
| character*80 varname |
| character*80 name |
| |
| c -------------------------------------------------------------------------------- |
| c Input |
| c -------------------------------------------------------------------------------- |
| |
| print*,'********************************************************' |
| print*,'* PREP_ITERATION *' |
| print*,'********************************************************' |
| |
| c Read parameter file |
| open(10,file='fort.10') |
| read(10,*) iterafile |
| read(10,*) anomafile |
| read(10,*) name,alpha |
| if ( trim(name).ne.'ALPHA' ) stop |
| close(10) |
| print* |
| print*,trim(anomafile) |
| print*,trim(iterafile) |
| print* |
| |
| c Get lat/lon gid parameters from input file |
| call read_dim (nx,ny,nz,dx,dy,dz,xmin,ymin,zmin,mdv, |
| > anomafile) |
| print*,'Read_Dim: nx,ny,nz = ',nx,ny,nz |
| print*,' dx,dy,dz = ',dx,dy,dz |
| print*,' xmin,ymin,zmin = ',xmin,ymin,zmin |
| print*,' mdv = ',mdv |
| print* |
| |
| c Count from 0, not from 1: consistent with <inv_cart.f>. |
| nx=nx-1 |
| ny=ny-1 |
| nz=nz-1 |
| |
| c Allocate memory for 3d arrays |
| allocate(u_anom (0:nx,0:ny,0:nz),STAT=stat) |
| if (stat.ne.0) print*,'error allocating u_anom' |
| allocate(v_anom (0:nx,0:ny,0:nz),STAT=stat) |
| if (stat.ne.0) print*,'error allocating v_anom' |
| allocate(t_anom (0:nx,0:ny,0:nz),STAT=stat) |
| if (stat.ne.0) print*,'error allocating t_anom' |
| allocate(p_anom (0:nx,0:ny,0:nz),STAT=stat) |
| if (stat.ne.0) print*,'error allocating p_anom' |
| |
| allocate(u_iter (0:nx,0:ny,0:nz),STAT=stat) |
| if (stat.ne.0) print*,'error allocating u_iter' |
| allocate(v_iter (0:nx,0:ny,0:nz),STAT=stat) |
| if (stat.ne.0) print*,'error allocating v_iter' |
| allocate(t_iter (0:nx,0:ny,0:nz),STAT=stat) |
| if (stat.ne.0) print*,'error allocating t_iter' |
| allocate(p_iter (0:nx,0:ny,0:nz),STAT=stat) |
| if (stat.ne.0) print*,'error allocating p_iter' |
| |
| c Read anomaly and iteration fields |
| varname='U' |
| call read_inp (u_anom,varname,anomafile, |
| > nx,ny,nz,dx,dy,dz,xmin,ymin,zmin,mdv) |
| varname='V' |
| call read_inp (v_anom,varname,anomafile, |
| > nx,ny,nz,dx,dy,dz,xmin,ymin,zmin,mdv) |
| varname='T' |
| call read_inp (t_anom,varname,anomafile, |
| > nx,ny,nz,dx,dy,dz,xmin,ymin,zmin,mdv) |
| varname='P' |
| call read_inp (p_anom,varname,anomafile, |
| > nx,ny,nz,dx,dy,dz,xmin,ymin,zmin,mdv) |
| varname='U' |
| call read_inp (u_iter,varname,iterafile, |
| > nx,ny,nz,dx,dy,dz,xmin,ymin,zmin,mdv) |
| varname='V' |
| call read_inp (v_iter,varname,iterafile, |
| > nx,ny,nz,dx,dy,dz,xmin,ymin,zmin,mdv) |
| varname='T' |
| call read_inp (t_iter,varname,iterafile, |
| > nx,ny,nz,dx,dy,dz,xmin,ymin,zmin,mdv) |
| varname='P' |
| call read_inp (p_iter,varname,iterafile, |
| > nx,ny,nz,dx,dy,dz,xmin,ymin,zmin,mdv) |
| |
| c -------------------------------------------------------------------------------- |
| c Modify the iteration fields |
| c -------------------------------------------------------------------------------- |
| |
| do i=0,nx |
| do j=0,ny |
| do k=0,nz |
| |
| c Update zonal velocity |
| if ((abs(u_anom(i,j,k)-mdv).gt.eps).and. |
| > (abs(u_iter(i,j,k)-mdv).gt.eps)) then |
| u_iter(i,j,k)=u_iter(i,j,k)-alpha*u_anom(i,j,k) |
| else |
| u_iter(i,j,k)=mdv |
| endif |
| |
| c Update meridional velocity |
| if ((abs(v_anom(i,j,k)-mdv).gt.eps).and. |
| > (abs(v_iter(i,j,k)-mdv).gt.eps)) then |
| v_iter(i,j,k)=v_iter(i,j,k)-alpha*v_anom(i,j,k) |
| else |
| v_iter(i,j,k)=mdv |
| endif |
| |
| c Update temperature |
| if ((abs(t_anom(i,j,k)-mdv).gt.eps).and. |
| > (abs(t_iter(i,j,k)-mdv).gt.eps)) then |
| t_iter(i,j,k)=t_iter(i,j,k)-alpha*t_anom(i,j,k) |
| else |
| t_iter(i,j,k)=mdv |
| endif |
| |
| c Update pressure |
| if ((abs(p_anom(i,j,k)-mdv).gt.eps).and. |
| > (abs(p_iter(i,j,k)-mdv).gt.eps)) then |
| p_iter(i,j,k)=p_iter(i,j,k)-alpha*p_anom(i,j,k) |
| else |
| p_iter(i,j,k)=mdv |
| endif |
| |
| enddo |
| enddo |
| enddo |
| |
| |
| c -------------------------------------------------------------------------------- |
| c Write output |
| c -------------------------------------------------------------------------------- |
| |
| varname='U' |
| call write_inp (u_iter,varname,iterafile,nx,ny,nz) |
| varname='V' |
| call write_inp (v_iter,varname,iterafile,nx,ny,nz) |
| varname='T' |
| call write_inp (t_iter,varname,iterafile,nx,ny,nz) |
| varname='P' |
| call write_inp (p_iter,varname,iterafile,nx,ny,nz) |
| |
| |
| end |
| |
| |
| |
| |
| c ******************************************************************************** |
| c * NETCDF INPUT AND OUTPUT * |
| c ******************************************************************************** |
| |
| c -------------------------------------------------------------------------------- |
| c Write input field to netcdf |
| c -------------------------------------------------------------------------------- |
| |
| SUBROUTINE write_inp (field,fieldname,pvsrcfile,nx,ny,nz) |
| |
| c Read <fieldname> from netcdf file <pvsrcfile> into <field>. The grid is specified |
| c by <nx,ny,nz,dx,dy,dz,xmin,ymin,zmin>. A check is performed whether the input |
| c files are consitent with this grid. |
| |
| implicit none |
| |
| c Declaration of subroutine parameters |
| integer nx,ny,nz |
| real field (0:nx,0:ny,0:nz) |
| character*80 fieldname |
| character*80 pvsrcfile |
| |
| c Auxiliary variables |
| integer cdfid,stat |
| integer vardim(4) |
| real misdat |
| real varmin(4),varmax(4),stag(4) |
| integer ndimin,outid,i,j,k |
| real max_th |
| real tmp(0:nx,0:ny,0:nz) |
| integer ntimes |
| real time(200) |
| integer nvars |
| character*80 vnam(100),varname |
| integer isok |
| |
| c Get grid parameters |
| call cdfopn(pvsrcfile,cdfid,stat) |
| if (stat.ne.0) goto 998 |
| call getvars(cdfid,nvars,vnam,stat) |
| if (stat.ne.0) goto 998 |
| isok=0 |
| varname='TH' |
| call check_varok(isok,varname,vnam,nvars) |
| if (isok.eq.0) goto 998 |
| call getdef(cdfid,varname,ndimin,misdat,vardim, |
| > varmin,varmax,stag,stat) |
| if (stat.ne.0) goto 998 |
| time(1)=0. |
| call gettimes(cdfid,time,ntimes,stat) |
| if (stat.ne.0) goto 998 |
| call clscdf(cdfid,stat) |
| if (stat.ne.0) goto 998 |
| |
| c Save variables (write definition, if necessary) |
| call cdfwopn(pvsrcfile,cdfid,stat) |
| if (stat.ne.0) goto 998 |
| isok=0 |
| varname=fieldname |
| call check_varok(isok,varname,vnam,nvars) |
| if (isok.eq.0) then |
| call putdef(cdfid,varname,ndimin,misdat,vardim, |
| > varmin,varmax,stag,stat) |
| if (stat.ne.0) goto 998 |
| endif |
| call putdat(cdfid,varname,time(1),0,field,stat) |
| print*,'W ',trim(varname),' ',trim(pvsrcfile) |
| if (stat.ne.0) goto 998 |
| |
| c Close input netcdf file |
| call clscdf(cdfid,stat) |
| if (stat.ne.0) goto 998 |
| |
| return |
| |
| c Exception handling |
| 998 print*,'Write_Inp: Problem with input netcdf file... Stop' |
| stop |
| |
| end |
| |
| |
| c -------------------------------------------------------------------------------- |
| c Read input fields for reference profile |
| c -------------------------------------------------------------------------------- |
| |
| SUBROUTINE read_inp (field,fieldname,pvsrcfile, |
| > nx,ny,nz,dx,dy,dz,xmin,ymin,zmin,mdv) |
| |
| c Read <fieldname> from netcdf file <pvsrcfile> into <field>. The grid is specified |
| c by <nx,ny,nz,dx,dy,dz,xmin,ymin,zmin>. A check is performed whether the input |
| c files are consitent with this grid. The missing data value is set to <mdv>. |
| |
| implicit none |
| |
| c Declaration of subroutine parameters |
| integer nx,ny,nz |
| real field(0:nx,0:ny,0:nz) |
| character*80 fieldname |
| character*80 pvsrcfile |
| real dx,dy,dz,xmin,ymin,zmin |
| real mdv |
| |
| c Numerical and physical parameters |
| real eps |
| parameter (eps=0.01) |
| |
| c Auxiliary variables |
| integer cdfid,stat,cdfid99 |
| integer vardim(4) |
| real misdat |
| real varmin(4),varmax(4),stag(4) |
| integer ndimin,outid,i,j,k |
| real max_th |
| real tmp(nx,ny,nz) |
| integer ntimes |
| real time(200) |
| integer nvars |
| character*80 vnam(100),varname |
| integer isok |
| |
| c Open the input netcdf file |
| call cdfopn(pvsrcfile,cdfid,stat) |
| if (stat.ne.0) goto 998 |
| |
| c Check whether needed variables are on file |
| call getvars(cdfid,nvars,vnam,stat) |
| if (stat.ne.0) goto 998 |
| isok=0 |
| varname=trim(fieldname) |
| call check_varok(isok,varname,vnam,nvars) |
| if (isok.eq.0) goto 998 |
| |
| c Get the grid parameters from theta |
| call getdef(cdfid,varname,ndimin,misdat,vardim, |
| > varmin,varmax,stag,stat) |
| if (stat.ne.0) goto 998 |
| time(1)=0. |
| call gettimes(cdfid,time,ntimes,stat) |
| if (stat.ne.0) goto 998 |
| |
| c Check whether grid parameters are consistent |
| if ( (vardim(1).ne.(nx+1)).or. |
| > (vardim(2).ne.(ny+1)).or. |
| > (vardim(3).ne.(nz+1)).or. |
| > (abs(varmin(1)-xmin).gt.eps).or. |
| > (abs(varmin(2)-ymin).gt.eps).or. |
| > (abs(varmin(3)-zmin).gt.eps).or. |
| > (abs((varmax(1)-varmin(1))/real(vardim(1)-1)-dx).gt.eps).or. |
| > (abs((varmax(2)-varmin(2))/real(vardim(2)-1)-dy).gt.eps).or. |
| > (abs((varmax(3)-varmin(3))/real(vardim(3)-1)-dz).gt.eps) ) |
| >then |
| print*,'Input grid inconsitency...' |
| print*,' Nx = ',vardim(1),nx+1 |
| print*,' Ny = ',vardim(2),ny+1 |
| print*,' Nz = ',vardim(3),nz+1 |
| print*,' Varminx = ',varmin(1),xmin |
| print*,' Varminy = ',varmin(2),ymin |
| print*,' Varminz = ',varmin(3),zmin |
| print*,' Dx = ',(varmax(1)-varmin(1))/real(nx-1),dx |
| print*,' Dy = ',(varmax(2)-varmin(2))/real(ny-1),dy |
| print*,' Dz = ',(varmax(3)-varmin(3))/real(nz-1),dz |
| goto 998 |
| endif |
| |
| c Load variables |
| call getdef(cdfid,varname,ndimin,misdat,vardim, |
| > varmin,varmax,stag,stat) |
| if (stat.ne.0) goto 998 |
| call getdat(cdfid,varname,time(1),0,field,stat) |
| print*, 'R ',trim(varname),' ',trim(pvsrcfile) |
| if (stat.ne.0) goto 998 |
| |
| c Close input netcdf file |
| call clscdf(cdfid,stat) |
| if (stat.ne.0) goto 998 |
| |
| c Set missing data value to <mdv> |
| do i=1,nx |
| do j=1,ny |
| do k=1,nz |
| if (abs(field(i,j,k)-misdat).lt.eps) then |
| field(i,j,k)=mdv |
| endif |
| enddo |
| enddo |
| enddo |
| |
| return |
| |
| c Exception handling |
| 998 print*,'Read_Inp: Problem with input netcdf file... Stop' |
| stop |
| |
| end |
| |
| c -------------------------------------------------------------------------------- |
| c Check whether variable is found on netcdf file |
| c -------------------------------------------------------------------------------- |
| |
| subroutine check_varok (isok,varname,varlist,nvars) |
| |
| c Check whether the variable <varname> is in the list <varlist(nvars)>. If this is |
| C the case, <isok> is incremented by 1. Otherwise <isok> keeps its value. |
| |
| implicit none |
| |
| c Declaraion of subroutine parameters |
| integer isok |
| integer nvars |
| character*80 varname |
| character*80 varlist(nvars) |
| |
| c Auxiliary variables |
| integer i |
| |
| c Main |
| do i=1,nvars |
| if (trim(varname).eq.trim(varlist(i))) isok=isok+1 |
| enddo |
| |
| end |
| |
| c -------------------------------------------------------------------------------- |
| c Get grid parameters |
| c -------------------------------------------------------------------------------- |
| |
| subroutine read_dim (nx,ny,nz,dx,dy,dz,xmin,ymin,zmin,mdv, |
| > pvsrcfile) |
| |
| c Get the grid parameters from the variable <THETA> on the input file <pvsrcfile>. |
| c The grid parameters are |
| c nx,ny,nz : Number of grid points in x, y and z direction |
| c xmin,ymin,zmin : Minimum domain coordinates in x, y and z direction |
| c xmax,ymax,zmax : Maximal domain coordinates in x, y and z direction |
| c dx,dy,dz : Horizontal and vertical resolution |
| c Additionally, it is checked whether the vertical grid is equally spaced. If ok, |
| c the grid paramters are transformed from lon/lat to distance (in meters) |
| |
| implicit none |
| |
| c Declaration of subroutine parameters |
| character*80 pvsrcfile |
| integer nx,ny,nz |
| real dx,dy,dz |
| real xmin,ymin,zmin,xmax,ymax,zmax |
| real mdv |
| |
| c Numerical epsilon and other physical/geoemtrical parameters |
| real eps |
| parameter (eps=0.01) |
| |
| c Auxiliary variables |
| integer cdfid,cstid |
| integer ierr |
| character*80 vnam(100),varname |
| integer nvars |
| integer isok |
| integer vardim(4) |
| real misdat |
| real varmin(4),varmax(4),stag(4) |
| real aklev(1000),bklev(1000),aklay(1000),bklay(1000) |
| real dh |
| character*80 csn |
| integer ndim |
| integer i |
| |
| c Get all grid parameters |
| call cdfopn(pvsrcfile,cdfid,ierr) |
| if (ierr.ne.0) goto 998 |
| call getvars(cdfid,nvars,vnam,ierr) |
| if (ierr.ne.0) goto 998 |
| isok=0 |
| varname='TH' |
| call check_varok(isok,varname,vnam,nvars) |
| if (isok.eq.0) goto 998 |
| call getcfn(cdfid,csn,ierr) |
| if (ierr.ne.0) goto 998 |
| call cdfopn(csn,cstid,ierr) |
| if (ierr.ne.0) goto 998 |
| call getdef(cdfid,varname,ndim,misdat,vardim,varmin,varmax, |
| > stag,ierr) |
| if (ierr.ne.0) goto 998 |
| nx=vardim(1) |
| ny=vardim(2) |
| nz=vardim(3) |
| xmin=varmin(1) |
| ymin=varmin(2) |
| zmin=varmin(3) |
| call getlevs(cstid,nz,aklev,bklev,aklay,bklay,ierr) |
| if (ierr.ne.0) goto 998 |
| call getgrid(cstid,dx,dy,ierr) |
| if (ierr.ne.0) goto 998 |
| xmax=varmax(1) |
| ymax=varmax(2) |
| zmax=varmax(3) |
| dz=(zmax-zmin)/real(nz-1) |
| call clscdf(cstid,ierr) |
| if (ierr.ne.0) goto 998 |
| call clscdf(cdfid,ierr) |
| if (ierr.ne.0) goto 998 |
| |
| c Check whether the grid is equallay spaced in the vertical |
| do i=1,nz-1 |
| dh=aklev(i+1)-aklev(i) |
| if (abs(dh-dz).gt.eps) then |
| print*,'Aklev: Vertical grid must be equally spaced... Stop' |
| print*,(aklev(i),i=1,nz) |
| stop |
| endif |
| dh=aklay(i+1)-aklay(i) |
| if (abs(dh-dz).gt.eps) then |
| print*,'Aklay: Vertical grid must be equally spaced... Stop' |
| print*,(aklay(i),i=1,nz) |
| stop |
| endif |
| enddo |
| |
| c Set missing data value |
| mdv=misdat |
| |
| return |
| |
| c Exception handling |
| 998 print*,'Read_Dim: Problem with input netcdf file... Stop' |
| stop |
| |
| end |
| |
| |
| Property changes: |
| Added: svn:executable |