超声波测液位的算法新增未成功
This commit is contained in:
parent
e82499f0c2
commit
2a6915b894
@ -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;
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
@ -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)
|
||||
|
||||
}
|
||||
|
||||
@ -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; // 迭代历史
|
||||
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user