using IStation.CalcModel; using IStation.Model; using System; using System.Collections.Generic; using System.Linq; namespace IStation.Calc { internal partial class ErQuCalcBaseHelper { protected int _maxOpenPumpCount = 4;//最大开泵数量 /// /// /// /// public static IStation.Calc.ErQuCalcBaseHelper Build(IStation.CalcModel.AnaRequest anaRequest) { if (anaRequest.MaxReservoirLevel != null) { DateTime? limit_time = GetMaxReservoirLevelTime(anaRequest); if (limit_time == null) { var calc = new IStation.Calc.ErQuCalcHelper_2_递归_定水位_任意时间(); calc.SetMaxReservoirHeight(anaRequest.MaxReservoirLevel.Value); return calc; } else { var calc = new IStation.Calc.ErQuCalcHelper_2_递归_定水位_指定时间(); calc.SetMaxReservoirHeight(anaRequest.MaxReservoirLevel.Value, limit_time.Value); return calc; } } else { return new IStation.Calc.ErQuCalcHelper_2_递归_定水量(); } } private static DateTime? GetMaxReservoirLevelTime(IStation.CalcModel.AnaRequest anaRequest) { if (string.IsNullOrEmpty(anaRequest.MaxReservoirLevelTime)) { return null; } DateTime time; if (DateTime.TryParse(anaRequest.MaxReservoirLevelTime, out time)) { return time; } if (anaRequest.MaxReservoirLevelTime.Contains(":")) { var sss = anaRequest.MaxReservoirLevelTime.Split(':'); if (sss.Count() == 2) { int hour = 0; int miut = 0; if (int.TryParse(sss[0], out hour) && int.TryParse(sss[1], out miut)) { if (hour < anaRequest.StartTime.Hour) return new DateTime(anaRequest.EndTime.Year, anaRequest.EndTime.Month, anaRequest.EndTime.Day, hour, miut, 0); else return new DateTime(anaRequest.StartTime.Year, anaRequest.StartTime.Month, anaRequest.StartTime.Day, hour, miut, 0); } } } else { int hour = 0; if (int.TryParse(anaRequest.MaxReservoirLevelTime, out hour)) { if (hour < anaRequest.StartTime.Hour) return new DateTime(anaRequest.EndTime.Year, anaRequest.EndTime.Month, anaRequest.EndTime.Day, hour, 0, 0); else return new DateTime(anaRequest.StartTime.Year, anaRequest.StartTime.Month, anaRequest.StartTime.Day, hour, 0, 0); } } return null; } /// /// /// public class RunBlock { public int PumpCount; public int StartIndx; public int EndIndx; public double TotalCompare; public double TotalFlow; public double ReservoirStartHeight;//水库水位 public double ReservoirEndHeight; } /// /// /// protected ErQuCalcBaseHelper() { var calStartTime = DateTime.Now; _calStartTime = new DateTime(calStartTime.Year, calStartTime.Month, calStartTime.Day, calStartTime.Hour, 0, 0); _calEndTime = _calStartTime.AddDays(1); } public void SetCalcTimeRange(DateTime calStartTime, DateTime calEndTime,int calcSpaceMinute) { if (calcSpaceMinute <= 1) { calcSpaceMinute = 10; } this._calcSpaceMinute = calcSpaceMinute; this._calStartTime = new DateTime(calStartTime.Year, calStartTime.Month, calStartTime.Day, calStartTime.Hour, ((int)(calStartTime.Minute/ calcSpaceMinute)) * calcSpaceMinute, 0); this._calEndTime = new DateTime(calEndTime.Year, calEndTime.Month, calEndTime.Day, calEndTime.Hour, ((int)(calEndTime.Minute / calcSpaceMinute)) * calcSpaceMinute, 0); } // public Action OnShowDebugInfo = null; //排序方式 protected IStation.CalcModel.eCalcOptType _clacOptType = CalcModel.eCalcOptType.功率; /// /// /// protected double _flowInTotalFlow = 0;//取水总量(不一定有值 单位: 吨) /// /// /// /// public void SetAnaRequest(IStation.CalcModel.AnaRequest anaRequest) { this._start_level水库水位 = anaRequest.StartReservoirLevel; this._clacOptType = anaRequest.CalcOptType; if (anaRequest.IsKnownStartOpenPump) { if (anaRequest.StartOpenPumpIndexArray == null) {//没有赋值就是表示不知道, 如果都不开机, 赋值[] this._startOpenPumpCount = -1; } else { this._startOpenPumpArray = anaRequest.StartOpenPumpIndexArray; this._startOpenPumpCount = anaRequest.StartOpenPumpIndexArray.Count; } } else { this._startOpenPumpCount = -1; } if (anaRequest.TotalFlowIn != null) this._flowInTotalFlow = anaRequest.TotalFlowIn.Value; this.Initial水库参数(anaRequest); this.SetRiverWaterLevels(anaRequest.WaterLevels长江); } /// /// 计算最优 /// /// /// /// public virtual AnaPrj CalcOptPrj(out string error_info) { error_info = null; #region 检查数据 if (this._calStartTime >= this._calEndTime) { error_info = "时间范围不对"; return null; } if (this._allPumpInfo == null || this._allPumpInfo.Count() != 5) { error_info = "泵台数不正确"; return null; } if (this._riverWaterLevels == null || this._riverWaterLevels.Count() < 1) { error_info = "长江水位未赋值"; return null; } if (_listRiverWaterLevelDrop == null) { _listRiverWaterLevelDrop = IStation.AnaGlobalParas.RiverWaterLevelDropList; if (_listRiverWaterLevelDrop == null || _listRiverWaterLevelDrop.Count() == 0) { error_info = "无法读取长江水位与水池落差的关系数据"; return null; } } #endregion 检查数据 // List listPrj; //System.Diagnostics.Stopwatch sw2 = new System.Diagnostics.Stopwatch(); //sw2.Start(); //迭代浮动, 不要每次都从0开始, 可能差几分钟更优, 后面此变量也要迭代 int dd_minute = 0; // CalcTimeData(dd_minute); // 真正开始分析 var optPrj = CalcOptPrjsCore(); //sw2.Stop(); //var seconds = (int)(sw2.ElapsedMilliseconds / 1000); //故意加1分钟 //if (this._calcSpaceMinute >= 5) //{ // seconds += 50; // Thread.Sleep(50 * 1000); //} //if (this._calcSpaceMinute == 4) //{ // seconds += 20; // Thread.Sleep(20 * 1000); //} if (optPrj == null) { error_info = "未找到合适的调度方案"; return null; } optPrj.StartTime = this._calStartTime; optPrj.EndTime = this._calEndTime; // OnShowDebugInfo.Invoke(string.Format("计算用时: {0} 秒", seconds)); return optPrj; } /// /// /// /// protected virtual AnaPrj CalcOptPrjsCore() { return null; } /// /// /// protected ulong _totalCalcCount = 0;//计算次数 protected ulong _totalCacheCount = 0;//缓存使用次数 //时间范围 protected DateTime _calStartTime; protected DateTime _calEndTime; //泵信息 internal List _allPumpInfo = null; public void SetPumpInfo(List allPumpInfo) { if (allPumpInfo == null) return; this._allPumpInfo = new List(); for (int k = 0; k < allPumpInfo.Count; k++) { var pump = allPumpInfo[k]; CalcModel.PumpCurveInfo pumpCurveInfo = new CalcModel.PumpCurveInfo(); pumpCurveInfo.ID = pump.ID; pumpCurveInfo.PumpIndex = k; pumpCurveInfo.Name = pump.Name; pumpCurveInfo.CurveInfo = pump.CurveInfo; pumpCurveInfo.RatedParas = pump.RatedParas; double spaceQ = (pump.CurveInfo.CurveQH.Max - pump.CurveInfo.CurveQH.Min) / 99; List groupPoints = new List(); for (int i = 0; i < 100; i++) { var q = pump.CurveInfo.CurveQH.Min + spaceQ * i; var h = IStation.Common.FitCurveHelper.GetFitPointY(pump.CurveInfo.CurveQH, q); double eta = 0; // IStation.Common.FitCurveHelper.GetFitPointY(pump.CurveInfo.CurveQE, q); var p = IStation.Common.FitCurveHelper.GetFitPointY(pump.CurveInfo.CurveQP, q); groupPoints.Add(new GroupPoint() { Q = q, H = h, E = eta, P = p }); } pumpCurveInfo.GroupPoints = groupPoints; _allPumpInfo.Add(pumpCurveInfo); } } //计算时间跨度 protected int _calcSpaceMinute = 5; public int CalcSpaceMinute { get { return _calcSpaceMinute; } set { _calcSpaceMinute = value; } } /// /// 中间最多切换次数 /// protected int _maxPumpSwitchCount = 3; public int MaxPumpSwitchCount { get { return _maxPumpSwitchCount; } set { _maxPumpSwitchCount = value; } } /// /// 不许切泵时间 /// protected List _limitSwitchPumpTimes = null; public List LimitSwitchPumpTimes { get { return _limitSwitchPumpTimes; } set { _limitSwitchPumpTimes = value; } } /// /// 不许开泵时间 /// protected List _limitOpenPumpTimes = null; public List LimitOpenPumpTimes { get { return _limitOpenPumpTimes; } set { _limitOpenPumpTimes = value; } } #region 泵出口压力 //private void InitialPumpOutletPress() //{ // _outBoxLevels = new List(); // _outBoxLevels.Add(new Model.TimeWaterLevel() { Level = 0.068 * 100 }); //} ///// ///// 出水水池水位 ///// //protected List _outBoxLevels = null; //暂时固定 protected double CalcPumpOutletPressM(DateTime time) {//返回m的单位数值 return 0.068 * 100; //return _outBoxLevels.First().Level; } #endregion 泵出口压力 /// /// 获取扬程(暂时简单处理) /// /// /// internal double GetPipeHead(DateTime time, TimeDataBundle timeDataBundle) { int openPumpCount = timeDataBundle.OpenPumpInfos.Count; var m2 = CalcPumpOutletPressM(time); var m1 = GetRiverWaterLevelByTime(time); double dropHeight = 0; if (openPumpCount >= 4) { dropHeight = 2.5; } else if (openPumpCount == 3) { dropHeight = 1.54; } else if (openPumpCount == 3) { dropHeight = 0.81; } else if (openPumpCount == 2) { dropHeight = 0.32; } //double totalFlow = 0; //double dropHeight = _listRiverWaterLevelDrop.Last().DropHeight; //if (totalFlow < _listRiverWaterLevelDrop.Last().Flow) //{ // for (int i = 0; i < _listRiverWaterLevelDrop.Count; i++) // { // if (totalFlow < _listRiverWaterLevelDrop[i].Flow) // { // dropHeight = _listRiverWaterLevelDrop[i].DropHeight; break; // } // } //} m1 = m1 - dropHeight; return (m2 - m1); } //电费 protected List _elecPrice = null; public List ElecPrice { get => _elecPrice; set => _elecPrice = value; } public double CalcMoney(DateTime time, double power) { var month = time.Month; var hour = time.Hour; var monthSettings = _elecPrice.Find(x => month >= x.StartMonth && month <= x.EndMonth); var hourList = monthSettings.HourList; //if (hour == 23) //{ // var item = hourList.Find(x => x.EndHour == 23); // return power * item.Price; //} //else { var item = hourList.Find(x => hour >= x.StartHour && hour < x.EndHour); return power * item.Price; } } /// /// 最少开泵时间 /// public int MinOpenPumpMinute = 30; protected int _minTimeCountOpenPump = 0; public int MinSwitchPumpMinute = 30; protected int _minTimeCountSwitch = 0; /// /// 初始化开机台数 /// protected int _startOpenPumpCount = -1; protected List _startOpenPumpArray = null; /// /// /// protected bool isDispDebug = false; public bool IsDispDebug { get => isDispDebug; set => isDispDebug = value; } /// /// /// /// /// protected bool CheckPrjItemTimeAble(List time_items) { if (time_items == null) return false; //if (time_items.Count == 1) //{ // for (int i = 0; i < 5; i++) // { // if (time_items[0].OpenPumpIndexs.Contains(i)) // { // if ((time_items[0].EndTime - time_items[0].StartTime).TotalMinutes < MinOpenPumpMinute) // return false; // } // } //} //if (time_items.Count == 2) //{ // for (int i = 0; i < 5; i++) // { // if (time_items[0].OpenPumpIndexs.Contains(i) && time_items[1].OpenPumpIndexs.Contains(i)) // { // if ((time_items[1].EndTime - time_items[0].StartTime).TotalMinutes < MinOpenPumpMinute) // return false; // } // if (time_items[0].OpenPumpIndexs.Contains(i) && !time_items[1].OpenPumpIndexs.Contains(i)) // { // if ((time_items[0].EndTime - time_items[0].StartTime).TotalMinutes < MinOpenPumpMinute) // return false; // } // if (!time_items[0].OpenPumpIndexs.Contains(i) && time_items[1].OpenPumpIndexs.Contains(i)) // { // if ((time_items[1].EndTime - time_items[1].StartTime).TotalMinutes < MinOpenPumpMinute) // return false; // } // } //} return true; } } }