! Conformal Cubic Atmospheric Model ! Copyright 2015-2018 Commonwealth Scientific Industrial Research Organisation (CSIRO) ! This file is part of the Conformal Cubic Atmospheric Model (CCAM) ! ! CCAM is free software: you can redistribute it and/or modify ! it under the terms of the GNU General Public License as published by ! the Free Software Foundation, either version 3 of the License, or ! (at your option) any later version. ! ! CCAM is distributed in the hope that it will be useful, ! but WITHOUT ANY WARRANTY; without even the implied warranty of ! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! GNU General Public License for more details. ! ! You should have received a copy of the GNU General Public License ! along with CCAM. If not, see . !------------------------------------------------------------------------------ program cdfvidar use ccinterp use cll_m use comsig_m use latlong_m use netcdf_m use sigdata_m implicit none include 'version.h' integer iout,in integer kvin,kuin,kbin integer ism,nrh integer krin,ktin,khin integer mtimer,id,jd integer mxcyc,nvsig,ntimes integer insm,l integer ilx,jlx,i,j,iq integer nplev,ilonx,ilatx integer ier,ijd,ilt,jlk integer irecd,ngatts,nvars integer ndims,idv,lonid,latid integer k,ivpres integer narch,idtim,idpres integer ilonn,iyr,imn,idy integer ivtim,ihr,imi integer icmonth_to_imn integer nt,iarch,khout,igout integer idvar,kn,kx integer nopnts,nlpnts,ijgd integer jk,imidpan2 integer ilatn,if2,inlsavn integer inzsavn,ints,inzs integer io_out,igd,jgd real ptop,grdx,grdy real g,pi,rlonx,rlatx real rlonn,rlatn real rlong0,rlat0,schmidt real elon,elat,xplev,tohpa real time,xa,an real spval,sinlong,coslat real coslong,polenz,poleny real polenx,sinlat,sx,cx real zonx,zony,sn,cn real sinth,conth,den,zonz real uzon,costh,ull,vll real vmer,ther,ds,du,tanl real rnml,stl1,stl2 real rlon real llrng,minlon,maxlon,minlat,maxlat character(len=1024) inf common/mapproj/du,tanl,rnml,stl1,stl2 include 'nplevs.h' ! maxplev real, dimension(maxplev) :: plev,cplev common/levpre/nplev,plev include 'lmax.h' parameter ( pi=3.1415926536 ) parameter ( g=9.80616 ) real, dimension(lmax) :: dsg,sgml common/ncdfids/dimil,dimjl,dimkl,dimtim,idil,idjl,idkl,idnt ! dimension ids integer dimil,dimjl,dimkl,dimtim ! variable ids integer idil,idjl,idkl,idnt,ix,iy integer il,jl,kl,ifull integer ncid integer iernc,liernc,lncid,varid,dimid integer idsoillvl, ivsoillvl, nsoillvl, ksearch, ktest integer, dimension(2) :: ccdim integer, dimension(2) :: start, ncount common/lconther/ther include 'vidar.h' logical sdiag real dst, xfrac real, dimension(2) :: lonlat real, dimension(:,:,:), allocatable :: rlld,xyz,axyz,bxyz real, dimension(:,:), allocatable :: grid real, dimension(:), allocatable :: ax,ay,az,bx,by,bz,x,y,z real, dimension(:), allocatable :: datan, datatemp real, dimension(:), allocatable :: zs_gbl, lsm_gbl real, dimension(:), allocatable :: glon, glat real plevin(maxplev) real, dimension(:,:,:), allocatable :: hgt real, dimension(:,:,:), allocatable :: temp real, dimension(:,:,:), allocatable :: u real, dimension(:,:,:), allocatable :: v real, dimension(:,:,:), allocatable :: rh real, dimension(:), allocatable :: sfcto_m real, dimension(:), allocatable :: lsmg_m real, dimension(:), allocatable :: zsg real, dimension(:), allocatable :: validlevhost real, dimension(:), allocatable :: validlevcc real, dimension(:), allocatable :: soildepth_in real, dimension(6), parameter :: soildepth_ccam = (/ 0.011, 0.051, 0.157, 0.4385, 1.1855, 3.164 /) real, dimension(6), parameter :: soilthick_ccam = (/ 0.022, 0.058, 0.154, 0.409, 1.085, 2.872 /) real, parameter :: rhowater = 1000. real fill_float common/datatype/moist_var,in_type character*1 in_type character*2 moist_var logical ofirst, ogbl, orev, olsm_gbl character*60 timorg character*60 cu character*3 cmonth character*80 zsavn,lsavn character*10 header,moistvar character*10 soilunits, geopotunits, presunits logical merge namelist/gnml/inf,vfil,ds,du,tanl,rnml,stl1,stl2,inzs,zsfil & ,ints,tsfil, ogbl,zsavn,inzsavn,lsavn,inlsavn & ,plevin,orev,io_out,igd,jgd,id,jd,mtimer,ntimes & ,spline,mxcyc,nvsig,nrh & ,oesig,sgml,dsg,ptop,debug,notop,opre,have_gp & ,in,calout & ,iout,oform,sdiag & ,insm,smfil & ,splineu,splinev,splinet,zerowinds & ,grdx,grdy,slon,slat & ,moistvar,kl,merge,llrng data khin/0/,kuin/0/,kvin/0/,ktin/0/,krin/0/ data igd/1/,jgd/1/,id/1/,jd/1/,mtimer/0/ data ofirst/.true./,io_out/3/ data ogbl/.true./,orev/.false./ data inzs/10/, ints/0/, insm/0/, in/50/, iout/70/ data ptop/0./, ntimes/1/, nvsig/4/ data mxcyc/20/, oform/.true./ data spline/.true./, notop/.false./, opre/.false./ data debug/.false./,oesig/.true./, calout/.true./, nrh/0/ data inzsavn/11/ , zsavn/'zsavn.ff'/ data inlsavn/11/ , lsavn/'lsavn.ff'/ data moistvar/''/ data zsfil/'/tmp/csjjk/topog5'/ data tsfil/'/tmp/csjjk/sfct'/ data smfil/'/tmp/csjjk/smfil'/ data sgml/lmax*0./, dsg/lmax*0./ data plevin/maxplev*0./ data splineu/.true./, splinev/.true./, splinet/.true./ data sdiag/.false./ data have_gp/.true./ data zerowinds/.true./ data grdx/1./ data grdy/-1./ data merge/.false./,llrng/0./ ! Start banner write(6,*) "==============================================================================" write(6,*) "CCAM: Starting cdfvidar" write(6,*) "=============================================================================" write(6,*) version #ifndef stacklimit ! For linux only - removes stacklimit on all processors call setstacklimit(-1) #endif slon=0. slat=90. !####################### read namelists ############################ write(6,*)'read namelist' read (5, gnml) write(6,nml=gnml) !####################### read namelist ############################ if (kl>lmax) then write(6,*) "ERROR: kl is greater than lmax" write(6,*) "kl= ",kl," lmax=",lmax call finishbanner stop -1 end if call comsigalloc(kl) dsgx=dsg(1:kl) sgmlx=sgml(1:kl) spline = splineu .or. splinev .or. splinet ! set up what sigma levels the outgoing data will have ! assumes top down, ie. sg(1)=0., dsg>0 sgx(1)=0. if ( sgmlx(kl/2).gt.0. ) then ! dsg=0, sgml>0 do l=2,kl sgx(l)=.5*(sgmlx(l-1)+sgmlx(l)) end do ! l=2,kl do l=2,kl+1 dsgx(l-1)=sgx(l)-sgx(l-1) end do ! l=2,kl+1 elseif ( dsgx(kl/2).gt.0. ) then ! sgml=0, dsg>0 do l=2,kl-1 sgx(l)=sgx(l-1)+dsgx(l-1) end do ! l=2,kl-1 do l=1,kl sgmlx(l)=.5*(sgx(l)+sgx(l+1)) end do ! l=1,kl elseif ( kl.eq.27 .or. kl.eq.35 ) then call calcsig(sgx,kl) do l=1,kl sgmlx(l)=.5*(sgx(l)+sgx(l+1)) dsgx(l)=sgx(l+1)-sgx(l) end do ! l=1,kl elseif ( oesig ) then do l=1,kl dsgx(l)=1./float(kl) sgmlx(l)=(l-.5)/float(kl) sgx(l+1)=sgx(l)+dsgx(l) end do ! l=1,kl else write(6,*)"Wrong sigma specification: STOP" call finishbanner stop -1 endif sgx(kl+1)=1. !####################### read topography data ############################ write(6,*)'open ',inzs,' zsfil=',zsfil if ( ogbl ) then write(6,*)"set up cc geometry" liernc=nf_open(zsfil,nf_nowrite,lncid) if (liernc==nf_noerr) then iernc=nf_inq_dimid(lncid,"longitude",dimid) iernc=nf_inq_dimlen(lncid,dimid,ilx) iernc=nf_inq_dimid(lncid,"latitude",dimid) iernc=nf_inq_dimlen(lncid,dimid,jlx) iernc=nf_get_att_real(lncid,nf_global,"lon0",rlong0) if (iernc/=0) then write(6,*) "ERROR reading lon0 ",iernc call finishbanner stop -1 end if iernc=nf_get_att_real(lncid,nf_global,"lat0",rlat0) iernc=nf_get_att_real(lncid,nf_global,"schmidt",schmidt) ds=0. header='' else open(unit=inzs,file=zsfil,status='old',form='formatted') read(inzs,*)ilx,jlx,rlong0,rlat0,schmidt,ds,header end if du=rlong0 tanl=rlat0 rnml=schmidt write(6,*)"gbl mapproj=",ilx,jlx,rlong0,rlat0,schmidt,ds il=ilx jl=6*il ifull=il*jl call latlongalloc(il) call cllalloc(il) call sigdataalloc(il,kl) allocate(hgt(il,jl,maxplev),temp(il,jl,maxplev)) allocate(u(il,jl,maxplev),v(il,jl,maxplev)) allocate(rh(il,jl,maxplev)) allocate(sfcto_m(ifull),lsmg_m(ifull)) allocate(zsg(ifull)) allocate(x(ifull),y(ifull),z(ifull)) allocate(ax(ifull),ay(ifull),az(ifull)) allocate(bx(ifull),by(ifull),bz(ifull)) allocate(validlevcc(ifull)) ! set-up CC grid ccdim(1)=il ccdim(2)=jl lonlat(1)=rlong0 lonlat(2)=rlat0 allocate(rlld(ccdim(1),ccdim(2),2),grid(ccdim(1),ccdim(2))) allocate(xyz(ccdim(1),ccdim(2),3),axyz(ccdim(1),ccdim(2),3)) allocate(bxyz(ccdim(1),ccdim(2),3)) !call cgg2(rlld,grid,ccdim,lonlat,schmidt,dst,iin,iie,iis,iiw) Call getcc(rlld,grid,xyz,axyz,bxyz,ccdim,lonlat,schmidt,dst) do i=1,ccdim(1) do j=1,ccdim(2) iq=i+(j-1)*ccdim(1) rlong(iq)=rlld(i,j,1) rlat(iq)=rlld(i,j,2) x(iq)=xyz(i,j,1) y(iq)=xyz(i,j,2) z(iq)=xyz(i,j,3) ax(iq)=axyz(i,j,1) ay(iq)=axyz(i,j,2) az(iq)=axyz(i,j,3) bx(iq)=bxyz(i,j,1) by(iq)=bxyz(i,j,2) bz(iq)=bxyz(i,j,3) end do end do deallocate(xyz,axyz,bxyz) deallocate (rlld,grid) !call setxyz rlatx=-1.e29 rlatn= 1.e29 rlonx=-1.e29 rlonn= 1.e29 do iq=1,ifull ! convert conformal cubic lats & longs to degrees (-90 to 90) & (0 to 360) ! used in sint16; N.B. original rlong is -pi to pi if(rlong(iq).lt.0.)rlong(iq)=rlong(iq)+360. if(rlat(iq).gt.rlatx)then rlatx=rlat(iq) ilatx=iq endif if(rlong(iq).gt.rlonx)then rlonx=rlong(iq) ilonx=iq endif if(rlat(iq).lt.rlatn)then rlatn=rlat(iq) ilatn=iq endif if(rlong(iq).lt.rlonn)then rlonn=rlong(iq) ilonn=iq endif enddo ! iq loop write(6,*)"rlong,rlat(1,1)=",rlong(1),rlat(1) write(6,*)"rlong:x,n=",rlonx,ilonx,rlonn,ilonn write(6,*)"rlatg:x,n=",rlatx,ilatx,rlatn,ilatn else ! ( not ogbl ) then liernc=-1 open(inzs,file=zsfil,form='formatted',recl=il*7,status='old') write(6,*)'read zsfil header' read(inzs,*)ilt,jlk,ds,du,tanl,rnml,stl1,stl2 if(ilt.eq.0.or.jlk.eq.0)then write(6,*)'no header in newtopo file' else write(6,*)'Header information for topofile' write(6,*)'ilt,jlk,ds,du,tanl,rnml,stl1,stl2',ilt,jlk,ds,du,tanl,rnml,stl1,stl2 if(ilt/=il.or.jlk/=jl) then write(6,*) 'wrong topofile supplied' call finishbanner stop -1 end if endif ! (ilt.eq.0.or.jlk.eq.0) write(6,*)"set up model grid params by calling lconset ds=",ds call lconset(ds) endif ! ( ogbl ) then if (liernc==nf_noerr) then write(6,*)'read model grid zs' iernc=nf_inq_varid(lncid,"zs",varid) iernc=nf_get_var_real(lncid,varid,zs) write(6,*)'read model grid land-sea mask (0=ocean, 1=land)' iernc=nf_inq_varid(lncid,"lsm",varid) iernc=nf_get_var_real(lncid,varid,lsm_m) iernc=nf_close(lncid) else write(6,*)'read model grid zsg = g*zs' read(inzs,*)zsg write(6,*)'read model grid land-sea mask (0=ocean, 1=land)' read(inzs,*)lsm_m close(inzs) write(6,*)'convert g*zs to zs(m)' zs(1:ifull)=zsg(1:ifull)/g ! convert ascii read in zs*g to zs(m) end if ijd=id+il*(jd-1) write(6,*)"ijd=",ijd," zs(m)=",zs(ijd)," lsm_m=",lsm_m(ijd) !####################### read topography data ############################ !####################### open input netcdf file ############################ write(6,*)'inf=' write(6,*) trim(inf) ier = nf_open(inf,nf_nowrite,ncid) write(6,*)'ncid=',ncid if(ier.ne.0) then write(6,*)' cannot open netCDF file; error code ',ier call finishbanner stop -1 end if !####################### get attributes of input netcdf file ############################ ier = nf_inq(ncid,ndims,nvars,ngatts,irecd) write(6,'("ndims,nvars,ngatts,irecd,ier")') write(6,'(5i6)') ndims,nvars,ngatts,irecd,ier ! Get dimensions write(6,*) "get dim1 ncid=",ncid ier = nf_inq_dimid(ncid,'lon',lonid) write(6,*)"lon ncid,lonid,ier=",ncid,lonid,ier if ( ier.eq.0 ) then write(6,*)"ncid,lonid=",ncid,lonid ier= nf_inq_dimlen(ncid,lonid,ix) write(6,*)"input ix,ier=",ix,ier ier = nf_inq_dimid(ncid,'lat',latid) ier= nf_inq_dimlen(ncid,latid,iy) write(6,*)"input iy,ier=",iy,ier ier = nf_inq_varid(ncid,'lon',idv) allocate(glon(ix),glat(iy)) ! get glon from input dataset ier = nf_get_var_real(ncid,idv,glon) ier = nf_inq_varid(ncid,'lat',idv) ier = nf_get_var_real(ncid,idv,glat) else write(6,*)"now try longitude" ier = nf_inq_dimid(ncid,'longitude',lonid) write(6,*)"lonid=",lonid," ier=",ier ier= nf_inq_dimlen(ncid,lonid,ix) write(6,*)"input ix=",ix," ier=",ier ier = nf_inq_dimid(ncid,'latitude',latid) ier= nf_inq_dimlen(ncid,latid,iy) write(6,*)"input iy=",iy allocate(glon(ix),glat(iy)) ier = nf_inq_varid(ncid,'longitude',idv) ier = nf_get_var_real(ncid,idv,glon) write(6,*)"glon=",(glon(i),i=1,ix) ier = nf_inq_varid(ncid,'latitude',idv) ier = nf_get_var_real(ncid,idv,glat) write(6,*)"glat=",(glat(i),i=1,iy) endif ! ( ier .eq. 0 ) then ! find min/max for input data set slon = glon(1) elon = glon(ix) slat = glat(1) elat = glat(iy) if ( slon slon=",slon," elon=",elon," ix=",ix write(6,*)"==================> slat=",slat," elat=",elat," iy=",iy ier = nf_inq_varid(ncid,'pres',ivpres) ier = nf_inq_dimid(ncid,'pres',idpres) in_type="p" if ( ier .ne. 0 ) then ier = nf_inq_varid(ncid,'plev',ivpres) ier = nf_inq_dimid(ncid,'plev',idpres) in_type="p" endif if ( ier .ne. 0 ) then ier = nf_inq_varid(ncid,'lev',ivpres) ier = nf_inq_dimid(ncid,'lev',idpres) in_type="p" endif if ( ier .ne. 0 ) then ier = nf_inq_varid(ncid,'lvl',ivpres) ier = nf_inq_dimid(ncid,'lvl',idpres) in_type="s" endif write(6,*)"ier=",ier," idpres=",idpres," in_type=",in_type ier= nf_inq_dimlen(ncid,idpres,nplev) write(6,*)"ier=",ier," nplev=",nplev write(6,*)"ier=",ier," ivpres=",ivpres ier = nf_get_var_real(ncid,ivpres,plev) write(6,*)"ier=",ier," ivpres=",ivpres write(6,*)"input nplev=",nplev write(6,*)"plevs=",(plev(k),k=1,nplev) ier = nf_get_att_text(ncid,ivpres,'units',presunits) write(6,*)"ier=",ier," presunits=",trim(presunits) orev = plev(nplev).gt.plev(1) write(6,*)"#################################### orev=",orev ier = nf_inq_dimid(ncid,'soil_lvl',idsoillvl) write(6,*)"ier=",ier," idsoillvl=",idsoillvl if ( ier==0 ) then ier = nf_inq_dimlen(ncid,idsoillvl,nsoillvl) write(6,*)"ier=",ier," nsoillvl=",nsoillvl else nsoillvl = 0 end if if ( nsoillvl>0 ) then allocate( soildepth_in(nsoillvl) ) ier = nf_inq_varid(ncid,'soil_lvl',ivsoillvl) write(6,*)"ier=",ier," ivsoillvl=",ivsoillvl ier = nf_get_var_real(ncid,ivsoillvl,soildepth_in) write(6,*)"soildepth_in=",soildepth_in(1:nsoillvl) end if write(6,*)"####################################" write(6,*)"allocate arrays ix,iy,nplevs=",ix,iy,nplev if ( nsoillvl>nplev ) then allocate(datan(ix*iy*nsoillvl)) else allocate(datan(ix*iy*nplev)) end if allocate(datatemp(ix*iy)) allocate(zs_gbl(ix*iy)) allocate(lsm_gbl(ix*iy)) allocate(validlevhost(ix*iy)) validlevhost(:) = 1. if ( orev ) then do k = 1,nplev datan(k) = plev(k) end do do k = 1,nplev plev(k) = datan(nplev+1-k) end do end if xplev = maxval( plev(1:nplev) ) write(6,*)"xplev=",xplev osig_in = .false. if ( .01 khin,datan(igout)=",khin,datan(igout) call sintp16(datan(1+ix*iy*(khin-1):ix*iy*khin),ix,iy,hgt(:,:,khout),glon,glat,sdiag,il) write(6,*)"khout,hgt(il/2,jl.2,khout)=",khout,hgt(il/2,jl/2,khout) write(6,*)'<=== model hgt(m) khin,khout=',khin,khout call findxn(hgt(:,:,khout),ifull,-1.e29,xa,kx,an,kn) enddo ! k endif ! ier = 0 write(6,*)"==================================================u" ier = nf_inq_varid(ncid,'u',idvar) write(6,*)"ier=",ier," idvar=",idvar if ( ier .ne. 0 ) then ier = nf_inq_varid(ncid,'zonal_wnd',idvar) write(6,*)"ier=",ier," idvar=",idvar endif call ncread_3d(ncid,iarch,idvar,ix,iy,nplev,datan) ! MJT quick fix ier = nf_get_att_real(ncid,idvar,'_FillValue',fill_float) if ( ier .ne. 0 ) then ier = nf_get_att_real(ncid,idvar,'missing_value',fill_float) end if if ( ier .eq. 0 ) then where ( datan==fill_float ) datan = 1.e10 end where end if call getvalidlev(validlevhost,datan,ix,iy,nplev) call filldat(datan,ix,iy,nplev) call amap ( datan(1:ix*iy), ix, iy, 'input u', 0., 0. ) do k=1,nplev write(6,*)"************************************************k=",k khin=k khout=nplev+1-k if(orev)khout=k call sintp16(datan(1+ix*iy*(khin-1):ix*iy*khin),ix,iy,u(:,:,khout),glon,glat,sdiag,il) call findxn(u(:,:,khout),ifull,-1.e29,xa,kx,an,kn) enddo write(6,*)"==================================================v" ier = nf_inq_varid(ncid,'v',idvar) write(6,*)"ier=",ier," idvar=",idvar if ( ier .ne. 0 ) then ier = nf_inq_varid(ncid,'merid_wnd',idvar) write(6,*)"ier=",ier," idvar=",idvar endif call ncread_3d(ncid,iarch,idvar,ix,iy,nplev,datan) ! MJT quick fix ier = nf_get_att_real(ncid,idvar,'_FillValue',fill_float) if ( ier .ne. 0 ) then ier = nf_get_att_real(ncid,idvar,'missing_value',fill_float) end if if ( ier .eq. 0 ) then where ( datan==fill_float ) datan = 1.e10 end where end if call getvalidlev(validlevhost,datan,ix,iy,nplev) call filldat(datan,ix,iy,nplev) call amap ( datan(1:ix*iy), ix, iy, 'input v', 0., 0. ) do k=1,nplev write(6,*)"************************************************k=",k khin=k khout=nplev+1-k if(orev)khout=k call sintp16(datan(1+ix*iy*(khin-1):ix*iy*khin),ix,iy,v(:,:,khout),glon,glat,sdiag,il) call findxn(v(:,:,khout),ifull,-1.e29,xa,kx,an,kn) enddo write(6,*)"==================================================temp" ier = nf_inq_varid(ncid,'temp',idvar) write(6,*)"ier=",ier," idvar=",idvar if ( ier .ne. 0 ) then ier = nf_inq_varid(ncid,'air_temp',idvar) write(6,*)"ier=",ier," idvar=",idvar endif call ncread_3d(ncid,iarch,idvar,ix,iy,nplev,datan) ! MJT quick fix ier = nf_get_att_real(ncid,idvar,'_FillValue',fill_float) if ( ier .ne. 0 ) then ier = nf_get_att_real(ncid,idvar,'missing_value',fill_float) end if if ( ier .eq. 0 ) then where ( datan==fill_float ) datan = 1.e10 end where end if call getvalidlev(validlevhost,datan,ix,iy,nplev) call filldat(datan,ix,iy,nplev) call amap ( datan(1:ix*iy), ix, iy, 'input temp', 0., 0. ) do k=1,nplev write(6,*)"************************************************k=",k khin=k khout=nplev+1-k if(orev)khout=k call sintp16(datan(1+ix*iy*(khin-1):ix*iy*khin),ix,iy,temp(:,:,khout),glon,glat,sdiag,il) call findxn(temp(:,:,khout),ifull,-1.e29,xa,kx,an,kn) enddo write(6,*)"================================================rh/q" ier = nf_inq_varid(ncid,'rh',idvar) write(6,*)"ier=",ier," idvar=",idvar if ( ier .eq. 0 ) then moist_var="rh" endif if ( ier .ne. 0 ) then ier = nf_inq_varid(ncid,'relhum',idvar) write(6,*)"ier=",ier," idvar=",idvar moist_var="rh" end if if ( ier .ne. 0 ) then ier = nf_inq_varid(ncid,'mix_rto',idvar) write(6,*)"ier=",ier," idvar=",idvar moist_var="mr" endif if ( ier .ne. 0 .and. moistvar .ne. '' ) then ier = nf_inq_varid(ncid,moistvar,idvar) write(6,*)"ier=",ier," idvar=",idvar moist_var="mr" endif write(6,*)"##################################moist_var=",moist_var call ncread_3d(ncid,iarch,idvar,ix,iy,nplev,datan) ! MJT quick fix ier = nf_get_att_real(ncid,idvar,'_FillValue',fill_float) if ( ier .ne. 0 ) then ier = nf_get_att_real(ncid,idvar,'missing_value',fill_float) end if if ( ier .eq. 0 ) then where ( datan==fill_float ) datan = 1.e10 end where end if call getvalidlev(validlevhost,datan,ix,iy,nplev) call filldat(datan,ix,iy,nplev) call findxn(datan,ix*iy*nplev,-1.e29,xa,kx,an,kn) if ( xa .lt. .1 ) then moist_var="mr" write(6,*)"################################moist_var=",moist_var endif ! ( xa .lt. 1.1 ) then call amap ( datan(1:ix*iy), ix, iy, 'input '//moist_var, 0., 0. ) do k=1,nplev write(6,*)"************************************************k=",k khin=k khout=nplev+1-k if(orev)khout=k call sintp16(datan(1+ix*iy*(khin-1):ix*iy*khin),ix,iy,rh(:,:,khout),glon,glat,sdiag,il) write(6,*)"make sure data is always between 0 and 100!" write(6,*)"for both mixr and rh" rh(:,:,khout)=max(0.,min(100.,rh(:,:,khout))) call findxn(rh(:,:,khout),ifull,-1.e29,xa,kx,an,kn) if ( moist_var .eq. "rh" .and. xa .lt. 1.1 ) then write(6,*)"######################convert rh from 0-1 to 0-100" rh(:,:,khout)=max(0.,min(100.,rh(:,:,khout)*100.)) call findxn(rh(:,:,khout),ifull,-1.e29,xa,kx,an,kn) endif ! ( moist_var .eq. "rh" .and. xa .lt. 1.1 ) then enddo call findxn(hgt(:,:, 1),ifull,-1.e29,xa,kx,an,kn) call findxn(hgt(:,:,nplev),ifull,-1.e29,xa,kx,an,kn) write(6,*)"nplev=",nplev !############################################################################ ! sfc data !############################################################################ write(6,*)"================================================mslp" ier = nf_inq_varid(ncid,'mslp',idvar) write(6,*)"ier=",ier," idvar=",idvar if ( ier .ne. 0 ) then ier = nf_inq_varid(ncid,'pmsl',idvar) write(6,*)"ier=",ier," idvar=",idvar endif if ( ier .eq. 0 ) then call ncread_2d(ncid,iarch,idvar,ix,iy,datan(1:ix*iy)) call amap ( datan(1:ix*iy), ix, iy, 'gbl mslp', 0., 0. ) call sintp16(datan(1:ix*iy),ix,iy,pmsl,glon,glat,sdiag,il) write(6,*)" findxn model mslp(Pa)" call findxn(pmsl,ifull,-1.e29,xa,kx,an,kn) if ( an .gt. 2000. ) then write(6,*)"#########################convert pmsl to hPa" pmsl(1:ifull)=pmsl(1:ifull)/100. ! to convert to hPa endif ! ( an .gt. 2000. ) then else write(6,*)"No pmsl data found, setting to 0" pmsl(1:ifull) = 0. endif ! ier call prt_pan(pmsl,il,jl,2,'pmsl') write(6,*)"================================================zs" ier = nf_inq_varid(ncid,'zs',idvar) ! from input netcdf file write(6,*)"ier=",ier," idvar=",idvar if ( ier .ne. 0 ) then ier = nf_inq_varid(ncid,'topo',idvar) write(6,*)"ier=",ier," idvar=",idvar endif if ( ier .ne. 0 ) then ier = nf_inq_varid(ncid,'topog',idvar) write(6,*)"ier=",ier," idvar=",idvar endif if ( ier .eq. 0 ) then geopotunits="gpm" ier = nf_get_att_text(ncid,idvar,'units',geopotunits) call ncread_2d(ncid,iarch,idvar,ix,iy,datan(1:ix*iy)) ! zsi(m) call findxn(zsi_m,ifull,-1.e29,xa,kx,an,kn) if ( geopotunits=="m" ) then write(6,*) "Converting from meters to gpm" datan(1:ix*iy) = datan(1:ix*iy)*g end if call amap ( datan(1:ix*iy), ix, iy, 'gbl zs', 0., 0. ) call sintp16(datan(1:ix*iy),ix,iy,zsi_m,glon,glat,sdiag,il) ! (m) write(6,*)" findxn zsi_m(m)" ! if ( an .gt. 2000. ) then ! write(6,*)"#########################convert m2/s2 to m" ! do i=1,ifull ! zsi_m(i)=zsi_m(i)/9.80616 ! enddo ! i=1,ifull ! endif ! ( an .gt. 2000. ) then else write(6,*)"No zs data found, setting to -999." zsi_m(1:ifull)=-999. endif ! ier call prt_pan(zs,il,jl,2,'zs(m)') call prt_pan(zsi_m,il,jl,2,'zsi_m(m)') write(6,*)"================================================land" write(6,*)"===================================== 1=land 0=ocean" ier = nf_inq_varid(ncid,'land',idvar) write(6,*)"ier=",ier," idvar=",idvar if ( ier .ne. 0 ) then ier = nf_inq_varid(ncid,'sfc_lsm',idvar) write(6,*)"ier=",ier," idvar=",idvar endif if ( ier .ne. 0 ) then ier = nf_inq_varid(ncid,'land_mask',idvar) write(6,*)"ier=",ier," idvar=",idvar endif if ( ier .ne. 0 ) then ier = nf_inq_varid(ncid,'lnd_mask',idvar) write(6,*)"ier=",ier," idvar=",idvar endif if ( ier .eq. 0 ) then olsm_gbl = .true. call ncread_2d(ncid,1,idvar,ix,iy,datan(1:ix*iy)) ! MJT quick fix datan(1:ix*iy)=abs(datan(1:ix*iy)) ! MJT quick fix lsm_gbl(1:ix*iy)=datan(1:ix*iy) ! MJT quick fix where (abs(lsm_gbl(1:ix*iy))>=1.e10) lsm_gbl(1:ix*iy)=0. end where call amap ( lsm_gbl, ix, iy, 'lsm_gbl', 0., 0. ) call sintp16(lsm_gbl,ix,iy,lsmg_m,glon,glat,sdiag,il) write(6,*)" findxn model lsmg_m" call findxn(lsmg_m,ifull,-1.e29,xa,kx,an,kn) ! if ( xa .gt. 1.5 ) then ! write(6,*)"#################convert so that 0=ocean/1=land" ! do i=1,ifull ! lsmg_m(i)=lsmg_m(i) ! enddo ! i=1,ifull ! endif ! ( an .gt. 2000. ) then else write(6,*)"No landmask data found, setting to -999." lsmg_m(1:ifull)=-999. endif ! ier call prt_pan(lsmg_m,il,jl,2,'lsmg_m') write(6,*)"================================================ps" ier = nf_inq_varid(ncid,'ps',idvar) write(6,*)"ier=",ier," idvar=",idvar if ( ier .ne. 0 ) then ier = nf_inq_varid(ncid,'sfc_pres',idvar) write(6,*)"ier=",ier," idvar=",idvar endif if ( ier .eq. 0 ) then call ncread_2d(ncid,iarch,idvar,ix,iy,datan(1:ix*iy)) if (any(datan(1:ix*iy)>2000)) then datan(1:ix*iy)=datan(1:ix*iy)/100. end if call amap ( datan(1:ix*iy), ix, iy, 'gbl sfcp', 0., 0. ) call sintp16(datan(1:ix*iy),ix,iy,psg_m,glon,glat,sdiag,il) ! remove levels below surface do j = 1,iy do i = 1,ix iq = i + ix*(j-1) do k = nint(validlevhost(iq)),nplev if ( datan(iq)>plev(k) ) then validlevhost(iq) = real(k) exit end if end do end do end do psg_m(1:ifull) = psg_m(1:ifull)*100. ! convert to Pa else write(6,*)"No sfcp data found, setting to -999." psg_m(1:ifull)=-999. end if ! ier call prt_pan(psg_m,il,jl,2,'psg_m') write(6,*)"================================================tss" ier = nf_inq_varid(ncid,'tss',idvar) write(6,*)"ier=",ier," idvar=",idvar if ( ier .ne. 0 ) then ier = nf_inq_varid(ncid,'sfc_temp',idvar) write(6,*)"ier=",ier," idvar=",idvar endif if ( ier .eq. 0 ) then ! we have sfc temp data write(6,*)"input data has sfc temp data, now read in" call ncread_2d(ncid,iarch,idvar,ix,iy,datan(1:ix*iy)) spval=-1.e10 write(6,*)"spval=",spval if (any(datan(1:ix*iy)<100..or.datan(1:ix*iy)>400.)) then write(6,*) "Missing data found in sfc temp" where (datan(1:ix*iy)<100..or.datan(1:ix*iy)>400.) datan(1:ix*iy)=spval end where call fill(datan(1:ix*iy),ix,iy,.1*spval,datan(1+2*ix*iy:3*ix*iy)) end if call amap ( datan(1:ix*iy), ix, iy, 'gbl sfct', 0., 0. ) write(6,*)"###################### do we have olsm_gbl=",olsm_gbl ijgd=igd+ix*(jgd-1) write(6,*)"igd,jgd,ijgd=",igd,jgd,ijgd ijd=id+il*(jd-1) write(6,*)"id,jd,ijd=",id,jd,ijd write(6,*)"prepare to interp. tss for sea and land separately" write(6,*)"igd,jgd,gtss=",igd,jgd,datan(ijgd) write(6,*)"putting only land values into datan" write(6,*)"putting only ocean values into datan(+ix*iy)" !not done since tss already at sea level write(6,*)"First: reduce tss to sea level" nlpnts=0 nopnts=0 do j=1,iy do i=1,ix iq = i+(j-1)*ix datan(iq+ix*iy)=datan(iq) ! for ocean pts if(olsm_gbl)then if ( lsm_gbl(iq) .lt. .5 ) then datan(iq)=spval ! land, fill in ocean pts nlpnts=nlpnts+1 else !!! ( lsm_gbl(iq) .lt. .5 ) then datan(iq+ix*iy)=spval ! ocean, fill in land pts nopnts=nopnts+1 endif ! ( lsm_gbl(iq) .gt. .5 ) then endif!(olsm_gbl)then enddo ! ix enddo ! iy write(6,*)"two global tss arrays with spval=", spval write(6,*)"igd,jgd,lgtss=",igd,jgd,datan(ijgd) write(6,*)"igd,jgd,ogtss=",igd,jgd,datan(ijgd+ix*iy) write(6,*)"fill in missing values nlpnts,nopnts=",nlpnts,nopnts write(6,*)"=======> for land array, fill in tss ocean values" call fill(datan(1:ix*iy),ix,iy,.1*spval,datan(1+2*ix*iy:3*ix*iy)) if(olsm_gbl .and. nopnts.gt.0)then write(6,*)"=======> for ocean array, fill in tss land values" call fill(datan(1+ix*iy:2*ix*iy),ix,iy,.1*spval,datan(1+2*ix*iy:3*ix*iy)) endif!(olsm_gbl)then write(6,*)"igd,jgd,lgtss=",igd,jgd,datan(ijgd) write(6,*)"igd,jgd,ogtss=",igd,jgd,datan(ijgd+ix*iy) !not done since tss already at sea level write(6,*)"tss at sea level here" write(6,*)"=========================> now interp. land data" call sintp16(datan(1:ix*iy),ix,iy,sfct,glon,glat,sdiag,il) ! land if(olsm_gbl .and. nopnts.gt.0)then write(6,*)"=========================> now interp. ocean data" call sintp16(datan(1+ix*iy:2*ix*iy),ix,iy,sfcto_m,glon,glat,sdiag,il) ! ocean endif!(olsm_gbl)then call prt_pan(sfct ,il,jl,2,'tss') call prt_pan(sfcto_m,il,jl,2,'tsso') write(6,*)"id,jd,ltss=",id,jd,sfct(ijd) write(6,*)"id,jd,otss=",id,jd,sfcto_m(ijd) if(olsm_gbl)then write(6,*)"now recombine two (land/ocean) fields" !not done since tss already at sea level write(6,*)"Also need to recompute tss at zs" do j=1,jl do i=1,il iq=i+(j-1)*il !not done since tss already at sea level sfct(i,j)=sfct(i,j)-zs(iq)*.0065 !not done since tss already at sea level sfctl_m(i,j)=sfctl_m(i,j)-zs(iq)*.0065 ! remeber, land < .5 is an ocean point if ( lsm_m(iq) .lt. .5 ) sfct(iq)=sfcto_m(iq) ! set to ocean interp pnt enddo ! i enddo ! j endif!(olsm_gbl)then write(6,*)"id,jd,sfct=",id,jd,sfct(ijd) write(6,*)" findxn model sfct" call findxn(sfct,ifull,-1.e29,xa,kx,an,kn) else write(6,*)"###################no sfc temp data in input dataset" write(6,*)"###################setting sfc temp data to 0!!!!!!!" sfct(1:il*jl) = 0. endif ! ier eq 0 , sfct call prt_pan(sfct,il,jl,2,'sfct') write(6,*)"============================================fracice" fracice=-1. ier = nf_inq_varid(ncid,'fracice',idvar) write(6,*)"ier=",ier," idvar=",idvar if ( ier .ne. 0 ) then ier = nf_inq_varid(ncid,'seaice',idvar) write(6,*)"ier=",ier," idvar=",idvar endif if ( ier .eq. 0 ) then ! we have fracice data write(6,*)"input data has fracice data, now read in" call ncread_2d(ncid,iarch,idvar,ix,iy,datan(1:ix*iy)) where (datan(1:ix*iy).gt.1.01) datan(1:ix*iy)=0. end where call amap ( datan(1:ix*iy), ix, iy, 'gbl fice', 0., 0. ) spval=-1.e10 write(6,*)"spval=",spval write(6,*)"###################### do we have olsm_gbl=",olsm_gbl ijgd=igd+ix*(jgd-1) write(6,*)"igd,jgd,ijgd=",igd,jgd,ijgd ijd=id+il*(jd-1) write(6,*)"id,jd,ijd=",id,jd,ijd write(6,*)"prepare to interp. fracice" write(6,*)"igd,jgd,gtss=",igd,jgd,datan(ijgd) nlpnts=0 nopnts=0 do j=1,iy do i=1,ix iq = i+(j-1)*ix datan(iq+ix*iy)=datan(iq) ! for ocean pts if(olsm_gbl)then if ( lsm_gbl(iq) .ge. .5 ) then datan(iq+ix*iy)=spval ! ocean, fill in land pts nopnts=nopnts+1 else nlpnts=nlpnts+1 endif ! ( lsm_gbl(iq) .ge. .5 ) then endif!(olsm_gbl)then enddo ! ix enddo ! iy write(6,*)"global fracice array with spval=", spval write(6,*)"igd,jgd,ogtss=",igd,jgd,datan(ijgd+ix*iy) write(6,*)"fill in missing values nlpnts,nopnts=",nlpnts,nopnts write(6,*)"===> for ocean array, fill in fracice land values" call fill(datan(1+ix*iy:2*ix*iy),ix,iy,.1*spval,datan(1+2*ix*iy:3*ix*iy)) write(6,*)"igd,jgd,ogtss=",igd,jgd,datan(ijgd+ix*iy) write(6,*)"=========================> now interp. ocean data" call sintp16(datan(1+ix*iy:2*ix*iy),ix,iy,fracice,glon,glat,sdiag,il) ! ocean call prt_pan(fracice,il,jl,2,'fracice') where (lsm_m.ge.0.5) fracice=0. end where write(6,*)"id,jd,fracice=",id,jd,fracice(ijd) write(6,*)" findxn model fracice" call findxn(fracice,ifull,-1.e29,xa,kx,an,kn) else write(6,*)"###############no fracice data in input dataset" write(6,*)"###############setting fracice data to -1.!!!!!!!" fracice(1:ifull) = -1. endif ! ier eq 0 , sfct call prt_pan(fracice,il,jl,2,'fracice') write(6,*)"================================================snod" ier = nf_inq_varid(ncid,'snod',idvar) write(6,*)"ier=",ier," idvar=",idvar if ( ier .ne. 0 ) then ier = nf_inq_varid(ncid,'snow_amt_lnd',idvar) write(6,*)"ier=",ier," idvar=",idvar endif snod(:) = 0. if ( ier .eq. 0 ) then call ncread_2d(ncid,iarch,idvar,ix,iy,datan(1:ix*iy)) ! fix for missing values where ( datan(1:ix*iy) > 1000. ) datan(1:ix*iy)=0. end where call amap ( datan(1:ix*iy), ix, iy, 'snod', 0., 0. ) call sintp16(datan(1:ix*iy),ix,iy,snod,glon,glat,sdiag,il) ! convert to equiv water snod(:) = snod(:)*100./1000. where ( lsm_m(:)<0.5 ) snod(:)=0. end where else write(6,*)"No snod data found, setting to 0." snod(:)=0. endif ! ier call prt_pan(snod,il,jl,2,'snod') !############################################################################ ! end sfc data !############################################################################ !############################################################################ ! soil data !############################################################################ write(6,*)"============================================soil_temp" soiltemp(:,:)=-1. ier = nf_inq_varid(ncid,'soil_temp',idvar) write(6,*)"ier=",ier," idvar=",idvar," nsoillvl=",nsoillvl if ( ier==0 ) then ! we have soil_temp data call ncread_3d(ncid,iarch,idvar,ix,iy,nsoillvl,datan) call filldat(datan,ix,iy,nsoillvl) call amap ( datan, ix, iy, 'input soil_temp', 0., 0. ) ! interpolate to CCAM soil levels ksearch = 2 do k = 1,6 write(6,*)"************************************************k=",k do ktest = ksearch,nsoillvl if ( soildepth_in(ktest)>soildepth_ccam(k) ) exit end do ksearch = max( min( ktest, nsoillvl ), 2 ) if ( soildepth_ccam(k)soildepth_in(ksearch) ) then ! extrapolate datatemp(:) = datan((nsoillvl-1)*ix*iy+1:nsoillvl*ix*iy) ! last level else ! interpolate xfrac = ( soildepth_ccam(k) - soildepth_in(ksearch-1) ) / ( soildepth_in(ksearch) - soildepth_in(ksearch-1) ) datatemp(:) = (1.-xfrac)*datan((ksearch-2)*ix*iy+1:(ksearch-1)*ix*iy) & + xfrac*datan((ksearch-1)*ix*iy+1:ksearch*ix*iy) end if call sintp16(datatemp(:),ix,iy,soiltemp(:,k),glon,glat,sdiag,il) end do end if write(6,*)"============================================soil_mois" soilmoist(:,:)=-1. ier = nf_inq_varid(ncid,'soil_mois',idvar) write(6,*)"ier=",ier," idvar=",idvar," nsoillvl=",nsoillvl if ( ier==0 ) then ! we have soil_moist data ! check units ier = nf_get_att_text(ncid,idvar,'units',soilunits) write(6,*)"ier=",ier," soilunits=",trim(soilunits) call ncread_3d(ncid,iarch,idvar,ix,iy,nsoillvl,datan) call filldat(datan,ix,iy,nsoillvl) call amap ( datan, ix, iy, 'input soil_mois', 0., 0. ) ! interpolate to CCAM soil levels ksearch = 2 do k = 1,6 write(6,*)"************************************************k=",k do ktest = ksearch,nsoillvl if ( soildepth_in(ktest)>soildepth_ccam(k) ) exit end do ksearch = max( min( ktest, nsoillvl ), 2 ) if ( soildepth_ccam(k)soildepth_in(ksearch) ) then ! extrapolate datatemp(:) = datan((nsoillvl-1)*ix*iy+1:nsoillvl*ix*iy) ! last level else ! interpolate xfrac = ( soildepth_ccam(k) - soildepth_in(ksearch-1) ) / ( soildepth_in(ksearch) - soildepth_in(ksearch-1) ) datatemp(:) = (1.-xfrac)*datan((ksearch-2)*ix*iy+1:(ksearch-1)*ix*iy) & + xfrac*datan((ksearch-1)*ix*iy+1:ksearch*ix*iy) end if if ( trim(soilunits)=="kg m-2" ) then ! fix units from kg/m2 to m3/m3 write(6,*) "Converting units from kg/m2 to m3/m3" datatemp(:) = datatemp(:)/soilthick_ccam(k)/rhowater end if call sintp16(datatemp(:),ix,iy,soilmoist(:,k),glon,glat,sdiag,il) end do end if !############################################################################ ! end soil data !############################################################################ write(6,*)"check of temp data to ensure all is going okay" write(6,*)" findxn model temp(1)" call findxn(temp(:,:,1),ifull,-1.e29,xa,kx,an,kn) write(6,*)" findxn model temp(nplev)" call findxn(temp(:,:,nplev),ifull,-1.e29,xa,kx,an,kn) write(6,*)"nplev=",nplev ! constrain rh to 0-100 do k=1,nplev do j=1,jl do i=1,il rh(i,j,k)=min(100.,max(0.,rh(i,j,k))) enddo ! i enddo ! j enddo ! k !############### fix winds if CC grid ############################### if ( ogbl ) then ! here use unstaggered lats and lons for u and v ! For calculating zonal and meridional wind components, use the ! following information, where theta is the angle between the ! (ax,ay,az) vector [along the xg axis] and the zonal-component-vector: ! veczon = k x r, i.e. (-y,x,0)/sqrt(x**2 + y**2) ! vecmer = r x veczon, i.e. (-xz,-yz,x**2 + y**2)/sqrt(x**2 + y**2) ! costh is (veczon . a) = (-y*ax + x*ay)/sqrt(x**2 + y**2) ! sinth is (vecmer . a) = [-xz*ax - yz*ay + (x**2 + y**2)*az]/sqrt ! using (r . a)=0, sinth collapses to az/sqrt(x**2 + y**2) ! For rotated coordinated version, see JMcG's notes coslong=cos(rlong0*pi/180.) sinlong=sin(rlong0*pi/180.) coslat=cos(rlat0*pi/180.) sinlat=sin(rlat0*pi/180.) polenx=-coslat poleny=0. polenz=sinlat write(6,*)'polenx,poleny,polenz ',polenx,poleny,polenz write(6,*)'x(1),y(1),z(1)',x(1),y(1),z(1) write(6,*)'ax(1),ay(1),az(1)',ax(1),ay(1),az(1) write(6,*)'bx(1),by(1),bz(1)',bx(1),by(1),bz(1) write(6,*)'before zon/meridional' call maxmin(u,' u',0,1.,il,nplev) call maxmin(v,' v',0,1.,il,nplev) write(6,*)"convert winds to CCAM grid convention" cx=-1.e29 sx=-1.e29 cn= 1.e29 sn= 1.e29 do j=1,jl do i=1,il iq=i+(j-1)*il ! set up unit zonal vector components zonx= -polenz*y(iq) zony=polenz*x(iq)-polenx*z(iq) zonz=polenx*y(iq) den=sqrt( max(zonx**2 + zony**2 + zonz**2,1.e-7) ) ! allow for poles costh= (zonx*ax(iq)+zony*ay(iq)+zonz*az(iq))/den sinth=-(zonx*bx(iq)+zony*by(iq)+zonz*bz(iq))/den cx=max(cx,costh) sx=max(sx,sinth) cn=min(cn,costh) sn=min(sn,sinth) do k=1,nplev uzon = u(i,j,k) vmer = v(i,j,k) u(i,j,k)= costh*uzon+sinth*vmer v(i,j,k)=-sinth*uzon+costh*vmer end do ! k loop end do end do write(6,*)'cx,cn,sx,sn=',cx,cn,sx,sn write(6,*)'after zon/meridional' call maxmin(u(:,:,1:nplev),' u',0,1.,il,nplev) call maxmin(v(:,:,1:nplev),' v',0,1.,il,nplev) call maxmin(hgt(:,:,1:nplev),' hgt',0,.001,il,nplev) call maxmin(temp(:,:,1:nplev),' temp',0,1.,il,nplev) call maxmin(rh(:,:,1:nplev),' rh',0,1.,il,nplev) !############### fix winds if DARLAM grid ############################### else ! not ogbl ! convert e-w/n-s lat/lon winds to model winds ! loop over all model grid points do k=1,nplev write(6,*)k,temp(1,1,k),u(1,1,k),v(1,1,k) do j=1,jl do i=1,il ! get lat lon of model grid ( just to get ther ) call lconll(rlon,rlat,float(i),float(j)) ! calculate ucmp l.c.winds ! ulc=v@u*s(th)+u@u*c(th) ull = u(i,j,k) vll = v(i,j,k) u(i,j,k)=vll*sin(ther)+ull*cos(ther) ! calculate vcmp l.c.winds ! vlc=v@v*c(th)-u@v*s(th) v(i,j,k)=vll*cos(ther)-ull*sin(ther) enddo ! i enddo ! j write(6,*)k,temp(1,1,k),u(1,1,k),v(1,1,k) enddo ! k endif ! not ogbl i=il/2 j=jl/2 write(6,'(6a10," at i,j=",2i3)') "p","z","t","u","v","rh",i,j write(6,*)"invert order of plev nplev=",nplev write(6,'(6a10)')"plev","hgt","temp","u","v","rh/mr" xplev = maxval( plev(1:nplev) ) tohpa = 1. if ( xplev > 1500. ) then tohpa = 0.01 end if do k=1,nplev cplev(k)=tohpa*plev(nplev+1-k) write(6,'(5f10.2,f10.5)') cplev(k),hgt(i,j,k),temp(i,j,k),u(i,j,k),v(i,j,k),rh(i,j,k) enddo ! k=1,nplev iq=il/2+(jl/2-1)*il write(6,'("pmsl=",f12.2," sfct=",f12.2)') pmsl(iq),sfct(iq) ! intepolate valid level call amap ( validlevhost, ix, iy, 'gbl levl', 0., 0. ) call sintp16(validlevhost,ix,iy,validlevcc,glon,glat,sdiag,il) write(6,*)"calling vidar now!! ntimes,iarch=",ntimes,iarch if2=0 !####################################################################### call vidar(nplev,hgt,temp,u,v,rh,validlevcc,iyr,imn,idy,ihr,iarch,time,mtimer,cplev,io_out,il,kl,merge, & minlon,maxlon,minlat,maxlat,llrng) !####################################################################### enddo ! narch deallocate(datan,zs_gbl,lsm_gbl) deallocate(glon,glat) deallocate(datatemp,validlevhost) write(6,*)'*********** Finished cdfvidar ************************' deallocate(x,y,z,ax,ay,az,bx,by,bz) deallocate(hgt,temp,u,v,rh) deallocate(sfcto_m,lsmg_m) deallocate(zsg) call sigdatadealloc call latlongdealloc call clldealloc call comsigdealloc ! Complete write(6,*) "CCAM: cdfvidar completed successfully" ! End banner call finishbanner stop end ! cdfvidar !*************************************************************************** subroutine ncread_2d(idhist,iarch,idvar,il,jl,var) use netcdf_m implicit none ! include 'gblparm.h' integer idhist,il,jl,iarch,idvar integer i,j,ij,ier,itype integer start(3),count(3) real var(il*jl), addoff, sf real dx, dn integer*2, dimension(:), allocatable :: ivar double precision, dimension(:), allocatable :: dvar ! integer*2 ivar(nnx*nny) character*30 name write(6,*)"=============================> ncread_2d idhist=",idhist write(6,*)"iarch=",iarch," idvar=",idvar write(6,*)"il=",il," jl=",jl ! read name ier = nf_inq_varname(idhist,idvar,name) write(6,*)"ier=",ier," name=",name if(ier.eq.0)then ! if(il*jl.gt.nnx*nny)stop "ncread_2d il*jl.gt.nnx*nny" start(1) = 1 start(2) = 1 start(3) = iarch count(1) = il count(2) = jl count(3) = 1 write(6,'("start=",4i4)') start write(6,'("count=",4i4)') count ier = nf_inq_vartype(idhist,idvar,itype) write(6,*)"itype=",itype," ier=",ier if ( itype .eq. nf_short ) then allocate(ivar(il*jl)) write(6,*)"variable is short" ier = nf_get_vara_int2(idhist,idvar,start,count,ivar) write(6,*)"ivar(1)=",ivar(1)," ier=",ier write(6,*)"ivar(il*jl)=",ivar(il*jl) else if ( itype .eq. nf_float ) then write(6,*)"variable is float" ier = nf_get_vara_real(idhist,idvar,start,count,var) write(6,*)"var(1)=",var(1)," ier=",ier write(6,*)"var(il*jl)=",var(il*jl) else if ( itype .eq. nf_double ) then allocate(dvar(il*jl)) write(6,*)"variable is double" ier = nf_get_vara_double(idhist,idvar,start,count,dvar) write(6,*)"dvar(1)=",dvar(1)," ier=",ier write(6,*)"dvar(il*jl)=",dvar(il*jl) else write(6,*)"variable is unknown" call finishbanner stop -1 endif ! obtain scaling factors and offsets from attributes ier = nf_get_att_real(idhist,idvar,'add_offset',addoff) if ( ier.ne.0 ) addoff=0. write(6,*)"ier=",ier," addoff=",addoff ier = nf_get_att_real(idhist,idvar,'scale_factor',sf) if ( ier.ne.0 ) sf=1. write(6,*)"ier=",ier," addoff=",addoff else!(ier.eq.0)then ! no data found do i=1,il*jl var(i)=0 enddo sf=0. addoff=0. endif!(ier.eq.0)then ! unpack data dx=-1.e29 dn= 1.e29 do j=1,jl do i=1,il ij=i+(j-1)*il if ( itype .eq. nf_short ) then if(i.eq.1.and.j.eq.1) write(6,*)"ivar,sf,addoff=",ivar(ij),sf,addoff var(ij) = ivar(ij)*sf + addoff else if ( itype .eq. nf_float ) then if(i.eq.1.and.j.eq.1) write(6,*)"var,sf,addoff=",var(ij),sf,addoff var(ij) = var(ij)*sf + addoff else if(i.eq.1.and.j.eq.1) write(6,*)"var,sf,addoff=",dvar(ij),sf,addoff var(ij) = dvar(ij)*sf + addoff endif dx=max(dx,var(ij)) dn=min(dn,var(ij)) end do end do write(6,*)"ncread_2d idvar=",idvar," iarch=",iarch write(6,*)"ncread_2d dx=",dx," dn=",dn if ( itype .eq. nf_short ) then deallocate(ivar) endif if ( itype .eq. nf_double ) then deallocate(dvar) end if return ! ncread_2d end !*************************************************************************** subroutine ncread_3d(idhist,iarch,idvar,il,jl,kl,var) ! call ncread_3d(ncid,iarch,idvar,ix,iy,nplev,datan) use netcdf_m implicit none ! include 'gblparm.h' integer, dimension(4) :: start,count integer, intent(in) :: idhist, iarch, idvar integer, intent(in) :: il, jl, kl integer ier, itype, i, j, k, ijk real addoff, sf real dx, dn integer*2, dimension(:), allocatable :: ivar double precision, dimension(:), allocatable :: dvar real, dimension(il*jl*kl), intent(out) :: var character*30 name write(6,*)"ncread_2d idhist=",idhist write(6,*)"iarch=",iarch," idvar=",idvar write(6,*)"il=",il," jl=",jl ier = nf_inq_varname(idhist,idvar,name) write(6,*)"ier=",ier," name=",name start(1) = 1 start(2) = 1 start(3) = 1 start(4) = iarch count(1) = il count(2) = jl count(3) = kl count(4) = 1 write(6,'("start=",4i4)') start write(6,'("count=",4i4)') count ! read data write(6,*)"idhist=",idhist," idvar=",idvar ier = nf_inq_vartype(idhist,idvar,itype) write(6,*)"ier=",ier," itype=",itype addoff=0. sf=1. if ( itype .eq. nf_short ) then write(6,*)"variable is short" allocate( ivar(il*jl*kl) ) ier = nf_get_vara_int2(idhist,idvar,start,count,ivar) else if ( itype .eq. nf_float ) then write(6,*)"variable is float" ier = nf_get_vara_real(idhist,idvar,start,count,var) else if ( itype .eq. nf_double ) then write(6,*)"variable is double" allocate( dvar(il*jl*kl) ) ier = nf_get_vara_double(idhist,idvar,start,count,dvar) var=real(dvar) else write(6,*)"variable is unknown" call finishbanner stop -1 endif if ( itype .eq. nf_short ) then write(6,*)"obtain scaling factors and offsets from attributes" ier = nf_get_att_real(idhist,idvar,'add_offset',addoff) if ( ier.ne.0 ) addoff=0. write(6,*)"ier=",ier," addoff=",addoff ier = nf_get_att_real(idhist,idvar,'scale_factor',sf) if ( ier.ne.0 ) sf=1. write(6,*)"ier=",ier," sf=",sf endif ! unpack data dx=-1.e29 dn= 1.e29 do k=1,kl do j=1,jl do i=1,il ijk=i+(j-1)*il+(k-1)*il*jl if(i.eq.1.and.j.eq.1.and.k.eq.1) write(6,*)"i,j,k,ijk=",i,j,k,ijk if ( itype .eq. nf_short ) then if(i.eq.1.and.j.eq.1.and.k.eq.1) write(6,*)"ivar,sf,addoff=",ivar(ijk),sf,addoff var(ijk) = real(ivar(ijk))*sf + addoff else if(i.eq.1.and.j.eq.1.and.k.eq.1) write(6,*)"var,sf,addoff=",var(ijk),sf,addoff var(ijk) = var(ijk)*sf + addoff endif if(i.eq.1.and.j.eq.1.and.k.eq.1) write(6,*)"var=",var(ijk) dx=max(dx,var(ijk)) dn=min(dn,var(ijk)) end do end do end do if ( itype .eq. nf_short ) then deallocate( ivar ) end if if ( itype .eq. nf_double ) then deallocate( dvar ) end if write(6,*)"ncread_3d idvar=",idvar," iarch=",iarch write(6,*)"ncread_3d dx=",dx," dn=",dn return ! ncread_3d end !*********************************************************************** function icmonth_to_imn(cmonth) integer icmonth_to_imn character*(*) cmonth write(6,*)"icmonth_to_imn cmonth=",cmonth icmonth_to_imn=0 if ( cmonth.eq.'jan' ) icmonth_to_imn=1 if ( cmonth.eq.'feb' ) icmonth_to_imn=2 if ( cmonth.eq.'mar' ) icmonth_to_imn=3 if ( cmonth.eq.'apr' ) icmonth_to_imn=4 if ( cmonth.eq.'may' ) icmonth_to_imn=5 if ( cmonth.eq.'jun' ) icmonth_to_imn=6 if ( cmonth.eq.'jul' ) icmonth_to_imn=7 if ( cmonth.eq.'aug' ) icmonth_to_imn=8 if ( cmonth.eq.'sep' ) icmonth_to_imn=9 if ( cmonth.eq.'oct' ) icmonth_to_imn=10 if ( cmonth.eq.'nov' ) icmonth_to_imn=11 if ( cmonth.eq.'dec' ) icmonth_to_imn=12 write(6,*)"icmonth_to_imn=",icmonth_to_imn return end !*********************************************************************** subroutine getvalidlev(validlev,datan,ix,iy,plev) implicit none integer, intent(in) :: ix,iy,plev integer i,j,k,iq,iqk real, dimension(ix*iy), intent(inout) :: validlev real, dimension(ix*iy*plev), intent(in) :: datan do j = 1,iy do i = 1,ix iq = i + ix*(j-1) do k = nint(validlev(iq)),plev iqk = i + ix*(j-1) + ix*iy*(k-1) if ( datan(iqk)<1.E10 ) then validlev(iq) = real(k) exit end if end do end do end do return end subroutine getvalidlev subroutine filldat(datan,ix,iy,plev) implicit none integer, intent(in) :: ix,iy,plev integer i,j,k,is,ie,iqk,iqn integer ncount real, dimension(ix*iy*plev), intent(inout) :: datan real, dimension(ix*iy) :: datatemp real datasum if ( any(datan(:)>9.e9) ) then write(6,*) "Using filldat to remove missing values" end if do k = 1,plev is = ix*iy*(k-1) + 1 ie = ix*iy*k if (all(datan(is:ie)>9.E9)) then write(6,*) "ERROR: No valid data on level" call finishbanner stop -1 end if datatemp(:) = datan(is:ie) do while ( any(datatemp(:)>9.E9) ) do j = 1,iy do i = 1,ix iqk = i + ix*(j-1) ! no vertical dimension for datatemp if (datatemp(iqk)>9.e9) then ncount = 0 datasum = 0. if ( j1 ) then iqn = i + ix*(j-2) + ix*iy*(k-1) if ( datan(iqn)<=9.e9 ) then datasum = datasum + datan(iqn) ncount = ncount + 1 end if end if if ( i1 ) then iqn = i - 1 + ix*(j-1) + ix*iy*(k-1) else iqn = ix + ix*(j-1) + ix*iy*(k-1) end if if ( datan(iqn)<=9.e9 ) then datasum = datasum + datan(iqn) ncount = ncount + 1 end if if ( ncount>0 ) then datatemp(iqk) = datasum/real(ncount) end if end if end do end do datan(is:ie) = datatemp(:) end do end do return end subroutine filldat subroutine processdatestring(datestring,yyyy,mm,dd,hh,mt) implicit none integer, intent(out) :: yyyy, mm, dd, hh, mt integer iposa, iposb, ierx character(len=*), intent(in) :: datestring !if ( datestring(1:7)/='minutes' ) then ! write(6,*) "ERROR: Time units expected to be minutes" ! write(6,*) "Found ",trim(datestring) ! stop -1 !end if ! process year iposa = index(trim(datestring),'since') iposa = iposa + 5 ! skip 'since' iposb = index(trim(datestring(iposa:)),'-') iposb = iposa + iposb - 2 ! remove '-' read(datestring(iposa:iposb),FMT=*,iostat=ierx) yyyy if ( ierx/=0 ) then write(6,*) "ERROR reading time units. Expecting year but found ",datestring(iposa:iposb) call finishbanner stop -1 end if ! process month iposa = iposb + 2 ! skip '-' iposb = index(trim(datestring(iposa:)),'-') iposb = iposa + iposb - 2 ! remove '-' read(datestring(iposa:iposb),FMT=*,iostat=ierx) mm if ( ierx/=0 ) then write(6,*) "ERROR reading time units. Expecting month but found ",datestring(iposa:iposb) call finishbanner stop -1 end if ! process day iposa = iposb + 2 ! skip '-' iposb = index(trim(datestring(iposa:)),' ') iposb = iposa + iposb - 2 ! remove ' ' read(datestring(iposa:iposb),FMT=*,iostat=ierx) dd if ( ierx/=0 ) then write(6,*) "ERROR reading time units. Expecting day but found ",datestring(iposa:iposb) call finishbanner stop -1 end if ! process hour iposa = iposb + 2 ! skip ' ' iposb = index(trim(datestring(iposa:)),':') iposb = iposa + iposb - 2 ! remove ':' read(datestring(iposa:iposb),FMT=*,iostat=ierx) hh if ( ierx/=0 ) then write(6,*) "ERROR reading time units. Expecting hour but found ",datestring(iposa:iposb) call finishbanner stop -1 end if ! process mins iposa = iposb + 2 ! skip ':' iposb = index(trim(datestring(iposa:)),':') iposb = iposa + iposb - 2 ! remove ':' read(datestring(iposa:iposb),FMT=*,iostat=ierx) mt if ( ierx/=0 ) then write(6,*) "ERROR reading time units. Expecting minutes but found ",datestring(iposa:iposb) call finishbanner stop -1 end if return end subroutine processdatestring subroutine finishbanner implicit none ! End banner write(6,*) "==============================================================================" write(6,*) "CCAM: Finished cdfvidar" write(6,*) "==============================================================================" return end