| | |
| | | using ErrorAnalysis.Repository; |
| | | using Microsoft.VisualBasic; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Linq; |
| | |
| | | const int _oWinStartIndex = (int)(4.88 / _gg + _offset); // org |
| | | const int _oWinEndIndex = (int)(6.36 / _gg + _offset); // width = 6.36-4.88=1.48 |
| | | |
| | | const double _coef = 1e8 * 2.54 * 2.54 * 4 * 6 * 2 * 11 * 77 * 0.2 / 0.6; |
| | | //const double _coef = 1e8 * 2.54 * 2.54 * 4 * 6 * 2 * 11 * 77 * 0.2 / 0.6; |
| | | |
| | | private static (double, double) GetFarInterplolateResult(string modelId, double porosity, double sw, double speed, double depth) |
| | | private static (double, double) GetFarInterplolateResult(string modelId, double porosity, double sw, double speed, double depth, double yieldCounting) |
| | | { |
| | | var cWinLength = _cWinEndIndex - _cWinStartIndex + 1; |
| | | var oWinLength = _oWinEndIndex - _oWinStartIndex + 1; |
| | |
| | | var waterLine = RepositoryInstance.Instance.COFarResultRepository?.GetCOFarResult(modelId, (int)porosity, 100); |
| | | if (oilLine == null || waterLine == null) |
| | | throw new InvalidDataException("COFarResult Line is null"); |
| | | var oilLineValArr = oilLine.InelasticSpec.Split(',').Select(v => Convert.ToDouble(v)).ToArray(); |
| | | var waterLineValArr = waterLine.InelasticSpec.Split(',').Select(v => Convert.ToDouble(v)).ToArray(); |
| | | var oilLineValArr = oilLine.CInelasticSpec.Split(',').Select(v => Convert.ToDouble(v)).ToArray(); |
| | | var waterLineValArr = waterLine.CInelasticSpec.Split(',').Select(v => Convert.ToDouble(v)).ToArray(); |
| | | |
| | | var oilLineC = oilLineValArr.Skip(_cWinStartIndex).Take(cWinLength).Sum() * _coef / speed * depth * 0.07; |
| | | var oilLineO = oilLineValArr.Skip(_oWinStartIndex).Take(oWinLength).Sum() * _coef / speed * depth * 0.07; |
| | | var oilLineCR = oilLineValArr.Skip(_cWinStartIndex).Take(cWinLength).Sum() / oilLineValArr.Sum(); |
| | | var oilLineOR = oilLineValArr.Skip(_oWinStartIndex).Take(oWinLength).Sum() / oilLineValArr.Sum(); |
| | | |
| | | var waterLineC = waterLineValArr.Skip(_cWinStartIndex).Take(cWinLength).Sum() * _coef / speed * depth * 0.07; |
| | | var waterLineO = waterLineValArr.Skip(_oWinStartIndex).Take(oWinLength).Sum() * _coef / speed * depth * 0.07; |
| | | var oilLineC = 36d / 160 * oilLineCR * yieldCounting / speed * depth * 0.0762; |
| | | var oilLineO = 36d / 160 * oilLineOR * yieldCounting / speed * depth * 0.0762; |
| | | |
| | | var waterLineCR = waterLineValArr.Skip(_cWinStartIndex).Take(cWinLength).Sum() / waterLineValArr.Sum(); |
| | | var waterLineOR = waterLineValArr.Skip(_oWinStartIndex).Take(oWinLength).Sum() / waterLineValArr.Sum(); |
| | | var waterLineC = 36d / 160 * waterLineCR * yieldCounting / speed * depth * 0.0762; |
| | | var waterLineO = 36d / 160 * waterLineOR * yieldCounting / speed * depth * 0.0762; |
| | | |
| | | double cRes = 0, oRes = 0; |
| | | if (sw == 0) |
| | | { |
| | | cRes = waterLineC; |
| | | oRes = waterLineO; |
| | | cRes = oilLineC; |
| | | oRes = oilLineO; |
| | | } |
| | | else if (sw == 100) |
| | | { |
| | |
| | | return (cRes, oRes); |
| | | } |
| | | |
| | | private static (double, double) GetNearInterplolateResult(string modelId, double porosity, double sw, double speed, double depth) |
| | | private static (double, double) GetNearInterplolateResult(string modelId, double porosity, double sw, double speed, double depth, double yieldCounting) |
| | | { |
| | | var cWinLength = _cWinEndIndex - _cWinStartIndex + 1; |
| | | var oWinLength = _oWinEndIndex - _oWinStartIndex + 1; |
| | |
| | | var waterLine = RepositoryInstance.Instance.CONearResultRepository?.GetCONearResult(modelId, (int)porosity, 100); |
| | | if (oilLine == null || waterLine == null) |
| | | throw new InvalidDataException("COFarResult Line is null"); |
| | | var oilLineValArr = oilLine.InelasticSpec.Split(',').Select(v => Convert.ToDouble(v)).ToArray(); |
| | | var waterLineValArr = waterLine.InelasticSpec.Split(',').Select(v => Convert.ToDouble(v)).ToArray(); |
| | | var oilLineValArr = oilLine.CInelasticSpec.Split(',').Select(v => Convert.ToDouble(v)).ToArray(); |
| | | var waterLineValArr = waterLine.CInelasticSpec.Split(',').Select(v => Convert.ToDouble(v)).ToArray(); |
| | | |
| | | var oilLineC = oilLineValArr.Skip(_cWinStartIndex).Take(cWinLength).Sum() * _coef / speed * depth * 0.07; |
| | | var oilLineO = oilLineValArr.Skip(_oWinStartIndex).Take(oWinLength).Sum() * _coef / speed * depth * 0.07; |
| | | var oilLineCR = oilLineValArr.Skip(_cWinStartIndex).Take(cWinLength).Sum() / oilLineValArr.Sum(); |
| | | var oilLineOR = oilLineValArr.Skip(_oWinStartIndex).Take(oWinLength).Sum() / oilLineValArr.Sum(); |
| | | var oilLineC = (36d / 160) * oilLineCR * yieldCounting / speed * depth * 0.0762; |
| | | var oilLineO = (36d / 160) * oilLineOR * yieldCounting / speed * depth * 0.0762; |
| | | |
| | | var waterLineC = waterLineValArr.Skip(_cWinStartIndex).Take(cWinLength).Sum() * _coef / speed * depth * 0.07; |
| | | var waterLineO = waterLineValArr.Skip(_oWinStartIndex).Take(oWinLength).Sum() * _coef / speed * depth * 0.07; |
| | | var waterLineCR = waterLineValArr.Skip(_cWinStartIndex).Take(cWinLength).Sum() / waterLineValArr.Sum(); |
| | | var waterLineOR = waterLineValArr.Skip(_oWinStartIndex).Take(oWinLength).Sum() / waterLineValArr.Sum(); |
| | | var waterLineC = (36d / 160) * waterLineCR * yieldCounting / speed * depth * 0.0762; |
| | | var waterLineO = (36d / 160) * waterLineOR * yieldCounting / speed * depth * 0.0762; |
| | | |
| | | double cRes = 0, oRes = 0; |
| | | if (sw == 0) |
| | |
| | | /// <param name="depth">深度</param> |
| | | /// <returns>碳和氧值</returns> |
| | | /// <exception cref="InvalidDataException">孔隙度超过范围</exception> |
| | | public static (double, double) GetFarMergeCOResult(string modelId, double porosity, double sw, double speed, double depth) |
| | | public static (double, double) GetFarMergeCOResult(string modelId, double porosity, double sw, double speed, double depth, double yieldCounting) |
| | | { |
| | | if (porosity > 40) |
| | | throw new InvalidDataException("Porosity value out of range!"); |
| | |
| | | (double, double) result = (0, 0); |
| | | if (porosity % 5 == 0) |
| | | { |
| | | result = GetFarInterplolateResult(modelId, porosity, sw, speed, depth); |
| | | result = GetFarInterplolateResult(modelId, porosity, sw, speed, depth, yieldCounting); |
| | | } |
| | | else |
| | | { |
| | | var ceilingPorosity = Math.Ceiling(porosity / 5) * 5; |
| | | var ceilingResult = GetFarInterplolateResult(modelId, ceilingPorosity, sw, speed, depth); |
| | | var ceilingResult = GetFarInterplolateResult(modelId, ceilingPorosity, sw, speed, depth, yieldCounting); |
| | | |
| | | var floorPorosity = Math.Floor(porosity / 5) * 5; |
| | | var floorResult = GetFarInterplolateResult(modelId, floorPorosity, sw, speed, depth); |
| | | var floorResult = GetFarInterplolateResult(modelId, floorPorosity, sw, speed, depth, yieldCounting); |
| | | |
| | | result.Item1 = Utility.Interpolate(porosity, floorPorosity, floorResult.Item1, ceilingPorosity, ceilingResult.Item1); |
| | | result.Item2 = Utility.Interpolate(porosity, floorPorosity, floorResult.Item2, ceilingPorosity, ceilingResult.Item2); |
| | |
| | | /// <param name="depth">深度</param> |
| | | /// <returns>碳或氧值</returns> |
| | | /// <exception cref="InvalidDataException">孔隙度超过范围</exception> |
| | | public static (double, double) GetNearMergeCOResult(string modelId, double porosity, double sw, double speed, double depth) |
| | | public static (double, double) GetNearMergeCOResult(string modelId, double porosity, double sw, double speed, double depth, double yieldCounting) |
| | | { |
| | | if (porosity > 40) |
| | | throw new InvalidDataException("Porosity value out of range!"); |
| | |
| | | (double, double) result = (0, 0); |
| | | if (porosity % 5 == 0) |
| | | { |
| | | result = GetNearInterplolateResult(modelId, porosity, sw, speed, depth); |
| | | result = GetNearInterplolateResult(modelId, porosity, sw, speed, depth, yieldCounting); |
| | | } |
| | | else |
| | | { |
| | | var ceilingPorosity = Math.Ceiling(porosity / 5) * 5; |
| | | var ceilingResult = GetNearInterplolateResult(modelId, ceilingPorosity, sw, speed, depth); |
| | | var ceilingResult = GetNearInterplolateResult(modelId, ceilingPorosity, sw, speed, depth, yieldCounting); |
| | | |
| | | var floorPorosity = Math.Floor(porosity / 5) * 5; |
| | | var floorResult = GetNearInterplolateResult(modelId, floorPorosity, sw, speed, depth); |
| | | var floorResult = GetNearInterplolateResult(modelId, floorPorosity, sw, speed, depth, yieldCounting); |
| | | |
| | | result.Item1 = Utility.Interpolate(porosity, floorPorosity, floorResult.Item1, ceilingPorosity, ceilingResult.Item1); |
| | | result.Item2 = Utility.Interpolate(porosity, floorPorosity, floorResult.Item2, ceilingPorosity, ceilingResult.Item2); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | public static (double, double) GetFarCROR(string modelId, double porosity, double sw) |
| | | { |
| | | var cWinLength = _cWinEndIndex - _cWinStartIndex + 1; |
| | | var oWinLength = _oWinEndIndex - _oWinStartIndex + 1; |
| | | var oilLine = RepositoryInstance.Instance.COFarResultRepository?.GetCOFarResult(modelId, (int)porosity, 0); |
| | | var waterLine = RepositoryInstance.Instance.COFarResultRepository?.GetCOFarResult(modelId, (int)porosity, 100); |
| | | if (oilLine == null || waterLine == null) |
| | | throw new InvalidDataException("COFarResult Line is null"); |
| | | var oilLineValArr = oilLine.CInelasticSpec.Split(',').Select(v => Convert.ToDouble(v)).ToArray(); |
| | | var waterLineValArr = waterLine.CInelasticSpec.Split(',').Select(v => Convert.ToDouble(v)).ToArray(); |
| | | |
| | | var oilLineCR = oilLineValArr.Skip(_cWinStartIndex).Take(cWinLength).Sum() / oilLineValArr.Sum(); |
| | | var oilLineOR = oilLineValArr.Skip(_oWinStartIndex).Take(oWinLength).Sum() / oilLineValArr.Sum(); |
| | | |
| | | var waterLineCR = waterLineValArr.Skip(_cWinStartIndex).Take(cWinLength).Sum() / waterLineValArr.Sum(); |
| | | var waterLineOR = waterLineValArr.Skip(_oWinStartIndex).Take(oWinLength).Sum() / waterLineValArr.Sum(); |
| | | |
| | | double cRes = 0, oRes = 0; |
| | | if (sw == 0) |
| | | { |
| | | cRes = oilLineCR; |
| | | oRes = oilLineOR; |
| | | } |
| | | else if (sw == 100) |
| | | { |
| | | cRes = waterLineCR; |
| | | oRes = waterLineOR; |
| | | } |
| | | else if (sw > 0 && sw < 100) |
| | | { |
| | | cRes = Utility.Interpolate(sw, 100, waterLineCR, 0, oilLineCR); |
| | | oRes = Utility.Interpolate(sw, 0, oilLineOR, 100, waterLineOR); |
| | | } |
| | | return (cRes, oRes); |
| | | } |
| | | |
| | | public static (double, double) GetNearCROR(string modelId, double porosity, double sw) |
| | | { |
| | | var cWinLength = _cWinEndIndex - _cWinStartIndex + 1; |
| | | var oWinLength = _oWinEndIndex - _oWinStartIndex + 1; |
| | | var oilLine = RepositoryInstance.Instance.CONearResultRepository?.GetCONearResult(modelId, (int)porosity, 0); |
| | | var waterLine = RepositoryInstance.Instance.CONearResultRepository?.GetCONearResult(modelId, (int)porosity, 100); |
| | | if (oilLine == null || waterLine == null) |
| | | throw new InvalidDataException("COFarResult Line is null"); |
| | | var oilLineValArr = oilLine.CInelasticSpec.Split(',').Select(v => Convert.ToDouble(v)).ToArray(); |
| | | var waterLineValArr = waterLine.CInelasticSpec.Split(',').Select(v => Convert.ToDouble(v)).ToArray(); |
| | | |
| | | var oilLineCR = oilLineValArr.Skip(_cWinStartIndex).Take(cWinLength).Sum() / oilLineValArr.Sum(); |
| | | var oilLineOR = oilLineValArr.Skip(_oWinStartIndex).Take(oWinLength).Sum() / oilLineValArr.Sum(); |
| | | |
| | | var waterLineCR = waterLineValArr.Skip(_cWinStartIndex).Take(cWinLength).Sum() / waterLineValArr.Sum(); |
| | | var waterLineOR = waterLineValArr.Skip(_oWinStartIndex).Take(oWinLength).Sum() / waterLineValArr.Sum(); |
| | | |
| | | double crRes = 0, orRes = 0; |
| | | if (sw == 0) |
| | | { |
| | | crRes = oilLineCR; |
| | | orRes = oilLineOR; |
| | | } |
| | | else if (sw == 100) |
| | | { |
| | | crRes = waterLineCR; |
| | | orRes = waterLineOR; |
| | | } |
| | | else if (sw > 0 && sw < 100) |
| | | { |
| | | crRes = Utility.Interpolate(sw, 100, waterLineCR, 0, oilLineCR); |
| | | orRes = Utility.Interpolate(sw, 0, oilLineOR, 100, waterLineOR); |
| | | } |
| | | return (crRes, orRes); |
| | | } |
| | | |
| | | public static (double, double) GetFarCOORResult(string modelId, double porosity, double sw) |
| | | { |
| | | if (porosity > 40) |
| | | throw new InvalidDataException("Porosity value out of range!"); |
| | | |
| | | (double, double) result = (0, 0); |
| | | if (porosity % 5 == 0) |
| | | { |
| | | result = GetFarCROR(modelId, porosity, sw); |
| | | } |
| | | else |
| | | { |
| | | var ceilingPorosity = Math.Ceiling(porosity / 5) * 5; |
| | | var ceilingResult = GetFarCROR(modelId, ceilingPorosity, sw); |
| | | |
| | | var floorPorosity = Math.Floor(porosity / 5) * 5; |
| | | var floorResult = GetFarCROR(modelId, floorPorosity, sw); |
| | | |
| | | result.Item1 = Utility.Interpolate(porosity, floorPorosity, floorResult.Item1, ceilingPorosity, ceilingResult.Item1); |
| | | result.Item2 = Utility.Interpolate(porosity, floorPorosity, floorResult.Item2, ceilingPorosity, ceilingResult.Item2); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | public static (double, double) GetNearCOORResult(string modelId, double porosity, double sw) |
| | | { |
| | | if (porosity > 40) |
| | | throw new InvalidDataException("Porosity value out of range!"); |
| | | |
| | | (double, double) result = (0, 0); |
| | | if (porosity % 5 == 0) |
| | | { |
| | | result = GetNearCROR(modelId, porosity, sw); |
| | | } |
| | | else |
| | | { |
| | | var ceilingPorosity = Math.Ceiling(porosity / 5) * 5; |
| | | var ceilingResult = GetNearCROR(modelId, ceilingPorosity, sw); |
| | | |
| | | var floorPorosity = Math.Floor(porosity / 5) * 5; |
| | | var floorResult = GetNearCROR(modelId, floorPorosity, sw); |
| | | |
| | | result.Item1 = Utility.Interpolate(porosity, floorPorosity, floorResult.Item1, ceilingPorosity, ceilingResult.Item1); |
| | | result.Item2 = Utility.Interpolate(porosity, floorPorosity, floorResult.Item2, ceilingPorosity, ceilingResult.Item2); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | } |
| | | } |
| | |
| | | using ErrorAnalysis.Repository; |
| | | using ErrorAnalysis.Service; |
| | | using ErrorAnalysis.Service.Model; |
| | | using System; |
| | | using System.Collections.Generic; |
| | |
| | | { |
| | | public class ErrorRatioCalc |
| | | { |
| | | public static ErrorRatioResult GetErrorRatioResult(string modelID, double porosity, double sw, double depth, bool lockSpeed, double speed, double targetErrorRatio, out double testSpeed, int pass = 0) |
| | | 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 |
| | | { |
| | |
| | | { |
| | | List<double[]> cWOL; |
| | | List<double[]> oWOL; |
| | | var firstErrorPassM = GetFirstErrorRatio(modelID, porosity, sw, speed, depth, out cWOL, out 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); |
| | |
| | | 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); |
| | | (cWOL, oWOL) = GetOilWaterLine(modelID); |
| | | result.CWOL = cWOL; |
| | | result.OWOL = oWOL; |
| | | speed -= 0.01; |
| | | } while (firstErrorPass.ErrorRatioValue != 0 && firstErrorPass.ErrorRatioValue > firstTargetErrorRatio); |
| | | |
| | | 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 firstErrorPassM = GetFirstErrorRatio(modelID, porosity, sw, speed, depth, yieldCounting, nearCofe, farCofe); |
| | | //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++) |
| | |
| | | |
| | | } |
| | | |
| | | private static ErrorRatio GetFirstErrorRatio(string modelID, double porosity, double sw, double speed, double depth, out List<double[]> cWOL, out List<double[]> oWOL) |
| | | 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!"); |
| | | |
| | | 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); |
| | | // //} |
| | | |
| | | // } |
| | | // } |
| | | //} |
| | | var mergePDEV = PDEVCalcService.GetMergePDEV(modelID, porosity, sw, speed, depth, yieldCounting, nearCofe, farCofe); |
| | | |
| | | foreach (var wolProperty in wolResType.GetProperties()) |
| | | var errorRatio = mergePDEV / GetMDelta(modelID, porosity); |
| | | |
| | | return new ErrorRatio { Pass = 1, ErrorRatioValue = errorRatio }; |
| | | } |
| | | catch |
| | | { |
| | | 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 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; |
| | |
| | | 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 }; |
| | | return cRes - oRes; |
| | | } |
| | | catch |
| | | |
| | | private static (List<double[]>, List<double[]>) GetOilWaterLine(string modelID) |
| | | { |
| | | cWOL = null; |
| | | oWOL = null; |
| | | return new ErrorRatio { Pass = 0, ErrorRatioValue = 0 }; |
| | | 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); |
| | | } |
| | | } |
| | | } |
| | |
| | | { |
| | | public class PDEVCalcService |
| | | { |
| | | public static double GetMergePDEV(string modelId, double porosity, double sw, double speed, double depth) |
| | | public static double GetMergePDEV(string modelId, double porosity, double sw, double speed, double depth, double yieldCounting, double nearCofe, double farCofe) |
| | | { |
| | | var farResult = COMergeCalcService.GetFarMergeCOResult(modelId, porosity, sw, speed, depth); |
| | | var farResult = COMergeCalcService.GetFarMergeCOResult(modelId, porosity, sw, speed, depth, yieldCounting); |
| | | var farPDEV = CalcPDEV(farResult.Item1, farResult.Item2); |
| | | |
| | | var nearResult = COMergeCalcService.GetNearMergeCOResult(modelId, porosity, sw, speed, depth); |
| | | var nearResult = COMergeCalcService.GetNearMergeCOResult(modelId, porosity, sw, speed, depth, yieldCounting); |
| | | var nearPDEV = CalcPDEV(nearResult.Item1, nearResult.Item2); |
| | | |
| | | return nearPDEV * 0.65 + farPDEV * 0.35; |
| | | return Math.Sqrt(Math.Pow(nearPDEV * nearCofe, 2) + Math.Pow(farPDEV * farCofe, 2)); |
| | | } |
| | | |
| | | private static double CalcPDEV(double c, double o) => Math.Sqrt(Math.Pow(c / o, 2) * (1 / c + 1 / o)); |
| | |
| | | cmbLithology = new ComboBox(); |
| | | label16 = new Label(); |
| | | tpPlan = new TabPage(); |
| | | label7 = new Label(); |
| | | cmbTargetLoggingIntervalUnit = new ComboBox(); |
| | | label5 = new Label(); |
| | | chkAlphaProcessing = new CheckBox(); |
| | | nudYieldCounting = new NumericUpDown(); |
| | | nudAlphaProcessingWin = new NumericUpDown(); |
| | | nudDepth = new NumericUpDown(); |
| | | nudTargetLoggingInterval = new NumericUpDown(); |
| | |
| | | ((System.ComponentModel.ISupportInitialize)nudSw).BeginInit(); |
| | | ((System.ComponentModel.ISupportInitialize)nudPorosity).BeginInit(); |
| | | tpPlan.SuspendLayout(); |
| | | ((System.ComponentModel.ISupportInitialize)nudYieldCounting).BeginInit(); |
| | | ((System.ComponentModel.ISupportInitialize)nudAlphaProcessingWin).BeginInit(); |
| | | ((System.ComponentModel.ISupportInitialize)nudDepth).BeginInit(); |
| | | ((System.ComponentModel.ISupportInitialize)nudTargetLoggingInterval).BeginInit(); |
| | |
| | | // |
| | | // nudSpeed |
| | | // |
| | | nudSpeed.DecimalPlaces = 1; |
| | | nudSpeed.DecimalPlaces = 2; |
| | | nudSpeed.Increment = new decimal(new int[] { 1, 0, 0, 65536 }); |
| | | nudSpeed.Location = new Point(54, 16); |
| | | nudSpeed.Maximum = new decimal(new int[] { 9999999, 0, 0, 0 }); |
| | |
| | | // |
| | | // tpPlan |
| | | // |
| | | tpPlan.Controls.Add(label7); |
| | | tpPlan.Controls.Add(cmbTargetLoggingIntervalUnit); |
| | | tpPlan.Controls.Add(label5); |
| | | tpPlan.Controls.Add(chkAlphaProcessing); |
| | | tpPlan.Controls.Add(label22); |
| | | tpPlan.Controls.Add(nudYieldCounting); |
| | | tpPlan.Controls.Add(nudAlphaProcessingWin); |
| | | tpPlan.Controls.Add(pnlLockPass); |
| | | tpPlan.Controls.Add(nudDepth); |
| | |
| | | tpPlan.TabIndex = 3; |
| | | tpPlan.Text = "Plan"; |
| | | tpPlan.UseVisualStyleBackColor = true; |
| | | // |
| | | // label7 |
| | | // |
| | | label7.AutoSize = true; |
| | | label7.Location = new Point(457, 102); |
| | | label7.Name = "label7"; |
| | | label7.Size = new Size(90, 17); |
| | | label7.TabIndex = 17; |
| | | label7.Text = "Yield counting"; |
| | | // |
| | | // cmbTargetLoggingIntervalUnit |
| | | // |
| | |
| | | // chkAlphaProcessing |
| | | // |
| | | chkAlphaProcessing.AutoSize = true; |
| | | chkAlphaProcessing.Location = new Point(421, 69); |
| | | chkAlphaProcessing.Location = new Point(419, 43); |
| | | chkAlphaProcessing.Name = "chkAlphaProcessing"; |
| | | chkAlphaProcessing.Size = new Size(128, 21); |
| | | chkAlphaProcessing.TabIndex = 15; |
| | | chkAlphaProcessing.Text = "Alpha processing"; |
| | | chkAlphaProcessing.UseVisualStyleBackColor = true; |
| | | // |
| | | // nudYieldCounting |
| | | // |
| | | nudYieldCounting.DecimalPlaces = 2; |
| | | nudYieldCounting.Increment = new decimal(new int[] { 100, 0, 0, 0 }); |
| | | nudYieldCounting.Location = new Point(565, 100); |
| | | nudYieldCounting.Maximum = new decimal(new int[] { 99999999, 0, 0, 0 }); |
| | | nudYieldCounting.Name = "nudYieldCounting"; |
| | | nudYieldCounting.Size = new Size(82, 23); |
| | | nudYieldCounting.TabIndex = 13; |
| | | // |
| | | // nudAlphaProcessingWin |
| | | // |
| | | nudAlphaProcessingWin.Location = new Point(555, 98); |
| | | nudAlphaProcessingWin.Location = new Point(565, 70); |
| | | nudAlphaProcessingWin.Maximum = new decimal(new int[] { 99999999, 0, 0, 0 }); |
| | | nudAlphaProcessingWin.Name = "nudAlphaProcessingWin"; |
| | | nudAlphaProcessingWin.Size = new Size(47, 23); |
| | |
| | | // label54 |
| | | // |
| | | label54.AutoSize = true; |
| | | label54.Location = new Point(391, 100); |
| | | label54.Location = new Point(389, 72); |
| | | label54.Name = "label54"; |
| | | label54.Size = new Size(158, 17); |
| | | label54.TabIndex = 12; |
| | |
| | | ((System.ComponentModel.ISupportInitialize)nudPorosity).EndInit(); |
| | | tpPlan.ResumeLayout(false); |
| | | tpPlan.PerformLayout(); |
| | | ((System.ComponentModel.ISupportInitialize)nudYieldCounting).EndInit(); |
| | | ((System.ComponentModel.ISupportInitialize)nudAlphaProcessingWin).EndInit(); |
| | | ((System.ComponentModel.ISupportInitialize)nudDepth).EndInit(); |
| | | ((System.ComponentModel.ISupportInitialize)nudTargetLoggingInterval).EndInit(); |
| | |
| | | private TableLayoutPanel tableLayoutPanel1; |
| | | private ProgressBar pbLoadDB; |
| | | private RichTextBox txtAnalysisResult; |
| | | private Label label7; |
| | | private NumericUpDown nudYieldCounting; |
| | | } |
| | | } |
| | |
| | | |
| | | if (!decimal.TryParse(nudOilDensity.Value.ToString(), out decimal oilDensity) || nudOilDensity.Value <= 0) |
| | | { |
| | | MessageBox.Show("Please enter a oil density"); |
| | | MessageBox.Show("Please enter a reasonable oil density"); |
| | | return; |
| | | } |
| | | |
| | | if (!double.TryParse(nudYieldCounting.Value.ToString(), out double yieldCounting) || nudYieldCounting.Value <= 0) |
| | | { |
| | | MessageBox.Show("Please enter a reasonable yield counting"); |
| | | return; |
| | | } |
| | | |
| | |
| | | MessageBox.Show("Please enter a reasonable speed"); |
| | | return; |
| | | } |
| | | var calcSpeed = cmbSpeedUnit.Text == "ft/hr" ? UnitConvert.FtHr2MMin(speed) : UnitConvert.MHR2MMin(speed); |
| | | var calcSpeed = cmbSpeedUnit.Text == "ft/hr" ? UnitConvert.FtHr2MS(speed) : UnitConvert.MHR2MS(speed); |
| | | |
| | | var result = ErrorRatioCalc.GetErrorRatioResult(_model.ModelID, porosity, sw, depth, true, calcSpeed, targetErrorRatio / 100, out _); |
| | | var result = ErrorRatioCalc.GetErrorRatioResult(_model.ModelID, porosity, sw, depth, true, calcSpeed, yieldCounting, targetErrorRatio / 100, out _); |
| | | Plot(result); |
| | | |
| | | double totalTime = Math.Round((targetLoggingInterval / calcSpeed / 60), 2); |
| | | double totalTime = Math.Round((targetLoggingInterval / calcSpeed / 60 / 60), 2); |
| | | var errorRate = Math.Round(result.ErrorRatios.Min(r => r.ErrorRatioValue) * 100, 2); |
| | | txtAnalysisResult.AppendText("A total of "); |
| | | AppendText(txtAnalysisResult, result.ErrorRatios.Count.ToString(), ColorTranslator.FromHtml("#8B0000")); |
| | |
| | | txtAnalysisResult.AppendText(" the estimated total job duration is "); |
| | | AppendText(txtAnalysisResult, $"{totalTime} hours.", ColorTranslator.FromHtml("#8B0000")); |
| | | |
| | | _reportModel = CreateReportModel(totalTime.ToString(), result.ErrorRatios.Count.ToString(), Math.Round(UnitConvert.MMin2FtHr(calcSpeed), 2).ToString(), errorRate.ToString()); |
| | | _reportModel = CreateReportModel(totalTime.ToString(), result.ErrorRatios.Count.ToString(), Math.Round(UnitConvert.MS2FtHr(calcSpeed), 2).ToString(), errorRate.ToString()); |
| | | } |
| | | else |
| | | { |
| | |
| | | return; |
| | | } |
| | | double speed; |
| | | var result = ErrorRatioCalc.GetErrorRatioResult(_model.ModelID, porosity, sw, depth, false, 0, targetErrorRatio / 100, out speed, pass); |
| | | var result = ErrorRatioCalc.GetErrorRatioResult(_model.ModelID, porosity, sw, depth, false, 0, yieldCounting, targetErrorRatio / 100, out speed, pass); |
| | | Plot(result); |
| | | |
| | | double totalTime = Math.Round((targetLoggingInterval / speed / 60), 2); |
| | | double totalTime = Math.Round((targetLoggingInterval / speed / 60 / 60), 2); |
| | | var errorRate = Math.Round(result.ErrorRatios.Min(r => r.ErrorRatioValue) * 100, 2); |
| | | var speedFr = Math.Round(UnitConvert.MMin2FtHr(speed), 2); |
| | | var speedFr = Math.Round(UnitConvert.MS2FtHr(speed), 2); |
| | | |
| | | txtAnalysisResult.AppendText("A total of "); |
| | | AppendText(txtAnalysisResult, result.ErrorRatios.Count.ToString(), ColorTranslator.FromHtml("#8B0000")); |
| | |
| | | if (curModels.Count == 0) |
| | | return; |
| | | |
| | | var casingFulids = curModels.Select(x => x.CasingFluid == "0" ? "water" : x.CasingFluid == "100" ? "oil" : x.CasingFluid == "200" ? "gas" : "none").Distinct().ToArray(); |
| | | var casingFulids = curModels.Select(x => x.CasingFluid == "999" ? "none" : x.CasingFluid == "100" ? "oil" : x.CasingFluid == "200" ? "gas" : "water").Distinct().ToArray(); |
| | | |
| | | if (casingFulids.Length == 1 && casingFulids[0] == "999") |
| | | if (casingFulids.Length == 1 && casingFulids[0] == "none") |
| | | { |
| | | cmbCasingHoldUp.Enabled = false; |
| | | nudCasingHoldUp.Enabled = false; |
| | |
| | | cmbCasingHoldUp.Items.AddRange(casingFulids); |
| | | } |
| | | |
| | | var screenFulids = curModels.Select(x => x.ScreenFluid == "0" ? "water" : x.ScreenFluid == "100" ? "oil" : x.ScreenFluid == "200" ? "gas" : "none").Distinct().ToArray(); |
| | | var screenFulids = curModels.Select(x => x.ScreenFluid == "999" ? "none" : x.ScreenFluid == "100" ? "oil" : x.ScreenFluid == "200" ? "gas" : "water").Distinct().ToArray(); |
| | | |
| | | if (screenFulids.Length == 1 && screenFulids[0] == "none") |
| | | { |
| | |
| | | cmbScreenHoldUp.Items.AddRange(screenFulids); |
| | | } |
| | | |
| | | var tubeFluids = curModels.Select(x => x.TubeFluid == "0" ? "water" : x.TubeFluid == "100" ? "oil" : x.TubeFluid == "200" ? "gas" : "none").Distinct().ToArray(); |
| | | var tubeFluids = curModels.Select(x => x.TubeFluid == "999" ? "none" : x.TubeFluid == "100" ? "oil" : x.TubeFluid == "200" ? "gas" : "water").Distinct().ToArray(); |
| | | if (tubeFluids.Length == 1 && tubeFluids[0] == "none") |
| | | { |
| | | cmbTubeHoldUp.Enabled = false; |
| | |
| | | } |
| | | } |
| | | #endregion |
| | | |
| | | private List<COModelTable> GetFilterResult() |
| | | { |
| | | var type = typeof(COModelTable); |
| | |
| | | |
| | | public static double M2Ft(double val) => val * 3.281; |
| | | |
| | | public static double FtHr2MMin(double val) => val / 3.281 / 60; |
| | | public static double FtHr2MS(double val) => val / 3.281 / 60/60; |
| | | |
| | | public static double MHR2MMin(double val) => val /60; |
| | | public static double MHR2MS(double val) => val /60/60; |
| | | |
| | | public static double MMin2FtHr(double val) => val * 3.281 * 60; |
| | | public static double MS2FtHr(double val) => val * 3.281 * 60*60; |
| | | |
| | | /// <summary> |
| | | /// 计算YieldCounting备用 |
| | | /// </summary> |
| | | /// <param name="yieldCounting">产额</param> |
| | | /// <returns>产额</returns> |
| | | public static double CalcYieldCounting(double yieldCounting) => yieldCounting; |
| | | } |
| | | } |