using ErrorAnalysis.Repository;
|
using ErrorAnalysis.Service.Model;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Threading.Tasks;
|
|
namespace ErrorAnalysis.Service
|
{
|
public class ErrorRatioCalc
|
{
|
public static ErrorRatioResult GetErrorRatioResult(string modelID, double porosity, double sw, double depth, bool lockSpeed, double speed, double targetErrorRatio, int pass = 0)
|
{
|
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 firsErrorPass = GetFirstErrorRatio(modelID, porosity, sw, speed, depth, out cWOL, out oWOL);
|
result.CWOL = cWOL;
|
result.OWOL = oWOL;
|
result.ErrorRatios.Add(firsErrorPass);
|
if (firsErrorPass.ErrorRatioValue > targetErrorRatio)
|
{
|
var targetPass = Convert.ToInt32(Math.Ceiling(Math.Pow(firsErrorPass.ErrorRatioValue / targetErrorRatio, 2)));
|
for (int i = 2; i <= targetPass; i++)
|
{
|
result.ErrorRatios.Add(new ErrorRatio { Pass = i, ErrorRatioValue = firsErrorPass.ErrorRatioValue / Math.Sqrt(i) });
|
}
|
}
|
}
|
else
|
{
|
var firstTargetErrorRatio = targetErrorRatio * Math.Sqrt(pass);
|
List<double[]> cWOL;
|
List<double[]> oWOL;
|
var firstErrorPass = new ErrorRatio();
|
speed = 0.6;
|
while (firstErrorPass.ErrorRatioValue != 0 && firstErrorPass.ErrorRatioValue > firstTargetErrorRatio)
|
{
|
firstErrorPass = GetFirstErrorRatio(modelID, porosity, sw, speed, depth, out cWOL, out oWOL);
|
result.CWOL = cWOL;
|
result.OWOL = oWOL;
|
speed -= 0.01;
|
}
|
}
|
|
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"))
|
{
|
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);
|
}
|
}
|
}
|
|
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);
|
|
return new ErrorRatio { Pass = 1, ErrorRatioValue = errorRatio };
|
}
|
catch
|
{
|
cWOL = null;
|
oWOL = null;
|
return new ErrorRatio { Pass = 0, ErrorRatioValue = 0 };
|
}
|
}
|
}
|
}
|