From 05946b151e7010b2b1a851892152e6b5d34151b3 Mon Sep 17 00:00:00 2001
From: lx <ex_lixiang17@cosl.com.cn>
Date: 星期五, 11 七月 2025 17:30:52 +0800
Subject: [PATCH] update

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

diff --git a/ErrorAnalysis.Service/ErrorRatioCalc.cs b/ErrorAnalysis.Service/ErrorRatioCalc.cs
index bde1691..9f0c95b 100644
--- a/ErrorAnalysis.Service/ErrorRatioCalc.cs
+++ b/ErrorAnalysis.Service/ErrorRatioCalc.cs
@@ -10,15 +10,130 @@
 {
     public class ErrorRatioCalc
     {
-        public static ErrorRatioResult GetErrorRatioResult() { return new ErrorRatioResult(); }
-
-        private static ErrorRatio GetErrorRatio(string connectionString, string modelID, int porosity)
+        public static ErrorRatioResult GetErrorRatioResultLockSpeed(string modelID, double porosity, double sw, double depth, bool lockSpeed, double speed, double targetErrorRatio, int pass = 0)
         {
-            var coWOLRepository = new COWOLRepository(connectionString);
-            var cWolRes = coWOLRepository.GetWOL(modelID, 0);
-            var oWolRes = coWOLRepository.GetWOL(modelID, 100);
-            
-            return new ErrorRatio { };
+            var result = new ErrorRatioResult
+            {
+                CWOL = new List<double[]>(),
+                OWOL = new List<double[]>(),
+                ErrorRatios = new List<ErrorRatio>()
+            };
+
+            result.COModel = RepositoryInstance.Instance.COModelRepository?.GetCOModel(modelID);
+            if (lockSpeed)
+            {
+                List<double[]> cWOL;
+                List<double[]> oWOL;
+                var firsErrorPass = GetFirstErrorRatio(modelID, porosity, sw, speed, depth, out cWOL, out oWOL);
+                result.CWOL = cWOL;
+                result.OWOL = oWOL;
+                result.ErrorRatios.Add(firsErrorPass);
+                if (firsErrorPass.ErrorRatioValue > targetErrorRatio)
+                {
+                    var targetPass = Convert.ToInt32(Math.Ceiling(Math.Pow(firsErrorPass.ErrorRatioValue / targetErrorRatio, 2)));
+                    for (int i = 2; i <= targetPass; i++)
+                    {
+                        result.ErrorRatios.Add(new ErrorRatio { Pass = i, ErrorRatioValue = firsErrorPass.ErrorRatioValue / Math.Sqrt(i) });
+                    }
+                }
+            }
+            else
+            {
+                var firstTargetErrorRatio = targetErrorRatio * Math.Sqrt(pass);
+                List<double[]> cWOL;
+                List<double[]> oWOL;
+                var firstErrorPass = new ErrorRatio();
+                speed = 0.6;
+                while (firstErrorPass.ErrorRatioValue != 0 && firstErrorPass.ErrorRatioValue > firstTargetErrorRatio)
+                {
+                    firstErrorPass = GetFirstErrorRatio(modelID, porosity, sw, speed, depth, out cWOL, out oWOL);
+                    result.CWOL = cWOL;
+                    result.OWOL = oWOL;
+                    speed -= 0.01;
+                }
+            }
+
+            return result;
+
+        }
+
+        private static ErrorRatio GetFirstErrorRatio(string modelID, double porosity, double sw, double speed, double depth, out List<double[]> cWOL, out List<double[]> oWOL)
+        {
+            if (porosity > 40)
+                throw new InvalidDataException("Porosity value out of range!");
+
+            cWOL = new List<double[]>();
+            oWOL = new List<double[]>();
+
+            var cWolRes = RepositoryInstance.Instance.COWOLRepository?.GetWOL(modelID, 0);
+            var oWolRes = RepositoryInstance.Instance.COWOLRepository?.GetWOL(modelID, 100);
+
+            var mergePDEV = PDEVCalcService.GetMergePDEV(modelID, porosity, sw, speed, depth);
+
+            var wolResType = cWolRes?.GetType();
+            try
+            {
+                if (sw > 0 && sw < 100)
+                {
+                    foreach (var wolProperty in wolResType.GetProperties())
+                    {
+                        if (wolProperty.Name.Contains("WLPu"))
+                        {
+                            var interC = Utility.Interpolate(sw, 100, 0, 0, (double)wolProperty.GetValue(cWolRes));
+                            var interO = Utility.Interpolate(sw, 0, 0, 100, (double)wolProperty.GetValue(oWolRes));
+                            wolProperty.SetValue(cWolRes, interC);
+                            wolProperty.SetValue(oWolRes, interO);
+                        }
+                    }
+                }
+
+                foreach (var wolProperty in wolResType.GetProperties())
+                {
+                    if (wolProperty.Name.Contains("WLPu"))
+                    {
+                        cWOL.Add([Convert.ToDouble(wolProperty.Name.Replace("WLPu", "")), Convert.ToDouble(wolProperty.GetValue(cWolRes))]);
+                        oWOL.Add([Convert.ToDouble(wolProperty.Name.Replace("WLPu", "")), Convert.ToDouble(wolProperty.GetValue(oWolRes))]);
+                    }
+                }
+
+                double cRes = 0;
+                double oRes = 0;
+
+                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));
+
+                    cRes = Utility.Interpolate(porosity, floorPorosity, floorC, ceilingPorosity, ceilingC);
+                    oRes = Utility.Interpolate(porosity, floorPorosity, floorO, ceilingPorosity, ceilingO);
+                }
+
+                var errorRatio = mergePDEV / (cRes - oRes);
+
+                return new ErrorRatio { Pass = 1, ErrorRatioValue = errorRatio };
+            }
+            catch
+            {
+                cWOL = null;
+                oWOL = null;
+                return new ErrorRatio { Pass = 0, ErrorRatioValue = 0 };
+            }
         }
     }
-}
+}
\ No newline at end of file

--
Gitblit v1.9.3