namespace IStation.Algorithm
|
{
|
#region ViewModel
|
|
/// <summary>
|
/// 分析泵项
|
/// </summary>
|
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<AnaPumpFreItem> 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<AnaPumpFreItem>();
|
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);
|
}
|
}
|
}
|
|
/// <summary>
|
/// 分析泵变频项
|
/// </summary>
|
public class AnaPumpFreItem
|
{
|
public double Frequency { get; set; }
|
public Curve.CurveExpress CurveQH { get; set; }
|
public Curve.CurveExpress CurveQP { get; set; }
|
}
|
|
#endregion
|
|
/// <summary>
|
/// 调度分析辅助类
|
/// </summary>
|
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<AnaPumpItem> 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();
|
|
|
/// <summary>
|
/// 分析泵组合
|
/// </summary>
|
/// <param name="pumps">泵列表</param>
|
/// <returns></returns>
|
public bool AnaCombine(List<Pump> pumps)
|
{
|
InsertAnaLog("开始分析泵组合");
|
if (pumps == null || pumps.Count < 1)
|
{
|
InsertAnaLog("分析失败:pumps == null || pumps.Count < 1");
|
return false;
|
}
|
var fre_def = _frequency_def;
|
var anaPumpItems = new List<AnaPumpItem>();
|
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 false;
|
}
|
|
|
string runFlag;
|
List<AnaPumpFreItem> pump1, pump2, pump3;
|
var maxPumpCount = 2;
|
var anaPumpItemsArray = anaPumpItems.ToArray();
|
var parallelHelper = new ParallelConnectionHelper();
|
for (int pumpCount = 1; pumpCount <= maxPumpCount; pumpCount++)
|
{
|
var pumpCombineList = PermutationAndCombination<AnaPumpItem>.GetCombination(anaPumpItemsArray, pumpCount);
|
var pumpCombineCount = pumpCombineList.Count;
|
InsertAnaLog($"分析进度:{pumpCount}台泵,{pumpCombineCount}个组合");
|
switch (pumpCount)
|
{
|
case 1:
|
{
|
|
for (int i = 0; i < pumpCombineCount; i++)
|
{
|
var list = new List<Entity.ScheduleCombine>();
|
var pumpCombine = pumpCombineList[i].ToList();
|
pump1 = pumpCombine[0].AnaFrequencyItems;
|
runFlag = GetRunFlag(pumpCombine);
|
InsertAnaLog($"分析进度:{pumpCount}台泵,{runFlag},第{i + 1}个组合");
|
if (ExistTable(runFlag))
|
{
|
InsertAnaLog($"分析进度:{pumpCount}台泵,{runFlag}已存在");
|
continue;
|
}
|
foreach (var freItem in pump1)
|
{
|
var scheduleCombine = new Entity.ScheduleCombine();
|
scheduleCombine.RunFlag = runFlag;
|
scheduleCombine.RunCount = pumpCount;
|
scheduleCombine.RunHZ = $"{freItem.Frequency}";
|
scheduleCombine.CurveQH = freItem.CurveQH.ToJson();
|
scheduleCombine.CurveQP = freItem.CurveQP.ToJson();
|
scheduleCombine.AnaStatus = false;
|
list.Add(scheduleCombine);
|
}
|
var bol = BulkInsertScheduleCombineList(list);
|
if (bol)
|
{
|
InsertAnaLog($"分析进度:{pumpCount}台泵,{runFlag},插入成功!");
|
}
|
else
|
{
|
InsertAnaLog($"分析进度:{pumpCount}台泵,{runFlag},插入失败!");
|
}
|
}
|
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<Entity.ScheduleCombine>();
|
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<CurvePoint> pointQH, out List<CurvePoint> pointQE, out List<CurvePoint> pointQP);
|
if (!allowParallel)
|
continue;
|
|
var scheduleCombine = new Entity.ScheduleCombine();
|
scheduleCombine.RunFlag = runFlag;
|
scheduleCombine.RunCount = pumpCount;
|
scheduleCombine.RunHZ = $"{freItem1.Frequency},{freItem2.Frequency}";
|
scheduleCombine.CurveQH = FitHelper.BuildCurveExpress(pointQH).ToJson();
|
scheduleCombine.CurveQP = FitHelper.BuildCurveExpress(pointQP).ToJson();
|
scheduleCombine.AnaStatus = false;
|
list.Add(scheduleCombine);
|
}
|
}
|
var bol = BulkInsertScheduleCombineList(list);
|
if (bol)
|
{
|
InsertAnaLog($"分析进度:{pumpCount}台泵,{runFlag},插入成功!");
|
}
|
else
|
{
|
InsertAnaLog($"分析进度:{pumpCount}台泵,{runFlag},插入失败!");
|
}
|
}
|
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<Entity.ScheduleCombine>();
|
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<CurvePoint> pointQH, out List<CurvePoint> pointQE, out List<CurvePoint> pointQP);
|
if (!allowParallel)
|
continue;
|
var scheduleCombine = new Entity.ScheduleCombine();
|
scheduleCombine.RunFlag = runFlag;
|
scheduleCombine.RunCount = pumpCount;
|
scheduleCombine.RunHZ = $"{freItem1.Frequency},{freItem2.Frequency},{freItem3.Frequency}";
|
scheduleCombine.CurveQH = FitHelper.BuildCurveExpress(pointQH).ToJson();
|
scheduleCombine.CurveQP = FitHelper.BuildCurveExpress(pointQP).ToJson();
|
scheduleCombine.AnaStatus = false;
|
list.Add(scheduleCombine);
|
|
}
|
}
|
}
|
var bol = BulkInsertScheduleCombineList(list);
|
if (bol)
|
{
|
InsertAnaLog($"分析进度:{pumpCount}台泵,{runFlag},插入成功!");
|
}
|
else
|
{
|
InsertAnaLog($"分析进度:{pumpCount}台泵,{runFlag},插入失败!");
|
}
|
}
|
InsertAnaLog($"分析进度:{pumpCount}台泵,分析完毕!");
|
}
|
break;
|
default: break;
|
}
|
}
|
InsertAnaLog("分析泵组合完成");
|
return true;
|
}
|
|
/// <summary>
|
/// 分析结论
|
/// </summary>
|
public void AnaConclusion()
|
{
|
InsertAnaLog("开始分析泵组合结论");
|
var scheduleCombineTableNames = _dal.GetAllTableName();
|
if (scheduleCombineTableNames == null || !scheduleCombineTableNames.Any())
|
{
|
InsertAnaLog("分析失败:scheduleCombineTableNames == null || !scheduleCombineTableNames.Any()");
|
return;
|
}
|
var tableCount = scheduleCombineTableNames.Count();
|
InsertAnaLog($"分析进度:{tableCount}个组合");
|
for (int tableIndex = 0; tableIndex < tableCount; tableIndex++)
|
{
|
var tableName = scheduleCombineTableNames[tableIndex];
|
InsertAnaLog($"分析进度:{tableName},第{tableIndex}个");
|
var scheduleCombineList = _dal.GetAllUnanalyzedAnaByTableName(tableName);
|
if (scheduleCombineList == null || !scheduleCombineList.Any())
|
{
|
InsertAnaLog($"分析进度:{tableName},分析完毕");
|
continue;
|
}
|
var scheduleConclusionList = new List<Entity.ScheduleConclusion>();
|
var scheduleCombineListCount = scheduleCombineList.Count();
|
InsertAnaLog($"分析进度:{tableName},{scheduleCombineListCount}条未分析数据");
|
|
var scheduleCombineIds = new List<long>();
|
for (int combineIndex = 0; combineIndex < scheduleCombineListCount; combineIndex++)
|
{
|
var scheduleCombine = scheduleCombineList[combineIndex];
|
var scheduleCombineID = scheduleCombine.ID;
|
scheduleCombineIds.Add(scheduleCombineID);
|
var freList = DoubleListHelper.ToList(scheduleCombine.RunHZ);
|
var runCount = scheduleCombine.RunCount;
|
var curveQH = JsonHelper.Json2Object<Curve.CurveExpress>(scheduleCombine.CurveQH);
|
var curveQP = JsonHelper.Json2Object<Curve.CurveExpress>(scheduleCombine.CurveQP);
|
var bol = curveQH.GetMinMaxPointY(out double maxY, out double minY);
|
if (!bol)
|
{
|
continue;
|
}
|
var maxHead = Math.Ceiling(maxY);
|
var minHead = Math.Floor(minY);
|
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 = freList[0];
|
if (runCount == 2)
|
{
|
scheduleConclusion.Pump2 = freList[1];
|
}
|
if (runCount == 3)
|
{
|
scheduleConclusion.Pump3 = freList[2];
|
}
|
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();
|
scheduleConclusionList.Add(scheduleConclusion);
|
|
}
|
}
|
SetAnaStatus(tableName, scheduleCombineIds);
|
BulkInsert_NativeSql_ScheduleConclusionList(scheduleConclusionList);
|
InsertAnaLog($"分析进度:{tableName},{scheduleCombineIds.Count}条,分析完毕");
|
}
|
InsertAnaLog("泵组合分析完毕");
|
}
|
|
|
|
/// <summary>
|
/// 插入分析日志
|
/// </summary>
|
private void InsertAnaLog(string info)
|
{
|
var entity = new Entity.ScheduleAnaLog(info);
|
_dalAnaLog.Insert(entity);
|
}
|
|
/// <summary>
|
/// 判断表是否存在
|
/// </summary>
|
public bool SetAnaStatus(string tableName, List<long> ids)
|
{
|
if (ids == null || !ids.Any())
|
{
|
return false;
|
}
|
return _dal.SetAnaStatus(tableName, ids);
|
}
|
|
/// <summary>
|
/// 判断表是否存在
|
/// </summary>
|
public bool ExistTable(string runFlag)
|
{
|
return _dal.ExistTable(runFlag);
|
}
|
|
/// <summary>
|
/// 脏插入调度组合列表
|
/// </summary>
|
private bool BulkInsertScheduleCombineList(List<Entity.ScheduleCombine> list)
|
{
|
if (list == null || !list.Any())
|
return false;
|
var bol = _dal.BulkInserts_SplitTable(list);
|
return bol;
|
}
|
|
|
/// <summary>
|
/// 脏插入调度结论列表
|
/// </summary>
|
private bool BulkInsertScheduleConclusionList(List<Entity.ScheduleConclusion> list)
|
{
|
if (list == null || !list.Any())
|
return false;
|
var bol = _dalScheduleConclusion.BulkInserts_SplitTable(list);
|
return bol;
|
}
|
|
/// <summary>
|
/// 脏插入调度结论列表
|
/// </summary>
|
private bool BulkInsert_NativeSql_ScheduleConclusionList(string runFalg, List<Entity.ScheduleConclusion> list)
|
{
|
if (list == null || !list.Any())
|
return false;
|
var bol = _dalScheduleConclusion.BulkInserts_NativeSql(runFalg, list);
|
return bol;
|
}
|
|
}
|
|
|
}
|