| | |
| | | using ErrorAnalysis.Repository; |
| | | using ErrorAnalysis.Service; |
| | | using ErrorAnalysis.Service.Model; |
| | | using System; |
| | | using System.Collections.Generic; |
| | |
| | | { |
| | | 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 yieldCounting, double targetErrorRatio, out double testSpeed, int pass = 0, double nearCofe = 0.65, double farCofe = 0.35) |
| | | { |
| | | 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, yieldCounting, nearCofe, farCofe); |
| | | (cWOL, oWOL) = GetOilWaterLine(modelID); |
| | | 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; |
| | | (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); |
| | | |
| | | var firstErrorPass = new ErrorRatio { Pass = 1, ErrorRatioValue = firstTargetErrorRatio }; |
| | | |
| | | //var firstErrorPass = new ErrorRatio(); |
| | | //speed = 0.05; |
| | | //do |
| | | //{ |
| | | // firstErrorPass = GetFirstErrorRatio(modelID, porosity, sw, speed, depth, yieldCounting, nearCofe, farCofe); |
| | | // result.CWOL = cWOL; |
| | | // result.OWOL = oWOL; |
| | | // speed -= 0.0001; |
| | | //} 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, double yieldCounting, double nearCofe, double farCofe) |
| | | { |
| | | if (porosity > 40) |
| | | throw new InvalidDataException("Porosity value out of range!"); |
| | | |
| | | try |
| | | { |
| | | |
| | | var mergePDEV = PDEVCalcService.GetMergePDEV(modelID, porosity, sw, speed, depth, yieldCounting, nearCofe, farCofe); |
| | | |
| | | var errorRatio = mergePDEV / GetMDelta(modelID, porosity); |
| | | |
| | | return new ErrorRatio { Pass = 1, ErrorRatioValue = errorRatio }; |
| | | } |
| | | catch |
| | | { |
| | | return new ErrorRatio { Pass = 0, ErrorRatioValue = 0 }; |
| | | } |
| | | } |
| | | |
| | | private static double GetMDelta(string modelID, double porosity) |
| | | { |
| | | var cWolRes = RepositoryInstance.Instance.COWOLRepository?.GetWOL(modelID, 0); |
| | | var oWolRes = RepositoryInstance.Instance.COWOLRepository?.GetWOL(modelID, 100); |
| | | var wolResType = cWolRes?.GetType(); |
| | | |
| | | 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); |
| | | } |
| | | return cRes - oRes; |
| | | } |
| | | |
| | | private static (List<double[]>, List<double[]>) GetOilWaterLine(string modelID) |
| | | { |
| | | 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 wolResType = cWolRes?.GetType(); |
| | | |
| | | 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))]); |
| | | } |
| | | } |
| | | return (cWOL, oWOL); |
| | | } |
| | | } |
| | | } |
| | | } |