Blame | Last modification | View Log | Download | RSS feed
PROGRAM prep_iterationc ************************************************************************c * Prepare the next step for the PV inversion *c * Michael Sprenger / Summer, Autumn 2006 *c ************************************************************************implicit nonec ------------------------------------------------------------------------c Declaration of variables and parametersc ------------------------------------------------------------------------c Input and output filecharacter*80 anomafilecharacter*80 iterafilec Grid parametersinteger nx,ny,nzreal xmin,ymin,zmin,xmax,ymax,zmaxreal dx,dy,dzreal mdvc Numerical epsilon and other variablesreal epsparameter (eps=0.01)real alphac 3d arraysreal,allocatable,dimension (:,:,:) :: v_iter,v_anomreal,allocatable,dimension (:,:,:) :: u_iter,u_anomreal,allocatable,dimension (:,:,:) :: t_iter,t_anomreal,allocatable,dimension (:,:,:) :: p_iter,p_anomc Auciliary variablesinteger i,j,kinteger statcharacter*80 varnamecharacter*80 namec --------------------------------------------------------------------------------c Inputc --------------------------------------------------------------------------------print*,'********************************************************'print*,'* PREP_ITERATION *'print*,'********************************************************'c Read parameter fileopen(10,file='fort.10')read(10,*) iterafileread(10,*) anomafileread(10,*) name,alphaif ( trim(name).ne.'ALPHA' ) stopclose(10)print*print*,trim(anomafile)print*,trim(iterafile)print*c Get lat/lon gid parameters from input filecall read_dim (nx,ny,nz,dx,dy,dz,xmin,ymin,zmin,mdv,> anomafile)print*,'Read_Dim: nx,ny,nz = ',nx,ny,nzprint*,' dx,dy,dz = ',dx,dy,dzprint*,' xmin,ymin,zmin = ',xmin,ymin,zminprint*,' mdv = ',mdvprint*c Count from 0, not from 1: consistent with <inv_cart.f>.nx=nx-1ny=ny-1nz=nz-1c Allocate memory for 3d arraysallocate(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 fieldsvarname='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 fieldsc --------------------------------------------------------------------------------do i=0,nxdo j=0,nydo k=0,nzc Update zonal velocityif ((abs(u_anom(i,j,k)-mdv).gt.eps).and.> (abs(u_iter(i,j,k)-mdv).gt.eps)) thenu_iter(i,j,k)=u_iter(i,j,k)-alpha*u_anom(i,j,k)elseu_iter(i,j,k)=mdvendifc Update meridional velocityif ((abs(v_anom(i,j,k)-mdv).gt.eps).and.> (abs(v_iter(i,j,k)-mdv).gt.eps)) thenv_iter(i,j,k)=v_iter(i,j,k)-alpha*v_anom(i,j,k)elsev_iter(i,j,k)=mdvendifc Update temperatureif ((abs(t_anom(i,j,k)-mdv).gt.eps).and.> (abs(t_iter(i,j,k)-mdv).gt.eps)) thent_iter(i,j,k)=t_iter(i,j,k)-alpha*t_anom(i,j,k)elset_iter(i,j,k)=mdvendifc Update pressureif ((abs(p_anom(i,j,k)-mdv).gt.eps).and.> (abs(p_iter(i,j,k)-mdv).gt.eps)) thenp_iter(i,j,k)=p_iter(i,j,k)-alpha*p_anom(i,j,k)elsep_iter(i,j,k)=mdvendifenddoenddoenddoc --------------------------------------------------------------------------------c Write outputc --------------------------------------------------------------------------------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)endc ********************************************************************************c * NETCDF INPUT AND OUTPUT *c ********************************************************************************c --------------------------------------------------------------------------------c Write input field to netcdfc --------------------------------------------------------------------------------SUBROUTINE write_inp (field,fieldname,pvsrcfile,nx,ny,nz)c Read <fieldname> from netcdf file <pvsrcfile> into <field>. The grid is specifiedc by <nx,ny,nz,dx,dy,dz,xmin,ymin,zmin>. A check is performed whether the inputc files are consitent with this grid.implicit nonec Declaration of subroutine parametersinteger nx,ny,nzreal field (0:nx,0:ny,0:nz)character*80 fieldnamecharacter*80 pvsrcfilec Auxiliary variablesinteger cdfid,statinteger vardim(4)real misdatreal varmin(4),varmax(4),stag(4)integer ndimin,outid,i,j,kreal max_threal tmp(0:nx,0:ny,0:nz)integer ntimesreal time(200)integer nvarscharacter*80 vnam(100),varnameinteger isokc Get grid parameterscall cdfopn(pvsrcfile,cdfid,stat)if (stat.ne.0) goto 998call getvars(cdfid,nvars,vnam,stat)if (stat.ne.0) goto 998isok=0varname='TH'call check_varok(isok,varname,vnam,nvars)if (isok.eq.0) goto 998call getdef(cdfid,varname,ndimin,misdat,vardim,> varmin,varmax,stag,stat)if (stat.ne.0) goto 998time(1)=0.call gettimes(cdfid,time,ntimes,stat)if (stat.ne.0) goto 998call clscdf(cdfid,stat)if (stat.ne.0) goto 998c Save variables (write definition, if necessary)call cdfwopn(pvsrcfile,cdfid,stat)if (stat.ne.0) goto 998isok=0varname=fieldnamecall check_varok(isok,varname,vnam,nvars)if (isok.eq.0) thencall putdef(cdfid,varname,ndimin,misdat,vardim,> varmin,varmax,stag,stat)if (stat.ne.0) goto 998endifcall putdat(cdfid,varname,time(1),0,field,stat)print*,'W ',trim(varname),' ',trim(pvsrcfile)if (stat.ne.0) goto 998c Close input netcdf filecall clscdf(cdfid,stat)if (stat.ne.0) goto 998returnc Exception handling998 print*,'Write_Inp: Problem with input netcdf file... Stop'stopendc --------------------------------------------------------------------------------c Read input fields for reference profilec --------------------------------------------------------------------------------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 specifiedc by <nx,ny,nz,dx,dy,dz,xmin,ymin,zmin>. A check is performed whether the inputc files are consitent with this grid. The missing data value is set to <mdv>.implicit nonec Declaration of subroutine parametersinteger nx,ny,nzreal field(0:nx,0:ny,0:nz)character*80 fieldnamecharacter*80 pvsrcfilereal dx,dy,dz,xmin,ymin,zminreal mdvc Numerical and physical parametersreal epsparameter (eps=0.01)c Auxiliary variablesinteger cdfid,stat,cdfid99integer vardim(4)real misdatreal varmin(4),varmax(4),stag(4)integer ndimin,outid,i,j,kreal max_threal tmp(nx,ny,nz)integer ntimesreal time(200)integer nvarscharacter*80 vnam(100),varnameinteger isokc Open the input netcdf filecall cdfopn(pvsrcfile,cdfid,stat)if (stat.ne.0) goto 998c Check whether needed variables are on filecall getvars(cdfid,nvars,vnam,stat)if (stat.ne.0) goto 998isok=0varname=trim(fieldname)call check_varok(isok,varname,vnam,nvars)if (isok.eq.0) goto 998c Get the grid parameters from thetacall getdef(cdfid,varname,ndimin,misdat,vardim,> varmin,varmax,stag,stat)if (stat.ne.0) goto 998time(1)=0.call gettimes(cdfid,time,ntimes,stat)if (stat.ne.0) goto 998c Check whether grid parameters are consistentif ( (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) )>thenprint*,'Input grid inconsitency...'print*,' Nx = ',vardim(1),nx+1print*,' Ny = ',vardim(2),ny+1print*,' Nz = ',vardim(3),nz+1print*,' Varminx = ',varmin(1),xminprint*,' Varminy = ',varmin(2),yminprint*,' Varminz = ',varmin(3),zminprint*,' Dx = ',(varmax(1)-varmin(1))/real(nx-1),dxprint*,' Dy = ',(varmax(2)-varmin(2))/real(ny-1),dyprint*,' Dz = ',(varmax(3)-varmin(3))/real(nz-1),dzgoto 998endifc Load variablescall getdef(cdfid,varname,ndimin,misdat,vardim,> varmin,varmax,stag,stat)if (stat.ne.0) goto 998call getdat(cdfid,varname,time(1),0,field,stat)print*, 'R ',trim(varname),' ',trim(pvsrcfile)if (stat.ne.0) goto 998c Close input netcdf filecall clscdf(cdfid,stat)if (stat.ne.0) goto 998c Set missing data value to <mdv>do i=1,nxdo j=1,nydo k=1,nzif (abs(field(i,j,k)-misdat).lt.eps) thenfield(i,j,k)=mdvendifenddoenddoenddoreturnc Exception handling998 print*,'Read_Inp: Problem with input netcdf file... Stop'stopendc --------------------------------------------------------------------------------c Check whether variable is found on netcdf filec --------------------------------------------------------------------------------subroutine check_varok (isok,varname,varlist,nvars)c Check whether the variable <varname> is in the list <varlist(nvars)>. If this isC the case, <isok> is incremented by 1. Otherwise <isok> keeps its value.implicit nonec Declaraion of subroutine parametersinteger isokinteger nvarscharacter*80 varnamecharacter*80 varlist(nvars)c Auxiliary variablesinteger ic Maindo i=1,nvarsif (trim(varname).eq.trim(varlist(i))) isok=isok+1enddoendc --------------------------------------------------------------------------------c Get grid parametersc --------------------------------------------------------------------------------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 arec nx,ny,nz : Number of grid points in x, y and z directionc xmin,ymin,zmin : Minimum domain coordinates in x, y and z directionc xmax,ymax,zmax : Maximal domain coordinates in x, y and z directionc dx,dy,dz : Horizontal and vertical resolutionc 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 nonec Declaration of subroutine parameterscharacter*80 pvsrcfileinteger nx,ny,nzreal dx,dy,dzreal xmin,ymin,zmin,xmax,ymax,zmaxreal mdvc Numerical epsilon and other physical/geoemtrical parametersreal epsparameter (eps=0.01)c Auxiliary variablesinteger cdfid,cstidinteger ierrcharacter*80 vnam(100),varnameinteger nvarsinteger isokinteger vardim(4)real misdatreal varmin(4),varmax(4),stag(4)real aklev(1000),bklev(1000),aklay(1000),bklay(1000)real dhcharacter*80 csninteger ndiminteger ic Get all grid parameterscall cdfopn(pvsrcfile,cdfid,ierr)if (ierr.ne.0) goto 998call getvars(cdfid,nvars,vnam,ierr)if (ierr.ne.0) goto 998isok=0varname='TH'call check_varok(isok,varname,vnam,nvars)if (isok.eq.0) goto 998call getcfn(cdfid,csn,ierr)if (ierr.ne.0) goto 998call cdfopn(csn,cstid,ierr)if (ierr.ne.0) goto 998call getdef(cdfid,varname,ndim,misdat,vardim,varmin,varmax,> stag,ierr)if (ierr.ne.0) goto 998nx=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 998call getgrid(cstid,dx,dy,ierr)if (ierr.ne.0) goto 998xmax=varmax(1)ymax=varmax(2)zmax=varmax(3)dz=(zmax-zmin)/real(nz-1)call clscdf(cstid,ierr)if (ierr.ne.0) goto 998call clscdf(cdfid,ierr)if (ierr.ne.0) goto 998c Check whether the grid is equallay spaced in the verticaldo i=1,nz-1dh=aklev(i+1)-aklev(i)if (abs(dh-dz).gt.eps) thenprint*,'Aklev: Vertical grid must be equally spaced... Stop'print*,(aklev(i),i=1,nz)stopendifdh=aklay(i+1)-aklay(i)if (abs(dh-dz).gt.eps) thenprint*,'Aklay: Vertical grid must be equally spaced... Stop'print*,(aklay(i),i=1,nz)stopendifenddoc Set missing data valuemdv=misdatreturnc Exception handling998 print*,'Read_Dim: Problem with input netcdf file... Stop'stopend