namespace IStation.Algorithm { /// /// 调度分析(核心算法) /// public class ScheduleCalc { double _frequency_def = 50; double _frequency_min = 25; double _frequency_max = 50; double _frequency_space = 0.1;//频率间隔 public bool CalcOptList(List pumps) { if (pumps == null || pumps.Count < 1) return false; #region 获取并预算一下 var fixPumpCalcList = new List();//固频泵 var frePumpCalcList = new List();//变频泵 foreach (var pump in pumps) { if (pump.IsBp) { //变频泵 var calcModel = new PumpCalcModel(pump, _frequency_min, _frequency_max, _frequency_space); if (calcModel.AllowCalc) frePumpCalcList.Add(calcModel); } else { //固频泵 var calcModel = new PumpCalcModel(pump); if (calcModel.AllowCalc) fixPumpCalcList.Add(calcModel); } } #endregion var pumpCount = pumps.Count; for (int runCount = 1; runCount <= 8; runCount++) { var arr = Combination(pumps, runCount); pump_combine.Add(arr.ToList()); } #region 开始分析 if (fixPumpCalcList == null || fixPumpCalcList.Count() == 0) { //没有合适的固频泵 var array = frePumpCalcList.ToArray(); AddOnlyFrePumpPrj(array); } else { //分析没有变频泵开启的情况 AddOnlyFrePumpPrj(frePumpCalcList.ToArray()); //分析有固频泵开启的情况 for (int fixPumpNum = 1; fixPumpNum <= fixPumpCalcList.Count(); fixPumpNum++) { //得到所有排列组合(工频) List fixPumpAnaCombineList = ISupply.Model.PermutationAndCombination.GetCombination( fixPumpCalcList.ToArray(), fixPumpNum); #region 分析每种组合 foreach (ISupply.WinFrmUI.Epanet.Dispatch.Model.FixPumpAnaData[] fixPumpAnaCombine in fixPumpAnaCombineList) { //遍历各种工频组合 #region 检查是否符合开机约束 List machine_ids = new List(); if (fixPumpAnaCombine != null) { foreach (var item in fixPumpAnaCombine) machine_ids.Add(item.MachineDetail.MachineID); } if (!IsAccordMachineRunFilter(machine_ids)) { continue; } #endregion var fix_pump_total_flow = (from x in fixPumpAnaCombine select x.AnaItem50Hz.WorkPointQ).Sum(); if (fix_pump_total_flow > _targetQmax) { continue; } if (fix_pump_total_flow > _targetQmin) {//只用固频泵即可 AddOnlyFixPumpPrj(fixPumpAnaCombine, fix_pump_total_flow); } else if (frePumpCalcList.Count() > 0) { //只有一台变频泵 AddSingleFreqPumpPrj1(fixPumpAnaCombine, frePumpCalcList.ToArray()); //有2台变频泵 if (frePumpCalcList.Count() >= 2) { AddMultiFreqPumpPrj2(fixPumpAnaCombine, frePumpCalcList.ToArray()); } //有3台变频泵 if (frePumpCalcList.Count() >= 3) { AddMultiFreqPumpPrj3(fixPumpAnaCombine, frePumpCalcList.ToArray()); } //有4台变频泵 if (frePumpCalcList.Count() >= 4) { AddMultiFreqPumpPrj4(fixPumpAnaCombine, frePumpCalcList.ToArray(), fix_pump_total_flow); } //有5台变频泵 if (frePumpCalcList.Count() >= 5) { AddMultiFreqPumpPrj5(fixPumpAnaCombine, frePumpCalcList.ToArray(), fix_pump_total_flow); } } } #endregion } } #endregion //计算 var ds_disp_project_list = new List(); foreach (var project in _anaSchemeList) { //计算流量 //project.TotalWrkQ = (from x in project.Items where x.WorkPointQ > 0 select x.WorkPointQ).Sum(); if (project.TotalWrkQ <= _targetQmax && project.TotalWrkQ >= this._targetQmin) ds_disp_project_list.Add(project); project.UWP = Math.Round(project.UWP, 3); project.WP = Math.Round(project.WP, 3); project.SpanQ = Math.Round(project.TotalWrkQ - _targetQ, 0); project.CalcItemParas(); } // 0 功率 1 流量间隔 if (SchemeSortType == ISupply.WinFrmUI.Epanet.Dispatch.Model.eAnaSchemeSortType.功率) ds_disp_project_list = (from x in ds_disp_project_list orderby x.TotalWrkP select x).ToList(); else if (SchemeSortType == ISupply.WinFrmUI.Epanet.Dispatch.Model.eAnaSchemeSortType.流量差值) ds_disp_project_list = (from x in ds_disp_project_list orderby Math.Abs(x.SpanQ) select x).ToList(); //重新编号ID for (int i = 0; i < ds_disp_project_list.Count; i++) { ds_disp_project_list[i].ID = i + 1; } if (ReturnSchemeNumber <= 0) return ds_disp_project_list; else return ds_disp_project_list.Take(ReturnSchemeNumber).ToList(); } #region 算出是否符合的固频泵:GetFixPumpAnaData privatePumpCalcModel GetFixPumpAnaData(ISupply.WinFrmUI.Epanet.Dispatch.Model.MachineDetailEx Machine) { if (Machine == null) return null; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem anaData = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem(); if (CalcAnaCurve(Machine.MaxCurveInfoQH, Machine.MaxCurveInfoQP, this._targetH, 50, Machine.Percentage, ref anaData) <= 0) return null; anaData.CurveInfoQH = Machine.MaxCurveInfoQH; anaData.CurveInfoQP = Machine.MaxCurveInfoQP; anaData.Frequence = 50; anaData.Speed = Machine.RatedN; return newPumpCalcModel() { MachineDetail = Machine, AnaItem50Hz = anaData }; } #endregion #region 算出是否符合的变频泵:GetFrePumpAnaData privatePumpCalcModel GetFrePumpAnaData( ISupply.WinFrmUI.Epanet.Dispatch.Model.MachineDetailEx Machine) { if (Machine == null) return null; PumpCalcModel anaData = newPumpCalcModel(); anaData.MachineDetail = Machine; anaData.AnaItemList = new List(); double targetH = this._targetH; double maxH; double minH; var points50 = ISupply.Model.FitCurveHelper.GetFitPoints(Machine.MaxCurveInfoQH, 50); ISupply.Model.FitCurveHelper.GetMinMaxPointY(points50, out maxH, out minH); if (maxH < targetH) { return null; } var pointsMin = ISupply.Common.SpeedSimuCalculer.GetSimuPointQH(Machine.MaxCurveInfoQH, 50, MinChangeFrequence); ISupply.Model.FitCurveHelper.GetMinMaxPointY(pointsMin, out maxH, out minH); if (minH > targetH) { return null; } //获取每个频率的值(粗算) for (double freqCurrentFrequ = 50; freqCurrentFrequ > MinChangeFrequence; freqCurrentFrequ = freqCurrentFrequ - ChangeFrequenceSpaece) { ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curve = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem(); int ret = CalcAnaCurve(Machine.MaxCurveInfoQH, Machine.MaxCurveInfoQP, this._targetH, freqCurrentFrequ, Machine.Percentage, ref curve); if (ret == -1) break;//-1 表示最大扬程都已经低于目标扬程了, 没必要再迭代了 if (ret == 0) continue; curve.Speed = Machine.CalcSpeedByFrequence(curve.Frequence); anaData.AnaItemList.Add(curve); } return anaData; } #endregion #region 精算 private void CalcDetailAccurate(ref ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaScheme project) { //没有变频泵, 就没有必要精算 var frequecePumps = (from x in project.Items where x.IsFrequency select x); if (frequecePumps == null || frequecePumps.Count() == 0) return; if (frequecePumps.Count() == 1) {//只有一台,比较简单 #region 只有一台,比较简单 ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem current_adjust_item = frequecePumps.FirstOrDefault(); var current_machine = (from x in this._allMachineList where x.MachineID == current_adjust_item.MachineID select x).FirstOrDefault(); if (current_machine == null) return; var totalWrkQ_other = (from x in project.Items where x.WorkPointQ > 0 && x.MachineID != current_adjust_item.MachineID select x.WorkPointQ).Sum(); // var target_pump_flow = this._targetQ - totalWrkQ_other; var max_fr = Math.Min(50, current_adjust_item.Frequence + ChangeFrequenceSpaece * 2); var min_fr = current_adjust_item.Frequence - ChangeFrequenceSpaece * 2; double flow_chajiu = Math.Abs(project.TotalWrkQ - this._targetQ); for (double fre = max_fr; fre > min_fr; fre = fre - 0.1) { ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem ana_item = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem(); int ret = CalcAnaCurve(current_machine.MaxCurveInfoQH, current_machine.MaxCurveInfoQP, this._targetH, fre, current_machine.Percentage, ref ana_item); if (ret == -1) return;//-1 表示最大扬程都已经低于目标扬程了, 没必要再迭代了 if (ret == 0) continue; var total_q = totalWrkQ_other + ana_item.WorkPointQ; if (total_q < this._targetQmin) break;//如果已经低于最小,不用再变频了 if (Math.Abs(total_q - this._targetQ) < flow_chajiu) { flow_chajiu = Math.Abs(total_q - this._targetQ); current_adjust_item.Frequence = Math.Round(fre, 1); current_adjust_item.WorkPointQ = Math.Round(ana_item.WorkPointQ, 1); current_adjust_item.WorkPointP = Math.Round(ana_item.WorkPointP, 1); // 再汇总一下 project.TotalWrkQ = (from x in project.Items where x.WorkPointQ > 0 select x.WorkPointQ).Sum(); project.TotalWrkP = (from x in project.Items where x.WorkPointP > 0 select x.WorkPointP).Sum(); project.UWP = Calcu_UWP(project.TotalWrkP, project.TotalWrkQ, this._targetH); project.WP = Calcu_WP(project.TotalWrkP, project.TotalWrkQ); } if (total_q < this._targetQ) { break; } } #endregion } else if (frequecePumps.Count() == 2) { ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem adjust_item_1 = frequecePumps.ElementAt(0); ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem adjust_item_2 = frequecePumps.ElementAt(1); var adjust_machine_1 = (from x in this._allMachineList where x.MachineID == adjust_item_1.MachineID select x).FirstOrDefault(); if (adjust_machine_1 == null) return; var adjust_machine_2 = (from x in this._allMachineList where x.MachineID == adjust_item_2.MachineID select x).FirstOrDefault(); if (adjust_machine_2 == null) return; //除了调解泵的其他泵流量 var total_flow_other = (from x in project.Items where x.WorkPointQ > 0 && x.MachineID != adjust_machine_1.MachineID && x.MachineID != adjust_machine_2.MachineID select x.WorkPointQ).Sum(); var total_power_other = (from x in project.Items where x.WorkPointP > 0 && x.MachineID != adjust_machine_1.MachineID && x.MachineID != adjust_machine_2.MachineID select x.WorkPointP).Sum(); List item_js_1 = new List(); for (double fre = Math.Min(50, adjust_item_1.Frequence + ChangeFrequenceSpaece * 2); fre > adjust_item_1.Frequence - ChangeFrequenceSpaece * 2; fre = fre - 0.1) { ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem ana_item = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem(); int ret = CalcAnaCurve(adjust_machine_1.MaxCurveInfoQH, adjust_machine_1.MaxCurveInfoQP, this._targetH, fre, adjust_machine_1.Percentage, ref ana_item); if (ret == -1) break; item_js_1.Add(ana_item); } List item_js_2 = new List(); for (double fre = Math.Min(50, adjust_item_2.Frequence + ChangeFrequenceSpaece * 2); fre > adjust_item_2.Frequence - ChangeFrequenceSpaece * 2; fre = fre - 0.1) { ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem ana_item = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem(); int ret = CalcAnaCurve(adjust_machine_2.MaxCurveInfoQH, adjust_machine_2.MaxCurveInfoQP, this._targetH, fre, adjust_machine_2.Percentage, ref ana_item); if (ret == -1) break; item_js_2.Add(ana_item); } double ump_chajiu = project.UWP; foreach (var item1 in item_js_1) { foreach (var item2 in item_js_2) { var total_flow = item1.WorkPointQ + item2.WorkPointQ + total_flow_other; if (Math.Abs(total_flow - this._targetQ) < this._targetQ * 0.01) { var total_power = item1.WorkPointP + item2.WorkPointP + total_power_other; var uwp = Calcu_UWP(total_power, total_flow, this._targetH); if (uwp < ump_chajiu) { adjust_item_1.ResetItem(item1); adjust_item_2.ResetItem(item2); adjust_item_1.Frequence = Math.Round(item1.Frequence, 1); adjust_item_2.Frequence = Math.Round(item2.Frequence, 1); // 再汇总一下 project.TotalWrkQ = (from x in project.Items where x.WorkPointQ > 0 select x.WorkPointQ).Sum(); project.TotalWrkP = (from x in project.Items where x.WorkPointP > 0 select x.WorkPointP).Sum(); project.UWP = Calcu_UWP(project.TotalWrkP, project.TotalWrkQ, this._targetH); project.WP = Calcu_WP(project.TotalWrkP, project.TotalWrkQ); } } } } } else { //哪个泵流量大,就调整哪个泵 ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem aj_pump = frequecePumps.FirstOrDefault(); foreach (var p in project.Items) { if (!p.IsFrequency) continue; if (p.WorkPointQ > aj_pump.WorkPointQ) { aj_pump = p; } } //除了调解泵的其他泵流量 var total_flow_other = (from x in project.Items where x.WorkPointQ > 0 && x.MachineID != aj_pump.MachineID select x.WorkPointQ).Sum(); // double flow_chajiu = Math.Abs(project.TotalWrkQ - this._targetQ); // var pump_curve = (from x in this._allMachineList where x.MachineID == aj_pump.MachineID select x).FirstOrDefault(); if (pump_curve != null) { var max_fr = Math.Min(50, aj_pump.Frequence + ChangeFrequenceSpaece * 2); var min_fr = aj_pump.Frequence - ChangeFrequenceSpaece * 2; for (double fre = max_fr; fre > min_fr; fre = fre - 0.1) { ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curve = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem(); int ret = CalcAnaCurve(pump_curve.MaxCurveInfoQH, pump_curve.MaxCurveInfoQP, this._targetH, fre, pump_curve.Percentage, ref curve); if (ret == -1) break;//-1 表示最大扬程都已经低于目标扬程了, 没必要再迭代了 if (ret == 0) continue; var total_q = total_flow_other + curve.WorkPointQ; if (total_q < this._targetQmin) break;//如果已经低于最小,不用再变频了 if (Math.Abs(total_q - this._targetQ) < flow_chajiu) { flow_chajiu = Math.Abs(total_q - this._targetQ); aj_pump.Frequence = Math.Round(fre, 1); aj_pump.WorkPointQ = Math.Round(curve.WorkPointQ, 1); aj_pump.WorkPointP = Math.Round(curve.WorkPointP, 1); //再汇总一下 project.TotalWrkQ = (from x in project.Items where x.WorkPointQ > 0 select x.WorkPointQ).Sum(); project.TotalWrkP = (from x in project.Items where x.WorkPointP > 0 select x.WorkPointP).Sum(); project.UWP = Calcu_UWP(project.TotalWrkP, project.TotalWrkQ, this._targetH); project.WP = Calcu_WP(project.TotalWrkP, project.TotalWrkQ); } if (total_q < this._targetQ) { break; } } } } } #endregion #region 根据频率值,计算变频曲线 /// /// 根据频率值,计算变频曲线(外部也会调用) /// /// /// /// /// /// /// public static int CalcAnaCurve( ISupply.Model.CurveExpress MaxCurveInfoQH, ISupply.Model.CurveExpress MaxCurveInfoQP, double targetH, double freqCurrentFrequ,//频率值 double extendMaxRatio, ref ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem ana_data) { if (ana_data == null) ana_data = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem(); if (freqCurrentFrequ >= 49.9) { ana_data.Frequence = freqCurrentFrequ; ana_data.CurveInfoQH = MaxCurveInfoQH; ana_data.CurveInfoQP = MaxCurveInfoQP; double flow = 0; var pointsQH = ISupply.Model.FitCurveHelper.GetFitPointsByExtend(ana_data.CurveInfoQH, extendMaxRatio, 50); if (!GetFolwByHead(pointsQH, targetH, ref flow)) { ana_data.IsOverMaxH = true; ana_data.Note = "已超出最大可行的流量"; return 0; } flow = Math.Round(flow, 1); var head = ISupply.Model.FitCurveHelper.GetFitPointY(ana_data.CurveInfoQH, Math.Round(flow, 1)); head = Math.Round(head, 1); ana_data.WorkPointQ = flow; ana_data.WorkPointH = head; ana_data.WorkPointP = Math.Round(ISupply.Model.FitCurveHelper.GetFitPointY(ana_data.CurveInfoQP, ana_data.WorkPointQ), 1); ana_data.WorkPointE = Math.Round(ISupply.Common.PumpParaHelper.CalculateE(ana_data.WorkPointQ, ana_data.WorkPointH, ana_data.WorkPointP), 1); ana_data.IsExtendCurve = false; if (flow > ana_data.CurveInfoQH.Max) {//在延长线上 ana_data.IsExtendCurve = true; ana_data.RatioExtend = extendMaxRatio; //延长率 double extRatioQ = Math.Round(flow * 100 / ana_data.CurveInfoQH.Max, 1); ana_data.Note = string.Format("在延长曲线部分,参数可能不准确,延长率为:{0:0.0}", extRatioQ); } return 1; } else { #region 变频 ana_data.Frequence = Math.Round(freqCurrentFrequ, 1); ana_data.CurveInfoQH = ISupply.Common.SpeedSimuCalculer.GetSimuPointQH(MaxCurveInfoQH, 50, ana_data.Frequence); ana_data.CurveInfoQP = ISupply.Common.SpeedSimuCalculer.GetSimuPointQP(MaxCurveInfoQP, 50, ana_data.Frequence); double flow = 0; var pointsQH = ISupply.Model.FitCurveHelper.GetFitPointsByExtend(ana_data.CurveInfoQH, extendMaxRatio, 50); if (!GetFolwByHead(pointsQH, targetH, ref flow)) { ana_data.IsOverMaxH = true; ana_data.Note = "已超出最大可行的流量"; return 0; } flow = Math.Round(flow, 1); var head = ISupply.Model.FitCurveHelper.GetFitPointY(ana_data.CurveInfoQH, Math.Round(flow, 1)); head = Math.Round(head, 1); ana_data.WorkPointQ = flow; ana_data.WorkPointH = head; ana_data.WorkPointP = Math.Round(ISupply.Model.FitCurveHelper.GetFitPointY(ana_data.CurveInfoQP, ana_data.WorkPointQ), 1); ana_data.WorkPointE = Math.Round(ISupply.Common.PumpParaHelper.CalculateE(ana_data.WorkPointQ, ana_data.WorkPointH, ana_data.WorkPointP), 1); ana_data.IsExtendCurve = false; if (flow > ana_data.CurveInfoQH.Max) {//在延长线上 ana_data.IsExtendCurve = true; ana_data.RatioExtend = extendMaxRatio; //延长率 double extRatioQ = Math.Round(flow * 100 / ana_data.CurveInfoQH.Max, 1); ana_data.Note = string.Format("在延长曲线部分,参数可能不准确,延长率为:{0:0.0}", extRatioQ); } #endregion return 1; } } //根据压差计算流量 //private static double OtherPressCoeff = 4 * 1000 / Math.PI / 3.6; /// /// /// /// /// /// /// public static bool GetFolwByHead(List curveInfoQH, double h, ref double q) { List listQ = ISupply.Model.FitCurveHelper.GetInterPointX(curveInfoQH, h); if (listQ == null || listQ.Count == 0) { return false; } q = listQ.Last().X; return true; } /// /// 根据频率值,计算变频曲线 /// /// /// /// /// /// public static int CalcAnaCurveDDD( ISupply.Model.CurveExpress MaxCurveInfoQH, double targetH, double freqCurrentFrequ,//频率值 double extendMaxRatio, ref ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curve) { if (curve == null) curve = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem(); if (freqCurrentFrequ >= 49.9) { curve.Frequence = freqCurrentFrequ; curve.CurveInfoQH = MaxCurveInfoQH; double maxH; double minH; var points = ISupply.Model.FitCurveHelper.GetFitPointsByExtend(curve.CurveInfoQH, extendMaxRatio, 50); ISupply.Model.FitCurveHelper.GetMinMaxPointY(points, out maxH, out minH); if (maxH < targetH) { curve.IsOverMaxH = true; curve.Note = "已超出最大运行扬程"; return -1;//-1 表示最大扬程都已经低于目标扬程了, 没必要再迭代了 } List interPts = ISupply.Model.FitCurveHelper.GetInterPointX(points, targetH); if (interPts == null || interPts.Count == 0) { curve.IsOverMaxH = true; curve.Note = "已超出最大可行的流量"; return 0; } ISupply.Model.CurvePoint pt = interPts.Last(); if (pt.X < MinFlowIngore) { curve.IsOverMaxH = true; curve.Note = "已超出最大可行的流量"; return -1; } curve.IsExtendCurve = false; curve.WorkPointQ = Math.Round(pt.X, 1); curve.WorkPointH = Math.Round(pt.Y, 1); if (pt.X > curve.CurveInfoQH.Max) {//在延长线上 curve.IsExtendCurve = true; curve.RatioExtend = extendMaxRatio; //延长率 double extRatioQ = Math.Round(pt.X * 100 / curve.CurveInfoQH.Max, 1); curve.Note = string.Format("在延长曲线部分,参数可能不准确,延长率为:{0:0.0}", extRatioQ); //效率延长不稳定 //if (anaData.CurveInfoQP != null) //{ // var exPointsQP = ISupply.Model.FitCurveHelper.GetFitPointsByExtend(anaData.CurveInfoQP, ExtendMaxRatio, 50);//延长 // anaData.WorkPointP = Math.Round(ISupply.Model.FitCurveHelper.GetFitPointY(exPointsQP, anaData.WorkPointQ), 1); // anaData.WorkPointE = ISupply.Common.PumpParaHelper.CalculateE(anaData.WorkPointQ, anaData.WorkPointH, anaData.WorkPointP); //} } else { curve.IsExtendCurve = false; } return 1; } else { #region 变频 curve.Frequence = freqCurrentFrequ; curve.CurveInfoQH = ISupply.Common.SpeedSimuCalculer.GetSimuPointQH(MaxCurveInfoQH, 50, freqCurrentFrequ); var points = ISupply.Model.FitCurveHelper.GetFitPointsByExtend(curve.CurveInfoQH, extendMaxRatio, 50);//延长 //ISupply.Model.FitCurveHelper.GetMinMaxPointY(points, out maxH, out minH); List extPtsQH = ISupply.Model.FitCurveHelper.GetInterPointX(points, targetH); if (extPtsQH == null || extPtsQH.Count == 0) {//在延长线都没有交点,就不要再迭代了. if (targetH > curve.CurveInfoQH.Index0) return -1;//-1 表示最大扬程都已经低于目标扬程了, 没必要再迭代了 return 0; } ISupply.Model.CurvePoint pt = extPtsQH.Last(); if (pt.X < MinFlowIngore) { return -1; } curve.IsExtendCurve = false; curve.WorkPointQ = Math.Round(pt.X, 1); curve.WorkPointH = Math.Round(pt.Y, 1); if (pt.X > curve.CurveInfoQH.Max) {//在延长线上 curve.IsExtendCurve = true; curve.RatioExtend = extendMaxRatio; //延长率 double extRatioQ = Math.Round(pt.X * 100 / curve.CurveInfoQH.Max, 1); curve.Note = string.Format("在延长曲线部分,参数可能不准确,延长率为:{0:0.0}", extRatioQ); //if (MaxCurveInfoQP != null) //{ // curve.CurveInfoQP = ISupply.Common.SpeedSimuCalculer.GetSimuPointQP(MaxCurveInfoQP, 50, freqCurrentFrequ); // var exPointsQP = ISupply.Model.FitCurveHelper.GetFitPointsByExtend(curve.CurveInfoQP, ExtendMaxRatio, 50);//延长 // curve.WorkPointP = Math.Round(ISupply.Model.FitCurveHelper.GetFitPointY(exPointsQP, curve.WorkPointQ), 1); // curve.WorkPointE = ISupply.Common.PumpParaHelper.CalculateE(curve.WorkPointQ, curve.WorkPointH, curve.WorkPointP); //} } else { curve.IsExtendCurve = false; //if (MaxCurveInfoQP != null) //{ // curve.CurveInfoQP = ISupply.Common.SpeedSimuCalculer.GetSimuPointQP(MaxCurveInfoQP, 50, freqCurrentFrequ); // curve.WorkPointP = Math.Round(ISupply.Model.FitCurveHelper.GetFitPointY(curve.CurveInfoQP, curve.WorkPointQ), 1); // curve.WorkPointE = ISupply.Common.PumpParaHelper.CalculateE(curve.WorkPointQ, curve.WorkPointH, curve.WorkPointP); //} } #endregion return 1; } } #endregion #region 添加项目 (只有用固频泵) private ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaScheme AddOnlyFixPumpPrj( PumpCalcModel[] fixPumpAnaDataList, double totalQ) { // var rowPrj = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaScheme(); rowPrj.TotalWrkQ = totalQ; rowPrj.TotalWrkH = Math.Round(this._targetH, 2); rowPrj.Items = new List(); foreach (var fixPump in fixPumpAnaDataList) { if (fixPump.AnaItem50Hz.WorkPointQ < 1) continue; var itemRow = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(fixPump.MachineDetail, fixPump.AnaItem50Hz); rowPrj.Items.Add(itemRow); } AddScheme(rowPrj, false); return rowPrj; } #endregion #region 添加项目 只有用变频频泵即可 private void AddOnlyFrePumpPrj( PumpCalcModel[] frePumpAnaList) { AddSingleFreqPumpPrj1(null, frePumpAnaList); //有2台变频泵 if (frePumpAnaList.Count() >= 2) { AddMultiFreqPumpPrj2(null, frePumpAnaList); } //有3台变频泵 if (frePumpAnaList.Count() >= 3) { AddMultiFreqPumpPrj3(null, frePumpAnaList); } //有4台变频泵 if (frePumpAnaList.Count() >= 4) { AddMultiFreqPumpPrj4(null, frePumpAnaList, 0); } //有5台变频泵 if (frePumpAnaList.Count() >= 5) { AddMultiFreqPumpPrj5(null, frePumpAnaList, 0); } } #endregion #region 添加项目 只有1台变频泵:AddOneFreqPumpPrj private int AddSingleFreqPumpPrj1(double targetHead, PumpCalcModel[] fixPumpCalcList, PumpCalcModel[] frePumpCalcList) { if (frePumpCalcList == null || frePumpCalcList.Length == 0) return 0; double fix_pump_total_flow = 0; if (fixPumpCalcList != null) { fix_pump_total_flow = (from x in fixPumpCalcList select x.AnaItem50Hz.WorkPointQ).Sum(); } if (fix_pump_total_flow >= this._targetQ * 0.99) return 0; int addPrjNum = 0; foreach (var freqPump in frePumpCalcList) { #region 检查是否符合开机约束 List machine_ids = new List(); machine_ids.Add(freqPump.MachineDetail.MachineID); if (fixPumpCalcList != null) { foreach (var item in fixPumpCalcList) machine_ids.Add(item.MachineDetail.MachineID); } if (!IsAccordMachineRunFilter(machine_ids)) { continue; } #endregion double h = Math.Round(this._targetH, 2); var wrkSpeed = ISupply.Common.SpeedSimuCalculer.GetSimuValue( freqPump.MachineDetail.MaxCurveInfoQH, new ISupply.Model.CurvePoint(_targetQ - fix_pump_total_flow, h), 2900); ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem currentAna = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem(); double fre = Math.Round(50 * wrkSpeed / 2900, 1); if (fre > 50) { fre = 50; } int ret = CalcAnaCurve(freqPump.MachineDetail.MaxCurveInfoQH, freqPump.MachineDetail.MaxCurveInfoQP, this._targetH, fre, freqPump.MachineDetail.Percentage, ref currentAna); if (ret == -1) continue; if (ret == 0) continue; currentAna.Speed = freqPump.MachineDetail.CalcSpeedByFrequence(fre); var rowPrj = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaScheme(); rowPrj.Items = new List(); #region 加入固频泵开启信息 if (fixPumpCalcList != null) { foreach (var fixPump in fixPumpCalcList) { if (fixPump.AnaItem50Hz.WorkPointQ < 1) continue; var itemRow = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(fixPump.MachineDetail, fixPump.AnaItem50Hz); rowPrj.Items.Add(itemRow); } } #endregion var itemRowF = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump.MachineDetail, currentAna); rowPrj.Items.Add(itemRowF); AddScheme(rowPrj, false); addPrjNum++; } return addPrjNum; } #endregion #region 添加项目 只有2台变频泵:AddTwoFreqPumpPrj private int AddMultiFreqPumpPrj2( PumpCalcModel[] fixPumpCalcList, PumpCalcModel[] allFreqPumpAnaList) { int addPrjNum = 0; int frePumpNum = 2; if (allFreqPumpAnaList == null || allFreqPumpAnaList.Count() < frePumpNum) return addPrjNum; //判断最大开机数 if (_max_open_machine_number > 0) { int macine_number = 2; if (fixPumpCalcList != null) { macine_number = macine_number + fixPumpCalcList.Count(); } if (macine_number > _max_open_machine_number) return 0; } double fix_pump_total_flow = 0; if (fixPumpCalcList != null) { fix_pump_total_flow = (from x in fixPumpCalcList select x.AnaItem50Hz.WorkPointQ).Sum(); } var freqPumpAnaCombineList = ISupply.Model.PermutationAndCombination. GetCombination(allFreqPumpAnaList, frePumpNum); foreach (var freqPumpAnaCombine in freqPumpAnaCombineList) { var freqPump1 = freqPumpAnaCombine[0]; var freqPump2 = freqPumpAnaCombine[1]; #region 检查是否符合开机约束 List machine_ids = new List { freqPump1.MachineDetail.MachineID, freqPump2.MachineDetail.MachineID }; if (fixPumpCalcList != null) { foreach (var item in fixPumpCalcList) machine_ids.Add(item.MachineDetail.MachineID); } if (!IsAccordMachineRunFilter(machine_ids)) { continue; } #endregion ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData1 = null; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData2 = null; var rowPrj = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaScheme(); rowPrj.Items = new List(); #region 加入固频泵开启信息 if (fixPumpCalcList != null) { foreach (var fixPump in fixPumpCalcList) { if (fixPump.AnaItem50Hz.WorkPointQ < 1) continue; var itemRow = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(fixPump.MachineDetail, fixPump.AnaItem50Hz); rowPrj.Items.Add(itemRow); } } #endregion bool isActCalc = true; if (freqPump1.MachineDetail.PumpCode == freqPump2.MachineDetail.PumpCode) { //同型号 #region 流量对半分 var fre_pump_total_flow = this._targetQ - fix_pump_total_flow; isActCalc = false; double h = Math.Round(this._targetH, 2); //流量对半分 var wrkSpeed1 = ISupply.Common.SpeedSimuCalculer.GetSimuValue(freqPump1.MachineDetail.MaxCurveInfoQH, new ISupply.Model.CurvePoint((_targetQ - fix_pump_total_flow) * 0.5, h), 2900); curveData1 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem(); double fre1 = Math.Round(50 * wrkSpeed1 / 2900, 1); int ret1 = CalcAnaCurve(freqPump1.MachineDetail.MaxCurveInfoQH, freqPump1.MachineDetail.MaxCurveInfoQP, this._targetH, fre1, freqPump1.MachineDetail.Percentage, ref curveData1); if (ret1 == -1) continue; if (ret1 == 0) continue; curveData1.Speed = freqPump1.MachineDetail.CalcSpeedByFrequence(fre1); var wrkSpeed2 = ISupply.Common.SpeedSimuCalculer.GetSimuValue(freqPump2.MachineDetail.MaxCurveInfoQH, new ISupply.Model.CurvePoint((_targetQ - fix_pump_total_flow) * 0.5, h), 2900); curveData2 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem(); double fre2 = Math.Round(50 * wrkSpeed2 / 2900, 1); int ret2 = CalcAnaCurve(freqPump2.MachineDetail.MaxCurveInfoQH, freqPump2.MachineDetail.MaxCurveInfoQP, this._targetH, fre2, freqPump2.MachineDetail.Percentage, ref curveData2); if (ret2 == -1) continue; if (ret2 == 0) continue; curveData2.Speed = freqPump2.MachineDetail.CalcSpeedByFrequence(fre2); #endregion } else { isActCalc = true; double minSpanQ = _targetQ; double totalPower = freqPump1.MachineDetail.RatedP + freqPump2.MachineDetail.RatedP; //找到离_targetQ最接近的频率点 for (int index1 = 0; index1 < freqPump1.AnaItemList.Count; index1++) { //频率越来越小,c.WorkPointQ也越来越小 for (int index2 = 0; index2 < freqPump2.AnaItemList.Count; index2++) { var anaItem1 = freqPump1.AnaItemList[index1]; var anaItem2 = freqPump2.AnaItemList[index2]; double freTotalQ = anaItem1.WorkPointQ + anaItem2.WorkPointQ; //频率越来越小,c.WorkPointQ也越来越小 double freTotalP = anaItem1.WorkPointP + anaItem2.WorkPointP; var diffFlow = Math.Abs(fix_pump_total_flow + freTotalQ - _targetQ); if (diffFlow < minSpanQ) { minSpanQ = Math.Abs(fix_pump_total_flow + freTotalQ - _targetQ); curveData1 = anaItem1; curveData2 = anaItem2; totalPower = curveData1.WorkPointP + curveData2.WorkPointP; } if (diffFlow < _targetQ * 0.01 && freTotalP < totalPower) { curveData1 = anaItem1; curveData2 = anaItem2; totalPower = curveData1.WorkPointP + curveData2.WorkPointP; } } } } if (curveData1?.WorkPointQ > 1) { var itemRowF1 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump1.MachineDetail, curveData1); rowPrj.Items.Add(itemRowF1); } if (curveData2?.WorkPointQ > 1) { var itemRowF2 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump2.MachineDetail, curveData2); rowPrj.Items.Add(itemRowF2); } if (rowPrj.Items.Count == 0) return default; if (AddScheme(rowPrj, isActCalc)) addPrjNum++; } return addPrjNum; } #endregion #region 添加项目 只有3台变频泵:AddThreeFreqPumpPrj private int AddMultiFreqPumpPrj3( PumpCalcModel[] fixPumpCalcList, PumpCalcModel[] allFreqPumpAnaList) { int addPrjNum = 0; int frePumpNum = 3; if (allFreqPumpAnaList == null || allFreqPumpAnaList.Count() < frePumpNum) return addPrjNum; //判断最大开机数 if (_max_open_machine_number > 0) { int macine_number = 3; if (fixPumpCalcList != null) { macine_number = macine_number + fixPumpCalcList.Count(); } if (macine_number > _max_open_machine_number) return 0; } double fix_pump_total_flow = 0; if (fixPumpCalcList != null) { fix_pump_total_flow = (from x in fixPumpCalcList select x.AnaItem50Hz.WorkPointQ).Sum(); } List freqPumpAnaCombineList = ISupply.Model.PermutationAndCombination.GetCombination( allFreqPumpAnaList.ToArray(), frePumpNum); foreach (var freqPumpAnaCombine in freqPumpAnaCombineList) { var freqPump1 = freqPumpAnaCombine[0]; var freqPump2 = freqPumpAnaCombine[1]; var freqPump3 = freqPumpAnaCombine[2]; #region 检查是否符合开机约束 List machine_ids = new List { freqPump1.MachineDetail.MachineID, freqPump2.MachineDetail.MachineID, freqPump3.MachineDetail.MachineID }; if (fixPumpCalcList != null) { foreach (var item in fixPumpCalcList) machine_ids.Add(item.MachineDetail.MachineID); } if (!IsAccordMachineRunFilter(machine_ids)) { continue; } #endregion double freTotalQ = fix_pump_total_flow; double minSpanQ = _targetQmax; double totalPower = freqPump1.MachineDetail.RatedP + freqPump2.MachineDetail.RatedP + freqPump3.MachineDetail.RatedP; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData1 = null; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData2 = null; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData3 = null; // var rowPrj = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaScheme(); rowPrj.TotalWrkQ = freTotalQ; rowPrj.TotalWrkH = Math.Round(this._targetH, 2); rowPrj.Items = new List(); //找到离_targetQ最接近的频率点 for (int index1 = 0; index1 < freqPump1.AnaItemList.Count; index1++) {//频率越来越小,c.WorkPointQ也越来越小 for (int index2 = 0; index2 < freqPump2.AnaItemList.Count; index2++) {//频率越来越小,c.WorkPointQ也越来越小 for (int index3 = 0; index3 < freqPump3.AnaItemList.Count; index3++) {//频率越来越小,c.WorkPointQ也越来越小 var anaItem1 = freqPump1.AnaItemList[index1]; var anaItem2 = freqPump2.AnaItemList[index2]; var anaItem3 = freqPump3.AnaItemList[index3]; double wrkQ = anaItem1.WorkPointQ + anaItem2.WorkPointQ + anaItem3.WorkPointQ; double freTotalP = anaItem1.WorkPointP + anaItem2.WorkPointP + anaItem3.WorkPointP; var diffFlow = Math.Abs(fix_pump_total_flow + wrkQ - _targetQ); if (diffFlow < minSpanQ) { freTotalQ = fix_pump_total_flow + wrkQ; rowPrj.TotalWrkQ = freTotalQ; minSpanQ = Math.Abs(freTotalQ - _targetQ); curveData1 = anaItem1; curveData2 = anaItem2; curveData3 = anaItem3; totalPower = curveData1.WorkPointP + curveData2.WorkPointP + curveData3.WorkPointP; } if (diffFlow < _targetQ * 0.01 && freTotalP < totalPower) { curveData1 = anaItem1; curveData2 = anaItem2; curveData3 = anaItem3; totalPower = curveData1.WorkPointP + curveData2.WorkPointP + curveData3.WorkPointP; } } } } // if (freTotalQ < _targetQmax && freTotalQ > _targetQmin && curveData1 != null) { #region 加入固频泵开启信息 if (fixPumpCalcList != null) { foreach (var fixPump in fixPumpCalcList) { if (fixPump.AnaItem50Hz.WorkPointQ < 1) continue; var itemRow = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(fixPump.MachineDetail, fixPump.AnaItem50Hz); rowPrj.Items.Add(itemRow); } } #endregion if (curveData1.WorkPointQ > 1) { var itemRowF1 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump1.MachineDetail, curveData1); rowPrj.Items.Add(itemRowF1); } if (curveData2.WorkPointQ > 1) { var itemRowF2 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump2.MachineDetail, curveData2); rowPrj.Items.Add(itemRowF2); } if (curveData3.WorkPointQ > 1) { var itemRowF3 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump3.MachineDetail, curveData3); rowPrj.Items.Add(itemRowF3); } AddScheme(rowPrj, true); addPrjNum++; } } return addPrjNum; } #endregion #region 添加项目 只有4台变频泵:AddFourFreqPumpPrj private int AddMultiFreqPumpPrj4( PumpCalcModel[] fixPumpCalcList, PumpCalcModel[] allFreqPumpAnaList, double fix_pump_total_flow) { int addPrjNum = 0; int frePumpNum = 4; if (allFreqPumpAnaList == null || allFreqPumpAnaList.Count() < frePumpNum) return addPrjNum; //判断最大开机数 if (_max_open_machine_number > 0) { int macine_number = 4; if (fixPumpCalcList != null) { macine_number = macine_number + fixPumpCalcList.Count(); } if (macine_number > _max_open_machine_number) return 0; } List freqPumpAnaCombineList = ISupply.Model.PermutationAndCombination.GetCombination( allFreqPumpAnaList, frePumpNum); foreach (var freqPumpAnaCombine in freqPumpAnaCombineList) { var freqPump1 = freqPumpAnaCombine[0]; var freqPump2 = freqPumpAnaCombine[1]; var freqPump3 = freqPumpAnaCombine[2]; var freqPump4 = freqPumpAnaCombine[3]; #region 检查是否符合开机约束 List machine_ids = new List { freqPump1.MachineDetail.MachineID, freqPump2.MachineDetail.MachineID, freqPump3.MachineDetail.MachineID, freqPump4.MachineDetail.MachineID }; if (fixPumpCalcList != null) { foreach (var item in fixPumpCalcList) machine_ids.Add(item.MachineDetail.MachineID); } if (!IsAccordMachineRunFilter(machine_ids)) { continue; } #endregion double totalPower = freqPump1.MachineDetail.RatedP + freqPump2.MachineDetail.RatedP + freqPump3.MachineDetail.RatedP + freqPump4.MachineDetail.RatedP; double freTotalQ = fix_pump_total_flow; double minSpanQ = _targetQmax; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData1 = null; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData2 = null; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData3 = null; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData4 = null; var rowPrj = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaScheme(); rowPrj.TotalWrkQ = freTotalQ; rowPrj.TotalWrkH = Math.Round(_targetH, 2); rowPrj.Items = new List(); //找到离_targetQ最接近的频率点 for (int index1 = 0; index1 < freqPump1.AnaItemList.Count; index1++) {//频率越来越小,c.WorkPointQ也越来越小 for (int index2 = 0; index2 < freqPump2.AnaItemList.Count; index2++) {//频率越来越小,c.WorkPointQ也越来越小 for (int index3 = 0; index3 < freqPump3.AnaItemList.Count; index3++) {//频率越来越小,c.WorkPointQ也越来越小 for (int index4 = 0; index4 < freqPump4.AnaItemList.Count; index4++) {//频率越来越小,c.WorkPointQ也越来越小 var anaItem1 = freqPump1.AnaItemList[index1]; var anaItem2 = freqPump2.AnaItemList[index2]; var anaItem3 = freqPump3.AnaItemList[index3]; var anaItem4 = freqPump4.AnaItemList[index4]; double wrkQ = anaItem1.WorkPointQ + anaItem2.WorkPointQ + anaItem3.WorkPointQ + anaItem4.WorkPointQ; double freTotalP = anaItem1.WorkPointP + anaItem2.WorkPointP + anaItem3.WorkPointP + anaItem4.WorkPointP; var diffFlow = Math.Abs(fix_pump_total_flow + wrkQ - _targetQ); if (diffFlow < minSpanQ) { freTotalQ = fix_pump_total_flow + wrkQ; rowPrj.TotalWrkQ = freTotalQ; minSpanQ = Math.Abs(freTotalQ - _targetQ); curveData1 = anaItem1; curveData2 = anaItem2; curveData3 = anaItem3; curveData4 = anaItem4; totalPower = curveData1.WorkPointP + curveData2.WorkPointP + curveData3.WorkPointP + curveData4.WorkPointP; } if (diffFlow < _targetQ * 0.01 && freTotalP < totalPower) { curveData1 = anaItem1; curveData2 = anaItem2; curveData3 = anaItem3; curveData4 = anaItem4; totalPower = curveData1.WorkPointP + curveData2.WorkPointP + curveData3.WorkPointP + curveData4.WorkPointP; } } } } } // if (freTotalQ < _targetQmax && freTotalQ > _targetQmin && curveData1 != null) { #region 加入固频泵开启信息 if (fixPumpCalcList != null) { foreach (var fixPump in fixPumpCalcList) { if (fixPump.AnaItem50Hz.WorkPointQ < 1) continue; var itemRow = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(fixPump.MachineDetail, fixPump.AnaItem50Hz); rowPrj.Items.Add(itemRow); } } #endregion var itemRowF1 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump1.MachineDetail, curveData1); rowPrj.Items.Add(itemRowF1); var itemRowF2 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump2.MachineDetail, curveData2); rowPrj.Items.Add(itemRowF2); var itemRowF3 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump3.MachineDetail, curveData3); rowPrj.Items.Add(itemRowF3); var itemRowF4 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump4.MachineDetail, curveData4); rowPrj.Items.Add(itemRowF4); AddScheme(rowPrj, true); addPrjNum++; } } return addPrjNum; } #endregion #region 添加项目 只有5台变频泵:AddMultiFreqPumpPrj5 private int AddMultiFreqPumpPrj5( PumpCalcModel[] fixPumpCalcList, PumpCalcModel[] allFreqPumpAnaList, double fix_pump_total_flow) { int addPrjNum = 0; int frePumpNum = 5; if (allFreqPumpAnaList == null || allFreqPumpAnaList.Count() < frePumpNum) return addPrjNum; //判断最大开机数 if (_max_open_machine_number > 0) { int macine_number = 5; if (fixPumpCalcList != null) { macine_number = macine_number + fixPumpCalcList.Count(); } if (macine_number > _max_open_machine_number) return 0; } List freqPumpAnaCombineList = ISupply.Model.PermutationAndCombination.GetCombination( allFreqPumpAnaList, frePumpNum); foreach (var freqPumpAnaCombine in freqPumpAnaCombineList) { var freqPump1 = freqPumpAnaCombine[0]; var freqPump2 = freqPumpAnaCombine[1]; var freqPump3 = freqPumpAnaCombine[2]; var freqPump4 = freqPumpAnaCombine[3]; var freqPump5 = freqPumpAnaCombine[4]; #region 检查是否符合开机约束 List machine_ids = new List(); machine_ids.Add(freqPump1.MachineDetail.MachineID); machine_ids.Add(freqPump2.MachineDetail.MachineID); machine_ids.Add(freqPump3.MachineDetail.MachineID); machine_ids.Add(freqPump4.MachineDetail.MachineID); machine_ids.Add(freqPump5.MachineDetail.MachineID); if (fixPumpCalcList != null) { foreach (var item in fixPumpCalcList) machine_ids.Add(item.MachineDetail.MachineID); } if (!IsAccordMachineRunFilter(machine_ids)) { continue; } #endregion double freTotalQ = fix_pump_total_flow; double minSpanQ = _targetQmax; double totalPower = freqPump1.MachineDetail.RatedP + freqPump2.MachineDetail.RatedP + freqPump3.MachineDetail.RatedP + freqPump4.MachineDetail.RatedP + freqPump5.MachineDetail.RatedP; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData1 = null; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData2 = null; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData3 = null; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData4 = null; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData5 = null; var rowPrj = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaScheme(); rowPrj.TotalWrkQ = freTotalQ; rowPrj.TotalWrkH = Math.Round(_targetH, 2); rowPrj.Items = new List(); //double TotalWrkP = 0; //找到离_targetQ最接近的频率点 for (int index1 = 0; index1 < freqPump1.AnaItemList.Count; index1++) {//频率越来越小,c.WorkPointQ也越来越小 for (int index2 = 0; index2 < freqPump2.AnaItemList.Count; index2++) {//频率越来越小,c.WorkPointQ也越来越小 for (int index3 = 0; index3 < freqPump3.AnaItemList.Count; index3++) {//频率越来越小,c.WorkPointQ也越来越小 for (int index4 = 0; index4 < freqPump4.AnaItemList.Count; index4++) {//频率越来越小,c.WorkPointQ也越来越小 for (int index5 = 0; index5 < freqPump5.AnaItemList.Count; index5++) {//频率越来越小,c.WorkPointQ也越来越小 var anaItem1 = freqPump1.AnaItemList[index1]; var anaItem2 = freqPump2.AnaItemList[index2]; var anaItem3 = freqPump3.AnaItemList[index3]; var anaItem4 = freqPump4.AnaItemList[index4]; var anaItem5 = freqPump5.AnaItemList[index5]; double wrkQ = anaItem1.WorkPointQ + anaItem2.WorkPointQ + anaItem3.WorkPointQ + anaItem4.WorkPointQ + anaItem5.WorkPointQ; double freTotalP = anaItem1.WorkPointP + anaItem2.WorkPointP + anaItem3.WorkPointP + anaItem4.WorkPointP + anaItem5.WorkPointP; var diffFlow = Math.Abs(fix_pump_total_flow + wrkQ - _targetQ); if (diffFlow < minSpanQ) { freTotalQ = fix_pump_total_flow + wrkQ; rowPrj.TotalWrkQ = freTotalQ; minSpanQ = Math.Abs(freTotalQ - _targetQ); curveData1 = anaItem1; curveData2 = anaItem2; curveData3 = anaItem3; curveData4 = anaItem4; curveData5 = anaItem5; totalPower = curveData1.WorkPointP + curveData2.WorkPointP + curveData3.WorkPointP + curveData4.WorkPointP + curveData5.WorkPointP; } if (diffFlow < _targetQ * 0.01 && freTotalP < totalPower) { curveData1 = anaItem1; curveData2 = anaItem2; curveData3 = anaItem3; curveData4 = anaItem4; curveData5 = anaItem5; totalPower = curveData1.WorkPointP + curveData2.WorkPointP + curveData3.WorkPointP + curveData4.WorkPointP + curveData5.WorkPointP; } } } } } } // if (freTotalQ < _targetQmax && freTotalQ > _targetQmin && curveData1 != null) { #region 加入固频泵开启信息 if (fixPumpCalcList != null) { foreach (var fixPump in fixPumpCalcList) { if (fixPump.AnaItem50Hz.WorkPointQ < 1) continue; var itemRow = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(fixPump.MachineDetail, fixPump.AnaItem50Hz); rowPrj.Items.Add(itemRow); } } #endregion var itemRowF1 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump1.MachineDetail, curveData1); rowPrj.Items.Add(itemRowF1); var itemRowF2 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump2.MachineDetail, curveData2); rowPrj.Items.Add(itemRowF2); var itemRowF3 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump3.MachineDetail, curveData3); rowPrj.Items.Add(itemRowF3); var itemRowF4 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump4.MachineDetail, curveData4); rowPrj.Items.Add(itemRowF4); var itemRowF5 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump5.MachineDetail, curveData5); rowPrj.Items.Add(itemRowF5); AddScheme(rowPrj, true); addPrjNum++; } } return addPrjNum; } #endregion #region 添加项目 只有6台变频泵:AddMultiFreqPumpPrj6 private int AddMultiFreqPumpPrj6( PumpCalcModel[] fixPumpCalcList, PumpCalcModel[] allFreqPumpAnaList, double fix_pump_total_flow) { int addPrjNum = 0; int frePumpNum = 6; if (allFreqPumpAnaList == null || allFreqPumpAnaList.Count() < frePumpNum) return addPrjNum; //判断最大开机数 if (_max_open_machine_number > 0) { int macine_number = 6; if (fixPumpCalcList != null) { macine_number = macine_number + fixPumpCalcList.Count(); } if (macine_number > _max_open_machine_number) return 0; } List freqPumpAnaCombineList = ISupply.Model.PermutationAndCombination.GetCombination( allFreqPumpAnaList, frePumpNum); foreach (var freqPumpAnaList in freqPumpAnaCombineList) { var freqPump1 = freqPumpAnaList[0]; var freqPump2 = freqPumpAnaList[1]; var freqPump3 = freqPumpAnaList[2]; var freqPump4 = freqPumpAnaList[3]; var freqPump5 = freqPumpAnaList[4]; var freqPump6 = freqPumpAnaList[5]; #region 检查是否符合开机约束 List machine_ids = new List(); machine_ids.Add(freqPump1.MachineDetail.MachineID); machine_ids.Add(freqPump2.MachineDetail.MachineID); machine_ids.Add(freqPump3.MachineDetail.MachineID); machine_ids.Add(freqPump4.MachineDetail.MachineID); machine_ids.Add(freqPump5.MachineDetail.MachineID); machine_ids.Add(freqPump6.MachineDetail.MachineID); if (fixPumpCalcList != null) { foreach (var item in fixPumpCalcList) machine_ids.Add(item.MachineDetail.MachineID); } if (!IsAccordMachineRunFilter(machine_ids)) { continue; } #endregion double freTotalQ = fix_pump_total_flow; double minSpanQ = _targetQmax; double totalPower = freqPump1.MachineDetail.RatedP + freqPump2.MachineDetail.RatedP + freqPump3.MachineDetail.RatedP + freqPump4.MachineDetail.RatedP + freqPump5.MachineDetail.RatedP + freqPump6.MachineDetail.RatedP; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData1 = null; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData2 = null; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData3 = null; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData4 = null; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData5 = null; ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaCurveItem curveData6 = null; var rowPrj = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaScheme(); rowPrj.TotalWrkQ = freTotalQ; rowPrj.TotalWrkH = Math.Round(this._targetH, 2); rowPrj.Items = new List(); //找到离_targetQ最接近的频率点 for (int index1 = 0; index1 < freqPump1.AnaItemList.Count; index1++) {//频率越来越小,c.WorkPointQ也越来越小 for (int index2 = 0; index2 < freqPump2.AnaItemList.Count; index2++) {//频率越来越小,c.WorkPointQ也越来越小 for (int index3 = 0; index3 < freqPump3.AnaItemList.Count; index3++) {//频率越来越小,c.WorkPointQ也越来越小 for (int index4 = 0; index4 < freqPump4.AnaItemList.Count; index4++) {//频率越来越小,c.WorkPointQ也越来越小 for (int index5 = 0; index5 < freqPump5.AnaItemList.Count; index5++) {//频率越来越小,c.WorkPointQ也越来越小 for (int index6 = 0; index6 < freqPump6.AnaItemList.Count; index6++) {//频率越来越小,c.WorkPointQ也越来越小 var anaItem1 = freqPump1.AnaItemList[index1]; var anaItem2 = freqPump2.AnaItemList[index2]; var anaItem3 = freqPump3.AnaItemList[index3]; var anaItem4 = freqPump4.AnaItemList[index4]; var anaItem5 = freqPump5.AnaItemList[index5]; var anaItem6 = freqPump6.AnaItemList[index6]; double wrkQ = anaItem1.WorkPointQ + anaItem2.WorkPointQ + anaItem3.WorkPointQ + anaItem4.WorkPointQ + anaItem5.WorkPointQ + anaItem6.WorkPointQ; double freTotalP = anaItem1.WorkPointP + anaItem2.WorkPointP + anaItem3.WorkPointP + anaItem4.WorkPointP + anaItem5.WorkPointP + anaItem6.WorkPointP; var diffFlow = Math.Abs(fix_pump_total_flow + wrkQ - _targetQ); if (diffFlow < minSpanQ) { freTotalQ = fix_pump_total_flow + wrkQ; rowPrj.TotalWrkQ = freTotalQ; minSpanQ = Math.Abs(freTotalQ - _targetQ); curveData1 = anaItem1; curveData2 = anaItem2; curveData3 = anaItem3; curveData4 = anaItem4; curveData5 = anaItem5; curveData6 = anaItem6; totalPower = curveData1.WorkPointP + curveData2.WorkPointP + curveData3.WorkPointP + curveData4.WorkPointP + curveData5.WorkPointP + curveData6.WorkPointP; } if (diffFlow < _targetQ * 0.01 && freTotalP < totalPower) { curveData1 = anaItem1; curveData2 = anaItem2; curveData3 = anaItem3; curveData4 = anaItem4; curveData5 = anaItem5; curveData6 = anaItem6; totalPower = curveData1.WorkPointP + curveData2.WorkPointP + curveData3.WorkPointP + curveData4.WorkPointP + curveData5.WorkPointP + curveData6.WorkPointP; } } } } } } } // if (freTotalQ < _targetQmax && freTotalQ > _targetQmin && curveData1 != null) { #region 加入固频泵开启信息 if (fixPumpCalcList != null) { foreach (var fixPump in fixPumpCalcList) { if (fixPump.AnaItem50Hz.WorkPointQ < 1) continue; var itemRow = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(fixPump.MachineDetail, fixPump.AnaItem50Hz); rowPrj.Items.Add(itemRow); } } #endregion var itemRowF1 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump1.MachineDetail, curveData1); rowPrj.Items.Add(itemRowF1); var itemRowF2 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump2.MachineDetail, curveData2); rowPrj.Items.Add(itemRowF2); var itemRowF3 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump3.MachineDetail, curveData3); rowPrj.Items.Add(itemRowF3); var itemRowF4 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump4.MachineDetail, curveData4); rowPrj.Items.Add(itemRowF4); var itemRowF5 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump5.MachineDetail, curveData5); rowPrj.Items.Add(itemRowF5); var itemRowF6 = new ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaSchemeItem(freqPump6.MachineDetail, curveData6); rowPrj.Items.Add(itemRowF6); AddScheme(rowPrj, true); addPrjNum++; } } return addPrjNum; } #endregion private int _schemeID = 1; private bool AddScheme(ISupply.WinFrmUI.Epanet.Dispatch.Model.AnaScheme project, bool IsAccurateCalc) { try { project.TotalWrkQ = (from x in project.Items where x.WorkPointQ > 0 select x.WorkPointQ).Sum(); project.TotalWrkH = Math.Round((from x in project.Items where x.WorkPointH > 0 select x.WorkPointH).Average(), 2); project.TotalWrkP = Math.Round((from x in project.Items where x.WorkPointP > 0 select x.WorkPointP).Sum(), 2); project.TotalWrkE = ISupply.Common.PumpParaHelper.CalculateE(project.TotalWrkQ, project.TotalWrkH, project.TotalWrkP); project.UWP = Calcu_UWP(project.TotalWrkP, project.TotalWrkQ, this._targetH); project.WP = Calcu_WP(project.TotalWrkP, project.TotalWrkQ); if (project.TotalWrkQ > _targetQmax || project.TotalWrkQ < _targetQmin) { return false; } } catch (Exception ex) { throw; } //计算流量 //rowPrj.TotalWrkQ = (from x in rowPrj.Items where x.WorkPointQ > 0 select x.WorkPointQ).Sum(); //if (rowPrj.TotalWrkQ <= _targetQmax && rowPrj.TotalWrkQ >= this._targetQmin) // ds_disp_project_list.Add(project); if (_machine_flow_limit_max_dict != null) { foreach (var item in project.Items) { if (_machine_flow_limit_max_dict.ContainsKey(item.MachineID)) {//操作开机限制 if (item.WorkPointQ > _machine_flow_limit_max_dict[item.MachineID]) return false; } } } if (_machine_flow_limit_min_dict != null) { foreach (var item in project.Items) { if (_machine_flow_limit_min_dict.ContainsKey(item.MachineID)) {//操作开机限制 if (item.WorkPointQ < _machine_flow_limit_min_dict[item.MachineID]) return false; } } } if (_anaSchemeList == null) _anaSchemeList = new List(); //再精算一下 if (IsAccurateCalc) CalcDetailAccurate(ref project); project.ID = _schemeID; _anaSchemeList.Add(project); _schemeID++; return true; } /// /// 单位水耗 千吨水 /// public static double Calcu_UWP(double P, double Q, double H) { if (Q <= 0.001) return 0; if (H <= 0.00001) return 0; if (P <= 0.001) return 0; return P * 1000f / Q / H; } /// /// 单位水耗 千吨水 /// public static double Calcu_UWP(double P, double Q, double inletPress, double outletPress) { double H = (outletPress - inletPress) * 102; if (Q <= 0.001) return 0; if (H <= 0.00001) return 0; if (P <= 0.001) return 0; return P * 1000f / Q / H; } /// /// 单位水耗 /// public static double Calcu_WP(double P, double Q) { if (Q <= 0.001) return 0; if (P <= 0.001) return 0; return P * 1000f / Q; } } public class PumpCalcModel { public PumpCalcModel() { } public PumpCalcModel(Model.Pump rhs) { this.Qr = rhs.Qr; this.Hr = rhs.Hr; this.Nr = rhs.Nr; this.Pr = rhs.Pr; this.Er = rhs.Er; if (rhs.CurveQH != null && rhs.CurveQP != null) { this.CurveQH = rhs.CurveQH.Clone(); this.CurveQP = rhs.CurveQP.Clone(); this.AllowCalc = true; } } public PumpCalcModel(Model.Pump rhs, double freMin, double freMax, double freSpace) : this(rhs) { this.CalcFrequencyItems(freMin, freMax, freSpace); } public int ID { get; set; } public string Code { get; set; } public string Name { get; set; } public double Qr { get; set; } public double Hr { get; set; } public double Nr { get; set; } public double Pr { get; set; } public double Er { get; set; } public bool IsBp { get; set; } public CurveExpress CurveQH { get; set; } public CurveExpress CurveQP { get; set; } public List PumpFrequencyItems { get; set; } public bool AllowCalc { get; set; } void CalcFrequencyItems(double freMin, double freMax, double freSpace) { if (!this.AllowCalc) return; this.PumpFrequencyItems = new List(); for (double fre = freMax; fre >= freMin; fre -= freSpace) { var fre_def = 50; var freItem = new PumpFrequencyItem(); freItem.Frequency = fre; freItem.CurveQH = Curve.PumpCalculateHelper.CalculateSimilarQH(this.CurveQH, fre_def, fre); freItem.CurveQP = Curve.PumpCalculateHelper.CalculateSimilarQP(this.CurveQP, fre_def, fre); this.PumpFrequencyItems.Add(freItem); } } } public class PumpFrequencyItem { public double Frequency { get; set; } public Curve.CurveExpress CurveQH { get; set; } public Curve.CurveExpress CurveQP { get; set; } } }