using System.Data;
|
using System.Drawing;
|
using System.Text;
|
|
namespace Yw.EPAnet
|
{
|
/// <summary>
|
/// 管网路径分析拓展
|
/// </summary>
|
public static class NetworkPathAnalyseExtensions
|
{
|
internal class InnerLossNode
|
{
|
public string Id { get; set; }
|
/// <summary>
|
/// 起始水头
|
/// </summary>
|
public double StartHead { get; set; }
|
|
/// <summary>
|
/// 结束水头
|
/// </summary>
|
public double EndHead { get; set; }
|
|
/// <summary>
|
/// 高程
|
/// </summary>
|
public double Elev { get; set; }
|
|
/// <summary>
|
/// 水头
|
/// </summary>
|
public double Head { get; internal set; }
|
|
/// <summary>
|
/// 局部水头损失
|
/// </summary>
|
public double MinorHeadLoss
|
{
|
get
|
{
|
return StartHead - EndHead;
|
}
|
}
|
|
public double Distance { get; set; }
|
}
|
|
public static List<LossNode> GetChartNodeByPathLinks(this Network network, List<Link> links,CalcuResult calcuResult)
|
{
|
|
var dictLinks = calcuResult.LinkList.ToDictionary(p => p.Id);
|
var dictNodes = calcuResult.NodeList.ToDictionary(p => p.Id);
|
|
double length = 0;
|
InnerLossNode nodeEnd = new InnerLossNode();
|
List<InnerLossNode> chartNodes = new List<InnerLossNode>();
|
for (int i = 0; i < links.Count; i++)
|
{
|
|
var link = links[i];
|
|
var node = dictLinks[link.Id].Flow > 0 ? link.StartNode : link.EndNode;
|
|
double elev = getElev(node);
|
|
|
var Cnode = new InnerLossNode()
|
{
|
Id = node.Id,
|
StartHead = dictNodes[node.Id].Head,
|
EndHead = dictNodes[node.Id].Head,
|
Elev = elev,
|
Distance = length
|
};
|
chartNodes.Add(Cnode);
|
|
|
var nodeEnd0 = dictLinks[link.Id].Flow > 0 ? link.EndNode : link.StartNode;
|
nodeEnd.Id = nodeEnd0.Id;
|
nodeEnd.Head = nodeEnd.StartHead = nodeEnd.EndHead = dictNodes[nodeEnd0.Id].Head;
|
nodeEnd.Elev = getElev(nodeEnd0);
|
|
if (link is Pipe p)
|
length += p.Length;
|
|
}
|
|
chartNodes.Add(nodeEnd);
|
|
for (int i=0;i<links.Count;i++)
|
{
|
|
var link = links[i];
|
|
Pipe p=link as Pipe;
|
|
if (p != null)
|
{
|
//根据p.diameter和p.flow计算流速
|
double velocity = dictLinks[ p.Id].Flow/ (Math.PI * Math.Pow(p.Diameter / 2, 2));
|
//根据流速计算局部水头损失
|
double minorloss1 = p.StartMinorloss* Math.Pow(velocity, 2) / 2 / 9.81;
|
double minorloss2 = p.EndMinorloss * Math.Pow(velocity, 2) / 2 / 9.81;
|
|
|
if (i < links.Count - 1)
|
{
|
|
chartNodes[i].EndHead = chartNodes[i].Head - minorloss1;
|
|
chartNodes[i + 1].StartHead = chartNodes[i].EndHead - minorloss2;
|
|
|
}
|
else
|
{
|
chartNodes[i].EndHead = chartNodes[i].Head - minorloss1;
|
}
|
|
}
|
|
|
}
|
List<LossNode> lossNodes = new List<LossNode>();
|
for (int i = 0; i < chartNodes.Count; i++)
|
{
|
var node = chartNodes[i];
|
LossNode lossNode = new LossNode()
|
{
|
Id = node.Id,
|
Elev = node.Elev,
|
Head = node.StartHead,
|
MinorLoss = node.MinorHeadLoss,
|
Distance =node.Distance,
|
};
|
lossNodes.Add(lossNode);
|
}
|
return lossNodes;
|
|
}
|
|
private static double getElev(Node node)
|
{
|
double elev = 0;
|
if (node is Tank tank)
|
{
|
elev = tank.PoolElev + tank.InitLevel;
|
}
|
else if (node is Reservoir reser)
|
{
|
elev = reser.Head;
|
}
|
else if (node is Junction junc)
|
{
|
elev = junc.Elev;
|
}
|
|
return elev;
|
}
|
|
|
/// <summary>
|
/// 分析下游主要供水路径
|
/// </summary>
|
public static List<Link> AnalyzeDownstreamPath(this Network network, Node startJunc,CalcuResult calcuResult)
|
{
|
var dictLinks = calcuResult.LinkList.ToDictionary(p => p.Id);
|
var dictNodes = calcuResult.NodeList.ToDictionary(p => p.Id);
|
var visitedNodes = new HashSet<Node>();
|
visitedNodes.Add(startJunc);
|
var nextLinks = startJunc.GetNextLinks(calcuResult.LinkList);
|
if (nextLinks==null || nextLinks.Count <= 0) return nextLinks;
|
|
var maxlink = nextLinks.OrderByDescending(o => Math.Abs(dictLinks[o.Id].Flow)).ToList()[0];
|
return network.TraversePipeNetworkALL(maxlink, visitedNodes, 1, true, calcuResult);
|
}
|
|
/// <summary>
|
/// 分析上游主要供水路径
|
/// </summary>
|
/// <param name="network"></param>
|
/// <param name="startJunc"></param>
|
/// <returns></returns>
|
public static List<Link> AnalyzeUpstreamPath(this Network network, Junction startJunc, CalcuResult calcuResult)
|
{
|
var dictLinks = calcuResult.LinkList.ToDictionary(p => p.Id);
|
var dictNodes = calcuResult.NodeList.ToDictionary(p => p.Id);
|
var visitedNodes = new HashSet<Node>();
|
var maxlink = startJunc.GetPrevLinks(calcuResult.LinkList).OrderByDescending(o => Math.Abs(dictLinks[o.Id].Flow)).ToList()[0];
|
return network.TraversePipeNetworkALL(maxlink, visitedNodes, -1, true, calcuResult);
|
}
|
/// <summary>
|
/// 宽度搜索遍历管网
|
/// </summary>
|
/// <param name="network"></param>
|
/// <param name="startLink">起始管线</param>
|
/// <param name="visitedNodes">遍历的哈希表(用于多点遍历)</param>
|
/// <param name="direction">遍历方向,0表示双向,1表示正向,-1表示反向</param>
|
/// <param name="isOnlyMax">是否只取最大流量的分支</param>
|
/// <returns></returns>
|
public static List<Link> TraversePipeNetworkALL(this Network network, Link startLink, HashSet<Node> visitedNodes, int direction = 0, bool isOnlyMax = false,CalcuResult calcuResult=null)
|
{
|
var dictLinks = calcuResult.LinkList.ToDictionary(p => p.Id);
|
var dictNodes = calcuResult.NodeList.ToDictionary(p => p.Id);
|
var _links主要路径=new List<Link>();
|
if (isOnlyMax) _links主要路径.Add(startLink);
|
Queue<Link> queue = new Queue<Link>();
|
|
queue.Enqueue(startLink);
|
|
|
while (queue.Count > 0)
|
{
|
Link currentLink = queue.Dequeue();
|
if (isOnlyMax) _links主要路径.Add(currentLink);
|
|
foreach (var node in new Node[] { currentLink.StartNode, currentLink.EndNode })
|
{
|
if (direction == 1 && dictLinks[currentLink.Id].Flow >= 0 && node == currentLink.StartNode) continue;
|
if (direction == -1 && dictLinks[currentLink.Id].Flow <= 0 && node == currentLink.EndNode) continue;
|
if (node != null && !visitedNodes.Contains(node))
|
{
|
visitedNodes.Add(node);
|
List<Link> list = new List<Link>();
|
|
foreach (var link in node.Links)
|
{
|
if (!visitedNodes.Contains(link.StartNode) || !visitedNodes.Contains(link.EndNode))
|
{
|
list.Add(link);
|
|
}
|
}
|
if (!isOnlyMax)
|
{
|
foreach (var link in list)
|
{
|
|
queue.Enqueue(link);
|
}
|
}
|
else
|
{
|
if (list.Count >= 1)
|
{
|
var maxlist = list.OrderByDescending(p => Math.Abs(dictLinks[p.Id].Flow)).ToList()[0];
|
queue.Enqueue(maxlist);
|
}
|
|
}
|
}
|
}
|
|
}
|
return _links主要路径;
|
|
|
}
|
|
}
|
|
public class LossNode
|
{
|
public string Id { get; set; }
|
|
/// <summary>
|
/// 高程
|
/// </summary>
|
public double Elev { get; set; }
|
|
/// <summary>
|
/// 水头
|
/// </summary>
|
public double Head { get; set; }
|
|
/// <summary>
|
/// 局部水头损失
|
/// </summary>
|
public double MinorLoss { get; set; }
|
|
/// <summary>
|
/// 距离
|
/// </summary>
|
public double Distance { get; set; }
|
}
|
}
|