From e5a570db2036a6b155c2ddc289b42bd050b9ad3c Mon Sep 17 00:00:00 2001
From: lx <ex_lixiang17@cosl.com.cn>
Date: 星期一, 24 十一月 2025 13:49:16 +0800
Subject: [PATCH] update 1.4
---
ErrorAnalysis.Service/ErrorRatioCalc.cs | 196 +++++++++++++++++++++++++++++++++++-------------
1 files changed, 141 insertions(+), 55 deletions(-)
diff --git a/ErrorAnalysis.Service/ErrorRatioCalc.cs b/ErrorAnalysis.Service/ErrorRatioCalc.cs
index 045af5c..0bb30b8 100644
--- a/ErrorAnalysis.Service/ErrorRatioCalc.cs
+++ b/ErrorAnalysis.Service/ErrorRatioCalc.cs
@@ -1,8 +1,10 @@
锘縰sing ErrorAnalysis.Repository;
+using ErrorAnalysis.Repository.Entity;
using ErrorAnalysis.Service;
using ErrorAnalysis.Service.Model;
using System;
using System.Collections.Generic;
+using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -11,25 +13,50 @@
{
public class ErrorRatioCalc
{
- public static ErrorRatioResult GetErrorRatioResult(string modelID, double porosity, double sw, double depth, bool lockSpeed, double speed, double yieldCounting, double targetErrorRatio, out double testSpeed, int pass = 0, double nearCofe = 0.65, double farCofe = 0.35)
+ private static (double slope, double intercept) _lineCoef;
+ private static (double a, double b, double c) _parabolaCoef;
+
+ public static ErrorRatioResult GetErrorRatioResult(string modelID, double porosity, double sw, double depth, bool lockSpeed, double speed, double yieldCounting, double targetErrorRatio, string type, out double testSpeed, out ProcessingDataModel processingData, int pass = 0, double nearCofe = 0.65, double farCofe = 0.35)
{
+ int countStart = 9;
+ int countEnd = 179;
+ if (type == "SMRT")
+ {
+ countStart = 24;
+ }
+ processingData = new ProcessingDataModel { Depth = depth, NearPDEVCoef = nearCofe, FarPDEVCoef = farCofe, NearTO = yieldCounting };
var result = new ErrorRatioResult
{
CWOL = new List<double[]>(),
OWOL = new List<double[]>(),
ErrorRatios = new List<ErrorRatio>()
};
-
result.COModel = RepositoryInstance.Instance.COModelRepository?.GetCOModel(modelID);
+ (result.CWOL, result.OWOL) = GetOilWaterLine(modelID);
+ processingData.OilLine = result.CWOL;
+ processingData.WaterLine = result.OWOL;
+ (processingData.OilLineOrigin, processingData.WaterLineOrgin) = GetOilWaterLine(modelID, true);
+ processingData.FarSpecData = COMergeCalcService.GetFarSpectrum(modelID, porosity, sw);
+ processingData.NearSpecData = COMergeCalcService.GetNearSpectrum(modelID, porosity, sw);
+
+ var nearCROR = COMergeCalcService.GetNearCOORResult(modelID, porosity, sw, countStart, countEnd);
+ var farCROR = COMergeCalcService.GetFarCOORResult(modelID, porosity, sw, countStart, countEnd);
+ processingData.NearCR = nearCROR.Item1;
+ processingData.NearOR = nearCROR.Item2;
+ processingData.FarCR = farCROR.Item1;
+ processingData.FarOR = farCROR.Item2;
+
+ var mDelta = GetMDelta(porosity, out double oilPoint, out double waterPoint);
+ processingData.OilPoint = oilPoint;
+ processingData.WaterPoint = waterPoint;
+
if (lockSpeed)
{
- List<double[]> cWOL;
- List<double[]> oWOL;
- var firstErrorPassM = GetFirstErrorRatio(modelID, porosity, sw, speed, depth, yieldCounting, nearCofe, farCofe);
- (cWOL, oWOL) = GetOilWaterLine(modelID);
- result.CWOL = cWOL;
- result.OWOL = oWOL;
+ var mergePDEV = Math.Sqrt(160 * speed / (0.0762 * 36 * depth)) * Math.Sqrt((Math.Pow(nearCofe, 2) / yieldCounting * (Math.Pow(nearCROR.Item1 / nearCROR.Item2, 2)) * (1 / nearCROR.Item1 + 1 / nearCROR.Item2)) + (Math.Pow(farCofe, 2) / yieldCounting / 2.2 * (Math.Pow(farCROR.Item1 / farCROR.Item2, 2)) * (1 / farCROR.Item1 + 1 / farCROR.Item2)));
+ var firstErrorPassM = new ErrorRatio { Pass = 1, ErrorRatioValue = mergePDEV / mDelta };
+ result.ErrorRatios.Clear();
result.ErrorRatios.Add(firstErrorPassM);
+
if (firstErrorPassM.ErrorRatioValue > targetErrorRatio)
{
var targetPass = Convert.ToInt32(Math.Ceiling(Math.Pow(firstErrorPassM.ErrorRatioValue / targetErrorRatio, 2)));
@@ -38,25 +65,17 @@
result.ErrorRatios.Add(new ErrorRatio { Pass = i, ErrorRatioValue = firstErrorPassM.ErrorRatioValue / Math.Sqrt(i) });
}
}
+ processingData.Speed = speed;
}
else
{
var firstTargetErrorRatio = targetErrorRatio * Math.Sqrt(pass);
- List<double[]> cWOL;
- List<double[]> oWOL;
- (cWOL, oWOL) = GetOilWaterLine(modelID);
- result.CWOL = cWOL;
- result.OWOL = oWOL;
- var nearCROR = COMergeCalcService.GetNearCOORResult(modelID, porosity, sw);
- var farCROR = COMergeCalcService.GetFarCOORResult(modelID, porosity, sw);
- var mDelta = GetMDelta(modelID, porosity);
-
- speed = Math.Pow(firstTargetErrorRatio /
- Math.Sqrt(1 / (0.0762 * depth * (36d / 160))) *
- mDelta /
- Math.Sqrt(((Math.Pow(nearCofe, 2) / yieldCounting) * (Math.Pow(nearCROR.Item1 / nearCROR.Item2, 2)) * (1 / nearCROR.Item1 + 1 / nearCROR.Item2)) + (Math.Pow(farCofe, 2) / yieldCounting) * (Math.Pow(farCROR.Item1 / farCROR.Item2, 2)) * (1 / farCROR.Item1 + 1 / farCROR.Item2))
- , 2);
+ processingData.Speed = speed = Math.Pow(firstTargetErrorRatio /
+ (Math.Sqrt(160 / (0.0762 * depth * 36d)) *
+ 1d / mDelta) /
+ Math.Sqrt((Math.Pow(nearCofe, 2) / yieldCounting * (Math.Pow(nearCROR.Item1 / nearCROR.Item2, 2)) * (1 / nearCROR.Item1 + 1 / nearCROR.Item2)) + (Math.Pow(farCofe, 2) / yieldCounting / 2.2 * (Math.Pow(farCROR.Item1 / farCROR.Item2, 2)) * (1 / farCROR.Item1 + 1 / farCROR.Item2)))
+ , 2);
var firstErrorPass = new ErrorRatio { Pass = 1, ErrorRatioValue = firstTargetErrorRatio };
@@ -82,69 +101,83 @@
}
- private static ErrorRatio GetFirstErrorRatio(string modelID, double porosity, double sw, double speed, double depth, double yieldCounting, double nearCofe, double farCofe)
+ //搴熷純
+ private static ErrorRatio GetFirstErrorRatio(string modelID, double porosity, double sw, double speed, double depth, double yieldCounting, double nearCofe, double farCofe,int countStart,int countEnd, out double oilPoint, out double waterPoint)
{
if (porosity > 40)
throw new InvalidDataException("Porosity value out of range!");
try
{
+ var mDelta = GetMDelta(porosity, out oilPoint, out waterPoint);
- var mergePDEV = PDEVCalcService.GetMergePDEV(modelID, porosity, sw, speed, depth, yieldCounting, nearCofe, farCofe);
+ var mergePDEVOld = PDEVCalcService.GetMergePDEV(modelID, porosity, sw, speed, depth, yieldCounting, nearCofe, farCofe,countStart,countEnd);
- var errorRatio = mergePDEV / GetMDelta(modelID, porosity);
+ //var nearCROR = COMergeCalcService.GetNearCOORResult(modelID, porosity, sw);
+ //var farCROR = COMergeCalcService.GetFarCOORResult(modelID, porosity, sw);
+
+ //var mergePDEV = Math.Sqrt(160 * speed / (0.0762 * 36 * depth)) * Math.Sqrt((Math.Pow(nearCofe, 2) / yieldCounting * (Math.Pow(nearCROR.Item1 / nearCROR.Item2, 2)) * (1 / nearCROR.Item1 + 1 / nearCROR.Item2)) + (Math.Pow(farCofe, 2) / yieldCounting / 2.2 * (Math.Pow(farCROR.Item1 / farCROR.Item2, 2)) * (1 / farCROR.Item1 + 1 / farCROR.Item2)));
+
+ var errorRatio = mergePDEVOld / mDelta;
return new ErrorRatio { Pass = 1, ErrorRatioValue = errorRatio };
}
catch
{
+ oilPoint = 0;
+ waterPoint = 0;
return new ErrorRatio { Pass = 0, ErrorRatioValue = 0 };
}
}
- private static double GetMDelta(string modelID, double porosity)
+ private static double GetMDelta(double porosity, out double oilPoint, out double waterPoint)
{
- var cWolRes = RepositoryInstance.Instance.COWOLRepository?.GetWOL(modelID, 0);
- var oWolRes = RepositoryInstance.Instance.COWOLRepository?.GetWOL(modelID, 100);
- var wolResType = cWolRes?.GetType();
+ oilPoint = Utility.GetParabolaValue(porosity, _parabolaCoef.a, _parabolaCoef.b, _parabolaCoef.c);
+ waterPoint = Utility.GetLineValue(porosity, _lineCoef.slope, _lineCoef.intercept);
- double cRes = 0;
- double oRes = 0;
+ //var cWolRes = RepositoryInstance.Instance.COWOLRepository?.GetWOL(modelID, 0);
+ //var oWolRes = RepositoryInstance.Instance.COWOLRepository?.GetWOL(modelID, 100);
+ //var wolResType = cWolRes?.GetType();
- if (porosity % 5 == 0)
- {
- var poroFiledName = $"WLPu" + porosity;
- var property = wolResType.GetProperty(poroFiledName);
+ //double cRes = 0;
+ //double oRes = 0;
- cRes = Convert.ToDouble(property.GetValue(cWolRes));
- oRes = Convert.ToDouble(property.GetValue(oWolRes));
- }
- else
- {
- var ceilingPorosity = Math.Ceiling(porosity / 5) * 5;
- var ceilingProperty = wolResType.GetProperty($"WLPu" + ceilingPorosity);
- var ceilingC = Convert.ToDouble(ceilingProperty.GetValue(cWolRes));
- var ceilingO = Convert.ToDouble(ceilingProperty.GetValue(oWolRes));
+ //if (porosity % 5 == 0)
+ //{
+ // var poroFiledName = $"WLPu" + porosity;
+ // var property = wolResType.GetProperty(poroFiledName);
+
+ // cRes = Convert.ToDouble(property.GetValue(cWolRes));
+ // oRes = Convert.ToDouble(property.GetValue(oWolRes));
+ //}
+ //else
+ //{
+ // var ceilingPorosity = Math.Ceiling(porosity / 5) * 5;
+ // var ceilingProperty = wolResType.GetProperty($"WLPu" + ceilingPorosity);
+ // var ceilingC = Convert.ToDouble(ceilingProperty.GetValue(cWolRes));
+ // var ceilingO = Convert.ToDouble(ceilingProperty.GetValue(oWolRes));
- var floorPorosity = Math.Floor(porosity / 5) * 5;
- var floorProperty = wolResType.GetProperty($"WLPu" + floorPorosity);
- var floorC = Convert.ToDouble(floorProperty.GetValue(cWolRes));
- var floorO = Convert.ToDouble(floorProperty.GetValue(oWolRes));
+ // var floorPorosity = Math.Floor(porosity / 5) * 5;
+ // var floorProperty = wolResType.GetProperty($"WLPu" + floorPorosity);
+ // var floorC = Convert.ToDouble(floorProperty.GetValue(cWolRes));
+ // var floorO = Convert.ToDouble(floorProperty.GetValue(oWolRes));
- cRes = Utility.Interpolate(porosity, floorPorosity, floorC, ceilingPorosity, ceilingC);
- oRes = Utility.Interpolate(porosity, floorPorosity, floorO, ceilingPorosity, ceilingO);
- }
- return cRes - oRes;
+ // cRes = Utility.Interpolate(porosity, floorPorosity, floorC, ceilingPorosity, ceilingC);
+ // oRes = Utility.Interpolate(porosity, floorPorosity, floorO, ceilingPorosity, ceilingO);
+ //}
+ return oilPoint - waterPoint;
}
- private static (List<double[]>, List<double[]>) GetOilWaterLine(string modelID)
+ private static (List<double[]>, List<double[]>) GetOilWaterLine(string modelID, bool original = false)
{
var cWOL = new List<double[]>();
var oWOL = new List<double[]>();
- var cWolRes = RepositoryInstance.Instance.COWOLRepository?.GetWOL(modelID, 0);
- var oWolRes = RepositoryInstance.Instance.COWOLRepository?.GetWOL(modelID, 100);
+ var fitModel = original ? GetModel(modelID) : GetFitModel(modelID);
+
+ var cWolRes = fitModel.Item1;
+ var oWolRes = fitModel.Item2;
var wolResType = cWolRes?.GetType();
foreach (var wolProperty in wolResType.GetProperties())
@@ -157,5 +190,58 @@
}
return (cWOL, oWOL);
}
+
+ private static (COWOLTable, COWOLTable) GetModel(string modelID)
+ {
+ var oilWol = RepositoryInstance.Instance.COWOLRepository?.GetWOL(modelID, 0);
+ var waterWol = RepositoryInstance.Instance.COWOLRepository?.GetWOL(modelID, 100);
+ return (oilWol, waterWol);
+ }
+
+ private static (COWOLTable, COWOLTable) GetFitModel(string modelID)
+ {
+ var oilWol = RepositoryInstance.Instance.COWOLRepository?.GetWOL(modelID, 0);
+ var waterWol = RepositoryInstance.Instance.COWOLRepository?.GetWOL(modelID, 100);
+ var wolResType = oilWol?.GetType();
+ List<PointF> oilPoints = [];
+ List<PointF> waterPoints = [];
+
+ foreach (var wolProperty in wolResType.GetProperties())
+ {
+ if (wolProperty.Name.Contains("WLPu"))
+ {
+ var porosity = float.Parse(wolProperty.Name.Replace("WLPu", ""));
+ var oilVal = (double)wolProperty.GetValue(oilWol);
+ var waterVal = (double)wolProperty.GetValue(waterWol);
+
+ oilPoints.Add(new PointF(porosity, (float)oilVal));
+ waterPoints.Add(new PointF(porosity, (float)waterVal));
+ }
+ }
+
+ _lineCoef = Utility.FitLine(waterPoints.ToArray());
+ _parabolaCoef = Utility.FitParabola(oilPoints.ToArray());
+ //var texCoef = Utility.quadraticLine(oilPoints.Select(o => Convert.ToDouble(o.X)).ToArray(), oilPoints.Select(o => Convert.ToDouble(o.Y)).ToArray());
+
+ double initDiff = 0;
+
+ foreach (var wolProperty in wolResType.GetProperties())
+ {
+ if (wolProperty.Name.Contains("WLPu"))
+ {
+ var porosity = double.Parse(wolProperty.Name.Replace("WLPu", ""));
+ var waterVal = Utility.GetLineValue(porosity, _lineCoef.slope, _lineCoef.intercept);
+ var oilVal = Utility.GetParabolaValue(porosity, _parabolaCoef.a, _parabolaCoef.b, _parabolaCoef.c);
+ //var testoilVal = Utility.GetParabolaValue(porosity, texCoef.a, texCoef.b, texCoef.c);
+ if (porosity == 0)
+ {
+ initDiff = oilVal - waterVal;
+ }
+ wolProperty.SetValue(waterWol, waterVal + initDiff);
+ wolProperty.SetValue(oilWol, oilVal);
+ }
+ }
+ return (oilWol, waterWol);
+ }
}
}
\ No newline at end of file
--
Gitblit v1.9.3