1
This commit is contained in:
commit
027e45867b
74
Controllers/FortranController.cs
Normal file
74
Controllers/FortranController.cs
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using FortranWebApi.Models;
|
||||||
|
using FortranWebApi.Services;
|
||||||
|
using System.Text.Json;
|
||||||
|
|
||||||
|
namespace FortranWebApi.Controllers
|
||||||
|
{
|
||||||
|
[ApiController]
|
||||||
|
[Route("[controller]")]
|
||||||
|
public class FortranCalculateController : ControllerBase
|
||||||
|
{
|
||||||
|
private readonly FortranInteropService _fortranService;
|
||||||
|
private readonly ILogger<FortranCalculateController> _logger;
|
||||||
|
|
||||||
|
public FortranCalculateController(FortranInteropService fortranService, ILogger<FortranCalculateController> logger)
|
||||||
|
{
|
||||||
|
_fortranService = fortranService;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpPost]
|
||||||
|
public IActionResult Post([FromBody] FortranRequestWrapper wrapper)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (string.IsNullOrEmpty(wrapper.Text))
|
||||||
|
{
|
||||||
|
return BadRequest(new
|
||||||
|
{
|
||||||
|
message = "请求文本不能为空",
|
||||||
|
success = false,
|
||||||
|
data = (object)null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
string result = _fortranService.ProcessFortranRequest(wrapper.Text);
|
||||||
|
|
||||||
|
// 使用驼峰命名法解析结果
|
||||||
|
var options = new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||||
|
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
|
||||||
|
PropertyNameCaseInsensitive = true,
|
||||||
|
WriteIndented = true
|
||||||
|
};
|
||||||
|
|
||||||
|
var resultObj = JsonSerializer.Deserialize<FortranRequest>(result, options);
|
||||||
|
|
||||||
|
// 返回新的格式
|
||||||
|
var response = new ApiResponse<FortranRequest>
|
||||||
|
{
|
||||||
|
Message = "Success",
|
||||||
|
Success = true,
|
||||||
|
Data = new ApiResponseData<FortranRequest>
|
||||||
|
{
|
||||||
|
Value = resultObj
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(response);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError(ex, "处理Fortran请求时发生错误");
|
||||||
|
return StatusCode(500, new
|
||||||
|
{
|
||||||
|
message = ex.Message,
|
||||||
|
success = false,
|
||||||
|
data = (object)null
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
88
Dockerfile
Normal file
88
Dockerfile
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
# ===== 第一阶段:构建阶段 =====
|
||||||
|
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
|
||||||
|
|
||||||
|
# 配置 NuGet 使用国内镜像源
|
||||||
|
RUN dotnet nuget add source https://mirrors.cloud.tencent.com/nuget/ \
|
||||||
|
&& dotnet nuget disable source nuget.org
|
||||||
|
|
||||||
|
# 配置 apt-get 使用 apt-cacher-ng 作为代理
|
||||||
|
RUN echo 'Acquire::http::Proxy "http://192.168.1.140:3142";' > /etc/apt/apt.conf.d/01proxy
|
||||||
|
|
||||||
|
# 创建并配置 Debian 镜像源
|
||||||
|
RUN echo "deb https://mirrors.ustc.edu.cn/debian/ bookworm main contrib non-free non-free-firmware" > /etc/apt/sources.list && \
|
||||||
|
echo "deb https://mirrors.ustc.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware" >> /etc/apt/sources.list && \
|
||||||
|
echo "deb https://mirrors.ustc.edu.cn/debian-security bookworm-security main contrib non-free non-free-firmware" >> /etc/apt/sources.list
|
||||||
|
|
||||||
|
# 允许使用不安全的软件源
|
||||||
|
RUN echo 'Acquire::AllowInsecureRepositories "true";' > /etc/apt/apt.conf.d/99allow-insecure && \
|
||||||
|
echo 'Acquire::AllowDowngradeToInsecureRepositories "true";' >> /etc/apt/apt.conf.d/99allow-insecure
|
||||||
|
|
||||||
|
WORKDIR /src
|
||||||
|
|
||||||
|
# 安装 Fortran 编译器
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
gfortran \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# 复制 Fortran 源文件并编译
|
||||||
|
COPY Fortran/*.f90 /src/Fortran/
|
||||||
|
WORKDIR /src/Fortran
|
||||||
|
|
||||||
|
# 编译所有 .f90 文件为 .o 文件
|
||||||
|
RUN for file in *.f90; do gfortran -fPIC -c "$file" -o "${file%.f90}.o"; done
|
||||||
|
|
||||||
|
# 链接所有 .o 文件为共享库
|
||||||
|
RUN gfortran -shared *.o -o libSUB_SHUILIANGJISUAN.so
|
||||||
|
|
||||||
|
# 回到主工作目录
|
||||||
|
WORKDIR /src
|
||||||
|
|
||||||
|
# 只复制项目文件
|
||||||
|
COPY ["FortranWebApi.csproj", "./"]
|
||||||
|
RUN dotnet restore
|
||||||
|
|
||||||
|
# 复制源代码
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# 合并 build 和 publish 命令
|
||||||
|
RUN dotnet publish -c Release -o /app/publish
|
||||||
|
|
||||||
|
# 复制编译好的 .so 文件到发布目录
|
||||||
|
RUN mkdir -p /app/publish && \
|
||||||
|
cp /src/Fortran/libSUB_SHUILIANGJISUAN.so /app/publish/
|
||||||
|
|
||||||
|
# ===== 第二阶段:运行阶段 =====
|
||||||
|
FROM mcr.microsoft.com/dotnet/aspnet:8.0
|
||||||
|
|
||||||
|
# 配置 apt-get 使用 apt-cacher-ng 作为代理
|
||||||
|
RUN echo 'Acquire::http::Proxy "http://192.168.1.140:3142";' > /etc/apt/apt.conf.d/01proxy
|
||||||
|
|
||||||
|
# 创建并配置 Debian 镜像源
|
||||||
|
RUN echo "deb https://mirrors.ustc.edu.cn/debian/ bookworm main contrib non-free non-free-firmware" > /etc/apt/sources.list && \
|
||||||
|
echo "deb https://mirrors.ustc.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware" >> /etc/apt/sources.list && \
|
||||||
|
echo "deb https://mirrors.ustc.edu.cn/debian-security bookworm-security main contrib non-free non-free-firmware" >> /etc/apt/sources.list
|
||||||
|
|
||||||
|
# 允许使用不安全的软件源
|
||||||
|
RUN echo 'Acquire::AllowInsecureRepositories "true";' > /etc/apt/apt.conf.d/99allow-insecure && \
|
||||||
|
echo 'Acquire::AllowDowngradeToInsecureRepositories "true";' >> /etc/apt/apt.conf.d/99allow-insecure
|
||||||
|
|
||||||
|
# 安装运行时依赖
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||||
|
libc6-dev \
|
||||||
|
libgfortran5 \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=build /app/publish .
|
||||||
|
|
||||||
|
# 确保 .so 文件的权限正确
|
||||||
|
RUN chmod 755 /app/libSUB_SHUILIANGJISUAN.so
|
||||||
|
|
||||||
|
# 设置 LD_LIBRARY_PATH
|
||||||
|
ENV LD_LIBRARY_PATH=/app
|
||||||
|
|
||||||
|
# 设置端口和监听地址
|
||||||
|
ENV ASPNETCORE_URLS=http://+:5000
|
||||||
|
EXPOSE 5000
|
||||||
|
|
||||||
|
ENTRYPOINT ["dotnet", "FortranWebApi.dll"]
|
120
Fortran/1.json
Normal file
120
Fortran/1.json
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
{
|
||||||
|
"fortranSourceFile": "D:\\\u5DE5\u4F5C2025\\\u7B97\u6CD5\u5E73\u53F0\\dll\\\u5355\u6CB3\u9053\u4E00\u7EF4\u6C34\u52A8\u529B\u6A21\u578B\\SUB_SHUILIANGJISUAN - \u526F\u672C.f90",
|
||||||
|
"fortranFunctionName": "SUB_SHUILIANGJISUAN",
|
||||||
|
"projectName": "FortranWebApi",
|
||||||
|
"outputDirectory": "D:\\\u5DE5\u4F5C2025\\\u7B97\u6CD5\u5E73\u53F0\\\u8F93\u51FA\u5E93\\\u5355\u6CB3\u9053\u4E00\u7EF4\u6C34\u52A8\u529B\u6A21\u578B",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"name": "NDATA",
|
||||||
|
"dataType": "Integer",
|
||||||
|
"arrayType": "Scalar",
|
||||||
|
"direction": "Input",
|
||||||
|
"description": "",
|
||||||
|
"isSelected": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "LONG",
|
||||||
|
"dataType": "Float",
|
||||||
|
"arrayType": "Scalar",
|
||||||
|
"direction": "Input",
|
||||||
|
"description": "",
|
||||||
|
"isSelected": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "INbd",
|
||||||
|
"dataType": "Integer",
|
||||||
|
"arrayType": "Scalar",
|
||||||
|
"direction": "Input",
|
||||||
|
"description": "",
|
||||||
|
"isSelected": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "INzd",
|
||||||
|
"dataType": "Integer",
|
||||||
|
"arrayType": "Scalar",
|
||||||
|
"direction": "Input",
|
||||||
|
"description": "",
|
||||||
|
"isSelected": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "INsm",
|
||||||
|
"dataType": "Integer",
|
||||||
|
"arrayType": "Scalar",
|
||||||
|
"direction": "Input",
|
||||||
|
"description": "",
|
||||||
|
"isSelected": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "INrough",
|
||||||
|
"dataType": "Integer",
|
||||||
|
"arrayType": "Scalar",
|
||||||
|
"direction": "Input",
|
||||||
|
"description": "",
|
||||||
|
"isSelected": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ZZ0",
|
||||||
|
"dataType": "Float",
|
||||||
|
"arrayType": "Scalar",
|
||||||
|
"direction": "Input",
|
||||||
|
"description": "",
|
||||||
|
"isSelected": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DB",
|
||||||
|
"dataType": "Integer",
|
||||||
|
"arrayType": "Scalar",
|
||||||
|
"direction": "Input",
|
||||||
|
"description": "",
|
||||||
|
"isSelected": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "UQ",
|
||||||
|
"dataType": "Float",
|
||||||
|
"arrayType": "OneDimensional",
|
||||||
|
"direction": "Input",
|
||||||
|
"description": "",
|
||||||
|
"isSelected": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "DQH",
|
||||||
|
"dataType": "Float",
|
||||||
|
"arrayType": "OneDimensional",
|
||||||
|
"direction": "Input",
|
||||||
|
"description": "",
|
||||||
|
"isSelected": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "dt",
|
||||||
|
"dataType": "Float",
|
||||||
|
"arrayType": "Scalar",
|
||||||
|
"direction": "Input",
|
||||||
|
"description": "",
|
||||||
|
"isSelected": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "OUTT",
|
||||||
|
"dataType": "Float",
|
||||||
|
"arrayType": "OneDimensional",
|
||||||
|
"direction": "Output",
|
||||||
|
"description": "",
|
||||||
|
"isSelected": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "OUTQ",
|
||||||
|
"dataType": "Float",
|
||||||
|
"arrayType": "OneDimensional",
|
||||||
|
"direction": "Output",
|
||||||
|
"description": "",
|
||||||
|
"isSelected": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "OUTH",
|
||||||
|
"dataType": "Float",
|
||||||
|
"arrayType": "OneDimensional",
|
||||||
|
"direction": "Output",
|
||||||
|
"description": "",
|
||||||
|
"isSelected": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
BIN
Fortran/1.xlsx
Normal file
BIN
Fortran/1.xlsx
Normal file
Binary file not shown.
161
Fortran/SUB_BOUND.f90
Normal file
161
Fortran/SUB_BOUND.f90
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
! ==================================================================================
|
||||||
|
! 确定计算时刻河段上下游边界条件值的子程序
|
||||||
|
! ==================================================================================
|
||||||
|
!
|
||||||
|
! 说明:下游外边界条件都给定一个过程,有ndata个数据点(1小时间隔),水位边界即为水位过程,
|
||||||
|
! 流量边界即为流量过程,水位流量关系边界只限挡潮闸情况,给出闸下潮位过程。
|
||||||
|
! 河道末端挡潮闸水位流量关系简化成Q=C1*B*e*dZ^C2。Z>Ztide且Z>Zctr时开闸,
|
||||||
|
! 否则关闸,Zctr是挡潮闸运行控制水位,保证内河不会过低。
|
||||||
|
! ----------------------------------------------------------------------------------
|
||||||
|
SUBROUTINE 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 )
|
||||||
|
|
||||||
|
INTEGER::NRIVER
|
||||||
|
INTEGER::NSECT
|
||||||
|
INTEGER::MRIVER
|
||||||
|
INTEGER::KRC
|
||||||
|
INTEGER::NDATA
|
||||||
|
|
||||||
|
INTEGER RIVER,TSTEP
|
||||||
|
|
||||||
|
! node
|
||||||
|
INTEGER::Ns(nriver),Pc(nriver),Nrc(krc,nriver),Lc(krc,nriver)
|
||||||
|
REAL::Dric(krc,nriver),Qj(ndata,krc,nriver),Asave(krc,nriver)
|
||||||
|
! boundary
|
||||||
|
INTEGER::UB1(nriver),UB2(nriver),DB1(nriver),DB2(nriver),NUB(2,nriver),NDB(2,nriver)
|
||||||
|
REAL::UBV(ndata,nriver),Aphi(2,nriver),DBV(ndata,nriver),Gate(4,nriver),ql,Zctr
|
||||||
|
! calcu
|
||||||
|
REAL::dt,sita,Bsor1,Bsor2
|
||||||
|
! zzqq
|
||||||
|
REAL::Z0(nsect,nriver),Q0(nsect,nriver),Z(nsect,nriver),Q(nsect,nriver),V(nsect,nriver)
|
||||||
|
! r_bv
|
||||||
|
REAL::condu,condd(3)
|
||||||
|
|
||||||
|
REAL:: ZQ(NDATA)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TC=DT*FLOAT(TSTEP)/3600.0
|
||||||
|
|
||||||
|
! 上游边界处理
|
||||||
|
IF(UB2(RIVER).EQ.1)THEN ! 外
|
||||||
|
DO II=1,NDATA
|
||||||
|
ZQ(II)=UBV(II,RIVER)
|
||||||
|
END DO
|
||||||
|
CALL INT_A(TC,NDATA,ZQ,FC)
|
||||||
|
CONDU=FC
|
||||||
|
ELSEIF(UB2(RIVER).EQ.2)THEN ! 内
|
||||||
|
IR=NUB(1,RIVER)
|
||||||
|
IS=NUB(2,RIVER)
|
||||||
|
IF(UB1(RIVER).EQ.1)THEN
|
||||||
|
CONDU=Z(IS,IR)
|
||||||
|
END IF
|
||||||
|
IF(UB1(RIVER).EQ.2)THEN
|
||||||
|
CONDU=Q(IS+1,IR)
|
||||||
|
END IF
|
||||||
|
END IF
|
||||||
|
|
||||||
|
! 下游边界处理
|
||||||
|
IF(DB2(RIVER).EQ.1)THEN
|
||||||
|
DO II=1,NDATA
|
||||||
|
ZQ(II)=DBV(II,RIVER)
|
||||||
|
END DO
|
||||||
|
CALL INT_A(TC,NDATA,ZQ,FC)
|
||||||
|
IF(DB1(RIVER).EQ.1)THEN
|
||||||
|
CONDD(1)=1.0
|
||||||
|
CONDD(2)=0.0
|
||||||
|
CONDD(3)=FC
|
||||||
|
ELSE IF(DB1(RIVER).EQ.2)THEN
|
||||||
|
CONDD(1)=0.0
|
||||||
|
CONDD(2)=1.0
|
||||||
|
CONDD(3)=FC
|
||||||
|
ELSE IF(DB1(RIVER).EQ.3)THEN
|
||||||
|
ZU0=Z0(NS(RIVER)-1,RIVER)
|
||||||
|
ZU=Z0(NS(RIVER)-1,RIVER)
|
||||||
|
ZU=(1-BSOR1)*ZU0+BSOR1*ZU
|
||||||
|
B=GATE(1,RIVER)
|
||||||
|
QMAX=GATE(2,RIVER)
|
||||||
|
C1=GATE(3,RIVER)
|
||||||
|
C2=GATE(4,RIVER)
|
||||||
|
IF(ZU>FC.AND.ZU>=ZCTR)THEN
|
||||||
|
DZ=ZU-FC
|
||||||
|
EK=5.0*DZ
|
||||||
|
IF(DZ<0.15)THEN
|
||||||
|
E=0.0
|
||||||
|
END IF
|
||||||
|
QQ=C1*B*EK*DZ**C2
|
||||||
|
QQ=(1-BSOR1)*Q0(NS(RIVER),RIVER)+BSOR1*QQ
|
||||||
|
IF(QQ>QMAX)THEN
|
||||||
|
QQ=QMAX
|
||||||
|
END IF
|
||||||
|
CONDD(1)=0.0
|
||||||
|
CONDD(2)=1.0
|
||||||
|
CONDD(3)=QQ
|
||||||
|
ELSE
|
||||||
|
CONDD(1)=0.0
|
||||||
|
CONDD(2)=1.0
|
||||||
|
CONDD(3)=0.0
|
||||||
|
END IF
|
||||||
|
END IF
|
||||||
|
ELSEIF(DB2(RIVER).EQ.2)THEN
|
||||||
|
IR=NDB(1,RIVER)
|
||||||
|
IS=NDB(2,RIVER)
|
||||||
|
IF(DB1(RIVER).EQ.1)THEN
|
||||||
|
CONDD(1)=1.0
|
||||||
|
CONDD(2)=0.0
|
||||||
|
CONDD(3)=Z(IS,IR)
|
||||||
|
ELSE
|
||||||
|
AH=APHI(1,RIVER)
|
||||||
|
PHI=APHI(2,RIVER)
|
||||||
|
IF(Z(NS(RIVER),RIVER)>=Z(IS,IR))THEN
|
||||||
|
QQ=AH*PHI*SQRT(2*9.8*(Z(NS(RIVER),RIVER)-Z(IS,IR)))
|
||||||
|
ELSE
|
||||||
|
QQ=-AH*PHI*SQRT(2*9.8*(Z(IS,IR)-Z(NS(RIVER),RIVER)))
|
||||||
|
END IF
|
||||||
|
QQ=(1-BSOR2)*Q0(NS(RIVER),RIVER)+BSOR2*QQ
|
||||||
|
CONDD(1)=0.0
|
||||||
|
CONDD(2)=1.0
|
||||||
|
CONDD(3)=QQ
|
||||||
|
END IF
|
||||||
|
END IF
|
||||||
|
|
||||||
|
END SUBROUTINE SUB_BOUND
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
29
Fortran/SUB_GETNXT.F90
Normal file
29
Fortran/SUB_GETNXT.F90
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
SUBROUTINE SUB_GETNXT(IIN)
|
||||||
|
|
||||||
|
IMPLICIT NONE
|
||||||
|
|
||||||
|
INTEGER::IIN
|
||||||
|
INTEGER::I
|
||||||
|
CHARACTER*80 DATALN
|
||||||
|
CHARACTER*1 CH
|
||||||
|
|
||||||
|
1 READ(IIN,'(A80)') DATALN
|
||||||
|
|
||||||
|
DO I = 1, 80
|
||||||
|
CH = DATALN(I:I)
|
||||||
|
IF ( CH .EQ. '|') GOTO 1 ! |号开头的内容不读直接跳过
|
||||||
|
IF ( CH .EQ. '*') GOTO 1 ! *号开头的内容不读直接跳过
|
||||||
|
IF ( CH .EQ. ' ') GOTO 10 !此处引号内为TAB空格
|
||||||
|
IF ( CH .NE. ' ') GOTO 40 ! 不是空行的跳出子程序外用参数去存储
|
||||||
|
10 END DO
|
||||||
|
|
||||||
|
GOTO 1
|
||||||
|
|
||||||
|
40 BACKSPACE IIN
|
||||||
|
RETURN
|
||||||
|
|
||||||
|
END SUBROUTINE SUB_GETNXT
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
42
Fortran/SUB_INT_A.f90
Normal file
42
Fortran/SUB_INT_A.f90
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
! 根据区域入河流量过程,计算当时时刻的流量大小
|
||||||
|
|
||||||
|
SUBROUTINE INT_A( TC ,& ! 真实时刻 // 输入参数
|
||||||
|
N ,& ! 入河流量变化过程时段数
|
||||||
|
F ,& ! 入河流量变化过程线
|
||||||
|
FC ) ! 当前时刻入河流量大小 // 输出参数
|
||||||
|
|
||||||
|
IMPLICIT NONE
|
||||||
|
|
||||||
|
! 输入参数
|
||||||
|
REAL::TC
|
||||||
|
INTEGER::N
|
||||||
|
REAL::F(N)
|
||||||
|
|
||||||
|
! 输出参数
|
||||||
|
REAL::FC
|
||||||
|
|
||||||
|
! 中间参数
|
||||||
|
INTEGER::I
|
||||||
|
REAL::T
|
||||||
|
REAL::T1
|
||||||
|
REAL::T2
|
||||||
|
|
||||||
|
! 当前时间刚好和入河流量过程时刻值相同
|
||||||
|
DO I=1,N
|
||||||
|
T=1.0*FLOAT(I-1)
|
||||||
|
IF(TC.EQ.T)THEN
|
||||||
|
FC=F(I)
|
||||||
|
END IF
|
||||||
|
END DO
|
||||||
|
|
||||||
|
! 当前时间和入河流量过程时刻值不同,做线性插值
|
||||||
|
DO I=1,N-1
|
||||||
|
T1=1.0*FLOAT(I-1)
|
||||||
|
T2=1.0*FLOAT(I)
|
||||||
|
IF(TC.GT.T1.AND.TC.LT.T2)THEN
|
||||||
|
FC=F(I)+(TC-T1)*(F(I+1)-F(I))/(T2-T1)
|
||||||
|
EXIT
|
||||||
|
END IF
|
||||||
|
END DO
|
||||||
|
|
||||||
|
END SUBROUTINE INT_A
|
339
Fortran/SUB_QZ.f90
Normal file
339
Fortran/SUB_QZ.f90
Normal file
@ -0,0 +1,339 @@
|
|||||||
|
! ==================================================================================
|
||||||
|
! 用四点隐格式计算未知时层水位Z和流量Q的子程序
|
||||||
|
! ==================================================================================
|
||||||
|
subroutine 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 )
|
||||||
|
|
||||||
|
|
||||||
|
INTEGER::NRIVER
|
||||||
|
INTEGER::NSECT
|
||||||
|
INTEGER::MRIVER
|
||||||
|
INTEGER::KRC
|
||||||
|
INTEGER::NDATA
|
||||||
|
integer River,tstep
|
||||||
|
REAL Qjj(ndata)
|
||||||
|
real L(nsect),M(nsect),P(nsect),R(nsect)
|
||||||
|
|
||||||
|
! node
|
||||||
|
INTEGER::Ns(nriver),Pc(nriver),Nrc(krc,nriver),Lc(krc,nriver)
|
||||||
|
REAL::Dric(krc,nriver),Qj(ndata,krc,nriver),Asave(krc,nriver)
|
||||||
|
! section
|
||||||
|
REAL::ds(mriver,nriver),bd(nsect,nriver),zd(nsect,nriver),sm(nsect,nriver), rough(nsect,nriver)
|
||||||
|
! boundary
|
||||||
|
INTEGER::UB1(nriver),UB2(nriver),DB1(nriver),DB2(nriver),NUB(2,nriver),NDB(2,nriver)
|
||||||
|
REAL::UBV(ndata,nriver),Aphi(2,nriver),DBV(ndata,nriver),Gate(4,nriver),ql,Zctr
|
||||||
|
! calcu
|
||||||
|
REAL::dt,sita,Bsor1,Bsor2
|
||||||
|
! zzqq
|
||||||
|
REAL::Z0(nsect,nriver),Q0(nsect,nriver),Z(nsect,nriver),Q(nsect,nriver),V(nsect,nriver)
|
||||||
|
! r_bv
|
||||||
|
REAL::condu,condd(3)
|
||||||
|
! BARC
|
||||||
|
REAL::Bs,As,Rs,Cs
|
||||||
|
|
||||||
|
|
||||||
|
f(t10,t1,t20,t2)=0.5*(sita*(t2+t1)+(1.0-sita)*(t20+t10))
|
||||||
|
tc=dt*float(tstep)/3600.0
|
||||||
|
|
||||||
|
if(UB1(river).eq.1)Z(1,river)=condu
|
||||||
|
if(UB1(river).eq.2)Q(1,river)=condu
|
||||||
|
|
||||||
|
! ----------------------------------------------------------------------------------
|
||||||
|
! 计算递推公式系数L、M、P、R
|
||||||
|
! ----------------------------------------------------------------------------------
|
||||||
|
P(1)=condu
|
||||||
|
R(1)=0.0
|
||||||
|
|
||||||
|
call sub_sect( NRIVER ,&
|
||||||
|
NSECT ,&
|
||||||
|
MRIVER ,&
|
||||||
|
KRC ,&
|
||||||
|
NDATA ,&
|
||||||
|
river,1,Z0(1,river),&
|
||||||
|
ds ,&
|
||||||
|
bd ,&
|
||||||
|
zd ,&
|
||||||
|
sm ,&
|
||||||
|
rough ,&
|
||||||
|
Bs ,&
|
||||||
|
As ,&
|
||||||
|
Rs ,&
|
||||||
|
Cs )
|
||||||
|
BB10=Bs
|
||||||
|
AA10=As
|
||||||
|
RR10=Rs
|
||||||
|
CC10=Cs
|
||||||
|
call sub_sect( NRIVER ,&
|
||||||
|
NSECT ,&
|
||||||
|
MRIVER ,&
|
||||||
|
KRC ,&
|
||||||
|
NDATA ,&
|
||||||
|
river,1,Z(1,river),&
|
||||||
|
ds ,&
|
||||||
|
bd ,&
|
||||||
|
zd ,&
|
||||||
|
sm ,&
|
||||||
|
rough ,&
|
||||||
|
Bs ,&
|
||||||
|
As ,&
|
||||||
|
Rs ,&
|
||||||
|
Cs )
|
||||||
|
BB1=Bs
|
||||||
|
AA1=As
|
||||||
|
RR1=Rs
|
||||||
|
CC1=Cs
|
||||||
|
do 100 k=1,Ns(river)-1
|
||||||
|
Ik=0
|
||||||
|
do 20 i=1,Pc(river)
|
||||||
|
if(Nrc(i,river).eq.k)then
|
||||||
|
Ic=i
|
||||||
|
Ik=1
|
||||||
|
end if
|
||||||
|
20 continue
|
||||||
|
|
||||||
|
if(Ik.ne.1)then
|
||||||
|
! ------------------------------------------------------
|
||||||
|
! 非汊点河段计算
|
||||||
|
!
|
||||||
|
! 计算河段M点处的水面宽B、面积A、水力半径R、流量Q和水位Z
|
||||||
|
! ------------------------------------------------------
|
||||||
|
call sub_sect( NRIVER ,&
|
||||||
|
NSECT ,&
|
||||||
|
MRIVER ,&
|
||||||
|
KRC ,&
|
||||||
|
NDATA ,&
|
||||||
|
river,k+1,Z0(k+1,river),&
|
||||||
|
ds ,&
|
||||||
|
bd ,&
|
||||||
|
zd ,&
|
||||||
|
sm ,&
|
||||||
|
rough ,&
|
||||||
|
Bs ,&
|
||||||
|
As ,&
|
||||||
|
Rs ,&
|
||||||
|
Cs )
|
||||||
|
BB20=Bs
|
||||||
|
AA20=As
|
||||||
|
RR20=Rs
|
||||||
|
CC20=Cs
|
||||||
|
call sub_sect( NRIVER ,&
|
||||||
|
NSECT ,&
|
||||||
|
MRIVER ,&
|
||||||
|
KRC ,&
|
||||||
|
NDATA ,&
|
||||||
|
river,k+1,Z(k+1,river),&
|
||||||
|
ds ,&
|
||||||
|
bd ,&
|
||||||
|
zd ,&
|
||||||
|
sm ,&
|
||||||
|
rough ,&
|
||||||
|
Bs ,&
|
||||||
|
As ,&
|
||||||
|
Rs ,&
|
||||||
|
Cs )
|
||||||
|
BB2=Bs
|
||||||
|
AA2=As
|
||||||
|
RR2=Rs
|
||||||
|
CC2=Cs
|
||||||
|
Bm=f(BB10,BB1,BB20,BB2)
|
||||||
|
Am=f(AA10,AA1,AA20,AA2)
|
||||||
|
Rm=f(RR10,RR1,RR20,RR2)
|
||||||
|
Cm=f(CC10,CC1,CC20,CC2)
|
||||||
|
Qm=f(Q0(k,river),Q(k,river),Q0(k+1,river),Q(k+1,river))
|
||||||
|
Zm=f(Z0(k,river),Z(k,river),Z0(k+1,river),Z(k+1,river))
|
||||||
|
|
||||||
|
! ------------------------------------------------------
|
||||||
|
! 计算河段方程中的系数
|
||||||
|
! ------------------------------------------------------
|
||||||
|
a1=1.0
|
||||||
|
c1=2.0*sita*dt/(ds(k,river)*Bm)
|
||||||
|
e1=Z0(k,river)+Z0(k+1,river)+(1.0-sita)/sita*c1*(Q0(k,river)-Q0(k+1,river))+2.0*dt*ql/Bm
|
||||||
|
a2=2.0*sita*dt/ds(k,river)*((Qm/Am)**2.0*Bm-9.8*Am)
|
||||||
|
c2=1.0-4.0*sita*dt/ds(k,river)*Qm/Am
|
||||||
|
d2=1.0+4.0*sita*dt/ds(k,river)*Qm/Am
|
||||||
|
call sub_sect( NRIVER ,&
|
||||||
|
NSECT ,&
|
||||||
|
MRIVER ,&
|
||||||
|
KRC ,&
|
||||||
|
NDATA ,&
|
||||||
|
river,k,Zm,&
|
||||||
|
ds ,&
|
||||||
|
bd ,&
|
||||||
|
zd ,&
|
||||||
|
sm ,&
|
||||||
|
rough ,&
|
||||||
|
Bs ,&
|
||||||
|
As ,&
|
||||||
|
Rs ,&
|
||||||
|
Cs )
|
||||||
|
AZm1=As
|
||||||
|
call sub_sect( NRIVER ,&
|
||||||
|
NSECT ,&
|
||||||
|
MRIVER ,&
|
||||||
|
KRC ,&
|
||||||
|
NDATA ,&
|
||||||
|
river,k+1,Zm,&
|
||||||
|
ds ,&
|
||||||
|
bd ,&
|
||||||
|
zd ,&
|
||||||
|
sm ,&
|
||||||
|
rough ,&
|
||||||
|
Bs ,&
|
||||||
|
As ,&
|
||||||
|
Rs ,&
|
||||||
|
Cs )
|
||||||
|
AZm2=As
|
||||||
|
e2=(1.0-sita)/sita*a2*(Z0(k+1,river)-Z0(k,river))+(1.0-4.0*(1.0-sita)*dt/ds(k,river)*Qm/Am)*Q0(k+1,river)+(1.0+4.0*(1.0-sita)*dt/ds(k,river)*Qm/Am)*Q0(k,river)+2.0*dt*(Qm/Am)**2.0*(AZm2-AZm1)/ds(k,river)-2.0*dt*9.8*abs(Qm)*Qm/(Am*Cm*Cm*Rm)
|
||||||
|
else
|
||||||
|
|
||||||
|
! --------------------------------------------------------
|
||||||
|
! 汊点计算处理(普通汊点Lc=1,集中入流Lc=2,调蓄水库Lc=3)
|
||||||
|
! --------------------------------------------------------
|
||||||
|
if(Lc(Ic,river).eq.1)then
|
||||||
|
do 35 j=1,nriver
|
||||||
|
if(NUB(1,j).eq.river.and.NUB(2,j).eq.Nrc(Ic,river))then
|
||||||
|
a1=0.0
|
||||||
|
c1=1.0
|
||||||
|
e1=Dric(Ic,river)*Q(1,j)
|
||||||
|
a2=1.0
|
||||||
|
c2=0.0
|
||||||
|
d2=0.0
|
||||||
|
e2=0.0
|
||||||
|
elseif(NDB(1,j).eq.river.and.NDB(2,j).eq.Nrc(Ic,river))then
|
||||||
|
a1=0.0
|
||||||
|
c1=1.0
|
||||||
|
e1=Dric(Ic,river)*Q(Ns(j),j)
|
||||||
|
a2=1.0
|
||||||
|
c2=0.0
|
||||||
|
d2=0.0
|
||||||
|
e2=0.0
|
||||||
|
end if
|
||||||
|
35 continue
|
||||||
|
elseif(Lc(Ic,river).eq.2)then
|
||||||
|
do 55 ii=1,ndata
|
||||||
|
Qjj(ii)=Qj(ii,Ic,river)
|
||||||
|
55 continue
|
||||||
|
call int_a(tc,ndata,Qjj,fc)
|
||||||
|
a1=0.0
|
||||||
|
c1=1.0
|
||||||
|
e1=Dric(Ic,river)*fc
|
||||||
|
a2=1.0
|
||||||
|
c2=0.0
|
||||||
|
d2=0.0
|
||||||
|
e2=0.0
|
||||||
|
elseif(Lc(Ic,river).eq.3)then
|
||||||
|
a1=0.5*Asave(Ic,river)/dt
|
||||||
|
c1=1.0
|
||||||
|
e1=Asave(Ic,river)*Z0(k,river)/dt
|
||||||
|
a2=1.0
|
||||||
|
c2=0.0
|
||||||
|
d2=0.0
|
||||||
|
e2=0.0
|
||||||
|
end if
|
||||||
|
|
||||||
|
|
||||||
|
end if
|
||||||
|
|
||||||
|
! ------------------------------------------------------
|
||||||
|
! 求上游边界条件为水位过程线的递推系数
|
||||||
|
! ------------------------------------------------------
|
||||||
|
if(UB1(river).eq.1)then
|
||||||
|
Y1=a1*R(k)-c1
|
||||||
|
Y2=a2*R(k)+c2
|
||||||
|
Y3=e1-a1*P(k)
|
||||||
|
Y4=e2-a2*P(k)
|
||||||
|
Y5=a1*Y2+a2*Y1
|
||||||
|
L(k+1)=(a2*Y3+a1*Y4)/Y5
|
||||||
|
M(k+1)=-(a1*d2+a2*c1)/Y5
|
||||||
|
P(k+1)=(Y2*Y3-Y1*Y4)/Y5
|
||||||
|
R(k+1)=(d2*Y1-c1*Y2)/Y5
|
||||||
|
end if
|
||||||
|
! ------------------------------------------------------
|
||||||
|
! 求上游边界条件为流量过程线的递推系数
|
||||||
|
! ------------------------------------------------------
|
||||||
|
if(UB1(river).eq.2)then
|
||||||
|
Y1=a1-c1*R(k)
|
||||||
|
Y2=a2+c2*R(k)
|
||||||
|
Y3=e1+c1*P(k)
|
||||||
|
Y4=e2-c2*P(k)
|
||||||
|
Y5=d2*Y1-c1*Y2
|
||||||
|
L(k+1)=(d2*Y3-c1*Y4)/Y5
|
||||||
|
M(k+1)=-(a1*d2+a2*c1)/Y5
|
||||||
|
P(k+1)=(Y1*Y4-Y2*Y3)/Y5
|
||||||
|
R(k+1)=(a1*Y2+a2*Y1)/Y5
|
||||||
|
end if
|
||||||
|
|
||||||
|
BB10=BB20
|
||||||
|
AA10=AA20
|
||||||
|
RR10=RR20
|
||||||
|
CC10=CC20
|
||||||
|
BB1=BB2
|
||||||
|
AA1=AA2
|
||||||
|
RR1=RR2
|
||||||
|
CC1=CC2
|
||||||
|
100 continue
|
||||||
|
! ----------------------------------------------------------------------------------
|
||||||
|
! 回代求出流量Q和水位Z
|
||||||
|
! ----------------------------------------------------------------------------------
|
||||||
|
if(UB1(river).eq.1)then
|
||||||
|
Q(Ns(river),river)=(condd(3)-condd(1)*P(Ns(river)))/(condd(1)*R(Ns(river))+condd(2))
|
||||||
|
do 120 i=Ns(river),2,-1
|
||||||
|
Z(i,river)=P(i)+R(i)*Q(i,river)
|
||||||
|
Q(i-1,river)=L(i)+M(i)*Q(i,river)
|
||||||
|
120 continue
|
||||||
|
end if
|
||||||
|
|
||||||
|
if(UB1(river).eq.2)then
|
||||||
|
Z(Ns(river),river)=(condd(3)-condd(2)*P(Ns(river)))/(condd(2)*R(Ns(river))+condd(1))
|
||||||
|
do 130 i=Ns(river),2,-1
|
||||||
|
Q(i,river)=P(i)+R(i)*Z(i,river)
|
||||||
|
Z(i-1,river)=L(i)+M(i)*Z(i,river)
|
||||||
|
130 continue
|
||||||
|
end if
|
||||||
|
|
||||||
|
return
|
||||||
|
end
|
45
Fortran/SUB_SECT.f90
Normal file
45
Fortran/SUB_SECT.f90
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
! ==================================================================================
|
||||||
|
! 计算断面几何要素的子程序
|
||||||
|
! ==================================================================================
|
||||||
|
subroutine sub_sect( NRIVER ,&
|
||||||
|
NSECT ,&
|
||||||
|
MRIVER ,&
|
||||||
|
KRC ,&
|
||||||
|
NDATA ,&
|
||||||
|
river ,&
|
||||||
|
Is ,&
|
||||||
|
Zs ,&
|
||||||
|
ds ,&
|
||||||
|
bd ,&
|
||||||
|
zd ,&
|
||||||
|
sm ,&
|
||||||
|
rough ,&
|
||||||
|
Bs ,&
|
||||||
|
As ,&
|
||||||
|
Rs ,&
|
||||||
|
Cs )
|
||||||
|
|
||||||
|
INTEGER::NRIVER
|
||||||
|
INTEGER::NSECT
|
||||||
|
INTEGER::MRIVER
|
||||||
|
INTEGER::KRC
|
||||||
|
INTEGER::NDATA
|
||||||
|
|
||||||
|
integer River
|
||||||
|
! section
|
||||||
|
REAL::ds(mriver,nriver),bd(nsect,nriver),zd(nsect,nriver),sm(nsect,nriver), rough(nsect,nriver)
|
||||||
|
! BARC
|
||||||
|
REAL::Bs,As,Rs,Cs
|
||||||
|
|
||||||
|
! ----------------------------------------------------------------------------------
|
||||||
|
! Bs、As、Rs、Cs——相应于水位Zs的断面要素(梯形断面)
|
||||||
|
! ----------------------------------------------------------------------------------
|
||||||
|
h=Zs-zd(Is,river)
|
||||||
|
Bs=bd(Is,river)+2.0*sm(Is,river)*h
|
||||||
|
As=(bd(Is,river)+sm(Is,river)*h)*h
|
||||||
|
Sl=bd(Is,river)+2*h*sqrt(1+sm(Is,river)**2.0)
|
||||||
|
Rs=As/Sl
|
||||||
|
Cs=Rs**(1.0/6.0)/rough(Is,river)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
563
Fortran/SUB_SHUILIANGJISUAN.f90
Normal file
563
Fortran/SUB_SHUILIANGJISUAN.f90
Normal file
@ -0,0 +1,563 @@
|
|||||||
|
! SUB_SHUILIANGJISUAN.f90
|
||||||
|
!
|
||||||
|
! FUNCTIONS/SUBROUTINES exported from SUB_SHUILIANGJISUAN.dll:
|
||||||
|
! SUB_SHUILIANGJISUAN - subroutine
|
||||||
|
!
|
||||||
|
subroutine SUB_SHUILIANGJISUAN( NDATA ,& ! 计算时刻数 // 输入参数
|
||||||
|
LONG ,& ! 河道长度
|
||||||
|
INbd ,& ! 断面底宽
|
||||||
|
INzd ,& ! 底高程
|
||||||
|
INsm ,& ! 边坡系数
|
||||||
|
INrough ,& ! 糙率
|
||||||
|
ZZ0 ,& ! 计算区域初始水位
|
||||||
|
DB ,& ! 下游边界条件类型 1.水位边界 2.流量边界
|
||||||
|
UQ ,& ! 上游流量过程
|
||||||
|
DQH ,& ! 上游水位/流量过程
|
||||||
|
dt ,& ! 计算步长( 秒)
|
||||||
|
OUTT ,& ! 计算断面输出时刻
|
||||||
|
OUTQ ,& ! 计算断面输出流量
|
||||||
|
OUTH ) ! 计算断面输出水位
|
||||||
|
|
||||||
|
! 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)
|
||||||
|
|
||||||
|
REAL::DDGC ! 计算断面堤顶高程
|
||||||
|
|
||||||
|
REAL::MAXH
|
||||||
|
|
||||||
|
INTEGER::MY ! 1.漫溢 2.未漫溢
|
||||||
|
|
||||||
|
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')
|
||||||
|
!WRITE(1,*)' ! 计算时刻数 ', NDATA ,&
|
||||||
|
! ' ! 河道长度 ', LONG ,&
|
||||||
|
! '! 断面底宽 ', INbd ,&
|
||||||
|
! '! 底高程 ' , INzd ,&
|
||||||
|
! '! 边坡系数 ', INsm ,&
|
||||||
|
! ' ! 糙率 ' , INrough ,&
|
||||||
|
! ' ! 计算区域初始水位 ', ZZ0 ,&
|
||||||
|
! ' ! 下游边界条件类型 1.水位边界 2.流量边界 ', DB ,&
|
||||||
|
! ' ! 上游流量过程 ' , UQ ,&
|
||||||
|
! ' ! 上游水位/流量过程 ', DQH ,&
|
||||||
|
! ' ! 计算步长( 秒) ', dt ,&
|
||||||
|
! '! 计算断面堤顶高程 ', DDGC
|
||||||
|
FHD = 0
|
||||||
|
TEMP = 0
|
||||||
|
|
||||||
|
! 1.读入河道组态数据
|
||||||
|
!open(1,file='河道组态数据.TXT')
|
||||||
|
|
||||||
|
! 读入:1.河道数量 2.河道计算断面数最大值 3.河道汊点数最大值 4.计算时刻数
|
||||||
|
!CALL SUB_GETNXT(1)
|
||||||
|
!read(1,*)
|
||||||
|
nriver = 1
|
||||||
|
nsect = 6
|
||||||
|
krc = 0
|
||||||
|
|
||||||
|
mriver=nsect - 1 ! 这是我写的,微段数不就等于断面数-1吗
|
||||||
|
|
||||||
|
ALLOCATE(Ns(nriver),Pc(nriver),Nrc(krc,nriver),Lc(krc,nriver))
|
||||||
|
ALLOCATE(Dric(krc,nriver),Qj(ndata,krc,nriver),Asave(krc,nriver))
|
||||||
|
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))
|
||||||
|
ALLOCATE(Qp(ndata))
|
||||||
|
ALLOCATE(Zc(nsect,nriver),Qc(nsect,nriver))
|
||||||
|
|
||||||
|
!读入: 1.河道序号 2.河道断面数 3.河道汊点数
|
||||||
|
! (所有汊点均变成三汊口处理)
|
||||||
|
! CALL SUB_GETNXT(1)
|
||||||
|
! DO I = 1,nriver
|
||||||
|
!read(1,*)II,Ns(i),Pc(i)
|
||||||
|
! END DO
|
||||||
|
Ns(1) = 6
|
||||||
|
Pc(1) = 0
|
||||||
|
|
||||||
|
!读入:! 1.河道序号 2.河道汊点微段号 3.汊点类型 4.流动方向
|
||||||
|
! 汊点类型:1——普通汊点,2——集中入流,3——调蓄水库
|
||||||
|
! 与汊点相连的河道或集中入流的水流方向,流入汊点:1,流出汊点:-1,调蓄水库任意给定
|
||||||
|
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
|
||||||
|
|
||||||
|
! 集中入流的汊点读入流量过程
|
||||||
|
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
|
||||||
|
|
||||||
|
! 连接调蓄水库的汊点读入水库面积(m2)
|
||||||
|
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
|
||||||
|
|
||||||
|
! 2.读入河道几何数据
|
||||||
|
! CALL SUB_GETNXT(1)
|
||||||
|
! ds = 0.0
|
||||||
|
! DO J = 1,nriver
|
||||||
|
! DO I = 1,Ns(j)-1
|
||||||
|
!read(1,*)II,II,ds(i,j) ! 每条河道各微段的长度,普通汊点、集中入流微段及调蓄水库的长度取0,每条河道的首末微段长度必须取一个非零值。
|
||||||
|
! 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)
|
||||||
|
!read(1,*)II,II,bd(i,j),zd(i,j),sm(i,j),rough(i,j) ! 梯形断面底宽、底高程、边坡系数、糙率
|
||||||
|
! END DO
|
||||||
|
! END DO
|
||||||
|
|
||||||
|
bd = INbd
|
||||||
|
zd = INzd
|
||||||
|
sm = INsm
|
||||||
|
rough = INrough
|
||||||
|
|
||||||
|
! 3.读入河道边界数据
|
||||||
|
! CALL SUB_GETNXT(1)
|
||||||
|
! read(1,*)ZZ0,Zctr ! ZZ0——计算区域初始水位,Zctr——河道末端挡潮闸运行控制水位,
|
||||||
|
|
||||||
|
Zctr = 0.0
|
||||||
|
|
||||||
|
Scanal = 0.0 ! Scanal——河网所有河道的合计长度,用于计算旁侧入流量ql
|
||||||
|
|
||||||
|
DO J = 1,nriver
|
||||||
|
DO I = 1,Ns(j)-1
|
||||||
|
Scanal = Scanal + ds(i,j) ! 每条河道各微段的长度,普通汊点、集中入流微段及调蓄水库的长度取0,每条河道的首末微段长度必须取一个非零值。
|
||||||
|
END DO
|
||||||
|
END DO
|
||||||
|
|
||||||
|
!CALL SUB_GETNXT(1)
|
||||||
|
!DO I = 1,ndata
|
||||||
|
! read(1,*)II,Qp(i) ! Qp——计算区域入河流量过程
|
||||||
|
! END DO
|
||||||
|
|
||||||
|
Qp = 0.0
|
||||||
|
|
||||||
|
! UB1上游边界条件类型1(1——水位边界,2——流量边界,3——水位流量关系)
|
||||||
|
! UB2上游边界条件类型2(1——河网外边界,2——河网内边界)
|
||||||
|
! DB1下游边界条件类型1(1——水位边界,2——流量边界,3——水位流量关系)
|
||||||
|
! DB2下游边界条件类型2(1——河网外边界,2——河网内边界)
|
||||||
|
!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
|
||||||
|
! 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) ! 读入上游内边界断面所连接的河道编号、微段编号
|
||||||
|
! endif
|
||||||
|
! END DO
|
||||||
|
|
||||||
|
DO I = 1,ndata
|
||||||
|
UBV(I,1) = UQ(I)
|
||||||
|
END DO
|
||||||
|
|
||||||
|
!CALL SUB_GETNXT(1)
|
||||||
|
!DO i=1,nriver
|
||||||
|
! 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) = 流量公式C1;Gate(4,i) = 流量公式C2 (流量公式Q=C1*B*e*dZ^C2中的C1和C2)
|
||||||
|
! ELSE
|
||||||
|
! read(1,*)II,II,II,(DBV(j,i),j=1,ndata) ! 读入下游外边界断面处的水位,或流量,或闸下潮位过程
|
||||||
|
! end if
|
||||||
|
! elseif(DB2(i).eq.2)then ! 下游内部
|
||||||
|
! if(DB1(i).eq.2)then
|
||||||
|
! read(1,*)II,II,II,(NDB(j,i),j=1,2),(Aphi(j,i),j=1,2) ! 下游流量内边界(管涵)的过流断面面积、流速系数 下游内边界一般用水位,如果用流量,一般是管涵,需要提供过流面积和流速系数
|
||||||
|
! ELSE
|
||||||
|
! read(1,*)II,II,II,(NDB(j,i),j=1,2) ! 读入下游内边界断面所连接的河道编号、微段编号
|
||||||
|
! end if
|
||||||
|
! endif
|
||||||
|
!END DO
|
||||||
|
|
||||||
|
DO I = 1,ndata
|
||||||
|
DBV(I,1) = DQH(I)
|
||||||
|
END DO
|
||||||
|
|
||||||
|
! 4.读入河道计算条件
|
||||||
|
!CALL SUB_GETNXT(1)
|
||||||
|
!read(1,*)period,dt,sita ! period——计算小时数,dt——计算时间步长(秒),sita——水量隐格式权系数
|
||||||
|
!CALL SUB_GETNXT(1)
|
||||||
|
!read(1,*)sorz,sorq,epsz,epsq ! sorz、sorq——水位、流量迭代松弛因子,epsz、epsq——水位、流量迭代控制精度
|
||||||
|
!CALL SUB_GETNXT(1)
|
||||||
|
!read(1,*)Bsor1,Bsor2 ! Bsor1、Bsor2——水闸外边界、管涵内边界计算中的松弛因子
|
||||||
|
!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
|
||||||
|
|
||||||
|
|
||||||
|
! 计算时间步长
|
||||||
|
maxtstep=period*3600/dt
|
||||||
|
maxiter=1000 ! 仿真模拟步数
|
||||||
|
|
||||||
|
! 给河道水位、流量赋初值
|
||||||
|
DO river=1,nriver
|
||||||
|
DO Is=1,Ns(river)
|
||||||
|
Z0(Is,river)=ZZ0
|
||||||
|
Q0(Is,river)=0.0
|
||||||
|
END DO
|
||||||
|
END DO
|
||||||
|
|
||||||
|
! 流量、水位输出
|
||||||
|
!open(1,file='河道1各断面水位变化.TXT')
|
||||||
|
!open(2,file='河道2各断面水位变化.TXT')
|
||||||
|
!open(3,file='河道3各断面水位变化.TXT')
|
||||||
|
!open(4,file='河道4各断面水位变化.TXT')
|
||||||
|
!
|
||||||
|
!open(11,file='河道1各断面流量变化.TXT')
|
||||||
|
!open(12,file='河道2各断面流量变化.TXT')
|
||||||
|
!open(13,file='河道3各断面流量变化.TXT')
|
||||||
|
!open(14,file='河道4各断面流量变化.TXT')
|
||||||
|
|
||||||
|
! ----------------------------------------------------------------------------------
|
||||||
|
! 迭代求解每个时刻的水位、流量
|
||||||
|
! ----------------------------------------------------------------------------------
|
||||||
|
DO tstep=1,maxtstep ! 步数累加器
|
||||||
|
|
||||||
|
TEMP = TEMP + 1
|
||||||
|
ttime=dt*tstep/3600.0 ! 真实时刻
|
||||||
|
! 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
|
||||||
|
|
||||||
|
! 计算当前时刻入河流量大小
|
||||||
|
call int_a( ttime ,& ! 真实时刻 // 输入参数
|
||||||
|
ndata ,& ! 入河流量变化过程时段数
|
||||||
|
Qp ,& ! 入河流量变化过程线
|
||||||
|
fc ) ! 当前时刻入河流量大小 // 输出参数
|
||||||
|
|
||||||
|
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
|
||||||
|
! 确定计算时刻河段上下游边界条件值
|
||||||
|
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 )
|
||||||
|
|
||||||
|
! 用四点隐格式计算未知时层水位Z和流量Q
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
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)
|
||||||
|
! 计算断面几何要素
|
||||||
|
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
|
||||||
|
|
||||||
|
! 输出几个典型河道的水位流量变化过程
|
||||||
|
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)
|
||||||
|
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,'迭代发散')
|
||||||
|
80 format(1x,40f12.4)
|
||||||
|
|
||||||
|
|
||||||
|
!MAXH = MAXVAL(OUTH)
|
||||||
|
!IF(MAXH.GT.DDGC)THEN
|
||||||
|
! MY = 1
|
||||||
|
!ELSE
|
||||||
|
! MY = 0
|
||||||
|
!END IF
|
||||||
|
|
||||||
|
!WRITE(1,*)' ! 1.漫溢 0.未漫溢 ' , MY ,&
|
||||||
|
! '! 计算断面输出时刻 ', OUTT ,&
|
||||||
|
! '! 计算断面输出流量 ', OUTQ ,&
|
||||||
|
! '! 计算断面输出水位 ', OUTH
|
||||||
|
|
||||||
|
CLOSE(1)
|
||||||
|
|
||||||
|
END SUBROUTINE SUB_SHUILIANGJISUAN
|
||||||
|
|
27
FortranWebApi.csproj
Normal file
27
FortranWebApi.csproj
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<InvariantGlobalization>true</InvariantGlobalization>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="8.0.0" />
|
||||||
|
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.4.0" />
|
||||||
|
<PackageReference Include="Serilog" Version="4.2.0" />
|
||||||
|
<PackageReference Include="Serilog.AspNetCore" Version="8.0.1" />
|
||||||
|
<PackageReference Include="Serilog.Extensions.Logging" Version="8.0.0" />
|
||||||
|
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
|
||||||
|
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.0" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="lib{{FortranFunctionName}}.so">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
23
HttpRequests/fortranwebapi.http
Normal file
23
HttpRequests/fortranwebapi.http
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
@FortranWebApi_HostAddress = http://localhost:5000
|
||||||
|
|
||||||
|
### 测试Fortran请求
|
||||||
|
|
||||||
|
POST {{FortranWebApi_HostAddress}}/FortranCalculate
|
||||||
|
Content-Type: application/json
|
||||||
|
|
||||||
|
{
|
||||||
|
"text": "{\"FuncName\":\"calculate_main\",\"ClassName\":\"\",\"Par\":[ {"Name":"NDATA","DataType":"0","ArrayType":"0","IsOut":"2","Data":0},
|
||||||
|
{"Name":"LONG","DataType":"1","ArrayType":"0","IsOut":"2","Data":0},
|
||||||
|
{"Name":"INbd","DataType":"0","ArrayType":"0","IsOut":"2","Data":0},
|
||||||
|
{"Name":"INzd","DataType":"0","ArrayType":"0","IsOut":"2","Data":0},
|
||||||
|
{"Name":"INsm","DataType":"0","ArrayType":"0","IsOut":"2","Data":0},
|
||||||
|
{"Name":"INrough","DataType":"0","ArrayType":"0","IsOut":"2","Data":0},
|
||||||
|
{"Name":"ZZ0","DataType":"1","ArrayType":"0","IsOut":"2","Data":0},
|
||||||
|
{"Name":"DB","DataType":"0","ArrayType":"0","IsOut":"2","Data":0},
|
||||||
|
{"Name":"UQ","DataType":"1","ArrayType":"1","IsOut":"2","Data":[]},
|
||||||
|
{"Name":"DQH","DataType":"1","ArrayType":"1","IsOut":"2","Data":[]},
|
||||||
|
{"Name":"dt","DataType":"1","ArrayType":"0","IsOut":"2","Data":0},
|
||||||
|
{"Name":"OUTT","DataType":"1","ArrayType":"1","IsOut":"1","Data":[]},
|
||||||
|
{"Name":"OUTQ","DataType":"1","ArrayType":"1","IsOut":"1","Data":[]},
|
||||||
|
{"Name":"OUTH","DataType":"1","ArrayType":"1","IsOut":"1","Data":[]}]}"
|
||||||
|
}
|
31
Models/ApiResponse.cs
Normal file
31
Models/ApiResponse.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace FortranWebApi.Models
|
||||||
|
{
|
||||||
|
public class ApiResponse<T>
|
||||||
|
{
|
||||||
|
[JsonPropertyName("message")]
|
||||||
|
public string Message { get; set; } = "Success";
|
||||||
|
|
||||||
|
[JsonPropertyName("success")]
|
||||||
|
public bool Success { get; set; } = true;
|
||||||
|
|
||||||
|
[JsonPropertyName("data")]
|
||||||
|
public ApiResponseData<T>? Data { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ApiResponseData<T>
|
||||||
|
{
|
||||||
|
[JsonPropertyName("contentType")]
|
||||||
|
public string? ContentType { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("serializerSettings")]
|
||||||
|
public object? SerializerSettings { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("statusCode")]
|
||||||
|
public int? StatusCode { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName("value")]
|
||||||
|
public T? Value { get; set; }
|
||||||
|
}
|
||||||
|
}
|
22
Models/FortranParameter.cs
Normal file
22
Models/FortranParameter.cs
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace FortranWebApi.Models
|
||||||
|
{
|
||||||
|
public class FortranParameter
|
||||||
|
{
|
||||||
|
[JsonPropertyName("name")]
|
||||||
|
public string Name { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[JsonPropertyName("dataType")]
|
||||||
|
public string DataType { get; set; } = "0";
|
||||||
|
|
||||||
|
[JsonPropertyName("arrayType")]
|
||||||
|
public string ArrayType { get; set; } = "0";
|
||||||
|
|
||||||
|
[JsonPropertyName("isOut")]
|
||||||
|
public string IsOut { get; set; } = "2";
|
||||||
|
|
||||||
|
[JsonPropertyName("data")]
|
||||||
|
public object? Data { get; set; }
|
||||||
|
}
|
||||||
|
}
|
13
Models/FortranRequest.cs
Normal file
13
Models/FortranRequest.cs
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace FortranWebApi.Models
|
||||||
|
{
|
||||||
|
public class FortranRequest
|
||||||
|
{
|
||||||
|
public string FuncName { get; set; } = string.Empty;
|
||||||
|
public string ClassName { get; set; } = string.Empty;
|
||||||
|
|
||||||
|
[JsonPropertyName("par")]
|
||||||
|
public List<FortranParameter> Parameters { get; set; } = new List<FortranParameter>();
|
||||||
|
}
|
||||||
|
}
|
7
Models/FortranRequestWrapper.cs
Normal file
7
Models/FortranRequestWrapper.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
namespace FortranWebApi.Models
|
||||||
|
{
|
||||||
|
public class FortranRequestWrapper
|
||||||
|
{
|
||||||
|
public string Text { get; set; } = string.Empty;
|
||||||
|
}
|
||||||
|
}
|
80
Program.cs
Normal file
80
Program.cs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
using Serilog;
|
||||||
|
using FortranWebApi.Services;
|
||||||
|
using System.IO;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
// 设置库搜索路径
|
||||||
|
string currentDir = Directory.GetCurrentDirectory();
|
||||||
|
Environment.SetEnvironmentVariable("LD_LIBRARY_PATH",
|
||||||
|
$"{Environment.GetEnvironmentVariable("LD_LIBRARY_PATH")}:{currentDir}");
|
||||||
|
|
||||||
|
var builder = WebApplication.CreateBuilder(args);
|
||||||
|
|
||||||
|
// 添加健康检查服务
|
||||||
|
builder.Services.AddHealthChecks();
|
||||||
|
|
||||||
|
// 配置Serilog
|
||||||
|
Log.Logger = new LoggerConfiguration()
|
||||||
|
.WriteTo.Console(outputTemplate:
|
||||||
|
"{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}")
|
||||||
|
.WriteTo.File("logs/log-.txt",
|
||||||
|
rollingInterval: RollingInterval.Day,
|
||||||
|
outputTemplate:
|
||||||
|
"{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz} [{Level:u3}] {Message:lj}{NewLine}{Exception}")
|
||||||
|
.CreateLogger();
|
||||||
|
|
||||||
|
builder.Host.UseSerilog(); // 将Serilog添加到Host
|
||||||
|
|
||||||
|
// 配置JSON序列化选项,使用驼峰命名法
|
||||||
|
builder.Services.AddControllers().AddJsonOptions(options =>
|
||||||
|
{
|
||||||
|
options.JsonSerializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase;
|
||||||
|
options.JsonSerializerOptions.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase;
|
||||||
|
options.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
|
||||||
|
options.JsonSerializerOptions.PropertyNameCaseInsensitive = true;
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Services.AddEndpointsApiExplorer();
|
||||||
|
builder.Services.AddSwaggerGen();
|
||||||
|
builder.Services.AddSingleton<FortranInteropService>();
|
||||||
|
|
||||||
|
// 配置CORS
|
||||||
|
builder.Services.AddCors(options =>
|
||||||
|
{
|
||||||
|
options.AddDefaultPolicy(policy =>
|
||||||
|
{
|
||||||
|
policy.AllowAnyOrigin()
|
||||||
|
.AllowAnyMethod()
|
||||||
|
.AllowAnyHeader();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
var app = builder.Build();
|
||||||
|
|
||||||
|
// Configure the HTTP request pipeline.
|
||||||
|
if (app.Environment.IsDevelopment())
|
||||||
|
{
|
||||||
|
app.UseSwagger();
|
||||||
|
app.UseSwaggerUI();
|
||||||
|
}
|
||||||
|
|
||||||
|
app.UseCors();
|
||||||
|
app.UseAuthorization();
|
||||||
|
// 映射健康检查端点
|
||||||
|
app.MapHealthChecks("/health");
|
||||||
|
app.MapControllers();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Log.Information("启动应用程序...");
|
||||||
|
app.Run();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Log.Fatal(ex, "应用程序启动失败");
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Log.CloseAndFlush();
|
||||||
|
}
|
14
Properties/launchSettings.json
Normal file
14
Properties/launchSettings.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"FortranWebApi": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"launchUrl": "swagger",
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"applicationUrl": "http://0.0.0.0:5000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
565
Services/FortranInteropService.cs
Normal file
565
Services/FortranInteropService.cs
Normal file
@ -0,0 +1,565 @@
|
|||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using FortranWebApi.Models;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Runtime.InteropServices.Marshalling;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace FortranWebApi.Services
|
||||||
|
{
|
||||||
|
public class FortranInteropService
|
||||||
|
{
|
||||||
|
// 静态构造函数设置DLL导入解析器
|
||||||
|
static FortranInteropService()
|
||||||
|
{
|
||||||
|
// 添加当前目录到库搜索路径
|
||||||
|
NativeLibrary.SetDllImportResolver(typeof(FortranInteropService).Assembly, (name, assembly, path) =>
|
||||||
|
{
|
||||||
|
if (name == "libSUB_SHUILIANGJISUAN.so")
|
||||||
|
{
|
||||||
|
// 尝试从当前目录加载
|
||||||
|
string currentDir = Directory.GetCurrentDirectory();
|
||||||
|
string libraryPath = Path.Combine(currentDir, "libSUB_SHUILIANGJISUAN.so");
|
||||||
|
|
||||||
|
if (File.Exists(libraryPath))
|
||||||
|
{
|
||||||
|
return NativeLibrary.Load(libraryPath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 回退到默认加载行为
|
||||||
|
return IntPtr.Zero;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// DllImport声明
|
||||||
|
[DllImport("libSUB_SHUILIANGJISUAN.so", CallingConvention = CallingConvention.Cdecl, EntryPoint = "SUB_SHUILIANGJISUAN")]
|
||||||
|
private static extern void SUB_SHUILIANGJISUAN(
|
||||||
|
ref int NDATA,
|
||||||
|
ref float LONG,
|
||||||
|
ref int INbd,
|
||||||
|
ref int INzd,
|
||||||
|
ref int INsm,
|
||||||
|
ref int INrough,
|
||||||
|
ref float ZZ0,
|
||||||
|
ref int DB,
|
||||||
|
float[] UQ,
|
||||||
|
float[] DQH,
|
||||||
|
ref float dt,
|
||||||
|
float[] OUTT,
|
||||||
|
float[] OUTQ,
|
||||||
|
float[] OUTH
|
||||||
|
);
|
||||||
|
|
||||||
|
public string ProcessFortranRequest(string requestText)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
// 解析请求
|
||||||
|
var options = new JsonSerializerOptions
|
||||||
|
{
|
||||||
|
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
|
||||||
|
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
|
||||||
|
PropertyNameCaseInsensitive = true,
|
||||||
|
WriteIndented = true
|
||||||
|
};
|
||||||
|
|
||||||
|
var request = JsonSerializer.Deserialize<FortranRequest>(requestText, options);
|
||||||
|
if (request == null)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("无效的请求格式");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 准备输入参数
|
||||||
|
var parameters = request.Parameters;
|
||||||
|
|
||||||
|
// 提取参数
|
||||||
|
int NDATA = GetIntParameter(parameters, "NDATA");
|
||||||
|
float LONG = GetFloatParameter(parameters, "LONG");
|
||||||
|
int INbd = GetIntParameter(parameters, "INbd");
|
||||||
|
int INzd = GetIntParameter(parameters, "INzd");
|
||||||
|
int INsm = GetIntParameter(parameters, "INsm");
|
||||||
|
int INrough = GetIntParameter(parameters, "INrough");
|
||||||
|
float ZZ0 = GetFloatParameter(parameters, "ZZ0");
|
||||||
|
int DB = GetIntParameter(parameters, "DB");
|
||||||
|
float[] UQ = GetFloatArrayParameter(parameters, "UQ");
|
||||||
|
float[] DQH = GetFloatArrayParameter(parameters, "DQH");
|
||||||
|
float dt = GetFloatParameter(parameters, "dt");
|
||||||
|
|
||||||
|
|
||||||
|
// 准备数组参数
|
||||||
|
float[] OUTT = new float[10000]; // 输出数组,初始大小为10000
|
||||||
|
float[] OUTQ = new float[10000]; // 输出数组,初始大小为10000
|
||||||
|
float[] OUTH = new float[10000]; // 输出数组,初始大小为10000
|
||||||
|
|
||||||
|
|
||||||
|
// 调用Fortran函数
|
||||||
|
SUB_SHUILIANGJISUAN(
|
||||||
|
ref NDATA,
|
||||||
|
ref LONG,
|
||||||
|
ref INbd,
|
||||||
|
ref INzd,
|
||||||
|
ref INsm,
|
||||||
|
ref INrough,
|
||||||
|
ref ZZ0,
|
||||||
|
ref DB,
|
||||||
|
UQ,
|
||||||
|
DQH,
|
||||||
|
ref dt,
|
||||||
|
OUTT,
|
||||||
|
OUTQ,
|
||||||
|
OUTH
|
||||||
|
);
|
||||||
|
|
||||||
|
// 更新输出参数
|
||||||
|
UpdateArrayParameter(parameters, "OUTT", OUTT);
|
||||||
|
UpdateArrayParameter(parameters, "OUTQ", OUTQ);
|
||||||
|
UpdateArrayParameter(parameters, "OUTH", OUTH);
|
||||||
|
|
||||||
|
|
||||||
|
// 处理输出数组
|
||||||
|
// 处理输出数组 OUTT
|
||||||
|
// 注意:没有找到明确的长度参数,使用非零元素数量
|
||||||
|
{
|
||||||
|
int nonZeroCount = 0;
|
||||||
|
for (int i = 0; i < OUTT.Length; i++)
|
||||||
|
{
|
||||||
|
if (OUTT[i] != 0) nonZeroCount = i + 1;
|
||||||
|
}
|
||||||
|
if (nonZeroCount > 0)
|
||||||
|
{
|
||||||
|
float[] resultArray = new float[nonZeroCount];
|
||||||
|
Array.Copy(OUTT, resultArray, nonZeroCount);
|
||||||
|
UpdateArrayParameter(parameters, "OUTT", resultArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 处理输出数组 OUTQ
|
||||||
|
// 注意:没有找到明确的长度参数,使用非零元素数量
|
||||||
|
{
|
||||||
|
int nonZeroCount = 0;
|
||||||
|
for (int i = 0; i < OUTQ.Length; i++)
|
||||||
|
{
|
||||||
|
if (OUTQ[i] != 0) nonZeroCount = i + 1;
|
||||||
|
}
|
||||||
|
if (nonZeroCount > 0)
|
||||||
|
{
|
||||||
|
float[] resultArray = new float[nonZeroCount];
|
||||||
|
Array.Copy(OUTQ, resultArray, nonZeroCount);
|
||||||
|
UpdateArrayParameter(parameters, "OUTQ", resultArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 处理输出数组 OUTH
|
||||||
|
// 注意:没有找到明确的长度参数,使用非零元素数量
|
||||||
|
{
|
||||||
|
int nonZeroCount = 0;
|
||||||
|
for (int i = 0; i < OUTH.Length; i++)
|
||||||
|
{
|
||||||
|
if (OUTH[i] != 0) nonZeroCount = i + 1;
|
||||||
|
}
|
||||||
|
if (nonZeroCount > 0)
|
||||||
|
{
|
||||||
|
float[] resultArray = new float[nonZeroCount];
|
||||||
|
Array.Copy(OUTH, resultArray, nonZeroCount);
|
||||||
|
UpdateArrayParameter(parameters, "OUTH", resultArray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 返回结果 - 只返回原始请求的结构,但包含更新后的参数
|
||||||
|
var result = new FortranRequest
|
||||||
|
{
|
||||||
|
FuncName = request.FuncName,
|
||||||
|
ClassName = request.ClassName,
|
||||||
|
Parameters = parameters
|
||||||
|
};
|
||||||
|
|
||||||
|
return JsonSerializer.Serialize(result, options);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
return JsonSerializer.Serialize(new { error = ex.Message });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private float GetFloatParameter(List<FortranParameter> parameters, string name)
|
||||||
|
{
|
||||||
|
var param = parameters.FirstOrDefault(p => p.Name == name);
|
||||||
|
if (param == null || param.Data == null)
|
||||||
|
{
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param.Data is JsonElement element)
|
||||||
|
{
|
||||||
|
if (element.ValueKind == JsonValueKind.Number)
|
||||||
|
{
|
||||||
|
return element.GetSingle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Convert.ToSingle(param.Data);
|
||||||
|
}
|
||||||
|
private double GetDoubleParameter(List<FortranParameter> parameters, string name)
|
||||||
|
{
|
||||||
|
var param = parameters.FirstOrDefault(p => p.Name == name);
|
||||||
|
if (param == null || param.Data == null)
|
||||||
|
{
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param.Data is JsonElement element)
|
||||||
|
{
|
||||||
|
if (element.ValueKind == JsonValueKind.Number)
|
||||||
|
{
|
||||||
|
return element.GetSingle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Convert.ToDouble(param.Data);
|
||||||
|
}
|
||||||
|
private int GetIntParameter(List<FortranParameter> parameters, string name)
|
||||||
|
{
|
||||||
|
var param = parameters.FirstOrDefault(p => p.Name == name);
|
||||||
|
if (param == null || param.Data == null)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param.Data is JsonElement element)
|
||||||
|
{
|
||||||
|
if (element.ValueKind == JsonValueKind.Number)
|
||||||
|
{
|
||||||
|
return element.GetInt32();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Convert.ToInt32(param.Data);
|
||||||
|
}
|
||||||
|
private int[] GetIntArrayParameter(List<FortranParameter> parameters, string name)
|
||||||
|
{
|
||||||
|
var param = parameters.FirstOrDefault(p => p.Name == name);
|
||||||
|
if (param == null || param.Data == null)
|
||||||
|
{
|
||||||
|
return Array.Empty<int>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param.Data is JsonElement element && element.ValueKind == JsonValueKind.Array)
|
||||||
|
{
|
||||||
|
var array = new List<int>();
|
||||||
|
foreach (var item in element.EnumerateArray())
|
||||||
|
{
|
||||||
|
if (item.ValueKind == JsonValueKind.Number)
|
||||||
|
{
|
||||||
|
array.Add(item.GetInt32());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param.Data is System.Collections.IEnumerable enumerable && !(param.Data is string))
|
||||||
|
{
|
||||||
|
var array = new List<int>();
|
||||||
|
foreach (var item in enumerable)
|
||||||
|
{
|
||||||
|
array.Add(Convert.ToInt32(item));
|
||||||
|
}
|
||||||
|
return array.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.Empty<int>();
|
||||||
|
}
|
||||||
|
private float[] GetFloatArrayParameter(List<FortranParameter> parameters, string name)
|
||||||
|
{
|
||||||
|
var param = parameters.FirstOrDefault(p => p.Name == name);
|
||||||
|
if (param == null || param.Data == null)
|
||||||
|
{
|
||||||
|
return Array.Empty<float>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param.Data is JsonElement element && element.ValueKind == JsonValueKind.Array)
|
||||||
|
{
|
||||||
|
var array = new List<float>();
|
||||||
|
foreach (var item in element.EnumerateArray())
|
||||||
|
{
|
||||||
|
if (item.ValueKind == JsonValueKind.Number)
|
||||||
|
{
|
||||||
|
array.Add(item.GetSingle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param.Data is System.Collections.IEnumerable enumerable && !(param.Data is string))
|
||||||
|
{
|
||||||
|
var array = new List<float>();
|
||||||
|
foreach (var item in enumerable)
|
||||||
|
{
|
||||||
|
array.Add(Convert.ToSingle(item));
|
||||||
|
}
|
||||||
|
return array.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.Empty<float>();
|
||||||
|
}
|
||||||
|
private double[] GetDoubleArrayParameter(List<FortranParameter> parameters, string name)
|
||||||
|
{
|
||||||
|
var param = parameters.FirstOrDefault(p => p.Name == name);
|
||||||
|
if (param == null || param.Data == null)
|
||||||
|
{
|
||||||
|
return Array.Empty<double>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param.Data is JsonElement element && element.ValueKind == JsonValueKind.Array)
|
||||||
|
{
|
||||||
|
var array = new List<double>();
|
||||||
|
foreach (var item in element.EnumerateArray())
|
||||||
|
{
|
||||||
|
if (item.ValueKind == JsonValueKind.Number)
|
||||||
|
{
|
||||||
|
array.Add(item.GetSingle());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return array.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (param.Data is System.Collections.IEnumerable enumerable && !(param.Data is string))
|
||||||
|
{
|
||||||
|
var array = new List<double>();
|
||||||
|
foreach (var item in enumerable)
|
||||||
|
{
|
||||||
|
array.Add(Convert.ToSingle(item));
|
||||||
|
}
|
||||||
|
return array.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.Empty<double>();
|
||||||
|
}
|
||||||
|
private void UpdateParameter(List<FortranParameter> parameters, string name, object value)
|
||||||
|
{
|
||||||
|
var param = parameters.FirstOrDefault(p => p.Name == name);
|
||||||
|
if (param != null)
|
||||||
|
{
|
||||||
|
param.Data = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateArrayParameter(List<FortranParameter> parameters, string name, float[] value)
|
||||||
|
{
|
||||||
|
var param = parameters.FirstOrDefault(p => p.Name == name);
|
||||||
|
if (param != null)
|
||||||
|
{
|
||||||
|
param.Data = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void UpdateDoubleArrayParameter(List<FortranParameter> parameters, string name, double[] value)
|
||||||
|
{
|
||||||
|
var param = parameters.FirstOrDefault(p => p.Name == name);
|
||||||
|
if (param != null)
|
||||||
|
{
|
||||||
|
param.Data = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private void UpdateIntArrayParameter(List<FortranParameter> parameters, string name, int[] value)
|
||||||
|
{
|
||||||
|
var param = parameters.FirstOrDefault(p => p.Name == name);
|
||||||
|
if (param != null)
|
||||||
|
{
|
||||||
|
param.Data = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 添加新的辅助方法来处理二维数组
|
||||||
|
private double[,] GetDouble2DArrayParameter(List<FortranParameter> parameters, string name, int rows, int cols)
|
||||||
|
{
|
||||||
|
var param = parameters.FirstOrDefault(p => p.Name == name);
|
||||||
|
if (param == null || param.Data == null)
|
||||||
|
{
|
||||||
|
return new double[rows, cols];
|
||||||
|
}
|
||||||
|
|
||||||
|
double[,] result = new double[rows, cols];
|
||||||
|
|
||||||
|
if (param.Data is JsonElement element && element.ValueKind == JsonValueKind.Array)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
foreach (var item in element.EnumerateArray())
|
||||||
|
{
|
||||||
|
if (item.ValueKind == JsonValueKind.Number)
|
||||||
|
{
|
||||||
|
int row = index / cols;
|
||||||
|
int col = index % cols;
|
||||||
|
if (row < rows && col < cols)
|
||||||
|
{
|
||||||
|
result[row, col] = item.GetDouble();
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (param.Data is System.Collections.IEnumerable enumerable && !(param.Data is string))
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
foreach (var item in enumerable)
|
||||||
|
{
|
||||||
|
int row = index / cols;
|
||||||
|
int col = index % cols;
|
||||||
|
if (row < rows && col < cols)
|
||||||
|
{
|
||||||
|
result[row, col] = Convert.ToDouble(item);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加更新二维数组参数的方法
|
||||||
|
private void UpdateDouble2DArrayParameter(List<FortranParameter> parameters, string name, double[,] value)
|
||||||
|
{
|
||||||
|
var param = parameters.FirstOrDefault(p => p.Name == name);
|
||||||
|
if (param != null)
|
||||||
|
{
|
||||||
|
// 将二维数组转换为一维数组以便于JSON序列化
|
||||||
|
int rows = value.GetLength(0);
|
||||||
|
int cols = value.GetLength(1);
|
||||||
|
double[] flatArray = new double[rows * cols];
|
||||||
|
for (int i = 0; i < rows; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < cols; j++)
|
||||||
|
{
|
||||||
|
flatArray[i * cols + j] = value[i, j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
param.Data = flatArray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// float版本
|
||||||
|
private float[,] GetFloat2DArrayParameter(List<FortranParameter> parameters, string name, int rows, int cols)
|
||||||
|
{
|
||||||
|
var param = parameters.FirstOrDefault(p => p.Name == name);
|
||||||
|
if (param == null || param.Data == null)
|
||||||
|
{
|
||||||
|
return new float[rows, cols];
|
||||||
|
}
|
||||||
|
|
||||||
|
float[,] result = new float[rows, cols];
|
||||||
|
|
||||||
|
if (param.Data is JsonElement element && element.ValueKind == JsonValueKind.Array)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
foreach (var item in element.EnumerateArray())
|
||||||
|
{
|
||||||
|
if (item.ValueKind == JsonValueKind.Number)
|
||||||
|
{
|
||||||
|
int row = index / cols;
|
||||||
|
int col = index % cols;
|
||||||
|
if (row < rows && col < cols)
|
||||||
|
{
|
||||||
|
result[row, col] = item.GetSingle();
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (param.Data is System.Collections.IEnumerable enumerable && !(param.Data is string))
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
foreach (var item in enumerable)
|
||||||
|
{
|
||||||
|
int row = index / cols;
|
||||||
|
int col = index % cols;
|
||||||
|
if (row < rows && col < cols)
|
||||||
|
{
|
||||||
|
result[row, col] = Convert.ToSingle(item);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateFloat2DArrayParameter(List<FortranParameter> parameters, string name, float[,] value)
|
||||||
|
{
|
||||||
|
var param = parameters.FirstOrDefault(p => p.Name == name);
|
||||||
|
if (param != null)
|
||||||
|
{
|
||||||
|
int rows = value.GetLength(0);
|
||||||
|
int cols = value.GetLength(1);
|
||||||
|
float[] flatArray = new float[rows * cols];
|
||||||
|
for (int i = 0; i < rows; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < cols; j++)
|
||||||
|
{
|
||||||
|
flatArray[i * cols + j] = value[i, j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
param.Data = flatArray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// int版本
|
||||||
|
private int[,] GetInt2DArrayParameter(List<FortranParameter> parameters, string name, int rows, int cols)
|
||||||
|
{
|
||||||
|
var param = parameters.FirstOrDefault(p => p.Name == name);
|
||||||
|
if (param == null || param.Data == null)
|
||||||
|
{
|
||||||
|
return new int[rows, cols];
|
||||||
|
}
|
||||||
|
|
||||||
|
int[,] result = new int[rows, cols];
|
||||||
|
|
||||||
|
if (param.Data is JsonElement element && element.ValueKind == JsonValueKind.Array)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
foreach (var item in element.EnumerateArray())
|
||||||
|
{
|
||||||
|
if (item.ValueKind == JsonValueKind.Number)
|
||||||
|
{
|
||||||
|
int row = index / cols;
|
||||||
|
int col = index % cols;
|
||||||
|
if (row < rows && col < cols)
|
||||||
|
{
|
||||||
|
result[row, col] = item.GetInt32();
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (param.Data is System.Collections.IEnumerable enumerable && !(param.Data is string))
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
foreach (var item in enumerable)
|
||||||
|
{
|
||||||
|
int row = index / cols;
|
||||||
|
int col = index % cols;
|
||||||
|
if (row < rows && col < cols)
|
||||||
|
{
|
||||||
|
result[row, col] = Convert.ToInt32(item);
|
||||||
|
}
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateInt2DArrayParameter(List<FortranParameter> parameters, string name, int[,] value)
|
||||||
|
{
|
||||||
|
var param = parameters.FirstOrDefault(p => p.Name == name);
|
||||||
|
if (param != null)
|
||||||
|
{
|
||||||
|
int rows = value.GetLength(0);
|
||||||
|
int cols = value.GetLength(1);
|
||||||
|
int[] flatArray = new int[rows * cols];
|
||||||
|
for (int i = 0; i < rows; i++)
|
||||||
|
{
|
||||||
|
for (int j = 0; j < cols; j++)
|
||||||
|
{
|
||||||
|
flatArray[i * cols + j] = value[i, j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
param.Data = flatArray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
16
appsettings.json
Normal file
16
appsettings.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"AllowedHosts": "*",
|
||||||
|
"Kestrel": {
|
||||||
|
"Endpoints": {
|
||||||
|
"Http": {
|
||||||
|
"Url": "http://0.0.0.0:5000"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user