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