namespace IStation.Curve
|
{
|
/// <summary>
|
/// 串并联辅助类
|
/// </summary>
|
public class ParallelConnectionHelper
|
{
|
|
// 计算曲线列表
|
private List<CurveExpress> _curveQhList = new List<CurveExpress>();
|
private List<CurveExpress> _curveQpList = new List<CurveExpress>();
|
|
// 延长率, 默认不延长
|
private double _extendMinRatio = 1;
|
private double _extendMaxRatio = 1;
|
|
//求Q的最大最小值
|
double minQ = 0, maxQ = 100000;
|
|
//求H的最大最小值
|
double minH = 0, maxH = 100000;
|
|
#region Curve
|
/// <summary>
|
/// 添加
|
/// </summary>
|
/// <param name="curveQh"></param>
|
/// <param name="curveQp"></param>
|
public void AddCurve(CurveExpress curveQh, CurveExpress curveQp)
|
{
|
if (curveQh != null)
|
_curveQhList.Add(curveQh);
|
|
if (curveQp != null)
|
_curveQpList.Add(curveQp);
|
}
|
|
/// <summary>
|
/// 添加
|
/// </summary>
|
/// <param name="pointsQH"></param>
|
/// <param name="pointsQP"></param>
|
public void AddCurve(List<CurvePoint> pointsQH, List<CurvePoint> 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));
|
}
|
|
/// <summary>
|
/// 清除
|
/// </summary>
|
public void ClearCurve()
|
{
|
this.minQ = 0;
|
this.maxQ = 100000;
|
this.minH = 0;
|
this.maxH = 100000;
|
_curveQhList.Clear();
|
_curveQpList.Clear();
|
}
|
#endregion
|
|
/// <summary>
|
/// 计算并联
|
/// </summary>
|
/// <param name="pointQH"></param>
|
/// <param name="pointQE"></param>
|
/// <param name="pointQP"></param>
|
/// <returns></returns>
|
public bool CalculateParallel(out List<CurvePoint> pointQH, out List<CurvePoint> pointQE, out List<CurvePoint> pointQP)
|
{
|
pointQH = pointQE = pointQP = null;
|
//求H的最大最小值
|
if (!CalculateMaxMinH())
|
return false;
|
|
//计算并联
|
return GetCurveParallel(out pointQH, out pointQE, out pointQP);
|
}
|
|
/// <summary>
|
/// 从并联曲线中分割出单泵曲线
|
/// </summary>
|
/// <param name="connectPointsQH"></param>
|
/// <param name="separatePointsQH"></param>
|
/// <returns></returns>
|
public bool SeparateParallelQH(List<CurvePoint> connectPointsQH, out List<CurvePoint> separatePointsQH)
|
{
|
separatePointsQH = new List<CurvePoint>();
|
|
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<CurvePoint> 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<CurvePoint> 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<CurvePoint> pointsQH,
|
out List<CurvePoint> pointsQE,
|
out List<CurvePoint> 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 < 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<CurvePoint> pointsQH, out List<CurvePoint> pointsQE, out List<CurvePoint> pointsQP)
|
{
|
if (_curveQhList == null || !_curveQhList.Any())
|
{
|
pointsQH = null;
|
pointsQE = null;
|
pointsQP = null;
|
return false;
|
}
|
|
pointsQH = new List<CurvePoint>();
|
pointsQE = new List<CurvePoint>();
|
pointsQP = new List<CurvePoint>();
|
|
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<CurvePoint> 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<CurvePoint> pointsQH, out List<CurvePoint> pointsQE, out List<CurvePoint> pointsQP)
|
{
|
if (_curveQhList.Count() == 0)
|
{
|
pointsQH = null;
|
pointsQE = null;
|
pointsQP = null;
|
return false;
|
}
|
pointsQH = new List<CurvePoint>();
|
pointsQE = new List<CurvePoint>();
|
pointsQP = new List<CurvePoint>();
|
|
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;
|
}
|
|
/// <summary>
|
/// 获取拟合点(延长率):和GetFitPointsByExtend一模一样
|
/// </summary>
|
public static List<CurvePoint> 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;
|
}
|
}
|
}
|