using System.Net.Http.Headers;
|
|
namespace Yw.EPAnet
|
{
|
/// <summary>
|
/// 管网能耗分析拓展
|
/// </summary>
|
public static class NetworkEnergyAnalyseExtensions
|
{
|
|
/// <summary>
|
/// 分析整个管网的能量
|
/// </summary>
|
public static EnergyResult AnalyzeEnergy(this Network network)
|
{
|
var result = new EnergyResult();
|
//找到管网中需水量为负的节点
|
var negativeDemandNodes = network.GetAllNodes().Where(n =>
|
{
|
if (n is Node node)
|
{
|
return node.Demand < 0;
|
}
|
return false;
|
}).ToList();
|
|
//计算这些节点的势能,势能计算公式为:势能=需水量*节点水头
|
|
foreach (var node in negativeDemandNodes)
|
{
|
if (node is Node n)
|
{
|
double energyInW = GetEnergyPowerByQH(Math.Abs( n.Demand),n.Head);
|
var energyPoint = new EnergyPoint
|
{
|
Id = n.Id,
|
Type = EnergyType.InputPotentialEnergy,
|
EnergyPower = energyInW,
|
Parter = n
|
};
|
result.InputEnergy.Add(n.Id,new List<EnergyPoint> { energyPoint });
|
result.InputTotalEnerge += energyInW;
|
}
|
}
|
|
//找到管网中需水量为正的节点
|
var positiveDemandNodes = network.GetAllNodes().Where(n =>
|
{
|
if (n is Node node)
|
{
|
return node.Demand > 0;
|
}
|
return false;
|
}).ToList();
|
|
|
|
foreach (var node in positiveDemandNodes)
|
{
|
if (node is Node n)
|
{
|
double energyInW = GetEnergyPowerByQH(Math.Abs(n.Demand), n.Head);
|
var energyPoint = new EnergyPoint
|
{
|
Id = n.Id,
|
Type = EnergyType.OutputPotentialEnergy,
|
EnergyPower = energyInW,
|
Parter = n
|
};
|
result.OutputEnergy.Add(n.Id, new List<EnergyPoint> { energyPoint });
|
result.OutputTotalEnerge += energyInW;
|
}
|
}
|
|
foreach (var link in network.GetAllLinks())
|
{
|
if (link is IPipe p)
|
{
|
|
var cStartnode = (link.Flow > 0 ? link.StartNode : link.EndNode) as Node;
|
var cEndnode = (link.Flow > 0 ? link.EndNode : link.StartNode) as Node;
|
var endNodeMinorlossCoff = p.EndNodeMinorlossCoff;
|
var startNodeMinorlossCoff = p.StartNodeMinorlossCoff;
|
//根据p.diameter和p.flow计算流速
|
double velocity = p.Flow / (Math.PI * Math.Pow(p.Diameter / 2, 2));
|
var flow = Math.Abs(p.Flow);
|
if (p.StartNodeMinorlossCoff!=0)
|
{
|
//根据流速计算局部水头损失
|
double headminorloss1 = p.StartNodeMinorlossCoff * 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<EnergyPoint>());
|
var energypoint=new EnergyPoint
|
{
|
Id = Id,
|
Type = EnergyType.MinorLossEnergy,
|
EnergyPower = energypower,
|
Parter = cStartnode
|
};
|
result.MinorLossTotalEnerge += energypower;
|
//如果存在多个局部水头损失,需要累加合并
|
if (result.LossEnergy[Id].Any(e => e.Type == EnergyType.MinorLossEnergy))
|
{
|
var exist = result.LossEnergy[Id].First(e => e.Type == EnergyType.MinorLossEnergy);
|
exist.EnergyPower += energypower;
|
}
|
else
|
{
|
result.LossEnergy[Id].Add(energypoint);
|
}
|
}
|
|
if (p.EndNodeMinorlossCoff != 0)
|
{
|
//根据流速计算局部水头损失
|
double headminorloss2 = p.EndNodeMinorlossCoff * 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<EnergyPoint>());
|
var energypoint = new EnergyPoint
|
{
|
Id = Id,
|
Type = EnergyType.MinorLossEnergy,
|
EnergyPower = energypower,
|
Parter = cEndnode
|
};
|
result.MinorLossTotalEnerge += energypower;
|
//如果存在多个局部水头损失,需要累加合并
|
if (result.LossEnergy[Id].Any(e => e.Type == EnergyType.MinorLossEnergy))
|
{
|
var exist = result.LossEnergy[Id].First(e => e.Type == EnergyType.MinorLossEnergy);
|
exist.EnergyPower += energypower;
|
}
|
else
|
{
|
result.LossEnergy[Id].Add(energypoint);
|
}
|
}
|
|
double pipeheadminorloss = 0;
|
if (p.MinorlossCoff!=0)
|
{
|
//根据流速计算局部水头损失
|
pipeheadminorloss = p.MinorlossCoff * 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<EnergyPoint>());
|
result.LossEnergy[Id].Add(new EnergyPoint
|
{
|
Id = Id,
|
Type = EnergyType.MinorLossEnergy,
|
EnergyPower = energypower,
|
Parter = p as Parter
|
});
|
result.MinorLossTotalEnerge += energypower;
|
}
|
|
|
{
|
double headlossFriction =Math.Abs(p.Headloss) - pipeheadminorloss;
|
double energypower = GetEnergyPowerByQH(flow, headlossFriction);
|
var Id = p.Id;
|
if (!result.LossEnergy.ContainsKey(Id)) result.LossEnergy.Add(Id, new List<EnergyPoint>());
|
result.LossEnergy[Id].Add(new EnergyPoint
|
{
|
Id = Id,
|
Type = EnergyType.FrictionalLossEnergy,
|
EnergyPower = energypower,
|
Parter = p as Parter
|
});
|
result.FrictionalLossTotalEnerge += energypower;
|
}
|
|
|
|
}
|
else if (link is IValve || link is IPump pump || link is IValveLink)
|
{
|
//只计算阀门本身的局部水头损失
|
var flow = Math.Abs(link.Flow);
|
//根据流速计算局部水头损失
|
double headminorloss1 =Math.Abs(link.StartNode.Head - link.EndNode.Head);
|
double energypower = GetEnergyPowerByQH(flow, headminorloss1);
|
var Id = link.Id;
|
|
if (link is IPump)
|
{
|
var Type = EnergyType.InputPumpEnergy;
|
if (!result.InputEnergy.ContainsKey(Id)) result.InputEnergy.Add(Id, new List<EnergyPoint>());
|
result.InputEnergy[Id].Add(new EnergyPoint
|
{
|
Id = Id,
|
Type = Type,
|
EnergyPower = energypower,
|
Parter = link as Parter
|
});
|
result.InputTotalEnerge += energypower;
|
}
|
else
|
{
|
var Type = EnergyType.MinorLossEnergy;
|
if (!result.LossEnergy.ContainsKey(Id)) result.LossEnergy.Add(Id, new List<EnergyPoint>());
|
result.LossEnergy[Id].Add(new EnergyPoint
|
{
|
Id = Id,
|
Type = Type,
|
EnergyPower = energypower,
|
Parter = link as Parter
|
});
|
result.MinorLossTotalEnerge += energypower;
|
}
|
|
}
|
}
|
|
return result;
|
}
|
|
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 EnergyType Type { get; set; }
|
/// <summary>
|
/// 单位时间内的能量,单位:瓦特W=焦耳J/秒s
|
/// </summary>
|
public double EnergyPower { get; set; }
|
|
public Parter Parter { get; set; }
|
}
|
|
public class EnergyResult
|
{
|
public Dictionary<string, List<EnergyPoint>> InputEnergy { get; set; }
|
public Dictionary<string, List<EnergyPoint>> LossEnergy { get; set; }
|
public Dictionary<string, List<EnergyPoint>> OutputEnergy { 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<string, List<EnergyPoint>>();
|
LossEnergy = new Dictionary<string, List<EnergyPoint>>();
|
OutputEnergy = new Dictionary<string, List<EnergyPoint>>();
|
InputTotalEnerge = 0;
|
MinorLossTotalEnerge = 0;
|
FrictionalLossTotalEnerge = 0;
|
OutputTotalEnerge = 0;
|
}
|
|
|
}
|
|
public enum EnergyType
|
{
|
/// <summary>
|
/// 重力势能输入
|
/// </summary>
|
InputPotentialEnergy,
|
/// <summary>
|
/// 重力势能输出
|
/// </summary>
|
OutputPotentialEnergy,
|
/// <summary>
|
/// 动能输出
|
/// </summary>
|
OutputKineticEnergy,
|
/// <summary>
|
/// 水泵提升能量(输入系统的有效功率),不考虑效率
|
/// </summary>
|
InputPumpEnergy,
|
/// <summary>
|
/// 局部摩擦阻力带来的能量损失
|
/// </summary>
|
MinorLossEnergy,
|
/// <summary>
|
/// 沿程摩擦阻力带来的能量损失
|
/// </summary>
|
FrictionalLossEnergy,
|
}
|
|
|
}
|