namespace IStation.Curve { /// /// 串并联辅助类 /// public class ParallelConnectionHelper { // 计算曲线列表 private List _curveQhList = new List(); private List _curveQpList = new List(); // 延长率, 默认不延长 private double _extendMinRatio = 1; private double _extendMaxRatio = 1; //求Q的最大最小值 double minQ = 0, maxQ = 100000; //求H的最大最小值 double minH = 0, maxH = 100000; #region Curve /// /// 添加 /// /// /// public void AddCurve(CurveExpress curveQh, CurveExpress curveQp) { if (curveQh != null) _curveQhList.Add(curveQh); if (curveQp != null) _curveQpList.Add(curveQp); } /// /// 添加 /// /// /// public void AddCurve(List pointsQH, List pointsQP) { if (pointsQH != null && pointsQH.Count > 3) _curveQhList.Add(FitHelper.BuildCurveExpress(pointsQH, eFitType.CubicCurve)); if (pointsQP != null && pointsQP.Count > 3) _curveQpList.Add(FitHelper.BuildCurveExpress(pointsQH, eFitType.CubicCurve)); } /// /// 清除 /// public void ClearCurve() { this.minQ = 0; this.maxQ = 100000; this.minH = 0; this.maxH = 100000; _curveQhList.Clear(); _curveQpList.Clear(); } #endregion /// /// 计算并联 /// /// /// /// /// public bool CalculateParallel(out List pointQH, out List pointQE, out List pointQP) { pointQH = pointQE = pointQP = null; //求H的最大最小值 if (!CalculateMaxMinH()) return false; //计算并联 return GetCurveParallel(out pointQH, out pointQE, out pointQP); } /// /// 从并联曲线中分割出单泵曲线 /// /// /// /// public bool SeparateParallelQH(List connectPointsQH, out List separatePointsQH) { separatePointsQH = new List(); maxH = (from x in connectPointsQH select x.Y).Max(); minH = (from x in connectPointsQH select x.Y).Min(); int insert_num = 30; double space = (maxH - minH) / (insert_num - 1); double H = minH; int i = 0, j = 0; for (j = 0; j < insert_num; j++) { //计算流量 List listQ = FitHelper.GetInterPointX(connectPointsQH, H); if (listQ == null || listQ.Count == 0) { continue; } double totalQ = listQ.Last().X; bool isInsect = true; for (i = 0; i < _curveQhList.Count(); i++) { var currentQH = _curveQhList[i]; //计算流量 List listQ2 = FitHelper.GetInterPointX(currentQH, H); if (listQ2 == null || listQ2.Count == 0) { isInsect = false; continue; } double Q = listQ2.Last().X; totalQ = totalQ - Q; } //添加到列表 if (isInsect) { separatePointsQH.Add(new CurvePoint(totalQ, H)); } H = H + space; } if (separatePointsQH.Count < 3) { separatePointsQH = null; return false; } var express = FitHelper.BuildCurveExpress(separatePointsQH, eFitType.CubicCurve); separatePointsQH = FitHelper.GetFitPoints(express, 20); return true; } //计算串联 public bool CalculateSeries( out List pointsQH, out List pointsQE, out List pointsQP) { pointsQH = pointsQE = pointsQP = null; //求Q的最大最小值 if (!CalculateMaxMinQ()) return false; //计算并联 return GetCurveSeries(out pointsQH, out pointsQE, out pointsQP); } private bool CalculateMaxMinH() { if (_curveQhList == null || _curveQhList.Count() == 0) return false; foreach (var curves in _curveQhList) { if (curves == null) continue; double min_h = 0, max_h = 0; GetMinMaxPointYByRatio(curves, _extendMinRatio, _extendMaxRatio, out max_h, out min_h); this.minH = Math.Max(min_h, this.minH); this.maxH = Math.Min(max_h, this.maxH); } if (this.maxH * 0.99 < this.minH) return false; return true; } private bool CalculateMaxMinQ() { if (_curveQhList == null || _curveQhList.Count() == 0) return false; foreach (var curve in _curveQhList) { if (curve == null) continue; minQ = Math.Max(curve.Min * _extendMinRatio, minH); maxQ = Math.Min(curve.Max * _extendMaxRatio, maxH); } if (minQ > maxQ - 3) return false; else return true; } //计算并联 private bool GetCurveParallel(out List pointsQH, out List pointsQE, out List pointsQP) { if (_curveQhList == null || !_curveQhList.Any()) { pointsQH = null; pointsQE = null; pointsQP = null; return false; } pointsQH = new List(); pointsQE = new List(); pointsQP = new List(); int insert_num = 30; double space = (maxH - minH) / (insert_num - 1); double H = minH; int i = 0, j = 0; for (j = 0; j < insert_num; j++) { double totalQ = 0; double totalP = 0; bool isInsect = true; for (i = 0; i < _curveQhList.Count(); i++) { CurveExpress currentQH = _curveQhList[i]; CurveExpress currentQP = null; if (_curveQpList != null && _curveQpList.Count > i) currentQP = _curveQpList[i]; //计算流量 List listQ = FitHelper.GetInterPointX(currentQH, H); if (listQ == null || listQ.Count == 0) { isInsect = false; continue; } double Q = listQ.Last().X; totalQ = totalQ + Q; //计算功率 if (currentQP != null) { double p = FitHelper.GetFitPointY(currentQP, Q); totalP = totalP + p; } } //添加到列表 if (isInsect) { pointsQH.Add(new CurvePoint(totalQ, H)); if (totalP > 0.001) { pointsQP.Add(new CurvePoint(totalQ, totalP)); double E = PumpCalculateHelper.CalculateE(totalQ, H, totalP); pointsQE.Add(new CurvePoint(totalQ, E)); } } H = H + space; } //根据流量排序 CurvePointComparer.Sort featPointComp = new CurvePointComparer.Sort(CurvePointComparer.eSortType.X); pointsQH.Sort(featPointComp); if (pointsQE != null && pointsQE.Count > 2) pointsQE.Sort(featPointComp); if (pointsQP != null && pointsQP.Count > 2) pointsQP.Sort(featPointComp); return true; } //计算串联 private bool GetCurveSeries(out List pointsQH, out List pointsQE, out List pointsQP) { if (_curveQhList.Count() == 0) { pointsQH = null; pointsQE = null; pointsQP = null; return false; } pointsQH = new List(); pointsQE = new List(); pointsQP = new List(); int insert_num = 30; double space = (maxQ - minQ) / (insert_num - 1); double Q = minQ; int i = 0, j = 0; for (j = 0; j < insert_num; j++) { double totalH = 0; double totalP = 0; bool isInsect = true; for (i = 0; i < _curveQhList.Count(); i++) { CurveExpress currentQH = _curveQhList[i]; CurveExpress currentQP = null; if (_curveQpList != null && _curveQpList.Count > i) currentQP = _curveQpList[i]; //计算H double h = FitHelper.GetFitPointY(currentQH, Q); totalH = totalH + h; //计算功率 if (currentQP != null) { double p = FitHelper.GetFitPointY(currentQP, Q); totalP = totalP + p; } } //添加到列表 if (isInsect) { pointsQH.Add(new CurvePoint(Q, totalH)); if (totalP > 0.001) { pointsQP.Add(new CurvePoint(Q, totalP)); double E = PumpCalculateHelper.CalculateE(Q, totalH, totalP); pointsQE.Add(new CurvePoint(Q, E)); } } Q = Q + space; } //根据流量排序 CurvePointComparer.Sort featPointComp = new CurvePointComparer.Sort(CurvePointComparer.eSortType.X); pointsQH.Sort(featPointComp); if (pointsQE != null && pointsQE.Count > 2) pointsQE.Sort(featPointComp); if (pointsQP != null && pointsQP.Count > 2) pointsQP.Sort(featPointComp); return true; } /// /// 获取拟合点(延长率):和GetFitPointsByExtend一模一样 /// public static List GetFitPointsByRatio(CurveExpress express, double ratioExtendmin, double ratioExtendmax, int pointNumber) { if (express == null) return default; return express.GetFitPointsByXRange(express.Min * ratioExtendmin, express.Max * ratioExtendmax, pointNumber); } //获取延长后 MaxY MinY public static bool GetMinMaxPointYByRatio(CurveExpress 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 || !fitPoints.Any()) { 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; } } }