subroutine readvbc c c======================================================================= c === c This routine reads in vertical boundary conditions data from === c input forcing NetCDF file. === c === c======================================================================= c c----------------------------------------------------------------------- c Define global data. c----------------------------------------------------------------------- c #include #include #include #include #include #include #include #include #if defined resetjulian # include #endif c c----------------------------------------------------------------------- c Define local data. c----------------------------------------------------------------------- c logical first integer dimid,dimsiz,lendim,lenstr,lenvar,n,ndims,ngatts,nvars, * nvatts,nvdims,recdim,vartyp integer count(4),vdims(4),start(4) integer lnblk FLOAT * tsshf,tssmf,tsswf,tsswr,dstarf #if defined bioMcGillic | defined bioFasham | defined bioAnder | defined bioDuse * ,tssnf #endif character*20 dimnam,varnam save first,dstarf data first /.true./ c c======================================================================= c Begin executable code. c======================================================================= c c======================================================================= c On first call, open and inquire input forcing NetCDF. c======================================================================= c c Initialize switches. c if(first) then first=.false. lsmflux=.false. lsmfgrd=.false. lshflux=.false. lshfgrd=.false. lswflux=.false. lswfgrd=.false. lsnflux=.false. lsnfgrd=.false. lswrad=.false. lswrgrd=.false. ntsmf=0 ntshf=0 ntswf=0 ntsnf=0 ntswr=0 itsmf=1 itshf=1 itswf=1 itsnf=1 itswr=1 tsmfindx=0 tshfindx=0 tswfindx=0 tsnfindx=0 tswrindx=0 tsmf(itsmf)=c0 tshf(itshf)=c0 tswf(itswf)=c0 #if defined bioMcGillic | defined bioFasham | defined bioAnder | defined bioDuse tsnf(itsnf)=c0 #endif tswr(itswr)=c0 #ifndef resetjulian dstarf=dstart #else dstarf=d0start #endif c c Open input forcing NetCDF. c lenstr=lnblk(frcname,len(frcname)) ncfrcid=ncopn(frcname(1:lenstr),ncnowrit,rcode) if(rcode.ne.0) then write(stdout,900) frcname(1:lenstr) call exitus('READVBC') endif c c----------------------------------------------------------------------- c Inquire about the content of forcing NetCDF file. c----------------------------------------------------------------------- c call ncinq(ncfrcid,ndims,nvars,ngatts,recdim,rcode) if(rcode.eq.0) then c c Inquire about variables. c do 10 n=1,nvars varid=n call ncvinq(ncfrcid,varid,varnam,vartyp,nvdims,vdims,nvatts, * rcode) lenvar=lnblk(varnam,len(varnam)) if(varnam(1:lenvar).eq.'shflux') then if(nvdims.gt.1) lshfgrd=.true. lshflux=.true. shfid=n elseif(varnam(1:lenvar).eq.'smflux') then if(nvdims.gt.2) lsmfgrd=.true. lsmflux=.true. smfid=n elseif(varnam(1:lenvar).eq.'snflux') then if(nvdims.gt.1) lsnfgrd=.true. lsnflux=.true. snfid=n elseif(varnam(1:lenvar).eq.'swflux') then if(nvdims.gt.1) lswfgrd=.true. lswflux=.true. swfid=n elseif(varnam(1:lenvar).eq.'swrad') then if(nvdims.gt.1) lswrgrd=.true. lswrad=.true. swrid=n elseif(varnam(1:lenvar).eq.'shf_time') then shftid=n elseif(varnam(1:lenvar).eq.'smf_time') then smftid=n elseif(varnam(1:lenvar).eq.'snf_time') then snftid=n elseif(varnam(1:lenvar).eq.'swf_time') then swftid=n elseif(varnam(1:lenvar).eq.'swr_time') then swrtid=n endif if(rcode.ne.0) then write(stdout,910) n,frcname call exitus('READVBC') endif 10 continue c c Inquire about dimensions. c do 20 n=1,ndims dimid=n call ncdinq(ncfrcid,dimid,dimnam,dimsiz,rcode) if(rcode.ne.0) then write(stdout,920) n,frcname call exitus('READVBC') endif lendim=lnblk(dimnam,len(dimnam)) if(dimnam(1:lendim).eq.'tlon') then tlonsiz=dimsiz elseif(dimnam(1:lendim).eq.'tlat') then tlatsiz=dimsiz elseif(dimnam(1:lendim).eq.'vlon') then vlonsiz=dimsiz elseif(dimnam(1:lendim).eq.'vlat') then vlatsiz=dimsiz elseif(dimnam(1:lendim).eq.'shf_time') then ntshf=dimsiz elseif(dimnam(1:lendim).eq.'smf_time') then ntsmf=dimsiz elseif(dimnam(1:lendim).eq.'snf_time') then ntsnf=dimsiz elseif(dimnam(1:lendim).eq.'swf_time') then ntswf=dimsiz elseif(dimnam(1:lendim).eq.'swr_time') then ntswr=dimsiz endif 20 continue else write(stdout,930) frcname call exitus('READVBC') endif c c Check dimension values. c if(lshfgrd.or.lswfgrd.or.lsnfgrd.or.lswrgrd) then if(tlonsiz.ne.imt) then write(stdout,940) 'TLON, IMT = ',tlonsiz,imt call exitus('READVBC') endif if(tlatsiz.ne.jmt) then write(stdout,940) 'TLAT, JMT = ',tlatsiz,jmt call exitus('READVBC') endif endif if(lsmfgrd) then if(vlonsiz.ne.imt) then write(stdout,940) 'VLON, IMT = ',vlonsiz,imt call exitus('READVBC') endif if(vlatsiz.ne.jmt) then write(stdout,940) 'VLAT, JMT = ',vlatsiz,jmt call exitus('READVBC') endif endif c c Ensure presence of data. c lsmflux = lsmflux .and. (ntsmf.gt.0) lshflux = lshflux .and. (ntshf.gt.0) lswflux = lswflux .and. (ntswf.gt.0) lsnflux = lsnflux .and. (ntsnf.gt.0) lswrad = lswrad .and. (ntswr.gt.0) c if (.not.(lsmflux.or.lshflux.or.lswflux.or. * lsnflux.or.lswrad)) then write(stdout,945) frcname(1:lenstr) call exitus('READVBC') endif c c----------------------------------------------------------------------- c Initialize surface forcing rolling storage. c----------------------------------------------------------------------- c c Surface momentum flux (dynes/cm^2). c if (lsmflux) then start(1)=1 count(1)=1 call ncvgt(ncfrcid,smftid,start,count,tsmf(1-itsmf),rcode) write(stdout,*) ' reading momentum forcing day ',tsmf(1-itsmf) if(rcode.ne.0) then write(stdout,950) 'smf_time',1 call exitus('READVBC') endif start(1)=min(2,ntsmf) call ncvgt(ncfrcid,smftid,start,count,tsmf(itsmf),rcode) write(stdout,*) ' reading momentum forcing day ',tsmf(itsmf) if(rcode.ne.0) then write(stdout,950) 'smf_time',start(1) call exitus('READVBC') endif if(lsmfgrd) then start(1)=1 count(1)=2 start(2)=1 count(2)=imt start(3)=1 count(3)=jmt start(4)=1 count(4)=1 call ncvgt(ncfrcid,smfid,start,count,smflux(1,1,1,1-itsmf), * rcode) if(rcode.ne.0) then write(stdout,950) 'smflux',1 call exitus('READVBC') endif start(4)=min(2,ntsmf) call ncvgt(ncfrcid,smfid,start,count,smflux(1,1,1,itsmf), * rcode) if(rcode.ne.0) then write(stdout,950) 'smflux',start(4) call exitus('READVBC') endif else start(1)=1 count(1)=2 start(2)=1 count(2)=1 call ncvgt(ncfrcid,smfid,start,count,smfx(1,1-itsmf),rcode) if(rcode.ne.0) then write(stdout,950) 'smflux',1 call exitus('READVBC') endif start(2)=min(2,ntsmf) call ncvgt(ncfrcid,smfid,start,count,smfx(1,itsmf),rcode) if(rcode.ne.0) then write(stdout,950) 'smflux',start(2) call exitus('READVBC') endif endif endif c c Surface (net) heat flux (W/m2). c if (lshflux) then start(1)=1 count(1)=1 call ncvgt(ncfrcid,shftid,start,count,tshf(1-itshf),rcode) write(stdout,*) ' reading heat forcing day ',tshf(1-itshf) if(rcode.ne.0) then write(stdout,950) 'shf_time',1 call exitus('READVBC') endif start(1)=min(2,ntshf) call ncvgt(ncfrcid,shftid,start,count,tshf(itshf),rcode) write(stdout,*) ' reading heat forcing day ',tshf(itshf) if(rcode.ne.0) then write(stdout,950) 'shf_time',start(1) call exitus('READVBC') endif if(lshfgrd) then start(1)=1 count(1)=imt start(2)=1 count(2)=jmt start(3)=1 count(3)=1 call ncvgt(ncfrcid,shfid,start,count,shflux(1,1,1-itshf), * rcode) if(rcode.ne.0) then write(stdout,950) 'shflux',1 call exitus('READVBC') endif start(3)=min(2,ntshf) call ncvgt(ncfrcid,shfid,start,count,shflux(1,1,itshf), * rcode) if(rcode.ne.0) then write(stdout,950) 'shflux',start(3) call exitus('READVBC') endif else start(1)=1 count(1)=1 call ncvgt(ncfrcid,shfid,start,count,shfx(1-itshf),rcode) if(rcode.ne.0) then write(stdout,950) 'shflux',1 call exitus('READVBC') endif start(1)=min(2,ntshf) call ncvgt(ncfrcid,shfid,start,count,shfx(itshf),rcode) if(rcode.ne.0) then write(stdout,950) 'shflux',start(1) call exitus('READVBC') endif endif endif c c Surface water flux: E-P (cm/day). c if (lswflux) then start(1)=1 count(1)=1 call ncvgt(ncfrcid,swftid,start,count,tswf(1-itswf),rcode) write(stdout,*) ' reading water forcing day ',tswf(1-itswf) if(rcode.ne.0) then write(stdout,950) 'swf_time',1 call exitus('READVBC') endif start(1)=min(2,ntswf) call ncvgt(ncfrcid,swftid,start,count,tswf(itswf),rcode) write(stdout,*) ' reading water forcing day ',tswf(itswf) if(rcode.ne.0) then write(stdout,950) 'swf_time',start(1) call exitus('READVBC') endif if(lswfgrd) then start(1)=1 count(1)=imt start(2)=1 count(2)=jmt start(3)=1 count(3)=1 call ncvgt(ncfrcid,swfid,start,count,swflux(1,1,1-itswf), * rcode) if(rcode.ne.0) then write(stdout,950) 'swflux',1 call exitus('READVBC') endif start(3)=min(2,ntswf) call ncvgt(ncfrcid,swfid,start,count,swflux(1,1,itswf), * rcode) if(rcode.ne.0) then write(stdout,950) 'swflux',start(3) call exitus('READVBC') endif else start(1)=1 count(1)=1 call ncvgt(ncfrcid,swfid,start,count,swfx(1-itswf),rcode) if(rcode.ne.0) then write(stdout,950) 'swflux',1 call exitus('READVBC') endif start(1)=min(2,ntswf) call ncvgt(ncfrcid,swfid,start,count,swfx(itswf),rcode) if(rcode.ne.0) then write(stdout,950) 'swflux',start(1) call exitus('READVBC') endif endif endif #if defined bioMcGillic | defined bioFasham | defined bioAnder | defined bioDuse c c Surface nitrate flux (umoles/m^2/day). c if (lsnflux) then start(1)=1 count(1)=1 call ncvgt(ncfrcid,snftid,start,count,tsnf(1-itsnf),rcode) write(stdout,*) ' reading nitrate forcing day ',tsnf(1-itsnf) if(rcode.ne.0) then write(stdout,950) 'snf_time',1 call exitus('READVBC') endif start(1)=min(2,ntsnf) call ncvgt(ncfrcid,snftid,start,count,tsnf(itsnf),rcode) write(stdout,*) ' reading nitrate forcing day ',tsnf(itsnf) if(rcode.ne.0) then write(stdout,950) 'snf_time',start(1) call exitus('READVBC') endif if(lsnfgrd) then start(1)=1 count(1)=imt start(2)=1 count(2)=jmt start(3)=tsnfindx count(3)=1 call ncvgt(ncfrcid,snfid,start,count,snflux(1,1,1-itsnf), * rcode) if(rcode.ne.0) then write(stdout,950) 'snflux',tsnfindx call exitus('READVBC') endif start(3)=min(2,ntsnf) call ncvgt(ncfrcid,snfid,start,count,snflux(1,1,itsnf), * rcode) if(rcode.ne.0) then write(stdout,950) 'snflux',start(3) call exitus('READVBC') endif else start(1)=tsnfindx count(1)=1 call ncvgt(ncfrcid,snfid,start,count,snfx(1-itsnf),rcode) if(rcode.ne.0) then write(stdout,950) 'snflux',tsnfindx call exitus('READVBC') endif start(1)=min(2,ntsnf) call ncvgt(ncfrcid,snfid,start,count,snfx(itsnf),rcode) if(rcode.ne.0) then write(stdout,950) 'snflux',start(1) call exitus('READVBC') endif endif endif #endif c c Shortwave radiation (W/m2). c if (lswrad) then start(1)=1 count(1)=1 call ncvgt(ncfrcid,swrtid,start,count,tswr(1-itswr),rcode) write(stdout,*) ' reading light forcing day ',tswr(1-itswr) if(rcode.ne.0) then write(stdout,950) 'swr_time',1 call exitus('READVBC') endif start(1)=min(2,ntswr) call ncvgt(ncfrcid,swrtid,start,count,tswr(itswr),rcode) write(stdout,*) ' reading light forcing day ',tswr(itswr) if(rcode.ne.0) then write(stdout,950) 'swr_time',start(1) call exitus('READVBC') endif if(lswrgrd) then start(1)=1 count(1)=imt start(2)=1 count(2)=jmt start(3)=1 count(3)=1 call ncvgt(ncfrcid,swrid,start,count,swrad(1,1,1-itswr), * rcode) if(rcode.ne.0) then write(stdout,950) 'swrad',1 call exitus('READVBC') endif start(3)=min(2,ntswr) call ncvgt(ncfrcid,swrid,start,count,swrad(1,1,itswr), * rcode) if(rcode.ne.0) then write(stdout,950) 'swrad',start(3) call exitus('READVBC') endif else start(1)=1 count(1)=1 call ncvgt(ncfrcid,swrid,start,count,swr(1-itswr),rcode) if(rcode.ne.0) then write(stdout,950) 'swrad',1 call exitus('READVBC') endif start(1)=min(2,ntswr) call ncvgt(ncfrcid,swrid,start,count,swr(itswr),rcode) if(rcode.ne.0) then write(stdout,950) 'swrad',start(1) call exitus('READVBC') endif endif endif c endif c c======================================================================= c End of introductory section. ======================================= c======================================================================= c c======================================================================= c Read in forcing data. c======================================================================= c c Surface momentum flux (dynes/cm^2). c tssmf=(tsmf(itsmf)-dstarf)*day2sec do 30 while (lsmflux.and.(tssmf.lt.ttsec)) tsmfindx=tsmfindx+1 if(tsmfindx.le.ntsmf) then itsmf=1-itsmf start(1)=tsmfindx count(1)=1 call ncvgt(ncfrcid,smftid,start,count,tsmf(itsmf),rcode) write(stdout,*) ' reading momentum forcing day ',tsmf(itsmf) if(rcode.ne.0) then write(stdout,950) 'smf_time',tsmfindx call exitus('READVBC') endif tssmf=(tsmf(itsmf)-dstarf)*day2sec if(lsmfgrd) then start(1)=1 count(1)=2 start(2)=1 count(2)=imt start(3)=1 count(3)=jmt start(4)=tsmfindx count(4)=1 call ncvgt(ncfrcid,smfid,start,count,smflux(1,1,1,itsmf), * rcode) if(rcode.ne.0) then write(stdout,950) 'smflux',tsmfindx call exitus('READVBC') endif else start(1)=1 count(1)=2 start(2)=tsmfindx count(2)=1 call ncvgt(ncfrcid,smfid,start,count,smfx(1,itsmf),rcode) if(rcode.ne.0) then write(stdout,950) 'smflux',tsmfindx call exitus('READVBC') endif endif else tsmf(itsmf)=dstarf+ttsec*sec2day tssmf=ttsec endif 30 continue c c----------------------------------------------------------------------- c Surface (net) heat flux (W/m2). c----------------------------------------------------------------------- c tsshf=(tshf(itshf)-dstarf)*day2sec do 40 while (lshflux.and.(tsshf.lt.ttsec)) tshfindx=tshfindx+1 if(tshfindx.le.ntshf) then itshf=1-itshf start(1)=tshfindx count(1)=1 call ncvgt(ncfrcid,shftid,start,count,tshf(itshf),rcode) write(stdout,*) ' reading heat forcing day ',tshf(itshf) if(rcode.ne.0) then write(stdout,950) 'shf_time',tshfindx call exitus('READVBC') endif tsshf=(tshf(itshf)-dstarf)*day2sec if(lshfgrd) then start(1)=1 count(1)=imt start(2)=1 count(2)=jmt start(3)=tshfindx count(3)=1 call ncvgt(ncfrcid,shfid,start,count,shflux(1,1,itshf), * rcode) if(rcode.ne.0) then write(stdout,950) 'shflux',tshfindx call exitus('READVBC') endif else start(1)=tshfindx count(1)=1 call ncvgt(ncfrcid,shfid,start,count,shfx(itshf),rcode) if(rcode.ne.0) then write(stdout,950) 'shflux',tshfindx call exitus('READVBC') endif endif else tshf(itshf)=dstarf+ttsec*sec2day tsshf=ttsec endif 40 continue c c----------------------------------------------------------------------- c Surface water flux: E-P (cm/day). c----------------------------------------------------------------------- c tsswf=(tswf(itswf)-dstarf)*day2sec do 50 while (lswflux.and.(tsswf.lt.ttsec)) tswfindx=tswfindx+1 if(tswfindx.le.ntswf) then itswf=1-itswf start(1)=tswfindx count(1)=1 call ncvgt(ncfrcid,swftid,start,count,tswf(itswf),rcode) write(stdout,*) ' reading water forcing day ',tswf(itswf) if(rcode.ne.0) then write(stdout,950) 'swf_time',tswfindx call exitus('READVBC') endif tsswf=(tswf(itswf)-dstarf)*day2sec if(lswfgrd) then start(1)=1 count(1)=imt start(2)=1 count(2)=jmt start(3)=tswfindx count(3)=1 call ncvgt(ncfrcid,swfid,start,count,swflux(1,1,itswf), * rcode) if(rcode.ne.0) then write(stdout,950) 'swflux',tswfindx call exitus('READVBC') endif else start(1)=tswfindx count(1)=1 call ncvgt(ncfrcid,swfid,start,count,swfx(itswf),rcode) if(rcode.ne.0) then write(stdout,950) 'swflux',tswfindx call exitus('READVBC') endif endif else tswf(itswf)=dstarf+ttsec*sec2day tsswf=ttsec endif 50 continue #if defined bioMcGillic | defined bioFasham | defined bioAnder | defined bioDuse c c----------------------------------------------------------------------- c Surface nitrate flux (umoles/m^2/day). c----------------------------------------------------------------------- c tssnf=(tsnf(itsnf)-dstarf)*day2sec do 60 while (lsnflux.and.(tssnf.lt.ttsec)) tsnfindx=tsnfindx+1 if(tsnfindx.le.ntsnf) then itsnf=1-itsnf start(1)=tsnfindx count(1)=1 call ncvgt(ncfrcid,snftid,start,count,tsnf(itsnf),rcode) write(stdout,*) ' reading nitrate forcing day ',tsnf(itsnf) if(rcode.ne.0) then write(stdout,950) 'snf_time',tsnfindx call exitus('READVBC') endif tssnf=(tsnf(itsnf)-dstarf)*day2sec if(lsnfgrd) then start(1)=1 count(1)=imt start(2)=1 count(2)=jmt start(3)=tsnfindx count(3)=1 call ncvgt(ncfrcid,snfid,start,count,snflux(1,1,itsnf), * rcode) if(rcode.ne.0) then write(stdout,950) 'snflux',tsnfindx call exitus('READVBC') endif else start(1)=tsnfindx count(1)=1 call ncvgt(ncfrcid,snfid,start,count,snfx(itsnf),rcode) if(rcode.ne.0) then write(stdout,950) 'snflux',tsnfindx call exitus('READVBC') endif endif else tsnf(itsnf)=dstarf+ttsec*sec2day tssnf=ttsec endif 60 continue #endif c c----------------------------------------------------------------------- c Shortwave radiation (W/m2). c----------------------------------------------------------------------- c tsswr=(tswr(itswr)-dstarf)*day2sec do 70 while (lswrad.and.(tsswr.lt.ttsec)) tswrindx=tswrindx+1 if(tswrindx.le.ntswr) then itswr=1-itswr start(1)=tswrindx count(1)=1 call ncvgt(ncfrcid,swrtid,start,count,tswr(itswr),rcode) write(stdout,*) ' reading light forcing day ',tswr(itswr) if(rcode.ne.0) then write(stdout,950) 'swr_time',tswrindx call exitus('READVBC') endif tsswr=(tswr(itswr)-dstarf)*day2sec if(lswrgrd) then start(1)=1 count(1)=imt start(2)=1 count(2)=jmt start(3)=tswrindx count(3)=1 call ncvgt(ncfrcid,swrid,start,count,swrad(1,1,itswr), * rcode) if(rcode.ne.0) then write(stdout,950) 'swrad',tswrindx call exitus('READVBC') endif else start(1)=tswrindx count(1)=1 call ncvgt(ncfrcid,swrid,start,count,swr(itswr),rcode) if(rcode.ne.0) then write(stdout,950) 'swrad',tswrindx call exitus('READVBC') endif endif else tswr(itswr)=dstarf+ttsec*sec2day tsswr=ttsec endif 70 continue c 900 format(/' READVBC - unable to open NetCDF file: ',a) 910 format(/' READVBC - error while inquiring information for', * ' variable: ',a,2x,' in input NetCDF file: ',a) 920 format(/' READVBC - error while reading dimension: ',a,2x, * ' in input NetCDF file: ',a) 930 format(/' READVBC - unable to inquire about contents of', * ' input NetCDF file: ',a) 940 format(/' READVBC - inconsistent dimension parameters, ',a,2i4) 945 format(/' READVBC - no data in NetCDF file: ',a) 950 format(/' READVBC - error while reading variable: ',a,2x, * ' at TIME index = ',i4) return end