超声波测液位的算法新增未成功
This commit is contained in:
parent
e82499f0c2
commit
2a6915b894
@ -86,8 +86,6 @@ public class GasController {
|
|||||||
return AjaxResult.success(gasProps);
|
return AjaxResult.success(gasProps);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public static void ngCalcVoid(FlowProps flowProps, GasProps gasProps) {
|
public static void ngCalcVoid(FlowProps flowProps, GasProps gasProps) {
|
||||||
thermService = new ThermService();
|
thermService = new ThermService();
|
||||||
detailService = new DetailService();
|
detailService = new DetailService();
|
||||||
@ -106,6 +104,11 @@ public class GasController {
|
|||||||
return GasConstants.MEMORY_ALLOCATION_ERROR;
|
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;
|
return GasConstants.NG_Cal_INITIALIZED;
|
||||||
|
|
||||||
}// NG_Cal_Init
|
}// NG_Cal_Init
|
||||||
@ -113,6 +116,7 @@ public class GasController {
|
|||||||
// delete the objects (if they exist)
|
// delete the objects (if they exist)
|
||||||
detailService = null;
|
detailService = null;
|
||||||
thermService = null;
|
thermService = null;
|
||||||
|
gbt11062Service=null;
|
||||||
return 0;
|
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