lx
2025-08-15 c97331d8eca8f9ef6a0c18ffce3518578b5638ff
ErrorAnalysis.Service/ErrorRatioCalc.cs
@@ -1,8 +1,10 @@
using 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,7 +56,7 @@
                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(160 / (0.0762 * depth * 36d * yieldCounting)) *
@@ -89,7 +95,7 @@
            try
            {
                var mDelta = GetMDelta(modelID, porosity);
                var mDelta = GetMDelta(porosity);
                //var mergePDEVOld = PDEVCalcService.GetMergePDEV(modelID, porosity, sw, speed, depth, yieldCounting, nearCofe, farCofe);
@@ -108,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)
@@ -149,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())
@@ -163,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);
        }
    }
}