namespace PBS.WinFrmUI.Hydro
{
public partial class SystemCurvePage : DocumentPage
{
public SystemCurvePage()
{
InitializeComponent();
this.facilityTreeListCtrl1.SelectFacilityEvent += FacilityTreeListCtrl1_SelectFacilityEvent;
this.facilityTreeListCtrl1.RefreshDataEvent += () => { RefreshData(); };
this.systemCurveChartCtrl1.RefreshCurveEvent += (u, l, a) =>
{
_curveUpperPressure = u;
_curveLowerPressure = l;
_curveAveragePressure = a;
};
}
private FacilityVmo _facility = null;
private Yw.Ahart.CubicCurve _curveUpperPressure = null;
private Yw.Ahart.CubicCurve _curveLowerPressure = null;
private Yw.Ahart.CubicCurve _curveAveragePressure = null;
///
/// 初始化数据源
///
public override async void InitialDataSource()
{
base.InitialDataSource();
var allFacilityList = await BLLFactory.Instance.GetAll();
this.facilityTreeListCtrl1.SetBindingData(allFacilityList);
}
//选择设施
private void FacilityTreeListCtrl1_SelectFacilityEvent(FacilityVmo obj)
{
InitialData(obj);
}
///
/// 初始化数据
///
public void InitialData(FacilityVmo obj)
{
_facility = obj;
this.facilityPropertyCtrl1.SetBindingData(obj);
this.systemCurveChartCtrl1.Clear();
}
#region 计算
///
/// 计算系统曲线
///
///
///
///
///
///
///
private void CalcSystemCurve(
string inpFilePath,
double minDemand,
double maxDemand,
double maxHeight,
double requiredEndPressure,
int calcCount)
{
var nodeConfig = new List();
var waterPointCalcList = new List(calcCount);
using (var helper = new Yw.Epanet.InteropXHelper())
{
var code = helper.Open(inpFilePath, "", "");
CheckCode(code);
code = helper.GetCount(Yw.Epanet.eCountType.Node, out int totalNodeCount);
CheckCode(code);
var rand = new Random();
for (int nodeIndex = 1; nodeIndex <= totalNodeCount; nodeIndex++)
{
helper.GetNodeType(nodeIndex, out Yw.Epanet.eNodeType nodeType);
if (nodeType == Yw.Epanet.eNodeType.Junction)
{
code = helper.GetNodeId(nodeIndex, out string id);
if (!id.Contains("M"))
{
continue;
}
helper.GetNodeValue(nodeIndex, Yw.Epanet.eNodeProperty.Elevation, out double elevation);
nodeConfig.Add(new WaterDistributionCalculator.NodeConfig()
{
NodeIndex = nodeIndex,
Elevation = elevation,
MinFlow = 0,
MaxFlow = rand.NextDouble() * 5
});
}
}
var userNodeCount = nodeConfig.Count;
var calculator = new WaterDistributionCalculator(nodeConfig, calcCount, minDemand, maxDemand);
var allDemands = calculator.CalculateDistributions();
code = helper.OpenH();
CheckCode(code);
for (int count = 0; count < allDemands.Count; count++)
{
var calcNodelDict = new Dictionary(userNodeCount);
var calcEndPressure = double.MaxValue;
code = helper.InitH(false);
CheckCode(code);
var demands = allDemands[count];
foreach (var node in nodeConfig)
{
var userNodeIndex = node.NodeIndex;
double demand = demands.NodeFlows[userNodeIndex];
code = helper.SetNodeValue(userNodeIndex, Yw.Epanet.eNodeProperty.BaseDemand, demand);
CheckCode(code);
calcNodelDict[userNodeIndex] = new WaterPointNodeViewModel()
{
Index = userNodeIndex,
Flow = demand
};
}
code = helper.RunH(out long t);
CheckCode(code);
foreach (var node in nodeConfig)
{
var userNodeIndex = node.NodeIndex;
//自由压力=绝对压力-标高
//默认起始点压力为最低水位,所以用 绝对压力 当自由压力 (绝对压力=自由压力+标高)
code = helper.GetNodeValue(userNodeIndex, Yw.Epanet.eNodeProperty.Head, out double head);
CheckCode(code);
var endPressure = head;
calcNodelDict[userNodeIndex].Pressure = endPressure;
if (calcEndPressure > endPressure)
{
calcEndPressure = endPressure;
}
}
code = helper.NextH(out long tstep);
CheckCode(code);
var waterPointCalc = new WaterPointCalcViewModel();
waterPointCalc.TotalFlow = demands.TotalDemand;
waterPointCalc.EndPressure = Math.Abs(calcEndPressure) + maxHeight + requiredEndPressure;
waterPointCalc.NodeList = calcNodelDict.Values.ToList();
waterPointCalcList.Add(waterPointCalc);
}
code = helper.Close();
CheckCode(code);
}
this.systemCurveChartCtrl1.SetBindingData(waterPointCalcList);
}
private void CheckCode(Yw.Epanet.eErrorCode code)
{
if (code != Yw.Epanet.eErrorCode.OK)
{
if ((int)code > 100)
{
var msg = code.GetDisplayText();
//TipFormHelper.ShowError(msg);
throw new Exception(msg);
}
}
}
//计算
private void barBtnCalc_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
if (_facility == null)
{
TipFormHelper.ShowWarn("请选择设施!");
return;
}
var file_path = _facility.ModelPath;
var minDemand = 0; // 最小总需水量(m³/h)
var maxDemand = _facility.MaxWaterDemand ?? 45; // 最大总需水量(m³/h)
var calcCount = 1000; // 计算次数
var maxHeight = 22.5; //顶楼标高
var requiredEndPressure = _facility.TerminalPressure ?? 15; //静压
CalcSystemCurve(file_path, minDemand, maxDemand, maxHeight, requiredEndPressure, calcCount);
}
#endregion
#region 模拟计算
//模拟计算
private void barBtnSimulationCalc_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e)
{
if (_facility==null)
{
return;
}
if (_curveAveragePressure==null)
{
TipFormHelper.ShowWarn("请先计算曲线!");
return;
}
var page = new SimulationSchedulePage();
page.Dock = DockStyle.Fill;
page.InitialData(_facility, _curveUpperPressure, _curveLowerPressure, _curveAveragePressure);
var dlg = new XtraForm();
dlg.Text = "模拟计算";
dlg.IconOptions.Icon = Yw.WinFrmUI.GlobalParas.AppIcon;
dlg.Controls.Add(page);
dlg.StartPosition = FormStartPosition.CenterScreen;
dlg.WindowState = FormWindowState.Maximized;
dlg.ShowDialog();
}
#endregion
///
/// 刷新数据
///
public override void RefreshData()
{
base.RefreshData();
InitialDataSource();
}
}
}