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;
}
}
}