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;
|
|
/// <summary>
|
/// 初始化数据源
|
/// </summary>
|
public override async void InitialDataSource()
|
{
|
base.InitialDataSource();
|
|
var allFacilityList = await BLLFactory<BLL.Facility>.Instance.GetAll();
|
this.facilityTreeListCtrl1.SetBindingData(allFacilityList);
|
|
}
|
|
//选择设施
|
private void FacilityTreeListCtrl1_SelectFacilityEvent(FacilityVmo obj)
|
{
|
InitialData(obj);
|
}
|
|
/// <summary>
|
/// 初始化数据
|
/// </summary>
|
public void InitialData(FacilityVmo obj)
|
{
|
_facility = obj;
|
this.facilityPropertyCtrl1.SetBindingData(obj);
|
this.systemCurveChartCtrl1.Clear();
|
|
}
|
|
#region 计算
|
|
/// <summary>
|
/// 计算系统曲线
|
/// </summary>
|
/// <param name="inpFilePath"></param>
|
/// <param name="minDemand"></param>
|
/// <param name="maxDemand"></param>
|
/// <param name="maxHeight"></param>
|
/// <param name="requiredEndPressure"></param>
|
/// <param name="calcCount"></param>
|
private void CalcSystemCurve(
|
string inpFilePath,
|
double minDemand,
|
double maxDemand,
|
double maxHeight,
|
double requiredEndPressure,
|
int calcCount)
|
{
|
var nodeConfig = new List<WaterDistributionCalculator.NodeConfig>();
|
var waterPointCalcList = new List<WaterPointCalcViewModel>(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<int, WaterPointNodeViewModel>(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
|
|
/// <summary>
|
/// 刷新数据
|
/// </summary>
|
public override void RefreshData()
|
{
|
base.RefreshData();
|
InitialDataSource();
|
}
|
|
|
}
|
|
}
|