SUB_SHUILIANGJISUAN/Fortran/SUB_SHUILIANGJISUAN.f90

573 lines
15 KiB
Fortran
Raw Normal View History

2025-05-09 17:45:43 +08:00
! SUB_SHUILIANGJISUAN.f90
!
! FUNCTIONS/SUBROUTINES exported from SUB_SHUILIANGJISUAN.dll:
! SUB_SHUILIANGJISUAN - subroutine
!
2025-05-09 17:54:04 +08:00
subroutine SUB_SHUILIANGJISUAN( NDATA ,& ! 计算时刻数 // 输入参数
LONG ,& ! 河道长度
INbd ,& ! 断面底宽
INzd ,& ! 底高程
INsm ,& ! 边坡系数
INrough ,& ! 糙率
ZZ0 ,& ! 计算区域初始水位
DB ,& ! 下游边界条件类型 1.水位边界 2.流量边界
UQ ,& ! 上游流量过程
DQH ,& ! 上游水位/流量过程
dt ,& ! 计算步长( 秒)
OUTT ,& ! 计算断面输出时刻
OUTQ ,& ! 计算断面输出流量
OUTH )& ! 计算断面输出水位
BIND(C, NAME="SUB_SHUILIANGJISUAN")
2025-05-09 17:45:43 +08:00
! Expose subroutine SUB_SHUILIANGJISUAN to users of this DLL
!
!DEC$ ATTRIBUTES DLLEXPORT::SUB_SHUILIANGJISUAN
! Variables
INTEGER::FHD
INTEGER::NRIVER
INTEGER::NSECT
INTEGER::MRIVER
INTEGER::KRC
INTEGER::NDATA
REAL::ZZ0
INTEGER::DB
REAL::UQ(NDATA)
REAL::DQH(NDATA)
REAL::OUTQ(1000)
REAL::OUTH(1000)
REAL::OUTT(1000)
2025-05-09 17:54:04 +08:00
REAL::DDGC ! 计算断面堤顶高程
2025-05-09 17:45:43 +08:00
REAL::MAXH
2025-05-09 17:54:04 +08:00
INTEGER::MY ! 1.漫溢 2.未漫溢
2025-05-09 17:45:43 +08:00
integer River,tstep
! node
INTEGER,ALLOCATABLE::Ns(:),Pc(:),Nrc(:,:),Lc(:,:)
REAL,ALLOCATABLE::Dric(:,:),Qj(:,:,:),Asave(:,:)
! section
REAL,ALLOCATABLE::ds(:,:),bd(:,:),zd(:,:),sm(:,:), rough(:,:)
! boundary
INTEGER,ALLOCATABLE::UB1(:),UB2(:),DB1(:),DB2(:),NUB(:,:),NDB(:,:)
REAL,ALLOCATABLE::UBV(:,:),Aphi(:,:),DBV(:,:),Gate(:,:)
REAL::ql,Zctr
! calcu
REAL::dt,sita,Bsor1,Bsor2
! zzqq
REAL,ALLOCATABLE::Z0(:,:),Q0(:,:),Z(:,:),Q(:,:),V(:,:)
! r_bv
REAL::condu,condd(3)
! BARC
REAL::Bs,As,Rs,Cs
REAL,ALLOCATABLE::Qp(:)
REAL,ALLOCATABLE::Zc(:,:),Qc(:,:)
INTEGER::I
INTEGER::II
REAL::LONG
REAL::INbd
REAL::INzd
REAL::INsm
REAL::INrough
INTEGER::TEMP
!OPEN(1,FILE='OUTFHDL.TXT')
2025-05-09 17:54:04 +08:00
!WRITE(1,*)' ! 计算时刻数 ', NDATA ,&
! ' ! 河道长度 ', LONG ,&
! '! 断面底宽 ', INbd ,&
! '! 底高程 ' , INzd ,&
! '! 边坡系数 ', INsm ,&
! ' ! 糙率 ' , INrough ,&
! ' ! 计算区域初始水位 ', ZZ0 ,&
! ' ! 下游边界条件类型 1.水位边界 2.流量边界 ', DB ,&
! ' ! 上游流量过程 ' , UQ ,&
! ' ! 上游水位/流量过程 ', DQH ,&
! ' ! 计算步长( 秒) ', dt ,&
! '! 计算断面堤顶高程 ', DDGC
2025-05-09 17:45:43 +08:00
FHD = 0
TEMP = 0
2025-05-09 17:54:04 +08:00
! 1.读入河道组态数据
!open(1,file='河道组态数据.TXT')
2025-05-09 17:45:43 +08:00
2025-05-09 17:54:04 +08:00
! 读入1.河道数量 2.河道计算断面数最大值 3.河道汊点数最大值 4.计算时刻数
2025-05-09 17:45:43 +08:00
!CALL SUB_GETNXT(1)
!read(1,*)
nriver = 1
nsect = 6
krc = 0
2025-05-09 17:54:04 +08:00
mriver=nsect - 1 ! 这是我写的,微段数不就等于断面数-1吗
2025-05-09 17:45:43 +08:00
ALLOCATE(Ns(nriver),Pc(nriver),Nrc(krc,nriver),Lc(krc,nriver))
ALLOCATE(Dric(krc,nriver),Qj(ndata,krc,nriver),Asave(krc,nriver))
2025-05-09 17:54:04 +08:00
ALLOCATE(ds(mriver,nriver),bd(nsect,nriver),zd(nsect,nriver),&
sm(nsect,nriver), rough(nsect,nriver))
ALLOCATE(UB1(nriver),UB2(nriver),DB1(nriver),DB2(nriver),&
NUB(2,nriver),NDB(2,nriver))
ALLOCATE(UBV(ndata,nriver),Aphi(2,nriver),DBV(ndata,nriver),&
Gate(4,nriver))
ALLOCATE(Z0(nsect,nriver),Q0(nsect,nriver),Z(nsect,nriver),&
Q(nsect,nriver),V(nsect,nriver))
2025-05-09 17:45:43 +08:00
ALLOCATE(Qp(ndata))
ALLOCATE(Zc(nsect,nriver),Qc(nsect,nriver))
2025-05-09 17:54:04 +08:00
!读入: 1.河道序号 2.河道断面数 3.河道汊点数
! (所有汊点均变成三汊口处理)
2025-05-09 17:45:43 +08:00
! CALL SUB_GETNXT(1)
! DO I = 1,nriver
!read(1,*)II,Ns(i),Pc(i)
! END DO
Ns(1) = 6
Pc(1) = 0
2025-05-09 17:54:04 +08:00
!读入:! 1.河道序号 2.河道汊点微段号 3.汊点类型 4.流动方向
! 汊点类型1——普通汊点2——集中入流3——调蓄水库
! 与汊点相连的河道或集中入流的水流方向流入汊点1流出汊点-1调蓄水库任意给定
2025-05-09 17:45:43 +08:00
Nrc = 0
Lc = 0
Dric = 0
! DO J = 1,nriver
! DO I = 1,Pc(J)
! CALL SUB_GETNXT(1)
!read(1,*)II,Nrc(i,j),Lc(i,j),Dric(i,j)
! END DO
! END DO
2025-05-09 17:54:04 +08:00
! 集中入流的汊点读入流量过程
2025-05-09 17:45:43 +08:00
Qj = 0.0
!DO k=1,nriver
! DO j=1,Pc(k)
! CALL SUB_GETNXT(1)
! if(Lc(j,k).eq.2)then
! read(1,*)II,II,(Qj(i,j,k),i=1,ndata)
! end if
! END DO
! END DO
2025-05-09 17:54:04 +08:00
! 连接调蓄水库的汊点读入水库面积m2
2025-05-09 17:45:43 +08:00
Asave = 0.0
!DO k=1,nriver
! DO j=1,Pc(k)
! if(Lc(j,k).eq.3)then
! CALL SUB_GETNXT(1)
! read(1,*)Asave(j,k)
! end if
! END DO
! END DO
2025-05-09 17:54:04 +08:00
! 2.读入河道几何数据
2025-05-09 17:45:43 +08:00
! CALL SUB_GETNXT(1)
! ds = 0.0
! DO J = 1,nriver
! DO I = 1,Ns(j)-1
2025-05-09 17:54:04 +08:00
!read(1,*)II,II,ds(i,j) ! 每条河道各微段的长度普通汊点、集中入流微段及调蓄水库的长度取0每条河道的首末微段长度必须取一个非零值。
2025-05-09 17:45:43 +08:00
! END DO
! END DO
ds(:,1) = LONG/5
! CALL SUB_GETNXT(1)
! bd = 0.0
! zd = 0.0
! sm = 0.0
! rough = 0.0
! DO j=1,nriver
! DO I =1,Ns(j)
2025-05-09 17:54:04 +08:00
!read(1,*)II,II,bd(i,j),zd(i,j),sm(i,j),rough(i,j) ! 梯形断面底宽、底高程、边坡系数、糙率
2025-05-09 17:45:43 +08:00
! END DO
! END DO
bd = INbd
zd = INzd
sm = INsm
rough = INrough
2025-05-09 17:54:04 +08:00
! 3.读入河道边界数据
2025-05-09 17:45:43 +08:00
! CALL SUB_GETNXT(1)
2025-05-09 17:54:04 +08:00
! read(1,*)ZZ0,Zctr ! ZZ0——计算区域初始水位,Zctr——河道末端挡潮闸运行控制水位,
2025-05-09 17:45:43 +08:00
Zctr = 0.0
2025-05-09 17:54:04 +08:00
Scanal = 0.0 ! Scanal——河网所有河道的合计长度用于计算旁侧入流量ql
2025-05-09 17:45:43 +08:00
DO J = 1,nriver
DO I = 1,Ns(j)-1
2025-05-09 17:54:04 +08:00
Scanal = Scanal + ds(i,j) ! 每条河道各微段的长度普通汊点、集中入流微段及调蓄水库的长度取0每条河道的首末微段长度必须取一个非零值。
2025-05-09 17:45:43 +08:00
END DO
END DO
!CALL SUB_GETNXT(1)
!DO I = 1,ndata
2025-05-09 17:54:04 +08:00
! read(1,*)II,Qp(i) ! Qp——计算区域入河流量过程
2025-05-09 17:45:43 +08:00
! END DO
Qp = 0.0
2025-05-09 17:54:04 +08:00
! UB1上游边界条件类型11——水位边界2——流量边界,3——水位流量关系
! UB2上游边界条件类型21——河网外边界2——河网内边界
! DB1下游边界条件类型11——水位边界2——流量边界,3——水位流量关系
! DB2下游边界条件类型21——河网外边界2——河网内边界
2025-05-09 17:45:43 +08:00
!CALL SUB_GETNXT(1)
! DO I = 1,nriver
! read(1,*)II,UB1(i),UB2(i),DB1(i),DB2(i)
!END DO
UB1(1) = 2
UB2(1) = 1
DB1(1) = DB
DB2(1) = 1
!CALL SUB_GETNXT(1)
UBV = 0.0
NUB = 0
!DO i=1,nriver
2025-05-09 17:54:04 +08:00
! if(UB2(i).eq.1)then ! 如果是上游河网外部边界
! read(1,*)II,II,II,(UBV(j,i),j=1,ndata) ! 读入上游外边界断面处的水位,或流量过程
! elseif(UB2(i).eq.2)then ! 如果是上游河网内部边界
! read(1,*)II,II,II,(NUB(j,i),j=1,2) ! 读入上游内边界断面所连接的河道编号、微段编号
2025-05-09 17:45:43 +08:00
! endif
! END DO
DO I = 1,ndata
UBV(I,1) = UQ(I)
END DO
!CALL SUB_GETNXT(1)
!DO i=1,nriver
2025-05-09 17:54:04 +08:00
! if(DB2(i).eq.1)then ! 下游外部
! if(DB1(i).eq.3)then ! 如果是闸下潮位过程
! read(1,*)II,II,II,(DBV(j,i),j=1,ndata),&
(Gate(j,i),j=1,4) ! 读入 Gate(1,i) = 闸净宽Gate(2,i) = 最大过流量Gate(3,i) = 流量公式C1Gate(4,i) = 流量公式C2 流量公式Q=C1*B*e*dZ^C2中的C1和C2
2025-05-09 17:45:43 +08:00
! ELSE
2025-05-09 17:54:04 +08:00
! read(1,*)II,II,II,(DBV(j,i),j=1,ndata) ! 读入下游外边界断面处的水位,或流量,或闸下潮位过程
2025-05-09 17:45:43 +08:00
! end if
2025-05-09 17:54:04 +08:00
! elseif(DB2(i).eq.2)then ! 下游内部
2025-05-09 17:45:43 +08:00
! if(DB1(i).eq.2)then
2025-05-09 17:54:04 +08:00
! read(1,*)II,II,II,(NDB(j,i),j=1,2),&
(Aphi(j,i),j=1,2) ! 下游流量内边界(管涵)的过流断面面积、流速系数 下游内边界一般用水位,如果用流量,一般是管涵,需要提供过流面积和流速系数
2025-05-09 17:45:43 +08:00
! ELSE
2025-05-09 17:54:04 +08:00
! read(1,*)II,II,II,(NDB(j,i),j=1,2) ! 读入下游内边界断面所连接的河道编号、微段编号
2025-05-09 17:45:43 +08:00
! end if
! endif
!END DO
DO I = 1,ndata
DBV(I,1) = DQH(I)
END DO
2025-05-09 17:54:04 +08:00
! 4.读入河道计算条件
2025-05-09 17:45:43 +08:00
!CALL SUB_GETNXT(1)
2025-05-09 17:54:04 +08:00
!read(1,*)period,dt,sita ! period——计算小时数dt——计算时间步长,sita——水量隐格式权系数
2025-05-09 17:45:43 +08:00
!CALL SUB_GETNXT(1)
2025-05-09 17:54:04 +08:00
!read(1,*)sorz,sorq,epsz,epsq ! sorz、sorq——水位、流量迭代松弛因子,epsz、epsq——水位、流量迭代控制精度
2025-05-09 17:45:43 +08:00
!CALL SUB_GETNXT(1)
2025-05-09 17:54:04 +08:00
!read(1,*)Bsor1,Bsor2 ! Bsor1、Bsor2——水闸外边界、管涵内边界计算中的松弛因子
2025-05-09 17:45:43 +08:00
!close(1)
period =REAL( NDATA - 1 )
! read(1,*)dt
sita = 0.7
sorz = 0.3
sorq = 0.3
epsz = 0.01
epsq = 0.1
Bsor1 = 0.3
Bsor2 = 0.1
2025-05-09 17:54:04 +08:00
! 计算时间步长
2025-05-09 17:45:43 +08:00
maxtstep=period*3600/dt
2025-05-09 17:54:04 +08:00
maxiter=1000 ! 仿真模拟步数
2025-05-09 17:45:43 +08:00
2025-05-09 17:54:04 +08:00
! 给河道水位、流量赋初值
2025-05-09 17:45:43 +08:00
DO river=1,nriver
DO Is=1,Ns(river)
Z0(Is,river)=ZZ0
Q0(Is,river)=0.0
END DO
END DO
2025-05-09 17:54:04 +08:00
! 流量、水位输出
!open(1,file='河道1各断面水位变化.TXT')
!open(2,file='河道2各断面水位变化.TXT')
!open(3,file='河道3各断面水位变化.TXT')
!open(4,file='河道4各断面水位变化.TXT')
2025-05-09 17:45:43 +08:00
!
2025-05-09 17:54:04 +08:00
!open(11,file='河道1各断面流量变化.TXT')
!open(12,file='河道2各断面流量变化.TXT')
!open(13,file='河道3各断面流量变化.TXT')
!open(14,file='河道4各断面流量变化.TXT')
2025-05-09 17:45:43 +08:00
! ----------------------------------------------------------------------------------
2025-05-09 17:54:04 +08:00
! 迭代求解每个时刻的水位、流量
2025-05-09 17:45:43 +08:00
! ----------------------------------------------------------------------------------
2025-05-09 17:54:04 +08:00
DO tstep=1,maxtstep ! 步数累加器
2025-05-09 17:45:43 +08:00
TEMP = TEMP + 1
2025-05-09 17:54:04 +08:00
ttime=dt*tstep/3600.0 ! 真实时刻
2025-05-09 17:45:43 +08:00
! write(*,15)ttime
iter=0
DO river=1,nriver
DO Is=1,Ns(river)
Z(Is,river)=Z0(Is,river)
Q(Is,river)=Q0(Is,river)
END DO
END DO
2025-05-09 17:54:04 +08:00
! 计算当前时刻入河流量大小
call int_a( ttime ,& ! 真实时刻 // 输入参数
ndata ,& ! 入河流量变化过程时段数
Qp ,& ! 入河流量变化过程线
fc ) ! 当前时刻入河流量大小 // 输出参数
2025-05-09 17:45:43 +08:00
ql=fc/Scanal
25 iter=iter+1
DO river=1,nriver
DO Is=1,Ns(river)
Zc(Is,river)=Z(Is,river)
Qc(Is,river)=Q(Is,river)
END DO
END DO
DO river=1,nriver
2025-05-09 17:54:04 +08:00
! 确定计算时刻河段上下游边界条件值
2025-05-09 17:45:43 +08:00
call sub_bound( NRIVER ,&
NSECT ,&
MRIVER ,&
KRC ,&
NDATA ,&
river ,&
tstep ,&
Ns ,&
Pc ,&
Nrc ,&
Lc ,&
Dric ,&
Qj ,&
Asave ,&
UB1 ,&
UB2 ,&
DB1 ,&
DB2 ,&
NUB ,&
NDB ,&
UBV ,&
Aphi ,&
DBV ,&
Gate ,&
ql ,&
Zctr ,&
dt ,&
sita ,&
Bsor1 ,&
Bsor2 ,&
Z0 ,&
Q0 ,&
Z ,&
Q ,&
V ,&
condu ,&
condd )
2025-05-09 17:54:04 +08:00
! 用四点隐格式计算未知时层水位Z和流量Q
2025-05-09 17:45:43 +08:00
call sub_QZ( NRIVER ,&
NSECT ,&
MRIVER ,&
KRC ,&
NDATA ,&
river ,&
tstep ,&
Ns ,&
Pc ,&
Nrc ,&
Lc ,&
Dric ,&
Qj ,&
Asave ,&
ds ,&
bd ,&
zd ,&
sm ,&
rough ,&
UB1 ,&
UB2 ,&
DB1 ,&
DB2 ,&
NUB ,&
NDB ,&
UBV ,&
Aphi ,&
DBV ,&
Gate ,&
ql ,&
Zctr ,&
dt ,&
sita ,&
Bsor1 ,&
Bsor2 ,&
Z0 ,&
Q0 ,&
Z ,&
Q ,&
V ,&
condu ,&
condd ,&
Bs ,&
As ,&
Rs ,&
Cs )
END DO
dzmax=0.0
dqmax=0.0
DO river=1,nriver
DO Is=1,Ns(river)
dz=abs(Z(Is,river)-Zc(Is,river))
dq=abs(Q(Is,river)-Qc(Is,river))
if(dz.gt.dzmax)then
dzmax=dz
maxz_r=river
maxz_s=Is
end if
if(dq.gt.dqmax)then
dqmax=dq
maxq_r=river
maxq_s=Is
end if
END DO
END DO
if(dzmax.gt.epsz.or.dqmax.gt.epsq)then
! write(*,50)iter,maxz_r,maxz_s,dzmax,maxq_r,maxq_s,dqmax
DO river=1,nriver
DO Is=1,Ns(river)
2025-05-09 17:54:04 +08:00
Z(Is,river)=(1.0-sorz)*Zc(Is,river)+&
sorz*Z(Is,river)
Q(Is,river)=(1.0-sorq)*Qc(Is,river)+&
sorq*Q(Is,river)
2025-05-09 17:45:43 +08:00
END DO
END DO
if(iter.le.maxiter)then
goto 25
else
! write(*,55)
goto 600
end if
else
DO river=1,nriver
DO Is=1,Ns(river)
2025-05-09 17:54:04 +08:00
! 计算断面几何要素
2025-05-09 17:45:43 +08:00
call sub_sect(NRIVER ,&
NSECT ,&
MRIVER ,&
KRC ,&
NDATA ,&
river,Is,Z(Is,river),&
ds ,&
bd ,&
zd ,&
sm ,&
rough ,&
Bs ,&
As ,&
Rs ,&
Cs )
V(Is,river)=Q(Is,river)/As
END DO
END DO
2025-05-09 17:54:04 +08:00
! 输出几个典型河道的水位流量变化过程
2025-05-09 17:45:43 +08:00
DO jj=1,nriver
!write(jj,80)ttime,(Z(ii,jj),ii=1,Ns(jj))
END DO
DO jj=1,nriver
jj1=jj+10
!write(jj1,80)ttime,(Q(ii,jj),ii=1,Ns(jj))
END DO
IF(FHD==1)THEN
OUTQ(TEMP ) = Q(5,1)*0.9
OUTH(TEMP ) = Z(5,1)*0.95
ELSE
OUTQ(TEMP ) = Q(5,1)
OUTH(TEMP ) = Z(5,1)
END IF
OUTT(TEMP ) = ttime
DO river=1,nriver
DO Is=1,Ns(river)
Z0(Is,river)=Z(Is,river)
Q0(Is,river)=Q(Is,river)
END DO
END DO
end if
END DO
600 close(100)
close(2)
close(3)
close(4)
close(11)
close(12)
close(13)
close(14)
15 format(55x,'time=',f10.2)
2025-05-09 17:54:04 +08:00
50 format(55x,'iter=',i5/1x,'maxz_r=',i5,5x,'maxz_s=',i5,&
5x,'dzmax=',e10.4/1x,'maxq_r=',i5,5x,'maxq_s=',i5,5x,'dqmax=',e10.4)
55 format(1x,'迭代发散')
2025-05-09 17:45:43 +08:00
80 format(1x,40f12.4)
!MAXH = MAXVAL(OUTH)
!IF(MAXH.GT.DDGC)THEN
! MY = 1
!ELSE
! MY = 0
!END IF
2025-05-09 17:54:04 +08:00
!WRITE(1,*)' ! 1.漫溢 0.未漫溢 ' , MY ,&
! '! 计算断面输出时刻 ', OUTT ,&
! '! 计算断面输出流量 ', OUTQ ,&
! '! 计算断面输出水位 ', OUTH
2025-05-09 17:45:43 +08:00
CLOSE(1)
END SUBROUTINE SUB_SHUILIANGJISUAN