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