From 2a6915b894a47babacf77d69fa2f51691114eead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BB=96=E5=BE=B7=E4=BA=91?= Date: Thu, 4 Dec 2025 00:06:27 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B6=85=E5=A3=B0=E6=B3=A2=E6=B5=8B=E6=B6=B2?= =?UTF-8?q?=E4=BD=8D=E7=9A=84=E7=AE=97=E6=B3=95=E6=96=B0=E5=A2=9E=E6=9C=AA?= =?UTF-8?q?=E6=88=90=E5=8A=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../caltools/controller/GasController.java | 10 +- .../controller/WaterDeepCalController.java | 334 ++++++++++++++++++ .../caltools/model/WaterDeepCalParams.java | 81 +++++ .../caltools/model/WaterDeepCalResult.java | 38 ++ 4 files changed, 460 insertions(+), 3 deletions(-) create mode 100644 ruoyi-models/ruoyi-ngtools/src/main/java/com/ruoyi/caltools/controller/WaterDeepCalController.java create mode 100644 ruoyi-models/ruoyi-ngtools/src/main/java/com/ruoyi/caltools/model/WaterDeepCalParams.java create mode 100644 ruoyi-models/ruoyi-ngtools/src/main/java/com/ruoyi/caltools/model/WaterDeepCalResult.java diff --git a/ruoyi-models/ruoyi-ngtools/src/main/java/com/ruoyi/caltools/controller/GasController.java b/ruoyi-models/ruoyi-ngtools/src/main/java/com/ruoyi/caltools/controller/GasController.java index 82e8eeb..7719a43 100644 --- a/ruoyi-models/ruoyi-ngtools/src/main/java/com/ruoyi/caltools/controller/GasController.java +++ b/ruoyi-models/ruoyi-ngtools/src/main/java/com/ruoyi/caltools/controller/GasController.java @@ -83,11 +83,9 @@ public class GasController { } gasProps.adMixture = doubleArray; Crit(gasProps, 0); //计算临界流函数所有参数都计算了 - return AjaxResult.success(gasProps); + 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; } diff --git a/ruoyi-models/ruoyi-ngtools/src/main/java/com/ruoyi/caltools/controller/WaterDeepCalController.java b/ruoyi-models/ruoyi-ngtools/src/main/java/com/ruoyi/caltools/controller/WaterDeepCalController.java new file mode 100644 index 0000000..7562480 --- /dev/null +++ b/ruoyi-models/ruoyi-ngtools/src/main/java/com/ruoyi/caltools/controller/WaterDeepCalController.java @@ -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 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; + } + +} diff --git a/ruoyi-models/ruoyi-ngtools/src/main/java/com/ruoyi/caltools/model/WaterDeepCalParams.java b/ruoyi-models/ruoyi-ngtools/src/main/java/com/ruoyi/caltools/model/WaterDeepCalParams.java new file mode 100644 index 0000000..c28484a --- /dev/null +++ b/ruoyi-models/ruoyi-ngtools/src/main/java/com/ruoyi/caltools/model/WaterDeepCalParams.java @@ -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) + +} + diff --git a/ruoyi-models/ruoyi-ngtools/src/main/java/com/ruoyi/caltools/model/WaterDeepCalResult.java b/ruoyi-models/ruoyi-ngtools/src/main/java/com/ruoyi/caltools/model/WaterDeepCalResult.java new file mode 100644 index 0000000..e864e3e --- /dev/null +++ b/ruoyi-models/ruoyi-ngtools/src/main/java/com/ruoyi/caltools/model/WaterDeepCalResult.java @@ -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 iterationHistory) { + this.iterationHistory = iterationHistory; + } + + public Double initialEstimate; // 初始估计深度(m) + public Double correctionFactor; // 修正因子 + public Integer iterations; // 迭代次数 + public String status; // 计算状态 + public List iterationHistory; // 迭代历史 + +} \ No newline at end of file