From c97331d8eca8f9ef6a0c18ffce3518578b5638ff Mon Sep 17 00:00:00 2001
From: lx <ex_lixiang17@cosl.com.cn>
Date: 星期五, 15 八月 2025 10:21:11 +0800
Subject: [PATCH] update cr/or fit line

---
 ErrorAnalysis.Service/ErrorRatioCalc.cs |  133 ++++++++++++++++++++++++++++++++------------
 1 files changed, 97 insertions(+), 36 deletions(-)

diff --git a/ErrorAnalysis.Service/ErrorRatioCalc.cs b/ErrorAnalysis.Service/ErrorRatioCalc.cs
index 045af5c..d308843 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,6 +13,9 @@
 {
     public class ErrorRatioCalc
     {
+        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, out double testSpeed, int pass = 0, double nearCofe = 0.65, double farCofe = 0.35)
         {
             var result = new ErrorRatioResult
@@ -25,10 +30,11 @@
             {
                 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 firstErrorPassM = GetFirstErrorRatio(modelID, porosity, sw, speed, depth, yieldCounting, nearCofe, farCofe);
+
                 result.ErrorRatios.Add(firstErrorPassM);
                 if (firstErrorPassM.ErrorRatioValue > targetErrorRatio)
                 {
@@ -50,12 +56,12 @@
 
                 var nearCROR = COMergeCalcService.GetNearCOORResult(modelID, porosity, sw);
                 var farCROR = COMergeCalcService.GetFarCOORResult(modelID, porosity, sw);
-                var mDelta = GetMDelta(modelID, porosity);
+                var mDelta = GetMDelta(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))
+                    (Math.Sqrt(160 / (0.0762 * depth * 36d * yieldCounting)) *
+                    1d / mDelta) /
+                    Math.Sqrt((Math.Pow(nearCofe, 2) * (Math.Pow(nearCROR.Item1 / nearCROR.Item2, 2)) * (1 / nearCROR.Item1 + 1 / nearCROR.Item2)) + (Math.Pow(farCofe, 2) * (Math.Pow(farCROR.Item1 / farCROR.Item2, 2)) * (1 / farCROR.Item1 + 1 / farCROR.Item2)))
                     , 2);
 
                 var firstErrorPass = new ErrorRatio { Pass = 1, ErrorRatioValue = firstTargetErrorRatio };
@@ -89,10 +95,16 @@
 
             try
             {
+                var mDelta = GetMDelta(porosity);
 
-                var mergePDEV = PDEVCalcService.GetMergePDEV(modelID, porosity, sw, speed, depth, yieldCounting, nearCofe, farCofe);
+                //var mergePDEVOld = PDEVCalcService.GetMergePDEV(modelID, porosity, sw, speed, depth, yieldCounting, nearCofe, farCofe);
 
-                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 * yieldCounting)) * Math.Sqrt((Math.Pow(nearCofe, 2) * (Math.Pow(nearCROR.Item1 / nearCROR.Item2, 2)) * (1 / nearCROR.Item1 + 1 / nearCROR.Item2)) + (Math.Pow(farCofe, 2) * (Math.Pow(farCROR.Item1 / farCROR.Item2, 2)) * (1 / farCROR.Item1 + 1 / farCROR.Item2)));
+
+                var errorRatio = mergePDEV / mDelta;
 
                 return new ErrorRatio { Pass = 1, ErrorRatioValue = errorRatio };
             }
@@ -102,40 +114,43 @@
             }
         }
 
-        private static double GetMDelta(string modelID, double porosity)
+        private static double GetMDelta(double porosity)
         {
-            var cWolRes = RepositoryInstance.Instance.COWOLRepository?.GetWOL(modelID, 0);
-            var oWolRes = RepositoryInstance.Instance.COWOLRepository?.GetWOL(modelID, 100);
-            var wolResType = cWolRes?.GetType();
+            var oilRes = Utility.GetParabolaValue(porosity, _parabolaCoef.a, _parabolaCoef.b, _parabolaCoef.c);
+            var waterRes = 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 oilRes - waterRes;
         }
 
         private static (List<double[]>, List<double[]>) GetOilWaterLine(string modelID)
@@ -143,8 +158,10 @@
             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 = GetFitModel(modelID);
+
+            var cWolRes = fitModel.Item1;
+            var oWolRes = fitModel.Item2;
             var wolResType = cWolRes?.GetType();
 
             foreach (var wolProperty in wolResType.GetProperties())
@@ -157,5 +174,49 @@
             }
             return (cWOL, oWOL);
         }
+
+        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());
+
+            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);
+                    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