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; } } }