!------------------------------------------------------------------------------- program postgp !$$$ Main program documentation block ! ! Main program: postgp Transform sigma to pressure grib ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: Program transforms sigma input to pressure grib output. ! The output consists of data on a regular lat/lon grid. ! Geopotential height, wind components, relative humidity, ! temperature, vertical velocity and absolute vorticity ! are output on mandatory pressures levels at 50 mb resolution. ! Constant pressure thickness fields are also output. ! Constant height above sea level fields are output too. ! Also output are sundry fields consisting of ! precipitable water, sea level pressure, two lifted indices, ! surface orography, temperature, pressure, and pressure tendency, ! tropopause temperature, pressure, wind components and shear, ! and maxwind level temperature, pressure and wind components. ! First nampgb namelist is read to determine output format. ! Then a sigma (grid or spectral) file is read from unit 11 and ! the program produces and writes a pressure grib1 file to unit 51. ! Then a sigma file is read from unit 12 and ! the program produces and writes a pressure grib1 file to unit 52. ! The program continues until an empty input file is encountered. ! ! Program history log: ! 92-10-31 Iredell ! 98-02-01 Iredell new levs 975,950,900,800,750,650,600,550,450,350, ! deleted all abs vor but 500 mb, ! smoothed abs vor to t72, ! included 1000 to 330 rh, ! made y2k-compliant, ! allow for tracers on the gaussian grid, ! reset fhour units for precip after day 10, ! corrected gds for gaussian grid option. ! 98-04-08 Iredell extend relative humidity to 100 mb and ! restrict ozone to 100 mb and above. ! 1999-05-08 Iredell SP version ! 1999-10-18 Iredell Documented ! 2000-09-11 Iredell Added freezing level ! 2000-09-27 Iredell Smoothed prmsl to t80 ! 2001-10-02 Iredell Extrapolated freezing level underground ! 2001-11-05 Iredell Included potential vorticity levels ! 2001-11-15 Iredell Allowed potential algorithm computation of PMSL ! 2003-02-01 Iredell Added level type 126 for isobaric levels above 1 mb ! 2003-02-01 Iredell Added relative humidity to constant height level and ! added constant height level 4267. ! 2003-03-01 Iredell Included potential temperature levels ! 2003-03-01 Iredell Added flexibility in fields to output ! with an optional filter list ! 2005-02-02 Iredell Added flux fields, changed maxwind and pv output ! ! Namelists: ! nampgb: parameters determining output format ! ddsig character(255) input sigma filename ! (default: 'postgp.inp.sig') ! ddflx character(255) input flux filename ! (default: 'postgp.inp.flx') ! ddpgb character(255) output pressure grib filename ! (default: 'postgp.out.pgb') ! idrtc integer compute grid flag (0 for latlon or 4 for gaussian) ! (default: idrt) ! ioc integer number of compute longitude points (default: io) ! joc integer number of compute latitude points (default: jo) ! idrt integer output grid flag (0 for latlon or 4 for gaussian) ! (default: 0 for latlon) ! io integer number of output longitude points ! (default: usually 360) ! jo integer number of output latitude points ! (default: usually 181) ! lpo integer pressure level set id ! (10=mandatory up to 10, 1=every 50 up to 1, 2=every 25 up to 1) ! (default: usually 1) ! kpo integer number of pressure levels (default: 26) ! po real (kpo) pressures in mb (default: every 50 mb ! plus 975 mb plus mandatory levels up to 10 mb) ! kpto integer number of pressure thickness layers output (default: 6) ! kpt integer number of pressure thickness layers computed ! (default: 6) ! pt real (kpt) pressure thickness in mb (default: 30.) ! kzz integer number of constant height levels (default: 8) ! zz real (kzz) constant heights in m ! (default: 305.,457.,610.,914.,1829.,2743.,3658.,4572.) ! kth integer number of potential temperature levels (default: 0) ! th real (kth) potential temperatures in K (default: ) ! kpv integer number of potential vorticity levels (default: 8) ! pv real (kpv) potential vorticities in PV units ! (default: 0.5,-0.5,1.0,-1.0,1.5,-1.5,2.0,-2.0) ! pvpt real (kpv) top pressures for PV search (default: 8*50.) ! pvsb real (kpv) bottom sigmas for PV search (default: 8*0.8) ! ncpus integer number of parallel processes (default: 1) ! mxbit integer maximum number of bits to pack data (default: 16) ! ids integer (255,255) decimal scaling of packed data ! (default: set by subprogram idsset) ! pob real (255) lowest level pressure in mb to output data ! as a function of parameter indicator ! (default: 500 for 5-wave height, 100 for ozone) ! pot real (255) highest level pressure in mb to output data ! as a function of parameter indicator ! (default: 500 for 5-wave height, 100 for rh or cloud, ! 100 for omega, 0 otherwise) ! omin real (255) minimum value in output data ! as a function of parameter indicator ! (default: 0. for humidity and ozone fields, -huge otherwise) ! omax real (255) maximum value in output data ! as a function of parameter indicator ! (default: 100. for rh, +huge otherwise) ! moo integer smoothing truncation for pressure level fields ! (set to 255 for no smoothing and no abs vorticity) ! (default: 2*joc/3 if idrt=0, jcap if idrt=4) ! mow integer smoothing width for pressure level fields ! (default: joc/6 if idrt=0, 0 if idrt=4) ! mooa integer smoothing truncation for pressure level abs vorticity ! (default: moo) ! mowa integer smoothing truncation for pressure level abs vorticity ! (default: mow) ! mooslp integer smoothing truncation for sea level pressure ! (default: 80) ! mowslp integer smoothing truncation for sea level pressure ! (default: 20) ! icen integer forecast center identifier (default: 7) ! icen2 integer forecast sub-center identifier ! (default: from sigma file) ! igen integer model generating code (default: from sigma file) ! ienst integer ensemble type (default: from sigma file) ! iensi integer ensemble identification ! (default: from sigma file) ! lmw integer multiple write flag (default: 1 for yes) ! nkplist integer number of entries in the filter list (default: 1) ! kplist integer (4,nkplist) filter list of fields to output ! in iptv,ipu,itl,il1*256+il2 order (-1 means wildcard) ! (default: kplist(:,1)=-1 and kplist(:,2:)=0) ! ! Input files: ! unit 11-? sigma file(s) ! ! Output files: ! unit 51-? pressure grib1 file(s) ! ! Modules used: ! postgp_module Shared data for postgp ! sigio_r_module Sigma file I/O ! funcphys Physical functions ! ! Subprograms called: ! baopenr byte-addressable open for read ! baopenwt byte-addressable open for write with truncate ! errmsg write error message to stderr ! gfuncphys initialize physics functions ! idsset set defaults for decimal scaling ! instrument collect wall-clock timings ! makglgds create global GDS ! mpabort abort a distributed program ! mpfilli4 gather grid decomposition ! mpfillr4 gather grid decomposition ! mpstart initialize a distributed program ! mpstop finalize a distributed program ! mptgen generate grid decomposition dimensions ! mptran1l1 transpose grid decompositions ! mptran1r4 transpose grid decompositions ! posta post subprogram to vertically interpolate ! posto post subprogram to pack and write output ! postx post subprogram to filter horizontally ! postx1 post subprogram to filter horizontally ! rtflx read and transform flux file ! rtsig read and transform sigma file ! sigio_rrhead read sigma file header ! sigio_rropen open sigma file ! w3tagb document beginning of program ! w3tage document end of program ! ! Attributes: ! Language: cray fortran ! !$$$ use postgp_module use sigio_module use sigio_r_module use funcphys use machine,only:kint_mpi implicit none ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Input namelist integer,parameter:: komax=200,nomax=2000 character(255) ddsig,ddflx,ddpgb integer idrtc,ioc,joc,idrt,io,jo integer lpo,kpo,kpto,kpt,kzz,kth,kpv integer ncpus,mxbit,moo,mow,mooa,mowa,mooslp,mowslp integer icen,icen2,igen,ienst,iensi integer lmw real po(komax),pt(komax),zz(komax),th(komax),pv(komax),pvpt(komax),pvsb(komax) integer ids(255,255) real pob(255),pot(255) real omin(255),omax(255) integer nkplist,kplist(4,nomax) namelist/nampgb/ ddsig,ddflx,ddpgb,& idrtc,ioc,joc,idrt,io,jo,lpo,kpo,po,kpto,kpt,pt,kzz,zz,& kth,th,kpv,pv,pvpt,pvsb,& ncpus,mxbit,ids,pob,pot,omin,omax,& moo,mow,mooa,mowa,mooslp,mowslp,& icen,icen2,igen,ienst,iensi,lmw,& nkplist,kplist ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Other local data integer iret,iretflx integer(sigio_intkind):: irets integer igridc,igrido integer kgdsc(200),kgdso(200),kenso(5) integer ipopt(20) real popa(komax),ptpa(komax),pvptpa(komax) integer(sigio_intkind),parameter:: lusig=11 integer,parameter:: luflx=31,lupgb=51 type(sigio_head):: sighead integer jcap,levs,mo3,mct integer kpdsflxs(200,nflxs),kpdsflxv(200,nflxv) integer kpdsfoxs(200,nfoxs),kpdsfoxv(200,nfoxv) real hrflx,fthour integer ijo,ijoc,nfpos,nfpov,nfpts,nfptv,nfzzs,nfzzv,nfths,nfthv,nfpvs,nfpvv integer(kint_mpi):: comm,rank,size integer k1a,k2a,kma,kna,kxa integer ns1b,ns2b,nsxb,nsmb,nsnb integer nv1b,nv2b,nvxb,nvmb,nvnb integer ij1c,ij2c,ijxc,ijmc,ijnc integer k1d,k2d,kxd,kmd,knd integer nfpos1e,nfpos2e,nfposxe,nfposme,nfposne integer nfpov1e,nfpov2e,nfpovxe,nfpovme,nfpovne integer nfpts1e,nfpts2e,nfptsxe,nfptsme,nfptsne integer nfptv1e,nfptv2e,nfptvxe,nfptvme,nfptvne integer nfzzs1e,nfzzs2e,nfzzsxe,nfzzsme,nfzzsne integer nfzzv1e,nfzzv2e,nfzzvxe,nfzzvme,nfzzvne integer nfths1e,nfths2e,nfthsxe,nfthsme,nfthsne integer nfthv1e,nfthv2e,nfthvxe,nfthvme,nfthvne integer nfpvs1e,nfpvs2e,nfpvsxe,nfpvsme,nfpvsne integer nfpvv1e,nfpvv2e,nfpvvxe,nfpvvme,nfpvvne integer nsuns1e,nsuns2e,nsunsxe,nsunsme,nsunsne integer nsunv1e,nsunv2e,nsunvxe,nsunvme,nsunvne integer nfoxs1e,nfoxs2e,nfoxsxe,nfoxsme,nfoxsne integer nfoxv1e,nfoxv2e,nfoxvxe,nfoxvme,nfoxvne logical*1 ldum(1) real gdum(1) integer iyr,imo,idy,ihr integer iprev,nfw integer i,nk,k,n,ng integer kall real ttot,tmin,tmax ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Allocatable data real,allocatable:: ha(:),pa(:),pxa(:),pya(:) real,allocatable:: ta(:,:),txa(:,:),tya(:,:) real,allocatable:: ua(:,:),va(:,:),da(:,:),za(:,:),sha(:,:),o3a(:,:),cta(:,:) integer,allocatable:: kpdsflxsb(:,:),kpdsflxvb(:,:) logical*1,allocatable:: lflxsb(:,:),lflxvb(:,:) real,allocatable:: fflxsb(:,:),fflxub(:,:),fflxvb(:,:) real,allocatable:: hc(:),pc(:),pxc(:),pyc(:) real,allocatable:: tc(:,:),txc(:,:),tyc(:,:) real,allocatable:: uc(:,:),vc(:,:),dc(:,:),zc(:,:),shc(:,:),o3c(:,:),ctc(:,:) logical*1,allocatable:: lflxsc(:,:),lflxvc(:,:) real,allocatable:: fflxsc(:,:),fflxuc(:,:),fflxvc(:,:) real,allocatable:: fposc(:,:),fpouc(:,:),fpovc(:,:) real,allocatable:: fptsc(:,:),fptuc(:,:),fptvc(:,:) real,allocatable:: fzzsc(:,:),fzzuc(:,:),fzzvc(:,:) logical*1,allocatable:: lthsc(:,:),lthvc(:,:) real,allocatable:: fthsc(:,:),fthuc(:,:),fthvc(:,:) logical*1,allocatable:: lpvsc(:,:),lpvvc(:,:) real,allocatable:: fpvsc(:,:),fpvuc(:,:),fpvvc(:,:) real,allocatable:: fsunsc(:,:),fsunuc(:,:),fsunvc(:,:) logical*1,allocatable:: lfoxsc(:,:),lfoxvc(:,:) real,allocatable:: ffoxsc(:,:),ffoxuc(:,:),ffoxvc(:,:) real,allocatable:: fposd(:,:,:),fpoud(:,:,:),fpovd(:,:,:) integer,allocatable:: ibmse(:),iptve(:),ipue(:),ipve(:) integer,allocatable:: itle(:),il1e(:),il2e(:) integer,allocatable:: ifue(:),ip1e(:),ip2e(:),itre(:) character(16) cinstep(30) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Initial setup call mpstart(comm,rank,size,iret) if(rank.eq.0) then call w3tagb('postgp ',0000,0000,0000,'np23 ') endif call instrument(30,kall,ttot,tmin,tmax) call gfuncphys ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Set defaults and read namelist ddsig='postgp.inp.sig' ddflx='postgp.inp.flx' ddpgb='postgp.out.pgb' idrtc=0 ioc=0 joc=0 idrt=0 io=0 jo=0 lpo=0 kpo=0 po=0. kpto=6 kpt=6 pt=(/30.,60.,90.,120.,150.,180.,(0.,k=6+1,komax)/) kzz=8 zz=(/305.,457.,610.,914.,1829.,2743.,3658.,4572.,(0.,k=8+1,komax)/) kth=0 kpv=8 pv=(/0.5,-0.5,1.0,-1.0,1.5,-1.5,2.0,-2.0,(0.,k=kpv+1,komax)/) pvpt=(/(50.,k=1,kpv),(0.,k=kpv+1,komax)/) pvsb=(/(0.8,k=1,kpv),(0.,k=kpv+1,komax)/) ncpus=1 mxbit=20 call idsset(ids) pob=1000. ! pob(051)=0. ! pob(153)=0. pob(154)=100. pob(222)=500. pot=0. pot(039)=100. pot(051)=100. pot(052)=100. pot(153)=100. pot(222)=500. omin=-huge(omin) omin(51)=0. omin(52)=0. omin(153)=0. omin(154)=0. omax=+huge(omax) omax(52)=100. moo=0 mow=0 mooa=0 mowa=0 mooslp=80 mowslp=20 icen=7 icen2=0 igen=0 ienst=0 iensi=0 lmw=1 nkplist=1 kplist(:,1)=-1 kplist(:,2:)=0 read(*,nampgb,iostat=iret) ! write(*,nampgb) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Open sigma file call sigio_rropen(lusig,ddsig,irets) if(irets.ne.0) then call errmsg('Error opening input sigma file '//ddsig) call mpabort(11) endif if(rank.eq.0)& print '("postgp: opened sigma file ",a)',ddsig call sigio_rrhead(lusig,sighead,irets) if(irets.ne.0) then call errmsg('Error reading input sigma file '//ddsig) call mpabort(11) endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Set more defaults jcap=sighead%jcap levs=sighead%levs if(icen2.eq.0) icen2=sighead%icen2 if(igen.eq.0) igen=sighead%igen if(ienst.eq.0) ienst=sighead%iens(1) if(iensi.eq.0) iensi=sighead%iens(2) if(io.eq.0.or.jo.eq.0) then idrt=0 if(jcap.eq.62) then io=144 jo=73 elseif(jcap.ge.382) then io=720 jo=361 else io=360 jo=181 endif endif if(ioc.eq.0.or.joc.eq.0) then idrtc=idrt ioc=io joc=jo endif if(moo.eq.0) then if(idrtc.eq.0) then moo=2*joc/3 mow=joc/6 else moo=jcap mow=0 endif endif if(mooa.eq.0) then mooa=moo mowa=mow endif if(mooslp.eq.0) then mooslp=moo mowslp=mow endif if(mooslp.gt.moo) then mooslp=moo mowslp=mow endif if(kpo.eq.0) then if(lpo.eq.0) then if(levs.lt.64) then lpo=1 else lpo=2 endif endif if(lpo.eq.1) then kpo=31 po=(/1000.,975.,950.,925.,900.,850.,800.,750.,700.,650.,600.,& 550.,500.,450.,400.,350.,300.,250.,200.,150.,100.,& 70.,50.,30.,20.,10.,7.,5.,3.,2.,1.,& (0.,k=31+1,komax)/) elseif(lpo.eq.2) then kpo=47 po=(/1000.,975.,950.,925.,900.,875.,850.,825.,800.,775.,750.,725.,700.,& 675.,650.,625.,600.,575.,550.,525.,500.,475.,450.,425.,400.,& 375.,350.,325.,300.,275.,250.,225.,200.,175.,150.,125.,100.,& 70.,50.,30.,20.,10.,7.,5.,3.,2.,1.,& (0.,k=47+1,komax)/) else kpo=15 po=(/1000.,850.,700.,500.,400.,300.,250.,200.,150.,100.,& 70.,50.,30.,20.,10.,& (0.,k=15+1,komax)/) endif endif nfpos=npos*kpo nfpov=npov*kpo nfpts=npts*kpt nfptv=nptv*kpt nfzzs=nzzs*kzz nfzzv=nzzv*kzz nfths=nths*kth nfthv=nthv*kth nfpvs=npvs*kpv nfpvv=npvv*kpv call makglgds(idrtc,ioc,joc,igridc,kgdsc) call makglgds(idrt,io,jo,igrido,kgdso) ijo=io*jo ijoc=ioc*joc popa=po*1.e+2 ptpa=pt*1.e+2 pvptpa=pvpt*1.e+2 if(rank.eq.0) then print '("postgp: sigma file resolution T ",i4," L ",i4)',jcap,levs if(idrtc.eq.0) then print '("postgp: compute grid is equal-spaced ",i4," by ",i4)',ioc,joc else print '("postgp: compute grid is Gaussian ",i4," by ",i4)',ioc,joc endif if(idrt.eq.0) then print '("postgp: output grid is equal-spaced ",i4," by ",i4)',io,jo else print '("postgp: output grid is Gaussian ",i4," by ",i4)',io,jo endif endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Open flux file call baopenr(luflx,ddflx,iretflx) if(iretflx.ne.0) then if(rank.eq.0)& print '("postgp: error opening flux file ",a)',ddflx else if(rank.eq.0)& print '("postgp: opened flux file ",a)',ddflx endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Open postgp file if(lmw.ne.0.or.rank.eq.0) then call baopenwt(lupgb,ddpgb,iret) if(iret.ne.0) then call errmsg('Error opening output postgp file '//ddpgb) call mpabort(51) endif endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Determine grid decompositions call mptgen(rank,size,1,1,levs,k1a,k2a,kxa,kma,kna) call mptgen(rank,size,1,1,nflxs,ns1b,ns2b,nsxb,nsmb,nsnb) call mptgen(rank,size,1,1,nflxv,nv1b,nv2b,nvxb,nvmb,nvnb) call mptgen(rank,size,1,1,ijoc,ij1c,ij2c,ijxc,ijmc,ijnc) call mptgen(rank,size,1,1,kpo,k1d,k2d,kxd,kmd,knd) call mptgen(rank,size,1,1,nfpos,nfpos1e,nfpos2e,nfposxe,nfposme,nfposne) call mptgen(rank,size,1,1,nfpov,nfpov1e,nfpov2e,nfpovxe,nfpovme,nfpovne) call mptgen(rank,size,1,1,nfpts,nfpts1e,nfpts2e,nfptsxe,nfptsme,nfptsne) call mptgen(rank,size,1,1,nfptv,nfptv1e,nfptv2e,nfptvxe,nfptvme,nfptvne) call mptgen(rank,size,1,1,nfzzs,nfzzs1e,nfzzs2e,nfzzsxe,nfzzsme,nfzzsne) call mptgen(rank,size,1,1,nfzzv,nfzzv1e,nfzzv2e,nfzzvxe,nfzzvme,nfzzvne) call mptgen(rank,size,1,1,nfths,nfths1e,nfths2e,nfthsxe,nfthsme,nfthsne) call mptgen(rank,size,1,1,nfthv,nfthv1e,nfthv2e,nfthvxe,nfthvme,nfthvne) call mptgen(rank,size,1,1,nfpvs,nfpvs1e,nfpvs2e,nfpvsxe,nfpvsme,nfpvsne) call mptgen(rank,size,1,1,nfpvv,nfpvv1e,nfpvv2e,nfpvvxe,nfpvvme,nfpvvne) call mptgen(rank,size,1,1,nsuns,nsuns1e,nsuns2e,nsunsxe,nsunsme,nsunsne) call mptgen(rank,size,1,1,nsunv,nsunv1e,nsunv2e,nsunvxe,nsunvme,nsunvne) call mptgen(rank,size,1,1,nfoxs,nfoxs1e,nfoxs2e,nfoxsxe,nfoxsme,nfoxsne) call mptgen(rank,size,1,1,nfoxv,nfoxv1e,nfoxv2e,nfoxvxe,nfoxvme,nfoxvne) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Allocate step c input arrays allocate(hc(ij1c:ij2c),& pc(ij1c:ij2c),& pxc(ij1c:ij2c),& pyc(ij1c:ij2c),& tc(levs,ij1c:ij2c),& txc(levs,ij1c:ij2c),& tyc(levs,ij1c:ij2c),& uc(levs,ij1c:ij2c),& vc(levs,ij1c:ij2c),& dc(levs,ij1c:ij2c),& zc(levs,ij1c:ij2c),& shc(levs,ij1c:ij2c),& o3c(levs,ij1c:ij2c),& ctc(levs,ij1c:ij2c),& lflxsc(nflxs,ij1c:ij2c),& lflxvc(nflxv,ij1c:ij2c),& fflxsc(nflxs,ij1c:ij2c),& fflxuc(nflxv,ij1c:ij2c),& fflxvc(nflxv,ij1c:ij2c)) call instrument(1,kall,ttot,tmin,tmax);cinstep(1)='setup' ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Step A: read and transform sigma file if(rank.eq.0)& print *,'Begin Step A.' allocate(ha(ijoc),& pa(ijoc),& pxa(ijoc),& pya(ijoc),& ta(ijoc,k1a:k2a),& txa(ijoc,k1a:k2a),& tya(ijoc,k1a:k2a),& ua(ijoc,k1a:k2a),& va(ijoc,k1a:k2a),& da(ijoc,k1a:k2a),& za(ijoc,k1a:k2a),& sha(ijoc,k1a:k2a),& o3a(ijoc,k1a:k2a),& cta(ijoc,k1a:k2a)) call rtsig(lusig,sighead,k1a,k2a,kgdsc,ijoc,1,ha,pa,pxa,pya,& ta,txa,tya,ua,va,da,za,sha,o3a,cta,mo3,mct,iret) if(iret.ne.0) then call errmsg('Error reading input sigma file '//ddsig) call mpabort(11) endif if(mo3.eq.0) o3a=0 if(mct.eq.0) cta=0 call instrument(2,kall,ttot,tmin,tmax);cinstep(2)='step a rtsig' hc=ha(ij1c:ij2c) deallocate(ha) pc=pa(ij1c:ij2c) deallocate(pa) pxc=pxa(ij1c:ij2c) deallocate(pxa) pyc=pya(ij1c:ij2c) deallocate(pya) call mptran1r4(comm,size,ijmc,ijoc,ijxc,ijoc,kma,kxa,levs,levs,ta,tc) deallocate(ta) call mptran1r4(comm,size,ijmc,ijoc,ijxc,ijoc,kma,kxa,levs,levs,txa,txc) deallocate(txa) call mptran1r4(comm,size,ijmc,ijoc,ijxc,ijoc,kma,kxa,levs,levs,tya,tyc) deallocate(tya) call mptran1r4(comm,size,ijmc,ijoc,ijxc,ijoc,kma,kxa,levs,levs,ua,uc) deallocate(ua) call mptran1r4(comm,size,ijmc,ijoc,ijxc,ijoc,kma,kxa,levs,levs,va,vc) deallocate(va) call mptran1r4(comm,size,ijmc,ijoc,ijxc,ijoc,kma,kxa,levs,levs,da,dc) deallocate(da) call mptran1r4(comm,size,ijmc,ijoc,ijxc,ijoc,kma,kxa,levs,levs,za,zc) deallocate(za) call mptran1r4(comm,size,ijmc,ijoc,ijxc,ijoc,kma,kxa,levs,levs,sha,shc) deallocate(sha) call mptran1r4(comm,size,ijmc,ijoc,ijxc,ijoc,kma,kxa,levs,levs,o3a,o3c) deallocate(o3a) call mptran1r4(comm,size,ijmc,ijoc,ijxc,ijoc,kma,kxa,levs,levs,cta,ctc) deallocate(cta) call instrument(3,kall,ttot,tmin,tmax);cinstep(3)='step a tran' ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Step B: read an transform flux file if(rank.eq.0)& print *,'Begin Step B.' if(iretflx.eq.0) then allocate(kpdsflxsb(200,ns1b:ns2b),& kpdsflxvb(200,nv1b:nv2b),& lflxsb(ijoc,ns1b:ns2b),& lflxvb(ijoc,nv1b:nv2b),& fflxsb(ijoc,ns1b:ns2b),& fflxub(ijoc,nv1b:nv2b),& fflxvb(ijoc,nv1b:nv2b)) call rtflx(luflx,nsxb,nvxb,kgdsc,ijoc,& jpdsflxs(1:24,ns1b:ns2b),& jpdsflxu(1:24,nv1b:nv2b),jpdsflxv(1:24,nv1b:nv2b),& kpdsflxsb,kpdsflxvb,lflxsb,lflxvb,fflxsb,fflxub,fflxvb) call instrument(4,kall,ttot,tmin,tmax);cinstep(4)='step b rtflx' call mpfilli4(comm,size,200,200,200,nsmb,nsxb,nflxs,kpdsflxsb,kpdsflxs) deallocate(kpdsflxsb) call mpfilli4(comm,size,200,200,200,nvmb,nvxb,nflxv,kpdsflxvb,kpdsflxv) deallocate(kpdsflxvb) call mptran1l1(comm,size,ijmc,ijoc,ijxc,ijoc,nsmb,nsxb,nflxs,nflxs,& lflxsb,lflxsc) deallocate(lflxsb) call mptran1l1(comm,size,ijmc,ijoc,ijxc,ijoc,nvmb,nvxb,nflxv,nflxv,& lflxvb,lflxvc) deallocate(lflxvb) call mptran1r4(comm,size,ijmc,ijoc,ijxc,ijoc,nsmb,nsxb,nflxs,nflxs,& fflxsb,fflxsc) deallocate(fflxsb) call mptran1r4(comm,size,ijmc,ijoc,ijxc,ijoc,nvmb,nvxb,nflxv,nflxv,& fflxub,fflxuc) deallocate(fflxub) call mptran1r4(comm,size,ijmc,ijoc,ijxc,ijoc,nvmb,nvxb,nflxv,nflxv,& fflxvb,fflxvc) deallocate(fflxvb) hrflx=0. if(kpdsflxs(16,iflxs_prate_sfc).eq.3)& hrflx=fthour(kpdsflxs(13,iflxs_prate_sfc),& kpdsflxs(15,iflxs_prate_sfc)-kpdsflxs(14,iflxs_prate_sfc)) else lflxsc=.false. lflxvc=.false. fflxsc=0. fflxuc=0. fflxvc=0. hrflx=0. endif call instrument(5,kall,ttot,tmin,tmax);cinstep(5)='step b tran' ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Step C: vertically interpolate to output levels if(rank.eq.0)& print *,'Begin Step C.' allocate(fposc(nfpos,ij1c:ij2c),& fpouc(nfpov,ij1c:ij2c),& fpovc(nfpov,ij1c:ij2c),& fptsc(nfpts,ij1c:ij2c),& fptuc(nfptv,ij1c:ij2c),& fptvc(nfptv,ij1c:ij2c),& fzzsc(nfzzs,ij1c:ij2c),& fzzuc(nfzzv,ij1c:ij2c),& fzzvc(nfzzv,ij1c:ij2c),& lthsc(nfths,ij1c:ij2c),& lthvc(nfthv,ij1c:ij2c),& fthsc(nfths,ij1c:ij2c),& fthuc(nfthv,ij1c:ij2c),& fthvc(nfthv,ij1c:ij2c),& lpvsc(nfpvs,ij1c:ij2c),& lpvvc(nfpvv,ij1c:ij2c),& fpvsc(nfpvs,ij1c:ij2c),& fpvuc(nfpvv,ij1c:ij2c),& fpvvc(nfpvv,ij1c:ij2c),& fsunsc(nsuns,ij1c:ij2c),& fsunuc(nsunv,ij1c:ij2c),& fsunvc(nsunv,ij1c:ij2c),& lfoxsc(nfoxs,ij1c:ij2c),& lfoxvc(nfoxv,ij1c:ij2c),& ffoxsc(nfoxs,ij1c:ij2c),& ffoxuc(nfoxv,ij1c:ij2c),& ffoxvc(nfoxv,ij1c:ij2c)) call posta(ijxc,levs,& sighead%idvc,sighead%idsl,sighead%nvcoord,sighead%vcoord,& hc,pc,pxc,pyc,tc,txc,tyc,uc,vc,dc,zc,shc,o3c,ctc,& hrflx,kpdsflxs,kpdsflxv,lflxsc,lflxvc,fflxsc,fflxuc,fflxvc,& kpo,popa,kpt,ptpa,kzz,zz,kth,th,kpv,pv,pvptpa,pvsb,& nfpos,nfpov,nfpts,nfptv,nfzzs,nfzzv,& nfths,nfthv,nfpvs,nfpvv,& kpdsfoxs,kpdsfoxv,lfoxsc,lfoxvc,& fposc,fpouc,fpovc,fptsc,fptuc,fptvc,fzzsc,fzzuc,fzzvc,& lthsc,lthvc,fthsc,fthuc,fthvc,lpvsc,lpvvc,fpvsc,fpvuc,fpvvc,& fsunsc,fsunuc,fsunvc,ffoxsc,ffoxuc,ffoxvc) deallocate(hc,pc,pxc,pyc,tc,txc,tyc,uc,vc,dc,zc,shc,o3c,ctc,& lflxsc,lflxvc,fflxsc,fflxuc,fflxvc) call instrument(6,kall,ttot,tmin,tmax);cinstep(6)='step c' ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Step D: filter horizontally if(rank.eq.0)& print *,'Begin Step D.' if(moo.ne.255) then allocate(fposd(ijoc,k1d:k2d,npos),& fpoud(ijoc,k1d:k2d,npov),& fpovd(ijoc,k1d:k2d,npov)) do n=1,npos call mptran1r4(comm,size,kmd,kpo,kxd,nfpos,ijmc,ijxc,ijoc,ijoc,& fposc(1+(n-1)*kpo,ij1c),fposd(1,k1d,n)) enddo do n=1,npov call mptran1r4(comm,size,kmd,kpo,kxd,nfpov,ijmc,ijxc,ijoc,ijoc,& fpouc(1+(n-1)*kpo,ij1c),fpoud(1,k1d,n)) call mptran1r4(comm,size,kmd,kpo,kxd,nfpov,ijmc,ijxc,ijoc,ijoc,& fpovc(1+(n-1)*kpo,ij1c),fpovd(1,k1d,n)) enddo call instrument(8,kall,ttot,tmin,tmax);cinstep(8)='step d tran' call postx(idrtc,ioc,joc,kxd,moo,mow,mooa,mowa,fposd,fpoud,fpovd) call instrument(7,kall,ttot,tmin,tmax);cinstep(7)='step d postx' do n=1,npos call mptran1r4(comm,size,ijmc,ijoc,ijxc,ijoc,kmd,kxd,kpo,nfpos,& fposd(1,k1d,n),fposc(1+(n-1)*kpo,ij1c)) enddo do n=1,npov call mptran1r4(comm,size,ijmc,ijoc,ijxc,ijoc,kmd,kxd,kpo,nfpov,& fpoud(1,k1d,n),fpouc(1+(n-1)*kpo,ij1c)) call mptran1r4(comm,size,ijmc,ijoc,ijxc,ijoc,kmd,kxd,kpo,nfpov,& fpovd(1,k1d,n),fpovc(1+(n-1)*kpo,ij1c)) enddo deallocate(fposd,fpoud,fpovd) call instrument(8,kall,ttot,tmin,tmax);cinstep(8)='step d tran' if(mooslp.ne.0) then allocate(fposd(ijoc,1,1)) call mpfillr4(comm,size,1,1,1,ijmc,ijxc,ijoc,& fsunsc(isuns_prmsl_msl,ij1c:ij2c),fposd) call instrument(8,kall,ttot,tmin,tmax);cinstep(8)='step d tran' call postx1(idrtc,ioc,joc,mooslp,mowslp,fposd) call instrument(7,kall,ttot,tmin,tmax);cinstep(7)='step d postx' fsunsc(isuns_prmsl_msl,ij1c:ij2c)=fposd(ij1c:ij2c,1,1) deallocate(fposd) call instrument(8,kall,ttot,tmin,tmax);cinstep(8)='step d tran' endif endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Step E: pack and write output file if(rank.eq.0)& print *,'Begin Step E.' iyr=sighead%idate(4) imo=sighead%idate(2) idy=sighead%idate(3) ihr=sighead%idate(1) iprev=0 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Output pressure level scalar allocate(ibmse(nfpos1e:nfpos2e),& iptve(nfpos1e:nfpos2e),& ipue(nfpos1e:nfpos2e),& ipve(nfpos1e:nfpos2e),& itle(nfpos1e:nfpos2e),& il1e(nfpos1e:nfpos2e),& il2e(nfpos1e:nfpos2e),& ifue(nfpos1e:nfpos2e),& ip1e(nfpos1e:nfpos2e),& ip2e(nfpos1e:nfpos2e),& itre(nfpos1e:nfpos2e)) do nk=nfpos1e,nfpos2e k=mod(nk-1,kpo)+1 n=(nk-1)/kpo+1 ibmse(nk)=0 iptve(nk)=jpdspos(19,n) ipue(nk)=jpdspos(5,n) ipve(nk)=-1 itle(nk)=100 il1e(nk)=0 il2e(nk)=nint(po(k)) if(abs(po(k)-nint(po(k))).gt.0.005.and.po(k).lt.655.) then itle(nk)=126 il1e(nk)=0 il2e(nk)=nint(po(k)*1.e2) endif ifue(nk)=1 ip1e(nk)=nint(sighead%fhour) ip2e(nk)=0 itre(nk)=10 if(n.eq.ipos_o3mr_prs.and.mo3.eq.0) ipue(nk)=0 if(n.eq.ipos_clwmr_prs.and.mct.eq.0) ipue(nk)=0 if(po(k).gt.pob(ipue(nk)).or.po(k).lt.pot(ipue(nk))) ipue(nk)=0 enddo call kpfilt(nkplist,kplist,nfposxe,iptve,ipue,itle,il1e,il2e) call posto(comm,size,nfpos,nfpos1e,nfpos2e,nfposme,nfposxe,& ijmc,ijxc,ijoc,ijo,ldum,fposc,gdum,0,0,lmw,& ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre,& idrtc,ioc,joc,kgdsc,idrt,io,jo,kgdso,& icen,igen,igrido,iyr,imo,idy,ihr,icen2,ienst,iensi,& ids,omin,omax,mxbit,lupgb,iprev,nfw,iret) deallocate(fposc) deallocate(ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre) if(iret.ne.0) then call errmsg('Error packing or writing to output file '//ddpgb) call mpabort(51) endif if(rank.eq.0)& print '(i6," pressure level scalar",t30,"fields written.",& &i15," total bytes written.")',nfw,iprev call instrument(9,kall,ttot,tmin,tmax);cinstep(9)='step e pos' ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Output pressure level vector allocate(ibmse(nfpov1e:nfpov2e),& iptve(nfpov1e:nfpov2e),& ipue(nfpov1e:nfpov2e),& ipve(nfpov1e:nfpov2e),& itle(nfpov1e:nfpov2e),& il1e(nfpov1e:nfpov2e),& il2e(nfpov1e:nfpov2e),& ifue(nfpov1e:nfpov2e),& ip1e(nfpov1e:nfpov2e),& ip2e(nfpov1e:nfpov2e),& itre(nfpov1e:nfpov2e)) do nk=nfpov1e,nfpov2e k=mod(nk-1,kpo)+1 n=(nk-1)/kpo+1 ibmse(nk)=0 iptve(nk)=jpdspov(19,n) ipue(nk)=jpdspou(5,n) ipve(nk)=jpdspov(5,n) itle(nk)=100 il1e(nk)=0 il2e(nk)=nint(po(k)) if(abs(po(k)-nint(po(k))).gt.0.005.and.po(k).lt.655.) then itle(nk)=126 il1e(nk)=0 il2e(nk)=nint(po(k)*1.e2) endif ifue(nk)=1 ip1e(nk)=nint(sighead%fhour) ip2e(nk)=0 itre(nk)=10 if(po(k).gt.pob(ipue(nk)).or.po(k).lt.pot(ipue(nk))) ipue(nk)=0 if(po(k).gt.pob(ipve(nk)).or.po(k).lt.pot(ipve(nk))) ipve(nk)=0 enddo call kpfilt(nkplist,kplist,nfpovxe,iptve,ipue,itle,il1e,il2e) call kpfilt(nkplist,kplist,nfpovxe,iptve,ipve,itle,il1e,il2e) call posto(comm,size,nfpov,nfpov1e,nfpov2e,nfpovme,nfpovxe,& ijmc,ijxc,ijoc,ijo,ldum,fpouc,fpovc,0,1,lmw,& ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre,& idrtc,ioc,joc,kgdsc,idrt,io,jo,kgdso,& icen,igen,igrido,iyr,imo,idy,ihr,icen2,ienst,iensi,& ids,omin,omax,mxbit,lupgb,iprev,nfw,iret) deallocate(fpouc,fpovc) deallocate(ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre) if(iret.ne.0) then call errmsg('Error packing or writing to output file '//ddpgb) call mpabort(51) endif if(rank.eq.0)& print '(i6," pressure level vector",t30,"fields written.",& &i15," total bytes written.")',nfw,iprev call instrument(10,kall,ttot,tmin,tmax);cinstep(10)='step e pov' ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Output pressure layer scalar allocate(ibmse(nfpts1e:nfpts2e),& iptve(nfpts1e:nfpts2e),& ipue(nfpts1e:nfpts2e),& ipve(nfpts1e:nfpts2e),& itle(nfpts1e:nfpts2e),& il1e(nfpts1e:nfpts2e),& il2e(nfpts1e:nfpts2e),& ifue(nfpts1e:nfpts2e),& ip1e(nfpts1e:nfpts2e),& ip2e(nfpts1e:nfpts2e),& itre(nfpts1e:nfpts2e)) do nk=nfpts1e,nfpts2e k=mod(nk-1,kpt)+1 n=(nk-1)/kpt+1 ibmse(nk)=0 iptve(nk)=jpdspts(19,n) ipue(nk)=jpdspts(5,n) ipve(nk)=-1 itle(nk)=116 il1e(nk)=nint(pt(k)) il2e(nk)=0 if(k.gt.1) il2e(nk)=nint(pt(k-1)) ifue(nk)=1 ip1e(nk)=nint(sighead%fhour) ip2e(nk)=0 itre(nk)=10 if(k.gt.kpto) ipue(nk)=0 enddo call kpfilt(nkplist,kplist,nfptsxe,iptve,ipue,itle,il1e,il2e) call posto(comm,size,nfpts,nfpts1e,nfpts2e,nfptsme,nfptsxe,& ijmc,ijxc,ijoc,ijo,ldum,fptsc,gdum,0,0,lmw,& ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre,& idrtc,ioc,joc,kgdsc,idrt,io,jo,kgdso,& icen,igen,igrido,iyr,imo,idy,ihr,icen2,ienst,iensi,& ids,omin,omax,mxbit,lupgb,iprev,nfw,iret) deallocate(fptsc) deallocate(ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre) if(iret.ne.0) then call errmsg('Error packing or writing to output file '//ddpgb) call mpabort(51) endif if(rank.eq.0)& print '(i6," pressure layer scalar",t30,"fields written.",& &i15," total bytes written.")',nfw,iprev call instrument(11,kall,ttot,tmin,tmax);cinstep(11)='step e pts' ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Output pressure layer vector allocate(ibmse(nfptv1e:nfptv2e),& iptve(nfptv1e:nfptv2e),& ipue(nfptv1e:nfptv2e),& ipve(nfptv1e:nfptv2e),& itle(nfptv1e:nfptv2e),& il1e(nfptv1e:nfptv2e),& il2e(nfptv1e:nfptv2e),& ifue(nfptv1e:nfptv2e),& ip1e(nfptv1e:nfptv2e),& ip2e(nfptv1e:nfptv2e),& itre(nfptv1e:nfptv2e)) do nk=nfptv1e,nfptv2e k=mod(nk-1,kpt)+1 n=(nk-1)/kpt+1 ibmse(nk)=0 iptve(nk)=jpdsptv(19,n) ipue(nk)=jpdsptu(5,n) ipve(nk)=jpdsptv(5,n) itle(nk)=116 il1e(nk)=nint(pt(k)) il2e(nk)=0 if(k.gt.1) il2e(nk)=nint(pt(k-1)) ifue(nk)=1 ip1e(nk)=nint(sighead%fhour) ip2e(nk)=0 itre(nk)=10 if(k.gt.kpto) ipue(nk)=0 if(k.gt.kpto) ipve(nk)=0 enddo call kpfilt(nkplist,kplist,nfptvxe,iptve,ipue,itle,il1e,il2e) call kpfilt(nkplist,kplist,nfptvxe,iptve,ipve,itle,il1e,il2e) call posto(comm,size,nfptv,nfptv1e,nfptv2e,nfptvme,nfptvxe,& ijmc,ijxc,ijoc,ijo,ldum,fptuc,fptvc,0,1,lmw,& ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre,& idrtc,ioc,joc,kgdsc,idrt,io,jo,kgdso,& icen,igen,igrido,iyr,imo,idy,ihr,icen2,ienst,iensi,& ids,omin,omax,mxbit,lupgb,iprev,nfw,iret) deallocate(fptuc,fptvc) deallocate(ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre) if(iret.ne.0) then call errmsg('Error packing or writing to output file '//ddpgb) call mpabort(51) endif if(rank.eq.0)& print '(i6," pressure layer vector",t30,"fields written.",& &i15," total bytes written.")',nfw,iprev call instrument(12,kall,ttot,tmin,tmax);cinstep(12)='step e ptv' ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Output height above sea level scalar allocate(ibmse(nfzzs1e:nfzzs2e),& iptve(nfzzs1e:nfzzs2e),& ipue(nfzzs1e:nfzzs2e),& ipve(nfzzs1e:nfzzs2e),& itle(nfzzs1e:nfzzs2e),& il1e(nfzzs1e:nfzzs2e),& il2e(nfzzs1e:nfzzs2e),& ifue(nfzzs1e:nfzzs2e),& ip1e(nfzzs1e:nfzzs2e),& ip2e(nfzzs1e:nfzzs2e),& itre(nfzzs1e:nfzzs2e)) do nk=nfzzs1e,nfzzs2e k=mod(nk-1,kzz)+1 n=(nk-1)/kzz+1 ibmse(nk)=0 iptve(nk)=jpdszzs(19,n) ipue(nk)=jpdszzs(5,n) ipve(nk)=-1 itle(nk)=103 il1e(nk)=0 il2e(nk)=nint(zz(k)) ifue(nk)=1 ip1e(nk)=nint(sighead%fhour) ip2e(nk)=0 itre(nk)=10 if(ipue(nk).eq.52) ipue(nk)=0 ! skip rh for now enddo call kpfilt(nkplist,kplist,nfzzsxe,iptve,ipue,itle,il1e,il2e) call posto(comm,size,nfzzs,nfzzs1e,nfzzs2e,nfzzsme,nfzzsxe,& ijmc,ijxc,ijoc,ijo,ldum,fzzsc,gdum,0,0,lmw,& ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre,& idrtc,ioc,joc,kgdsc,idrt,io,jo,kgdso,& icen,igen,igrido,iyr,imo,idy,ihr,icen2,ienst,iensi,& ids,omin,omax,mxbit,lupgb,iprev,nfw,iret) deallocate(fzzsc) deallocate(ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre) if(iret.ne.0) then call errmsg('Error packing or writing to output file '//ddpgb) call mpabort(51) endif if(rank.eq.0)& print '(i6," height level scalar",t30,"fields written.",& &i15," total bytes written.")',nfw,iprev call instrument(13,kall,ttot,tmin,tmax);cinstep(13)='step e zzs' ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Output height above sea level vector allocate(ibmse(nfzzv1e:nfzzv2e),& iptve(nfzzv1e:nfzzv2e),& ipue(nfzzv1e:nfzzv2e),& ipve(nfzzv1e:nfzzv2e),& itle(nfzzv1e:nfzzv2e),& il1e(nfzzv1e:nfzzv2e),& il2e(nfzzv1e:nfzzv2e),& ifue(nfzzv1e:nfzzv2e),& ip1e(nfzzv1e:nfzzv2e),& ip2e(nfzzv1e:nfzzv2e),& itre(nfzzv1e:nfzzv2e)) do nk=nfzzv1e,nfzzv2e k=mod(nk-1,kzz)+1 n=(nk-1)/kzz+1 ibmse(nk)=0 iptve(nk)=jpdszzv(19,n) ipue(nk)=jpdszzu(5,n) ipve(nk)=jpdszzv(5,n) itle(nk)=103 il1e(nk)=0 il2e(nk)=nint(zz(k)) ifue(nk)=1 ip1e(nk)=nint(sighead%fhour) ip2e(nk)=0 itre(nk)=10 enddo call kpfilt(nkplist,kplist,nfzzvxe,iptve,ipue,itle,il1e,il2e) call kpfilt(nkplist,kplist,nfzzvxe,iptve,ipve,itle,il1e,il2e) call posto(comm,size,nfzzv,nfzzv1e,nfzzv2e,nfzzvme,nfzzvxe,& ijmc,ijxc,ijoc,ijo,ldum,fzzuc,fzzvc,0,1,lmw,& ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre,& idrtc,ioc,joc,kgdsc,idrt,io,jo,kgdso,& icen,igen,igrido,iyr,imo,idy,ihr,icen2,ienst,iensi,& ids,omin,omax,mxbit,lupgb,iprev,nfw,iret) deallocate(fzzuc,fzzvc) deallocate(ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre) if(iret.ne.0) then call errmsg('Error packing or writing to output file '//ddpgb) call mpabort(51) endif if(rank.eq.0)& print '(i6," height level vector",t30,"fields written.",& &i15," total bytes written.")',nfw,iprev call instrument(14,kall,ttot,tmin,tmax);cinstep(14)='step e zzv' ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Output potential temperature level scalar allocate(ibmse(nfths1e:nfths2e),& iptve(nfths1e:nfths2e),& ipue(nfths1e:nfths2e),& ipve(nfths1e:nfths2e),& itle(nfths1e:nfths2e),& il1e(nfths1e:nfths2e),& il2e(nfths1e:nfths2e),& ifue(nfths1e:nfths2e),& ip1e(nfths1e:nfths2e),& ip2e(nfths1e:nfths2e),& itre(nfths1e:nfths2e)) do nk=nfths1e,nfths2e k=mod(nk-1,kth)+1 n=(nk-1)/kth+1 ibmse(nk)=1 iptve(nk)=jpdsths(19,n) ipue(nk)=jpdsths(5,n) ipve(nk)=-1 itle(nk)=113 il1e(nk)=0 il2e(nk)=nint(th(k)) ifue(nk)=1 ip1e(nk)=nint(sighead%fhour) ip2e(nk)=0 itre(nk)=10 enddo call kpfilt(nkplist,kplist,nfthsxe,iptve,ipue,itle,il1e,il2e) call posto(comm,size,nfths,nfths1e,nfths2e,nfthsme,nfthsxe,& ijmc,ijxc,ijoc,ijo,lthsc,fthsc,gdum,1,0,lmw,& ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre,& idrtc,ioc,joc,kgdsc,idrt,io,jo,kgdso,& icen,igen,igrido,iyr,imo,idy,ihr,icen2,ienst,iensi,& ids,omin,omax,mxbit,lupgb,iprev,nfw,iret) deallocate(lthsc,fthsc) deallocate(ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre) if(iret.ne.0) then call errmsg('Error packing or writing to output file '//ddpgb) call mpabort(51) endif if(rank.eq.0)& print '(i6," isentropic level scalar",t30,"fields written.",& &i15," total bytes written.")',nfw,iprev call instrument(15,kall,ttot,tmin,tmax);cinstep(13)='step e ths' ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Output potential temperature level vector allocate(ibmse(nfthv1e:nfthv2e),& iptve(nfthv1e:nfthv2e),& ipue(nfthv1e:nfthv2e),& ipve(nfthv1e:nfthv2e),& itle(nfthv1e:nfthv2e),& il1e(nfthv1e:nfthv2e),& il2e(nfthv1e:nfthv2e),& ifue(nfthv1e:nfthv2e),& ip1e(nfthv1e:nfthv2e),& ip2e(nfthv1e:nfthv2e),& itre(nfthv1e:nfthv2e)) do nk=nfthv1e,nfthv2e k=mod(nk-1,kth)+1 n=(nk-1)/kth+1 ibmse(nk)=1 iptve(nk)=jpdsthv(19,n) ipue(nk)=jpdsthu(5,n) ipve(nk)=jpdsthv(5,n) itle(nk)=113 il1e(nk)=0 il2e(nk)=nint(th(k)) ifue(nk)=1 ip1e(nk)=nint(sighead%fhour) ip2e(nk)=0 itre(nk)=10 enddo call kpfilt(nkplist,kplist,nfthvxe,iptve,ipue,itle,il1e,il2e) call kpfilt(nkplist,kplist,nfthvxe,iptve,ipve,itle,il1e,il2e) call posto(comm,size,nfthv,nfthv1e,nfthv2e,nfthvme,nfthvxe,& ijmc,ijxc,ijoc,ijo,lthvc,fthuc,fthvc,1,1,lmw,& ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre,& idrtc,ioc,joc,kgdsc,idrt,io,jo,kgdso,& icen,igen,igrido,iyr,imo,idy,ihr,icen2,ienst,iensi,& ids,omin,omax,mxbit,lupgb,iprev,nfw,iret) deallocate(lthvc,fthuc,fthvc) deallocate(ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre) if(iret.ne.0) then call errmsg('Error packing or writing to output file '//ddpgb) call mpabort(51) endif if(rank.eq.0)& print '(i6," isentropic level vector",t30,"fields written.",& &i15," total bytes written.")',nfw,iprev call instrument(16,kall,ttot,tmin,tmax);cinstep(14)='step e thv' ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Output potential vorticity level scalar allocate(ibmse(nfpvs1e:nfpvs2e),& iptve(nfpvs1e:nfpvs2e),& ipue(nfpvs1e:nfpvs2e),& ipve(nfpvs1e:nfpvs2e),& itle(nfpvs1e:nfpvs2e),& il1e(nfpvs1e:nfpvs2e),& il2e(nfpvs1e:nfpvs2e),& ifue(nfpvs1e:nfpvs2e),& ip1e(nfpvs1e:nfpvs2e),& ip2e(nfpvs1e:nfpvs2e),& itre(nfpvs1e:nfpvs2e)) do nk=nfpvs1e,nfpvs2e k=mod(nk-1,kpv)+1 n=(nk-1)/kpv+1 ibmse(nk)=1 iptve(nk)=jpdspvs(19,n) ipue(nk)=jpdspvs(5,n) ipve(nk)=-1 itle(nk)=117 il1e(nk)=0 il2e(nk)=nint(pv(k)*1.e3) ifue(nk)=1 ip1e(nk)=nint(sighead%fhour) ip2e(nk)=0 itre(nk)=10 enddo call kpfilt(nkplist,kplist,nfpvsxe,iptve,ipue,itle,il1e,il2e) call posto(comm,size,nfpvs,nfpvs1e,nfpvs2e,nfpvsme,nfpvsxe,& ijmc,ijxc,ijoc,ijo,lpvsc,fpvsc,gdum,1,0,lmw,& ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre,& idrtc,ioc,joc,kgdsc,idrt,io,jo,kgdso,& icen,igen,igrido,iyr,imo,idy,ihr,icen2,ienst,iensi,& ids,omin,omax,mxbit,lupgb,iprev,nfw,iret) deallocate(lpvsc,fpvsc) deallocate(ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre) if(iret.ne.0) then call errmsg('Error packing or writing to output file '//ddpgb) call mpabort(51) endif if(rank.eq.0)& print '(i6," PV level scalar",t30,"fields written.",& &i15," total bytes written.")',nfw,iprev call instrument(15,kall,ttot,tmin,tmax);cinstep(13)='step e pvs' ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Output potential vorticity level vector allocate(ibmse(nfpvv1e:nfpvv2e),& iptve(nfpvv1e:nfpvv2e),& ipue(nfpvv1e:nfpvv2e),& ipve(nfpvv1e:nfpvv2e),& itle(nfpvv1e:nfpvv2e),& il1e(nfpvv1e:nfpvv2e),& il2e(nfpvv1e:nfpvv2e),& ifue(nfpvv1e:nfpvv2e),& ip1e(nfpvv1e:nfpvv2e),& ip2e(nfpvv1e:nfpvv2e),& itre(nfpvv1e:nfpvv2e)) do nk=nfpvv1e,nfpvv2e k=mod(nk-1,kpv)+1 n=(nk-1)/kpv+1 ibmse(nk)=1 iptve(nk)=jpdspvv(19,n) ipue(nk)=jpdspvu(5,n) ipve(nk)=jpdspvv(5,n) itle(nk)=117 il1e(nk)=0 il2e(nk)=nint(pv(k)*1.e3) ifue(nk)=1 ip1e(nk)=nint(sighead%fhour) ip2e(nk)=0 itre(nk)=10 enddo call kpfilt(nkplist,kplist,nfpvvxe,iptve,ipue,itle,il1e,il2e) call kpfilt(nkplist,kplist,nfpvvxe,iptve,ipve,itle,il1e,il2e) call posto(comm,size,nfpvv,nfpvv1e,nfpvv2e,nfpvvme,nfpvvxe,& ijmc,ijxc,ijoc,ijo,lpvvc,fpvuc,fpvvc,1,1,lmw,& ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre,& idrtc,ioc,joc,kgdsc,idrt,io,jo,kgdso,& icen,igen,igrido,iyr,imo,idy,ihr,icen2,ienst,iensi,& ids,omin,omax,mxbit,lupgb,iprev,nfw,iret) deallocate(lpvvc,fpvuc,fpvvc) deallocate(ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre) if(iret.ne.0) then call errmsg('Error packing or writing to output file '//ddpgb) call mpabort(51) endif if(rank.eq.0)& print '(i6," PV level vector",t30,"fields written.",& &i15," total bytes written.")',nfw,iprev call instrument(16,kall,ttot,tmin,tmax);cinstep(14)='step e pvv' ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Output sundry scalar allocate(ibmse(nsuns1e:nsuns2e),& iptve(nsuns1e:nsuns2e),& ipue(nsuns1e:nsuns2e),& ipve(nsuns1e:nsuns2e),& itle(nsuns1e:nsuns2e),& il1e(nsuns1e:nsuns2e),& il2e(nsuns1e:nsuns2e),& ifue(nsuns1e:nsuns2e),& ip1e(nsuns1e:nsuns2e),& ip2e(nsuns1e:nsuns2e),& itre(nsuns1e:nsuns2e)) do n=nsuns1e,nsuns2e ibmse(n)=0 iptve(n)=jpdssuns(19,n) ipue(n)=jpdssuns(5,n) ipve(n)=-1 itle(n)=jpdssuns(6,n) il1e(n)=jpdssuns(7,n)/256 il2e(n)=mod(jpdssuns(7,n),256) ifue(n)=1 ip1e(n)=nint(sighead%fhour) ip2e(n)=0 itre(n)=10 if(n.eq.isuns_tozne_clm.and.mo3.eq.0) ipue(n)=0 if(n.eq.isuns_cwat_clm.and.mct.eq.0) ipue(n)=0 enddo call kpfilt(nkplist,kplist,nsunsxe,iptve,ipue,itle,il1e,il2e) call posto(comm,size,nsuns,nsuns1e,nsuns2e,nsunsme,nsunsxe,& ijmc,ijxc,ijoc,ijo,ldum,fsunsc,gdum,0,0,lmw,& ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre,& idrtc,ioc,joc,kgdsc,idrt,io,jo,kgdso,& icen,igen,igrido,iyr,imo,idy,ihr,icen2,ienst,iensi,& ids,omin,omax,mxbit,lupgb,iprev,nfw,iret) deallocate(fsunsc) deallocate(ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre) if(iret.ne.0) then call errmsg('Error packing or writing to output file '//ddpgb) call mpabort(51) endif if(rank.eq.0)& print '(i6," sundry scalar",t30,"fields written.",& &i15," total bytes written.")',nfw,iprev call instrument(17,kall,ttot,tmin,tmax);cinstep(15)='step e suns' ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Output sundry vector allocate(ibmse(nsunv1e:nsunv2e),& iptve(nsunv1e:nsunv2e),& ipue(nsunv1e:nsunv2e),& ipve(nsunv1e:nsunv2e),& itle(nsunv1e:nsunv2e),& il1e(nsunv1e:nsunv2e),& il2e(nsunv1e:nsunv2e),& ifue(nsunv1e:nsunv2e),& ip1e(nsunv1e:nsunv2e),& ip2e(nsunv1e:nsunv2e),& itre(nsunv1e:nsunv2e)) do n=nsunv1e,nsunv2e ibmse(n)=0 iptve(n)=jpdssunv(19,n) ipue(n)=jpdssunu(5,n) ipve(n)=jpdssunv(5,n) itle(n)=jpdssunv(6,n) il1e(n)=jpdssunv(7,n)/256 il2e(n)=mod(jpdssunv(7,n),256) ifue(n)=1 ip1e(n)=nint(sighead%fhour) ip2e(n)=0 itre(n)=10 enddo call kpfilt(nkplist,kplist,nsunvxe,iptve,ipue,itle,il1e,il2e) call kpfilt(nkplist,kplist,nsunvxe,iptve,ipve,itle,il1e,il2e) call posto(comm,size,nsunv,nsunv1e,nsunv2e,nsunvme,nsunvxe,& ijmc,ijxc,ijoc,ijo,ldum,fsunuc,fsunvc,0,1,lmw,& ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre,& idrtc,ioc,joc,kgdsc,idrt,io,jo,kgdso,& icen,igen,igrido,iyr,imo,idy,ihr,icen2,ienst,iensi,& ids,omin,omax,mxbit,lupgb,iprev,nfw,iret) deallocate(fsunuc,fsunvc) deallocate(ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre) if(iret.ne.0) then call errmsg('Error packing or writing to output file '//ddpgb) call mpabort(51) endif if(rank.eq.0)& print '(i6," sundry vector",t30,"fields written.",& &i15," total bytes written.")',nfw,iprev call instrument(18,kall,ttot,tmin,tmax);cinstep(16)='step e sunv' ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Output flux scalar allocate(ibmse(nfoxs1e:nfoxs2e),& iptve(nfoxs1e:nfoxs2e),& ipue(nfoxs1e:nfoxs2e),& ipve(nfoxs1e:nfoxs2e),& itle(nfoxs1e:nfoxs2e),& il1e(nfoxs1e:nfoxs2e),& il2e(nfoxs1e:nfoxs2e),& ifue(nfoxs1e:nfoxs2e),& ip1e(nfoxs1e:nfoxs2e),& ip2e(nfoxs1e:nfoxs2e),& itre(nfoxs1e:nfoxs2e)) do n=nfoxs1e,nfoxs2e ibmse(n)=1 iptve(n)=jpdsfoxs(19,n) ipue(n)=jpdsfoxs(5,n) ipve(n)=-1 itle(n)=jpdsfoxs(6,n) il1e(n)=jpdsfoxs(7,n)/256 il2e(n)=mod(jpdsfoxs(7,n),256) ifue(n)=kpdsfoxs(13,n) ip1e(n)=kpdsfoxs(14,n) ip2e(n)=kpdsfoxs(15,n) itre(n)=kpdsfoxs(16,n) if(any(kpdsfoxs(13:16,n).lt.0)) ipue(n)=0 enddo call kpfilt(nkplist,kplist,nfoxsxe,iptve,ipue,itle,il1e,il2e) call posto(comm,size,nfoxs,nfoxs1e,nfoxs2e,nfoxsme,nfoxsxe,& ijmc,ijxc,ijoc,ijo,lfoxsc,ffoxsc,gdum,1,0,lmw,& ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre,& idrtc,ioc,joc,kgdsc,idrt,io,jo,kgdso,& icen,igen,igrido,iyr,imo,idy,ihr,icen2,ienst,iensi,& ids,omin,omax,mxbit,lupgb,iprev,nfw,iret) deallocate(ffoxsc) deallocate(ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre) if(iret.ne.0) then call errmsg('Error packing or writing to output file '//ddpgb) call mpabort(51) endif if(rank.eq.0)& print '(i6," flux scalar",t30,"fields written.",& &i15," total bytes written.")',nfw,iprev call instrument(19,kall,ttot,tmin,tmax);cinstep(17)='step e foxs' ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Output flux vector allocate(ibmse(nfoxv1e:nfoxv2e),& iptve(nfoxv1e:nfoxv2e),& ipue(nfoxv1e:nfoxv2e),& ipve(nfoxv1e:nfoxv2e),& itle(nfoxv1e:nfoxv2e),& il1e(nfoxv1e:nfoxv2e),& il2e(nfoxv1e:nfoxv2e),& ifue(nfoxv1e:nfoxv2e),& ip1e(nfoxv1e:nfoxv2e),& ip2e(nfoxv1e:nfoxv2e),& itre(nfoxv1e:nfoxv2e)) do n=nfoxv1e,nfoxv2e ibmse(n)=1 iptve(n)=jpdsfoxv(19,n) ipue(n)=jpdsfoxu(5,n) ipve(n)=jpdsfoxv(5,n) itle(n)=jpdsfoxv(6,n) il1e(n)=jpdsfoxv(7,n)/256 il2e(n)=mod(jpdsfoxv(7,n),256) ifue(n)=kpdsfoxv(13,n) ip1e(n)=kpdsfoxv(14,n) ip2e(n)=kpdsfoxv(15,n) itre(n)=kpdsfoxv(16,n) if(any(kpdsfoxv(13:16,n).lt.0)) ipue(n)=0 if(any(kpdsfoxv(13:16,n).lt.0)) ipve(n)=0 enddo call kpfilt(nkplist,kplist,nfoxvxe,iptve,ipue,itle,il1e,il2e) call kpfilt(nkplist,kplist,nfoxvxe,iptve,ipve,itle,il1e,il2e) call posto(comm,size,nfoxv,nfoxv1e,nfoxv2e,nfoxvme,nfoxvxe,& ijmc,ijxc,ijoc,ijo,lfoxvc,ffoxuc,ffoxvc,1,1,lmw,& ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre,& idrtc,ioc,joc,kgdsc,idrt,io,jo,kgdso,& icen,igen,igrido,iyr,imo,idy,ihr,icen2,ienst,iensi,& ids,omin,omax,mxbit,lupgb,iprev,nfw,iret) deallocate(ffoxuc,ffoxvc) deallocate(ibmse,iptve,ipue,ipve,itle,il1e,il2e,ifue,ip1e,ip2e,itre) if(iret.ne.0) then call errmsg('Error packing or writing to output file '//ddpgb) call mpabort(51) endif if(rank.eq.0)& print '(i6," flux vector",t30,"fields written.",& &i15," total bytes written.")',nfw,iprev call instrument(20,kall,ttot,tmin,tmax);cinstep(18)='step e foxv' ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Finish up call mpstop(iret) call instrument(21,kall,ttot,tmin,tmax);cinstep(21)='mpstop' if(rank.eq.0) then do n=1,30 call instrument(-n,kall,ttot,tmin,tmax) if(kall.gt.0)& print '("TIME SPENT IN STEP ",i2,x,a,g16.6)',n,cinstep(n),ttot enddo call w3tage('postgp ') endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end program !------------------------------------------------------------------------------- subroutine rtsig(lusig,head,k1,k2,kgds,ijo,nct,& h,p,px,py,t,tx,ty,u,v,d,z,sh,o3,ct,mo3,mct,iret) !$$$ Subprogram documentation block ! ! Subprogram: rtsig Read and transform sigma file ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram reads a sigma file and transforms ! the fields to a designated global grid. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call rtsig(lusig,head,k1,k2,kgds,ijo,nct,& ! h,p,px,py,t,tx,ty,u,v,d,z,sh,o3,ct,mo3,mct,iret) ! Input argument list: ! lusig integer(sigio_intkind) sigma file unit number ! head type(sigio_head) sigma file header ! k1 integer first model level to return ! k2 integer last model level to return ! kgds integer (200) GDS to which to transform ! ijo integer dimension of output fields ! nct integer number of output cloud types ! Output argument list: ! h real (ijo) surface orography (m) ! p real (ijo) surface pressure (Pa) ! px real (ijo) log surface pressure x-gradient (1/m) ! py real (ijo) log surface pressure y-gradient (1/m) ! t real (ijo,k1:k2) temperature (K) ! tx real (ijo,k1:k2) virtual temperature x-gradient (K/m) ! ty real (ijo,k1:k2) virtual temperature y-gradient (K/m) ! u real (ijo,k1:k2) x-component wind (m/s) ! v real (ijo,k1:k2) y-component wind (m/s) ! d real (ijo,k1:k2) wind divergence (1/s) ! z real (ijo,k1:k2) absolute vorticity (1/s) ! sh real (ijo,k1:k2) specific humidity (kg/kg) ! o3 real (ijo,k1:k2) specific ozone (kg/kg) ! ct real (ijo,k1:k2,nct) specific cloud water (kg/kg) ! mo3 integer number of ozone fields returned ! mct integer number of cloud water fields returned ! iret integer return code ! ! Modules used: ! sigio_r_module sigma file I/O ! ! Subprograms called: ! sigio_aldatm allocate sigma upper air data ! sigio_aldats allocate sigma surface data ! sigio_axdatm deallocate sigma upper air data ! sigio_axdats deallocate sigma surface data ! sigio_rrdatm read sigma upper air data ! sigio_rrdats read sigma surface data ! sptez scalar spectral transform ! sptezd gradient spectral transform ! sptezm multiple scalar spectral transform ! sptezmv multiple vector spectral transform ! ! Attributes: ! Language: Fortran 90 ! !$$$ use sigio_module use sigio_r_module use physcons implicit none integer(sigio_intkind),intent(in):: lusig type(sigio_head),intent(in):: head integer,intent(in):: k1,k2,kgds(200),ijo,nct real,dimension(ijo),intent(out):: h,p,px,py real,dimension(ijo,k1:k2),intent(out):: t,tx,ty,u,v,d,z,sh,o3 real,dimension(ijo,k1:k2,nct),intent(out):: ct integer,intent(out):: mo3,mct,iret integer idrt,io,jo integer(sigio_intkind):: irets type(sigio_dats):: dats type(sigio_datm):: datm integer io3,ict,jct real pmean,tmean(k1:k2) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Determine output grid idrt=kgds(1) if(kgds(1).eq.0.and.kgds(4).lt.90000) idrt=256 io=kgds(2) jo=kgds(3) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Read and transform surface fields iret=1 call sigio_aldats(head,dats,irets) call sigio_rrdats(lusig,head,dats,irets) if(irets.ne.0) return call sptez(0,head%jcap,idrt,io,jo,dats%hs,h,1) call sptez(0,head%jcap,idrt,io,jo,dats%ps,p,1) p=1.e3*exp(p) call sptezd(0,head%jcap,idrt,io,jo,dats%ps,pmean,px,py,1) call sigio_axdats(dats,irets) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Determine types of tracer fields mo3=0 mct=0 if(head%idvt.eq.0) then io3=2 ict=3 else io3=mod(head%idvt,10)+1 ict=mod(head%idvt/10,10)+1 endif if(io3.gt.1.and.io3.le.head%ntrac) mo3=1 if(ict.gt.1.and.ict.le.head%ntrac) mct=min(nct,head%ntrac-ict+1,head%ncldt) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Read and transform fields on levels k1 through k2 iret=2 if(k2.ge.k1) then call sigio_aldatm(head,k1,k2,datm,irets) call sigio_rrdatm(lusig,head,datm,irets) if(irets.ne.0) return call sptezm(0,head%jcap,idrt,io,jo,k2-k1+1,datm%t,t,1) call sptezmd(0,head%jcap,idrt,io,jo,k2-k1+1,datm%t,tmean,tx,ty,1) call sptezmv(0,head%jcap,idrt,io,jo,k2-k1+1,datm%d,datm%z,u,v,1) call sptezm(0,head%jcap,idrt,io,jo,k2-k1+1,datm%d,d,1) datm%z(3,:)=datm%z(3,:)+2*con_omega/sqrt(1.5) call sptezm(0,head%jcap,idrt,io,jo,k2-k1+1,datm%z,z,1) call sptezm(0,head%jcap,idrt,io,jo,k2-k1+1,datm%q,sh,1) if(mo3.gt.0) then call sptezm(0,head%jcap,idrt,io,jo,mo3*(k2-k1+1),datm%q(1,k1,io3),o3,1) endif if(mct.gt.0) then call sptezm(0,head%jcap,idrt,io,jo,mct*(k2-k1+1),datm%q(1,k1,ict),ct,1) endif t=t/(1+con_fvirt*sh) call sigio_axdatm(datm,irets) endif iret=0 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end subroutine !------------------------------------------------------------------------------- subroutine rtflx(luflx,ns,nv,kgdsc,ijoc,jpdss,jpdsu,jpdsv,& kpdss,kpdsv,ls,lv,fs,fu,fv) !$$$ Subprogram documentation block ! ! Subprogram: rtflx Read and transform flux file ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram reads a flux file and transforms ! the fields to a designated global grid. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call rtflx(luflx,ns,nv,kgdsc,ijoc,jpdss,jpdsu,jpdsv,& ! kpdss,kpdsv,ls,lv,fs,fu,fv) ! Input argument list: ! luflx integer flux file unit number ! ns integer number of scalar fields to return ! nv integer number of vector fields to return ! kgdsc integer (200) GDS to which to transform ! ijoc integer dimension of output fields ! jpdss integer (1:24,ns) PDS type and level for scalar fields ! jpdsu integer (1:24,nv) PDS type and level for vector x-component fields ! jpdsv integer (1:24,nv) PDS type and level for vector y-component fields ! Output argument list: ! kpdss integer (200,ns) PDS from scalar fields ! kpdsv integer (200,ns) PDS from vector y-component fields ! ls logical*1 (ijoc,ns) bitmaps for scalar fields ! lv logical*1 (ijoc,nv) bitmaps for vector fields ! fs real (ijoc,ns) scalar fields ! fu real (ijoc,ns) vector x-component fields ! fv real (ijoc,ns) vector y-component fields ! ! Subprograms called: ! getgb read and unpack GRIB message ! getgbh read and unpack GRIB header ! ipolates general scalar interpolation ! ipolatev general vector interpolation ! ! Attributes: ! Language: Fortran 90 ! !$$$ implicit none integer,intent(in):: luflx,ns,nv,kgdsc(200),ijoc integer,intent(in):: jpdss(1:24,ns),jpdsu(1:24,nv),jpdsv(1:24,nv) integer,intent(out):: kpdss(200,ns),kpdsv(200,nv) logical*1,intent(out):: ls(ijoc,ns),lv(ijoc,nv) real,intent(out):: fs(ijoc,ns),fu(ijoc,nv),fv(ijoc,nv) integer jpds1(200),jgds(200),kpds(200),kgds(200) integer kfa,kg,kf,k,iret,ko,n integer ibis(ns),ibiv(nv),ibos(ns),ibov(nv) logical*1,allocatable:: lrs(:,:),lrv(:,:) real,allocatable:: frs(:,:),fru(:,:),frv(:,:) integer ipopt(20) real rlat(ijoc),rlon(ijoc),crot(ijoc),srot(ijoc) integer kall,ttot,tmin,tmax ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if(ns.le.0.and.nv.le.0) return jpds1=-1 jgds=-1 call getgbh(luflx,0,0,jpds1,jgds,kg,kfa,k,kpds,kgds,iret) if(iret.ne.0) then kpdss=-9999 kpdsv=-9999 ls=.false. lv=.false. fs=0. fv=0. return endif jpds1(3)=kpds(3) jgds=kgds allocate(lrs(kfa,ns),lrv(kfa,nv),frs(kfa,ns),fru(kfa,nv),frv(kfa,nv)) do n=1,ns jpds1(19)=jpdss(19,n) jpds1(5:7)=jpdss(5:7,n) call getgb(luflx,0,kfa,0,jpds1,jgds,& kf,k,kpdss(1,n),kgds,lrs(1,n),frs(1,n),iret) if(iret.ne.0) then kpdss(:,n)=-9999 lrs(:,n)=.false. frs(:,n)=0. ibis(n)=1 else ibis(n)=mod(kpdss(4,n)/64,2) endif enddo do n=1,nv jpds1(19)=jpdsu(19,n) jpds1(5:7)=jpdsu(5:7,n) call getgb(luflx,0,kfa,0,jpds1,jgds,& kf,k,kpdsv(1,n),kgds,lrv(1,n),fru(1,n),iret) if(iret.eq.0) then jpds1(19)=jpdsv(19,n) jpds1(5:7)=jpdsv(5:7,n) call getgb(luflx,0,kfa,0,jpds1,jgds,& kf,k,kpdsv(1,n),kgds,lrv(1,n),frv(1,n),iret) endif if(iret.ne.0) then kpdsv(:,n)=-9999 lrv(:,n)=.false. frv(:,n)=0. ibiv(n)=1 else ibiv(n)=mod(kpdsv(4,n)/64,2) endif enddo ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ipopt=-1 ipopt(1)=1 do n=1,ns if(ibis(n).eq.0) then ibis(n)=1 lrs(:,n)=frs(:,n).ne.0. endif enddo call ipolates(1,ipopt,kgds,kgdsc,kf,ijoc,ns,ibis,lrs,frs,& ko,rlat,rlon,ibos,ls,fs,iret) do n=1,ns ls(:ko,n)=ls(:ko,n).or.mod(kpdss(4,n)/64,2).eq.0 enddo call ipolatev(1,ipopt,kgds,kgdsc,kfa,ijoc,nv,ibiv,lrv,fru,frv,& ko,rlat,rlon,crot,srot,ibov,lv,fu,fv,iret) deallocate(lrs,lrv,frs,fru,frv) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end subroutine !------------------------------------------------------------------------------- real function fthour(iftu,ift) !$$$ Subprogram documentation block ! ! Subprogram: fthour Convert GRIB forecast time units to hours ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This function returns a forecast hour as encoded in the GRIB PDS. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: ...=fthour(iftu,ift) ! Input argument list: ! iftu integer GRIB PDS forecast time unit ! ift integer GRIB PDS forecast time ! Output argument list: ! fthour integer forecast hour ! ! Attributes: ! Language: Fortran 90 ! !$$$ implicit none integer,intent(in):: iftu,ift ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if(iftu.eq.0) then ! convert from minutes fthour=ift/60. elseif(iftu.eq.1) then ! convert from hours fthour=ift elseif(iftu.eq.2) then ! convert from days fthour=ift*24. elseif(iftu.eq.10) then ! convert from 3-hours fthour=ift*3. elseif(iftu.eq.11) then ! convert from 6-hours fthour=ift*6. elseif(iftu.eq.12) then ! convert from 12-hours fthour=ift*12. elseif(iftu.eq.254) then ! convert from seconds fthour=ift/3600. else ! unknown or imprecise forecast time unit fthour=-1. endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end function !------------------------------------------------------------------------------- subroutine makglgds(idrt,imax,jmax,igrid,kgds) !$$$ Subprogram documentation block ! ! Subprogram: makglgds Create global GDS ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram creates a global Grid Description Section. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call makglgds(idrt,imax,jmax,igrid,kgds) ! Input argument list: ! idrt integer data representation type (0 for latlon, 4 for Gaussian) ! imax integer zonal dimension ! jmax integer meridional dimension ! Output argument list: ! igrid integer NCEP grid identifier ! kgds integer (200) unpacked GDS ! ! Attributes: ! Language: Fortran 90 ! !$$$ implicit none integer,intent(in):: idrt,imax,jmax integer,intent(out):: igrid,kgds(200) real slat(jmax),wlat(jmax) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - igrid=255 if(idrt.eq.0.and.imax.eq.144.and.jmax.eq.73) igrid=2 if(idrt.eq.0.and.imax.eq.360.and.jmax.eq.181) igrid=3 if(idrt.eq.0.and.imax.eq.720.and.jmax.eq.361) igrid=4 if(idrt.eq.4.and.imax.eq.192.and.jmax.eq.94) igrid=98 if(idrt.eq.4.and.imax.eq.384.and.jmax.eq.192) igrid=126 if(idrt.eq.4.and.imax.eq.512.and.jmax.eq.256) igrid=170 if(idrt.eq.4.and.imax.eq.768.and.jmax.eq.384) igrid=127 kgds(1)=modulo(idrt,256) kgds(2)=imax kgds(3)=jmax select case(idrt) case(0) kgds(4)=90000 case(4) call splat(4,jmax,slat,wlat) kgds(4)=nint(180000./acos(-1.)*asin(slat(1))) case(256) kgds(4)=90000-nint(0.5*180000./jmax) end select kgds(5)=0 kgds(6)=128 kgds(7)=-kgds(4) kgds(8)=-nint(360000./imax) kgds(9)=-kgds(8) select case(idrt) case(0) kgds(10)=nint(180000./(jmax-1)) case(4) kgds(10)=jmax/2 case(256) kgds(10)=nint(180000./jmax) end select kgds(11:19)=0 kgds(20)=255 kgds(21:200)=0 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end subroutine !------------------------------------------------------------------------------- subroutine makglpds(iptv,icen,igen,igrid,ibms,ipu,itl,il1,il2,& iyr,imo,idy,ihr,iftu,ip1,ip2,itr,& ina,inm,icen2,ids,kpds) !$$$ Subprogram documentation block ! ! Subprogram: makglpds Create global PDS ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram creates a global Product Description Section. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call makglpds(iptv,icen,igen,igrid,ibms,ipu,itl,il1,il2,& ! iyr,imo,idy,ihr,iftu,ip1,ip2,itr,& ! ina,inm,icen2,ids,kpds) ! Input argument list: ! iptv integer parameter table version ! icen integer center ! igen integer model generating code ! igrid integer center grid identifier ! ibms integer bitmap section flag ! ipu integer parameter identifier ! itl integer type of level ! il1 integer level 1 ! il2 integer level 2 ! iyr integer year ! imo integer month ! idy integer day ! ihr integer hour ! iftu integer forecast time unit ! ip1 integer time 1 ! ip2 integer time 2 ! itr integer time representation ! ina integer number in average ! inm integer number missing ! icen2 integer subcenter ! ids integer decimal scaling ! Output argument list: ! kpds integer (200) unpacked PDS ! ! Attributes: ! Language: Fortran 90 ! !$$$ implicit none integer,intent(in):: iptv,icen,igen,igrid,ibms,ipu,itl,il1,il2,& iyr,imo,idy,ihr,iftu,ip1,ip2,itr,& ina,inm,icen2,ids integer,intent(out):: kpds(200) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - kpds(01)=icen kpds(02)=igen kpds(03)=igrid kpds(04)=128+64*ibms kpds(05)=ipu kpds(06)=itl kpds(07)=256*il1+il2 kpds(08)=mod(iyr-1,100)+1 kpds(09)=imo kpds(10)=idy kpds(11)=ihr kpds(12)=0 kpds(13)=iftu kpds(14)=ip1 kpds(15)=ip2 kpds(16)=itr kpds(17)=ina kpds(18)=1 kpds(19)=iptv kpds(20)=inm kpds(21)=(iyr-1)/100+1 kpds(22)=ids kpds(23)=icen2 kpds(24)=0 kpds(25:)=0 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end subroutine !------------------------------------------------------------------------------- subroutine idsset(ids) !$$$ subprogram documentation block ! ! subprogram: idsset sets default decimal scalings ! prgmmr: iredell org: w/nmc23 date: 92-10-31 ! ! abstract: sets decimal scalings defaults for various parameters. ! a decimal scaling of -3 means data is packed in kilo-si units. ! ! program history log: ! 92-10-31 iredell ! ! usage:call idsset(ids) ! output arguments: ! ids integer (255,255) decimal scalings ! (unknown decimal scalings will not be set) ! ! attributes: ! language: cray fortran ! !$$$ implicit none integer,intent(out):: ids(255,255) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! standard fields ids(1:8,001)=0 ! pressure (pa) ids(1:8,002)=0 ! sea-level pressure (pa) ids(1:8,003)=3 ! pressure tendency (pa/s) ids(1:8,004)=1 ! potential vorticity (Km2/kg/s) ! ids(1:8,006)=0 ! geopotential (m2/s2) ids(1:8,007)=1 ! geopotential height (m) ids(1:8,008)=1 ! geometric height (m) ids(1:8,009)=1 ! standard deviation of height (m) ids(1:8,010)=1 ! total ozone (dobson) ids(1:8,011)=1 ! temperature (k) ids(1:8,012)=1 ! virtual temperature (k) ids(1:8,013)=1 ! potential temperature (k) ids(1:8,014)=1 ! pseudo-adiabatic potential temperature (k) ids(1:8,015)=1 ! maximum temperature (k) ids(1:8,016)=1 ! minimum temperature (k) ids(1:8,017)=1 ! dewpoint temperature (k) ids(1:8,018)=1 ! dewpoint depression (k) ids(1:8,019)=4 ! temperature lapse rate (k/m) ids(1:8,020)=0 ! visibility (m) ! radar spectra 1 () ! radar spectra 2 () ! radar spectra 3 () ! ids(1:8,025)=1 ! temperature anomaly (k) ids(1:8,026)=0 ! pressure anomaly (pa) ids(1:8,027)=1 ! geopotential height anomaly (m) ! wave spectra 1 () ! wave spectra 2 () ! wave spectra 3 () ids(1:8,031)=0 ! wind direction (degrees) ids(1:8,032)=1 ! wind speed (m/s) ids(1:8,033)=1 ! zonal wind (m/s) ids(1:8,034)=1 ! meridional wind (m/s) ids(1:8,035)=-4 ! streamfunction (m2/s) ids(1:8,036)=-4 ! velocity potential (m2/s) ids(1:8,037)=0 ! montgomery stream function (m2/s2) ids(1:8,038)=8 ! sigma vertical velocity (1/s) ids(1:8,039)=3 ! pressure vertical velocity (pa/s) ids(1:8,040)=4 ! geometric vertical velocity (m/s) ids(1:8,041)=6 ! absolute vorticity (1/s) ids(1:8,042)=6 ! absolute divergence (1/s) ids(1:8,043)=6 ! relative vorticity (1/s) ids(1:8,044)=6 ! relative divergence (1/s) ids(1:8,045)=4 ! vertical u shear (1/s) ids(1:8,046)=4 ! vertical v shear (1/s) ids(1:8,047)=0 ! direction of current (degrees) ! speed of current (m/s) ! u of current (m/s) ! v of current (m/s) ids(1:8,051)=5 ! specific humidity (kg/kg) ids(1:8,052)=0 ! relative humidity (percent) ids(1:8,053)=5 ! humidity mixing ratio (kg/kg) ids(1:8,054)=1 ! precipitable water (kg/m2) ids(1:8,055)=0 ! vapor pressure (pa) ids(1:8,056)=0 ! saturation deficit (pa) ids(1:8,057)=1 ! evaporation (kg/m2) ids(1:8,058)=1 ! cloud ice (kg/m2) ids(1:8,059)=6 ! precipitation rate (kg/m2/s) ids(1:8,060)=0 ! thunderstorm probability (percent) ids(1:8,061)=1 ! total precipitation (kg/m2) ids(1:8,062)=1 ! large-scale precipitation (kg/m2) ids(1:8,063)=1 ! convective precipitation (kg/m2) ids(1:8,064)=6 ! water equivalent snowfall rate (kg/m2/s) ids(1:8,065)=0 ! water equivalent of snow depth (kg/m2) ids(1:8,066)=2 ! snow depth (m) ! mixed-layer depth (m) ! transient thermocline depth (m) ! main thermocline depth (m) ! main thermocline anomaly (m) ids(1:8,071)=0 ! total cloud cover (percent) ids(1:8,072)=0 ! convective cloud cover (percent) ids(1:8,073)=0 ! low cloud cover (percent) ids(1:8,074)=0 ! middle cloud cover (percent) ids(1:8,075)=0 ! high cloud cover (percent) ids(1:8,076)=2 ! cloud water (kg/m2) ! ids(1:8,078)=1 ! convective snow (kg/m2) ids(1:8,079)=1 ! large scale snow (kg/m2) ids(1:8,080)=1 ! water temperature (k) ids(1:8,081)=0 ! sea-land mask () ! deviation of sea level from mean (m) ids(1:8,083)=5 ! roughness (m) ids(1:8,084)=1 ! albedo (percent) ids(1:8,085)=1 ! soil temperature (k) ids(1:8,086)=0 ! soil wetness (kg/m2) ids(1:8,087)=0 ! vegetation (percent) ! salinity (kg/kg) ids(1:8,089)=4 ! density (kg/m3) ids(1:8,090)=1 ! runoff (kg/m2) ids(1:8,091)=2 ! ice concentration () ids(1:8,092)=2 ! ice thickness (m) ids(1:8,093)=0 ! direction of ice drift (degrees) ! speed of ice drift (m/s) ! u of ice drift (m/s) ! v of ice drift (m/s) ! ice growth (m) ! ice divergence (1/s) ids(1:8,099)=1 ! snow melt (kg/m2) ! sig height of waves and swell (m) ids(1:8,101)=0 ! direction of wind waves (degrees) ! sig height of wind waves (m) ! mean period of wind waves (s) ids(1:8,104)=0 ! direction of swell waves (degrees) ! sig height of swell waves (m) ! mean period of swell waves (s) ids(1:8,107)=0 ! primary wave direction (degrees) ! primary wave mean period (s) ids(1:8,109)=0 ! secondary wave direction (degrees) ! secondary wave mean period (s) ids(1:8,111)=0 ! net solar radiative flux at surface (w/m2) ids(1:8,112)=0 ! net longwave radiative flux at surface (w/m2) ids(1:8,113)=0 ! net solar radiative flux at top (w/m2) ids(1:8,114)=0 ! net longwave radiative flux at top (w/m2) ids(1:8,115)=0 ! net longwave radiative flux (w/m2) ids(1:8,116)=0 ! net solar radiative flux (w/m2) ids(1:8,117)=0 ! total radiative flux (w/m2) ! ! ! ids(1:8,121)=0 ! latent heat flux (w/m2) ids(1:8,122)=0 ! sensible heat flux (w/m2) ids(1:8,123)=0 ! boundary layer dissipation (w/m2) ids(1:8,124)=3 ! u wind stress (n/m2) ids(1:8,125)=3 ! v wind stress (n/m2) ! wind mixing energy (j) ! image data () ids(1:8,128)=0 ! mean sea-level pressure (stdatm) (pa) ids(1:8,129)=0 ! mean sea-level pressure (maps) (pa) ids(1:8,130)=0 ! mean sea-level pressure (eta) (pa) ids(1:8,131)=1 ! surface lifted index (k) ids(1:8,132)=1 ! best lifted index (k) ids(1:8,133)=1 ! k index (k) ids(1:8,134)=1 ! sweat index (k) ids(1:8,135)=10 ! horizontal moisture divergence (kg/kg/s) ids(1:8,136)=4 ! speed shear (1/s) ids(1:8,137)=3 ! 3-hr pressure tendency (pa/s) ids(1:8,138)=6 ! brunt-vaisala frequency squared (1/s2) ids(1:8,139)=11 ! potential vorticity (mass-weighted) (1/s/m) ids(1:8,140)=0 ! rain mask () ids(1:8,141)=0 ! freezing rain mask () ids(1:8,142)=0 ! ice pellets mask () ids(1:8,143)=0 ! snow mask () ids(1:8,144)=3 ! volumetric soil moisture content (fraction) ids(1:8,145)=0 ! potential evaporation rate (w/m2) ids(1:8,146)=0 ! cloud workfunction (j/kg) ids(1:8,147)=3 ! u gravity wave stress (n/m2) ids(1:8,148)=3 ! v gravity wave stress (n/m2) ids(1:8,149)=10 ! potential vorticity (m2/s/kg) ! covariance between v and u (m2/s2) ! covariance between u and t (k*m/s) ! covariance between v and t (k*m/s) ids(1:8,153)=6 ! cloud water mixing ratio (kg/kg) ids(1:8,154)=9 ! ozone mixing ratio (kg/kg) ids(1:8,155)=0 ! ground heat flux (w/m2) ids(1:8,156)=0 ! convective inhibition (j/kg) ids(1:8,157)=0 ! convective ape (j/kg) ids(1:8,158)=0 ! turbulent ke (j/kg) ids(1:8,159)=0 ! condensation pressure of lifted parcel (pa) ids(1:8,160)=0 ! clear sky upward solar flux (w/m2) ids(1:8,161)=0 ! clear sky downward solar flux (w/m2) ids(1:8,162)=0 ! clear sky upward longwave flux (w/m2) ids(1:8,163)=0 ! clear sky downward longwave flux (w/m2) ids(1:8,164)=0 ! cloud forcing net solar flux (w/m2) ids(1:8,165)=0 ! cloud forcing net longwave flux (w/m2) ids(1:8,166)=0 ! visible beam downward solar flux (w/m2) ids(1:8,167)=0 ! visible diffuse downward solar flux (w/m2) ids(1:8,168)=0 ! near ir beam downward solar flux (w/m2) ids(1:8,169)=0 ! near ir diffuse downward solar flux (w/m2) ! ! ids(1:8,172)=3 ! momentum flux (n/m2) ids(1:8,173)=0 ! mass point model surface () ids(1:8,174)=0 ! velocity point model surface () ids(1:8,175)=0 ! sigma layer number () ids(1:8,176)=2 ! latitude (degrees) ids(1:8,177)=2 ! east longitude (degrees) ! ! ! ids(1:8,181)=9 ! x-gradient log pressure (1/m) ids(1:8,182)=9 ! y-gradient log pressure (1/m) ids(1:8,183)=5 ! x-gradient height (m/m) ids(1:8,184)=5 ! y-gradient height (m/m) ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ! ids(1:8,201)=0 ! ice-free water surcace (percent) ! ! ids(1:8,204)=0 ! downward solar radiative flux (w/m2) ids(1:8,205)=0 ! downward longwave radiative flux (w/m2) ! ids(1:8,207)=0 ! moisture availability (percent) ! exchange coefficient (kg/m2/s) ids(1:8,209)=0 ! number of mixed layer next to sfc () ! ids(1:8,211)=0 ! upward solar radiative flux (w/m2) ids(1:8,212)=0 ! upward longwave radiative flux (w/m2) ids(1:8,213)=0 ! non-convective cloud cover (percent) ids(1:8,214)=6 ! convective precipitation rate (kg/m2/s) ids(1:8,215)=7 ! total diabatic heating rate (k/s) ids(1:8,216)=7 ! total radiative heating rate (k/s) ids(1:8,217)=7 ! total diabatic nonradiative heating rate (k/s) ids(1:8,218)=2 ! precipitation index (fraction) ids(1:8,219)=1 ! std dev of ir t over 1x1 deg area (k) ids(1:8,220)=4 ! natural log of surface pressure over 1 kpa () ids(1:8,221)=1 ! planetary boundary layer height (m) ids(1:8,222)=1 ! 5-wave geopotential height (m) ids(1:8,223)=1 ! plant canopy surface water (kg/m2) ! ! ! blackadars mixing length (m) ! asymptotic mixing length (m) ids(1:8,228)=1 ! potential evaporation (kg/m2) ids(1:8,229)=0 ! snow phase-change heat flux (w/m2) ! ids(1:8,231)=3 ! convective cloud mass flux (pa/s) ids(1:8,232)=0 ! downward total radiation flux (w/m2) ids(1:8,233)=0 ! upward total radiation flux (w/m2) ids(1:8,234)=1 ! baseflow-groundwater runoff (kg/m2) ids(1:8,235)=1 ! storm surface runoff (kg/m2) ! ids(1:8,237)=6 ! total ozone (kg/m2) ids(1:8,238)=0 ! snow cover (percent) ids(1:8,239)=1 ! snow temperature (k) ! ids(1:8,241)=7 ! large scale condensation heating rate (k/s) ids(1:8,242)=7 ! deep convective heating rate (k/s) ids(1:8,243)=10 ! deep convective moistening rate (kg/kg/s) ids(1:8,244)=7 ! shallow convective heating rate (k/s) ids(1:8,245)=10 ! shallow convective moistening rate (kg/kg/s) ids(1:8,246)=7 ! vertical diffusion heating rate (kg/kg/s) ids(1:8,247)=7 ! vertical diffusion zonal acceleration (m/s/s) ids(1:8,248)=7 ! vertical diffusion merid acceleration (m/s/s) ids(1:8,249)=10 ! vertical diffusion moistening rate (kg/kg/s) ids(1:8,250)=7 ! solar radiative heating rate (k/s) ids(1:8,251)=7 ! longwave radiative heating rate (k/s) ! drag coefficient () ! friction velocity (m/s) ! richardson number () ! ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! other fields ids(129,200)=2 ! UV-B downward solar flux (W/m2) ids(129,201)=2 ! clear sky UV-B downward solar flux (W/m2) ids(130,066)=2 ! snow depth (m) ids(130,160)=3 ! liquid volumetric soil moisture (non-frozen) () ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end subroutine !------------------------------------------------------------------------------- subroutine posta(im,levs,idvc,idsl,nvcoord,vcoord,& hs,ps,psx,psy,t,tx,ty,u,v,d,z,sh,o3,ct,& hrflx,kpdsflxs,kpdsflxv,lflxs,lflxv,fflxs,fflxu,fflxv,& kpo,po,kpt,pt,kzz,zz,kth,th,kpv,pv,pvpt,pvsb,& nfpos,nfpov,nfpts,nfptv,nfzzs,nfzzv,& nfths,nfthv,nfpvs,nfpvv,& kpdsfoxs,kpdsfoxv,lfoxs,lfoxv,& fpos,fpou,fpov,fpts,fptu,fptv,fzzs,fzzu,fzzv,& lths,lthv,fths,fthu,fthv,lpvs,lpvv,fpvs,fpvu,fpvv,& fsuns,fsunu,fsunv,ffoxs,ffoxu,ffoxv) !$$$ Subprogram documentation block ! ! Subprogram: posta Post subprogram to vertically interpolate ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram computes profiles of posted products ! from profiles of model variables, from soup to nuts. ! Relative humidity and height are calculated on model surfaces. ! Then fields are vertically interpolated to specified ! pressure levels, specified pressure layers, and specified ! height levels. Sundry single level fields are also computed. ! Additional flux fields are calculated if necessary. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call posta(im,levs,idvc,idsl,nvcoord,vcoord,& ! hs,ps,psx,psy,t,tx,ty,u,v,d,z,sh,o3,ct,& ! hrflx,kpdsflxs,kpdsflxv,lflxs,lflxv,fflxs,fflxu,fflxv,& ! kpo,po,kpt,pt,kzz,zz,kth,th,kpv,pv,pvpt,pvsb,& ! nfpos,nfpov,nfpts,nfptv,nfzzs,nfzzv,& ! nfths,nfthv,nfpvs,nfpvv,& ! kpdsfoxs,kpdsfoxv,lfoxs,lfoxv,& ! fpos,fpou,fpov,fpts,fptu,fptv,fzzs,fzzu,fzzv,& ! lths,lthv,fths,fthu,fthv,lpvs,lpvv,fpvs,fpvu,fpvv,& ! fsuns,fsunu,fsunv,ffoxs,ffoxu,ffoxv) ! Input argument list: ! im integer number of profiles ! levs integer number of model levels ! idvc integer vertical coordinate id (1 for sigma and 2 for hybrid) ! idsl integer type of sigma structure (1 for phillips or 2 for mean) ! nvcoord integer number of vertical coordinates ! vcoord real (km+1,nvcoord) vertical coordinates ! hs real (im) surface orography (m) ! ps real (im) surface pressure (Pa) ! psx real (im) log surface pressure x-gradient (1/m) ! psy real (im) log surface pressure y-gradient (1/m) ! t real (levs,im) temperature (K) ! tx real (levs,im) temperature x-gradient (K/m) ! ty real (levs,im) temperature y-gradient (K/m) ! u real (levs,im) x-component wind (m/s) ! v real (levs,im) y-component wind (m/s) ! d real (levs,im) wind divergence (1/s) ! z real (levs,im) absolute vorticity (1/s) ! sh real (levs,im) specific humidity (kg/kg) ! o3 real (levs,im) specific ozone (kg/kg) ! ct real (levs,im) specific cloud water (kg/kg) ! hrflx real hours over which fluxes are averaged ! kpdsflxs integer (200,nflxs) input scalar flux PDS ! kpdsflxv integer (200,nflxv) input vector flux PDS ! lflxs logical*1 (nflxs,im) scalar flux bitmaps ! lflxv logical*1 (nflxv,im) vector flux bitmaps ! fflxs real (nflxs,im) scalar flux fields ! fflxu real (nflxv,im) vector flux x-component fields ! fflxv real (nflxv,im) vector flux y-component fields ! kpo integer number of pressure levels ! po real (kpo) pressure levels (Pa) ! kpt integer number of pressure layers ! pt real (kpt) pressure layer edges above the surface (Pa) ! kzz integer number of height levels ! zz real (kpt) heights above sea level (m) ! kth integer number of potential temperature levels ! th real (kpv) potential temperatures (K) ! kpv integer number of potential vorticity levels ! pv real (kpv) potential vorticities (10**-6*K*m**2/kg/s) ! pvpt real (kpv) top pressures for PV search (Pa) ! pvsb real (kpv) bottom sigmas for PV search () ! nfpos integer first dimension of output pressure level scalar data ! nfpov integer first dimension of output pressure level vector data ! nfpts integer first dimension of output pressure layer scalar data ! nfptv integer first dimension of output pressure layer vector data ! nfzzs integer first dimension of output height level scalar data ! nfzzv integer first dimension of output height level vector data ! nfths integer first dimension of output potential temperature level scalar data ! nfthv integer first dimension of output potential temperature level vector data ! nfpvs integer first dimension of output potential vorticity level scalar data ! nfpvv integer first dimension of output potential vorticity level vector data ! Output argument list: ! kpdsfoxs integer (200,nfoxs) output scalar flux PDS ! kpdsfoxv integer (200,nfoxv) output vector flux PDS ! lfoxs logical*1 (nfoxs,im) scalar flux bitmaps ! lfoxv logical*1 (nfoxv,im) vector flux bitmaps ! fpos real (nfpos,im) pressure level scalar fields ! fpou real (nfpos,im) pressure level vector x-component fields ! fpov real (nfpos,im) pressure level vector y-component fields ! fpts real (nfpts,im) pressure layer scalar fields ! fptu real (nfpts,im) pressure layer vector x-component fields ! fptv real (nfpts,im) pressure layer vector y-component fields ! fzzs real (nfzzs,im) height level scalar fields ! fzzu real (nfzzs,im) height level vector x-component fields ! fzzv real (nfzzs,im) height level vector y-component fields ! lths logical*1 (nfpvs,im) potential temperature level scalar bitmaps ! lthv logical*1 (nfpvv,im) potential temperature level vector bitmaps ! fths real (nfpvs,im) potential temperature level scalar fields ! fthu real (nfpvv,im) potential temperature level vector x-component fields ! fthv real (nfpvv,im) potential temperature level vector y-component fields ! lpvs logical*1 (nfpvs,im) potential vorticity level scalar bitmaps ! lpvv logical*1 (nfpvv,im) potential vorticity level vector bitmaps ! fpvs real (nfpvs,im) potential vorticity level scalar fields ! fpvu real (nfpvv,im) potential vorticity level vector x-component fields ! fpvv real (nfpvv,im) potential vorticity level vector y-component fields ! fsuns real (nsuns,im) scalar sundry fields ! fsunu real (nsunv,im) vector sundry x-component fields ! fsunv real (nsunv,im) vector sundry y-component fields ! ffoxs real (nfoxs,im) scalar flux fields ! ffoxu real (nfoxv,im) vector flux x-component fields ! ffoxv real (nfoxv,im) vector flux y-component fields ! ! Modules used: ! postgp_module Shared data for postgp ! ! Subprograms called: ! flxcnv1 Copy flux metadata ! modstuff Compute model coordinate dependent functions ! getrh Compute saturation humidity and relative humidity ! hydro Compute geopotential heights ! p2po Interpolate to pressure level ! p2pt Interpolate to pressure layer ! p2zz Interpolate to height level ! sundry Compute sundry single-level posted fields ! calwxt1 Compute precipitation type ! flxcnv Copy flux data ! ! Attributes: ! Language: Fortran 90 ! !$$$ use postgp_module implicit none integer,intent(in):: im,levs,idvc,idsl,nvcoord,kpo,kpt,kzz,kth,kpv integer,intent(in):: nfpos,nfpov,nfpts,nfptv,nfzzs,nfzzv integer,intent(in):: nfths,nfthv,nfpvs,nfpvv real,intent(in):: hrflx real,intent(in):: vcoord(levs+1,nvcoord) real,intent(in):: hs(im),ps(im),psx(im),psy(im) real,intent(in):: t(levs,im),tx(levs,im),ty(levs,im) real,intent(in):: u(levs,im),v(levs,im),d(levs,im),z(levs,im) real,intent(in):: sh(levs,im),o3(levs,im),ct(levs,im) integer,intent(in):: kpdsflxs(200,nflxs),kpdsflxv(200,nflxv) logical*1,intent(in):: lflxs(nflxs,im),lflxv(nflxv,im) real,intent(in):: fflxs(nflxs,im),fflxu(nflxv,im),fflxv(nflxv,im) real,intent(in):: po(kpo),pt(kpt),zz(kzz),th(kth),pv(kpv),pvpt(kpv),pvsb(kpv) integer,intent(out):: kpdsfoxs(200,nfoxs),kpdsfoxv(200,nfoxv) logical*1,intent(out):: lfoxs(nfoxs,im),lfoxv(nfoxv,im) real,intent(out):: fpos(nfpos,im),fpou(nfpov,im),fpov(nfpov,im) real,intent(out):: fpts(nfpts,im),fptu(nfptv,im),fptv(nfptv,im) real,intent(out):: fzzs(nfzzs,im),fzzu(nfzzv,im),fzzv(nfzzv,im) logical*1,intent(out):: lths(nfths,im),lthv(nfthv,im) real,intent(out):: fths(nfths,im),fthu(nfthv,im),fthv(nfthv,im) logical*1,intent(out):: lpvs(nfpvs,im),lpvv(nfpvv,im) real,intent(out):: fpvs(nfpvs,im),fpvu(nfpvv,im),fpvv(nfpvv,im) real,intent(out):: fsuns(nsuns,im),fsunu(nsunv,im),fsunv(nsunv,im) real,intent(out):: ffoxs(nfoxs,im),ffoxu(nfoxv,im),ffoxv(nfoxv,im) real,dimension(kpo):: apo real,dimension(levs):: pd,pl,apl,om,px,py,shs,rh,tv,hl real,dimension(levs):: hm,se,bvf2,pvn,theta,sigma,pvu real,dimension(levs+1):: pi real os,aps integer ipoh,ipou,ipov,ipot,ipow,ipor,ipoa,ipos,ipoo,ipoc integer iptu,iptv,iptt,iptr,iptq integer izzu,izzv,izzt,izzr integer ithu,ithv,ithh,itht,ithz integer ipvu,ipvv,ipvh,ipvt,ipvp,ipvs integer isun,ifox integer i,k,iwx ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Compute indices ipoh=1+kpo*(ipos_hgt_prs-1) ipou=1+kpo*(ipou_ugrd_prs-1) ipov=1+kpo*(ipov_vgrd_prs-1) ipot=1+kpo*(ipos_tmp_prs-1) ipow=1+kpo*(ipos_vvel_prs-1) ipor=1+kpo*(ipos_rh_prs-1) ipoa=1+kpo*(ipos_absv_prs-1) ipos=1+kpo*(ipos_spfh_prs-1) ipoo=1+kpo*(ipos_o3mr_prs-1) ipoc=1+kpo*(ipos_clwmr_prs-1) iptu=1+kpt*(iptu_ugrd_plg-1) iptv=1+kpt*(iptv_vgrd_plg-1) iptt=1+kpt*(ipts_tmp_plg-1) iptr=1+kpt*(ipts_rh_plg-1) iptq=1+kpt*(ipts_spfh_plg-1) izzu=1+kzz*(izzu_ugrd_hml-1) izzv=1+kzz*(izzv_vgrd_hml-1) izzt=1+kzz*(izzs_tmp_hml-1) izzr=1+kzz*(izzs_rh_hml-1) ithu=1+kth*(ithu_ugrd_thel-1) ithv=1+kth*(ithv_vgrd_thel-1) ithh=1+kth*(iths_mntsf_thel-1) itht=1+kth*(iths_tmp_thel-1) ithz=1+kth*(iths_pvort_thel-1) ipvu=1+kpv*(ipvu_ugrd_pvl-1) ipvv=1+kpv*(ipvv_vgrd_pvl-1) ipvh=1+kpv*(ipvs_hgt_pvl-1) ipvt=1+kpv*(ipvs_tmp_pvl-1) ipvp=1+kpv*(ipvs_pres_pvl-1) ipvs=1+kpv*(ipvs_vwsh_pvl-1) isun=1 ifox=1 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Compute log pressures and copy flux PDS data apo=log(po) call flxcnv1(kpdsflxs,kpdsflxv,kpdsfoxs,kpdsfoxv) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! For every profile, compute model coordinate information, ! compute relative humidity and heights on model levels, ! interpolate to pressure level, pressure thickness and height level, ! compute sundry fields, compute precipitation type, and copy flux fields. do i=1,im call modstuff(levs,idvc,idsl,nvcoord,vcoord,& ps(i),psx(i),psy(i),d(1,i),u(1,i),v(1,i),& pd,pi,pl,aps,apl,os,om,px,py) call getrh(levs,pl,sh(1,i),t(1,i),shs,rh) call hydro(levs,hs(i),aps,apl,t(1,i),sh(1,i),tv,hl) call pvetc(levs,pl,px,py,tv,tx(1,i),ty(1,i),hl,u(1,i),v(1,i),z(1,i),& hm,se,bvf2,pvn,theta,sigma,pvu) call p2po(levs,apl,u(1,i),v(1,i),om,hl,t(1,i),rh,sh(1,i),o3(1,i),ct(1,i),& kpo,apo,& fpou(ipou,i),fpov(ipov,i),fpos(ipow,i),fpos(ipoh,i),& fpos(ipot,i),fpos(ipor,i),fpos(ipos,i),fpos(ipoo,i),fpos(ipoc,i)) call p2pt(levs,ps(i),pd,u(1,i),v(1,i),t(1,i),sh(1,i),shs,kpt,pt,& fptu(iptu,i),fptv(iptv,i),fpts(iptt,i),fpts(iptq,i),fpts(iptr,i)) call p2zz(levs,hl,u(1,i),v(1,i),t(1,i),rh,kzz,zz,& fzzu(izzu,i),fzzv(izzv,i),fzzs(izzt,i),fzzs(izzr,i)) call p2th(levs,theta,u(1,i),v(1,i),hm,t(1,i),pvu,kth,th,& lths(ithh,i),fthu(ithu,i),fthv(ithv,i),& fths(ithh,i),fths(itht,i),fths(ithz,i)) lthv(ithu:ithu+kth-1,i)=lths(ithh:ithh+kth-1,i) lths(itht:itht+kth-1,i)=lths(ithh:ithh+kth-1,i) lths(ithz:ithz+kth-1,i)=lths(ithh:ithh+kth-1,i) call p2pv(levs,pvu,hl,t(1,i),pl,u(1,i),v(1,i),kpv,pv,pvpt,pvsb*ps(i),& lpvs(ipvh,i),fpvu(ipvu,i),fpvv(ipvv,i),& fpvs(ipvh,i),fpvs(ipvt,i),fpvs(ipvp,i),fpvs(ipvs,i)) lpvv(ipvu:ipvu+kpv-1,i)=lpvs(ipvh:ipvh+kpv-1,i) lpvs(ipvt:ipvt+kpv-1,i)=lpvs(ipvh:ipvh+kpv-1,i) lpvs(ipvp:ipvp+kpv-1,i)=lpvs(ipvh:ipvh+kpv-1,i) lpvs(ipvs:ipvs+kpv-1,i)=lpvs(ipvh:ipvh+kpv-1,i) call sundry(hs(i),ps(i),levs,pd,pl,u(1,i),v(1,i),t(1,i),& hl,om,rh,sh(1,i),shs,o3(1,i),ct(1,i),& kpo,po,fpos(ipoh,i),kpt,pt,fpts(iptt,i),fpts(iptq,i),& fsuns(1,i),fsunu(1,i),fsunv(1,i)) call calwxt1(levs,fflxs(iflxs_prate_sfc,i),& t(levs:1:-1,i),sh(levs:1:-1,i),pl(levs:1:-1),pi(levs+1:1:-1),& iwx) call flxcnv(hrflx,lflxs(1,i),lflxv(1,i),fflxs(1,i),fflxu(1,i),fflxv(1,i),& iwx,kpdsfoxs,kpdsfoxv,& lfoxs(1,i),lfoxv(1,i),ffoxs(1,i),ffoxu(1,i),ffoxv(1,i)) enddo ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - contains ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine modstuff(km,idvc,idsl,nvcoord,vcoord,ps,psx,psy,d,u,v,& pd,pi,pm,aps,apm,os,om,px,py) !$$$ Subprogram documentation block ! ! Subprogram: modstuff Compute model coordinate dependent functions ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram computes fields which depend on the model coordinate ! such as pressure thickness and vertical velocity. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call modstuff(km,idvc,idsl,nvcoord,vcoord,ps,psx,psy,d,u,v,& ! pd,pi,pm,aps,apm,os,om,px,py) ! Input argument list: ! km integer number of levels ! idvc integer vertical coordinate id (1 for sigma and 2 for hybrid) ! idsl integer type of sigma structure (1 for phillips or 2 for mean) ! nvcoord integer number of vertical coordinates ! vcoord real (km+1,nvcoord) vertical coordinates ! ps real surface pressure (Pa) ! psx real log surface pressure x-gradient (1/m) ! psy real log surface pressure y-gradient (1/m) ! d real (km) wind divergence (1/s) ! u real (km) x-component wind (m/s) ! v real (km) y-component wind (m/s) ! Output argument list: ! pd real (km) pressure thickness (Pa) ! pi real (km+1) interface pressure (Pa) ! pm real (km+1) mid-layer pressure (Pa) ! aps real log surface pressure () ! apm real (km+1) log mid-layer pressure () ! os real (km) surface pressure tendency (Pa/s) ! om real (km) vertical velocity (Pa/s) ! px real (km) mid-layer pressure x-gradient (Pa/m) ! py real (km) mid-layer pressure y-gradient (Pa/m) ! ! Attributes: ! Language: Fortran 90 ! !$$$ use sigio_module implicit none integer,intent(in):: km,idvc,idsl,nvcoord real,intent(in):: vcoord(km+1,nvcoord) real,intent(in):: ps,psx,psy real,intent(in):: u(km),v(km),d(km) real,intent(out):: pd(km),pi(km+1),pm(km) real,intent(out):: aps,apm(km),os,om(km),px(km),py(km) real dpmdps(km),dpddps(km),dpidps(km+1),vgradp integer k,iret ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - call sigio_modpr(1,1,km,nvcoord,idvc,idsl,vcoord,iret,& ps=(/ps/),& pm=pm,pd=pd,dpmdps=dpmdps,dpddps=dpddps) pi(1)=ps dpidps(1)=1. do k=1,km pi(k+1)=pi(k)-pd(k) dpidps(k+1)=dpidps(k)-dpddps(k) enddo aps=log(ps) apm=log(pm) os=0 do k=km,1,-1 vgradp=u(k)*psx+v(k)*psy os=os-vgradp*ps*(dpmdps(k)-dpidps(k+1))-d(k)*(pm(k)-pi(k+1)) om(k)=vgradp*ps*dpmdps(k)+os os=os-vgradp*ps*(dpidps(k)-dpmdps(k))-d(k)*(pi(k)-pm(k)) enddo px=ps*dpmdps*psx py=ps*dpmdps*psy end subroutine ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine modpr1(km,idvc,idsl,si,ak,bk,ps,pi,pm) !$$$ subprogram documentation block ! ! subprogram: modpr1 compute model pressures ! prgmmr: iredell org: w/nmc23 date: 92-10-31 ! ! abstract: compute model pressures. ! ! program history log: ! 2001-07-25 mark iredell ! ! usage: call modpr1(km,idvc,idsl,si,ak,bk,ps,pi,pm) ! input argument list: ! km integer number of levels ! idvc integer vertical coordinate id ! (1 for sigma and 2 for hybrid) ! idsl integer type of sigma structure ! (1 for phillips or 2 for mean) ! si real (km+1) sigma interface values (idvc=1) ! ak real (km+1) hybrid interface a (idvc=2) ! bk real (km+1) hybrid interface b (idvc=2) ! ps real surface pressure (Pa) ! output argument list: ! pi real (km+1) interface pressure (Pa) ! pm real (km) mid-layer pressure (Pa) ! ! Subprograms called: ! fpkap compute pressure to the kappa ! frkap compute pressure to the 1/kappa ! ! attributes: ! language: fortran ! !$$$ use funcphys use physcons implicit none integer,intent(in):: km,idvc,idsl real,intent(in):: si(km+1),ak(km+1),bk(km+1),ps real,intent(out):: pi(km+1),pm(km) integer k real(krealfp) pd,pu,pkd,pku ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if(idvc.eq.2) then do k=1,km+1 pi(k)=ak(k)+bk(k)*ps enddo else do k=1,km+1 pi(k)=si(k)*ps enddo endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - if(idsl.eq.2) then do k=1,km pm(k)=(pi(k)+pi(k+1))/2 enddo else pd=pi(1) pkd=fpkap(pd) do k=1,km if(pi(k+1).gt.0) then pu=pi(k+1) pku=fpkap(pu) pm(k)=frkap((pd*pkd-pu*pku)/((con_rocp+1)*(pd-pu))) else pu=0 pku=0 pm(k)=frkap(pkd/(con_rocp+1)) endif pd=pu pkd=pku enddo endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end subroutine ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine getrh(km,p,sh,t,shs,rh) !$$$ Subprogram documentation block ! ! Subprogram: getrh Compute saturation humidity and relative humidity ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram computes the saturation specific humidity and the ! relative humidity. The relative humidity is constrained to be ! between 0 and 100. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call getrh(km,p,sh,t,shs,rh) ! Input argument list: ! km integer number of levels ! p real (km) pressure (Pa) ! sh real (km) specific humidity (kg/kg) ! t real (km) temperature (K) ! Output argument list: ! shs real (km) saturation specific humidity (kg/kg) ! rh real (km) relative humidity (percent) ! ! Modules used: ! funcphys Physical functions ! ! Files included: ! physcons.h Physical constants ! ! Subprograms called: ! fpvs compute saturation vapor pressure ! ! Attributes: ! Language: Fortran 90 ! !$$$ use funcphys use physcons implicit none integer,intent(in):: km real,intent(in):: p(km),sh(km),t(km) real,intent(out):: shs(km),rh(km) real(krealfp) pr,tr,es integer k ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - do k=1,km pr=p(k) tr=t(k) es=fpvs(tr) es=min(es,pr) shs(k)=con_eps*es/(pr+con_epsm1*es) rh(k)=1.e2*min(max(sh(k)/shs(k),0.),1.) enddo end subroutine ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine hydro(km,hs,aps,ap,t,sh,tv,h) !$$$ Subprogram documentation block ! ! Subprogram: hydro Compute geopotential heights ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram computes geopotential heights by integrating ! the hydrostatic equation. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call hydro(km,hs,aps,ap,t,sh,tv,h) ! Input argument list: ! km integer number of levels ! hs real surface height (m) ! aps real log surface pressure () ! ap real (km) log pressure () ! t real (km) temperature (K) ! sh real (km) specific humidity (kg/kg) ! Output argument list: ! tv real (km) virtual temperature (K) ! h real (km) height (m) ! ! Files included: ! physcons.h Physical constants ! ! Attributes: ! Language: Fortran 90 ! !$$$ use physcons implicit none integer,intent(in):: km real,intent(in):: hs,aps,ap(km),t(km),sh(km) real,intent(out):: tv(km),h(km) integer k ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - tv(1)=t(1)*(1+con_fvirt*sh(1)) h(1)=hs-con_rog*tv(1)*(ap(1)-aps) do k=2,km tv(k)=t(k)*(1+con_fvirt*sh(k)) h(k)=h(k-1)-con_rog*0.5*(tv(k-1)+tv(k))*(ap(k)-ap(k-1)) enddo end subroutine ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine pvetc(km,p,px,py,t,tx,ty,h,u,v,av,hm,s,bvf2,pvn,theta,sigma,pvu) !$$$ Subprogram documentation block ! ! Subprogram: pvetc Compute potential vorticity, etc ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram computes ! the Montgomery streamfunction ! hm=cp*t+g*z ! the specific entropy ! s=cp*log(t/t0)-r*log(p/p0) ! the Brunt-Vaisala frequency squared ! bvf2=g/cp*ds/dz ! the potential vorticity defined as ! pvn=(av*ds/dz-dv/dz*ds/dx+du/dz*ds/dy)/rho/cp ! the potential temperature ! theta=t0*exp(s/cp) ! the static stability ! sigma=t/g*bvf2 ! and the potential vorticity in PV units ! pvu=10**-6*theta*pvn ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call pvetc(km,p,px,py,t,tx,ty,h,u,v,av,s,bvf2,pvn,theta,sigma,pvu) ! Input argument list: ! km integer number of levels ! p real (km) pressure (Pa) ! px real (km) pressure x-gradient (Pa/m) ! py real (km) pressure y-gradient (Pa/m) ! t real (km) (virtual) temperature (K) ! tx real (km) (virtual) temperature x-gradient (K/m) ! ty real (km) (virtual) temperature y-gradient (K/m) ! h real (km) height (m) ! u real (km) x-component wind (m/s) ! v real (km) y-component wind (m/s) ! av real (km) absolute vorticity (1/s) ! Output argument list: ! hm real (km) Montgomery streamfunction (m**2/s**2) ! s real (km) specific entropy (J/K/kg) ! bvf2 real (km) Brunt-Vaisala frequency squared (1/s**2) ! pvn real (km) potential vorticity (m**2/kg/s) ! theta real (km) (virtual) potential temperature (K) ! sigma real (km) static stability (K/m) ! pvu real (km) potential vorticity (10**-6*K*m**2/kg/s) ! ! Modules used: ! physcons Physical constants ! ! Attributes: ! Language: Fortran 90 ! !$$$ use physcons implicit none integer,intent(in):: km real,intent(in),dimension(km):: p,px,py,t,tx,ty,h,u,v,av real,intent(out),dimension(km):: hm,s,bvf2,pvn,theta,sigma,pvu ! real,parameter:: hhmin=500.,t0=2.e2,p0=1.e5 real,parameter:: hhmin=5.,t0=2.e2,p0=1.e5 integer k,kd,ku,k2(2) real cprho,sx,sy,sz,uz,vz ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - do k=1,km hm(k)=con_cp*t(k)+con_g*h(k) s(k)=con_cp*log(t(k)/t0)-con_rd*log(p(k)/p0) enddo do k=1,km call rsearch1(km,h,2,(/h(k)-hhmin,h(k)+hhmin/),k2) kd=max(k2(1),1) ku=min(k2(2)+1,km) cprho=p(k)/(con_rocp*t(k)) sx=con_cp*tx(k)/t(k)-con_rd*px(k)/p(k) sy=con_cp*ty(k)/t(k)-con_rd*py(k)/p(k) sz=(s(ku)-s(kd))/(h(ku)-h(kd)) uz=(u(ku)-u(kd))/(h(ku)-h(kd)) vz=(v(ku)-v(kd))/(h(ku)-h(kd)) bvf2(k)=con_g/con_cp*sz pvn(k)=(av(k)*sz-vz*sx+uz*sy)/cprho theta(k)=t0*exp(s(k)/con_cp) sigma(k)=t(k)/con_g*bvf2(k) pvu(k)=1.e6*theta(k)*pvn(k) enddo end subroutine ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine p2po(km,ap,u,v,om,h,t,rh,sh,o3,ct,& kpo,apo,up,vp,omp,hp,tp,rhp,shp,o3p,ctp) !$$$ Subprogram documentation block ! ! Subprogram: p2po Interpolate to pressure level ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram interpolates fields to given pressure levels. ! The interpolation is linear in log pressure within the domain. ! The height is then integrated hydrostatically by assuming that ! the virtual temperature is linear in log pressure. ! Outside the domain, fields are held constant with the following exceptions. ! Above the top, the height is integrated hydrostatically. ! Below the bottom, the height and temperature are found by the Shuell method, ! which limits the errors in extrapolation. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call p2po(km,ap,u,v,om,h,t,rh,sh,o3,ct,& ! kpo,apo,up,vp,omp,hp,tp,rhp,shp,o3p,ctp) ! Input argument list: ! km integer number of levels ! ap real (km) log pressure () ! u real (km) x-component wind (m/s) ! v real (km) y-component wind (m/s) ! om real (km) vertical velocity (Pa/s) ! h real (km) height (m) ! t real (km) temperature (K) ! rh real (km) relative humidity (percent) ! sh real (km) specific humidity (kg/kg) ! o3 real (km) specific ozone (kg/kg) ! ct real (km) specific cloud water (kg/kg) ! kpo integer number of pressure levels ! apo real (kpo) log pressure levels () ! Output argument list: ! up real (kpo) x-component wind (m/s) ! vp real (kpo) y-component wind (m/s) ! omp real (kpo) vertical velocity (Pa/s) ! hp real (kpo) height (m) ! tp real (kpo) temperature (K) ! rhp real (kpo) relative humidity (percent) ! shp real (kpo) specific humidity (kg/kg) ! o3p real (kpo) specific ozone (kg/kg) ! ctp real (kpo) specific cloud water (kg/kg) ! ! Files included: ! physcons.h Physical constants ! ! Subprograms called: ! rsearch1 search for a surrounding real interval ! ! Attributes: ! Language: Fortran 90 ! !$$$ use physcons implicit none integer,intent(in):: km,kpo real,intent(in),dimension(km):: ap,u,v,om,h,t,rh,sh,o3,ct real,intent(in):: apo(kpo) real,intent(out),dimension(kpo):: up,vp,omp,hp,tp,rhp,shp,o3p,ctp real,parameter:: gammam=-6.5e-3,zshul=75.,tvshul=290.66 real w,tvd,tvu,gammas,part integer loc(kpo),l integer k ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - call rsearch1(km,ap(1),kpo,apo(1),loc(1)) do k=1,kpo l=loc(k) if(l.eq.0) then ! below bottom up(k)=u(1) vp(k)=v(1) omp(k)=om(1) rhp(k)=rh(1) shp(k)=sh(1) o3p(k)=o3(1) ctp(k)=ct(1) tvu=t(1)*(1.+con_fvirt*sh(1)) if(h(1).gt.zshul) then tvd=tvu-gammam*h(1) if(tvd.gt.tvshul) then if(tvu.gt.tvshul) then tvd=tvshul-5.e-3*(tvu-tvshul)**2 else tvd=tvshul endif endif gammas=(tvu-tvd)/h(1) else gammas=0. endif part=con_rog*(apo(k)-ap(1)) hp(k)=h(1)-tvu*part/(1.+0.5*gammas*part) ! tp(k)=t(1)+gammas*(hp(k)-h(1)) tp(k)=t(1)+gammam*(hp(k)-h(1)) ! within domain elseif(l.lt.km) then w=(apo(k)-ap(l))/(ap(l+1)-ap(l)) up(k)=u(l)+w*(u(l+1)-u(l)) vp(k)=v(l)+w*(v(l+1)-v(l)) omp(k)=om(l)+w*(om(l+1)-om(l)) tp(k)=t(l)+w*(t(l+1)-t(l)) rhp(k)=rh(l)+w*(rh(l+1)-rh(l)) shp(k)=sh(l)+w*(sh(l+1)-sh(l)) o3p(k)=o3(l)+w*(o3(l+1)-o3(l)) ctp(k)=ct(l)+w*(ct(l+1)-ct(l)) tvd=t(l)*(1+con_fvirt*sh(l)) tvu=tp(k)*(1+con_fvirt*shp(k)) hp(k)=h(l)-con_rog*0.5*(tvd+tvu)*(apo(k)-ap(l)) ! above top else up(k)=u(km) vp(k)=v(km) omp(k)=om(km) tp(k)=t(km) rhp(k)=rh(km) shp(k)=sh(km) o3p(k)=o3(km) ctp(k)=ct(km) tvd=t(km)*(1+con_fvirt*sh(km)) hp(k)=h(km)-con_rog*tvd*(apo(k)-ap(km)) endif enddo end subroutine ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine p2pt(km,ps,pd,u,v,t,sh,shs,kpt,pt,upt,vpt,tpt,shpt,rhpt) !$$$ Subprogram documentation block ! ! Subprogram: p2pt Interpolate to pressure layer ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram interpolates fields to given pressure layers. ! The pressure layers begin abutting the surface and lay contiguously ! up into the boundary layer. The interpolation is actually an integrated ! mean value in pressure through each output layer. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call p2pt(km,ps,pd,u,v,t,sh,shs,kpt,pt,upt,vpt,tpt,shpt,rhpt) ! Input argument list: ! km integer number of levels ! ps real surface pressure (Pa) ! pd real (km) pressure thickness (Pa) ! u real (km) x-component wind (m/s) ! v real (km) y-component wind (m/s) ! t real (km) temperature (K) ! sh real (km) specific humidity (kg/kg) ! shs real (km) saturation specific humidity (kg/kg) ! kpt integer number of pressure layers ! pt real (kpt) pressure layer edges above surface (Pa) ! Output argument list: ! upt real (kpt) x-component wind (m/s) ! vpt real (kpt) y-component wind (m/s) ! omp real (kpt) vertical velocity (Pa/s) ! tpt real (kpt) temperature (K) ! shpt real (kpt) specific humidity (kg/kg) ! rhpt real (kpt) relative humidity (percent) ! ! Subprograms called: ! rsearch1 search for a surrounding real interval ! ! Attributes: ! Language: Fortran 90 ! !$$$ implicit none integer,intent(in):: km,kpt real,intent(in):: ps real,intent(in),dimension(km):: pd,u,v,t,sh,shs real,intent(in):: pt(kpt) real,intent(out),dimension(kpt):: upt,vpt,tpt,shpt,rhpt real pi(km+1),pta(0:kpt),ptd integer loc(kpt),l1,l2,l integer k ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - pi(1)=ps do k=2,km+1 pi(k)=pi(k-1)-pd(k-1) enddo pta(0)=ps pta(1:kpt)=ps-pt call rsearch1(km,pi(1),kpt,pta(1),loc(1)) l1=1 do k=1,kpt l2=loc(k) upt(k)=0. vpt(k)=0. tpt(k)=0. shpt(k)=0. rhpt(k)=0. do l=l1,l2 ptd=max(min(pi(l),pta(k-1))-max(pi(l+1),pta(k)),0.) upt(k)=upt(k)+ptd*u(l) vpt(k)=vpt(k)+ptd*v(l) tpt(k)=tpt(k)+ptd*t(l) shpt(k)=shpt(k)+ptd*sh(l) rhpt(k)=rhpt(k)+ptd*shs(l) enddo l1=l2 rhpt(k)=1.e2*min(max(shpt(k)/rhpt(k),0.),1.) upt(k)=upt(k)/(pta(k-1)-pta(k)) vpt(k)=vpt(k)/(pta(k-1)-pta(k)) tpt(k)=tpt(k)/(pta(k-1)-pta(k)) shpt(k)=shpt(k)/(pta(k-1)-pta(k)) enddo end subroutine ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine p2zz(km,h,u,v,t,r,kzz,zz,uzz,vzz,tzz,rzz) !$$$ Subprogram documentation block ! ! Subprogram: p2zz Interpolate to height level ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram interpolates fields to given height levels. ! The output levels are constant height above sea level. The interpolation ! is linear in height. Outside the domain fields are held constant. ! ! Program history log: ! 1999-10-18 Mark Iredell ! 2001-05-04 Mark Iredell Added relative humidity ! ! Usage: call p2zz(km,h,u,v,t,r,kzz,zz,uzz,vzz,tzz,rzz) ! Input argument list: ! km integer number of levels ! h real (km) height (m) ! u real (km) x-component wind (m/s) ! v real (km) y-component wind (m/s) ! t real (km) temperature (K) ! r real (km) relative humidity (percent) ! kzz integer number of height levels ! zz real (kzz) height levels (m) ! Output argument list: ! uzz real (kzz) x-component wind (m/s) ! vzz real (kzz) y-component wind (m/s) ! tzz real (kzz) temperature (K) ! rzz real (kzz) relative humidity (percent) ! ! Subprograms called: ! rsearch1 search for a surrounding real interval ! ! Attributes: ! Language: Fortran 90 ! !$$$ implicit none integer,intent(in):: km,kzz real,intent(in),dimension(km):: h,u,v,t,r real,intent(in):: zz(kzz) real,intent(out),dimension(kzz):: uzz,vzz,tzz,rzz real w integer loc(kzz),l integer k ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - call rsearch1(km,h(1),kzz,zz(1),loc(1)) do k=1,kzz l=loc(k) if(l.eq.0) then ! below bottom uzz(k)=u(1) vzz(k)=v(1) tzz(k)=t(1) rzz(k)=r(1) ! within domain elseif(l.lt.km) then w=(zz(k)-h(l))/(h(l+1)-h(l)) uzz(k)=u(l)+w*(u(l+1)-u(l)) vzz(k)=v(l)+w*(v(l+1)-v(l)) tzz(k)=t(l)+w*(t(l+1)-t(l)) rzz(k)=r(l)+w*(r(l+1)-r(l)) ! above top else uzz(k)=u(km) vzz(k)=v(km) tzz(k)=t(km) rzz(k)=r(km) endif enddo end subroutine ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine p2th(km,theta,u,v,h,t,pvu,kth,th,lth,uth,vth,hth,tth,zth) !$$$ Subprogram documentation block ! ! Subprogram: p2th Interpolate to isentropic level ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram interpolates fields to given isentropic levels. ! The interpolation is linear in entropy. ! Outside the domain the bitmap is set to false. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call p2th(km,theta,u,v,h,t,puv,kth,th,uth,vth,tth) ! Input argument list: ! km integer number of levels ! theta real (km) potential temperature (K) ! u real (km) x-component wind (m/s) ! v real (km) y-component wind (m/s) ! h real (km) height (m) ! t real (km) temperature (K) ! pvu real (km) potential vorticity in PV units (10**-6*K*m**2/kg/s) ! kth integer number of isentropic levels ! th real (kth) isentropic levels (K) ! Output argument list: ! lpv logical*1 (kth) bitmap ! uth real (kth) x-component wind (m/s) ! vth real (kth) y-component wind (m/s) ! hth real (kth) height (m) ! tth real (kth) temperature (K) ! zth real (kth) potential vorticity in PV units (10**-6*K*m**2/kg/s) ! ! Subprograms called: ! rsearch1 search for a surrounding real interval ! ! Attributes: ! Language: Fortran 90 ! !$$$ implicit none integer,intent(in):: km,kth real,intent(in),dimension(km):: theta,u,v,h,t,pvu real,intent(in):: th(kth) logical*1,intent(out),dimension(kth):: lth real,intent(out),dimension(kth):: uth,vth,hth,tth,zth real w integer loc(kth),l integer k ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - call rsearch1(km,theta(1),kth,th(1),loc(1)) do k=1,kth l=loc(k) lth(k)=l.gt.0.and.l.lt.km if(lth(k)) then w=log(th(k)/theta(l))/log(theta(l+1)/theta(l)) uth(k)=u(l)+w*(u(l+1)-u(l)) vth(k)=v(l)+w*(v(l+1)-v(l)) hth(k)=h(l)+w*(h(l+1)-h(l)) tth(k)=t(l)+w*(t(l+1)-t(l)) zth(k)=pvu(l)+w*(pvu(l+1)-pvu(l)) endif enddo end subroutine ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine p2pv(km,pvu,h,t,p,u,v,kpv,pv,pvpt,pvpb,& lpv,upv,vpv,hpv,tpv,ppv,spv) !$$$ Subprogram documentation block ! ! Subprogram: p2pv Interpolate to potential vorticity level ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram interpolates fields to given potential vorticity ! levels within given pressure limits. ! The output level is the first encountered from the top pressure limit. ! If the given potential vorticity level is not found, the outputs are zero ! and the bitmap is false. The interpolation is linear in potential vorticity. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call p2pv(km,pvu,h,t,p,u,v,kpv,pv,pvpt,pvpb,& ! lpv,upv,vpv,hpv,tpv,ppv,spv) ! Input argument list: ! km integer number of levels ! pvu real (km) potential vorticity in PV units (10**-6*K*m**2/kg/s) ! h real (km) height (m) ! t real (km) temperature (K) ! p real (km) pressure (Pa) ! u real (km) x-component wind (m/s) ! v real (km) y-component wind (m/s) ! kpv integer number of potential vorticity levels ! pv real (kpv) potential vorticity levels (10**-6*K*m**2/kg/s) ! pvpt real (kpv) top pressures for PV search (Pa) ! pvpb real (kpv) bottom pressures for PV search (Pa) ! Output argument list: ! lpv logical*1 (kpv) bitmap ! upv real (kpv) x-component wind (m/s) ! vpv real (kpv) y-component wind (m/s) ! hpv real (kpv) temperature (K) ! tpv real (kpv) temperature (K) ! ppv real (kpv) pressure (Pa) ! spv real (kpv) wind speed shear (1/s) ! ! Subprograms called: ! rsearch1 search for a surrounding real interval ! ! Attributes: ! Language: Fortran 90 ! !$$$ use physcons implicit none integer,intent(in):: km,kpv real,intent(in),dimension(km):: pvu,h,t,p,u,v real,intent(in):: pv(kpv),pvpt(kpv),pvpb(kpv) logical*1,intent(out),dimension(kpv):: lpv real,intent(out),dimension(kpv):: upv,vpv,hpv,tpv,ppv,spv real,parameter:: pd=2500. real w,spdu,spdd integer k,l1,l2,lu,ld,l ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - do k=1,kpv call rsearch1(km,p,1,pvpb(k),l1) call rsearch1(km,p,1,pvpt(k),l2) l1=l1+1 l=0 if(pv(k).ge.0.) then do lu=l2-1,l1,-1 if(pv(k).lt.pvu(lu+1).and.pv(k).ge.pvu(lu)) then call rsearch1(km,p,1,p(lu)+pd,ld) if(all(pv(k).ge.pvu(ld:lu-1))) then l=lu exit endif endif enddo else do lu=l2-1,l1,-1 if(pv(k).gt.pvu(lu+1).and.pv(k).le.pvu(lu)) then call rsearch1(km,p,1,p(lu)+pd,ld) if(all(pv(k).le.pvu(ld:lu-1))) then l=lu exit endif endif enddo endif lpv(k)=l.gt.0 if(lpv(k)) then w=(pv(k)-pvu(l))/(pvu(l+1)-pvu(l)) upv(k)=u(l)+w*(u(l+1)-u(l)) vpv(k)=v(l)+w*(v(l+1)-v(l)) hpv(k)=h(l)+w*(h(l+1)-h(l)) tpv(k)=t(l)+w*(t(l+1)-t(l)) ppv(k)=p(l)*exp((h(l)-hpv(k))*(1-0.5*(tpv(k)/t(l)-1))/(con_rog*t(l))) spdu=sqrt(u(l+1)**2+v(l+1)**2) spdd=sqrt(u(l)**2+v(l)**2) spv(k)=(spdu-spdd)/(h(l+1)-h(l)) endif enddo end subroutine ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine sundry(hs,ps,km,pd,p,u,v,t,h,om,rh,sh,shs,o3,ct,& kpo,po,hpo,kpt,pt,tpt,shpt,suns,sunu,sunv) !$$$ Subprogram documentation block ! ! Subprogram: sundry Compute sundry single-level posted fields ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram computes sundry single-level posted fields. ! The fields returned are surface orography and pressure; tropopause wind, ! temperature, height, and vertical shear; both surface and best lifted index, ! convective available potential energy and convective inhibition; maximum ! wind level wind, temperature, and height; sea level pressure; column ! precipitable water and average relative humidities; bottom sigma fields; ! and total ozone and total cloud water. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call sundry(hs,ps,km,pd,p,u,v,t,h,om,rh,sh,shs,o3,ct,& ! kpo,po,hpo,kpt,pt,tpt,shpt,suns,sunu,sunv) ! Input argument list: ! hs real surface height (m) ! ps real surface pressure (Pa) ! km integer number of levels ! pd real (km) pressure thickness (Pa) ! p real (km) pressure (Pa) ! u real (km) x-component wind (m/s) ! v real (km) y-component wind (m/s) ! t real (km) temperature (K) ! h real (km) height (m) ! om real (km) vertical velocity (Pa/s) ! rh real (km) relative humidity (percent) ! sh real (km) specific humidity (kg/kg) ! shs real (km) saturation specific humidity (kg/kg) ! o3 real (km) specific ozone (kg/kg) ! ct real (km) specific cloud water (kg/kg) ! kpo integer number of pressure levels ! po real (kpo) pressure levels (Pa) ! hpo real (kpo) height (m) ! kpt integer number of pressure layers ! pt real (kpt) pressure layer edges above surface (Pa) ! tpt real (kpt) temperature (K) ! shpt real (kpt) specific humidity (kg/kg) ! Output argument list: ! suns real (nsuns) sundry scalar fields ! sunu real (nsunv) sundry vector x-component fields ! sunv real (nsunv) sundry vector y-component fields ! ! Modules used: ! postgp_module Shared data for postgp ! funcphys Physical functions ! ! Files included: ! physcons.h Physical constants ! ! Subprograms called: ! tpause compute tropopause level fields ! liftix compute lifting index, cape and cin ! mxwind compute maximum wind level fields ! freeze compute freezing level fields ! rsearch1 search for a surrounding real interval ! ! Attributes: ! Language: Fortran 90 ! !$$$ use postgp_module use funcphys use physcons implicit none integer,intent(in):: km,kpo,kpt real,intent(in):: hs,ps real,intent(in),dimension(km):: pd,p,u,v,t,h,om,rh,sh,shs,o3,ct real,intent(in),dimension(kpo):: po,hpo real,intent(in),dimension(kpt):: pt,tpt,shpt real,intent(out):: suns(nsuns),sunu(nsunv),sunv(nsunv) real,parameter:: pslp(2)=(/1000.e+2,500.e+2/),& pm1=1.e5,tm1=287.45,hm1=113.,hm2=5572.,& fslp=con_g*(hm2-hm1)/(con_rd*tm1) real,parameter:: strh1=0.44,strh2=0.72,strh3=0.44,strh4=0.33,& sbrh1=1.00,sbrh2=0.94,sbrh3=0.72,sbrh4=1.00 real,parameter:: sl1=0.9950 integer k,kslp(2) real sumtn,sumtd,sum1n,sum1d,sum2n,sum2d,sum3n,sum3d,sum4n,sum4d real pid,piu,dp1,dp2,dp3,dp4 real sumo3,sumct,p1,p1k,f2 real hfac ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! surface orography and surface pressure suns(isuns_hgt_sfc)=hs suns(isuns_pres_sfc)=ps ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! sundry tropopause fields call tpause(km,p,u,v,t,h,& suns(isuns_pres_trp),sunu(isunu_ugrd_trp),sunv(isunv_vgrd_trp),& suns(isuns_tmp_trp),suns(isuns_hgt_trp),suns(isuns_vwsh_trp)) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! lifted index, cape and cin call liftix(ps,kpt,pt,tpt,shpt,km,p,t,sh,h,& suns(isuns_lftx_sfc),suns(isuns_cape_sfc),suns(isuns_cin_sfc),& suns(isuns_blftx_sfc),& suns(isuns_cape_plg_180_0),suns(isuns_cin_plg_180_0)) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! sundry maxwind fields call mxwind(km,p,u,v,t,h,& suns(isuns_pres_mwl),sunu(isunu_ugrd_mwl),sunv(isunv_vgrd_mwl),& suns(isuns_tmp_mwl),suns(isuns_hgt_mwl)) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! sundry freezing fields call freeze(km,hs,p,t,h,rh,& suns(isuns_hgt_zdeg),suns(isuns_rh_zdeg),& suns(isuns_hgt_htfl),suns(isuns_rh_htfl)) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! sea level pressure call rsearch1(kpo,po(1),2,pslp(1),kslp(1)) if(kslp(1).gt.0.and.po(kslp(1)).eq.pslp(1).and.& kslp(2).gt.0.and.po(kslp(2)).eq.pslp(2)) then hfac=hpo(kslp(1))/(hpo(kslp(2))-hpo(kslp(1))) suns(isuns_prmsl_msl)=pm1*exp(fslp*hfac) else suns(isuns_prmsl_msl)=0 endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! column precipitable water and average relative humidities sumtn=0 sumtd=0 sum1n=0 sum1d=0 sum2n=0 sum2d=0 sum3n=0 sum3d=0 sum4n=0 sum4d=0 pid=ps do k=1,km sumtn=sumtn+sh(k)*pd(k) sumtd=sumtd+shs(k)*pd(k) piu=pid-pd(k) dp1=max(min(pid,sbrh1*ps)-max(piu,strh1*ps),0.) sum1n=sum1n+sh(k)*dp1 sum1d=sum1d+shs(k)*dp1 dp2=max(min(pid,sbrh2*ps)-max(piu,strh2*ps),0.) sum2n=sum2n+sh(k)*dp2 sum2d=sum2d+shs(k)*dp2 dp3=max(min(pid,sbrh3*ps)-max(piu,strh3*ps),0.) sum3n=sum3n+sh(k)*dp3 sum3d=sum3d+shs(k)*dp3 dp4=max(min(pid,sbrh4*ps)-max(piu,strh4*ps),0.) sum4n=sum4n+sh(k)*dp4 sum4d=sum4d+shs(k)*dp4 pid=piu enddo suns(isuns_pwat_clm)=max(sumtn,0.)/con_g suns(isuns_rh_clm)=1.e2*min(max(sumtn/sumtd,0.),1.) suns(isuns_rh_slr_044_100)=1.e2*min(max(sum1n/sum1d,0.),1.) suns(isuns_rh_slr_072_094)=1.e2*min(max(sum2n/sum2d,0.),1.) suns(isuns_rh_slr_044_072)=1.e2*min(max(sum3n/sum3d,0.),1.) suns(isuns_rh_slr_033_100)=1.e2*min(max(sum4n/sum4d,0.),1.) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! bottom sigma fields interpolated from first two model layers p1=sl1*ps f2=log(p(1)/p1)/log(p(1)/p(2)) p1k=fpkap(real(p1,krealfp)) suns(isuns_tmp_sig_9950)=t(1)+f2*(t(2)-t(1)) suns(isuns_pot_sig_9950)=suns(isuns_tmp_sig_9950)/p1k suns(isuns_vvel_sig_9950)=om(1)+f2*(om(2)-om(1)) suns(isuns_rh_sig_9950)=rh(1)+f2*(rh(2)-rh(1)) sunu(isunu_ugrd_sig_9950)=u(1)+f2*(u(2)-u(1)) sunv(isunv_vgrd_sig_9950)=v(1)+f2*(v(2)-v(1)) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! total ozone sumo3=0 do k=1,km sumo3=sumo3+o3(k)*pd(k) enddo ! convert ozone from kg/m2 to dobson units, which give the depth of the ! ozone layer in 1e-5 m if brought to natural temperature and pressure. suns(isuns_tozne_clm)=max(sumo3,0.)/(con_g*2.14e-5) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! total cloud water sumct=0 do k=1,km sumct=sumct+ct(k)*pd(k) enddo suns(isuns_cwat_clm)=max(sumct,0.)/con_g end subroutine ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine tpause(km,p,u,v,t,h,ptp,utp,vtp,ttp,htp,shrtp) !$$$ Subprogram documentation block ! ! Subprogram: tpause Compute tropopause level fields ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram finds the tropopause level and computes fields ! at the tropopause level. The tropopause is defined as the lowest level ! above 500 mb which has a temperature lapse rate of less than 2 K/km. ! The lapse rate must average less than 2 K/km over a 2 km depth. ! If no such level is found below 50 mb, the tropopause is set to 50 mb. ! The tropopause fields are interpolated linearly in lapse rate. ! The tropopause pressure is found hydrostatically. ! The tropopause wind shear is computed as the partial derivative ! of wind speed with respect to height at the tropopause level. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call tpause(km,p,u,v,t,h,ptp,utp,vtp,ttp,htp,shrtp) ! Input argument list: ! km integer number of levels ! p real (km) pressure (Pa) ! u real (km) x-component wind (m/s) ! v real (km) y-component wind (m/s) ! t real (km) temperature (K) ! h real (km) height (m) ! Output argument list: ! ptp real tropopause pressure (Pa) ! utp real tropopause x-component wind (m/s) ! vtp real tropopause y-component wind (m/s) ! ttp real tropopause temperature (K) ! htp real tropopause height (m) ! shrtp real tropopause wind shear (1/s) ! ! Files included: ! physcons.h Physical constants ! ! Subprograms called: ! rsearch1 search for a surrounding real interval ! ! Attributes: ! Language: Fortran 90 ! !$$$ use physcons implicit none integer,intent(in):: km real,intent(in),dimension(km):: p,u,v,t,h real,intent(out):: ptp,utp,vtp,ttp,htp,shrtp real,parameter:: ptplim(2)=(/500.e+2,50.e+2/),gamtp=2.e-3,hd=2.e+3 real gamu,gamd,td,gami,wtp,spdu,spdd integer klim(2),k,kd,ktp ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! find tropopause level call rsearch1(km-2,p(2),2,ptplim(1),klim(1)) klim(1)=klim(1)+2 klim(2)=klim(2)+1 gamd=1.e+9 ktp=klim(2) wtp=0 do k=klim(1),klim(2) gamu=(t(k-1)-t(k+1))/(h(k+1)-h(k-1)) if(gamu.le.gamtp) then call rsearch1(km-k-1,h(k+1),1,h(k)+hd,kd) td=t(k+kd)+(h(k)+hd-h(k+kd))/(h(k+kd+1)-h(k+kd))*(t(k+kd+1)-t(k+kd)) gami=(t(k)-td)/hd if(gami.le.gamtp) then ktp=k wtp=(gamtp-gamu)/(max(gamd,gamtp+0.1e-3)-gamu) exit endif endif gamd=gamu enddo ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! compute tropopause level fields utp=u(ktp)-wtp*(u(ktp)-u(ktp-1)) vtp=v(ktp)-wtp*(v(ktp)-v(ktp-1)) ttp=t(ktp)-wtp*(t(ktp)-t(ktp-1)) htp=h(ktp)-wtp*(h(ktp)-h(ktp-1)) ptp=p(ktp)*exp((h(ktp)-htp)*(1-0.5*(ttp/t(ktp)-1))/(con_rog*t(ktp))) spdu=sqrt(u(ktp)**2+v(ktp)**2) spdd=sqrt(u(ktp-1)**2+v(ktp-1)**2) shrtp=(spdu-spdd)/(h(ktp)-h(ktp-1)) end subroutine ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine mxwind(km,p,u,v,t,h,pmw,umw,vmw,tmw,hmw) !$$$ Subprogram documentation block ! ! Subprogram: mxwind Compute maximum wind level fields ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram finds the maximum wind level and computes fields ! at the maximum wind level. The maximum wind level is searched for ! between 500 mb and 100 mb. The height and wind speed at the maximum wind ! speed level is calculated by assuming the wind speed varies quadratically ! in height in the neighborhood of the maximum wind level. The other fields ! are interpolated linearly in height to the maximum wind level. ! The maximum wind level pressure is found hydrostatically. ! ! Program history log: ! 1999-10-18 Mark Iredell ! 2005-02-02 Mark Iredell changed upper limit to 100 mb ! ! Usage: call mxwind(km,p,u,v,t,h,pmw,umw,vmw,tmw,hmw) ! Input argument list: ! km integer number of levels ! p real (km) pressure (Pa) ! u real (km) x-component wind (m/s) ! v real (km) y-component wind (m/s) ! t real (km) temperature (K) ! h real (km) height (m) ! Output argument list: ! pmw real maximum wind level pressure (Pa) ! umw real maximum wind level x-component wind (m/s) ! vmw real maximum wind level y-component wind (m/s) ! tmw real maximum wind level temperature (K) ! hmw real maximum wind level height (m) ! ! Files included: ! physcons.h Physical constants ! ! Subprograms called: ! rsearch1 search for a surrounding real interval ! ! Attributes: ! Language: Fortran 90 ! !$$$ use physcons implicit none integer,intent(in):: km real,intent(in),dimension(km):: p,u,v,t,h real,intent(out):: pmw,umw,vmw,tmw,hmw real,parameter:: pmwlim(2)=(/500.e+2,100.e+2/) integer klim(2),k,kmw real spd(km),spdmw,wmw,dhd,dhu,shrd,shru,dhmw,ub,vb,spdb ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! find maximum wind level call rsearch1(km,p(1),2,pmwlim(1),klim(1)) klim(1)=klim(1)+1 spd(klim(1):klim(2))=sqrt(u(klim(1):klim(2))**2+v(klim(1):klim(2))**2) spdmw=spd(klim(1)) kmw=klim(1) do k=klim(1)+1,klim(2) if(spd(k).gt.spdmw) then spdmw=spd(k) kmw=k endif enddo ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! find speed and height at the maximum wind level if(kmw.eq.klim(1).or.kmw.eq.klim(2)) then hmw=h(kmw) spdmw=spd(kmw) wmw=0. else dhd=h(kmw)-h(kmw-1) dhu=h(kmw+1)-h(kmw) shrd=(spd(kmw)-spd(kmw-1))/(h(kmw)-h(kmw-1)) shru=(spd(kmw)-spd(kmw+1))/(h(kmw+1)-h(kmw)) dhmw=(shrd*dhu-shru*dhd)/(2*(shrd+shru)) hmw=h(kmw)+dhmw spdmw=spd(kmw)+dhmw**2*(shrd+shru)/(dhd+dhu) if(dhmw.gt.0) kmw=kmw+1 wmw=(h(kmw)-hmw)/(h(kmw)-h(kmw-1)) endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! compute maximum wind level fields ub=u(kmw)-wmw*(u(kmw)-u(kmw-1)) vb=v(kmw)-wmw*(v(kmw)-v(kmw-1)) spdb=max(sqrt(ub**2+vb**2),1.e-6) umw=ub*spdmw/spdb vmw=vb*spdmw/spdb tmw=t(kmw)-wmw*(t(kmw)-t(kmw-1)) pmw=p(kmw)*exp((h(kmw)-hmw)*(1-0.5*(tmw/t(kmw)-1))/(con_rog*t(kmw))) end subroutine ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine freeze(km,hs,p,t,h,rh,hfz1,rhfz1,hfz2,rhfz2) !$$$ Subprogram documentation block ! ! Subprogram: freeze Compute freezing level fields ! Prgmmr: Iredell Org: np23 Date: 2000-09-11 ! ! Abstract: This subprogram finds the lowest and highest freezing levels ! and interpolates the height and relative humidity to those levels. ! The freezing levels are the respectively the lowest and highest levels ! below 50 mb where temperature crosses the freezing point. ! Fields are interpolated linearly in temperature. ! If temperature is all below freezing, then the relative humidities ! are set to the bottom relative humidity and the heights are set ! to where the freezing level would be if the temperature is assumed ! to be increasing at a lapse rate of 6.5 K/km below the bottom level, ! with a minimum limit of 1 km below sea level. ! ! Program history log: ! 2000-09-11 Mark Iredell ! 2001-10-02 Mark Iredell Below ground algorithm changed ! ! Usage: call freeze(km,hs,p,t,h,rh,hfz1,rhfz1,hfz2,rhfz2) ! Input argument list: ! km integer number of levels ! hs real surface height (m) ! p real (km) pressure (Pa) ! t real (km) temperature (K) ! h real (km) height (m) ! rh real (km) relative humidity (percent) ! Output argument list: ! hfz1 real lowest freezing level height (m) ! rhfz1 real lowest freezing level relative humidity (percent) ! hfz2 real highest freezing level height (m) ! rhfz2 real highest freezing level relative humidity (percent) ! ! Files included: ! physcons.h Physical constants ! ! Subprograms called: ! rsearch1 search for a surrounding real interval ! ! Attributes: ! Language: Fortran 90 ! !$$$ use physcons implicit none integer,intent(in):: km real,intent(in):: hs real,intent(in),dimension(km):: p,t,h,rh real,intent(out):: hfz1,rhfz1,hfz2,rhfz2 real tc(km) real,parameter:: pfzlim=50.e+2,gammam=-6.5e-3,zfzlim=-1.e+3 integer klim,k,kfz1,kfz2 real wfz ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! find the lowest and highest freezing levels call rsearch1(km,p(1),1,pfzlim,klim) kfz1=klim+1 kfz2=1 do k=1,klim tc(k)=t(k)-con_t0c if(kfz1.gt.klim.and.tc(k).le.0) kfz1=k if(tc(k).gt.0) kfz2=k+1 enddo ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! interpolate fields to the lowest freezing level if(kfz1.eq.1) then hfz1=max(h(1)-tc(1)/gammam,zfzlim) rhfz1=rh(1) elseif(kfz1.eq.klim+1) then hfz1=h(klim) rhfz1=rh(klim) else wfz=-tc(kfz1)/(tc(kfz1-1)-tc(kfz1)) hfz1=h(kfz1)-wfz*(h(kfz1)-h(kfz1-1)) rhfz1=rh(kfz1)-wfz*(rh(kfz1)-rh(kfz1-1)) endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! interpolate fields to the highest freezing level if(kfz2.eq.1) then hfz2=max(h(1)-tc(1)/gammam,zfzlim) rhfz2=rh(1) elseif(kfz2.eq.klim+1) then hfz2=h(klim) rhfz2=rh(klim) else wfz=-tc(kfz2)/(tc(kfz2-1)-tc(kfz2)) hfz2=h(kfz2)-wfz*(h(kfz2)-h(kfz2-1)) rhfz2=rh(kfz2)-wfz*(rh(kfz2)-rh(kfz2-1)) endif end subroutine ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine liftix(ps,kpt,pt,tpt,shpt,km,p,t,sh,h,& sli,scape,scin,bli,bcape,bcin) !$$$ Subprogram documentation block ! ! Subprogram: liftix Compute lifting index, cape and cin ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram computes both surface and best lifting index, ! convective available potential energy and convective inhibition. ! The surface quantities result from lifting a parcel from a pressure ! layer at the surface. The so-called best quantities result from lifting ! the pressure layer parcel with the warmest equivalent potential temperature. ! The lifted index is the parcel temperature minus the environment temperature ! when lifted to 500 mb. The convective available potential energy (CAPE) ! and the convective inhibition (CIN) are found by integrating buoyant energy ! between the lifting condensation level and the highest buoyant level. ! The CAPE is the integral of the positively buoyant region and ! the CIN is the integral of the negatively buoyant region. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call liftix(ps,kpt,pt,tpt,shpt,km,p,t,sh,h,& ! sli,scape,scin,bli,bcape,bcin) ! Input argument list: ! ps real surface pressure (Pa) ! kpt integer number of pressure layers ! pt real (kpt) pressure layer edges above surface (Pa) ! tpt real (kpt) temperature (K) ! shpt real (kpt) specific humidity (kg/kg) ! km integer number of levels ! p real (km) pressure (Pa) ! t real (km) temperature (K) ! sh real (km) specific humidity (kg/kg) ! h real (km) height (m) ! Output argument list: ! sli real surface lifted index (K) ! scape real surface cape (J/kg) ! scin real surface cin (J/kg) ! bli real best lifted index (K) ! bcape real best cape (J/kg) ! bcin real best cin (J/kg) ! ! Modules used: ! funcphys Physical functions ! ! Files included: ! physcons.h Physical constants ! ! Subprograms called: ! rsearch1 search for a surrounding real interval ! ! Attributes: ! Language: Fortran 90 ! !$$$ use funcphys use physcons implicit none integer,intent(in):: kpt,km real,intent(in):: ps real,intent(in),dimension(kpt):: pt,tpt,shpt real,intent(in),dimension(km):: p,t,sh,h real,intent(out):: sli,scape,scin,bli,bcape,bcin real,parameter:: plift=500.e+2,ptop=40.e+2 integer k real(krealfp) pm,pv,tr,tdpd,tlcl,pklcl,thelcl,pkmas,themas,pkmab,themab real(krealfp) tlift,pliftr,pliftk,pks,pkb,tma,shma,pr,pk real pta(0:kpt),tvenv,gdz,tvcld ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! select the warmest equivalent potential temperature pta(0)=ps pta(1:kpt)=ps-pt do k=1,kpt pm=0.5*(pta(k-1)+pta(k)) pv=pm*shpt(k)/(con_eps-con_epsm1*shpt(k)) tr=tpt(k) tdpd=max(tr-ftdp(pv),0._krealfp) tlcl=ftlcl(tr,tdpd) pklcl=fpkap(pm)*tlcl/tr thelcl=fthe(tlcl,pklcl) if(k.eq.1) then pkmas=pklcl themas=thelcl pkmab=pklcl themab=thelcl elseif(thelcl.gt.themab) then pkmab=pklcl themab=thelcl endif enddo ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! lift the parcel to 500 mb along a dry adiabat below the lcl ! or along a moist adiabat above the lcl. ! the lifted index is the environment minus parcel temperature. call rsearch1(km,p(1),1,plift,k) if(k.gt.0.and.k.lt.km) then tlift=t(k)+log(p(k)/plift)/log(p(k)/p(k+1))*(t(k+1)-t(k)) pliftr=plift pliftk=fpkap(pliftr) pks=min(pliftk,pkmas) call stma(themas,pks,tma,shma) sli=tlift-tma*pliftk/pks pkb=min(pliftk,pkmab) call stma(themab,pkb,tma,shma) bli=tlift-tma*pliftk/pkb else sli=0. bli=0. endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! lift the parcel to its highest buoyant layer (below 40 mb). ! separately integrate between the lcl and this top layer ! positively buoyant area (cape) and negatively buoyant area (cin). scape=0. scin=0. bcape=0. bcin=0. do k=km-1,2,-1 if(p(k).gt.ptop) then pr=p(k) pk=fpkap(pr) tvenv=t(k)*(1.+con_fvirt*sh(k)) gdz=con_g*0.5*(h(k+1)-h(k-1)) if(pk.le.pkmas) then call stma(themas,pk,tma,shma) tvcld=tma*(1.+con_fvirt*shma) if(tvcld.gt.tvenv) then scape=scape+gdz*log(tvcld/tvenv) elseif(scape.gt.0.) then scin=scin+gdz*log(tvcld/tvenv) endif endif if(pk.le.pkmab) then call stma(themab,pk,tma,shma) tvcld=tma*(1.+con_fvirt*shma) if(tvcld.gt.tvenv) then bcape=bcape+gdz*log(tvcld/tvenv) elseif(bcape.gt.0.) then bcin=bcin+gdz*log(tvcld/tvenv) endif endif endif enddo end subroutine ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine flxcnv1(kpdsflxs,kpdsflxv,kpdsfoxs,kpdsfoxv) !$$$ Subprogram documentation block ! ! Subprogram: flxcnv1 Copy flux metadata ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram copies flux metadata from the input flux arrays ! to the output flux arrays. The metadata copied consist of words 13-16 ! of the integer PDS arrays, which refer to forecast hour information. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call flxcnv1(kpdsflxs,kpdsflxv,kpdsfoxs,kpdsfoxv) ! Input argument list: ! kpdsflxs integer (200,nflxs) input flux scalar metadata ! kpdsflxv integer (200,nflxv) input flux vector metadata ! Output argument list: ! kpdsfoxs integer (200,nfoxs) output flux scalar metadata ! kpdsfoxv integer (200,nfoxv) output flux vector metadata ! ! Modules used: ! postgp_module Shared data for postgp ! ! Attributes: ! Language: Fortran 90 ! !$$$ use postgp_module implicit none integer,intent(in):: kpdsflxs(200,nflxs),kpdsflxv(200,nflxv) integer,intent(out):: kpdsfoxs(200,nfoxs),kpdsfoxv(200,nfoxv) integer i ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - do i=13,16 kpdsfoxs(i,ifoxs_shtfl_sfc )=kpdsflxs(i,iflxs_shtfl_sfc ) kpdsfoxs(i,ifoxs_lhtfl_sfc )=kpdsflxs(i,iflxs_lhtfl_sfc ) kpdsfoxs(i,ifoxs_tmp_sfc )=kpdsflxs(i,iflxs_tmp_sfc ) kpdsfoxs(i,ifoxs_soilw_dlr_0_10 )=kpdsflxs(i,iflxs_soilw_dlr_0_10 ) kpdsfoxs(i,ifoxs_soilw_dlr_10_40 )=kpdsflxs(i,iflxs_soilw_dlr_10_40 ) kpdsfoxs(i,ifoxs_soilw_dlr_40_100 )=kpdsflxs(i,iflxs_soilw_dlr_40_100 ) kpdsfoxs(i,ifoxs_soilw_dlr_100_200 )=kpdsflxs(i,iflxs_soilw_dlr_100_200 ) kpdsfoxs(i,ifoxs_soilw_dlr_10_200 )=kpdsflxs(i,iflxs_soilw_dlr_10_200 ) kpdsfoxs(i,ifoxs_tmp_dlr_0_10 )=kpdsflxs(i,iflxs_tmp_dlr_0_10 ) kpdsfoxs(i,ifoxs_tmp_dlr_10_40 )=kpdsflxs(i,iflxs_tmp_dlr_10_40 ) kpdsfoxs(i,ifoxs_tmp_dlr_40_100 )=kpdsflxs(i,iflxs_tmp_dlr_40_100 ) kpdsfoxs(i,ifoxs_tmp_dlr_100_200 )=kpdsflxs(i,iflxs_tmp_dlr_100_200 ) kpdsfoxs(i,ifoxs_tmp_dlr_10_200 )=kpdsflxs(i,iflxs_tmp_dlr_10_200 ) kpdsfoxs(i,ifoxs_soill_dlr_0_10 )=kpdsflxs(i,iflxs_soill_dlr_0_10 ) kpdsfoxs(i,ifoxs_soill_dlr_10_40 )=kpdsflxs(i,iflxs_soill_dlr_10_40 ) kpdsfoxs(i,ifoxs_soill_dlr_40_100 )=kpdsflxs(i,iflxs_soill_dlr_40_100 ) kpdsfoxs(i,ifoxs_soill_dlr_100_200 )=kpdsflxs(i,iflxs_soill_dlr_100_200 ) kpdsfoxs(i,ifoxs_cnwat_sfc )=kpdsflxs(i,iflxs_cnwat_sfc ) kpdsfoxs(i,ifoxs_snod_sfc )=kpdsflxs(i,iflxs_snod_sfc ) kpdsfoxs(i,ifoxs_weasd_sfc )=kpdsflxs(i,iflxs_weasd_sfc ) kpdsfoxs(i,ifoxs_dlwrf_sfc )=kpdsflxs(i,iflxs_dlwrf_sfc ) kpdsfoxs(i,ifoxs_ulwrf_sfc )=kpdsflxs(i,iflxs_ulwrf_sfc ) kpdsfoxs(i,ifoxs_ulwrf_toa )=kpdsflxs(i,iflxs_ulwrf_toa ) kpdsfoxs(i,ifoxs_uswrf_toa )=kpdsflxs(i,iflxs_uswrf_toa ) kpdsfoxs(i,ifoxs_uswrf_sfc )=kpdsflxs(i,iflxs_uswrf_sfc ) kpdsfoxs(i,ifoxs_dswrf_sfc )=kpdsflxs(i,iflxs_dswrf_sfc ) kpdsfoxs(i,ifoxs_duvb_sfc )=kpdsflxs(i,iflxs_duvb_sfc ) kpdsfoxs(i,ifoxs_cduvb_sfc )=kpdsflxs(i,iflxs_cduvb_sfc ) kpdsfoxs(i,ifoxs_tcdc_hcl )=kpdsflxs(i,iflxs_tcdc_hcl ) kpdsfoxs(i,ifoxs_pres_hct )=kpdsflxs(i,iflxs_pres_hct ) kpdsfoxs(i,ifoxs_pres_hcb )=kpdsflxs(i,iflxs_pres_hcb ) kpdsfoxs(i,ifoxs_tmp_hct )=kpdsflxs(i,iflxs_tmp_hct ) kpdsfoxs(i,ifoxs_tcdc_mcl )=kpdsflxs(i,iflxs_tcdc_mcl ) kpdsfoxs(i,ifoxs_pres_mct )=kpdsflxs(i,iflxs_pres_mct ) kpdsfoxs(i,ifoxs_pres_mcb )=kpdsflxs(i,iflxs_pres_mcb ) kpdsfoxs(i,ifoxs_tmp_mct )=kpdsflxs(i,iflxs_tmp_mct ) kpdsfoxs(i,ifoxs_tcdc_lcl )=kpdsflxs(i,iflxs_tcdc_lcl ) kpdsfoxs(i,ifoxs_pres_lct )=kpdsflxs(i,iflxs_pres_lct ) kpdsfoxs(i,ifoxs_pres_lcb )=kpdsflxs(i,iflxs_pres_lcb ) kpdsfoxs(i,ifoxs_tmp_lct )=kpdsflxs(i,iflxs_tmp_lct ) kpdsfoxs(i,ifoxs_prate_sfc )=kpdsflxs(i,iflxs_prate_sfc ) kpdsfoxs(i,ifoxs_cprat_sfc )=kpdsflxs(i,iflxs_cprat_sfc ) kpdsfoxs(i,ifoxs_gflux_sfc )=kpdsflxs(i,iflxs_gflux_sfc ) kpdsfoxs(i,ifoxs_land_sfc )=kpdsflxs(i,iflxs_land_sfc ) kpdsfoxs(i,ifoxs_icec_sfc )=kpdsflxs(i,iflxs_icec_sfc ) kpdsfoxs(i,ifoxs_icetk_sfc )=kpdsflxs(i,iflxs_icetk_sfc ) kpdsfoxs(i,ifoxs_tmp_hag_2 )=kpdsflxs(i,iflxs_tmp_hag_2 ) kpdsfoxs(i,ifoxs_spfh_hag_2 )=kpdsflxs(i,iflxs_spfh_hag_2 ) kpdsfoxs(i,ifoxs_tmax_hag_2 )=kpdsflxs(i,iflxs_tmax_hag_2 ) kpdsfoxs(i,ifoxs_tmin_hag_2 )=kpdsflxs(i,iflxs_tmin_hag_2 ) kpdsfoxs(i,ifoxs_watr_sfc )=kpdsflxs(i,iflxs_watr_sfc ) kpdsfoxs(i,ifoxs_pevpr_sfc )=kpdsflxs(i,iflxs_pevpr_sfc ) kpdsfoxs(i,ifoxs_cwork_clm )=kpdsflxs(i,iflxs_cwork_clm ) kpdsfoxs(i,ifoxs_hpbl_sfc )=kpdsflxs(i,iflxs_hpbl_sfc ) kpdsfoxs(i,ifoxs_albdo_sfc )=kpdsflxs(i,iflxs_albdo_sfc ) kpdsfoxs(i,ifoxs_tcdc_clm )=kpdsflxs(i,iflxs_tcdc_clm ) kpdsfoxs(i,ifoxs_tcdc_cvc )=kpdsflxs(i,iflxs_tcdc_cvc ) kpdsfoxs(i,ifoxs_pres_cvt )=kpdsflxs(i,iflxs_pres_cvt ) kpdsfoxs(i,ifoxs_pres_cvb )=kpdsflxs(i,iflxs_pres_cvb ) kpdsfoxs(i,ifoxs_tcdc_blc )=kpdsflxs(i,iflxs_tcdc_blc ) kpdsfoxs(i,ifoxs_apcp_sfc )=kpdsflxs(i,iflxs_prate_sfc ) kpdsfoxs(i,ifoxs_acpcp_sfc )=kpdsflxs(i,iflxs_cprat_sfc ) kpdsfoxs(i,ifoxs_crain_sfc )=kpdsflxs(i,iflxs_prate_sfc ) kpdsfoxs(i,ifoxs_cfrzr_sfc )=kpdsflxs(i,iflxs_prate_sfc ) kpdsfoxs(i,ifoxs_cicep_sfc )=kpdsflxs(i,iflxs_prate_sfc ) kpdsfoxs(i,ifoxs_csnow_sfc )=kpdsflxs(i,iflxs_prate_sfc ) kpdsfoxs(i,ifoxs_rh_hag_2 )=kpdsflxs(i,iflxs_tmp_hag_2 ) kpdsfoxv(i,ifoxu_uflx_sfc )=kpdsflxv(i,iflxu_uflx_sfc ) kpdsfoxv(i,ifoxu_ugrd_hag_10 )=kpdsflxv(i,iflxu_ugrd_hag_10 ) kpdsfoxv(i,ifoxu_ugwd_sfc )=kpdsflxv(i,iflxu_ugwd_sfc ) enddo kpdsfoxs(16,ifoxs_apcp_sfc )=4 kpdsfoxs(16,ifoxs_acpcp_sfc )=4 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end subroutine ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine flxcnv(hrflx,lflxs,lflxv,fflxs,fflxu,fflxv,iwx,& kpdsfoxs,kpdsfoxv,lfoxs,lfoxv,ffoxs,ffoxu,ffoxv) !$$$ Subprogram documentation block ! ! Subprogram: flxcnv Copy flux data ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram copies flux data from the input flux arrays ! to the output flux arrays. The accumulated precipitation fields are ! computed from the average precipitation rate fields. The categorical ! precipitation types are decoded. The 2-meter relative humidity is computed. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call flxcnv(hrflx,lflxs,lflxv,fflxs,fflxu,fflxv,iwx,& ! kpdsfoxs,kpdsfoxv,lfoxs,lfoxv,ffoxs,ffoxu,ffoxv) ! Input argument list: ! hrflx real number of hours flux over which fields are averaged ! lflxs logical*1 (nflxs) input scalar bitmap ! lflxv logical*1 (nflxv) input vector bitmap ! fflxs real (nflxs) input scalar data ! fflxu real (nflxv) input vector x-component data ! fflxv real (nflxv) input vector y-component data ! iwx integer encoded categorical precipitation type ! kpdsfoxs integer (200,nfoxs) output flux scalar metadata ! kpdsfoxv integer (200,nfoxv) output flux vector metadata ! Output argument list: ! lfoxs logical*1 (nfoxs) output scalar bitmap ! lfoxv logical*1 (nfoxv) output vector bitmap ! ffoxs real (nfoxs) output scalar data ! ffoxu real (nfoxv) output vector x-component data ! ffoxv real (nfoxv) output vector y-component data ! ! Modules used: ! postgp_module Shared data for postgp ! funcphys Physical functions ! ! Files included: ! physcons.h Physical constants ! ! Attributes: ! Language: Fortran 90 ! !$$$ use postgp_module use funcphys use physcons implicit none real,intent(in):: hrflx logical*1,intent(in):: lflxs(nflxs),lflxv(nflxv) real,intent(in):: fflxs(nflxs),fflxu(nflxv),fflxv(nflxv) integer,intent(in):: iwx integer,intent(in):: kpdsfoxs(200,nfoxs),kpdsfoxv(200,nfoxv) logical*1,intent(out):: lfoxs(nfoxs),lfoxv(nfoxv) real,intent(out):: ffoxs(nfoxs),ffoxu(nfoxv),ffoxv(nfoxv) integer n real t2,q2,ps,p2,pvs2,qs2 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Copy bitmaps. lfoxs(ifoxs_shtfl_sfc )=lflxs(iflxs_shtfl_sfc ) lfoxs(ifoxs_lhtfl_sfc )=lflxs(iflxs_lhtfl_sfc ) lfoxs(ifoxs_tmp_sfc )=lflxs(iflxs_tmp_sfc ) lfoxs(ifoxs_soilw_dlr_0_10 )=lflxs(iflxs_soilw_dlr_0_10 ) lfoxs(ifoxs_soilw_dlr_10_40 )=lflxs(iflxs_soilw_dlr_10_40 ) lfoxs(ifoxs_soilw_dlr_40_100 )=lflxs(iflxs_soilw_dlr_40_100 ) lfoxs(ifoxs_soilw_dlr_100_200 )=lflxs(iflxs_soilw_dlr_100_200 ) lfoxs(ifoxs_soilw_dlr_10_200 )=lflxs(iflxs_soilw_dlr_10_200 ) lfoxs(ifoxs_tmp_dlr_0_10 )=lflxs(iflxs_tmp_dlr_0_10 ) lfoxs(ifoxs_tmp_dlr_10_40 )=lflxs(iflxs_tmp_dlr_10_40 ) lfoxs(ifoxs_tmp_dlr_40_100 )=lflxs(iflxs_tmp_dlr_40_100 ) lfoxs(ifoxs_tmp_dlr_100_200 )=lflxs(iflxs_tmp_dlr_100_200 ) lfoxs(ifoxs_tmp_dlr_10_200 )=lflxs(iflxs_tmp_dlr_10_200 ) lfoxs(ifoxs_soill_dlr_0_10 )=lflxs(iflxs_soill_dlr_0_10 ) lfoxs(ifoxs_soill_dlr_10_40 )=lflxs(iflxs_soill_dlr_10_40 ) lfoxs(ifoxs_soill_dlr_40_100 )=lflxs(iflxs_soill_dlr_40_100 ) lfoxs(ifoxs_soill_dlr_100_200 )=lflxs(iflxs_soill_dlr_100_200 ) lfoxs(ifoxs_cnwat_sfc )=lflxs(iflxs_cnwat_sfc ) lfoxs(ifoxs_snod_sfc )=lflxs(iflxs_snod_sfc ) lfoxs(ifoxs_weasd_sfc )=lflxs(iflxs_weasd_sfc ) lfoxs(ifoxs_dlwrf_sfc )=lflxs(iflxs_dlwrf_sfc ) lfoxs(ifoxs_ulwrf_sfc )=lflxs(iflxs_ulwrf_sfc ) lfoxs(ifoxs_ulwrf_toa )=lflxs(iflxs_ulwrf_toa ) lfoxs(ifoxs_uswrf_toa )=lflxs(iflxs_uswrf_toa ) lfoxs(ifoxs_uswrf_sfc )=lflxs(iflxs_uswrf_sfc ) lfoxs(ifoxs_dswrf_sfc )=lflxs(iflxs_dswrf_sfc ) lfoxs(ifoxs_duvb_sfc )=lflxs(iflxs_duvb_sfc ) lfoxs(ifoxs_cduvb_sfc )=lflxs(iflxs_cduvb_sfc ) lfoxs(ifoxs_tcdc_hcl )=lflxs(iflxs_tcdc_hcl ) lfoxs(ifoxs_pres_hct )=lflxs(iflxs_pres_hct ) lfoxs(ifoxs_pres_hcb )=lflxs(iflxs_pres_hcb ) lfoxs(ifoxs_tmp_hct )=lflxs(iflxs_tmp_hct ) lfoxs(ifoxs_tcdc_mcl )=lflxs(iflxs_tcdc_mcl ) lfoxs(ifoxs_pres_mct )=lflxs(iflxs_pres_mct ) lfoxs(ifoxs_pres_mcb )=lflxs(iflxs_pres_mcb ) lfoxs(ifoxs_tmp_mct )=lflxs(iflxs_tmp_mct ) lfoxs(ifoxs_tcdc_lcl )=lflxs(iflxs_tcdc_lcl ) lfoxs(ifoxs_pres_lct )=lflxs(iflxs_pres_lct ) lfoxs(ifoxs_pres_lcb )=lflxs(iflxs_pres_lcb ) lfoxs(ifoxs_tmp_lct )=lflxs(iflxs_tmp_lct ) lfoxs(ifoxs_prate_sfc )=lflxs(iflxs_prate_sfc ) lfoxs(ifoxs_cprat_sfc )=lflxs(iflxs_cprat_sfc ) lfoxs(ifoxs_gflux_sfc )=lflxs(iflxs_gflux_sfc ) lfoxs(ifoxs_land_sfc )=lflxs(iflxs_land_sfc ) lfoxs(ifoxs_icec_sfc )=lflxs(iflxs_icec_sfc ) lfoxs(ifoxs_icetk_sfc )=lflxs(iflxs_icetk_sfc ) lfoxs(ifoxs_tmp_hag_2 )=lflxs(iflxs_tmp_hag_2 ) lfoxs(ifoxs_spfh_hag_2 )=lflxs(iflxs_spfh_hag_2 ) lfoxs(ifoxs_tmax_hag_2 )=lflxs(iflxs_tmax_hag_2 ) lfoxs(ifoxs_tmin_hag_2 )=lflxs(iflxs_tmin_hag_2 ) lfoxs(ifoxs_watr_sfc )=lflxs(iflxs_watr_sfc ) lfoxs(ifoxs_pevpr_sfc )=lflxs(iflxs_pevpr_sfc ) lfoxs(ifoxs_cwork_clm )=lflxs(iflxs_cwork_clm ) lfoxs(ifoxs_hpbl_sfc )=lflxs(iflxs_hpbl_sfc ) lfoxs(ifoxs_albdo_sfc )=lflxs(iflxs_albdo_sfc ) lfoxs(ifoxs_tcdc_clm )=lflxs(iflxs_tcdc_clm ) lfoxs(ifoxs_tcdc_cvc )=lflxs(iflxs_tcdc_cvc ) lfoxs(ifoxs_pres_cvt )=lflxs(iflxs_pres_cvt ) lfoxs(ifoxs_pres_cvb )=lflxs(iflxs_pres_cvb ) lfoxs(ifoxs_tcdc_blc )=lflxs(iflxs_tcdc_blc ) lfoxs(ifoxs_apcp_sfc )=lflxs(iflxs_prate_sfc ) lfoxs(ifoxs_acpcp_sfc )=lflxs(iflxs_cprat_sfc ) lfoxs(ifoxs_crain_sfc )=lflxs(iflxs_prate_sfc ) lfoxs(ifoxs_cfrzr_sfc )=lflxs(iflxs_prate_sfc ) lfoxs(ifoxs_cicep_sfc )=lflxs(iflxs_prate_sfc ) lfoxs(ifoxs_csnow_sfc )=lflxs(iflxs_prate_sfc ) lfoxs(ifoxs_rh_hag_2 )=lflxs(iflxs_tmp_hag_2 ).and.& lflxs(iflxs_spfh_hag_2 ).and.& lflxs(iflxs_pres_sfc ) lfoxv(ifoxu_uflx_sfc )=lflxv(iflxu_uflx_sfc ) lfoxv(ifoxu_ugrd_hag_10 )=lflxv(iflxu_ugrd_hag_10 ) lfoxv(ifoxu_ugwd_sfc )=lflxv(iflxu_ugwd_sfc ) do n=1,nfoxs if(kpdsfoxs(16,n).ge.2.and.kpdsfoxs(16,n).le.5.and.hrflx.le.0) then lfoxs(n)=.false. endif enddo do n=1,nfoxv if(kpdsfoxv(16,n).ge.2.and.kpdsfoxv(16,n).le.5.and.hrflx.le.0) then lfoxv(n)=.false. endif enddo ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Copy scalar data. ffoxs(ifoxs_shtfl_sfc )=fflxs(iflxs_shtfl_sfc ) ffoxs(ifoxs_lhtfl_sfc )=fflxs(iflxs_lhtfl_sfc ) ffoxs(ifoxs_tmp_sfc )=fflxs(iflxs_tmp_sfc ) ffoxs(ifoxs_soilw_dlr_0_10 )=fflxs(iflxs_soilw_dlr_0_10 ) ffoxs(ifoxs_soilw_dlr_10_40 )=fflxs(iflxs_soilw_dlr_10_40 ) ffoxs(ifoxs_soilw_dlr_40_100 )=fflxs(iflxs_soilw_dlr_40_100 ) ffoxs(ifoxs_soilw_dlr_100_200 )=fflxs(iflxs_soilw_dlr_100_200 ) ffoxs(ifoxs_soilw_dlr_10_200 )=fflxs(iflxs_soilw_dlr_10_200 ) ffoxs(ifoxs_tmp_dlr_0_10 )=fflxs(iflxs_tmp_dlr_0_10 ) ffoxs(ifoxs_tmp_dlr_10_40 )=fflxs(iflxs_tmp_dlr_10_40 ) ffoxs(ifoxs_tmp_dlr_40_100 )=fflxs(iflxs_tmp_dlr_40_100 ) ffoxs(ifoxs_tmp_dlr_100_200 )=fflxs(iflxs_tmp_dlr_100_200 ) ffoxs(ifoxs_tmp_dlr_10_200 )=fflxs(iflxs_tmp_dlr_10_200 ) ffoxs(ifoxs_soill_dlr_0_10 )=fflxs(iflxs_soill_dlr_0_10 ) ffoxs(ifoxs_soill_dlr_10_40 )=fflxs(iflxs_soill_dlr_10_40 ) ffoxs(ifoxs_soill_dlr_40_100 )=fflxs(iflxs_soill_dlr_40_100 ) ffoxs(ifoxs_soill_dlr_100_200 )=fflxs(iflxs_soill_dlr_100_200 ) ffoxs(ifoxs_cnwat_sfc )=fflxs(iflxs_cnwat_sfc ) ffoxs(ifoxs_snod_sfc )=fflxs(iflxs_snod_sfc ) ffoxs(ifoxs_weasd_sfc )=fflxs(iflxs_weasd_sfc ) ffoxs(ifoxs_dlwrf_sfc )=fflxs(iflxs_dlwrf_sfc ) ffoxs(ifoxs_ulwrf_sfc )=fflxs(iflxs_ulwrf_sfc ) ffoxs(ifoxs_ulwrf_toa )=fflxs(iflxs_ulwrf_toa ) ffoxs(ifoxs_uswrf_toa )=fflxs(iflxs_uswrf_toa ) ffoxs(ifoxs_uswrf_sfc )=fflxs(iflxs_uswrf_sfc ) ffoxs(ifoxs_dswrf_sfc )=fflxs(iflxs_dswrf_sfc ) ffoxs(ifoxs_duvb_sfc )=fflxs(iflxs_duvb_sfc ) ffoxs(ifoxs_cduvb_sfc )=fflxs(iflxs_cduvb_sfc ) ffoxs(ifoxs_tcdc_hcl )=fflxs(iflxs_tcdc_hcl ) ffoxs(ifoxs_pres_hct )=fflxs(iflxs_pres_hct ) ffoxs(ifoxs_pres_hcb )=fflxs(iflxs_pres_hcb ) ffoxs(ifoxs_tmp_hct )=fflxs(iflxs_tmp_hct ) ffoxs(ifoxs_tcdc_mcl )=fflxs(iflxs_tcdc_mcl ) ffoxs(ifoxs_pres_mct )=fflxs(iflxs_pres_mct ) ffoxs(ifoxs_pres_mcb )=fflxs(iflxs_pres_mcb ) ffoxs(ifoxs_tmp_mct )=fflxs(iflxs_tmp_mct ) ffoxs(ifoxs_tcdc_lcl )=fflxs(iflxs_tcdc_lcl ) ffoxs(ifoxs_pres_lct )=fflxs(iflxs_pres_lct ) ffoxs(ifoxs_pres_lcb )=fflxs(iflxs_pres_lcb ) ffoxs(ifoxs_tmp_lct )=fflxs(iflxs_tmp_lct ) ffoxs(ifoxs_prate_sfc )=fflxs(iflxs_prate_sfc ) ffoxs(ifoxs_cprat_sfc )=fflxs(iflxs_cprat_sfc ) ffoxs(ifoxs_gflux_sfc )=fflxs(iflxs_gflux_sfc ) ffoxs(ifoxs_land_sfc )=fflxs(iflxs_land_sfc ) ffoxs(ifoxs_icec_sfc )=fflxs(iflxs_icec_sfc ) ffoxs(ifoxs_icetk_sfc )=fflxs(iflxs_icetk_sfc ) ffoxs(ifoxs_tmp_hag_2 )=fflxs(iflxs_tmp_hag_2 ) ffoxs(ifoxs_spfh_hag_2 )=fflxs(iflxs_spfh_hag_2 ) ffoxs(ifoxs_tmax_hag_2 )=fflxs(iflxs_tmax_hag_2 ) ffoxs(ifoxs_tmin_hag_2 )=fflxs(iflxs_tmin_hag_2 ) ffoxs(ifoxs_watr_sfc )=fflxs(iflxs_watr_sfc ) ffoxs(ifoxs_pevpr_sfc )=fflxs(iflxs_pevpr_sfc ) ffoxs(ifoxs_cwork_clm )=fflxs(iflxs_cwork_clm ) ffoxs(ifoxs_hpbl_sfc )=fflxs(iflxs_hpbl_sfc ) ffoxs(ifoxs_albdo_sfc )=fflxs(iflxs_albdo_sfc ) ffoxs(ifoxs_tcdc_clm )=fflxs(iflxs_tcdc_clm ) ffoxs(ifoxs_tcdc_cvc )=fflxs(iflxs_tcdc_cvc ) ffoxs(ifoxs_pres_cvt )=fflxs(iflxs_pres_cvt ) ffoxs(ifoxs_pres_cvb )=fflxs(iflxs_pres_cvb ) ffoxs(ifoxs_tcdc_blc )=fflxs(iflxs_tcdc_blc ) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Compute accumulated precipitation and categorical precipitation types. ffoxs(ifoxs_apcp_sfc )=3600*hrflx*fflxs(iflxs_prate_sfc ) ffoxs(ifoxs_acpcp_sfc )=3600*hrflx*fflxs(iflxs_cprat_sfc ) ffoxs(ifoxs_crain_sfc )=mod(iwx/8,2) ffoxs(ifoxs_cfrzr_sfc )=mod(iwx/4,2) ffoxs(ifoxs_cicep_sfc )=mod(iwx/2,2) ffoxs(ifoxs_csnow_sfc )=mod(iwx/1,2) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Compute 2-meter relative humidity. if(lfoxs(ifoxs_rh_hag_2 )) then t2=fflxs(iflxs_tmp_hag_2 ) q2=fflxs(iflxs_spfh_hag_2 ) ps=fflxs(iflxs_pres_sfc ) p2=ps*(1.-2./con_rog/t2) pvs2=fpvs(real(t2,krealfp)) qs2=con_eps*pvs2/(p2+con_epsm1*pvs2) ffoxs(ifoxs_rh_hag_2 )=1.e2*min(max(q2/qs2,0.),1.) endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Copy vector data. ffoxu(ifoxu_uflx_sfc )=fflxu(iflxu_uflx_sfc ) ffoxv(ifoxv_vflx_sfc )=fflxv(iflxv_vflx_sfc ) ffoxu(ifoxu_ugrd_hag_10 )=fflxu(iflxu_ugrd_hag_10 ) ffoxv(ifoxv_vgrd_hag_10 )=fflxv(iflxv_vgrd_hag_10 ) ffoxu(ifoxu_ugwd_sfc )=fflxu(iflxu_ugwd_sfc ) ffoxv(ifoxv_vgwd_sfc )=fflxv(iflxv_vgwd_sfc ) end subroutine ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - subroutine calwxt1(lm,prec,t,q,p,pint,iwx) !$$$ Subprogram documentation block ! ! Subprogram: calwxt1 Compute precipitation type ! Prgmmr: Baldwin Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram computes precipitation type using ! a decision tree approach that uses variables ! such as integrated wet bulb temperature below freezing ! and lowest layer temperature. ! For more details, see Baldwin and Contorno preprint ! from 13th Weather Analysis and Forecasting Conference ! (or Baldwin et al. 10th NWP Conference preprint). ! ! Program history log: ! 1993-11-11 Baldwin ! 1994-09-30 Baldwin set up new decision tree ! 1995-03-27 Iredell modularized and vectorized ! 1999-10-18 Mark Iredell fortran 90 ! ! Usage: call calwxt1(lm,prec,t,q,p,pint,iwx) ! Input argument list: ! lm integer number of levels in this profile ! prec real precipitation (mm?) ! t real (lm) temperature (from top) (k) ! q real (lm) specific humidity (from top) (kg/kg) ! p real (lm) pressure (from top) (pa) ! pint real (lm+1) interface pressure (from top) (pa) ! output arguments: ! iwx integer instantaneous weather type ! (the one's digit is for snow; ! the two's digit is for ice pellets; ! the four's digit is for freezing rain; ! the eight's digit is for rain.) ! ! Modules used: ! funcphys Physical functions ! ! Files included: ! physcons.h Physical constants ! ! Subprograms called: ! (ftdp) compute dewpoint temperature ! (ftcl) compute lcl temperature ! (fthe) compute equivalent potential temperature ! (ftma) compute moist adiabat temperature ! ! Remarks: Weather type is only computed where there is precipitation. ! All profiles must start at the top and go down. ! For efficiency, inline all function calls. ! ! Attributes: ! Language: Fortran 90 ! !$$$ use funcphys use physcons implicit none integer,intent(in):: lm real,intent(in):: prec,t(lm),q(lm),p(lm),pint(lm+1) integer,intent(out):: iwx integer lice,l,l150,lfrz,lwrm,lone real tcold,twarm,tdchk real psm150,tv,dz150,surfw,surfc real dz(lm) real(krealfp) pv,pr,tdpd,tr,pk,tlcl,thelcl,twet(lm),qwet,areap4,areas8 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Initialize the weather type. iwx=0 ! If there is precipitation, find the coldest and warmest temperatures ! in the saturated layer between 70 mb above ground and 500 mb. ! Also find highest saturated layer in that range. if(prec.gt.0.) then tcold=t(lm) twarm=t(lm) lice=lm tdchk=2. ! Try to find first 2 then 4 then 6 degree dewpoint depressions. do while(tcold.eq.t(lm).and.tdchk.le.6) do l=1,lm if(p(l).ge.500.e2.and.p(l).le.pint(lm+1)-70.e2) then pv=p(l)*q(l)/(con_eps-con_epsm1*q(l)) tdpd=t(l)-ftdp(pv) if(tdpd.lt.tdchk) then tcold=min(tcold,t(l)) twarm=max(twarm,t(l)) lice=min(lice,l) endif endif enddo tdchk=tdchk+2 enddo ! Decide weather type if there is no cold saturated air. if(tcold.gt.con_t0c-4) then ! Decide freezing rain if the surface is cold. if(t(lm).lt.con_t0c) then iwx=iwx+4 ! Otherwise decide rain. else iwx=iwx+8 endif ! If there is cold saturated air, then find lowest 150 mb level ! and the lowest freezing level and warm level. else psm150=pint(lm)-150.e2 l150=1 lfrz=1 lwrm=1 do l=1,lm if(pint(l+1).le.psm150) l150=l+1 if(t(l).lt.con_t0c) lfrz=l+1 if(t(l).ge.twarm) lwrm=l+1 enddo ! Compute layer thickness and wet bulb temperature where needed. lone=min(lice,l150,lfrz,lwrm) do l=lone,lm if(pint(l).gt.0) then tv=t(l)*(1+con_fvirt*q(l)) dz(l)=con_rog*tv*log(pint(l+1)/pint(l)) else dz(l)=0 endif pv=p(l)*q(l)/(con_eps-con_epsm1*q(l)) tdpd=t(l)-ftdp(pv) if(tdpd.gt.0.) then pr=p(l) tr=t(l) pk=fpkap(pr) tlcl=ftlcl(tr,tdpd) thelcl=fthe(tlcl,pk*tlcl/tr) call stma(thelcl,pk,twet(l),qwet) else twet(l)=t(l) endif enddo ! Integrate area of twet above -4c below highest saturated layer. areap4=0 do l=lice,lm if(twet(l).gt.con_t0c-4) then areap4=areap4+(twet(l)-(con_t0c-4))*dz(l) endif enddo ! Decide snow if there is scarce warm air. if(areap4.lt.3000.) then iwx=iwx+1 else ! Otherwise integrate net area of twet w.r.t. 0c in lowest 150 mb. l=l150 tv=t(l)*(1+con_fvirt*q(l)) dz150=con_rog*tv*log(pint(l+1)/psm150) areas8=(twet(l)-con_t0c)*dz150 do l=l150+1,lm areas8=areas8+(twet(l)-con_t0c)*dz(l) enddo ! Integrate area of twet above 0c below the freezing level. surfw=0 do l=lfrz,lm if(twet(l).gt.con_t0c) then surfw=surfw+(twet(l)-con_t0c)*dz(l) endif enddo ! Integrate area of twet below 0c below the warmest saturated level. surfc=0 do l=lwrm,lm if(twet(l).lt.con_t0c) then surfc=surfc+(twet(l)-con_t0c)*dz(l) endif enddo ! Decide ice pellets if there is yet plenty of cold air. if(surfc.lt.-3000..or.(areas8.lt.-3000..and.surfw.lt.50.)) then iwx=iwx+2 else ! Otherwise decide freezing rain if the surface is cold. if(t(lm).lt.con_t0c) then iwx=iwx+4 ! Otherwise decide rain. else iwx=iwx+8 endif endif endif endif endif end subroutine ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end subroutine !------------------------------------------------------------------------------- subroutine rsearch1(km1,z1,km2,z2,l2) !$$$ subprogram documentation block ! ! subprogram: rsearch1 search for a surrounding real interval ! prgmmr: iredell org: w/nmc23 date: 98-05-01 ! ! abstract: this subprogram searches a monotonic sequences of real numbers ! for intervals that surround a given search set of real numbers. ! the sequences may be monotonic in either direction; the real numbers ! may be single or double precision. ! ! program history log: ! 1999-01-05 mark iredell ! 2013-01-09 mark iredell vanilla ! ! usage: call rsearch1(km1,z1,km2,z2,l2) ! input argument list: ! km1 integer number of points in the sequence ! z1 real (km1) sequence values to search ! (z1 must be monotonic in either direction) ! km2 integer number of points to search for ! z2 real (km2) set of values to search for ! (z2 need not be monotonic) ! ! output argument list: ! l2 integer (km2) interval locations from 0 to km1 ! (z2 will be between z1(l2) and z1(l2+1)) ! ! remarks: ! returned values of 0 or km1 indicate that the given search value ! is outside the range of the sequence. ! ! if a search value is identical to one of the sequence values ! then the location returned points to the identical value. ! if the sequence is not strictly monotonic and a search value is ! identical to more than one of the sequence values, then the ! location returned may point to any of the identical values. ! ! if l2(k)=0, then z2(k) is less than the start point z1(1) ! for ascending sequences (or greater than for descending sequences). ! if l2(k)=km1, then z2(k) is greater than or equal to the end point ! z1(km1) for ascending sequences (or less than or equal to for ! descending sequences). otherwise z2(k) is between the values ! z1(l2(k)) and z1(l2(k+1)) and may equal the former. ! ! attributes: ! language: fortran ! !$$$ implicit none integer,intent(in):: km1,km2 real,intent(in):: z1(km1),z2(km2) integer,intent(out):: l2(km2) integer k1,k2 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! find the surrounding input interval for each output point. if(z1(1)<z1(km1)) then ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! input coordinate is monotonically ascending. do k2=1,km2 l2(k2)=km1 do k1=1,km1 if(z2(k2)<z1(k1)) then l2(k2)=k1-1 exit endif enddo enddo else ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! input coordinate is monotonically descending. do k2=1,km2 l2(k2)=km1 do k1=1,km1 if(z2(k2)>z1(k1)) then l2(k2)=k1-1 exit endif enddo enddo endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end subroutine !------------------------------------------------------------------------------- subroutine postx(id,im,jm,km,mt,mw,mta,mwa,fpos,fpou,fpov) !$$$ Subprogram documentation block ! ! Subprogram: postx Post subprogram to filter horizontally ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram horizontally filters pressure level posted fields. ! The filtering is done in spectral space. The filtering need not be a ! straight spectral truncation, however, but can gradually filter over ! a finite width in spectral space, which should ameliorate Gibbsing. ! Also calculated are absolute vorticity and five-wave geopotential height. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call postx(id,im,jm,km,mt,mw,mta,mwa,fpos,fpou,fpov) ! Input argument list: ! id integer data representation type ! im integer number of longitudes ! jm integer number of latitudes ! mt integer smoothing truncation ! mw integer smoothing width ! mta integer smoothing truncation for absolute vorticity ! mwa integer smoothing width for absolute vorticity ! fpos real (im,jm,km,npos) scalar fields ! fpou real (im,jm,km,npov) vector x-component fields ! fpov real (im,jm,km,npov) vector y-component fields ! Output argument list: ! fpos real (im,jm,km,npos) scalar fields ! fpou real (im,jm,km,npov) vector x-component fields ! fpov real (im,jm,km,npov) vector y-component fields ! ! Modules used: ! postgp_module Shared data for postgp ! ! Files included: ! physcons.h Physical constants ! ! Subprograms called: ! sptezm multiple scalar spectral transform ! sptezmv multiple vector spectral transform ! ! Attributes: ! Language: Fortran 90 ! !$$$ use postgp_module use physcons implicit none integer,intent(in):: id,im,jm,km,mt,mw,mta,mwa real,intent(inout):: fpos(im,jm,km,npos) real,intent(inout):: fpou(im,jm,km,npov),fpov(im,jm,km,npov) real s((mt+mw/2+1)*(mt+mw/2+2),km,7) integer mx,k,i,l,n real fac ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Transform to spectral mx=mt+mw/2 call sptezm(0,mx,id,im,jm,km,s(1,1,1),fpos(1,1,1,ipos_hgt_prs),-1) call sptezmv(0,mx,id,im,jm,km,s(1,1,2),s(1,1,3),& fpou(1,1,1,ipou_ugrd_prs),fpov(1,1,1,ipov_vgrd_prs),-1) call sptezm(0,mx,id,im,jm,km,s(1,1,4),fpos(1,1,1,ipos_tmp_prs),-1) call sptezm(0,mx,id,im,jm,km,s(1,1,5),fpos(1,1,1,ipos_vvel_prs),-1) !omp$ parallel do private(i,fac) do k=1,km i=0 do l=0,mx do n=l,mx ! Compute five-wave geopotential height ! if(n.le.5) then ! triangular 5 ! if(l.le.5.and.n-l.le.5) then ! rhomboidal 5 if(l.le.5) then ! zonal-wave 5 s(i+1,k,6)=s(i+1,k,1) s(i+2,k,6)=s(i+2,k,1) else s(i+1,k,6)=0. s(i+2,k,6)=0. endif ! Compute relative vorticity if(n.gt.mta-mwa/2) then fac=0. if(mwa.gt.0) fac=min(max(0.5+(mta-n)/float(mwa),0.),1.) s(i+1,k,7)=fac*s(i+1,k,3) s(i+2,k,7)=fac*s(i+2,k,3) else s(i+1,k,7)=s(i+1,k,3) s(i+2,k,7)=s(i+2,k,3) endif ! Filter other fields if(n.gt.mt-mw/2) then fac=0. if(mw.gt.0) fac=min(max(0.5+(mt-n)/float(mw),0.),1.) s(i+1,k,1)=fac*s(i+1,k,1) s(i+2,k,1)=fac*s(i+2,k,1) s(i+1,k,2)=fac*s(i+1,k,2) s(i+2,k,2)=fac*s(i+2,k,2) s(i+1,k,3)=fac*s(i+1,k,3) s(i+2,k,3)=fac*s(i+2,k,3) s(i+1,k,4)=fac*s(i+1,k,4) s(i+2,k,4)=fac*s(i+2,k,4) s(i+1,k,5)=fac*s(i+1,k,5) s(i+2,k,5)=fac*s(i+2,k,5) endif i=i+2 enddo enddo ! Add planetary vorticity to get absolute vorticity s(3,k,7)=s(3,k,7)+2*con_omega/sqrt(1.5) enddo ! Transform back to grid call sptezm(0,mx,id,im,jm,km,s(1,1,1),fpos(1,1,1,ipos_hgt_prs),+1) call sptezmv(0,mx,id,im,jm,km,s(1,1,2),s(1,1,3),& fpou(1,1,1,ipou_ugrd_prs),fpov(1,1,1,ipov_vgrd_prs),+1) call sptezm(0,mx,id,im,jm,km,s(1,1,4),fpos(1,1,1,ipos_tmp_prs),+1) call sptezm(0,mx,id,im,jm,km,s(1,1,5),fpos(1,1,1,ipos_vvel_prs),+1) call sptezm(0,mx,id,im,jm,km,s(1,1,6),fpos(1,1,1,ipos_fwavh_prs),+1) call sptezm(0,mx,id,im,jm,km,s(1,1,7),fpos(1,1,1,ipos_absv_prs),+1) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end subroutine !------------------------------------------------------------------------------- subroutine postx1(id,im,jm,mt,mw,f) !$$$ Subprogram documentation block ! ! Subprogram: postx1 Post subprogram to filter horizontally ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram horizontally filters a scalar field. ! The filtering is done in spectral space. The filtering need not be a ! straight spectral truncation, however, but can gradually filter over ! a finite width in spectral space, which should ameliorate Gibbsing. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call postx1(id,im,jm,mt,mw,f) ! Input argument list: ! id integer data representation type ! im integer number of longitudes ! jm integer number of latitudes ! mt integer smoothing truncation ! mw integer smoothing width ! fpos real (im,jm) scalar field ! Output argument list: ! fpos real (im,jm) scalar field ! ! Modules used: ! postgp_module Shared data for postgp ! ! Files included: ! physcons.h Physical constants ! ! Subprograms called: ! sptez scalar spectral transform ! ! Attributes: ! Language: Fortran 90 ! !$$$ use postgp_module implicit none integer,intent(in):: id,im,jm,mt,mw real,intent(inout):: f(im,jm) real s((mt+mw/2+1)*(mt+mw/2+2)) integer mx,i,l,n real fac ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Transform to spectral mx=mt+mw/2 call sptez(0,mx,id,im,jm,s,f,-1) ! Filter i=0 do l=0,mx do n=l,mx if(n.gt.mt-mw/2) then fac=0. if(mw.gt.0) fac=min(max(0.5+(mt-n)/float(mw),0.),1.) s(i+1)=fac*s(i+1) s(i+2)=fac*s(i+2) endif i=i+2 enddo enddo ! Transform back to grid call sptez(0,mx,id,im,jm,s,f,+1) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end subroutine !------------------------------------------------------------------------------- subroutine kpfilt(nkplist,kplist,nfx,iptv,ipu,itl,il1,il2) !$$$ Subprogram documentation block ! ! Subprogram: kpfilt Filter output before packing and writing ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram makes the determination whether or not fields are ! packed and written based on an input filter list. If the parameter, ! level type and level values are in the filter list, then the fields ! will be written. The filter list can have -1 as a wild card. ! ! Program history log: ! 2003-02-24 Mark Iredell ! ! Usage: call kpfilt(nkplist,kplist,nfx,ipu,itl,il1,il2) ! Input argument list: ! nkplist integer number of entries in the filter list ! kplist integer (4,nkplist) filter list iptv,ipu,itl,il1*256+il2 ! nfx integer local size of field decomposition ! iptv integer (nfx) parameter table version ! ipu integer (nfx) parameter identifier ! itl integer (nfx) type of level ! il1 integer (nfx) level 1 ! il2 integer (nfx) level 2 ! Output argument list: ! ipu integer (nfx) parameter identifier ! ! Attributes: ! Language: Fortran 90 ! !$$$ integer,intent(in):: nkplist,nfx integer,dimension(4,nkplist),intent(in):: kplist integer,dimension(nfx),intent(in):: iptv,itl,il1,il2 integer,dimension(nfx),intent(inout):: ipu integer n,k,kpn(4) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Determine if each parameter is in the list field: do n=1,nfx kpn(1)=iptv(n) kpn(2)=ipu(n) kpn(3)=itl(n) kpn(4)=abs(il1(n)*256+il2(n)) if(il2(n).lt.0) kpn(4)=kpn(4)+32768 do k=1,nkplist if(all(kplist(:,k).eq.-1.or.kplist(:,k).eq.kpn)) cycle field enddo ipu(n)=0 ! not found enddo field end subroutine !------------------------------------------------------------------------------- subroutine posto(comm,size,nf,nf1,nf2,nfm,nfx,ijmc,ijxc,ijoc,ijo,& lc,fc,gc,lb,lv,lmw,& ibms,iptv,ipu,ipv,itl,il1,il2,ifu,ip1,ip2,itr,& idrtc,ioc,joc,kgdsc,idrt,io,jo,kgdso,& icen,igen,igrido,iyr,imo,idy,ihr,icen2,ienst,iensi,& ids,omin,omax,mxbit,lupgb,iprev,nfw,iret) !$$$ Subprogram documentation block ! ! Subprogram: posto Post subprogram to pack and write output ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram packs and writes the posted output data. ! It also may first interpolate the data from a different compute grid. ! The data is passed in decomposed over the compute grid, but is internally ! transposed to the full horizontal dimension and partial field dimension ! before any processing is done. The packed data are written by all tasks ! to a random access file, with coordination to avoid conflict. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call posto(comm,size,nf,nf1,nf2,nfm,nfx,ijmc,ijxc,ijoc,ijo,& ! lc,fc,gc,lb,lv,lmw,& ! ibms,iptv,ipu,ipv,itl,il1,il2,ifu,ip1,ip2,itr,& ! idrtc,ioc,joc,kgdsc,idrt,io,jo,kgdso,& ! icen,igen,igrido,iyr,imo,idy,ihr,icen2,ienst,iensi,& ! ids,omin,omax,mxbit,lupgb,iprev,nfw,iret) ! Input argument list: ! comm integer message passing communicator ! size integer message passing size ! nf integer total number of fields ! nf1 integer local first field index ! nf2 integer local last field index ! nfm integer maximum size of field decomposition ! nfx integer local size of field decomposition ! ijmc integer maximum size of compute grid decomposition ! ijxc integer local size of compute grid decomposition ! ijoc integer total number of compute grid points ! ijo integer total number of output grid points ! lc logical*1 (nf,ijxc) bitmap on local compute grid ! fc real (nf,ijxc) data field 1 on local compute grid ! gc real (nf,ijxc) data field 2 on local compute grid ! lb integer bitmap switch ! lv integer vector switch ! lmw integer multiple write switch ! ibms integer (nfx) bitmap flag ! iptv integer (nfx) parameter table version ! ipu integer (nfx) parameter identifier for field 1 ! ipv integer (nfx) parameter identifier for field 2 ! itl integer (nfx) type of level ! il1 integer (nfx) level 1 ! il2 integer (nfx) level 2 ! ifu integer (nfx) forecast time unit ! ip1 integer (nfx) time 1 ! ip2 integer (nfx) time 2 ! itr integer (nfx) time representation ! idrtc integer compute grid data representation type ! ioc integer compute grid number of longitudes ! joc integer compute grid number of latitudes ! kgdsc integer (200) compute grid GDS ! idrt integer output grid data representation type ! io integer output grid number of longitudes ! jo integer output grid number of latitudes ! kgdso integer (200) output grid GDS ! icen integer center ! igen integer model generating code ! igrido integer center grid identifier ! iyr integer year ! imo integer month ! idy integer day ! ihr integer hour ! icen2 integer subcenter ! ienst integer ensemble type ! iensi integer ensemble identification ! ids integer (255,255) decimal scaling ! omin real (255) minimum value in output data ! omax real (255) maximum value in output data ! mxbit integer maximum number of bits to pack data ! lupgb integer unit number of random access output file ! iprev integer number of bytes to written to output file ! Output argument list: ! iprev integer number of bytes to written to output file ! nfw integer number of fields written ! iret integer return code ! ! Subprograms called: ! mptran1l1 transpose grid decompositions ! mptran1r4 transpose grid decompositions ! ipolates interpolate scalar fields ! ipolatev interpolate vector fields ! makglgrb make GRIB messages ! mpfilli4 gather grid decomposition ! bawrite write random access record ! ! Attributes: ! Language: Fortran 90 ! !$$$ use machine,only:kint_mpi implicit none integer(kint_mpi),intent(in):: comm,size integer,intent(in):: nf,nf1,nf2,nfm,nfx,ijmc,ijxc,ijoc,ijo logical*1,intent(in):: lc(nf,ijxc) real,intent(in):: fc(nf,ijxc),gc(nf,ijxc) integer,intent(in):: lb,lv,lmw integer,dimension(nfx),intent(in):: ibms,iptv,ipu,ipv,itl,il1,il2 integer,dimension(nfx),intent(in):: ifu,ip1,ip2,itr integer,intent(in):: idrtc,ioc,joc,kgdsc(200),idrt,io,jo,kgdso(200) integer,intent(in):: icen,igen,igrido,iyr,imo,idy,ihr,icen2,ienst,iensi integer,intent(in):: ids(255,255) real,intent(in):: omin(255),omax(255) integer,intent(in):: mxbit,lupgb integer,intent(inout):: iprev integer,intent(out):: nfw,iret logical*1,allocatable:: lt(:,:) real,allocatable:: ft(:,:),gt(:,:) integer ibo(nf1:nf2) logical*1,allocatable:: lo(:,:) real,allocatable:: fo(:,:),go(:,:) integer nxo,nco(nf1:nf2),ngo(nf) character,allocatable:: co(:) logical lbm,luv integer ipopt(20),ko real rlat(ijo),rlon(ijo),crot(ijo),srot(ijo) integer iskip,iread,nread integer,allocatable:: igread(:) character,allocatable:: cgo(:) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Transpose distributed data to full horizontal fields nfw=0 nxo=(1000+ijo*(mxbit+1)/8)*nfx lbm=lb.eq.1 luv=lv.eq.1 allocate(lt(ijoc,nf1:nf2)) if(lbm) then call mptran1l1(comm,size,nfm,nf,nfx,nf,ijmc,ijxc,ijoc,ijoc,lc,lt) endif allocate(ft(ijoc,nf1:nf2)) call mptran1r4(comm,size,nfm,nf,nfx,nf,ijmc,ijxc,ijoc,ijoc,fc,ft) if(luv) then allocate(gt(ijoc,nf1:nf2)) call mptran1r4(comm,size,nfm,nf,nfx,nf,ijmc,ijxc,ijoc,ijoc,gc,gt) endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Interpolate to output grid ipopt(1)=1 allocate(fo(ijo,nf1:nf2)) allocate(lo(ijo,nf1:nf2)) if(luv) allocate(go(ijo,nf1:nf2)) if(idrt.eq.idrtc.and.io.eq.ioc.and.jo.eq.joc) then ibo=ibms if(lbm) then lo=lt else lo=.true. endif fo=ft if(luv) then go=gt endif elseif(luv) then call ipolatev(1,ipopt,kgdsc,kgdso,ijoc,ijo,nfx,ibms,lt,ft,gt,& ko,rlat,rlon,crot,srot,ibo,lo,fo,go,iret) if(iret.ne.0) return else call ipolates(1,ipopt,kgdsc,kgdso,ijoc,ijo,nfx,ibms,lt,ft,& ko,rlat,rlon,ibo,lo,fo,iret) if(iret.ne.0) return endif deallocate(lt) deallocate(ft) if(luv) deallocate(gt) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Make and write GRIB messages for field 1 allocate(co(nxo)) call makglgrb(icen,igen,igrido,iyr,imo,idy,ihr,0,0,icen2,& nfx,ibo,iptv,ipu,itl,il1,il2,ifu,ip1,ip2,itr,& ids,ienst,iensi,kgdso,omin,omax,& mxbit,ijo,ijo,nxo,lo,fo,nco,co,iret) if(.not.luv) deallocate(lo) deallocate(fo) if(iret.ne.0) return call mpfilli4(comm,size,1,1,1,nfm,nfx,nf,nco,ngo) iskip=iprev+sum(ngo(1:nf1-1)) iread=sum(ngo(nf1:nf2)) if(lmw.eq.0) then allocate(igread(size)) call mpfilli4(comm,size,1,1,1,1,1,size,iread,igread) allocate(cgo(sum(igread))) call mpfillc1(comm,size,1,1,1,maxval(igread),iread,sum(igread),co,cgo) if(nf1.eq.1) then iread=sum(igread) call bawrite(lupgb,iskip,iread,nread,cgo) else iread=0 nread=0 endif deallocate(igread,cgo) else call bawrite(lupgb,iskip,iread,nread,co) endif if(nread.ne.iread) then iret=23 return endif iprev=iprev+sum(ngo) nfw=count(ngo.gt.0) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! Make and write GRIB messages for field 2 if(luv) then call makglgrb(icen,igen,igrido,iyr,imo,idy,ihr,0,0,icen2,& nfx,ibo,iptv,ipv,itl,il1,il2,ifu,ip1,ip2,itr,& ids,ienst,iensi,kgdso,omin,omax,& mxbit,ijo,ijo,nxo,lo,go,nco,co,iret) deallocate(lo) deallocate(go) if(iret.ne.0) return call mpfilli4(comm,size,1,1,1,nfm,nfx,nf,nco,ngo) iskip=iprev+sum(ngo(1:nf1-1)) iread=sum(ngo(nf1:nf2)) if(lmw.eq.0) then allocate(igread(size)) call mpfilli4(comm,size,1,1,1,1,1,size,iread,igread) allocate(cgo(sum(igread))) call mpfillc1(comm,size,1,1,1,maxval(igread),iread,sum(igread),co,cgo) if(nf1.eq.1) then iread=sum(igread) call bawrite(lupgb,iskip,iread,nread,co) else iread=0 nread=0 endif deallocate(igread,cgo) else call bawrite(lupgb,iskip,iread,nread,co) endif call bawrite(lupgb,iskip,iread,nread,co) if(nread.ne.iread) then iret=23 return endif iprev=iprev+sum(ngo) nfw=nfw+count(ngo.gt.0) endif deallocate(co) end subroutine !------------------------------------------------------------------------------- subroutine makglgrb(icen,igen,igrid,iyr,imo,idy,ihr,ina,inm,icen2,& na,ibms,iptv,ipu,itl,il1,il2,iftu,ip1,ip2,itr,& ids,ienst,iensi,kgds,famin,famax,& mxbit,ija,ida,idc,la,fa,ncg,cg,iret) !$$$ Subprogram documentation block ! ! Subprogram: makglgrb Make GRIB messages ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram creates several GRIB messages. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call makglgrb(icen,igen,igrid,iyr,imo,idy,ihr,ina,inm,icen2,& ! na,ibms,iptv,ipu,itl,il1,il2,iftu,ip1,ip2,itr,& ! ids,ienst,iensi,kgds,famin,famax,& ! mxbit,ija,ida,idc,la,fa,ncg,cg,iret) ! Input argument list: ! icen integer center ! igen integer model generating code ! igrid integer center grid identifier ! iyr integer year ! imo integer month ! idy integer day ! ihr integer hour ! ina integer number in average ! inm integer number missing ! icen2 integer subcenter ! na integer number of GRIB messages ! ibms integer (na) bitmap flag ! iptv integer (na) parameter table version ! ipu integer (na) parameter identifier for field 1 ! (if any are zero, that message is skipped) ! itl integer (na) type of level ! il1 integer (na) level 1 ! il2 integer (na) level 2 ! iftu integer (na) forecast time unit ! ip1 integer (na) time 1 ! ip2 integer (na) time 2 ! itr integer (na) time representation ! ids integer (255,255) decimal scaling ! ienst integer ensemble type ! iensi integer ensemble identification ! kgds integer (200) grid GDS ! famin real (255) minimum value in output data ! famax real (255) maximum value in output data ! mxbit integer maximum number of bits to pack data ! ija integer total number of grid points ! ida integer first dimension of input data ! idc integer size of output buffer in bytes ! la logical*1 (ida,na) bitmap to pack ! fa real (ida,na) data to pack ! Output argument list: ! ncg integer (na) length of GRIB messages ! cg character (idc) output buffer ! iret integer return code ! ! Subprograms called: ! makglpds create global PDS ! pakgb make GRIB message ! ! Attributes: ! Language: Fortran 90 ! !$$$ implicit none integer,intent(in):: icen,igen,igrid,iyr,imo,idy,ihr,ina,inm,icen2,na integer,intent(in):: ibms(na),iptv(na),ipu(na),itl(na),il1(na),il2(na) integer,intent(in):: iftu(na),ip1(na),ip2(na),itr(na) integer,intent(in):: ids(255,255),ienst,iensi,kgds(200) integer,intent(in):: mxbit,ija,ida,idc logical*1,intent(in):: la(ida,na) real,intent(in):: famin(255),famax(255) real,intent(in):: fa(ida,na) integer,intent(out):: ncg(na) character,intent(out):: cg(idc) integer ng,iskip,n,ip,ib,kbm,nbit,iret integer kpds(200),kens(5) real f(ija) real fmin,fmax character c1(1000+ija*(mxbit+1)/8) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! For each GRIB message, make PDS array, then make full GRIB message ng=1000+ija*(mxbit+1)/8 iskip=0 do n=1,na ncg(n)=0 ip=ipu(n) if(ip.le.0) cycle ib=ibms(n) if(ib.eq.1) then if(.not.any(la(1:ija,n))) cycle if(all(la(1:ija,n))) ib=0 endif call makglpds(iptv(n),icen,igen,igrid,ib,ip,itl(n),il1(n),il2(n),& iyr,imo,idy,ihr,iftu(n),ip1(n),ip2(n),itr(n),& ina,inm,icen2,ids(iptv(n),ip),kpds) kens(1)=1 kens(2)=ienst kens(3)=iensi kens(4)=1 kens(5)=255 f=min(max(fa(1:ija,n),famin(ip)),famax(ip)) call pakgb(ija,ng,0,mxbit,0,kpds,kgds,kens,la(1,n),f,& kbm,fmin,fmax,nbit,ncg(n),c1,iret) if(iret.ne.0) ncg(n)=0 cg(iskip+1:iskip+ncg(n))=c1(1:ncg(n)) iskip=iskip+ncg(n) enddo ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end subroutine !------------------------------------------------------------------------------- subroutine pakgb(kf,kg,minbit,maxbit,ibs,kpds,kgds,kens,lb,f,& kbm,fmin,fmax,nbit,lg,g,iret) !$$$ Subprogram documentation block ! ! Subprogram: pakgb Make GRIB message ! Prgmmr: Iredell Org: np23 Date: 1999-10-18 ! ! Abstract: This subprogram creates one GRIB message. ! ! Program history log: ! 1999-10-18 Mark Iredell ! ! Usage: call pakgb(kf,kg,minbit,maxbit,ibs,kpds,kgds,kens,lb,f,& ! kbm,fmin,fmax,nbit,lg,g,iret) ! Input argument list: ! kf integer length of data arrays ! kg integer length of output buffer ! minbit integer minimum number of bits to pack data ! maxbit integer maximum number of bits to pack data ! ibs integer binary scaling ! kpds integer (200) PDS parameters ! kgds integer (200) GDS parameters ! kens integer (5) ensemble parameters ! lb logical*1 (kf) bitmap to pack ! fa real (kf) data to pack ! Output argument list: ! kbm integer number of packed valid data ! fmin real data packed data minimum ! fmax real data packed data maximum ! nbit integer number of bits used ! lg integer length of GRIB message ! g character (kg) GRIB message ! iret integer return code ! ! Subprograms called: ! r63w72 map w3fi63 parameters onto w3fi72 parameters ! getbit get number of bits and round data ! w3fi68 convert 25 word array to grib pds ! pdsens packs grib pds extension 41- for ensemble ! w3fi72 pack grib ! ! Attributes: ! Language: Fortran 90 ! !$$$ integer kpds(200),kgds(200),kens(5) logical*1 lb(kf) real f(kf) character g(kg) integer ibm(kf),ipds(200),igds(200),ibds(200) real fr(kf) character pds(400) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! get w3fi72 parameters call r63w72(kpds,kgds,ipds,igds) ibds=0 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! count valid data kbm=kf if(ipds(7).ne.0) then kbm=0 do i=1,kf if(lb(i)) then ibm(i)=1 kbm=kbm+1 else ibm(i)=0 endif enddo if(kbm.eq.kf) ipds(7)=0 endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! get number of bits and round data if(kbm.eq.0) then do i=1,kf fr(i)=0. enddo fmin=0. fmax=0. nbit=0 else call getbit(ipds(7),ibs,ipds(25),kf,ibm,f,fr,fmin,fmax,nbit) if(nbit.lt.minbit) then ibs2=ibs+(minbit-nbit) call getbit(ipds(7),ibs2,ipds(25),kf,ibm,f,fr,fmin,fmax,nbit) endif if(maxbit.gt.0) nbit=min(nbit,maxbit) endif ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! create product definition section call w3fi68(ipds,pds) if(ipds(24).eq.2) call pdsens(kens,kprob,xprob,kclust,kmembr,45,pds) ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ! pack grib data call w3fi72(0,fr,0,nbit,1,ipds,pds,1,255,igds,0,0,ibm,kf,ibds,kfo,g,lg,iret) if(iret.eq.0.and.lg.gt.kg) iret=98 ! - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - end subroutine