超声波测液位的算法新增未成功

This commit is contained in:
廖德云 2025-12-04 00:06:27 +08:00
parent e82499f0c2
commit 2a6915b894
4 changed files with 460 additions and 3 deletions

View File

@ -86,8 +86,6 @@ public class GasController {
return AjaxResult.success(gasProps);
}
public static void ngCalcVoid(FlowProps flowProps, GasProps gasProps) {
thermService = new ThermService();
detailService = new DetailService();
@ -106,6 +104,11 @@ public class GasController {
return GasConstants.MEMORY_ALLOCATION_ERROR;
}
//create object for calculating thermodynamic properties
if (null == (gbt11062Service=new GBT11062Service())) {
return GasConstants.MEMORY_ALLOCATION_ERROR;
}
return GasConstants.NG_Cal_INITIALIZED;
}// NG_Cal_Init
@ -113,6 +116,7 @@ public class GasController {
// delete the objects (if they exist)
detailService = null;
thermService = null;
gbt11062Service=null;
return 0;
}

View File

@ -0,0 +1,334 @@
package com.ruoyi.caltools.controller;
import com.ruoyi.caltools.model.FlowProps;
import com.ruoyi.caltools.model.GasProps;
import com.ruoyi.caltools.model.WaterDeepCalParams;
import com.ruoyi.caltools.model.WaterDeepCalResult;
import com.ruoyi.caltools.service.DetailService;
import com.ruoyi.caltools.service.GBT11062Service;
import com.ruoyi.caltools.service.ThermService;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.system.controller.UnitConvert;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
import static com.ruoyi.caltools.controller.GasController.Crit;
@RestController
@RequestMapping("/WaterDeepCalc")
public class WaterDeepCalController {
private static final Double G = 9.81; // 重力加速度
private static final Double R = 8.314; // 通用气体常数
@Autowired
private UnitConvert unitConvert=new UnitConvert();
@PostMapping("/calculatedepth")
public AjaxResult calculatedepth(@RequestBody FlowProps flowProps) {
GasProps gasProps = new GasProps();
//大气压力转换成Pa
double tempPatm = unitConvert.ConvertUniter("pressure", flowProps.getdPatm(), flowProps.getdPatmUnit(), 0);
//压力转换成Pa
double tempPf = unitConvert.ConvertUniter("pressure", flowProps.getdPf(), flowProps.getdPfUnit(), 0);
//压力转换成Pa
double tempDP = unitConvert.ConvertUniter("pressure", flowProps.getdDp(), flowProps.getdDpUnit(), 0);
//温度转换成K
double tempTf = unitConvert.ConvertUniter("temperature", flowProps.getdTf(), flowProps.getdTfUnit(), 2);
if (flowProps.getdPfType() == 0) //0是表压
{
gasProps.dPf = tempPatm + tempPf;
flowProps.setdPf(tempPatm + tempPf);
} else {
gasProps.dPf = tempPf;
flowProps.setdPf(tempPf);
}
gasProps.dTf = tempTf;
flowProps.setdDp(tempDP);
flowProps.setdTf(tempTf);
gasProps.dCbtj = flowProps.getdCbtj();
switch (gasProps.dCbtj)
{
case 2:
gasProps.setdPb(101325);
gasProps.setdTb( 273.15);
flowProps.setdPb_M(101325);
flowProps.setdTb_M(273.15);
break;
case 1:
gasProps.setdPb(101325);
gasProps.setdTb( 288.15);
flowProps.setdPb_M(101325);
flowProps.setdTb_M(288.15);
break;
case 0:
gasProps.setdPb(101325);
gasProps.setdTb( 293.15);
flowProps.setdPb_M(101325);
flowProps.setdTb_M(293.15);
break;
}
String[] stringArray = flowProps.getdngComponents().split("_");
double[] doubleArray = new double[stringArray.length]; // 遍历字符串数组将每个元素转换为 double 类型
for (int i = 0; i < stringArray.length; i++) {
try {
doubleArray[i] = Double.parseDouble(stringArray[i]) / 100;
} catch (NumberFormatException e) {
// 处理转换异常
System.err.println("无法将字符串 " + stringArray[i] + " 转换为 double 类型: " + e.getMessage());
}
}
gasProps.adMixture = doubleArray;
GasController.ngCalcVoid(flowProps, gasProps); //计算临界流函数所有参数都计算了
WaterDeepCalParams request=new WaterDeepCalParams();
request.setSurfacePressure(flowProps.getdPf());
request.setSurfaceTemperature(flowProps.getdTf());
request.setConstantLayerDepth(flowProps.getdVFlowMax());
request.setMeasuredTime(flowProps.getdVFlowMin());
request.setTemperatureGradient(flowProps.getdVFlowCon());
request.setGasProps(gasProps);
WaterDeepCalResult response = calculateCorrectedDepth(request);
return AjaxResult.success(response);
}
/**
* 计算深度处的温度
*/
private Double temperatureAtDepth(Double depth, Double surfaceTemp,
Double gradient, Double constantLayerDepth) {
if (depth <= constantLayerDepth) {
return surfaceTemp;
} else {
return surfaceTemp + gradient * (depth - constantLayerDepth);
}
}
/**
* 改进的压力计算使用密度积分
*/
private Double pressureAtDepth(Double depth, Double surfacePressure,
Double surfaceTemp, Double gradient,
Double constantLayerDepth, GasProps gasProps) {
if (depth <= 0) {
return surfacePressure;
}
int segments = 100; // 积分段数
Double dz = depth / segments;
Double currentPressure = surfacePressure;
// 克隆GasProps以避免修改原始对象
GasProps tempGasProps = cloneGasProps(gasProps);
for (int i = 0; i < segments; i++) {
Double currentDepth = i * dz + dz/2; // 使用中点
Double currentTemp = temperatureAtDepth(currentDepth, surfaceTemp,
gradient, constantLayerDepth);
// 设置当前温度和压力
tempGasProps.dTf = currentTemp;
tempGasProps.dPf = currentPressure;
// 更新气体参数
Crit(tempGasProps, 0);
// 使用实际密度计算压力增量
Double density = tempGasProps.getdRhof(); // 使用计算得到的密度
// 压力增量dP = ρ * g * dz
Double dP = density * G * dz;
currentPressure += dP;
// 防止压力异常
if (currentPressure <= 0) {
currentPressure = surfacePressure * 1.1; // 给一个安全值
}
}
return currentPressure;
}
/**
* 计算给定深度的理论传播时间
*/
private Double calculateTheoreticalTime(Double depth, WaterDeepCalParams request) {
if (depth <= 0) return 0.0;
int segments = Math.max(50, (int)(depth / 10)); // 根据深度调整分段数
segments = Math.min(segments, 200); // 不超过200段
Double dz = depth / segments;
Double totalTime = 0.0;
// 克隆GasProps以避免修改原始对象
GasProps tempGasProps = cloneGasProps(request.getGasProps());
for (int i = 0; i < segments; i++) {
Double currentDepth = i * dz + dz/2; // 中点
// 计算中点温度
Double temp = temperatureAtDepth(currentDepth, request.getSurfaceTemperature(),
request.getTemperatureGradient(), request.getConstantLayerDepth());
// 计算中点压力
Double pressure = pressureAtDepth(currentDepth, request.getSurfacePressure(),
request.getSurfaceTemperature(), request.getTemperatureGradient(),
request.getConstantLayerDepth(), tempGasProps);
// 设置气体参数
tempGasProps.dTf = temp;
tempGasProps.dPf = pressure;
// 计算声速
Crit(tempGasProps, 0);
Double soundVelocity = tempGasProps.dSOS;
// 检查声速有效性
if (soundVelocity <= 0 || Double.isNaN(soundVelocity)) {
soundVelocity = 300.0; // 默认声速
}
totalTime += dz / soundVelocity;
}
return 2 * totalTime; // 往返时间
}
/**
* 改进的迭代算法
*/
public WaterDeepCalResult calculateCorrectedDepth(WaterDeepCalParams request) {
WaterDeepCalResult response = new WaterDeepCalResult();
try {
// 验证输入参数
if (request.getMeasuredTime() <= 0) {
response.setStatus("ERROR: 测量时间必须大于0");
return response;
}
if (request.getSurfacePressure() <= 0) {
response.setStatus("ERROR: 表面压力必须大于0");
return response;
}
// 计算井口声速
Crit(request.getGasProps(), 0);
Double surfaceSoundVelocity = request.getGasProps().dSOS;
// 检查声速有效性
if (surfaceSoundVelocity <= 0 || Double.isNaN(surfaceSoundVelocity)) {
surfaceSoundVelocity = 300.0; // 默认值
}
// 初始估计深度
Double initialEstimate = surfaceSoundVelocity * request.getMeasuredTime() / 2;
// 迭代求解
Double lowerBound = initialEstimate * 0.5; // 下界初始估计的一半
Double upperBound = initialEstimate * 2.0; // 上界初始估计的两倍
// 如果初始估计不合理调整边界
if (initialEstimate < 0) {
lowerBound = 0.0;
upperBound = 10000.0; // 假设最大深度10000米
}
Double currentDepth = initialEstimate;
List<Double> iterationHistory = new ArrayList<>();
Integer iterations = 0;
// 二分法迭代
while (iterations < request.getMaxIterations()) {
iterationHistory.add(currentDepth);
// 计算理论时间
Double theoreticalTime = calculateTheoreticalTime(currentDepth, request);
Double error = theoreticalTime - request.getMeasuredTime();
// 检查收敛
if (Math.abs(error) < request.getTolerance()) {
break;
}
// 更新边界
if (error > 0) {
// 理论时间 > 测量时间说明深度估计过大
upperBound = currentDepth;
} else {
// 理论时间 < 测量时间说明深度估计过小
lowerBound = currentDepth;
}
// 计算新的深度估计
Double newDepth = (lowerBound + upperBound) / 2;
// 检查是否收敛或变化很小
if (Math.abs(newDepth - currentDepth) < request.getTolerance()) {
currentDepth = newDepth;
break;
}
currentDepth = newDepth;
iterations++;
// 安全检查
if (upperBound - lowerBound < 0.001) {
break;
}
}
// 计算修正因子
Double correctionFactor = currentDepth / initialEstimate;
// 设置响应
response.setCorrectedDepth(currentDepth);
response.setInitialEstimate(initialEstimate);
response.setCorrectionFactor(correctionFactor);
response.setIterations(iterations);
response.setIterationHistory(iterationHistory);
if (iterations < request.getMaxIterations()) {
response.setStatus("CONVERGED");
} else {
response.setStatus("MAX_ITERATIONS_REACHED");
}
} catch (Exception e) {
response.setStatus("ERROR: " + e.getMessage());
}
return response;
}
/**
* 克隆GasProps对象
*/
private GasProps cloneGasProps(GasProps original) {
GasProps cloned = new GasProps();
// 复制基本属性
cloned.dPf = original.dPf;
cloned.dTf = original.dTf;
cloned.dPb = original.dPb;
cloned.dTb = original.dTb;
cloned.dMrx = original.dMrx;
cloned.dCbtj = original.dCbtj;
// 复制数组
if (original.adMixture != null) {
cloned.adMixture = original.adMixture.clone();
}
return cloned;
}
}

View File

@ -0,0 +1,81 @@
package com.ruoyi.caltools.model;
public class WaterDeepCalParams {
public Double measuredTime; // 测量的往返时间(s)
public Double surfacePressure; // 井口压力(Pa)
public Double surfaceTemperature; // 地表温度(K)
public Double constantLayerDepth; // 恒温层深度(m)
public Double temperatureGradient; // 温度梯度(K/m)
public GasProps gasProps;
public Double getMeasuredTime() {
return measuredTime;
}
public void setMeasuredTime(Double measuredTime) {
this.measuredTime = measuredTime;
}
public Double getSurfacePressure() {
return surfacePressure;
}
public void setSurfacePressure(Double surfacePressure) {
this.surfacePressure = surfacePressure;
}
public Double getSurfaceTemperature() {
return surfaceTemperature;
}
public void setSurfaceTemperature(Double surfaceTemperature) {
this.surfaceTemperature = surfaceTemperature;
}
public Double getConstantLayerDepth() {
return constantLayerDepth;
}
public void setConstantLayerDepth(Double constantLayerDepth) {
this.constantLayerDepth = constantLayerDepth;
}
public Double getTemperatureGradient() {
return temperatureGradient;
}
public void setTemperatureGradient(Double temperatureGradient) {
this.temperatureGradient = temperatureGradient;
}
public GasProps getGasProps() {
return gasProps;
}
public void setGasProps(GasProps gasProps) {
this.gasProps = gasProps;
}
public Integer getMaxIterations() {
return maxIterations;
}
public void setMaxIterations(Integer maxIterations) {
this.maxIterations = maxIterations;
}
public Double getTolerance() {
return tolerance;
}
public void setTolerance(Double tolerance) {
this.tolerance = tolerance;
}
public Integer maxIterations = 100; // 最大迭代次数
public Double tolerance = 0.001; // 收敛容差(m)
}

View File

@ -0,0 +1,38 @@
package com.ruoyi.caltools.model;
import java.util.List;
public class WaterDeepCalResult {
public Double correctedDepth; // 修正后的深度(m)
public void setCorrectedDepth(Double correctedDepth) {
this.correctedDepth = correctedDepth;
}
public void setInitialEstimate(Double initialEstimate) {
this.initialEstimate = initialEstimate;
}
public void setCorrectionFactor(Double correctionFactor) {
this.correctionFactor = correctionFactor;
}
public void setIterations(Integer iterations) {
this.iterations = iterations;
}
public void setStatus(String status) {
this.status = status;
}
public void setIterationHistory(List<Double> iterationHistory) {
this.iterationHistory = iterationHistory;
}
public Double initialEstimate; // 初始估计深度(m)
public Double correctionFactor; // 修正因子
public Integer iterations; // 迭代次数
public String status; // 计算状态
public List<Double> iterationHistory; // 迭代历史
}