module defpara implicit none integer::INTDIV integer,parameter::MAXDIV=20 real(8),parameter::ADDMAX=0.0D0 ! INTDIV : number of pertial division of time increment for nemerical integration ! MAXDIV : number of division from zero to maximum run-off ! ADDMAX : coefficient of additional number at maximum run-off ! (arrange the weight for regression analysis) end module !**************************************************/ program f90_SFM !**************************************************/ !---------------------------------------------------------------------------*/ ! Storage Function Mehod !---------------------------------------------------------------------------*/ use defpara implicit none integer,parameter::NDmax=1000 integer::i,j,io,nnn,nn !---------------------------------------------------------------------------*/ ! nd : Number of observed data ! md : Divided number of time increment ! n1 : Starting point of direct run-off ! n2 : Ending point of direct run-off ! CA : Catchment area ! dt : Time increment of observed data ! ddt : Time increment for calculation ! R_org() : Observed rainfall ! Q_org() : Observed discharge ! RO() : Rainfall for calculation ! QO() : Discharge for calculation ! RE : Effective rainfall ! QC() : Direct run-off ! QB() : Base run-off ! SS() : Storage function ! QE() : Estimated flow ! ff : Run-off percentage ! kk, pp : SS=kk*QC**pp (kk,pp : coefficient) ! LT : Number of delay time (delay time = LT*dt) ! ! subroutine QSPRT() : print out of q-s relationship ! subroutine DEFQCQB() : definition of QC and QB ! subroutine CALC() : control rooutine for calculation of LT, ff, pp, kk ! subroutine LSM() : regression analysis for calculation of pp, kk ! subroutine CALAREA() : calculation of LT, ff, pp, kk ! subroutine RUNGE() : Runge-Kutta numerical integration ! real(8) function FQ() : function for Runge-Kutta method ! subroutine SPL3() : spline interpolation ! subroutine STEGJ() : solver of simultaneous equations for spline interpolation !---------------------------------------------------------------------------*/ integer::nd,nt,n1,n2,md,mm,num1,num2 real(8)::CA,dt,ddt real(8),allocatable::R_org(:),Q_org(:) real(8),allocatable::RO(:),QO(:) real(8),allocatable::QC(:),QB(:),SS(:),QE(:) real(8),allocatable::datax(:),datay(:) real(8)::ff,kk,pp real(8)::Qmax,SQ,sumQO,sumQE real(8)::Qres1,Qres2 integer::LT,iQmax real(8)::x1,y1,x2,y2,xx,w1,w2,qq,xmax character(len=50)::fnameR,fnameW character(len=100)::strcom character(len=100)::dat character(len=50)::dummy1,dummy2 ! Reading from command line call getarg(1,fnameR) !Input data file call getarg(2,fnameW) !Output data file call getarg(3,dummy1) read(dummy1,*) n1 !starting point of direct run-off call getarg(4,dummy1) read(dummy1,*) mm !mm=0: base flow=QO(n1) call getarg(5,dummy1) read(dummy1,*) INTDIV !INTDIV: pertial division of time increment ! Data input allocate(R_org(1:NDmax),Q_org(1:NDmax)) open(11,file=fnameR,status='old') read(11,'(a)') strcom !River, location, date read(11,*) dummy1,CA !Catchment Area (km2) read(11,*) dummy1,dt !Time increment (hour) read(11,'()') do i=1,NDmax read(11,*,iostat=io) dummy1,dummy1,R_org(i),Q_org(i) if(io<0)exit end do close(11) nd=i-1 md=INTDIV allocate(datax(1:nd),datay(1:nd)) n1=(n1-1)*md+1 nt=(nd-1)*md+1 ddt=dt/dble(md) allocate(RO(1:nt),QO(1:nt)) do i=0,nd-2 do j=1,md RO(i*md+j+1)=R_org(i+2) end do end do do i=1,nd datax(i)=dt*dble(i) datay(i)=Q_org(i) end do call SPL3(nd,datax,datay,md) open(11,file='_spline.txt',status='old') do i=1,nt read(11,*) dummy1,QO(i) if(QO(i)<0.0D0)QO(i)=0.0D0 end do close(11) RO(1)=R_org(1) QO(1)=Q_org(1) RO(nt)=R_org(nd) QO(nt)=Q_org(nd) deallocate(R_org,Q_org) deallocate(datax,datay) allocate(QC(1:nt),QB(1:nt),SS(1:nt),QE(1:nt)) Qmax=QO(1) do i=1,nt if(Qmaxm1)then mm=m1 else mm=n1-i+1 end if do j=1,mm z=array(i,j) if(j/=m1)then if(m1-j+11)then array(i,j)=z/array(i,1) else array(i,1)=sqrt(z) end if else array(i,j)=z/array(i,1) end if end do end do vector(1)=vector(1)/array(1,1) do i=2,n1 z=vector(i) if(i>m1)then mm=m1 else mm=i end if do j=2,mm z=z-array(i-j+1,j)*vector(i-j+1) end do vector(i)=z/array(i,1) end do vector(n1)=vector(n1)/array(n1,1) do i=n1-1,1,-1 z=vector(i) do j=2,m1 if(i+j-1>n1)exit z=z-array(i,j)*vector(i+j-1) end do vector(i)=z/array(i,1) end do end subroutine CHBAND !---------------------------------------------------------------------------*/ end program f90_SFM !---------------------------------------------------------------------------*/