cloudflight
2024-06-08 970022ca59c5c22cf572c458c01e0328be85a253
Hydraulic/Hydro.MapView/MapViewNetWork2Inp.cs
@@ -1,5 +1,6 @@
using Hydro.Core.Model;
using Hydro.MapView.Common;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Drawing;
@@ -13,12 +14,12 @@
using static Hydro.Core.ObjectEnum;
using static Hydro.MapView.RepeaterViewModel;
using static System.Math;
namespace Hydro.MapView
{
    partial class MapViewNetWork
    public partial class MapViewNetWork
    {
        public bool BuildFromInp(string filePath, bool use_old=false)
        public bool BuildFromInp(string filePath, bool use_old = false)
        {
            this.use_old = use_old;
            if (this.use_old)
@@ -33,8 +34,6 @@
            {
                Nodes = new NodeViewModelList();
                Links = new LinkViewModelList();
                string line;
                string section = "";
@@ -58,14 +57,17 @@
                                {
                                    NodeViewModel j = null;
                                    if (parts[-2] == "Meter")
                                        j = new MeterViewModel();
                                    {
                                        var m = new MeterViewModel();
                                        m.DlTemplateID = parts.ToString(-4, "");
                                        j = m;
                                    }
                                    else if (parts[-2] == "Nozzle")
                                    {
                                        var n = new NozzleViewModel();
                                        j = n;
                                        n.FlowCoefficient = parts.ToFloat(-4, 0);
                                    }
                                    else
                                        j = new JunctionViewModel();
@@ -76,10 +78,11 @@
                                    j.PatternID = parts.ToString(3, null);
                                    if (j.PatternID == "NONE") j.PatternID = null;
                                    j.Level = parts.ToInt(-1, 0);
                                    Nodes.Add(j);
                                }
                                break;
                            case "RESERVOIRS":
                                {
                                    ReservoirViewModel r = new ReservoirViewModel();
@@ -92,6 +95,7 @@
                                    Nodes.Add(r);
                                }
                                break;
                            case "TANKS":
                                {
                                    TankViewModel tank = new TankViewModel();
@@ -109,9 +113,9 @@
                                    Nodes.Add(tank);
                                }
                                break;
                            case "PIPES":
                                {
                                    if (parts[-2] == "Repeater")
                                    {
                                        RepeaterViewModel repeater = new RepeaterViewModel();
@@ -151,12 +155,9 @@
                                        p.MinorLoss = parts.ToFloat(6, 0);
                                        p.Status = StringToStatus(parts.ToString(7, "OPEN"));
                                        p.Level = parts.ToInt(-1, 0);
                                        Links.Add(p);
                                    }
                                }
                                break;
@@ -177,6 +178,7 @@
                                    Links.Add(valve);
                                }
                                break;
                            case "PUMPS":
                                {
                                    PumpViewModel pump = new PumpViewModel();
@@ -196,6 +198,7 @@
                                            case "HEAD":
                                                pump.HeadCurve = parts.ToString(index + 1, "PumpDefault");
                                                break;
                                            case "SPEED":
                                                pump.当前转速 = parts.ToFloat(index + 1, 0);
                                                break;
@@ -208,6 +211,7 @@
                                    Links.Add(pump);
                                }
                                break;
                            case "CURVES":
                                {
                                    string ID = parts.ToString(0, "");
@@ -219,6 +223,7 @@
                                    dict_dataset[ID]._data.Add(new PointF(parts.ToFloat(1, 0), parts.ToFloat(2, 0)));
                                }
                                break;
                            case "COORDINATES":
                                {
                                    string id = parts[0];
@@ -230,6 +235,7 @@
                                    }
                                }
                                break;
                            case "STATUS":
                                {
                                    LinkViewModel link = Links.Find(l => l.ID == parts.ToString(0, null));
@@ -238,16 +244,14 @@
                                }
                                break;
                        }
                        if (o!=null)
                        if (o != null)
                        {
                            o.Tags =new TagList( parts.ToString(-3, null));
                            o.Tags = new TagList(parts.ToString(-3, null));
                        }
                    }
                }
                sr.Close();
                if (!dict_dataset.ContainsKey("GPVDefault"))
                {
                    var data = new Dataset("GPVDefault", null);
@@ -257,7 +261,6 @@
                        new PointF(100,0),
                    };
                    dict_dataset.Add("GPVDefault", data);
                }
                if (!dict_dataset.ContainsKey("PumpDefault"))
                {
@@ -292,9 +295,6 @@
                        new PointF(750f             ,31.44f),
                        new PointF(777.7777778f     ,30.37f),
                        new PointF(805.5555556f     ,29.27f),
                    };
                    dict_dataset.Add("PumpDefault", data);
                }
@@ -315,7 +315,6 @@
                    {
                        k2++;
                        if (k2 < points.Count) coor = points[k2];
                    }
                    if (k2 == points.Count)
                    {
@@ -325,49 +324,66 @@
                    J.Y = coor.Position.Y;
                    k1++;
                }
                BuildRelation();
                return true;
            }
        }
        StatusType StringToStatus(string status)
        {
        private StatusType StringToStatus(string status)
        {
            switch (status)
            {
                case "CLOESD":
                case "0":
                    return StatusType.CLOSED;
                    break;
                case "OPEN":
                case "1":
                    return StatusType.OPEN;
                    break;
                case "ACTIVE":
                    return StatusType.ACTIVE;
                    break;
                default:
                    return StatusType.DEFAULT;
                    break;
            }
        }
        /// <summary>
        /// 下拉文本框转换为显示内容
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public string ToDisplyName(string id)
        {
            if (string.IsNullOrEmpty(id))
                return null;
            var filePath = Path.Combine(Directory.GetCurrentDirectory(), "Data\\WaterEquivalent.Json");
            List<EquivalentTemplateModel> equivalentTemplateModels = new List<EquivalentTemplateModel>();
            if (File.Exists(filePath))
            {
                var json = File.ReadAllText(filePath);
                if (!string.IsNullOrEmpty(json))
                {
                    equivalentTemplateModels = JsonConvert.DeserializeObject<List<EquivalentTemplateModel>>(json);
                }
            }
            return equivalentTemplateModels.Where(x => x.ID == Convert.ToInt64(id)).FirstOrDefault().Name;
        }
        public void BuildRelation()
        {
            //读取坐标
            int k1 = 0;//表示管线索引
            int k2 = 0;//表示节点索引
            Nodes.Sort((a, b) => string.Compare(a.ID, b.ID));
            //建立点线关系链表StartNode,先将管线以Node1(节点1的ID)排序,再将Nodes按ID排序,建立两个游标k1、k2,正向一次循环,建立链表关系
            //时间复杂度 O(n)
@@ -383,7 +399,6 @@
                {
                    k2++;
                    if (k2 < Nodes.Count) J = Nodes[k2];
                }
                if (k2 == Nodes.Count)
                {
@@ -417,7 +432,6 @@
                }
                if (k2 == Nodes.Count)
                {
                    k2 = k0;
                    k1++;
                    p.Visible = false;
@@ -434,10 +448,7 @@
            //while (valveNodes.Count>0)
            //{
            //}
            foreach (ValveNodeViewModel vn in valveNodes.ToList())
            {
@@ -473,8 +484,6 @@
                Nodes.Remove(vn);
            }
            foreach (PumpNodeViewModel pn in pumpNodes.ToList())
            {
                if (pn.Links.Count != 2) continue;
@@ -483,7 +492,6 @@
                    LinkViewModel temp0 = pn.Links[0] as LinkViewModel;
                    pn.Links.RemoveAt(0);
                    pn.Links.Add(temp0);
                }
                var junc1 = AddJunction("S__" + pn.ID, pn.Position, pn.Elev);
                if (pn.Links[0].StartNode.ID == pn.ID)
@@ -522,7 +530,6 @@
            if (dict_dataset == null)
            {
                dict_dataset = new Dictionary<string, Dataset>();
            }
            pumps.ForEach(p =>
            {
@@ -549,7 +556,6 @@
                        pump.Datasets["流量扬程曲线"] = ds;
                    }
                    ds.pump = pump;
                }
                if (!pump.Datasets.ContainsKey("流量扬程曲线"))
@@ -568,7 +574,6 @@
            Hash_ID = new HashSet<string>();
            Nodes.ForEach(o => Hash_ID.Add(o.ID));
            Links.ForEach(o => Hash_ID.Add(o.ID));
        }
        public bool loadInpFile_old(string filePath)
@@ -583,10 +588,9 @@
                //tanks = new List<Tank>();
                //meters = new List<Meter>();
                Links =new LinkViewModelList();
                Links = new LinkViewModelList();
                //valves = new List<Valve>();
                //repeaters = new List<Repeater>();
                string line;
                string section = "";
@@ -632,9 +636,9 @@
                                        j.Level = level;
                                    Nodes.Add(j);
                                }
                                break;
                            case "RESERVOIRS":
                                {
                                    ReservoirViewModel r = new ReservoirViewModel();
@@ -649,6 +653,7 @@
                                    Nodes.Add(r);
                                }
                                break;
                            case "TANKS":
                                {
                                    TankViewModel tank = new TankViewModel(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], parts[6], parts[7], parts[8]);
@@ -708,6 +713,7 @@
                                    Links.Add(valve);
                                }
                                break;
                            case "REPEATERS":
                                {
                                    RepeaterViewModel repeater = new RepeaterViewModel();
@@ -736,6 +742,7 @@
                                    Links.Add(repeater);
                                }
                                break;
                            case "COORDINATES":
                                {
                                    string id = parts[0];
@@ -768,7 +775,6 @@
                    {
                        k2++;
                        if (k2 < points.Count) coor = points[k2];
                    }
                    if (k2 == points.Count)
                    {
@@ -778,12 +784,7 @@
                    J.Y = coor.Position.Y;
                    k1++;
                }
                //建立点线关系链表StartNode,先将管线以Node1(节点1的ID)排序,再将Nodes按ID排序,建立两个游标k1、k2,正向一次循环,建立链表关系
                //时间复杂度 O(n)
@@ -798,7 +799,6 @@
                    {
                        k1++;
                        if (k1 < Nodes.Count) J = Nodes[k1];
                    }
                    if (k1 == Nodes.Count)
                    {
@@ -822,7 +822,7 @@
                    while (J.ID != p.Node2 && k1 < Nodes.Count)
                    {
                        k1++;
                        if (k1 < Nodes.Count) J =Nodes[k1];
                        if (k1 < Nodes.Count) J = Nodes[k1];
                    }
                    if (k1 == Nodes.Count)
                    {
@@ -832,28 +832,26 @@
                    if (J.MaxDiameter < p.Diameter) J.MaxDiameter = p.Diameter;
                    J.Links.Add(p);
                    k2++;
                }
                return true;
            }
        }
        public void ClearMinorLoss()
        {
            Links.ForEach(l => l.MinorLoss = 0);
        }
        public void CalcLinkMinorLoss()
        {
            Links.ForEach(l => l.MinorLoss = 0);
            Nodes.ForEach(n =>
            Nodes.ForEach(n =>
            {
                var links_Down= n.ViewLinks.FindAll(l=>l.StartNode==n ?l.EN_FLOW>0:l.EN_FLOW<0);
                var links_Down = n.ViewLinks.FindAll(l => l.StartNode == n ? l.EN_FLOW > 0 : l.EN_FLOW < 0);
                var links_Up = n.ViewLinks.FindAll(l => l.StartNode == n ? l.EN_FLOW < 0 : l.EN_FLOW > 0);
                /*两侧均连接一个管线*/
                if (links_Down.Count==1 && links_Up.Count==1)
                if (links_Down.Count == 1 && links_Up.Count == 1)
                {
                    var link_Down = links_Down[0];
                    var link_Up = links_Up[0];
@@ -864,12 +862,10 @@
                    link_Up.MinorLoss += minorLoss;
                }
                /*上游管线为1根,下游管线为多个*/
                if (links_Up.Count == 1 && links_Down.Count>1)
                if (links_Up.Count == 1 && links_Down.Count > 1)
                {
                    var link_Up = links_Up[0];
                    //计算两个管线的夹角,根据夹角计算损失系数
                    foreach (var link_Down in links_Down)
                    {
@@ -879,15 +875,12 @@
                        minorLoss += GetChangeDiameterMinorLoss(link_Down, link_Up);
                        link_Down.MinorLoss += minorLoss;
                    }
                }
                /*下游管线为1根,上游管线为多个*/
                if (links_Up.Count > 1 && links_Down.Count == 1)
                {
                    var link_Down = links_Down[0];
                    //计算两个管线的夹角,根据夹角计算损失系数
                    foreach (var link_Up in links_Up)
@@ -898,20 +891,16 @@
                        minorLoss += GetChangeDiameterMinorLoss(link_Down, link_Up);
                        link_Up.MinorLoss += minorLoss;
                    }
                }
                /*下游管线为多个,上游管线为多个*/
                if (links_Up.Count > 1 && links_Down.Count > 1)
                {
                    var UpCount= links_Up.Count;
                    var UpCount = links_Up.Count;
                    //计算两个管线的夹角,根据夹角计算损失系数
                    foreach (var link_Up in links_Up)
                    {
                        foreach (var link_Down in links_Down)
                        {
                            var angle = GetAngle(link_Down, link_Up);
@@ -920,60 +909,50 @@
                            minorLoss += GetChangeDiameterMinorLoss(link_Down, link_Up);
                            link_Up.MinorLoss += minorLoss / UpCount;
                        }
                    }
                }
            });
        }
        private static float GetChangeDiameterMinorLoss(LinkViewModel link_Down, LinkViewModel link_Up)
        {
            var Diameter_Down = link_Down.Diameter;
            var Diameter_Down = link_Down.Diameter;
            var Diameter_Up = link_Up.Diameter;
            //计算两个管线变径的损失系数
            var minorLoss = 0f;
            if(Diameter_Down>=Diameter_Up)//突然变粗
            if (Diameter_Down >= Diameter_Up)//突然变粗
            {
                minorLoss = (float)Pow(1 - Diameter_Up/ Diameter_Down,2);
                minorLoss = (float)Pow(1 - Diameter_Up / Diameter_Down, 2);
            }
            else//突然变细
            {
                minorLoss = 0.5f * (1 - Diameter_Down / Diameter_Up);
            }
            return minorLoss;
        }
        private static double GetAngle(LinkViewModel link_Down, LinkViewModel link_Up)
        {
            //两个管线link_Down,link_Up的向量
            Vector3D vector_Down = new Vector3D(link_Down.EndNode.X - link_Down.StartNode.X, link_Down.EndNode.Y - link_Down.StartNode.Y, link_Down.EndNode.Elev- link_Down.StartNode.Elev);
            Vector3D vector_Up=new Vector3D(link_Up.EndNode.X - link_Up.StartNode.X, link_Up.EndNode.Y - link_Up.StartNode.Y, link_Up.EndNode.Elev - link_Up.StartNode.Elev);
            Vector3D vector_Down = new Vector3D(link_Down.EndNode.X - link_Down.StartNode.X, link_Down.EndNode.Y - link_Down.StartNode.Y, link_Down.EndNode.Elev - link_Down.StartNode.Elev);
            Vector3D vector_Up = new Vector3D(link_Up.EndNode.X - link_Up.StartNode.X, link_Up.EndNode.Y - link_Up.StartNode.Y, link_Up.EndNode.Elev - link_Up.StartNode.Elev);
            //获取两个向量vector_Down,vector_Up的空间夹角
            if (vector_Down.Length == 0 || vector_Up.Length == 0) return 0;
            else
                return Vector3D.CalculateAngle(vector_Down, vector_Up);
        }
        private static float GetMinorLossByAngle(double angle)
        {
            double minorLoss;
            minorLoss=0.946 * Pow(Sin(Abs(angle) / 2),2)+2.05* Pow(Sin(Abs(angle) / 2),4);
            minorLoss = 0.946 * Pow(Sin(Abs(angle) / 2), 2) + 2.05 * Pow(Sin(Abs(angle) / 2), 4);
            return (float)minorLoss;
        }
        public void BuildToInp(string filePath, string userCoorString = null, string sourcePath = null, bool isReplace = false)
        {
            if (sourcePath == null) sourcePath = filePath;
            string tempString = "";
@@ -991,7 +970,6 @@
            {
                tempString = File.ReadAllText(sourcePath);
            }
            Dictionary<string, string> dictExchange = new Dictionary<string, string>() {
                {"{junctions}","{0}" },
@@ -1017,7 +995,7 @@
                if (o is JunctionViewModel j)
                    junctionStringBuilder.AppendLine(j.ToString() + $"{j.Level}\tJunction\t{o.Tags}");
                else if (o is MeterViewModel m)
                    junctionStringBuilder.AppendLine(m.ToString() + $"{o.Level}\tMeter\t{o.Tags}");
                    junctionStringBuilder.AppendLine(m.ToString() + $"{o.Level}\tMeter\t{o.Tags}\t{m.DlTemplateID}");
                else if (o is NozzleViewModel no)
                    junctionStringBuilder.AppendLine(no.ToString() + $"{o.Level}\tNozzle\t{o.Tags}\t{no.FlowCoefficient}");
            });
@@ -1082,10 +1060,7 @@
            });
            string pumpString = pumpStringBuilder.ToString();
            StringBuilder curveStringBuilder = new StringBuilder();
            //pumps.ForEach(o =>
            //{
@@ -1093,22 +1068,20 @@
            //    curveStringBuilder.AppendLine(o.Datasets["流量扬程曲线"].ToString());
            //});
            curveStringBuilder.AppendLine(@";ID                 X-Value        Y-Value
;HEADLOSS:
 GPVDefault         0              0
;HEADLOSS:
 GPVDefault         0              0
 GPVDefault         100            0           ");
            if (dict_dataset != null)
                curveStringBuilder.AppendLine(";PUMP: ");
                foreach (var kp in dict_dataset)
                {
                    curveStringBuilder.AppendLine(kp.Value.ToString());
                }
            foreach (var kp in dict_dataset)
            {
                curveStringBuilder.AppendLine(kp.Value.ToString());
            }
            string curveString = curveStringBuilder.ToString();
            StringBuilder coorStringBuilder = new StringBuilder();
            if (userCoorString == null)
            {
                coorStringBuilder.AppendLine(";Node               X-Coord              Y-Coord");
                Nodes.ForEach(o => coorStringBuilder.AppendLine(o.ToCoorString()));
            }
@@ -1117,36 +1090,20 @@
                coorStringBuilder.Append(userCoorString);
            }
            string coorString = coorStringBuilder.ToString();
            string output = "";
            StringBuilder emitterStringBuilder = new StringBuilder();
            emitterStringBuilder.AppendLine(";Junction        \tCoefficient");
            Nodes.ForEach(o => emitterStringBuilder.Append((o).ToEmitterString()));
            string emitterString = emitterStringBuilder.ToString();
            StringBuilder statusStringBuilder = new StringBuilder();
            statusStringBuilder.AppendLine(";ID              \tStatus/Setting\r\n");
            Links.ForEach(o => statusStringBuilder.Append(o.ToStatusString()));
            string statusString = statusStringBuilder.ToString();
            output = tempString;
@@ -1157,7 +1114,6 @@
            output = replaceContent(output, "VALVES", valveString);
            output = replaceContent(output, "PUMPS", pumpString);
            output = replaceContent(output, "CURVES", curveString);
            output = replaceContent(output, "COORDINATES", coorString);
            output = replaceContent(output, "EMITTERS", emitterString);
@@ -1171,7 +1127,6 @@
            string backupFileName = $"{Path.GetFileNameWithoutExtension(filePath)}_{DateTime.Now:yyyyMMddHHmmss}{Path.GetExtension(filePath)}";
            string backupFilePath = Path.Combine(backupFolderPath, backupFileName);
            //if (File.Exists(filePath)) File.Copy(filePath, backupFilePath, true);
            // 检查文件是否存在
            try
@@ -1190,8 +1145,6 @@
        private string replaceContent(string text, string content, string replaceString)
        {
            string str = replaceString;
            string replacedText = ReplaceCoordinatesSection(text, content, str);
@@ -1220,8 +1173,8 @@
            return replacedText;
        }
    }
    public class Vector3D
    {
        public double X { get; set; }
@@ -1234,6 +1187,7 @@
            Y = y;
            Z = z;
        }
        public static double CalculateAngle(Vector3D v1, Vector3D v2)
        {
            // 计算两个向量的点积
@@ -1251,12 +1205,13 @@
            return angleInRadians;
        }
        public double Length
        {
            get
            {
                return Math.Sqrt( X * X + Y * Y + Z * Z);
                return Math.Sqrt(X * X + Y * Y + Z * Z);
            }
        }
    }
}
}