using System.Net.Http.Headers; namespace Yw.EPAnet { /// /// 管网能耗分析拓展 /// public static class NetworkEnergyAnalyseExtensions { /// /// 分析整个管网的能量 /// public static List AnalyzeEnergy(this Network network,CalcuResult calcuResult) { var dictLinks = calcuResult.LinkList.ToDictionary(p => p.Id); var dictNodes = calcuResult.NodeList.ToDictionary(p => p.Id); var points=new List(); var result = new EnergyResult(); //找到管网中需水量为负的节点 var negativeDemandNodes = network.GetAllNodes().Where(n => { if (n is Node node) { return dictNodes[node.Id].Demand < 0; } return false; }).ToList(); //计算这些节点的势能,势能计算公式为:势能=需水量*节点水头 foreach (var node in negativeDemandNodes) { if (node is Node n) { double energyInW = GetEnergyPowerByQH(Math.Abs(dictNodes[n.Id].Demand), dictNodes[n.Id].Head); var energyPoint = new EnergyPoint { Id = n.Id, EnergyType = eEnergyType.Input, EnergyPower = energyInW, }; points.Add(energyPoint); result.InputEnergy.Add(n.Id,new List { energyPoint }); result.InputTotalEnerge += energyInW; } } //找到管网中需水量为正的节点 var positiveDemandNodes = network.GetAllNodes().Where(n => { if (n is Node node) { return dictNodes[node.Id].Demand > 0; } return false; }).ToList(); foreach (var node in positiveDemandNodes) { if (node is Node n) { double energyInW = GetEnergyPowerByQH(Math.Abs(dictNodes[n.Id].Demand), dictNodes[n.Id].Head); var energyPoint = new EnergyPoint { Id = n.Id, EnergyType = eEnergyType.Output, EnergyPower = energyInW, }; points.Add(energyPoint); result.OutputEnergy.Add(n.Id, new List { energyPoint }); result.OutputTotalEnerge += energyInW; } } foreach (var link in network.GetAllLinks()) { if (link is Pipe p) { var cStartnode = (dictLinks[ link.Id].Flow > 0 ? link.StartNode : link.EndNode) as Node; var cEndnode = (dictLinks[link.Id].Flow > 0 ? link.EndNode : link.StartNode) as Node; var endNodeMinorlossCoff = p.EndMinorloss; var startNodeMinorlossCoff = p.StartMinorloss; //根据p.diameter和p.flow计算流速 double velocity = dictLinks[p.Id].Flow / (Math.PI * Math.Pow(p.Diameter / 2, 2)); var flow = Math.Abs(dictLinks[p.Id].Flow); if (p.StartMinorloss!=0) { //根据流速计算局部水头损失 double headminorloss1 = p.StartMinorloss * Math.Pow(velocity, 2) / 2 / 9.81; double energypower=GetEnergyPowerByQH(flow, headminorloss1); var Id = cStartnode.Id; if (!result.LossEnergy.ContainsKey(Id)) result.LossEnergy.Add(Id, new List()); var energypoint=new EnergyPoint { Id = Id, EnergyType = eEnergyType.MinorLoss, EnergyPower = energypower, }; result.MinorLossTotalEnerge += energypower; //如果存在多个局部水头损失,需要累加合并 if (result.LossEnergy[Id].Any(e => e.EnergyType == eEnergyType.MinorLoss)) { var exist = result.LossEnergy[Id].First(e => e.EnergyType == eEnergyType.MinorLoss); exist.EnergyPower += energypower; } else { result.LossEnergy[Id].Add(energypoint); } var point = result.LossEnergy[Id].First(e => e.EnergyType == eEnergyType.MinorLoss); points.Add(point); } if (p.EndMinorloss != 0) { //根据流速计算局部水头损失 double headminorloss2 = p.EndMinorloss * Math.Pow(velocity, 2) / 2 / 9.81; double energypower = GetEnergyPowerByQH(flow, headminorloss2); var Id = cEndnode.Id; if (!result.LossEnergy.ContainsKey(Id)) result.LossEnergy.Add(Id, new List()); var energypoint = new EnergyPoint { Id = Id, EnergyType = eEnergyType.MinorLoss, EnergyPower = energypower, }; result.MinorLossTotalEnerge += energypower; //如果存在多个局部水头损失,需要累加合并 if (result.LossEnergy[Id].Any(e => e.EnergyType == eEnergyType.MinorLoss)) { var exist = result.LossEnergy[Id].First(e => e.EnergyType == eEnergyType.MinorLoss); exist.EnergyPower += energypower; } else { result.LossEnergy[Id].Add(energypoint); } var point = result.LossEnergy[Id].First(e => e.EnergyType == eEnergyType.MinorLoss); points.Add(point); } double pipeheadminorloss = 0; if (p.MinorLoss!=0) { //根据流速计算局部水头损失 pipeheadminorloss = p.MinorLoss * Math.Pow(velocity, 2) / 2 / 9.81; double energypower = GetEnergyPowerByQH(flow, pipeheadminorloss); var Id = p.Id; if (!result.LossEnergy.ContainsKey(Id)) result.LossEnergy.Add(Id, new List()); var energypoint = new EnergyPoint { Id = Id, EnergyType = eEnergyType.MinorLoss, EnergyPower = energypower, }; result.LossEnergy[Id].Add(energypoint); result.MinorLossTotalEnerge += energypower; points.Add(energypoint); } { double headlossFriction =Math.Abs(dictLinks[p.Id].Headloss) - pipeheadminorloss; double energypower = GetEnergyPowerByQH(flow, headlossFriction); var Id = p.Id; if (!result.LossEnergy.ContainsKey(Id)) result.LossEnergy.Add(Id, new List()); var energypoint = new EnergyPoint { Id = Id, EnergyType = eEnergyType.FrictionalLoss, EnergyPower = energypower, }; result.LossEnergy[Id].Add(energypoint); result.FrictionalLossTotalEnerge += energypower; points.Add(energypoint); } } else if (link is Valve || link is Pump || link is Resistance) { //只计算阀门本身的局部水头损失 var flow = Math.Abs(dictLinks[link.Id].Flow); //根据流速计算局部水头损失 double headminorloss1 =Math.Abs(dictNodes[link.StartNode.Id].Head - dictNodes[link.EndNode.Id].Head); double energypower = GetEnergyPowerByQH(flow, headminorloss1); var Id = link.Id; if (link is Pump) { var Type = eEnergyType.Promote; if (!result.InputEnergy.ContainsKey(Id)) result.InputEnergy.Add(Id, new List()); var energypoint = new EnergyPoint { Id = Id, EnergyType = Type, EnergyPower = energypower, }; result.InputEnergy[Id].Add(energypoint); result.InputTotalEnerge += energypower; points.Add(energypoint); } else { var Type = eEnergyType.MinorLoss; if (!result.LossEnergy.ContainsKey(Id)) result.LossEnergy.Add(Id, new List()); EnergyPoint energypoint = new EnergyPoint { Id = Id, EnergyType = Type, EnergyPower = energypower, }; result.LossEnergy[Id].Add(energypoint); result.MinorLossTotalEnerge += energypower; points.Add(energypoint); } } } return points; } private static double GetEnergyPowerByQH(double flowQ,double head) { // 计算将 1 m³的水,提升 1 m 的高度所需要的能量 // 1 m³的水受到重力G=1m³ * 1000 kg/m³(密度) * 9.81 m/s² (重力加速度) = 9810 N // 能量 = 力 * 距离 = 9810 N * 1 m = 9810 J // 势能等效功率 = 能量 / 时间 = 9810 J / 1 h = 9810 J/h = 9810/3600 J/s= 9810/3600 W double energyInM4PerH = flowQ * head; double energyInW = energyInM4PerH * 1000 * 9.81 / 3600; return energyInW; } } public class EnergyPoint { public string Id { get; set; } public eEnergyType EnergyType { get; set; } /// /// 单位时间内的能量,单位:瓦特W=焦耳J/秒s /// public double EnergyPower { get; set; } } public class EnergyResult { public Dictionary> InputEnergy { get; set; } public Dictionary> LossEnergy { get; set; } public Dictionary> OutputEnergy { get; set; } public double InitTotalEnerge { get; set; } public double InputTotalEnerge { get; set; } public double MinorLossTotalEnerge { get; set; } public double FrictionalLossTotalEnerge { get; set; } public double OutputTotalEnerge { get; set; } public EnergyResult() { InputEnergy = new Dictionary>(); LossEnergy = new Dictionary>(); OutputEnergy = new Dictionary>(); InputTotalEnerge = 0; MinorLossTotalEnerge = 0; FrictionalLossTotalEnerge = 0; OutputTotalEnerge = 0; } } public enum eEnergyType { /// /// 重力势能输入:水池、水库 /// Input, /// /// 重力势能输出:水池、水库、扩散器 /// Output, /// /// 水泵提升能量(输入系统的有效功率),不考虑效率 /// Promote, /// /// 局部摩擦阻力带来的能量损失:阀门、连接节点、管道、设备(换热器、空压机) /// MinorLoss, /// /// 沿程摩擦阻力带来的能量损失:管道 /// FrictionalLoss, } }