lx
2025-08-04 e0279fe6db39d1071ef04ad0080b887cb6a0d335
ErrorAnalysis.Service/ErrorRatioCalc.cs
@@ -10,15 +10,149 @@
{
    public class ErrorRatioCalc
    {
        public static ErrorRatioResult GetErrorRatioResult() { return new ErrorRatioResult(); }
        private static ErrorRatio GetErrorRatio(string connectionString, string modelID, int porosity)
        public static ErrorRatioResult GetErrorRatioResult(string modelID, double porosity, double sw, double depth, bool lockSpeed, double speed, double targetErrorRatio, out double testSpeed, 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 firstErrorPassM = GetFirstErrorRatio(modelID, porosity, sw, speed, depth, out cWOL, out oWOL);
                result.CWOL = cWOL;
                result.OWOL = oWOL;
                result.ErrorRatios.Add(firstErrorPassM);
                if (firstErrorPassM.ErrorRatioValue > targetErrorRatio)
                {
                    var targetPass = Convert.ToInt32(Math.Ceiling(Math.Pow(firstErrorPassM.ErrorRatioValue / targetErrorRatio, 2)));
                    for (int i = 2; i <= targetPass; i++)
                    {
                        result.ErrorRatios.Add(new ErrorRatio { Pass = i, ErrorRatioValue = firstErrorPassM.ErrorRatioValue / Math.Sqrt(i) });
                    }
                }
            }
            else
            {
                var firstTargetErrorRatio = targetErrorRatio * Math.Sqrt(pass);
                List<double[]> cWOL;
                List<double[]> oWOL;
                var firstErrorPass = new ErrorRatio();
                speed = 2;
                do
                {
                    firstErrorPass = GetFirstErrorRatio(modelID, porosity, sw, speed, depth, out cWOL, out oWOL);
                    result.CWOL = cWOL;
                    result.OWOL = oWOL;
                    speed -= 0.01;
                } while (firstErrorPass.ErrorRatioValue != 0 && firstErrorPass.ErrorRatioValue > firstTargetErrorRatio);
                result.ErrorRatios.Clear();
                result.ErrorRatios.Add(firstErrorPass);
                for (int i = 2; i <= pass; i++)
                {
                    result.ErrorRatios.Add(new ErrorRatio { Pass = i, ErrorRatioValue = firstErrorPass.ErrorRatioValue / Math.Sqrt(i) });
                }
            }
            testSpeed = speed;
            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"))
                //        {
                //            //if (wolProperty.Name != "WLPu0")
                //            //{
                //            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);
                //            //}
                //            //else
                //            //{
                //            //    var interC = Utility.Interpolate(sw, 100, 0, 0, (double)wolProperty.GetValue(cWolRes));
                //            //    var interO = Utility.Interpolate(sw, 0, 0, 100, (double)wolProperty.GetValue(oWolRes));
                //            //    var interVal = Utility.Interpolate(sw, 0, interC, 100, interO);
                //            //    wolProperty.SetValue(cWolRes, interVal);
                //            //    wolProperty.SetValue(oWolRes, interVal);
                //            //}
                //        }
                //    }
                //}
                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 ? (cRes - oRes) : (oRes - cRes));
                return new ErrorRatio { Pass = 1, ErrorRatioValue = errorRatio };
            }
            catch
            {
                cWOL = null;
                oWOL = null;
                return new ErrorRatio { Pass = 0, ErrorRatioValue = 0 };
            }
        }
    }
}
}