using Yw.Geometry;
|
|
namespace Yw.WinFrmUI.Phart
|
{
|
/// <summary>
|
/// 串并联辅助类
|
/// </summary>
|
public class PumpParallelConnectionHelper
|
{
|
|
private List<Yw.Geometry.CubicSpline2d> _cubic_spline_qh_list = new List<Yw.Geometry.CubicSpline2d>();
|
private List<Yw.Geometry.CubicSpline2d> _cubic_spline_qp_list = new List<Yw.Geometry.CubicSpline2d>();
|
|
// 延长率, 默认不延长
|
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
|
|
/// <summary>
|
/// 添加
|
/// </summary>
|
/// <param name="cubic_spline_qh"></param>
|
/// <param name="cubic_spline_qp"></param>
|
public void Add(Yw.Geometry.CubicSpline2d cubic_spline_qh, Yw.Geometry.CubicSpline2d cubic_spline_qp)
|
{
|
if (cubic_spline_qh != null)
|
_cubic_spline_qh_list.Add(cubic_spline_qh);
|
|
if (cubic_spline_qp != null)
|
_cubic_spline_qp_list.Add(cubic_spline_qp);
|
}
|
|
/// <summary>
|
/// 添加
|
/// </summary>
|
/// <param name="pt_qh_list"></param>
|
/// <param name="pt_qp_list"></param>
|
public void Add(List<Yw.Geometry.Point2d> pt_qh_list, List<Yw.Geometry.Point2d> pt_qp_list)
|
{
|
if (pt_qh_list != null && pt_qh_list.Count > 3)
|
_cubic_spline_qh_list.Add(new Yw.Geometry.CubicSpline2d(pt_qh_list));
|
|
if (pt_qp_list != null && pt_qp_list.Count > 3)
|
_cubic_spline_qp_list.Add(new Yw.Geometry.CubicSpline2d(pt_qp_list));
|
}
|
|
/// <summary>
|
/// 清除
|
/// </summary>
|
public void Clear()
|
{
|
_cubic_spline_qh_list.Clear();
|
_cubic_spline_qp_list.Clear();
|
}
|
#endregion
|
|
/// <summary>
|
/// 计算并联
|
/// </summary>
|
/// <param name="pt_qh_list"></param>
|
/// <param name="pt_qe_list"></param>
|
/// <param name="pt_qp_list"></param>
|
/// <returns></returns>
|
public bool CalculateParallel(out List<Yw.Geometry.Point2d> pt_qh_list, out List<Yw.Geometry.Point2d> pt_qe_list, out List<Yw.Geometry.Point2d> pt_qp_list)
|
{
|
pt_qh_list = pt_qe_list = pt_qp_list = null;
|
//求H的最大最小值
|
if (!CalculateMaxMinH())
|
return false;
|
|
//计算并联
|
return GetCurveParallel(out pt_qh_list, out pt_qe_list, out pt_qp_list);
|
}
|
|
/// <summary>
|
/// 从并联曲线中分割出单泵曲线
|
/// </summary>
|
/// <param name="connect_pt_qh_list"></param>
|
/// <param name="separate_pt_qh_list"></param>
|
/// <returns></returns>
|
public bool SeparateParallelQH(List<Yw.Geometry.Point2d> connect_pt_qh_list, out List<Yw.Geometry.Point2d> separate_pt_qh_list)
|
{
|
separate_pt_qh_list = new List<Yw.Geometry.Point2d>();
|
|
_max_head = (from x in connect_pt_qh_list select x.Y).Max();
|
_min_head = (from x in connect_pt_qh_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_pt_qh_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 < _cubic_spline_qh_list.Count; i++)
|
{
|
var cubic_spline_qh = _cubic_spline_qh_list[i];
|
//计算流量
|
var q_list2 = cubic_spline_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_pt_qh_list.Add(new Yw.Geometry.Point2d(total_q, head));
|
}
|
|
head = head + space;
|
}
|
|
if (separate_pt_qh_list.Count < 3)
|
{
|
separate_pt_qh_list = null;
|
return false;
|
}
|
|
separate_pt_qh_list = new Yw.Geometry.CubicSpline2d(separate_pt_qh_list).GetPointList(20);
|
return true;
|
}
|
|
|
//计算串联
|
public bool CalculateSeries(
|
out List<Yw.Geometry.Point2d> pt_qh_list,
|
out List<Yw.Geometry.Point2d> pt_qe_list,
|
out List<Yw.Geometry.Point2d> pt_qp_list)
|
{
|
pt_qh_list = pt_qe_list = pt_qp_list = null;
|
//求Q的最大最小值
|
if (!CalculateMaxMinQ())
|
return false;
|
|
//计算并联
|
return GetCurveSeries(out pt_qh_list, out pt_qe_list, out pt_qp_list);
|
}
|
|
|
private bool CalculateMaxMinH()
|
{
|
if (_cubic_spline_qh_list == null || _cubic_spline_qh_list.Count() == 0)
|
return false;
|
foreach (var curves in _cubic_spline_qh_list)
|
{
|
if (curves == null)
|
continue;
|
GetMinMaxPointYByRatio(curves, _extend_min_ratio, _extend_max_ratio, out double maxH, out double minH);
|
this._min_head = Math.Max(minH, this._min_head);
|
this._max_head = Math.Min(maxH, this._max_head);
|
return true;
|
}
|
return false;
|
}
|
|
private bool CalculateMaxMinQ()
|
{
|
if (_cubic_spline_qh_list == null || _cubic_spline_qh_list.Count() == 0)
|
return false;
|
foreach (var cubic_spline in _cubic_spline_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<Yw.Geometry.Point2d> pt_qh_list, out List<Yw.Geometry.Point2d> pt_qe_list, out List<Yw.Geometry.Point2d> pt_qp_list)
|
{
|
if (_cubic_spline_qh_list == null || !_cubic_spline_qh_list.Any())
|
{
|
pt_qh_list = null;
|
pt_qe_list = null;
|
pt_qp_list = null;
|
return false;
|
}
|
|
pt_qh_list = new List<Yw.Geometry.Point2d>();
|
pt_qe_list = new List<Yw.Geometry.Point2d>();
|
pt_qp_list = new List<Yw.Geometry.Point2d>();
|
|
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 < _cubic_spline_qh_list.Count(); i++)
|
{
|
Yw.Geometry.CubicSpline2d cubic_spline_qh = _cubic_spline_qh_list[i];
|
Yw.Geometry.CubicSpline2d cubic_spline_qp = null;
|
if (_cubic_spline_qp_list != null && _cubic_spline_qp_list.Count > i)
|
cubic_spline_qp = _cubic_spline_qp_list[i];
|
|
//计算流量
|
var listQ = cubic_spline_qh.GetPointsX(head);
|
if (listQ == null || listQ.Length == 0)
|
{
|
is_insect = false;
|
continue;
|
}
|
double Q = listQ.Last();
|
total_q = total_q + Q;
|
|
//计算功率
|
if (cubic_spline_qp != null)
|
{
|
double p = cubic_spline_qp.GetPointY(Q);
|
total_p = total_p + p;
|
}
|
}
|
|
//添加到列表
|
if (is_insect)
|
{
|
pt_qh_list.Add(new Yw.Geometry.Point2d(total_q, head));
|
if (total_p > 0.001)
|
{
|
pt_qp_list.Add(new Yw.Geometry.Point2d(total_q, total_p));
|
|
double E = PumpCalcHelper.CalculateE(total_q, head, total_p);
|
pt_qe_list.Add(new Yw.Geometry.Point2d(total_q, E));
|
}
|
}
|
|
head = head + space;
|
}
|
|
//根据流量排序
|
Point2dComparer.Sort featPointComp = new Point2dComparer.Sort(Point2dComparer.eSortType.X);
|
pt_qh_list.Sort(featPointComp);
|
if (pt_qe_list != null && pt_qe_list.Count > 2)
|
pt_qe_list.Sort(featPointComp);
|
if (pt_qp_list != null && pt_qp_list.Count > 2)
|
pt_qp_list.Sort(featPointComp);
|
|
return true;
|
}
|
|
//计算串联
|
private bool GetCurveSeries(out List<Yw.Geometry.Point2d> pt_qh_list, out List<Yw.Geometry.Point2d> pt_qe_list, out List<Yw.Geometry.Point2d> pt_qp_list)
|
{
|
if (_cubic_spline_qh_list.Count() == 0)
|
{
|
pt_qh_list = null;
|
pt_qe_list = null;
|
pt_qp_list = null;
|
return false;
|
}
|
pt_qh_list = new List<Yw.Geometry.Point2d>();
|
pt_qe_list = new List<Yw.Geometry.Point2d>();
|
pt_qp_list = new List<Yw.Geometry.Point2d>();
|
|
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 < _cubic_spline_qh_list.Count(); i++)
|
{
|
Yw.Geometry.CubicSpline2d cubic_spline_qh = _cubic_spline_qh_list[i];
|
Yw.Geometry.CubicSpline2d cubic_spline_qp = null;
|
if (_cubic_spline_qp_list != null && _cubic_spline_qp_list.Count > i)
|
cubic_spline_qp = _cubic_spline_qp_list[i];
|
|
//计算H
|
double h = cubic_spline_qh.GetPointY(Q);
|
total_h = total_h + h;
|
|
//计算功率
|
if (cubic_spline_qp != null)
|
{
|
double p = cubic_spline_qp.GetPointY(Q);
|
total_p = total_p + p;
|
}
|
}
|
|
//添加到列表
|
if (isInsect)
|
{
|
pt_qh_list.Add(new Yw.Geometry.Point2d(Q, total_h));
|
if (total_p > 0.001)
|
{
|
pt_qp_list.Add(new Yw.Geometry.Point2d(Q, total_p));
|
|
double E = PumpCalcHelper.CalculateE(Q, total_h, total_p);
|
pt_qe_list.Add(new Yw.Geometry.Point2d(Q, E));
|
}
|
}
|
|
Q = Q + space;
|
}
|
|
//根据流量排序
|
Point2dComparer.Sort featPointComp = new Point2dComparer.Sort(Point2dComparer.eSortType.X);
|
pt_qh_list.Sort(featPointComp);
|
if (pt_qe_list != null && pt_qe_list.Count > 2)
|
pt_qe_list.Sort(featPointComp);
|
if (pt_qp_list != null && pt_qp_list.Count > 2)
|
pt_qp_list.Sort(featPointComp);
|
|
return true;
|
}
|
|
/// <summary>
|
/// 获取拟合点(延长率):和GetFitPointsByExtend一模一样
|
/// </summary>
|
public static List<Yw.Geometry.Point2d> 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;
|
}
|
|
|
}
|
}
|