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