cloudflight
2024-11-23 e5bfcecde9a5c696b3119ae29a6b7f2eb993cb82
Hydro/Yw.EPAnet.Calcu.Core/03-calcu/NetworkPathAnalyseExtensions.cs
@@ -9,43 +9,81 @@
    /// </summary>
    public static class NetworkPathAnalyseExtensions
    {
        internal class InnerLossNode
        {
            public string Id { get; set; }
            /// <summary>
            /// 起始水头
            /// </summary>
            public double StartHead { get; set; }
        public static List<ChartNode> GetChartNodeByPathLinks(this Network network, List<ILink> links)
            /// <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;
            ChartNode nodeEnd = new ChartNode();
            List<ChartNode> chartNodes = new List<ChartNode>();
            InnerLossNode nodeEnd = new InnerLossNode();
            List<InnerLossNode> chartNodes = new List<InnerLossNode>();
            for (int i = 0; i < links.Count; i++)
            {
                var link = links[i];
                var node = link.Flow > 0 ? link.StartNode : link.EndNode;
                var node = dictLinks[link.Id].Flow > 0 ? link.StartNode : link.EndNode;
                double elev = getElev(node);
                var Cnode = new ChartNode()
                var Cnode = new InnerLossNode()
                {
                    Id = node.Id,
                    StartHead = node.Head,
                    EndHead = node.Head,
                    Elev = node.Elev
                    StartHead = dictNodes[node.Id].Head,
                    EndHead = dictNodes[node.Id].Head,
                    Elev = elev,
                    Distance = length
                };
                chartNodes.Add(Cnode);
                var nodeEnd0 = link.Flow > 0 ? link.EndNode : link.StartNode;
                var nodeEnd0 = dictLinks[link.Id].Flow > 0 ? link.EndNode : link.StartNode;
                nodeEnd.Id = nodeEnd0.Id;
                nodeEnd.Head = nodeEnd.StartHead = nodeEnd.EndHead = nodeEnd0.Head;
                nodeEnd.Elev = nodeEnd0.Elev;
                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);
@@ -60,10 +98,10 @@
                if (p != null)
                {
                    //根据p.diameter和p.flow计算流速
                    double velocity = p.Flow / (Math.PI * Math.Pow(p.Diameter / 2, 2));
                    double velocity = dictLinks[ p.Id].Flow/ (Math.PI * Math.Pow(p.Diameter / 2, 2));
                    //根据流速计算局部水头损失
                    double minorloss1 = p.StartNodeMinorlossCoff* Math.Pow(velocity, 2) / 2 / 9.81;
                    double minorloss2 = p.EndNodeMinorlossCoff * Math.Pow(velocity, 2) / 2 / 9.81;
                    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)
@@ -84,18 +122,53 @@
                
                
            }
            return chartNodes;
            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<ILink> AnalyzeDownstreamPath(this Network network, Junction startJunc)
        public static List<Link> AnalyzeDownstreamPath(this Network network, Node startJunc,CalcuResult calcuResult)
        {
            var visitedNodes = new HashSet<INode>();
            var maxlink = startJunc.NextLinks.OrderByDescending(o => Math.Abs(o.Flow)).ToList()[0];
            var dictLinks = calcuResult.LinkList.ToDictionary(p => p.Id);
            var dictNodes = calcuResult.NodeList.ToDictionary(p => p.Id);
            var visitedNodes = new HashSet<Node>();
            var maxlink = startJunc.GetNextLinks(calcuResult.LinkList).OrderByDescending(o => Math.Abs(dictLinks[o.Id].Flow)).ToList()[0];
            return  network.TraversePipeNetworkALL(maxlink, visitedNodes, 1, true);
        }
        
@@ -105,11 +178,13 @@
        /// <param name="network"></param>
        /// <param name="startJunc"></param>
        /// <returns></returns>
        public static List<ILink> AnalyzeUpstreamPath(this Network network, Junction startJunc)
        public static List<Link> AnalyzeUpstreamPath(this Network network, Junction startJunc, CalcuResult calcuResult)
        {
            var visitedNodes = new HashSet<INode>();
            var maxlink = startJunc.NextLinks.OrderByDescending(o => Math.Abs(o.Flow)).ToList()[0];
            return network.TraversePipeNetworkALL(maxlink, visitedNodes, -1, true);
            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>
        /// 宽度搜索遍历管网
@@ -120,29 +195,31 @@
        /// <param name="direction">遍历方向,0表示双向,1表示正向,-1表示反向</param>
        /// <param name="isOnlyMax">是否只取最大流量的分支</param>
        /// <returns></returns>
        public static List<ILink> TraversePipeNetworkALL(this Network network,ILink startLink, HashSet<INode> visitedNodes = null, int direction = 0, bool isOnlyMax = false)
        public static List<Link> TraversePipeNetworkALL(this Network network, Link startLink, HashSet<Node> visitedNodes = null, int direction = 0, bool isOnlyMax = false,CalcuResult calcuResult=null)
        {
            var _links主要路径=new List<ILink>();
            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<ILink> queue = new Queue<ILink>();
            Queue<Link> queue = new Queue<Link>();
            queue.Enqueue(startLink);
            if (visitedNodes == null)
                visitedNodes = new HashSet<INode>();
                visitedNodes = new HashSet<Node>();
            while (queue.Count > 0)
            {
                ILink currentLink = queue.Dequeue();
                Link currentLink = queue.Dequeue();
                if (isOnlyMax) _links主要路径.Add(currentLink);
                foreach (var node in new INode[] { currentLink.StartNode, currentLink.EndNode })
                foreach (var node in new Node[] { currentLink.StartNode, currentLink.EndNode })
                {
                    if (direction == 1 && currentLink.Flow >= 0 && node == currentLink.StartNode) continue;
                    if (direction == -1 && currentLink.Flow <= 0 && node == currentLink.EndNode) continue;
                    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<ILink> list = new List<ILink>();
                        List<Link> list = new List<Link>();
                        foreach (var link in node.Links)
                        {
@@ -164,7 +241,7 @@
                        {
                            if (list.Count >= 1)
                            {
                                var maxlist = list.OrderByDescending(p => Math.Abs(p.Flow)).ToList()[0];
                                var maxlist = list.OrderByDescending(p => Math.Abs(dictLinks[p.Id].Flow)).ToList()[0];
                                queue.Enqueue(maxlist);
                            }
@@ -180,19 +257,9 @@
    }
    public class ChartNode
    public class LossNode
    {
        public string Id { get; set; }
        /// <summary>
        /// 起始水头
        /// </summary>
        public double StartHead { get; set; }
        /// <summary>
        /// 结束水头
        /// </summary>
        public double EndHead { get; set; }
        /// <summary>
        /// 高程
@@ -202,17 +269,16 @@
        /// <summary>
        /// 水头
        /// </summary>
        public double Head { get; internal set; }
        public double Head { get; set; }
        /// <summary>
        /// 局部水头损失
        /// </summary>
        public double MinorHeadLoss
        {
            get
            {
                return StartHead - EndHead;
            }
        }
        public double MinorLoss { get; set; }
        /// <summary>
        /// 距离
        /// </summary>
        public double Distance { get; set; }
    }
}