namespace IStation.Curve
{
///
/// 串并联辅助类
///
public class ParallelConnectionHelper
{
// 计算曲线列表
private List _curveQhList = new List();
private List _curveQpList = new List();
// 延长率, 默认不延长
private double _extendMinRatio = 1;
private double _extendMaxRatio = 1;
//求Q的最大最小值
double minQ = 0, maxQ = 100000;
//求H的最大最小值
double minH = 0, maxH = 100000;
#region Curve
///
/// 添加
///
///
///
public void AddCurve(CurveExpress curveQh, CurveExpress curveQp)
{
if (curveQh != null)
_curveQhList.Add(curveQh);
if (curveQp != null)
_curveQpList.Add(curveQp);
}
///
/// 添加
///
///
///
public void AddCurve(List pointsQH, List pointsQP)
{
if (pointsQH != null && pointsQH.Count > 3)
_curveQhList.Add(FitHelper.BuildCurveExpress(pointsQH, eFitType.CubicCurve));
if (pointsQP != null && pointsQP.Count > 3)
_curveQpList.Add(FitHelper.BuildCurveExpress(pointsQH, eFitType.CubicCurve));
}
///
/// 清除
///
public void ClearCurve()
{
this.minQ = 0;
this.maxQ = 100000;
this.minH = 0;
this.maxH = 100000;
_curveQhList.Clear();
_curveQpList.Clear();
}
#endregion
///
/// 计算并联
///
///
///
///
///
public bool CalculateParallel(out List pointQH, out List pointQE, out List pointQP)
{
pointQH = pointQE = pointQP = null;
//求H的最大最小值
if (!CalculateMaxMinH())
return false;
//计算并联
return GetCurveParallel(out pointQH, out pointQE, out pointQP);
}
///
/// 从并联曲线中分割出单泵曲线
///
///
///
///
public bool SeparateParallelQH(List connectPointsQH, out List separatePointsQH)
{
separatePointsQH = new List();
maxH = (from x in connectPointsQH select x.Y).Max();
minH = (from x in connectPointsQH select x.Y).Min();
int insert_num = 30;
double space = (maxH - minH) / (insert_num - 1);
double H = minH;
int i = 0, j = 0;
for (j = 0; j < insert_num; j++)
{
//计算流量
List listQ = FitHelper.GetInterPointX(connectPointsQH, H);
if (listQ == null || listQ.Count == 0)
{
continue;
}
double totalQ = listQ.Last().X;
bool isInsect = true;
for (i = 0; i < _curveQhList.Count(); i++)
{
var currentQH = _curveQhList[i];
//计算流量
List listQ2 = FitHelper.GetInterPointX(currentQH, H);
if (listQ2 == null || listQ2.Count == 0)
{
isInsect = false;
continue;
}
double Q = listQ2.Last().X;
totalQ = totalQ - Q;
}
//添加到列表
if (isInsect)
{
separatePointsQH.Add(new CurvePoint(totalQ, H));
}
H = H + space;
}
if (separatePointsQH.Count < 3)
{
separatePointsQH = null;
return false;
}
var express = FitHelper.BuildCurveExpress(separatePointsQH, eFitType.CubicCurve);
separatePointsQH = FitHelper.GetFitPoints(express, 20);
return true;
}
//计算串联
public bool CalculateSeries(
out List pointsQH,
out List pointsQE,
out List pointsQP)
{
pointsQH = pointsQE = pointsQP = null;
//求Q的最大最小值
if (!CalculateMaxMinQ())
return false;
//计算并联
return GetCurveSeries(out pointsQH, out pointsQE, out pointsQP);
}
private bool CalculateMaxMinH()
{
if (_curveQhList == null || _curveQhList.Count() == 0)
return false;
foreach (var curves in _curveQhList)
{
if (curves == null)
continue;
double min_h = 0, max_h = 0;
GetMinMaxPointYByRatio(curves, _extendMinRatio, _extendMaxRatio, out max_h, out min_h);
this.minH = Math.Max(min_h, this.minH);
this.maxH = Math.Min(max_h, this.maxH);
}
if (this.maxH * 0.99 < this.minH)
return false;
return true;
}
private bool CalculateMaxMinQ()
{
if (_curveQhList == null || _curveQhList.Count() == 0)
return false;
foreach (var curve in _curveQhList)
{
if (curve == null)
continue;
minQ = Math.Max(curve.Min * _extendMinRatio, minH);
maxQ = Math.Min(curve.Max * _extendMaxRatio, maxH);
}
if (minQ > maxQ - 3)
return false;
else
return true;
}
//计算并联
private bool GetCurveParallel(out List pointsQH, out List pointsQE, out List pointsQP)
{
if (_curveQhList == null || !_curveQhList.Any())
{
pointsQH = null;
pointsQE = null;
pointsQP = null;
return false;
}
pointsQH = new List();
pointsQE = new List();
pointsQP = new List();
int insert_num = 30;
double space = (maxH - minH) / (insert_num - 1);
double H = minH;
int i = 0, j = 0;
for (j = 0; j < insert_num; j++)
{
double totalQ = 0;
double totalP = 0;
bool isInsect = true;
for (i = 0; i < _curveQhList.Count(); i++)
{
CurveExpress currentQH = _curveQhList[i];
CurveExpress currentQP = null;
if (_curveQpList != null && _curveQpList.Count > i)
currentQP = _curveQpList[i];
//计算流量
List listQ = FitHelper.GetInterPointX(currentQH, H);
if (listQ == null || listQ.Count == 0)
{
isInsect = false;
continue;
}
double Q = listQ.Last().X;
totalQ = totalQ + Q;
//计算功率
if (currentQP != null)
{
double p = FitHelper.GetFitPointY(currentQP, Q);
totalP = totalP + p;
}
}
//添加到列表
if (isInsect)
{
pointsQH.Add(new CurvePoint(totalQ, H));
if (totalP > 0.001)
{
pointsQP.Add(new CurvePoint(totalQ, totalP));
double E = PumpCalculateHelper.CalculateE(totalQ, H, totalP);
pointsQE.Add(new CurvePoint(totalQ, E));
}
}
H = H + space;
}
//根据流量排序
CurvePointComparer.Sort featPointComp = new CurvePointComparer.Sort(CurvePointComparer.eSortType.X);
pointsQH.Sort(featPointComp);
if (pointsQE != null && pointsQE.Count > 2)
pointsQE.Sort(featPointComp);
if (pointsQP != null && pointsQP.Count > 2)
pointsQP.Sort(featPointComp);
return true;
}
//计算串联
private bool GetCurveSeries(out List pointsQH, out List pointsQE, out List pointsQP)
{
if (_curveQhList.Count() == 0)
{
pointsQH = null;
pointsQE = null;
pointsQP = null;
return false;
}
pointsQH = new List();
pointsQE = new List();
pointsQP = new List();
int insert_num = 30;
double space = (maxQ - minQ) / (insert_num - 1);
double Q = minQ;
int i = 0, j = 0;
for (j = 0; j < insert_num; j++)
{
double totalH = 0;
double totalP = 0;
bool isInsect = true;
for (i = 0; i < _curveQhList.Count(); i++)
{
CurveExpress currentQH = _curveQhList[i];
CurveExpress currentQP = null;
if (_curveQpList != null && _curveQpList.Count > i)
currentQP = _curveQpList[i];
//计算H
double h = FitHelper.GetFitPointY(currentQH, Q);
totalH = totalH + h;
//计算功率
if (currentQP != null)
{
double p = FitHelper.GetFitPointY(currentQP, Q);
totalP = totalP + p;
}
}
//添加到列表
if (isInsect)
{
pointsQH.Add(new CurvePoint(Q, totalH));
if (totalP > 0.001)
{
pointsQP.Add(new CurvePoint(Q, totalP));
double E = PumpCalculateHelper.CalculateE(Q, totalH, totalP);
pointsQE.Add(new CurvePoint(Q, E));
}
}
Q = Q + space;
}
//根据流量排序
CurvePointComparer.Sort featPointComp = new CurvePointComparer.Sort(CurvePointComparer.eSortType.X);
pointsQH.Sort(featPointComp);
if (pointsQE != null && pointsQE.Count > 2)
pointsQE.Sort(featPointComp);
if (pointsQP != null && pointsQP.Count > 2)
pointsQP.Sort(featPointComp);
return true;
}
///
/// 获取拟合点(延长率):和GetFitPointsByExtend一模一样
///
public static List GetFitPointsByRatio(CurveExpress express, double ratioExtendmin, double ratioExtendmax, int pointNumber)
{
if (express == null)
return default;
return express.GetFitPointsByXRange(express.Min * ratioExtendmin, express.Max * ratioExtendmax, pointNumber);
}
//获取延长后 MaxY MinY
public static bool GetMinMaxPointYByRatio(CurveExpress express, double ratioExtendmin, double ratioExtendmax, out double maxY, out double minY)
{
if (express == null)
{
maxY = minY = 0;
return false;
}
var fitPoints = GetFitPointsByRatio(express, ratioExtendmin, ratioExtendmax, 50);
if (fitPoints == null || !fitPoints.Any())
{
maxY = minY = 0;
return false;
}
maxY = (from x in fitPoints select x.Y).Max();
minY = (from x in fitPoints select x.Y).Min();
return true;
}
}
}