using Yw.Geometry;
namespace Yw.WinFrmUI.Phart
{
///
/// 串并联辅助类
///
public class PumpParallelConnectionHelper
{
private List _qh_list = new List();
private List _qp_list = new List();
// 延长率, 默认不延长
private double _extend_min_ratio = 1;
private double _extend_max_ratio = 1;
// 求Q的最大最小值
double _min_flow = 0, _max_flow = 100000;
// 求H的最大最小值
double _min_head = 0, _max_head = 100000;
#region CubicSpline
///
/// 添加
///
///
///
public void Add(Yw.Geometry.CubicSpline2d qh, Yw.Geometry.CubicSpline2d qp)
{
if (qh != null)
_qh_list.Add(qh);
if (qp != null)
_qp_list.Add(qp);
}
///
/// 添加
///
///
///
public void Add(List qh_pt_list, List qp_pt_list)
{
if (qh_pt_list != null && qh_pt_list.Count > 3)
_qh_list.Add(new Yw.Geometry.CubicSpline2d(qh_pt_list));
if (qp_pt_list != null && qp_pt_list.Count > 3)
_qp_list.Add(new Yw.Geometry.CubicSpline2d(qp_pt_list));
}
///
/// 清除
///
public void Clear()
{
_qh_list.Clear();
_qp_list.Clear();
}
#endregion
///
/// 计算并联
///
///
///
///
///
public bool CalculateParallel(out List qh_pt_list, out List qe_pt_list, out List qp_pt_list)
{
qh_pt_list = qe_pt_list = qp_pt_list = null;
//求H的最大最小值
if (!CalculateMaxMinH())
return false;
//计算并联
return GetCurveParallel(out qh_pt_list, out qe_pt_list, out qp_pt_list);
}
///
/// 从并联曲线中分割出单泵曲线
///
///
///
///
public bool SeparateParallelQH(List connect_qh_pt_list, out List separate_qh_pt_list)
{
separate_qh_pt_list = new List();
_max_head = (from x in connect_qh_pt_list select x.Y).Max();
_min_head = (from x in connect_qh_pt_list select x.Y).Min();
int insert_num = 30;
double space = (_max_head - _min_head) / (insert_num - 1);
double head = _min_head;
int i = 0, j = 0;
for (j = 0; j < insert_num; j++)
{
//计算流量
var q_list = connect_qh_pt_list.GetInterPointsX(head)?.ToList();
if (q_list == null || q_list.Count() == 0)
{
continue;
}
var total_q = q_list.Last();
var is_insect = true;
for (i = 0; i < _qh_list.Count; i++)
{
var qh = _qh_list[i];
//计算流量
var q_list2 = qh.GetPointsX(head)?.ToList();
if (q_list2 == null || q_list2.Count == 0)
{
is_insect = false;
continue;
}
var last_q = q_list2.Last();
total_q = total_q - last_q;
}
//添加到列表
if (is_insect)
{
separate_qh_pt_list.Add(new Yw.Geometry.Point2d(total_q, head));
}
head = head + space;
}
if (separate_qh_pt_list.Count < 3)
{
separate_qh_pt_list = null;
return false;
}
separate_qh_pt_list = new Yw.Geometry.CubicSpline2d(separate_qh_pt_list).GetPointList(20);
return true;
}
//计算串联
public bool CalculateSeries(
out List qh_pt_list,
out List qe_pt_list,
out List qp_pt_list)
{
qh_pt_list = qe_pt_list = qp_pt_list = null;
//求Q的最大最小值
if (!CalculateMaxMinQ())
return false;
//计算并联
return GetCurveSeries(out qh_pt_list, out qe_pt_list, out qp_pt_list);
}
private bool CalculateMaxMinH()
{
if (_qh_list == null || _qh_list.Count() == 0)
return false;
foreach (var curves in _qh_list)
{
if (curves == null)
continue;
GetMinMaxPointYByRatio(curves, _extend_min_ratio, _extend_max_ratio, out double max_head, out double min_head);
this._min_head = Math.Max(min_head, this._min_head);
this._max_head = Math.Min(max_head, this._max_head);
return true;
}
return false;
}
private bool CalculateMaxMinQ()
{
if (_qh_list == null || _qh_list.Count() == 0)
return false;
foreach (var cubic_spline in _qh_list)
{
if (cubic_spline == null)
continue;
_min_flow = Math.Max(cubic_spline.MinX * _extend_min_ratio, _min_head);
_max_flow = Math.Min(cubic_spline.MaxX * _extend_max_ratio, _max_head);
}
if (_min_flow > _max_flow - 3)
return false;
else
return true;
}
//计算并联
private bool GetCurveParallel(out List qh_pt_list, out List qe_pt_list, out List qp_pt_list)
{
if (_qh_list == null || !_qh_list.Any())
{
qh_pt_list = null;
qe_pt_list = null;
qp_pt_list = null;
return false;
}
qh_pt_list = new List();
qe_pt_list = new List();
qp_pt_list = new List();
int insert_num = 30;
double space = (_max_head - _min_head) / (insert_num - 1);
double head = _min_head;
int i = 0, j = 0;
for (j = 0; j < insert_num; j++)
{
double total_q = 0;
double total_p = 0;
bool is_insect = true;
for (i = 0; i < _qh_list.Count(); i++)
{
Yw.Geometry.CubicSpline2d qh = _qh_list[i];
Yw.Geometry.CubicSpline2d qp = null;
if (_qp_list != null && _qp_list.Count > i)
qp = _qp_list[i];
//计算流量
var listQ = qh.GetPointsX(head);
if (listQ == null || listQ.Length == 0)
{
is_insect = false;
continue;
}
double Q = listQ.Last();
total_q = total_q + Q;
//计算功率
if (qp != null)
{
double p = qp.GetPointY(Q);
total_p = total_p + p;
}
}
//添加到列表
if (is_insect)
{
qh_pt_list.Add(new Yw.Geometry.Point2d(total_q, head));
if (total_p > 0.001)
{
qp_pt_list.Add(new Yw.Geometry.Point2d(total_q, total_p));
double E = PumpCalcHelper.CalculateE(total_q, head, total_p);
qe_pt_list.Add(new Yw.Geometry.Point2d(total_q, E));
}
}
head = head + space;
}
if (!qh_pt_list.Any())
{
return false;
}
//根据流量排序
Point2dComparer.Sort featPointComp = new Point2dComparer.Sort(Point2dComparer.eSortType.X);
qh_pt_list.Sort(featPointComp);
if (qe_pt_list != null && qe_pt_list.Count > 2)
qe_pt_list.Sort(featPointComp);
if (qp_pt_list != null && qp_pt_list.Count > 2)
qp_pt_list.Sort(featPointComp);
return true;
}
//计算串联
private bool GetCurveSeries(out List qh_pt_list, out List qe_pt_list, out List qp_pt_list)
{
if (_qh_list.Count() == 0)
{
qh_pt_list = null;
qe_pt_list = null;
qp_pt_list = null;
return false;
}
qh_pt_list = new List();
qe_pt_list = new List();
qp_pt_list = new List();
int insert_num = 30;
double space = (_max_flow - _min_flow) / (insert_num - 1);
double Q = _min_flow;
int i = 0, j = 0;
for (j = 0; j < insert_num; j++)
{
double total_h = 0;
double total_p = 0;
bool isInsect = true;
for (i = 0; i < _qh_list.Count(); i++)
{
Yw.Geometry.CubicSpline2d qh = _qh_list[i];
Yw.Geometry.CubicSpline2d qp = null;
if (_qp_list != null && _qp_list.Count > i)
qp = _qp_list[i];
//计算H
double h = qh.GetPointY(Q);
total_h = total_h + h;
//计算功率
if (qp != null)
{
double p = qp.GetPointY(Q);
total_p = total_p + p;
}
}
//添加到列表
if (isInsect)
{
qh_pt_list.Add(new Yw.Geometry.Point2d(Q, total_h));
if (total_p > 0.001)
{
qp_pt_list.Add(new Yw.Geometry.Point2d(Q, total_p));
double E = PumpCalcHelper.CalculateE(Q, total_h, total_p);
qe_pt_list.Add(new Yw.Geometry.Point2d(Q, E));
}
}
Q = Q + space;
}
//根据流量排序
Point2dComparer.Sort featPointComp = new Point2dComparer.Sort(Point2dComparer.eSortType.X);
qh_pt_list.Sort(featPointComp);
if (qe_pt_list != null && qe_pt_list.Count > 2)
qe_pt_list.Sort(featPointComp);
if (qp_pt_list != null && qp_pt_list.Count > 2)
qp_pt_list.Sort(featPointComp);
return true;
}
///
/// 获取拟合点(延长率):和GetFitPointsByExtend一模一样
///
public static List GetFitPointsByRatio(Yw.Geometry.CubicSpline2d express, double ratioExtendmin, double ratioExtendmax, int pointNumber)
{
if (express == null)
return default;
return express.GetPointListByXRange(express.MinX * ratioExtendmin, express.MaxX * ratioExtendmax, pointNumber);
}
//获取延长后 MaxY MinY
public static bool GetMinMaxPointYByRatio(Yw.Geometry.CubicSpline2d 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)
{
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;
}
}
}