using ErrorAnalysis.Repository; using Microsoft.VisualBasic; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using static System.Runtime.InteropServices.JavaScript.JSType; namespace ErrorAnalysis.Service { public class COMergeCalcService { //Ncoef=1e8*2.54*2.54*2*6*11*2*77*0.2/0.6*speed; //Fcoef=1e8*2.54*2.54*4*6*2*11*77*0.2/0.6*speed; const double _gg = (9.0 - 0.0) / 255.0;//0.03529 const double _offset = 0.0; const int _cWinStartIndex = (int)(3.3 / _gg + _offset); //C窗口index const int _cWinEndIndex = (int)(4.78 / _gg + _offset); // width= 4.78-3.3 = 1.48 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; 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 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 oilLineC = 36d / 160d * oilLineCR * yieldCounting / speed * depth * 0.0762d; var oilLineO = 36d / 160d * oilLineOR * yieldCounting / speed * depth * 0.0762d; var waterLineCR = waterLineValArr.Skip(_cWinStartIndex).Take(cWinLength).Sum() / waterLineValArr.Sum(); var waterLineOR = waterLineValArr.Skip(_oWinStartIndex).Take(oWinLength).Sum() / waterLineValArr.Sum(); var waterLineC = 36d / 160d * waterLineCR * yieldCounting / speed * depth * 0.0762d; var waterLineO = 36d / 160d * waterLineOR * yieldCounting / speed * depth * 0.0762d; double cRes = 0, oRes = 0; if (sw == 0) { cRes = oilLineC; oRes = oilLineO; } else if (sw == 100) { cRes = waterLineC; oRes = waterLineO; } else if (sw > 0 && sw < 100) { cRes = Utility.Interpolate(sw, 100, waterLineC, 0, oilLineC); oRes = Utility.Interpolate(sw, 0, oilLineO, 100, waterLineO); } return (cRes, oRes); } 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 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 oilLineC = (36d / 160d) * oilLineCR * yieldCounting / speed * depth * 0.0762d; var oilLineO = (36d / 160d) * oilLineOR * yieldCounting / speed * depth * 0.0762d; var waterLineCR = waterLineValArr.Skip(_cWinStartIndex).Take(cWinLength).Sum() / waterLineValArr.Sum(); var waterLineOR = waterLineValArr.Skip(_oWinStartIndex).Take(oWinLength).Sum() / waterLineValArr.Sum(); var waterLineC = (36d / 160d) * waterLineCR * yieldCounting / speed * depth * 0.0762d; var waterLineO = (36d / 160d) * waterLineOR * yieldCounting / speed * depth * 0.0762d; double cRes = 0, oRes = 0; if (sw == 0) { cRes = waterLineC; oRes = waterLineO; } else if (sw == 100) { cRes = waterLineC; oRes = waterLineO; } else if (sw > 0 && sw < 100) { cRes = Utility.Interpolate(sw, 100, waterLineC, 0, oilLineC); oRes = Utility.Interpolate(sw, 0, oilLineO, 100, waterLineO); } return (cRes, oRes); } /// /// 获取远探头C或O值 /// /// 数据库连接字符串 /// 管柱ID /// 孔隙度 /// 含水饱和度 /// 读取含水饱和度(0为碳,100为氧) /// 测速 /// 深度 /// 碳和氧值 /// 孔隙度超过范围 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, yieldCounting); } else { var ceilingPorosity = Math.Ceiling(porosity / 5) * 5; var ceilingResult = GetFarInterplolateResult(modelId, ceilingPorosity, sw, speed, depth, yieldCounting); var floorPorosity = Math.Floor(porosity / 5) * 5; 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); } return result; } /// /// 获取近探头C或O值 /// /// 数据库连接字符串 /// 管柱ID /// 孔隙度 /// 含水饱和度 /// 读取含水饱和度(0为碳,100为氧) /// 测速 /// 深度 /// 碳或氧值 /// 孔隙度超过范围 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, yieldCounting); } else { var ceilingPorosity = Math.Ceiling(porosity / 5) * 5; var ceilingResult = GetNearInterplolateResult(modelId, ceilingPorosity, sw, speed, depth, yieldCounting); var floorPorosity = Math.Floor(porosity / 5) * 5; 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; } } }