program geos2fv,23 c****6***0*********0*********0*********0*********0*********0**********72 C Program to convert GEOS-2 A-grid data on sigma coordinate to C The hybrid sigma-P Eulerian coordinate coordinate for the C finite-volume GCM C The terrain and the IC for the fv-GCM must be 64-bit precision. C Must compile with "f90 -O -r8" if FVGCM restart is desired; -r8 no C longer necessary for grads or GFIO output (Arlindo) C Programmer : S.-J. Lin, Code 910.3, NASA/GSFC, with revisions by A. da Silva C Last modified: July 21, 1999 c The terrain data can be found on our machines at nas c /share/fvgcm/surf.data_144x91 for 2x2.5 c /share/fvgcm/surf.data_288x181 1x1.25 c /share/fvgcm/surf.data_576x361 0.5x0.625 c c REVISION HISTORY: c c dark ages SJ Lin Initial code. c c 10oct1999 da Silva Changed some real*8 into real for having the option of c compiling with 32 bits (otherwise it does not on my c linux box). When compiled in 32-bits the c restart option does not produce a valid output file. c c 02nov1999 da Silva Started conversion to read GEOS-DAS HDF files c written by GFIO. GEOS levels are still hardwired c in the main program butb get_geos2() now uses c dynamic allocation according to input file. c c 09nov1999 da Silva Reading of SST for dyn vect. c 06dec1999 da Silva Better defaults for sst/surf file names. c 18dec1999 da Silva Introduced f77 interface of dyn_init() c 20apr2001 da Silva Added option of sst fname = 'NONE', setting sst c to 288 K in this case. c c****6***0*********0*********0*********0*********0*********0**********72 use m_dyn ! dynamics state vector implicit none type(dyn_vect) w_f integer rc C Output horizontal resolution: integer imr, jmr integer jnp, nl parameter (imr=144, jmr=90) c parameter (imr=288, jmr=180) c parameter (imr=576, jmr=360) parameter (jnp = jmr+1) C Output vertical resolution c parameter(nl=32) parameter(nl=55) C Original data vertical resolution: For GEOS 48 and 70 layrs just C set olev below - no other change necessary (ams) integer plev c parameter (plev=55) c parameter (plev=70) parameter (plev=48) C Note: there are a few other hard-wired parameter statement that set the horizontal C resolution. (For example, in plft2d and lpft) C Input/output units: integer iuhs !unit to read terrain data for the fv integer iuic !unit to write IC for f-v dycore parameter (iuhs = 80) parameter (iuic = 81) integer it integer nymd, nhms, nstep include 'geos2fv.h' c ================= c Dynamical fields: c ================= real u(imr,jnp,nl) !zonal wind on D-grid real v(imr,jnp,nl) !meridional wind real pt(imr,jnp,nl) !scaled virture potential temperature real q(imr,jnp,nl,1) !specific humidity & tracer mixing ratios real delp(imr,jnp,nl) !pressure thickness in pascal real pe1(imr,nl+1) !pressure at layer edges real ps(imr, jnp) !surface pressure (pascal) real ts(imr, jnp) ! sea surface temperature real lwi(imr, jnp) ! land-water-mask for dyn_vect real ud(imr,jnp) !D-grid zonal wind real vd(imr,jnp) !D-grid meridional wind real*8 hs8(imr,jnp) !surface geopotential real*8 stdv8(imr,jnp) !surface geopotential stdv real hs(imr,jnp) !surface geopotential real phis(imr,jnp) !surface geopotential real stdv(imr,jnp) !surface geopotential stdv C Eta coordinate arrays and constants real ak(nl+1) real bk(nl+1) real ptop !pressure at model top real pint !Interface pressure integer ks !number of layers in pure p region real ps2(imr, jnp) real uwnd(imr,jnp,plev) real vwnd(imr,jnp,plev) real tmpu(imr,jnp,plev) real sphu(imr,jnp,plev) real pe2(imr, plev+1, jnp) real phis2(imr,jnp) real u2(imr,plev) real v2(imr,plev) real q2(imr,plev) real pk2(imr,plev+1) real peln(imr,plev+1) real pkz2(imr,plev) real ph2(imr,plev+1) real t2(imr,plev) real q_new(imr,nl) integer i,j,k integer fid, err, im, jm, km, lm, nvars, ngatts real grav real rh2o real rair real zvir real cappa real cpair !ams real*8 rkap !ams real*8 r8tmp real rkap real r8tmp real pmax, pmin, vmax real diff(imr, jnp) real dlp, beta real dp1(imr, nl) real dp2(imr, plev) integer npt logical geos2 geos2 = .true. c Get file names and dates from command line c ------------------------------------------ call parse_cmd ( nymd, nhms, imr, jnp, nstep ) C Hard wired year/date C get geos-2 data C Constants: grav = 9.80616 rh2o = 4.61e2 rair = 287.04 zvir = rh2o/rair - 1. cpair = 1004.64 cappa = rair/cpair rkap = cpair/rair write(6,*) 'grav=',grav,' zvir=',zvir,' cappa=',cappa write(6,*) 'rkap=', rkap write(6,*) ' ' C get SST if writing GFIO file if ( ftype .eq. GFIO ) then if ( trim(sfname) .ne. 'NONE' ) then call GFIO_Open ( trim(sfname), READ_ONLY, fid, err ) if ( err .ne. 0 ) then print *, 'geos2fv: cannot open SST file '//trim(sfname) stop endif call GFIO_DimInquire ( fid, im, jm, km, lm, nvars, ngatts, err) if ( err .ne. 0 ) then print *, 'geos2fv: error reading SST file '//trim(sfname) stop endif if ( im .ne. imr .or. jm .ne. jnp ) then print *, 'geos2fv: SST file has inconsistent dimensions' print *, 'geos2fv: SST file has im, jm: ', im, jm print *, 'geos2fv: SST file should have im, jm: ', imr, jnp stop end if call GFIO_GetVarT ( fid, 'SST', nymd, nhms, & im, jm, 0, 1, Ts, err ) if ( err .ne. 0 ) then print *, 'geos2fv: could not read sst' stop end if print * print *, 'geos2fv: just read SST file ', trim(sfname) Ts = Ts + 273. ! convert to Kelvin else Ts = 15. + 273. end if pmax = vmax(Ts,pmin,imr*jnp) write(6,*) 'SST: max=', pmax, ' min=', pmin print * end if C get terrain (in geopotential unit) for fvcore open(iuhs,file=tfname,form='unformatted') read(iuhs) hs8 read(iuhs) stdv8 do j=1,jnp do i=1,imr phis(i,j) = hs8(i,j) stdv(i,j) = stdv8(i,j) enddo enddo c Check topography for fvcore pmax = vmax(phis,pmin,imr*jnp) write(6,*) 'FVCORE: max hs=', pmax/grav, ' min=', pmin/grav if(geos2) then call get_geos2( nymd, nhms, imr, jnp, plev, phis2, ps2, & uwnd, vwnd, tmpu, sphu, pe2) else call get_d_rst(imr, jnp, plev, phis2, ps2, & uwnd, vwnd, tmpu, sphu, pe2) endif c Check topography pmax = vmax(phis2,pmin,imr*jnp) write(6,*) 'Original: max hs=', pmax/grav, ' min=', pmin/grav pmax = vmax(ps2,pmin,imr*jnp) write(6,*) 'max PS (mb)=', pmax/100., ' min=', pmin/100. pmax = vmax(pe2,pmin,imr*jnp*(plev+1)) write(6,*) 'max PE=', pmax/100., ' min=', pmin/100. pmax = vmax(uwnd,pmin,imr*jnp*plev) write(6,*) 'max U=', pmax, ' min=', pmin pmax = vmax(vwnd,pmin,imr*jnp*plev) write(6,*) 'max V=', pmax, ' min=', pmin pmax = vmax(tmpu,pmin,imr*jnp*plev) write(6,*) 'max T=', pmax, ' min=', pmin pmax = vmax(sphu,pmin,imr*jnp*plev) write(6,*) 'max Q=', pmax, ' min=', pmin do j=1, jnp do i=1,imr diff(i,j) = phis(i,j) - phis2(i,j) enddo enddo pmax = vmax(diff,pmin,imr*jnp) write(6,*) 'Phis (NEW-OLD) max =', pmax/grav, ' min=', pmin/grav write(6,*) 'ptop=', pe2(1,1,1) C setup vertical coordinate call set_eta(nl,ks,ptop,pint,ak,bk) do 1000 j=1,jnp C Comput pk2 do k=1,plev+1 do i=1,imr pk2(i,k) = pe2(i,k,j)**cappa peln(i,k) = log(pe2(i,k,j)) enddo enddo do k=1,plev do i=1,imr dp2(i,k) = pe2(i,k+1,j) - pe2(i,k,j) enddo enddo C Compute dry pt do k=1, plev do i=1,imr C Comput pkz2 pkz2(i,k) = (pk2(i,k+1) - pk2(i,k) ) / & (cappa*(peln(i,k+1) - peln(i,k)) ) enddo enddo do k=1, plev do i=1,imr if(geos2) then C Convert tmpu to potential temp t2(i,k) = tmpu(i,j,k)/pkz2(i,k) else t2(i,k) = tmpu(i,j,k) endif enddo enddo do k=1, plev do i=1,imr u2(i,k) = uwnd(i,j,k) v2(i,k) = vwnd(i,j,k) q2(i,k) = sphu(i,j,k) enddo enddo C Do dry convective adjustment do it = 1, 5 call dry_adj(imr, plev, plev-1, t2, & u2, v2, q2, dp2, npt) if(npt .ne. 0) then !!! write(6,*) 'j= ',j,' dry unstable points=', npt else go to 333 endif enddo 333 continue C Convert pt to virture potential temp if(geos2) then do k=1, plev do i=1,imr t2(i,k) = t2(i,k)*(1.+zvir*q2(i,k)) enddo enddo endif do i=1,imr ph2(i,plev+1) = phis2(i,j) enddo do k=plev,1,-1 do i=1,imr ph2(i,k) = ph2(i,k+1) + cpair*t2(i,k)* & (pk2(i,k+1) - pk2(i,k)) enddo enddo c****6***0*********0*********0*********0*********0*********0**********72 C Adjust ps2 to new terrain c****6***0*********0*********0*********0*********0*********0**********72 do i=1,imr if(phis(i,j) .ge. phis2(i,j)) then c if(phis(i,j) .ge. ph2(i,plev+1)) then C Interpolation C --- searching ... do k=plev,1,-1 if(phis(i,j) .le. ph2(i,k) .and. & phis(i,j) .ge. ph2(i,k+1)) then c dlp = pe2(i,k+1,j)-pe2(i,k,j) c beta= (ph2(i,k)-phis(i,j)) / (ph2(i,k)-ph2(i,k+1)) c ps(i,j) = pe2(i,k,j) + dlp*beta dlp = pk2(i,k+1)-pk2(i,k) beta= (ph2(i,k)-phis(i,j)) / (ph2(i,k)-ph2(i,k+1)) r8tmp = pk2(i,k) + dlp*beta ps(i,j) = r8tmp ** (1./cappa) C Bug... c ps(i,j) = r8tmp ** rkap C Safety check if(ps(i,j) .gt. ps2(i,j)) Then write(6,*) k, 'Interpolation failed' write(6,*) i,j, ps2(i,j), phis2(i,j) write(6,*) ps(i,j), phis(i,j), dlp, beta stop endif go to 123 endif enddo 123 continue else C Extrapolation !!! r8tmp = pk2(i,plev+1) + (phis2(i,j)-phis(i,j)) / * (cpair*t2(i,plev)) ps(i,j) = r8tmp ** (1./cappa) c ps(i,j) = r8tmp ** rkap endif enddo do i = 1, imr pe1(i, 1) = ptop pe2(i, 1,j) = ptop pe1(i,nl+1) = ps(i,j) enddo do k=2,nl do i=1,imr pe1(i,k) = ak(k) + ps(i,j)*bk(k) enddo enddo do k=1,nl do i=1,imr dp1(i,k) = pe1(i,k+1) - pe1(i,k) delp(i,j,k) = dp1(i,k) enddo enddo c****6***0*********0*********0*********0*********0*********0**********72 C map u c****6***0*********0*********0*********0*********0*********0**********72 call mappm(plev, pe2(1,1,j), dp2, u2, nl, pe1, dp1, q_new, & imr, 1, 3) do k=1,nl do i=1,imr u(i,j,k) = q_new(i,k) enddo enddo c****6***0*********0*********0*********0*********0*********0**********72 C map v c****6***0*********0*********0*********0*********0*********0**********72 call mappm(plev, pe2(1,1,j), dp2, v2, nl, pe1, dp1, q_new, & imr, 1, 3) do k=1,nl do i=1,imr v(i,j,k) = q_new(i,k) enddo enddo c****6***0*********0*********0*********0*********0*********0**********72 C map water vapor c****6***0*********0*********0*********0*********0*********0**********72 call mappm(plev, pe2(1,1,j), dp2, q2, nl, pe1, dp1, q_new, & imr, 0, 5) do k=1,nl do i=1,imr q(i,j,k,1) = q_new(i,k) enddo enddo c****6***0*********0*********0*********0*********0*********0**********72 C map pt using geopotential conserving scheme. c****6***0*********0*********0*********0*********0*********0**********72 do k=1,plev do i=1,imr dp2(i,k) = pk2(i,k+1) - pk2(i,k) enddo enddo do k=1,nl+1 do i=1,imr pe1(i,k) = pe1(i,k) ** cappa enddo enddo do k=1,nl do i=1,imr dp1(i,k) = pe1(i,k+1) - pe1(i,k) enddo enddo call mappm(plev, pk2, dp2, t2, nl, pe1, dp1, q_new, & imr, 1, 3) C Do Dry convective adjustment here... do k=1,nl do i=1,imr pt(i,j,k) = q_new(i,k) enddo enddo 1000 continue write(6,*) ' ' write(6,*) 'Checking PS for fvcore' pmax = vmax(ps,pmin,imr*jnp) write(6,*) 'max PS (mb)=', pmax/100., ' min=', pmin/100. pmax = vmax(u,pmin,imr*jnp*nl) write(6,*) 'max U=', pmax, ' min=', pmin pmax = vmax(v,pmin,imr*jnp*nl) write(6,*) 'max V=', pmax, ' min=', pmin pmax = vmax(pt,pmin,imr*jnp*nl) write(6,*) 'max PT=', pmax, ' min=', pmin pmax = vmax(q,pmin,imr*jnp*nl) write(6,*) 'max Q=', pmax, ' min=', pmin C A to D transform... do k=1, nl call atod(u(1,1,k),v(1,1,k),ud,vd,imr,jnp) do j=1,jnp do i=1,imr u(i,j,k) = ud(i,j) v(i,j,k) = vd(i,j) enddo enddo enddo pmax = vmax(u,pmin,imr*jnp*nl) write(6,*) 'max U=', pmax, ' min=', pmin pmax = vmax(v,pmin,imr*jnp*nl) write(6,*) 'max V=', pmax, ' min=', pmin C write IC for fvgcm C 8-BYTE print *, 'Number of levels is ', nl hs = hs8 print * if ( ftype .eq. RESTART ) then print *, ' [] writing RESTRAT file ', trim(ofname) open(iuic,file=ofname,form='unformatted') write(iuic) nstep, nymd, nhms write(iuic) ps,delp,u,v,pt write(iuic) q close(iuic) else if ( ftype .eq. GRADS ) then print *, ' [] writing GRADS file ', trim(ofname) open(iuic,file=ofname,form='unformatted') call write_grads ( iuic, hs, imr, jnp, 1 ) call write_grads ( iuic, ps, imr, jnp, 1 ) call write_grads ( iuic, delp, imr, jnp, nl ) call write_grads ( iuic, u, imr, jnp, nl ) call write_grads ( iuic, v, imr, jnp, nl ) call write_grads ( iuic, pt, imr, jnp, nl ) call write_grads ( iuic, q, imr, jnp, nl ) close(iuic) else if ( ftype .eq. GFIO ) then print *, ' [] writing GFIO file ', trim(ofname) lwi(:,:) = 0.0 ! aqua-planet for now. call Dyn_Init ( imr, jnp, nl, 1, ptop, ks, ak, bk, & phis, stdv, Ts, lwi, ps, & delp, u, v, pt, q, w_f, rc ) if ( rc .ne. 0 ) then print *, 'geos2fv: could not initialize w_f' stop else print *, 'geos2fv: initialized w_f' end if print *, 'geos2fv: about to put...' if ( prec .eq. 32 ) prec = 0 if ( prec .eq. 64 ) prec = 1 call dyn_put ( ofname, nymd, nhms, prec, w_f, rc, & nstep=nstep, verbose=.true. ) if ( rc .ne. 0 ) then print *, 'geos2fv: cannot write w_f ', rc stop end if else print *, 'Oops, cannot write output file type ', ftype stop endif stop end subroutine get_d_rst(im, jm, km, hs, ps, u, v, t, q, pe) 1,8 implicit none integer im integer jm integer km integer i,j,k integer in integer jn parameter(in=288, jn=181) real hs(im,jm) ! surface geopotential (m/sec)**2 real ps(im,jm) ! surface pressure (mb) real u(im,jm,km) ! U-Wind (m/sec) real v(im,jm,km) ! V-Wind (m/sec) real t(im,jm,km) ! temperature (K) real q(im,jm,km) ! specific humidity (g/kg) real pe(im,km+1,jm) ! Pressure mb real phis(in,jn) ! surface geopotential (m/sec)**2 real ps2(in,jn) ! surface pressure (mb) real u2(in,jn,km) ! U-Wind (m/sec) real v2(in,jn,km) ! V-Wind (m/sec) real t2(in,jn,km) ! temperature (K) real q2(in,jn,km) ! specific humidity (g/kg) real coslon(in), sinlon(in) real ptop, pint real dl, pi real ak(km+1), bk(km+1) integer nstep, nymd, nhms integer ks pi = 4.0 * atan(1.0) dl = (pi+pi)/float(in) do i=1,in/2 coslon(i) = -cos((i-1)*dl) coslon(i+in/2) = -coslon(i) sinlon(i) = -sin((i-1)*dl) sinlon(i+in/2) = -sinlon(i) enddo C Set up coord call set_eta(km,KS,PTOP,PINT,ak,bk) C Read in phis read(70) phis C Read d-rst read(71) nstep, nymd, nhms read(71) ps2, u2, u2, v2, t2 read(71) q2 if(in .ne. im) then C Interpolate all fields, including phis, to finer grid. C phis call lo2hi(phis, hs, in, jn, im, jm, 0) call lo2hi( ps2, ps, in, jn, im, jm, 0) do 2000 k=1, km C t call lo2hi(t2(1,1,k), t(1,1,k), in, jn, im, jm, 0) C q call lo2hi(q2(1,1,k), q(1,1,k), in, jn, im, jm, 0) C D -> A call d2a(u2(1,1,k),v2(1,1,k),u2(1,1,k),v2(1,1,k), & in, jn, coslon, sinlon) C u call lo2hi(u2(1,1,k), u(1,1,k), in, jn, im, jm, 1) C v call lo2hi(v2(1,1,k), v(1,1,k), in, jn, im, jm, 1) 2000 continue else C Copying .... do j=1, jm do i=1, im ps(i,j) = ps2(i,j) hs(i,j) = phis(i,j) enddo enddo do k=1, km do j=1, jm do i=1, im t(i,j,k) = t2(i,j,k) q(i,j,k) = q2(i,j,k) u(i,j,k) = u2(i,j,k) v(i,j,k) = v2(i,j,k) enddo enddo enddo endif C Recompute pe do j=1, jm do i=1, im pe(i,1,j) = ptop pe(i,km+1,j) = ps(i,j) enddo enddo do k=2,km do j=1, jm do i=1, im pe(i,k,j) = ak(k) + bk(k)*ps(i,j) enddo enddo enddo return end !........................................................................ subroutine get_geos2 ( nymd, nhms, im, jm, km, 1,20 & hs, ps, u, v, t, q, pe) implicit none include 'geos2fv.h' ! Input file name comes from here integer nymd, nhms integer im integer jm integer km integer i,j,k real hs(im,jm) ! surface geopotential (m/sec)**2 real ps(im,jm) ! surface pressure (mb) c real slp(im,jm) ! sea level pressure (mb) real u(im,jm,km) ! U-Wind (m/sec) real v(im,jm,km) ! V-Wind (m/sec) c real h(im,jm,km) ! pertabation geopotential height (m) real t(im,jm,km) ! temperature (K) real q(im,jm,km) ! specific humidity (g/kg) real pe(im,km+1,jm) ! Pressure mb C GEOS-2 DAS Data integer in integer jn !ams parameter(in=144, jn=91) !ams real phis(in,jn) ! surface geopotential (m/sec)**2 !ams real ps2(in,jn) ! surface pressure (mb) !ams real u2(in,jn,km) ! U-Wind (m/sec) !ams real v2(in,jn,km) ! V-Wind (m/sec) !ams real t2(in,jn,km) ! temperature (K) !ams real q2(in,jn,km) ! specific humidity (g/kg) !ams real rh2(in,jn,km) ! relative humidity (g/kg) real, allocatable :: phis(:,:) ! surface geopotential (m/sec)**2 real, allocatable :: ps2(:,:) ! surface pressure (mb) real, allocatable :: u2(:,:,:) ! U-Wind (m/sec) real, allocatable :: v2(:,:,:) ! V-Wind (m/sec) real, allocatable :: t2(:,:,:) ! temperature (K) real, allocatable :: q2(:,:,:) ! specific humidity (g/kg) real, allocatable :: rh2(:,:,:) ! relative humidity (g/kg) real, allocatable :: sige(:) real ptop logical filter data filter /.false./ integer ndeg !!! real pmin, pmax, vmax integer ier, imf, jmf, kmf C Get geos-2 das data C Sharon's version c call readprog(in, jn, km, phis, ps2, u2, v2, t2, q2, c & ptop, sige) C Arlindo's version c call readieee(in, jn, km, phis, ps2, u2, v2, t2, q2, c & ptop, sige) ! Read PROG/SIG files written by GFIO ! ----------------------------------- call ProgSig_Dim ( trim(ifname), imf, jmf, kmf, ier ) if ( ier .ne. 0 ) then print *, 'get_geos2: cannot get dims from ', trim(ifname) call exit(7) stop else if ( km .ne. kmf ) then print *, 'get_geos2: imcompatible vertical dimensions' print *, 'get_geos2: km on file: ', kmf print *, 'get_geos2: km in here: ', km call exit(7) stop end if ! Allocate necessary memory ! ------------------------- in = imf; jn = jmf allocate ( sige(km+1), phis(in,jn), ps2(in,jn), & u2(in,jn,km), v2(in,jn,km), t2(in,jn,km), & q2(in,jn,km), rh2(in,jn,km), stat = ier ) if ( ier .ne. 0 ) then print *, 'get_geos2: cannot allocate memory ' call exit(7) stop end if ! OK, just read the data. Note: ps, ptop in Pa, sphi in kg/kg ! ----------------------------------------------------------- call ProgSig_Read ( trim(ifname), nymd, nhms, & in, jn, km, ptop, sige, & phis, ps2, u2, v2, t2, q2, rh2, ier ) if ( ier .ne. 0 ) then print *, 'getgeos2: cannot read ', trim(ifname) call exit(7) stop end if ! Turn fields upside down ! ----------------------- u2(:,:,1:km) = u2(:,:,km:1:-1) v2(:,:,1:km) = v2(:,:,km:1:-1) t2(:,:,1:km) = t2(:,:,km:1:-1) q2(:,:,1:km) = q2(:,:,km:1:-1) rh2(:,:,1:km) = rh2(:,:,km:1:-1) C Shift 180 deg for CCM3 phys package. call shiftx(phis, in, jn, 1) call shiftx(ps2, in, jn, 1) call shiftx(u2, in, jn, km) call shiftx(v2, in, jn, km) call shiftx(t2, in, jn, km) call shiftx(q2, in, jn, km) if( in .ne. im) then C Interpolate all fields, including phis, to finer grid. C phis call lo2hi(phis, hs, in, jn, im, jm, 0) call lo2hi( ps2, ps, in, jn, im, jm, 0) do 2000 k=1, km C t call lo2hi(t2(1,1,k), t(1,1,k), in, jn, im, jm, 0) C q call lo2hi(q2(1,1,k), q(1,1,k), in, jn, im, jm, 0) C u call lo2hi(u2(1,1,k), u(1,1,k), in, jn, im, jm, 1) C v call lo2hi(v2(1,1,k), v(1,1,k), in, jn, im, jm, 1) 2000 continue else C Copying .... do j=1, jm do i=1, im ps(i,j) = ps2(i,j) ! mb -> Pa hs(i,j) = phis(i,j) enddo enddo do k=1, km C Debug .. c pmax = vmax(t2(1,1,k),pmin,in*jn) c write(6,*) k, ' max T=', pmax, ' min=', pmin do j=1, jm do i=1, im t(i,j,k) = t2(i,j,k) q(i,j,k) = q2(i,j,k) u(i,j,k) = u2(i,j,k) v(i,j,k) = v2(i,j,k) enddo enddo enddo endif if (filter) then ndeg = 80 call plft2d(ps, 2, jm-1, ndeg) call plft2d(hs, 2, jm-1, ndeg) do k=1, km call plft2d(u(1,1,k), 2, jm-1, ndeg) call plft2d(v(1,1,k), 2, jm-1, ndeg) call plft2d(t(1,1,k), 2, jm-1, ndeg) call plft2d(q(1,1,k), 2, jm-1, ndeg) enddo endif C Recompute pe based on ps and sige do j=1, jm do i=1, im pe(i,1,j) = ptop pe(i,km+1,j) = ps(i,j) enddo enddo do k=2,km do j=1, jm do i=1, im pe(i,k,j) = (ps(i,j)-ptop)*sige(k) + ptop enddo enddo enddo ! Free local workspace ! -------------------- deallocate ( sige, phis, ps2, u2, v2, t2, q2, rh2 ) return end subroutine lo2hi(qh, q, imh, jmh, im, jm, iv) 12,1 implicit none integer iv C iv=0: Scalar C iv=1: vector C Interpolation to finer grid in y C Mapping in x integer i, j integer im, jm integer imh, jmh integer ih, jh real sum1, sum2 real qh(imh, jmh) ! coarse grid data real q (im, jm) ! 2x grid data C Poles: if( iv .eq. 0) then C Scalars sum1 = 0. sum2 = 0. do i=1, imh sum1 = sum1 + qh(i,1) sum2 = sum2 + qh(i,jmh) enddo sum1 = sum1 / float(imh) sum2 = sum2 / float(imh) do i=1, im q(i, 1) = sum1 q(i,jm) = sum2 enddo else C Vector: do i=1, im-1, 2 ih = i/2 + 1 q(i, 1) = qh(ih,1) q(i,jm) = qh(ih,jmh) enddo do i=2,im-2, 2 q(i, 1) = 0.5*(q(i-1,1)+q(i+1,1)) q(i,jm) = 0.5*(q(i-1,jm)+q(i+1,jm)) enddo C i=im q(im, 1) = 0.5*(q(im-1, 1)+q(1, 1)) q(im,jm) = 0.5*(q(im-1,jm)+q(1,jm)) endif C PPM Mapping in E-W: do 2000 j=3, jm-2, 2 jh = j/2 + 1 call xppmap(im, imh, qh(1,jh), q(1,j)) 2000 continue C N-S Interpolation: do 3000 j=2, jm-1, 2 do i=1,im q(i,j) = 0.5*(q(i,j-1)+q(i,j+1)) enddo 3000 continue return end subroutine xppmap(im, imh, qh, q) 1,2 implicit none integer im, imh integer i, ih real qh(*) real q(*) real temp real r3 parameter ( r3 = 1./3.) real r16, r56 parameter ( r16 = 1./16., r56 = 5./6.) C Local Auto arrays: real dm(imh) real a3(3,imh) real a4(4,imh) call mist(imh,qh,dm) do i=1,imh a4(1,i) = qh(i) enddo c i=1 a4(2,1) = 0.5*(qh(imh)+qh(1)) + (dm(imh) - dm(1))*r3 do i=2,imh a4(2,i) = 0.5*(qh(i-1)+qh(i)) + (dm(i-1) - dm(i))*r3 enddo do i=1,imh-1 a4(3,i) = a4(2,i+1) enddo a4(3,imh) = a4(2,1) do i=1,imh a4(4,i) = 3.*(a4(1,i)+a4(1,i) - (a4(2,i)+a4(3,i))) enddo call kmppm(dm, a4, imh, 0) do i=1,imh a4(1,i) = qh(i) a4(2,i) = qh(i) a4(3,i) = qh(i) a4(4,i) = 0. enddo do i=1,imh temp = a4(2,i)+a4(3,i) + r56*a4(4,i) C left: a3(1,i) = r16*(temp + 6.*a4(2,i)) C Right: a3(3,i) = r16*(temp + 6.*a4(3,i)) C Center: a3(2,i) = 2.*qh(i) - (a3(1,i)+a3(3,i)) enddo do i=1,im-1,2 ih = i/2 + 1 q(i) = a3(2,ih) enddo do i=2,im-2,2 ih = i/2 q(i) = a3(3,ih) + a3(1,ih+1) enddo q(im) = a3(3,imh) + a3(1,1) return end c****6***0*********0*********0*********0*********0*********0**********72 subroutine mist(im,p,dm) 1 c****6***0*********0*********0*********0*********0*********0**********72 implicit none integer im integer i real p(im) real dm(im) real pmin, pmax C i=1 dm(1) = 0.25*(p(2) - p(im)) do i=2,im-1 dm(i) = 0.25*(p(i+1) - p(i-1)) enddo C i=im dm(im) = 0.25*(p(1) - p(im-1)) c Apply monotonicity constraint (Lin et al. 1994, MWR) i=1 pmax = max(p(im), p(i), p(2)) - p(i) pmin = p(i) - min(p(im), p(i), p(2)) dm(i) = sign(min(abs(dm(i)),pmax,pmin), dm(i)) do 20 i=2,im-1 pmax = max(p(i-1), p(i), p(i+1)) - p(i) pmin = p(i) - min(p(i-1), p(i), p(i+1)) dm(i) = sign(min(abs(dm(i)),pmax,pmin), dm(i)) 20 continue i = im pmax = max(p(i-1), p(i), p(1)) - p(i) pmin = p(i) - min(p(i-1), p(i), p(1)) dm(i) = sign(min(abs(dm(i)),pmax,pmin), dm(i)) return end subroutine lo2hio_int(qh, q, imh, jmh, im, jm, iv) implicit none integer iv C iv=0: Scalar C iv=1: vector C Linear interpolation integer i, j integer im, jm integer imh, jmh integer ih, jh real sum1, sum2 real qh(imh, jmh) ! coarse grid data real q (im, jm) ! 2x grid data C Poles: if( iv .eq. 0) then C Scalars sum1 = 0. sum2 = 0. do i=1, imh sum1 = sum1 + qh(i,1) sum2 = sum2 + qh(i,jmh) enddo sum1 = sum1 / float(imh) sum2 = sum2 / float(imh) do i=1, im q(i, 1) = sum1 q(i,jm) = sum2 enddo else C Vector: do i=1, im-1, 2 ih = i/2 + 1 q(i, 1) = qh(ih,1) q(i,jm) = qh(ih,jmh) enddo do i=2,im-2, 2 q(i, 1) = 0.5*(q(i-1,1)+q(i+1,1)) q(i,jm) = 0.5*(q(i-1,jm)+q(i+1,jm)) enddo C i=im q(im, 1) = 0.5*(q(im-1, 1)+q(1, 1)) q(im,jm) = 0.5*(q(im-1,jm)+q(1,jm)) endif do 2000 j=3, jm-2, 2 do i=1,im-1, 2 ih = i/2 + 1 jh = j/2 + 1 q(i,j) = qh(ih,jh) enddo do i=2,im-2, 2 q(i,j) = 0.5*(q(i-1,j)+q(i+1,j)) enddo C i=im q(im,j) = 0.5*(q(im-1,j)+q(1,j)) 2000 continue do 3000 j=2, jm-1, 2 do i=1,im q(i,j) = 0.5*(q(i,j-1)+q(i,j+1)) enddo 3000 continue return end subroutine readieee(imr, jnp, km, phis, ps,,9 & uwnd, vwnd, tmpu, sphu, ptop, sge) C This program Reads Arlindo's data C C Modified from original code from S. Nebuda implicit none integer imr integer jnp integer im integer jm integer km integer nlayr integer ntime real ptop parameter (im = 144) ! number of x points parameter (jm = 91) ! number of y points parameter (nlayr = 70) ! geos-2 70 level resolution parameter (ntime = 1) ! number of times c input real phis(im,jm) ! surface geopotential (m/sec)**2 real ps(im,jm) ! surface pressure (mb) real slp(im,jm) ! sea level pressure (mb) real lwi(im,jm) ! Surface Types from Land/Surface Model real uwnd(im,jm,nlayr) ! U-Wind (m/sec) real vwnd(im,jm,nlayr) ! V-Wind (m/sec) c real hghtp(im,jm,nlayr) ! pertabation geopotential height (m) real tmpu(im,jm,nlayr) ! temperature (K) real sphu(im,jm,nlayr) ! specific humidity (g/kg) c real rh(im,jm,nlayr) ! relative humidity (%) c unique to the routine !!! character*60 filein ! filename of input include 'geos2fv.h' integer i,j,k ! loop variables !!! integer nri ! record number of input and output file real sig(nlayr) ! sigma levels of data real sge(nlayr+1) ! edge sigma levels of data real sige(nlayr+1) ! edge sigma levels of data real fac real wk(im,jm) !!! real pmin, pmax, vmax integer iu integer irec c--------------- Grads input file --------------------------- C DSET /monthlyb/nebuda/e0523.progsig.t960917.data C FORMAT SEQUENTIAL C TITLE e0523d Control assimilation for NSCAT C UNDEF 0.100000E+16 C XDEF 144 LINEAR -180.0 2.50000000 C YDEF 91 LINEAR -90.0 2.00000000 C ZDEF 70 LEVELS 70.00 69.00 68.00 67.00 66.00 C 65.00 64.00 63.00 62.00 61.00 C 60.00 59.00 58.00 57.00 56.00 C 55.00 54.00 53.00 52.00 51.00 C 50.00 49.00 48.00 47.00 46.00 C 45.00 44.00 43.00 42.00 41.00 C 40.00 39.00 38.00 37.00 36.00 C 35.00 34.00 33.00 32.00 31.00 C 30.00 29.00 28.00 27.00 26.00 C 25.00 24.00 23.00 22.00 21.00 C 20.00 19.00 18.00 17.00 16.00 C 15.00 14.00 13.00 12.00 11.00 C 10.00 9.00 8.00 7.00 6.00 C 5.00 4.00 3.00 2.00 1.00 C TDEF 1 LINEAR 00:00Z17SEP96 6hr C VARS 10 C PHIS 0 0 Surface Geopotential Heights (m/sec)**2 C PS 0 0 Surface Pressure (mb) C SLP 0 0 Sea Level Pressure (mb) C LWI 0 0 Surface Types from Land/Surface Model C UWND 70 0 U-Wind (m/sec) C VWND 70 0 V-Wind (m/sec) C HGHTP 70 0 Perturbation Geopotential Height (m) C TMPU 70 0 Temperature (K) C SPHU 70 0 Specific Humidity (g/kg) C RH 70 0 Relative Humidity (Percent) C ENDVARS c--------------- Variable Initialization ------------------------ data sige / . 0.000000E+00 , 6.016350E-06 , 1.370820E-05 , 2.295240E-05 , . 3.401840E-05 , 4.802090E-05 , 6.594130E-05 , 8.865010E-05 , . 1.177850E-04 , 1.550160E-04 , 2.024040E-04 , 2.624830E-04 , . 3.383480E-04 , 4.337660E-04 , 5.532970E-04 , 7.024390E-04 , . 8.877800E-04 , 1.118005E-03 , 1.403066E-03 , 1.754897E-03 , . 2.187742E-03 , 2.718547E-03 , 3.367386E-03 , 4.157950E-03 , . 5.118086E-03 , 6.280394E-03 , 7.682883E-03 , 9.369687E-03 , . 1.139184E-02 , 1.380810E-02 , 1.668584E-02 , 2.010197E-02 , . 2.414387E-02 , 2.891042E-02 , 3.451000E-02 , 4.107631E-02 , . 4.872000E-02 , 5.757372E-02 , 6.781108E-02 , 7.963646E-02 , . 9.325208E-02 , 1.088781E-01 , 1.267550E-01 , 1.471300E-01 , . 1.703000E-01 , 1.965500E-01 , 2.262500E-01 , 2.595500E-01 , . 2.962800E-01 , 3.360700E-01 , 3.784500E-01 , 4.230300E-01 , . 4.694000E-01 , 5.170351E-01 , 5.654188E-01 , 6.138495E-01 , . 6.615992E-01 , 7.078959E-01 , 7.519437E-01 , 7.929700E-01 , . 8.303000E-01 , 8.635700E-01 , 8.927438E-01 , 9.179000E-01 , . 9.392300E-01 , 9.570000E-01 , 9.715000E-01 , 9.829000E-01 , . 9.914000E-01 , 9.970951E-01 , 1.000000E+00 / if(im .ne. imr) then write(6,*) 'Stop!', im, imr stop endif if(km .ne. nlayr) then write(6,*) 'Stop!', km, nlayr stop endif C Arlindo's dataset !!! filein = 'uth01.fg.t19971221.dat' C In pascal!!! ptop = 1. ! model top pressure level ! Read the data for t=1 ! --------------------- iu = 20 open(iu,file=ifname,form='unformatted', & access='direct',recl=im*jm*4) irec = 0 call read_grads ( iu, phis, im, jm, 1, irec ) call read_grads ( iu, ps, im, jm, 1, irec ) call read_grads ( iu, slp, im, jm, 1, irec ) call read_grads ( iu, lwi, im, jm, 1, irec ) do k = nlayr, 1, -1 call read_grads ( iu, wk, im, jm, 1, irec ) do j=1, jm do i=1,im uwnd(i,j,k) = wk(i,j) enddo enddo enddo do k = nlayr, 1, -1 call read_grads ( iu, wk, im, jm, 1, irec ) do j=1, jm do i=1,im vwnd(i,j,k) = wk(i,j) enddo enddo enddo do k = nlayr, 1, -1 call read_grads ( iu, wk, im, jm, 1, irec ) do j=1, jm do i=1,im tmpu(i,j,k) = wk(i,j) enddo enddo enddo do k = nlayr, 1, -1 call read_grads ( iu, wk, im, jm, 1, irec ) do j=1, jm do i=1,im sphu(i,j,k) = wk(i,j) enddo enddo enddo do k = nlayr, 1, -1 call read_grads ( iu, wk, im, jm, 1, irec ) do j=1, jm do i=1,im c rh(i,j,k) = wk(i,j) enddo enddo enddo c------------- Compute New output --------------------------------------- do k = 1, nlayr+1 sge(k) = sige(k) enddo do k = 1, nlayr sig(k) = (sige(k) + sige(k+1)) * 0.5 C write(6,*) k, sig(k) enddo C Convert mb to pascal fac = 100. do j = 1, jm do i = 1, im ps(i,j) = ps(i,j) * fac enddo enddo do k = 1, nlayr do j = 1, jm do i = 1, im sphu(i,j,k) = 0.001*sphu(i,j,k) enddo enddo enddo c enddo ! time loop close(iu) return end subroutine read_grads ( iu, a, im, jm, km, irec ) 9 real a(im,jm,km) real*4 buffer(im,jm) do k = 1, km irec = irec + 1 read(iu,rec=irec) buffer do j = 1, jm do i = 1, im a(i,j,k) = buffer(i,j) end do end do end do return end subroutine write_grads ( iu, a, im, jm, km ) 41,2 real a(im,jm,km) real*4 buffer(im,jm) do k = 1, km do j = 1, jm do i = 1, im buffer(i,j) = a(i,j,k) end do end do write(iu) buffer end do return end subroutine readprog(imr, jnp, km, phis, ps, & uwnd, vwnd, tmpu, sphu, ptop, sge) C C Modified from original code from S. Nebuda implicit none integer imr integer jnp integer im integer jm integer km integer nlayr integer ntime real ptop parameter (im = 144) ! number of x points parameter (jm = 91) ! number of y points parameter (nlayr = 70) ! geos-2 70 level resolution parameter (ntime = 1) ! number of times c input real phis(im,jm) ! surface geopotential (m/sec)**2 real ps(im,jm) ! surface pressure (mb) real slp(im,jm) ! sea level pressure (mb) c real lwi(im,jm) ! Surface Types from Land/Surface Model real uwnd(im,jm,nlayr) ! U-Wind (m/sec) real vwnd(im,jm,nlayr) ! V-Wind (m/sec) c real hghtp(im,jm,nlayr) ! pertabation geopotential height (m) real tmpu(im,jm,nlayr) ! temperature (K) real sphu(im,jm,nlayr) ! specific humidity (g/kg) c real rh(im,jm,nlayr) ! relative humidity (%) c unique to the routine character*60 filein ! filename of input integer i,j,k,n ! loop variables integer nri ! record number of input and output file real sig(nlayr) ! sigma levels of data real sge(nlayr+1) ! edge sigma levels of data real sige(nlayr+1) ! edge sigma levels of data real fac real*4 r4a(im,jm) real pmin, pmax, vmax c--------------- Grads input file --------------------------- C DSET /monthlyb/nebuda/e0523.progsig.t960917.data C FORMAT SEQUENTIAL C TITLE e0523d Control assimilation for NSCAT C UNDEF 0.100000E+16 C XDEF 144 LINEAR -180.0 2.50000000 C YDEF 91 LINEAR -90.0 2.00000000 C ZDEF 70 LEVELS 70.00 69.00 68.00 67.00 66.00 C 65.00 64.00 63.00 62.00 61.00 C 60.00 59.00 58.00 57.00 56.00 C 55.00 54.00 53.00 52.00 51.00 C 50.00 49.00 48.00 47.00 46.00 C 45.00 44.00 43.00 42.00 41.00 C 40.00 39.00 38.00 37.00 36.00 C 35.00 34.00 33.00 32.00 31.00 C 30.00 29.00 28.00 27.00 26.00 C 25.00 24.00 23.00 22.00 21.00 C 20.00 19.00 18.00 17.00 16.00 C 15.00 14.00 13.00 12.00 11.00 C 10.00 9.00 8.00 7.00 6.00 C 5.00 4.00 3.00 2.00 1.00 C TDEF 1 LINEAR 00:00Z17SEP96 6hr C VARS 10 C PHIS 0 0 Surface Geopotential Heights (m/sec)**2 C PS 0 0 Surface Pressure (mb) C SLP 0 0 Sea Level Pressure (mb) C LWI 0 0 Surface Types from Land/Surface Model C UWND 70 0 U-Wind (m/sec) C VWND 70 0 V-Wind (m/sec) C HGHTP 70 0 Perturbation Geopotential Height (m) C TMPU 70 0 Temperature (K) C SPHU 70 0 Specific Humidity (g/kg) C RH 70 0 Relative Humidity (Percent) C ENDVARS c--------------- Variable Initialization ------------------------ data sige / . 0.000000E+00 , 6.016350E-06 , 1.370820E-05 , 2.295240E-05 , . 3.401840E-05 , 4.802090E-05 , 6.594130E-05 , 8.865010E-05 , . 1.177850E-04 , 1.550160E-04 , 2.024040E-04 , 2.624830E-04 , . 3.383480E-04 , 4.337660E-04 , 5.532970E-04 , 7.024390E-04 , . 8.877800E-04 , 1.118005E-03 , 1.403066E-03 , 1.754897E-03 , . 2.187742E-03 , 2.718547E-03 , 3.367386E-03 , 4.157950E-03 , . 5.118086E-03 , 6.280394E-03 , 7.682883E-03 , 9.369687E-03 , . 1.139184E-02 , 1.380810E-02 , 1.668584E-02 , 2.010197E-02 , . 2.414387E-02 , 2.891042E-02 , 3.451000E-02 , 4.107631E-02 , . 4.872000E-02 , 5.757372E-02 , 6.781108E-02 , 7.963646E-02 , . 9.325208E-02 , 1.088781E-01 , 1.267550E-01 , 1.471300E-01 , . 1.703000E-01 , 1.965500E-01 , 2.262500E-01 , 2.595500E-01 , . 2.962800E-01 , 3.360700E-01 , 3.784500E-01 , 4.230300E-01 , . 4.694000E-01 , 5.170351E-01 , 5.654188E-01 , 6.138495E-01 , . 6.615992E-01 , 7.078959E-01 , 7.519437E-01 , 7.929700E-01 , . 8.303000E-01 , 8.635700E-01 , 8.927438E-01 , 9.179000E-01 , . 9.392300E-01 , 9.570000E-01 , 9.715000E-01 , 9.829000E-01 , . 9.914000E-01 , 9.970951E-01 , 1.000000E+00 / if(im .ne. imr) then write(6,*) 'Stop!', im, imr stop endif if(km .ne. nlayr) then write(6,*) 'Stop!', km, nlayr stop endif C Set #1 c filein = 'e0523.progsig.t960917.data' C Set #2 c filein = 'e0523.progsig.t961020.data' c Set #3 c filein = 'e0523.progsig.t961025.data' c Set #4 c filein = 'e0523d.progsig.t961028.data' C Set #5 (NSCAT) c filein = 'e0543d.progsig.t961020.data' c Set #6 (NSCAT) c filein = 'e0543d.progsig.t961028.data' C C Arlindo's dataset filein = 'uth01.fg.t19971221.dat' c--------------- Open Files ------------------------------------- C In pascal!!! ptop = 1. ! model top pressure level open(10, file=filein, form='unformatted', access='direct', . recl=im*jm*4) c . recl=im*jm) c--------------- Step through time -------------------------------- nri = 0 do n = 1, ntime c---------------- Read Input --------------------------------------- C PHIS 0 0 Surface Geopotential Heights (m/sec)**2 C PS 0 0 Surface Pressure (mb) C SLP 0 0 Sea Level Pressure (mb) C LWI 0 0 Surface Types from Land/Surface Model C UWND 70 0 U-Wind (m/sec) C VWND 70 0 V-Wind (m/sec) C HGHTP 70 0 Perturbation Geopotential Height (m) C TMPU 70 0 Temperature (K) C SPHU 70 0 Specific Humidity (g/kg) C RH 70 0 Relative Humidity (Percent) nri = nri + 1 c read(10,rec=nri) phis read(10,rec=nri) r4a do j=1, jm do i=1,im phis(i,j) = r4a(i,j) enddo enddo nri = nri + 1 c read(10,rec=nri) ps read(10,rec=nri) r4a do j=1, jm do i=1,im ps(i,j) = r4a(i,j) enddo enddo nri = nri + 1 c read(10,rec=nri) slp read(10,rec=nri) r4a do j=1, jm do i=1,im slp(i,j) = r4a(i,j) enddo enddo nri = nri + 1 c read(10,rec=nri) lwi read(10,rec=nri) r4a do j=1, jm do i=1,im c lwi(i,j) = r4a(i,j) enddo enddo do k = nlayr, 1, -1 nri = nri + 1 c read(10,rec=nri) ((uwnd(i,j,k),i=1,im),j=1,jm) read(10,rec=nri) r4a do j=1, jm do i=1,im uwnd(i,j,k) = r4a(i,j) enddo enddo C DEbug c pmax = vmax(uwnd(1,1,k),pmin,im*jm) c write(6,*) k, ' max U=', pmax, ' min=', pmin enddo do k = nlayr, 1, -1 nri = nri + 1 c read(10,rec=nri) ((vwnd(i,j,k),i=1,im),j=1,jm) read(10,rec=nri) r4a do j=1, jm do i=1,im vwnd(i,j,k) = r4a(i,j) enddo enddo enddo do k = nlayr, 1, -1 nri = nri + 1 c read(10,rec=nri) ((hghtp(i,j,k),i=1,im),j=1,jm) C The following line must be commented out for Arlindo's dataset c read(10,rec=nri) r4a do j=1, jm do i=1,im c hghtp(i,j,k) = r4a(i,j) enddo enddo enddo do k = nlayr, 1, -1 nri = nri + 1 c read(10,rec=nri) ((tmpu(i,j,k),i=1,im),j=1,jm) read(10,rec=nri) r4a do j=1, jm do i=1,im tmpu(i,j,k) = r4a(i,j) enddo enddo C DEbug c pmax = vmax(tmpu(1,1,k),pmin,im*jm) c write(6,*) k, ' max T=', pmax, ' min=', pmin enddo do k = nlayr, 1, -1 nri = nri + 1 c read(10,rec=nri) ((sphu(i,j,k),i=1,im),j=1,jm) read(10,rec=nri) r4a do j=1, jm do i=1,im sphu(i,j,k) = r4a(i,j) enddo enddo enddo do k = nlayr, 1, -1 nri = nri + 1 c read(10,rec=nri) ((rh(i,j,k),i=1,im),j=1,jm) read(10,rec=nri) r4a do j=1, jm do i=1,im c rh(i,j,k) = r4a(i,j) enddo enddo enddo c------------- Compute New output --------------------------------------- do k = 1, nlayr+1 sge(k) = sige(k) enddo do k = 1, nlayr sig(k) = (sige(k) + sige(k+1)) * 0.5 C write(6,*) k, sig(k) enddo C Convert mb to pascal fac = 100. do j = 1, jm do i = 1, im ps(i,j) = ps(i,j) * fac enddo enddo do k = 1, nlayr do j = 1, jm do i = 1, im sphu(i,j,k) = 0.001*sphu(i,j,k) enddo enddo enddo enddo ! time loop close(10) return end real function vmax(a,pmin,n) implicit none integer n, i real pmin, pmax real a(*) pmax =a(n) pmin =a(n) do 10 i=1,n-1 pmax = max(pmax,a(i)) pmin = min(pmin,a(i)) 10 continue vmax = pmax return end subroutine shiftx(a, im, jm, km) 6 C Shift the position of i=1 from the international dateline to C Greenwich. C im must be even integer implicit none integer imax parameter (imax = 720) integer i, j, k, im, jm, km integer shift real a(im,jm,*), a1(imax) if(imax .lt. im) then write(6,*) 'Increase imax in shiftx' stop endif shift = im/2 if(shift .ne. (shift/2)*2) then write(6,*) 'im in shift is NOT an even integer' stop endif do 100 k=1,km do 50 j=1,jm do i=1,im if(i .le. shift) then a1(i+shift) = a(i,j,k) else a1(i-shift) = a(i,j,k) endif enddo C Copy back to A do i=1,im a(i,j,k) = a1(i) enddo 50 continue 100 continue return end subroutine set_32(km,KS,PTOP,PINT,ak,bk) C A and B smoothed by R. Swinbank implicit none integer NL, KS, k, km parameter (NL = 32) real ak(km+1),bk(km+1) real a(NL+1),b(NL+1),PRESS(NL+1) real ptop, pint, p0, dp data a /300.0000, 454.1491, 652.5746, 891.9637, 1159.7102, & 1492.8248, 1902.5026, 2400.4835, 2998.6740, 3708.6584, & 4541.1041, 5505.0739, 6607.2675, 7851.2298, 9236.5661, & 10866.3427, 12420.400, 13576.500, 14365.400, 14807.800, & 14915.500, 14691.400, 14129.400, 13214.800, 11923.200, & 10220.700, 8062.000, 5849.500, 3777.000, 2017.200, & 720.600, 0.000, 0.000 / data b /0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, & 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, & 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, & 0.0000000, 0.003633 , 0.014628 , 0.033276 , 0.060071 , & 0.095722 , 0.141171 , 0.197623 , 0.266571 , 0.349839 , & 0.449632 , 0.568589 , 0.685887 , 0.793252 , 0.883128 , & 0.948792 , 0.9851119, 1.0000000 / if( km .ne. nl) then write(6,*) 'Stop in set_eta(km=32)' stop endif KS = 15 PTOP = a(1) PINT = a(KS+1) do k=1,NL+1 ak(k) = a(k) bk(k) = b(k) enddo return end c****6***0*********0*********0*********0*********0*********0**********72 subroutine set_eta(km,KS,PTOP,PINT,ak,bk) 19,2 c****6***0*********0*********0*********0*********0*********0**********72 implicit none integer NL, KS, k, km parameter (NL = 55) real ak(km+1),bk(km+1) real a(NL+1),b(NL+1),PRESS(NL+1) real ptop, pint, p0, dp data a /1.0000, 2.0000, 3.2700, 4.7585, 6.6000, & 8.9345, 11.9703, 15.9495, 21.1349, 27.8526, & 36.5041, 47.5806, 61.6779, 79.5134, 101.9442, & 130.0508, 165.0792, 208.4972, 262.0212, 327.6433, & 407.6567, 504.6805, 621.6800, 761.9839, 929.2943, & 1127.6888, 1364.3392, 1645.7072, 1979.1554, 2373.0361, & 2836.7816, 3380.9955, 4017.5417, 4764.3932, 5638.7938, & 6660.3377, 7851.2298, 9236.5661,10866.3427, 12420.400 , & 13576.500 , 14365.400, 14807.800, 14915.500 , 14691.400, & 14129.400 , 13214.800, 11923.200, 10220.700 , 8062.000, & 5849.500 , 3777.000, 2017.200, 720.600, 0.000, & 0.000 / data b / 0.0000000, 0.0000000, 0.0000000, & 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, & 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, & 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, & 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, & 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, & 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, & 0.0000000, 0.0000000, 0.0000000, 0.0000000, 0.0000000, & 0.0000000, 0.003633 , 0.014628 , 0.033276 , 0.060071 , & 0.095722 , 0.141171 , 0.197623 , 0.266571 , 0.349839 , & 0.449632 , 0.568589 , 0.685887 , 0.793252 , 0.883128 , & 0.948792 , 0.9851119, 1.0000000 / if( km .ne. nl) then write(6,*) 'Stop in set_eta(km=55)', km, nl stop endif KS = 38 PTOP = a(1) PINT = a(KS+1) do k=1,NL+1 ak(k) = a(k) bk(k) = b(k) enddo return end C****6***0*********0*********0*********0*********0*********0**********72 subroutine mappm(km, pe1, dp1, q1, kn, pe2, dp2, q2, im, iv, kord) 8,2 C****6***0*********0*********0*********0*********0*********0**********72 C IV = 0: constituents C C Mass flux preserving mapping: q1(im,km) -> q2(im,kn) C C pe1: pressure at layer edges (from model top to bottom surface) C in the original vertical coordinate C pe2: pressure at layer edges (from model top to bottom surface) C in the new vertical coordinate parameter (kmax = 200) parameter (R3 = 1./3., R23 = 2./3.) real dp1(im,km), dp2(im,kn), & q1(im,km), q2(im,kn), & pe1(im,km+1), pe2(im,kn+1) integer kord C local work arrays real a4(4,im,km) do k=1,km do i=1,im a4(1,i,k) = q1(i,k) enddo enddo call ppm2m(a4, dp1, im, km, iv, kord) C Lowest layer: constant distribution do i=1, im a4(2,i,km) = q1(i,km) a4(3,i,km) = q1(i,km) a4(4,i,km) = 0. enddo do 5555 i=1,im k0 = 1 do 555 k=1,kn if(pe2(i,k+1) .le. pe1(i,1)) then C Entire grid above old ptop q2(i,k) = a4(2,i,1) elseif(pe2(i,k) .ge. pe1(i,km+1)) then C Entire grid below old ps q2(i,k) = a4(3,i,km) elseif(pe2(i,k ) .lt. pe1(i,1) .and. & pe2(i,k+1) .gt. pe1(i,1)) then C Part of the grid above ptop q2(i,k) = a4(1,i,1) c elseif(pe2(i,k) .lt. pe1(i,km+1) .and. c & (pe2(i,k+1)-pe1(i,km+1))/dp2(i,kn) .gt. 0.01) then C Part of the grid below old ps c q2(i,k) = a4(1,i,km) else do 45 L=k0,km C locate the top edge at pe2(i,k) if( pe2(i,k) .ge. pe1(i,L) .and. & pe2(i,k) .le. pe1(i,L+1) ) then k0 = L PL = (pe2(i,k)-pe1(i,L)) / dp1(i,L) if(pe2(i,k+1) .le. pe1(i,L+1)) then C entire new grid is within the original grid PR = (pe2(i,k+1)-pe1(i,L)) / dp1(i,L) TT = R3*(PR*(PR+PL)+PL**2) q2(i,k) = a4(2,i,L) + 0.5*(a4(4,i,L)+a4(3,i,L) & - a4(2,i,L))*(PR+PL) - a4(4,i,L)*TT goto 555 else C Fractional area... delp = pe1(i,L+1) - pe2(i,k) TT = R3*(1.+PL*(1.+PL)) qsum = delp*(a4(2,i,L)+0.5*(a4(4,i,L)+ & a4(3,i,L)-a4(2,i,L))*(1.+PL)-a4(4,i,L)*TT) dpsum = delp k1 = L + 1 goto 111 endif endif 45 continue 111 continue do 55 L=k1,km if( pe2(i,k+1) .gt. pe1(i,L+1) ) then C Whole layer.. qsum = qsum + dp1(i,L)*q1(i,L) dpsum = dpsum + dp1(i,L) else delp = pe2(i,k+1)-pe1(i,L) esl = delp / dp1(i,L) qsum = qsum + delp * (a4(2,i,L)+0.5*esl* & (a4(3,i,L)-a4(2,i,L)+a4(4,i,L)*(1.-r23*esl)) ) dpsum = dpsum + delp k0 = L goto 123 endif 55 continue delp = pe2(i,k+1) - pe1(i,km+1) if(delp .gt. 0.) then C Extended below old ps qsum = qsum + delp * a4(3,i,km) dpsum = dpsum + delp endif 123 q2(i,k) = qsum / dpsum endif 555 continue 5555 continue return end c****6***0*********0*********0*********0*********0*********0**********72 subroutine ppm2m(a4,delp,im,km,iv,kord) 6,17 c****6***0*********0*********0*********0*********0*********0**********72 c iv = 0: positive definite scalars c iv = 1: others implicit none integer im, km, lmt, iv integer kord integer i, k, km1 real a4(4,im,km), delp(im,km) c local arrays. real dc(im,km),delq(im,km) real h2(im,km) real a1, a2, a3, b2, c1, c2, c3, d1, d2, f1, f2, f3, f4 real s1, s2, s3, s4, ss3, s32, s34, s42, sc real qmax, qmin, cmax, cmin real dm, qm, dq, tmp C Local scalars: real qmp real lac c real x, y, z c real median c median(x,y,z) = min(max(x,y), max(y,z), max(z,x)) km1 = km - 1 do 500 k=2,km do 500 i=1,im delq(i,k-1) = a4(1,i,k) - a4(1,i,k-1) 500 a4(4,i,k ) = delp(i,k-1) + delp(i,k) do 1220 k=2,km1 do 1220 i=1,im c1 = (delp(i,k-1)+0.5*delp(i,k))/a4(4,i,k+1) c2 = (delp(i,k+1)+0.5*delp(i,k))/a4(4,i,k) tmp = delp(i,k)*(c1*delq(i,k) + c2*delq(i,k-1)) / & (a4(4,i,k)+delp(i,k+1)) qmax = max(a4(1,i,k-1),a4(1,i,k),a4(1,i,k+1)) - a4(1,i,k) qmin = a4(1,i,k) - min(a4(1,i,k-1),a4(1,i,k),a4(1,i,k+1)) dc(i,k) = sign(min(abs(tmp),qmax,qmin), tmp) 1220 continue c****6***0*********0*********0*********0*********0*********0**********72 c 4th order interpolation of the provisional cell edge value c****6***0*********0*********0*********0*********0*********0**********72 do 12 k=3,km1 do 12 i=1,im c1 = delq(i,k-1)*delp(i,k-1) / a4(4,i,k) a1 = a4(4,i,k-1) / (a4(4,i,k) + delp(i,k-1)) a2 = a4(4,i,k+1) / (a4(4,i,k) + delp(i,k)) a4(2,i,k) = a4(1,i,k-1) + c1 + 2./(a4(4,i,k-1)+a4(4,i,k+1)) * & ( delp(i,k)*(c1*(a1 - a2)+a2*dc(i,k-1)) - & delp(i,k-1)*a1*dc(i,k ) ) 12 continue c three-cell parabolic subgrid distribution at model top c do 10 i=1,im c three-cell PP-distribution c Compute a,b, and c of q = aP**2 + bP + c using cell averages and delp c a3 = a / 3 c b2 = b / 2 c s1 = delp(i,1) c s2 = delp(i,2) + s1 c s3 = delp(i,2) + delp(i,3) c s4 = s3 + delp(i,4) c ss3 = s3 + s1 c s32 = s3*s3 c s42 = s4*s4 c s34 = s3*s4 c model top c a3 = (delq(i,2) - delq(i,1)*s3/s2) / (s3*ss3) c if(abs(a3) .gt. 1.e-14) then c b2 = delq(i,1)/s2 - a3*(s1+s2) c sc = -b2/(3.*a3) c if(sc .lt. 0. .or. sc .gt. s1) then c a4(2,i,1) = a4(1,i,1) - s1*(a3*s1 + b2) c else c a4(2,i,1) = a4(1,i,1) - delq(i,1)*s1/s2 c endif c else c Linear c a4(2,i,1) = a4(1,i,1) - delq(i,1)*s1/s2 c endif c dc(i,1) = a4(1,i,1) - a4(2,i,1) c compute coef. for the off-centered area preserving cubic poly. c dm = delp(i,1) / (s34*ss3*(delp(i,2)+s3)*(s4+delp(i,1))) c f1 = delp(i,2)*s34 / ( s2*ss3*(s4+delp(i,1)) ) c f2 = (delp(i,2)+s3) * (ss3*(delp(i,2)*s3+s34+delp(i,2)*s4) c & + s42*(delp(i,2)+s3+s32/s2)) c f3 = -delp(i,2)*( ss3*(s32*(s3+s4)/(s4-delp(i,2)) c & + (delp(i,2)*s3+s34+delp(i,2)*s4)) c & + s42*(delp(i,2)+s3) ) c f4 = ss3*delp(i,2)*s32*(delp(i,2)+s3) / (s4-delp(i,2)) c a4(2,i,2) = f1*a4(1,i,1)+(f2*a4(1,i,2)+f3*a4(1,i,3)+ c & f4*a4(1,i,4))*dm c****6***0*********0*********0*********0*********0*********0**********72 c No over- and undershoot condition c cmax = max(a4(1,i,1), a4(1,i,2)) c cmin = min(a4(1,i,1), a4(1,i,2)) c a4(2,i,2) = max(cmin,a4(2,i,2)) c a4(2,i,2) = min(cmax,a4(2,i,2)) c 10 continue C Area preserving cubic with 2nd deriv. = 0 at the boundaries C Top do i=1,im d1 = delp(i,1) d2 = delp(i,2) qm = (d2*a4(1,i,1)+d1*a4(1,i,2)) / (d1+d2) dq = 2.*(a4(1,i,2)-a4(1,i,1)) / (d1+d2) c1 = 4.*(a4(2,i,3)-qm-d2*dq) / ( d2*(2.*d2*d2+d1*(d2+3.*d1)) ) c3 = dq - 0.5*c1*(d2*(5.*d1+d2)-3.*d1**2) a4(2,i,2) = qm - 0.25*c1*d1*d2*(d2+3.*d1) a4(2,i,1) = d1*(2.*c1*d1**2-c3) + a4(2,i,2) dc(i,1) = a4(1,i,1) - a4(2,i,1) C No over- and undershoot condition cmax = max(a4(1,i,1), a4(1,i,2)) cmin = min(a4(1,i,1), a4(1,i,2)) a4(2,i,2) = max(cmin,a4(2,i,2)) a4(2,i,2) = min(cmax,a4(2,i,2)) enddo if(iv .eq. 0) then do i=1,im a4(2,i,1) = max(0.,a4(2,i,1)) a4(2,i,2) = max(0.,a4(2,i,2)) enddo endif c****6***0*********0*********0*********0*********0*********0**********72 c Bottom c Area preserving cubic with 2nd deriv. = 0 at the surface do 15 i=1,im d1 = delp(i,km) d2 = delp(i,km1) qm = (d2*a4(1,i,km)+d1*a4(1,i,km1)) / (d1+d2) dq = 2.*(a4(1,i,km1)-a4(1,i,km)) / (d1+d2) c1 = (a4(2,i,km1)-qm-d2*dq) / (d2*(2.*d2*d2+d1*(d2+3.*d1))) c3 = dq - 2.0*c1*(d2*(5.*d1+d2)-3.*d1**2) a4(2,i,km) = qm - c1*d1*d2*(d2+3.*d1) a4(3,i,km) = d1*(8.*c1*d1**2-c3) + a4(2,i,km) dc(i,km) = a4(3,i,km) - a4(1,i,km) c****6***0*********0*********0*********0*********0*********0**********72 c No over- and undershoot condition cmax = max(a4(1,i,km), a4(1,i,km1)) cmin = min(a4(1,i,km), a4(1,i,km1)) a4(2,i,km) = max(cmin,a4(2,i,km)) a4(2,i,km) = min(cmax,a4(2,i,km)) c****6***0*********0*********0*********0*********0*********0**********72 15 continue if(iv .eq. 0) then do i=1,im a4(2,i,km) = max(0.,a4(2,i,km)) a4(3,i,km) = max(0.,a4(3,i,km)) enddo endif do 20 k=1,km1 do 20 i=1,im a4(3,i,k) = a4(2,i,k+1) 20 continue c c f(s) = AL + s*[(AR-AL) + A6*(1-s)] ( 0 <= s <= 1 ) c c Top 2 and bottom 2 layers always use monotonic mapping do k=1,2 do i=1,im a4(4,i,k) = 3.*(2.*a4(1,i,k) - (a4(2,i,k)+a4(3,i,k))) enddo call kmppm(dc(1,k),a4(1,1,k),im, 0) enddo if(kord .eq. 7) then c****6***0*********0*********0*********0*********0*********0**********72 C Huynh's 2nd constraint c****6***0*********0*********0*********0*********0*********0**********72 do k=2, km1 do i=1,im h2(i,k) = delq(i,k) - delq(i,k-1) enddo enddo do 4000 k=3, km-2 do 3000 i=1, im C Right edges qmp = a4(1,i,k) + 2.0*delq(i,k-1) lac = a4(1,i,k) + 1.5*h2(i,k-1) + 0.5*delq(i,k-1) qmin = min(a4(1,i,k), qmp, lac) qmax = max(a4(1,i,k), qmp, lac) c a4(3,i,k) = median(a4(3,i,k), qmin, qmax) a4(3,i,k) = min(max(a4(3,i,k), qmin), qmax) C Left edges qmp = a4(1,i,k) - 2.0*delq(i,k) lac = a4(1,i,k) + 1.5*h2(i,k+1) - 0.5*delq(i,k) qmin = min(a4(1,i,k), qmp, lac) qmax = max(a4(1,i,k), qmp, lac) c a4(2,i,k) = median(a4(2,i,k), qmin, qmax) a4(2,i,k) = min(max(a4(2,i,k), qmin), qmax) C Recompute A6 a4(4,i,k) = 3.*(2.*a4(1,i,k) - (a4(2,i,k)+a4(3,i,k))) 3000 continue C Additional constraint to prevent negatives if (iv .eq. 0) then call kmppm(dc(1,k),a4(1,1,k),im, 2) endif 4000 continue else lmt = kord - 3 lmt = max(0, lmt) if (iv .eq. 0) lmt = min(2, lmt) do k=3, km-2 do i=1,im a4(4,i,k) = 3.*(2.*a4(1,i,k) - (a4(2,i,k)+a4(3,i,k))) enddo call kmppm(dc(1,k),a4(1,1,k),im, lmt) enddo endif do 5000 k=km1,km do i=1,im a4(4,i,k) = 3.*(2.*a4(1,i,k) - (a4(2,i,k)+a4(3,i,k))) enddo call kmppm(dc(1,k),a4(1,1,k),im, 0) 5000 continue return end c****6***0*********0*********0*********0*********0*********0**********72 subroutine kmppm(dm, a4, km, lmt) 17 c****6***0*********0*********0*********0*********0*********0**********72 implicit none real r12 parameter (r12 = 1./12.) integer km, lmt integer i real a4(4,km),dm(km) real da1, da2, a6da real fmin if (lmt .eq. 3) return c Full constraint if(lmt .eq. 0) then do 100 i=1,km if(dm(i) .eq. 0.) then a4(2,i) = a4(1,i) a4(3,i) = a4(1,i) a4(4,i) = 0. else da1 = a4(3,i) - a4(2,i) da2 = da1**2 a6da = a4(4,i)*da1 if(a6da .lt. -da2) then a4(4,i) = 3.*(a4(2,i)-a4(1,i)) a4(3,i) = a4(2,i) - a4(4,i) elseif(a6da .gt. da2) then a4(4,i) = 3.*(a4(3,i)-a4(1,i)) a4(2,i) = a4(3,i) - a4(4,i) endif endif 100 continue elseif (lmt .eq. 2) then c Positive definite c Positive definite constraint do 250 i=1,km if(abs(a4(3,i)-a4(2,i)) .ge. -a4(4,i)) go to 250 fmin = a4(1,i)+0.25*(a4(3,i)-a4(2,i))**2/a4(4,i)+a4(4,i)*r12 if(fmin.ge.0.) go to 250 if(a4(1,i).lt.a4(3,i) .and. a4(1,i).lt.a4(2,i)) then a4(3,i) = a4(1,i) a4(2,i) = a4(1,i) a4(4,i) = 0. elseif(a4(3,i) .gt. a4(2,i)) then a4(4,i) = 3.*(a4(2,i)-a4(1,i)) a4(3,i) = a4(2,i) - a4(4,i) else a4(4,i) = 3.*(a4(3,i)-a4(1,i)) a4(2,i) = a4(3,i) - a4(4,i) endif 250 continue elseif (lmt .eq. 1) then write(6,*) 'semi-monotonic not implemented!' stop endif return end subroutine atod(ua,va,u,v,im,jm) 1 C Convert A-grid winds to D-grid C 4th order version real r16 parameter (r16 = 1./16.) real ua(im,jm), va(im,jm) !ams real*8 u(im,jm), v(im,jm) real u(im,jm), v(im,jm) C C****6***0*********0*********0*********0*********0*********0**********72 jmr = jm-1 jnp = jm DO 10 i=1,IM u(i, 2) = 0.5*(ua(i,2) + ua(i,1)) 10 u(i,JNP) = 0.5*(ua(i,JMR) + ua(i,JNP)) C do 20 j=3,JMR DO 20 i=1,IM u(i,j)=(9.*(ua(i,j) + ua(i,j-1))-(ua(i,j+1) + ua(i,j-2)))*R16 20 continue C ********************************************** C C JS = 1+JMR/8 JS = 3 JN = JNP - JS + 1 C do 30 j=2,JS-1 DO 30 i=2,IM v(i,j) = 0.5*(va(i,j) + va(i-1,j)) 30 continue C do j=2,JS-1 v(1,j) = 0.5*(va(1,j) + va(IM,j)) enddo C do 35 j=JN+1,JMR DO 35 i=2,IM v(i,j) = 0.5*(va(i,j) + va(i-1,j)) 35 continue C do j=JN+1,JMR v(1,j) = 0.5*(va(1,j) + va(IM,j)) enddo C do 40 j=JS,JN DO 40 i=3,IM-1 v(i,j) = (9.*(va(i, j) + va(i-1,j)) - & (va(i+1,j) + va(i-2,j)) ) * R16 40 continue C do 50 j=JS,JN C i=1 v(1,j) = (9.*(va(1, j) + va(IM,j)) - & (va(2,j) + va(IM-1,j)) ) * R16 C i=2 v(2,j) = (9.*(va(2, j) + va(1,j)) - & (va(3,j) + va(IM,j)) ) * R16 C i=IM v(IM,j) = (9.*(va(IM, j) + va(IM-1,j)) - & (va(1 , j) + va(IM-2,j)) ) * R16 50 continue return end C****6***0*********0*********0*********0*********0*********0**********72 subroutine plft2d(p, JS, JN, NDEG) 6,3 C****6***0*********0*********0*********0*********0*********0**********72 C This is a weak LOCAL polar filter. C Developer: Shian-Jiann Lin implicit none c include 'vrslv.com' integer imr, jmr parameter(imr=144, jmr=90) c parameter(imr=288, jmr=180) integer JNP, Nmax parameter (JNP = JMR + 1) parameter (Nmax= IMR/2) integer js, jn, ndeg integer i, j, n, ideg, jj, jc !ams real*8 p(imr,jnp),cosp(JMR+1),cose(JMR+1),a(0:Nmax+1) !ams real*8 se(JMR+1), sc(JMR+1),sine(JNP),sinp(JNP) real p(imr,jnp),cosp(JMR+1),cose(JMR+1),a(0:Nmax+1) real se(JMR+1), sc(JMR+1),sine(JNP),sinp(JNP) !ams real*8 pi, dp, dl, e0, ycrit, coszc, smax, rn, rn2, esl, tmp real pi, dp, dl, e0, ycrit, coszc, smax, rn, rn2, esl, tmp data IDEG /0/ save sc, se if(IDEG .ne. NDEG) then IDEG = NDEG C (e0 = 2.6) e0 = 0.5 * sqrt(27.) PI = 4. * ATAN(1.) call setrig(IMR,JNP,DP,DL,cosp,cose,sinp,sine) ycrit = IDEG*PI/180. coszc = cos(ycrit) Smax = JMR/2 write(6,*) 'Critical latitude in local pft = ',NDEG a(0) = 1. do n=1,Nmax+1 rn = n rn2 = 2*n a(n) = sqrt(rn2+1.) * ((rn2+1.)/rn2)**rn enddo do j=2,JMR sc(j) = coszc / cosp(j) IF(sc(j) .gt.1. .and. sc(j) .le. 1.5 ) THEN esl = 1./ sc(j) sc(j) = 1. + (1.-esl) / (1.+esl) ELSEIF(sc(j) .gt.1.5 .and. sc(j) .le. e0 ) THEN esl = 1./ sc(j) sc(j) = 1. + 2./ (27.*esl**2 - 2.) ELSEIF(sc(j).gt. e0) THEN C Search do jj=1,Nmax if(sc(j).le. a(jj)) then jc = jj goto 111 endif enddo jc = Nmax + 1 111 continue tmp = ((sc(j) - a(jc-1))/(a(jc) - a(jc-1)))**0.25 sc(j) = jc + min(1., tmp) sc(j) = min(Smax,sc(j)) ENDIF enddo C ==================================================== do j=2,JMR+1 se(j) = coszc / cose(j) IF(se(j) .gt.1. .and. se(j) .le. 1.5 ) THEN esl = 1./ se(j) se(j) = 1. + (1.-esl) / (1.+esl) ELSEIF(se(j) .gt.1.5 .and. se(j) .le. e0 ) THEN esl = 1./ se(j) se(j) = 1. + 2./ (27.*esl**2 - 2.) ELSEIF(se(j).gt. e0) THEN C Search do jj=1,Nmax if(se(j) .le. a(jj)) then jc = jj goto 222 endif enddo jc = Nmax + 1 222 continue tmp = ((se(j) - a(jc-1))/(a(jc) - a(jc-1)))**0.25 se(j) = jc + min(1., tmp) se(j) = min(Smax,se(j)) ENDIF enddo do i=1,IMR se( 2) = sc(2) se(JNP) = sc(JMR) enddo do j=2,JMR c write(6,*) j,sc(j) enddo ENDIF if(JN.eq.JMR) then C Cell-centered variables CALL lpft(p,IMR,JNP,2,JMR,Sc) else C Cell-edge variables CALL lpft(p,IMR,JNP,2,JNP,Se) endif return end C****6***0*********0*********0*********0*********0*********0**********72 subroutine lpft(p,IM,JM,j1,j2,S) 2 C****6***0*********0*********0*********0*********0*********0**********72 implicit none c include 'vrslv.com' integer imr, jmr parameter(imr=144, jmr=90) c parameter(imr=288, jmr=180) integer JNP parameter (JNP = JMR+1) integer im, jm, j1, j2 integer i, j, n, nt !ams real*8 P(IMR,JNP),S(JNP),ptmp(0:IMR+1),q(IMR+1) real P(IMR,JNP),S(JNP),ptmp(0:IMR+1),q(IMR+1) !ams real*8 frac, rsc, bt, fac real frac, rsc, bt, fac do 2500 j=j1,j2 if(S(j) .gt. 1.02) then NT = INT(S(j)) frac = S(j) - NT if(frac .gt. 0.01) then rsc = 1./ (1.+frac) bt = 0.5 * frac do i=1,IMR ptmp(i) = p(i,j) enddo ptmp(0) = p(IMR,j) ptmp(IMR+1) = p(1,j) do i=1,IMR p(i,j) = rsc * (ptmp(i) + bt*(ptmp(i-1)+ptmp(i+1))) enddo endif NT = NT-1 if(NT.GE.1) then fac = 0.25**NT do 500 N=1,NT ptmp(0) = p(IMR,j) do i=1,IMR ptmp(i) = p(i,j) enddo C left do i=1,IMR q(i) = ptmp(i) + ptmp(i-1) enddo q(IMR+1) = q(1) C right do i=1,IMR p(i,j) = q(i) + q(i+1) enddo 500 continue do i=1,IMR p(i,j) = p(i,j)*fac enddo endif ENDIF 2500 continue return end C****6***0*********0*********0*********0*********0*********0**********72 subroutine setrig(im,jm,DP,DL,cosp,cose,sinp,sine) 5 C****6***0*********0*********0*********0*********0*********0**********72 implicit none integer im, jm integer j, jm1 !ams real*8 sine(jm),cosp(jm),sinp(jm),cose(jm) real sine(jm),cosp(jm),sinp(jm),cose(jm) !ams real*8 dp, dl !ams real*8 PI, ph5 real dp, dl real PI, ph5 jm1 = jm - 1 PI = 4.D0 * DATAN(1.D0) DL = (PI+PI)/DBLE(im) DP = PI/DBLE(jm1) do 10 j=2,jm ph5 = -0.5D0*PI + (DBLE(J-1)-0.5D0)*(PI/DBLE(jm1)) !ams10 sine(j) = DSIN(ph5) 10 sine(j) = SIN(ph5) cosp( 1) = 0. cosp(jm) = 0. do 80 j=2,jm1 80 cosp(j) = (sine(j+1)-sine(j)) / DP C Define cosine at edges.. do 90 j=2,jm 90 cose(j) = 0.5 * (cosp(j-1) + cosp(j)) cose(1) = cose(2) sinp( 1) = -1. sinp(jm) = 1. do 100 j=2,jm1 100 sinp(j) = 0.5 * (sine(j) + sine(j+1)) C write(6,*) 'SETRIG called. ',im,jm return end subroutine dry_adj(im, km, klo, pt, u, v, q, dp, npt) 1 implicit none integer i, k, im, km integer npt, klo real tiny parameter (tiny = 0.01) real u(im,km) real v(im,km) real pt(im,km) real q(im,km) real dp(im,km) npt = 0 C Top down do k=1, klo-1 do i=1,im if((pt(i,k)+tiny) .lt. pt(i,k+1)) then pt(i,k) = (pt(i,k)*dp(i,k)+pt(i,k+1)*dp(i,k+1)) & / (dp(i,k) + dp(i,k+1)) pt(i,k+1) = pt(i,k) u(i,k) = (u(i,k)*dp(i,k)+u(i,k+1)*dp(i,k+1)) & / (dp(i,k) + dp(i,k+1)) u(i,k+1) = u(i,k) v(i,k) = (v(i,k)*dp(i,k)+v(i,k+1)*dp(i,k+1)) & / (dp(i,k) + dp(i,k+1)) v(i,k+1) = v(i,k) q(i,k) = (q(i,k)*dp(i,k)+q(i,k+1)*dp(i,k+1)) & / (dp(i,k) + dp(i,k+1)) q(i,k+1) = q(i,k) npt = npt + 1 endif enddo enddo C From Bottom up if(npt .ne. 0) then do k=klo, 2 do i=1,im if(pt(i,k) .gt. (pt(i,k-1)+tiny)) then pt(i,k) = (pt(i,k)*dp(i,k)+pt(i,k-1)*dp(i,k-1)) & / (dp(i,k) + dp(i,k-1)) pt(i,k-1) = pt(i,k) u(i,k) = (u(i,k)*dp(i,k)+u(i,k-1)*dp(i,k-1)) & / (dp(i,k) + dp(i,k-1)) u(i,k-1) = u(i,k) v(i,k) = (v(i,k)*dp(i,k)+v(i,k-1)*dp(i,k-1)) & / (dp(i,k) + dp(i,k-1)) v(i,k-1) = v(i,k) q(i,k) = (q(i,k)*dp(i,k)+q(i,k-1)*dp(i,k-1)) & / (dp(i,k) + dp(i,k-1)) q(i,k-1) = q(i,k) npt = npt + 1 endif enddo enddo endif return end c****6***0*********0*********0*********0*********0*********0**********72 subroutine d2a(u,v,ua,va,imr,jnp,coslon,sinlon) 7 c****6***0*********0*********0*********0*********0*********0**********72 c This is primarily for turbulence package designed for A-grid. c Also used for output to A-grid. implicit none integer imr, imh, jmr, jnp real r16 parameter (r16 = 1./16.) integer i, j, js, jn, im1 real un, vn, us, vs c Convert D-grid winds to A-grid c u --> ua, v --> va real u(imr,jnp),v(imr,jnp),ua(imr,jnp),va(imr,jnp) & ,coslon(imr),sinlon(imr),utmp(imr,jnp),vtmp(imr,jnp) imh = imr/2 jmr = jnp-1 c Near poles. do 20 i=1,imr utmp(i,2) = 0.5*(u(i,2) + u(i,3)) utmp(i,jmr) = 0.5*(u(i,jmr) + u(i,jnp)) 20 continue do 25 j=3,jmr-1 do 25 i=1,imr utmp(i,j) = ( 9.*(u(i,j+1)+u(i,j)) - & (u(i,j+2)+u(i,j-1)) ) * r16 25 continue js = 3 jn = jnp - js + 1 im1 = imr-1 do 30 j=2,js-1 do 30 i=1,im1 30 vtmp(i,j) = 0.5*(v(i,j) + v(i+1,j)) do 35 j=2,js-1 35 vtmp(imr,j) = 0.5*(v(imr,j) + v(1,j)) do 45 j=jn+1,jmr do 45 i=1,im1 45 vtmp(i,j) = 0.5*(v(i,j) + v(i+1,j)) do 50 j=jn+1,jmr 50 vtmp(imr,j) = 0.5*(v(imr,j) + v(1,j)) do 60 j=js,jn do 60 i=2,imr-2 vtmp(i,j) = ( 9.*(v(i, j) + v(i+1,j)) - & (v(i-1,j) + v(i+2,j)) ) * r16 60 continue do 70 j=js,jn vtmp(1,j) = ( 9.*(v(1,j) + v(2,j)) - & (v(imr,j) + v(3,j)) ) * r16 vtmp(imr,j) = ( 9.*(v(imr,j) + v(1,j)) - & (v(im1,j) + v(2,j)) ) * r16 vtmp(im1,j) = ( 9.*(v(im1, j) + v(imr,j)) - & (v(imr-2,j) + v(1,j)) ) * r16 70 continue c Projection at Poles c NP un = 0. vn = 0. c SP us = 0. vs = 0. j=jmr do 80 i=1,imh un = un + (utmp(i+imh,j)-utmp(i,j))*sinlon(i) & + (vtmp(i+imh,j)-vtmp(i,j))*coslon(i) vn = vn + (utmp(i,j)-utmp(i+imh,j))*coslon(i) & + (vtmp(i+imh,j)-vtmp(i,j))*sinlon(i) us = us + (utmp(i+imh,2)-utmp(i,2))*sinlon(i) & + (vtmp(i,2)-vtmp(i+imh,2))*coslon(i) vs = vs + (utmp(i+imh,2)-utmp(i,2))*coslon(i) & + (vtmp(i+imh,2)-vtmp(i,2))*sinlon(i) 80 continue un = un/imr vn = vn/imr us = us/imr vs = vs/imr do 90 i=1,imh c SP ua(i,1) = -us*sinlon(i) - vs*coslon(i) va(i,1) = us*coslon(i) - vs*sinlon(i) ua(i+imh,1) = -ua(i,1) va(i+imh,1) = -va(i,1) c NP ua(i,jnp) = -un*sinlon(i) + vn*coslon(i) va(i,jnp) = -un*coslon(i) - vn*sinlon(i) ua(i+imh,jnp) = -ua(i,jnp) 90 va(i+imh,jnp) = -va(i,jnp) do 100 j=2,jmr do 100 i=1,imr ua(i,j) = utmp(i,j) 100 va(i,j) = vtmp(i,j) return end c...................................................................... c Get file names and dates from command line c ------------------------------------------ subroutine parse_cmd ( nymd, nhms, im, jm, nstep ) 1,8 include 'geos2fv.h' integer im, jm, nstep integer iarg, argc, iargc character*255 argv, res ! defaults ! -------- ftype = GFIO ! GFIO output ifname = 'b290_03_w98.pre-anal.sig.t19971221' nymd = 19971221 nhms = 000000 ofname = 'b290_03_w98.fv.t19971221' tfname = '#none#' sfname = '#none#' prec = 32 C Caution: Using nstep =0 for fvgcm will force the lsm to do a hard C and random initialization nstep = 0 print *, 'Starting...' ! parse command line ! ------------------ argc = iargc() narg = argc if ( argc .lt. 2 ) call usage() iarg = 0 do i = 1, 32767 iarg = iarg + 1 if ( iarg .gt. argc ) go to 111 call GetArg ( iArg, argv ) if(index(argv,'-i') .gt. 0 ) then if ( iarg+1 .gt. argc ) call usage() iarg = iarg + 1 call GetArg ( iArg, ifname ) narg = narg - 2 else if(index(argv,'-o') .gt. 0 ) then if ( iarg+1 .gt. argc ) call usage() iarg = iarg + 1 call GetArg ( iArg, ofname ) narg = narg - 2 else if(index(argv,'-t') .gt. 0 ) then if ( iarg+1 .gt. argc ) call usage() iarg = iarg + 1 call GetArg ( iArg, tfname ) narg = narg - 2 else if(index(argv,'-s') .gt. 0 ) then if ( iarg+1 .gt. argc ) call usage() iarg = iarg + 1 call GetArg ( iArg, sfname ) narg = narg - 2 else if(index(argv,'-gfio') .gt. 0 ) then if ( iarg+1 .gt. argc ) call usage() iarg = iarg + 1 call GetArg ( iArg, argv ) if(index(argv,'64') .gt. 0 ) prec = 64 else prec = 32 ftype = GFIO narg = narg - 2 else if(index(argv,'-n') .gt. 0 ) then if ( iarg+1 .gt. argc ) call usage() iarg = iarg + 1 call GetArg ( iArg, argv ) read(argv,*) nstep narg = narg - 2 print *, nstep else if(index(argv,'-grads') .gt. 0 ) then ftype = GRADS narg = narg - 1 else if(index(argv,'-rs') .gt. 0 ) then ftype = RESTART narg = narg - 1 else if ( narg .lt. 2 ) call usage() read(argv,*) nymd iarg = iarg + 1 call GetArg ( iArg, argv ) read(argv,*) nhms end if end do 111 continue ! Default files based on date/resolution ! -------------------------------------- if ( jm .gt. 99 ) then write(res,'(i3,a,i3)') im, 'x', jm else write(res,'(i3,a,i2)') im, 'x', jm end if if ( trim(sfname) .eq. '#none#' ) then write(sfname,'(a,i4.4,a)') & '/share/fvgcm/sstsice_' // trim(res) & //'.weekly.y', nymd/10000, '.nc' endif if ( trim(tfname) .eq. '#none#' ) then tfname = '/share/fvgcm/surf_r.data_' // trim(res) // '.usgs' end if lf = index(ofname,' ') - 1 if ( ftype .eq. RESTART ) ofname = ofname(1:lf) ! // '.rs' if ( ftype .eq. GRADS ) ofname = ofname(1:lf) // '.grd' if ( ftype .eq. GFIO ) ofname = ofname(1:lf) // '.hdf' print * print *, 'Input file name: ', ifname(1:60) print *, 'Output file name: ', ofname(1:60) print *, 'Topo file name: ', tfname(1:60) print *, 'SST file name: ', sfname(1:60) if ( ftype .eq. RESTART ) print *, 'Output file is RESTART' if ( ftype .eq. GRADS ) print *, 'Output file is GRADS' if ( ftype .eq. GFIO ) print *, 'Output file is GFIO' print *, 'Precision: ', prec print *, 'nymd, nhms, nstep: ', nymd, nhms, nstep print * return end subroutine usage() 132,6 print *, 'Usage: ' print * print *, ' geos2fv.x [-i ifname] [-o ofname] [-t tfname] [-s sfname]' print *, ' [-gfio 32|64] [-grads] [-rs] [-n nstep] nymd nhms' print * print *, 'where:' print * print *, ' -i ifname input GEOS prog.sig file in HDF format, ' print *, ' written by GFIO' print * print *, ' -o ofname output file basename' print * print *, ' -t tfname topography file name, e.g., surf.data_144x91;' print *, ' find these files on bjerknes:/share/fvgcm/fvdata' print *, ' The default is a resolution appropriate file ' print *, ' under /share/fvgcm/' print * print *, ' -s sfname SST file name, e.g., sstsice_144x91.weekly.y1997.nc;' print *, ' find these files on dixon0:/share/fvgcm/fvdata.' print *, ' You only need this if producing GFIO files.' print *, ' The default is a resolution/year appropriate file ' print *, ' under /share/fvgcm/' print * print *, ' -gfio specify GFIO output with 32 or 64 bits; the' print *, ' default is GFIO 32 bits' print * print *, ' -grads output file is in GrADS IEEE format' print * print *, ' -rs output is FVGCM restart (must have been' print *, ' compiled with -r8 for this to work' print * print *, ' -n nstep FVGCM step (for restarts); default: 0' print * print *, ' nymd year-month-day, e.g., 19971221' print * print *, ' nhms hour-min-sec, e.g., 120000' print * print *, 'Send algorithm related questions to SJ Lin (lin@dao),' print *, 'GFIO, lats4d and other format related questions to' print *, 'Arlindo da Silva (dasilva@dao).' print * print *, 'Last update: Seg Dez 6 08:13:42 EST 1999' print * call exit(7) end