namespace IStation.Algorithm { #region ViewModel /// /// 分析泵项 /// public class AnaPumpItem { public AnaPumpItem() { } public AnaPumpItem(Pump rhs) { this.ID = rhs.ID; this.Name = rhs.Name; this.Code = rhs.Code; this.IsBp = rhs.IsBp; 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 AnaPumpItem(Pump rhs, double freDef, double freMin, double freMax, double freSpace) : this(rhs) { this.CalcFrequencyItems(freDef, 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 Curve.CurveExpress CurveQH { get; set; } public Curve.CurveExpress CurveQP { get; set; } public List AnaFrequencyItems { get; set; } public bool AllowCalc { get; set; } void CalcFrequencyItems(double freDef, double freMin, double freMax, double freSpace) { if (!this.AllowCalc) return; this.AnaFrequencyItems = new List(); for (double fre = freMax; fre >= freMin; fre -= freSpace) { var freItem = new AnaPumpFreItem(); freItem.Frequency = Math.Round(fre, 1); freItem.CurveQH = Curve.PumpCalculateHelper.CalculateSimilarQH(this.CurveQH, freDef, fre); freItem.CurveQP = Curve.PumpCalculateHelper.CalculateSimilarQP(this.CurveQP, freDef, fre); this.AnaFrequencyItems.Add(freItem); } } } /// /// 分析泵变频项 /// public class AnaPumpFreItem { public double Frequency { get; set; } public Curve.CurveExpress CurveQH { get; set; } public Curve.CurveExpress CurveQP { get; set; } } #endregion /// /// 调度分析辅助类 /// public class SchedulingAnaHelper { double _frequency_def = 50; double _frequency_min = 25; double _frequency_max = 50; double _frequency_space = 0.1;//频率间隔 double _head_space = 0.1;//扬程间隔 #region RunFlag string _falgFrePumpTag = "B"; string _falgFixPumpTag = "G"; string _falgSpaceMark = "_"; string GetRunFlag(List pumpItems) { var tableName = string.Empty; var count = pumpItems.Count; pumpItems = pumpItems.OrderBy(p => p.ID).ToList(); for (int i = 0; i < count; i++) { var pumpItem = pumpItems[i]; tableName += GetRunFlag(pumpItem); if ((i + 1) != count) { tableName += _falgSpaceMark; } } return tableName; } string GetRunFlag(AnaPumpItem pumpItem) { return (pumpItem.IsBp ? _falgFrePumpTag : _falgFixPumpTag) + pumpItem.ID; } #endregion DAL.ScheduleCombine _dal = new DAL.ScheduleCombine(); DAL.ScheduleConclusion _dalScheduleConclusion = new DAL.ScheduleConclusion(); DAL.ScheduleAnaLog _dalAnaLog = new DAL.ScheduleAnaLog(); /// /// 分析泵组合 /// /// 泵列表 /// public void AnaCombine(List pumps) { InsertAnaLog("开始分析泵组合"); if (pumps == null || pumps.Count < 1) { InsertAnaLog("分析失败:pumps == null || pumps.Count < 1"); return; } var fre_def = _frequency_def; var anaPumpItems = new List(); foreach (var pump in pumps) { if (pump.IsBp) { //变频泵 var anaPump = new AnaPumpItem(pump, fre_def, _frequency_min, _frequency_max, _frequency_space); if (anaPump.AllowCalc) anaPumpItems.Add(anaPump); } else { //固频泵 var anaPump = new AnaPumpItem(pump); if (anaPump.AllowCalc) anaPumpItems.Add(anaPump); } } if (anaPumpItems.Count < 1) { InsertAnaLog("分析失败:anaPumpItems.Count < 1"); return; } string runFlag; List pump1, pump2, pump3; var maxPumpCount = 2; var anaPumpItemsArray = anaPumpItems.ToArray(); var parallelHelper = new ParallelConnectionHelper(); for (int pumpCount = 1; pumpCount <= maxPumpCount; pumpCount++) { var pumpCombineList = PermutationAndCombination.GetCombination(anaPumpItemsArray, pumpCount); var pumpCombineCount = pumpCombineList.Count; InsertAnaLog($"分析进度:{pumpCount}台泵,{pumpCombineCount}个组合"); switch (pumpCount) { case 1: { for (int i = 0; i < pumpCombineCount; i++) { var pumpCombine = pumpCombineList[i].ToList(); pump1 = pumpCombine[0].AnaFrequencyItems; runFlag = GetRunFlag(pumpCombine); InsertAnaLog($"分析进度:{pumpCount}台泵,{runFlag},第{i + 1}个组合"); if (ExistTable(runFlag)) { InsertAnaLog($"分析进度:{pumpCount}台泵,{runFlag}已存在"); continue; } var list = new List(pump1.Count); foreach (var freItem in pump1) { var scheduleCombine = new Entity.ScheduleCombine(); scheduleCombine.RunFlag = runFlag; scheduleCombine.RunCount = pumpCount; scheduleCombine.Pump1 = freItem.Frequency; scheduleCombine.CurveQH = freItem.CurveQH.ToJson(); scheduleCombine.CurveQP = freItem.CurveQP.ToJson(); scheduleCombine.AnaStatus = false; list.Add(scheduleCombine); } InsertCombine(i + 1, runFlag, list); } InsertAnaLog($"分析进度:{pumpCount}台泵,分析完毕!"); } break; case 2: { for (int i = 0; i < pumpCombineCount; i++) { var pumpCombine = pumpCombineList[i].ToList(); pump1 = pumpCombine[0].AnaFrequencyItems; pump2 = pumpCombine[1].AnaFrequencyItems; runFlag = GetRunFlag(pumpCombine); InsertAnaLog($"分析进度:{pumpCount}台泵,{runFlag},第{i + 1}个组合"); if (ExistTable(runFlag)) { InsertAnaLog($"分析进度:{pumpCount}台泵,{runFlag}已存在"); continue; } var list = new List(pump1.Count * pump2.Count); for (int pump1Index = 0; pump1Index < pump1.Count; pump1Index++) { for (int pump2Index = 0; pump2Index < pump2.Count; pump2Index++) { var freItem1 = pump1[pump1Index]; var freItem2 = pump2[pump2Index]; parallelHelper.ClearCurve(); parallelHelper.AddCurve(freItem1.CurveQH, freItem1.CurveQP); parallelHelper.AddCurve(freItem2.CurveQH, freItem2.CurveQP); var allowParallel = parallelHelper.CalculateParallel(out List pointQH, out List pointQE, out List pointQP); if (!allowParallel) continue; var scheduleCombine = new Entity.ScheduleCombine(); scheduleCombine.RunFlag = runFlag; scheduleCombine.RunCount = pumpCount; scheduleCombine.Pump1 = freItem1.Frequency; scheduleCombine.Pump2 = freItem2.Frequency; scheduleCombine.CurveQH = FitHelper.BuildCurveExpress(pointQH).ToJson(); scheduleCombine.CurveQP = FitHelper.BuildCurveExpress(pointQP).ToJson(); scheduleCombine.AnaStatus = false; list.Add(scheduleCombine); } } InsertCombine(i + 1, runFlag, list); } InsertAnaLog($"分析进度:{pumpCount}台泵,分析完毕!"); } break; case 3: { for (int i = 0; i < pumpCombineCount; i++) { var pumpCombine = pumpCombineList[i].ToList(); pump1 = pumpCombine[0].AnaFrequencyItems; pump2 = pumpCombine[1].AnaFrequencyItems; pump3 = pumpCombine[2].AnaFrequencyItems; runFlag = GetRunFlag(pumpCombine); InsertAnaLog($"分析进度:{pumpCount}台泵,{runFlag},第{i + 1}个组合"); if (ExistTable(runFlag)) { InsertAnaLog($"分析进度:{pumpCount}台泵,{runFlag}已存在"); continue; } var list = new List(pump1.Count * pump2.Count * pump3.Count); for (int pump1Index = 0; pump1Index < pump1.Count; pump1Index++) { for (int pump2Index = 0; pump2Index < pump2.Count; pump2Index++) { for (int pump3Index = 0; pump3Index < pump3.Count; pump3Index++) { var freItem1 = pump1[pump1Index]; var freItem2 = pump2[pump2Index]; var freItem3 = pump3[pump3Index]; parallelHelper.ClearCurve(); parallelHelper.AddCurve(freItem1.CurveQH, freItem1.CurveQP); parallelHelper.AddCurve(freItem2.CurveQH, freItem2.CurveQP); parallelHelper.AddCurve(freItem3.CurveQH, freItem3.CurveQP); var allowParallel = parallelHelper.CalculateParallel(out List pointQH, out List pointQE, out List pointQP); if (!allowParallel) continue; var scheduleCombine = new Entity.ScheduleCombine(); scheduleCombine.RunFlag = runFlag; scheduleCombine.RunCount = pumpCount; scheduleCombine.Pump1 = freItem1.Frequency; scheduleCombine.Pump2 = freItem2.Frequency; scheduleCombine.Pump3 = freItem3.Frequency; scheduleCombine.CurveQH = FitHelper.BuildCurveExpress(pointQH).ToJson(); scheduleCombine.CurveQP = FitHelper.BuildCurveExpress(pointQP).ToJson(); scheduleCombine.AnaStatus = false; list.Add(scheduleCombine); } } } InsertCombine(i + 1, runFlag, list); } InsertAnaLog($"分析进度:{pumpCount}台泵,分析完毕!"); } break; default: break; } } } /// /// 分析结论 /// public void AnaConclusion() { InsertAnaLog($"开始分析泵组合结论!"); _dalScheduleConclusion.DeleteAllTable(); var scheduleCombineTableNames = _dal.GetAllTableName(); if (scheduleCombineTableNames == null || !scheduleCombineTableNames.Any()) { InsertAnaLog($"无泵组合表!"); return; } var tableCount = scheduleCombineTableNames.Count(); InsertAnaLog($"分析{tableCount}个组合!"); for (int tableIndex = 0; tableIndex < tableCount; tableIndex++) { var tableName = scheduleCombineTableNames[tableIndex]; var scheduleCombineList = _dal.GetAllUnanalyzedAnaByTableName(tableName); if (scheduleCombineList == null || !scheduleCombineList.Any()) { InsertAnaLog($"分析进度:{tableName},第{tableIndex + 1}个,分析完毕"); continue; } var scheduleCombineListCount = scheduleCombineList.Count(); var scheduleConclusionList = new List>(scheduleCombineListCount); var scheduleCombineIds = new List(scheduleCombineListCount); for (int combineIndex = 0; combineIndex < scheduleCombineListCount; combineIndex++) { var scheduleCombine = scheduleCombineList[combineIndex]; var scheduleCombineID = scheduleCombine.ID; scheduleCombineIds.Add(scheduleCombineID); var curveQH = JsonHelper.Json2Object(scheduleCombine.CurveQH); var curveQP = JsonHelper.Json2Object(scheduleCombine.CurveQP); var bol = curveQH.GetMinMaxPointY(out double maxY, out double minY); if (!bol) return; var maxHead = Math.Ceiling(maxY); var minHead = Math.Floor(minY); var currentListCount = (int)((maxHead - minHead) / _head_space) + 1; var currentScheduleConclusionList = new List(currentListCount); for (double head = minHead; head <= maxHead; head += _head_space) { var flow = curveQH.GetInterPointLastX(head); if (!flow.HasValue) { continue; } var scheduleConclusion = new Entity.ScheduleConclusion(); scheduleConclusion.ScheduleCombineID = scheduleCombineID; scheduleConclusion.RunFlag = scheduleCombine.RunFlag; scheduleConclusion.Pump1 = scheduleCombine.Pump1; scheduleConclusion.Pump2 = scheduleCombine.Pump2; scheduleConclusion.Pump3 = scheduleCombine.Pump3; scheduleConclusion.Head = head; scheduleConclusion.Flow = flow.Value; scheduleConclusion.Power = curveQP.GetFitPointY(flow.Value); scheduleConclusion.UWP = PumpCalculateHelper.CalculateUWP(scheduleConclusion.Power, scheduleConclusion.Flow, scheduleConclusion.Head); scheduleConclusion.WP = PumpCalculateHelper.CalculateWP(scheduleConclusion.Power, scheduleConclusion.Flow); scheduleConclusion.Round(); currentScheduleConclusionList.Add(scheduleConclusion); } scheduleConclusionList.Add(currentScheduleConclusionList); } SetAnaStatus(tableName, scheduleCombineIds); var list = scheduleConclusionList.SelectMany(x => x.ToList()).ToList(); var runFlag = list[0].RunFlag; InsertConclusion(tableIndex + 1, runFlag, list); } } /// /// 插入分析日志 /// private void InsertAnaLog(string info) { var entity = new Entity.ScheduleAnaLog(info); _dalAnaLog.Insert(entity); } /// /// 判断表是否存在 /// public bool SetAnaStatus(string tableName, List ids) { if (ids == null || !ids.Any()) { return false; } return _dal.SetAnaStatus(tableName, ids); } /// /// 判断表是否存在 /// public bool ExistTable(string runFlag) { return _dal.ExistTable(runFlag); } public void InsertCombine(int index, string runFlag, List list) { if (list == null || !list.Any()) { var log = $"{runFlag}:下标:{index},无数据"; InsertAnaLog(log); return; } Task.Run(() => { var sw = Stopwatch.StartNew(); var db = new DAL.ScheduleCombine(); db.BulkInserts_Create(runFlag, list); var log = $"{runFlag}:下标:{index},数量:{list.Count},插入耗时:{sw.ElapsedMilliseconds / 1000}m"; InsertAnaLog(log); }); } public void InsertConclusion(int index, string runFlag, List list) { if (list == null || !list.Any()) { var log = $"{runFlag}:下标:{index},无数据"; InsertAnaLog(log); return; } Task.Run(() => { var sw = Stopwatch.StartNew(); var db = new DAL.ScheduleConclusion(); db.BulkInserts_Create(runFlag, list); var log = $"分析进度:{runFlag},下标:{index},数量:{list.Count},插入耗时:{sw.ElapsedMilliseconds / 1000}m"; InsertAnaLog(log); }); } } } //public void Run(Action action, string description) //{ // Stopwatch sw = Stopwatch.StartNew(); // action(); // var log = $"--> {description}:{sw.ElapsedMilliseconds / 1000}m"; // InsertAnaLog(log); //} //public T Run(Func func, string description) //{ // var sw = Stopwatch.StartNew(); // T result = func(); // var log = $"--> {description}:{sw.ElapsedMilliseconds / 1000}m"; // InsertAnaLog(log); // return result; //}