using Yw.Geometry;
namespace Yw.WinFrmUI.Phart
{
///
/// 串并联辅助类
///
public class PumpParallelConnectionHelper
{
private List _cubic_spline_qh_list = new List();
private List _cubic_spline_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 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);
}
///
/// 添加
///
///
///
public void Add(List pt_qh_list, List 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));
}
///
/// 清除
///
public void Clear()
{
_cubic_spline_qh_list.Clear();
_cubic_spline_qp_list.Clear();
}
#endregion
///
/// 计算并联
///
///
///
///
///
public bool CalculateParallel(out List pt_qh_list, out List pt_qe_list, out List 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);
}
///
/// 从并联曲线中分割出单泵曲线
///
///
///
///
public bool SeparateParallelQH(List connect_pt_qh_list, out List separate_pt_qh_list)
{
separate_pt_qh_list = new List();
_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 pt_qh_list,
out List pt_qe_list,
out List 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 pt_qh_list, out List pt_qe_list, out List 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();
pt_qe_list = new List();
pt_qp_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 < _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 pt_qh_list, out List pt_qe_list, out List 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();
pt_qe_list = new List();
pt_qp_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 < _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;
}
///
/// 获取拟合点(延长率):和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;
}
}
}