Blame | Last modification | View Log | Download | RSS feed
PROGRAM z2sc Calculate secondary fields on z levelsc Michael Sprenger / Summer 2006implicit nonec ---------------------------------------------------------------c Declaration of variablesc ---------------------------------------------------------------c Variables for output Z file : height levelcharacter*80 cfnreal varmin(4),varmax(4),stag(4)integer vardim(4)real mdvinteger ndiminteger nx,ny,nzreal xmin,xmax,ymin,ymax,dx,dyinteger ntimesreal aklev(1000),bklev(1000)real aklay(1000),bklay(1000)real timereal pollon,pollatinteger idate(5)integer nfieldscharacter*80 field_nam(100)real,allocatable, dimension (:,:,:,:) :: field_datreal,allocatable, dimension (:,:,:) :: z3real,allocatable, dimension (:,:) :: x2,y2,f2real,allocatable, dimension (:,:,:) :: outreal,allocatable, dimension (:,:,:) :: inpinteger nvarscharacter*80 vnam(100),varnameinteger isokinteger cdfid,cstidc Parameter filecharacter*80 fieldnameinteger nfiltcharacter*80 ofn,gric Auxiliary variablesinteger ierr,statinteger i,j,k,nreal,allocatable, dimension (:,:) :: out2character*80 vnam2(100)integer nvars2c ---------------------------------------------------------------c Preparationsc ---------------------------------------------------------------print*,'*********************************************************'print*,'* z2s *'print*,'*********************************************************'c Read parameter fileopen(10,file='fort.10')read(10,*) fieldnameread(10,*) ofnread(10,*) griread(10,*) nfiltclose(10)c Get grid description for Z file : height levelcall cdfopn(ofn,cdfid,ierr)if (ierr.ne.0) goto 998call getcfn(cdfid,cfn,ierr)if (ierr.ne.0) goto 998call cdfopn(cfn,cstid,ierr)if (ierr.ne.0) goto 998call getdef(cdfid,'T',ndim,mdv,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)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=xmin+real(nx-1)*dxymax=ymin+real(ny-1)*dycall gettimes(cdfid,time,ntimes,ierr)if (ierr.ne.0) goto 998call getstart(cstid,idate,ierr)if (ierr.ne.0) goto 998call getpole(cstid,pollon,pollat,ierr)if (ierr.ne.0) goto 998call getvars(cdfid,nvars,vnam,ierr)if (ierr.ne.0) goto 998call clscdf(cstid,ierr)if (ierr.ne.0) goto 998call clscdf(cdfid,ierr)if (ierr.ne.0) goto 998c Get a list of all variables on the GRID fileif (trim(gri).ne.trim(ofn)) thencall cdfopn(gri,cdfid,ierr)if (ierr.ne.0) goto 998call getvars(cdfid,nvars2,vnam2,ierr)if (ierr.ne.0) goto 998do i=1,nvars2vnam(nvars+i)=vnam2(i)enddonvars=nvars+nvars2endifc Check whether calculation of <fieldname> is supportedif ( (fieldname.ne.'TH' ).and.> (fieldname.ne.'NSQ') .and.> (fieldname.ne.'PV' ) .and.> (fieldname.ne.'RHO')) thenprint*,'Variable not supported ',trim(fieldname)stopendifc Set dependenciesif (fieldname.eq.'TH') thennfields=2field_nam(1)='T'field_nam(2)='P'else if (fieldname.eq.'RHO') thennfields=2field_nam(1)='T'field_nam(2)='P'else if (fieldname.eq.'NSQ') thennfields=2field_nam(1)='T'field_nam(2)='Q'else if (fieldname.eq.'PV') thennfields=4field_nam(1)='T'field_nam(2)='P'field_nam(3)='U'field_nam(4)='V'endifc Allocate memoryallocate(field_dat(nfields,nx,ny,nz),stat=stat)if (stat.ne.0) print*,'error allocating field_dat'allocate(out(nx,ny,nz),stat=stat)if (stat.ne.0) print*,'error allocating out'allocate(inp(nx,ny,nz),stat=stat)if (stat.ne.0) print*,'error allocating inp'allocate(z3(nx,ny,nz),stat=stat)if (stat.ne.0) print*,'error allocating z3'allocate(x2(nx,ny),stat=stat)if (stat.ne.0) print*,'error allocating x2'allocate(y2(nx,ny),stat=stat)if (stat.ne.0) print*,'error allocating y2'allocate(f2(nx,ny),stat=stat)if (stat.ne.0) print*,'error allocating f2'c Allocate auxiliary fieldsallocate(out2(nx,ny),stat=stat)if (stat.ne.0) print*,'error allocating out2'c Read X gridvarname='X'isok=0call check_varok (isok,varname,vnam,nvars)if (isok.eq.0) thenprint*,'Variable ',trim(varname),' missing... Stop'stopendifcall cdfopn(gri,cdfid,ierr)if (ierr.ne.0) goto 998call getdat(cdfid,varname,time,0,x2,ierr)if (ierr.ne.0) goto 998print*,'R ',trim(varname),' ',trim(gri)call clscdf(cdfid,ierr)if (ierr.ne.0) goto 998c Read Y gridvarname='Y'isok=0call check_varok (isok,varname,vnam,nvars)if (isok.eq.0) thenprint*,'Variable ',trim(varname),' missing... Stop'stopendifcall cdfopn(gri,cdfid,ierr)if (ierr.ne.0) goto 998call getdat(cdfid,varname,time,0,y2,ierr)if (ierr.ne.0) goto 998print*,'R ',trim(varname),' ',trim(gri)call clscdf(cdfid,ierr)if (ierr.ne.0) goto 998c Read Coriolis parametzervarname='CORIOL'isok=0call check_varok (isok,varname,vnam,nvars)if (isok.eq.0) thenprint*,'Variable ',trim(varname),' missing... Stop'stopendifcall cdfopn(gri,cdfid,ierr)if (ierr.ne.0) goto 998call getdat(cdfid,varname,time,0,f2,ierr)if (ierr.ne.0) goto 998print*,'R ',trim(varname),' ',trim(gri)call clscdf(cdfid,ierr)if (ierr.ne.0) goto 998c Init height levelsdo i=1,nxdo j=1,nydo k=1,nzz3(i,j,k)=aklay(k)enddoenddoenddoc Load needed variablesdo n=1,nfieldsc Check whether variable is available on filevarname=field_nam(n)isok=0call check_varok (isok,varname,vnam,nvars)c Variable is available on fileif (isok.eq.1) thencall cdfopn(ofn,cdfid,ierr)if (ierr.ne.0) goto 998call getdat(cdfid,varname,time,0,inp,ierr)if (ierr.ne.0) goto 998print*,'R ',trim(varname),' ',trim(ofn)call clscdf(cdfid,ierr)if (ierr.ne.0) goto 998do i=1,nxdo j=1,nydo k=1,nzfield_dat(n,i,j,k)=inp(i,j,k)enddoenddoenddoelseprint*,'Variable missing : ',trim(varname)stopendifenddoc Change unit of pressure from hPa to Pan=0do i=1,nfieldsif (field_nam(i).eq.'P') n=ienddoif (n.ne.0) thendo i=1,nxdo j=1,nydo k=1,nzfield_dat(n,i,j,k)=100.*field_dat(n,i,j,k)enddoenddoenddoendifc ----------------------------------------------------------------c Calculationsc ----------------------------------------------------------------c Call to the defining routinesif (fieldname.eq.'RHO') thenprint*,'C ',trim(fieldname)call calc_rho (out, ! RHO> field_dat(1,:,:,:), ! T> field_dat(2,:,:,:), ! P> nx,ny,nz,mdv)else if (fieldname.eq.'TH') thenprint*,'C ',trim(fieldname)call calc_theta (out, ! TH> field_dat(1,:,:,:), ! T> field_dat(2,:,:,:), ! P> nx,ny,nz,mdv)else if (fieldname.eq.'NSQ') thenprint*,'C ',trim(fieldname)call calc_nsq (out, ! NSQ> field_dat(1,:,:,:), ! T> field_dat(2,:,:,:), ! Q> z3, ! Z> nx,ny,nz,mdv)else if (fieldname.eq.'PV') thenprint*,'C ',trim(fieldname)call calc_pv (out, ! PV> field_dat(1,:,:,:), ! T> field_dat(2,:,:,:), ! P> field_dat(3,:,:,:), ! U> field_dat(4,:,:,:), ! V> z3,x2,y2,f2, ! Z,X,Y,CORIOL> nx,ny,nz,mdv)endifc Horizontal filtering of the resulting fieldsprint*,'F ',trim(fieldname)do k=1,nzdo i=1,nxdo j=1,nyout2(i,j)=out(i,j,k)enddoenddodo n=1,nfiltcall filt2d (out2,out2,nx,ny,1.,mdv,0,0,0,0)enddodo i=1,nxdo j=1,nyout(i,j,k)=out2(i,j)enddoenddoenddoc ----------------------------------------------------------------c Save result onto netcdf filec ----------------------------------------------------------------call cdfwopn(ofn,cdfid,ierr)if (ierr.ne.0) goto 998isok=0varname=fieldnamecall check_varok(isok,varname,vnam,nvars)if (isok.eq.0) thencall putdef(cdfid,varname,ndim,mdv,vardim,> varmin,varmax,stag,ierr)if (ierr.ne.0) goto 998endifcall putdat(cdfid,varname,time,0,out,ierr)if (ierr.ne.0) goto 998print*,'W ',trim(varname),' ',trim(ofn)call clscdf(cdfid,ierr)if (ierr.ne.0) goto 998c ----------------------------------------------------------------c Exception handlingc ----------------------------------------------------------------stop998 print*,'Problem with netcdf file'stopendc ****************************************************************c * SUBROUTINE SECTION: AUXILIARY ROUTINES *c ****************************************************************c ----------------------------------------------------------------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)>.c If this is the case, <isok> is incremented by 1. Otherwise <isok>c 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 * SUBROUTINE SECTION: CALCULATE SECONDARY FIELDS *c ****************************************************************c -----------------------------------------------------------------c Calculate densityc -----------------------------------------------------------------subroutine calc_rho (rho3,t3,p3,> nx,ny,nz,mdv)c Calculate the density <rho3> (in kg/m^3) from temperature <t3>c (in deg C) and pressure <p3> (in hPa).implicit nonec Declaration of subroutine parametersinteger nx,ny,nzreal mdvreal rho3(nx,ny,nz)real t3 (nx,ny,nz)real p3 (nx,ny,nz)c Declaration of physical constantsreal epsparameter (eps=0.01)real rdparameter (rd=287.)real tzeroparameter (tzero=273.15)c Auxiliary variablesinteger i,j,kc Calculationdo i=1,nxdo j=1,nydo k=1,nzif ((abs(t3(i,j,k)-mdv).gt.eps).and.> (abs(p3(i,j,k)-mdv).gt.eps)) thenrho3(i,j,k)=1./rd*p3(i,j,k)/(t3(i,j,k)+tzero)elserho3(i,j,k)=mdvendifenddoenddoenddoendc -----------------------------------------------------------------c Calculate potential temperaturec -----------------------------------------------------------------subroutine calc_theta (th3,t3,p3,> nx,ny,nz,mdv)c Calculate potential temperature <th3> (in K) from temperature <t3>c (in deg C) and pressure <p3> (in hPa).implicit nonec Declaration of subroutine parametersinteger nx,ny,nzreal mdvreal th3(nx,ny,nz)real t3 (nx,ny,nz)real p3 (nx,ny,nz)c Declaration of physical constantsreal rdcp,tzero,p0parameter (rdcp=0.286)parameter (tzero=273.15)parameter (p0=100000.)real epsparameter (eps=0.01)c Auxiliary variablesinteger i,j,kc Calculationdo i=1,nxdo j=1,nydo k=1,nzif ((abs(t3(i,j,k)-mdv).gt.eps).and.> (abs(p3(i,j,k)-mdv).gt.eps)) thenth3(i,j,k)=(t3(i,j,k)+tzero)*( (p0/p3(i,j,k))**rdcp )elseth3(i,j,k)=mdvendifenddoenddoenddoendc -----------------------------------------------------------------c Calculate stratificationc -----------------------------------------------------------------subroutine calc_nsq (nsq3,t3,q3,> z3,nx,ny,nz,mdv)c Calculate stratification <nsq3> on the model grid. The grid isc specified in the horizontal by <xmin,ymin,dx,dy,nx,ny>. The numberc of vertical levels is <nz>. The input field are: temperature <t3>,c specific humidity <q3>, height <z3> and horizontal grid <x2>, <y2>.implicit nonec Declaration of subroutine parametersinteger nx,ny,nzreal nsq3(nx,ny,nz)real t3 (nx,ny,nz)real q3 (nx,ny,nz)real z3 (nx,ny,nz)real x2 (nx,ny)real y2 (nx,ny)real mdvc Physical and numerical parametersreal scaleparameter (scale=1.)real gparameter (g=9.80665)real epsparameter (eps=0.01)real tzeroparameter (tzero=273.15)real kappaparameter (kappa=0.6078)real cpparameter (cp=1005.)real zerodivparameter (zerodiv=0.0000000001)real Rparameter (R=287.)c Auxiliary variablesreal tv (nx,ny,nz)real dtvdz(nx,ny,nz)integer i,j,kreal scaledzc Calculate 3d virtual temperaturedo k=1,nzdo i=1,nxdo j=1,nyif ((abs(t3(i,j,k)-mdv).gt.eps).and.> (abs(q3(i,j,k)-mdv).gt.eps))> thentv(i,j,k) = (t3(i,j,k)+tzero)*(1.+kappa*q3(i,j,k))elsetv(i,j,k) = mdvendifenddoenddoenddoc Vertical derivative of virtual temperaturecall deriv (dtvdz,tv,'z',z3,x2,y2,nx,ny,nz,mdv)c Stratificationdo i=1,nxdo j=1,nydo k=1,nzif ((abs(dtvdz(i,j,k)-mdv).gt.eps).and.> (abs(tv (i,j,k)-mdv).gt.eps))> thennsq3(i,j,k) = g/tv(i,j,k) * (dtvdz(i,j,k) + g/cp)elsensq3(i,j,k) = mdvendifenddoenddoenddoendc -----------------------------------------------------------------c Calculate potential vorticityc -----------------------------------------------------------------subroutine calc_pv (pv3,t3,p3,u3,v3,> z3,x2,y2,f2,nx,ny,nz,mdv)c Calculate potential vorticity <pv3> on the model grid. The grid isc specified in the horizontal by <xmin,ymin,dx,dy,nx,ny>. The numberc of vertical levels is <nz>. The input field are: potential temperaturec <th3>, horizontal wind <u3> and <v3>, density <rho3>, height <z3>.c The terms including the vertical velocity are neglected in the calculationc of the PV.implicit nonec Declaration of subroutine parametersinteger nx,ny,nzreal pv3 (nx,ny,nz)real t3 (nx,ny,nz)real p3 (nx,ny,nz)real u3 (nx,ny,nz)real v3 (nx,ny,nz)real z3 (nx,ny,nz)real x2 (nx,ny)real y2 (nx,ny)real f2 (nx,ny)real mdvc Physical and numerical parametersreal scaleparameter (scale=1.E6)real omegaparameter (omega=7.292E-5)real pi180parameter (pi180=3.141592654/180.)real epsparameter (eps=0.01)c Auxiliary variablesreal dtdz(nx,ny,nz)real dtdx(nx,ny,nz)real dtdy(nx,ny,nz)real dudz(nx,ny,nz)real dvdz(nx,ny,nz)real dvdx(nx,ny,nz)real dudy(nx,ny,nz)real rho3(nx,ny,nz)real th3 (nx,ny,nz)integer i,j,kc Calculate density and potential temperaturecall calc_rho (rho3,t3,p3,nx,ny,nz,mdv)call calc_theta (th3 ,t3,p3,nx,ny,nz,mdv)c Calculate needed derivativescall deriv (dudz, u3,'z',z3,x2,y2,nx,ny,nz,mdv)call deriv (dvdz, v3,'z',z3,x2,y2,nx,ny,nz,mdv)call deriv (dtdz,th3,'z',z3,x2,y2,nx,ny,nz,mdv)call deriv (dtdx,th3,'x',z3,x2,y2,nx,ny,nz,mdv)call deriv (dtdy,th3,'y',z3,x2,y2,nx,ny,nz,mdv)call deriv (dvdx, v3,'x',z3,x2,y2,nx,ny,nz,mdv)call deriv (dudy, u3,'y',z3,x2,y2,nx,ny,nz,mdv)c Calculate potential vorticitydo j=1,nydo i=1,nxdo k=1,nzc Evaluate PV formula with missing data checkif ((abs(dtdz(i,j,k)-mdv).gt.eps).and.> (abs(dudz(i,j,k)-mdv).gt.eps).and.> (abs(dtdy(i,j,k)-mdv).gt.eps).and.> (abs(dvdz(i,j,k)-mdv).gt.eps).and.> (abs(rho3(i,j,k)-mdv).gt.eps).and.> (abs(dtdx(i,j,k)-mdv).gt.eps).and.> (abs(dvdx(i,j,k)-mdv).gt.eps).and.> (abs(dudy(i,j,k)-mdv).gt.eps)) thenpv3(i,j,k)=scale*1./rho3(i,j,k)*> ((dvdx(i,j,k)-dudy(i,j,k)+f2(i,j))*dtdz(i,j,k)> +dudz(i,j,k)*dtdy(i,j,k)> -dvdz(i,j,k)*dtdx(i,j,k))elsepv3(i,j,k)=mdvendifenddoenddoenddoendc ****************************************************************c * SUBROUTINE SECTION: GRID HANDLING *c ****************************************************************c -----------------------------------------------------------------c Horizontal and vertical derivatives for 3d fieldsc -----------------------------------------------------------------subroutine deriv (df,f,direction,> z3,x2,y2,nx,ny,nz,mdv)c Calculate horizontal and vertical derivatives of the 3d field <f>.c The direction of the derivative is specified in <direction>c 'x','y' : Horizontal derivative in x and y directionc 'p','z','t','m' : Vertical derivative (pressure, height, theta, model)c The 3d field <z3> specifies the isosurfaces along which the horizontalc derivatives are calculated or the levels for the vertical derivatives.implicit nonec Input and output parametersinteger nx,ny,nzreal df (nx,ny,nz)real f (nx,ny,nz)real z3 (nx,ny,nz)real x2 (nx,ny)real y2 (nx,ny)character directionreal mdvc Numerical and physical parametersreal pi180parameter (pi180=3.141592654/180.)real zerodivparameter (zerodiv=0.00000001)real epsparameter (eps=0.01)c Auxiliary variablesinteger i,j,kreal vmin,vmaxreal scale,latreal vu,vl,vuvl,vlvuinteger o,u,w,e,n,sc Vertical derivativeif ((direction.eq.'z').or.> (direction.eq.'th').or.> (direction.eq.'p').or.> (direction.eq.'m').and.> (nz.gt.1)) thendo i=1,nxdo j=1,nydo k=1,nzo=k+1if (o.gt.nz) o=nzu=k-1if (u.lt.1) u=1if ((abs(f(i,j,o)-mdv).gt.eps).and.> (abs(f(i,j,u)-mdv).gt.eps).and.> (abs(f(i,j,k)-mdv).gt.eps)) thenvu = z3(i,j,k)-z3(i,j,o)vl = z3(i,j,u)-z3(i,j,k)vuvl = vu/(vl+zerodiv)vlvu = 1./(vuvl+zerodiv)df(i,j,k) = 1./(vu+vl)> * (vuvl*(f(i,j,u)-f(i,j,k))> + vlvu*(f(i,j,k)-f(i,j,o)))elsedf(i,j,k) = mdvendifenddoenddoenddoc Horizontal derivative in the y direction: 3delseif (direction.eq.'y') thendo i=1,nxdo j=1,nydo k=1,nzs=j-1if (s.lt.1) s=1n=j+1if (n.gt.ny) n=nyif ((abs(f(i,n,k)-mdv).gt.eps).and.> (abs(f(i,j,k)-mdv).gt.eps).and.> (abs(f(i,s,k)-mdv).gt.eps)) thenvu = 1000.*(y2(i,j)-y2(i,n))vl = 1000.*(y2(i,s)-y2(i,j))vuvl = vu/(vl+zerodiv)vlvu = 1./(vuvl+zerodiv)df(i,j,k) = 1./(vu+vl)> * (vuvl*(f(i,s,k)-f(i,j,k))> + vlvu*(f(i,j,k)-f(i,n,k)))elsedf(i,j,k) = mdvendifenddoenddoenddoc Horizontal derivative in the x direction: 3delseif (direction.eq.'x') thendo i=1,nxdo j=1,nydo k=1,nzw=i-1if (w.lt.1) w=1e=i+1if (e.gt.nx) e=nxif ((abs(f(w,j,k)-mdv).gt.eps).and.> (abs(f(i,j,k)-mdv).gt.eps).and.> (abs(f(e,j,k)-mdv).gt.eps)) thenvu = 1000.*(x2(i,j)-x2(e,j))vl = 1000.*(x2(w,j)-x2(i,j))vuvl = vu/(vl+zerodiv)vlvu = 1./(vuvl+zerodiv)df(i,j,k) = 1./(vu+vl)> * (vuvl*(f(w,j,k)-f(i,j,k))> + vlvu*(f(i,j,k)-f(e,j,k)))elsedf(i,j,k) = mdvendifenddoenddoenddoc Undefined direction for derivativeelseprint*,'Invalid direction of derivative... Stop'stopendifendc -----------------------------------------------------------------c Horizontal filterc -----------------------------------------------------------------subroutine filt2d (a,af,nx,ny,fil,misdat,& iperx,ipery,ispol,inpol)c Apply a conservative diffusion operator onto the 2d field a,c with full missing data checking.cc a real inp array to be filtered, dimensioned (nx,ny)c af real out filtered array, dimensioned (nx,ny), can bec equivalenced with array a in the calling routinec 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=1c corresponds to one application of the linear filter.c misdat real inp missing-data value, a(i,j)=misdat indicates thatc the corresponding value is not available. Thec 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)cc Christoph Schaer, 1993c argument declarationinteger nx,nyreal a(nx,ny),af(nx,ny),fil,misdatinteger iperx,ipery,inpol,ispolc local variable declarationinteger i,j,isreal fhreal f1(nx+1,ny),f2(nx,ny+1)c compute constant fhfh=0.125*filc compute fluxes in x-directionif (misdat.eq.0.) thendo j=1,nydo i=2,nxf1(i,j)=a(i-1,j)-a(i,j)enddoenddoelsedo j=1,nydo i=2,nxif ((a(i,j).eq.misdat).or.(a(i-1,j).eq.misdat)) thenf1(i,j)=0.elsef1(i,j)=a(i-1,j)-a(i,j)endifenddoenddoendifif (iperx.eq.1) thenc do periodic boundaries in the x-directiondo j=1,nyf1(1,j)=f1(nx,j)f1(nx+1,j)=f1(2,j)enddoelsec set boundary-fluxes to zerodo j=1,nyf1(1,j)=0.f1(nx+1,j)=0.enddoendifc compute fluxes in y-directionif (misdat.eq.0.) thendo j=2,nydo i=1,nxf2(i,j)=a(i,j-1)-a(i,j)enddoenddoelsedo j=2,nydo i=1,nxif ((a(i,j).eq.misdat).or.(a(i,j-1).eq.misdat)) thenf2(i,j)=0.elsef2(i,j)=a(i,j-1)-a(i,j)endifenddoenddoendifc set boundary-fluxes to zerodo i=1,nxf2(i,1)=0.f2(i,ny+1)=0.enddoif (ipery.eq.1) thenc do periodic boundaries in the x-directiondo i=1,nxf2(i,1)=f2(i,ny)f2(i,ny+1)=f2(i,2)enddoendifif (iperx.eq.1) thenif (ispol.eq.1) thenc do south-poleis=(nx-1)/2do i=1,nxf2(i,1)=-f2(mod(i-1+is,nx)+1,2)enddoendifif (inpol.eq.1) thenc do north-poleis=(nx-1)/2do i=1,nxf2(i,ny+1)=-f2(mod(i-1+is,nx)+1,ny)enddoendifendifc compute flux-convergence -> filterif (misdat.eq.0.) thendo j=1,nydo i=1,nxaf(i,j)=a(i,j)+fh*(f1(i,j)-f1(i+1,j)+f2(i,j)-f2(i,j+1))enddoenddoelsedo j=1,nydo i=1,nxif (a(i,j).eq.misdat) thenaf(i,j)=misdatelseaf(i,j)=a(i,j)+fh*(f1(i,j)-f1(i+1,j)+f2(i,j)-f2(i,j+1))endifenddoenddoendifend