¶Ô±ÈÐÂÎļþ |
| | |
| | | using Hydro.CommonBase; |
| | | using Hydro.Core.Model; |
| | | //using Hydro.HydraulicModel; |
| | | using System; |
| | | using System.Collections.Generic; |
| | | using System.Data; |
| | | using System.Drawing; |
| | | using System.IO; |
| | | using System.IO.Ports; |
| | | using System.Linq; |
| | | using System.Text; |
| | | using System.Text.RegularExpressions; |
| | | using System.Threading; |
| | | using System.Threading.Tasks; |
| | | using System.Xml.Linq; |
| | | using static Hydro.Core.EpanetEnum; |
| | | using static Hydro.Core.ObjectEnum; |
| | | |
| | | namespace Hydro.Core |
| | | { |
| | | [Serializable] |
| | | public class NetWork //: INetWork |
| | | { |
| | | public NetWork() |
| | | { |
| | | } |
| | | |
| | | public List<JunctionModel> Junctions |
| | | { |
| | | get |
| | | { |
| | | var js = Nodes.Where(d => d is JunctionModel); |
| | | return js?.Select(d => d as JunctionModel).ToList(); |
| | | } |
| | | |
| | | } |
| | | public List<TankModel> Tanks |
| | | { |
| | | get |
| | | { |
| | | var js = Nodes.Where(d => d is TankModel); |
| | | return js?.Select(d => d as TankModel).ToList(); |
| | | } |
| | | } |
| | | |
| | | public List<PipeModel> Pipes |
| | | { |
| | | get |
| | | { |
| | | var js = Links.Where(d => d is PipeModel); |
| | | return js?.Select(d => d as PipeModel).ToList(); |
| | | } |
| | | } |
| | | |
| | | public List<PumpModel> Pumps |
| | | { |
| | | get |
| | | { |
| | | var js = Links.Where(d => d is PumpModel); |
| | | return js?.Select(d => d as PumpModel).ToList(); |
| | | } |
| | | } |
| | | |
| | | public List<ValveModel> Valves |
| | | { |
| | | get |
| | | { |
| | | var js = Links.Where(d => d is ValveModel); |
| | | return js?.Select(d => d as ValveModel).ToList(); |
| | | } |
| | | } |
| | | |
| | | public List<ReservoisModel> Reservos |
| | | { |
| | | get |
| | | { |
| | | var js = Nodes.Where(d => d is ReservoisModel); |
| | | return js?.Select(d => d as ReservoisModel).ToList(); |
| | | } |
| | | } |
| | | |
| | | public List<MeterModel> Meters |
| | | { |
| | | get |
| | | { |
| | | var js = Nodes.Where(d => d is MeterModel); |
| | | return js?.Select(d => d as MeterModel).ToList(); |
| | | } |
| | | } |
| | | |
| | | public List<NozzleModel> Nozzles |
| | | { |
| | | get |
| | | { |
| | | var js = Nodes.Where(d => d is NozzleModel); |
| | | return js?.Select(d => d as NozzleModel).ToList(); |
| | | } |
| | | } |
| | | |
| | | public virtual void AddJunction(JunctionModel junction) |
| | | { |
| | | CheckNodesExist(junction); |
| | | Nodes.Add(junction); |
| | | } |
| | | |
| | | public virtual void AddJunctions(List<JunctionModel> junctions) |
| | | { |
| | | junctions.ForEach(junction => { AddJunction(junction); }); |
| | | } |
| | | |
| | | public virtual void AddTank(TankModel tank) |
| | | { |
| | | CheckNodesExist(tank); |
| | | Nodes.Add(tank); |
| | | } |
| | | |
| | | public virtual void AddTanks(List<TankModel> tanks) |
| | | { |
| | | tanks.ForEach(tank => { AddTank(tank); }); |
| | | } |
| | | |
| | | public virtual void AddPipe(PipeModel pipe) |
| | | { |
| | | CheckLinksExist(pipe); |
| | | Links.Add(pipe); |
| | | } |
| | | |
| | | public virtual void AddPipes(List<PipeModel> pipes) |
| | | { |
| | | pipes.ForEach(pipe => { AddPipe(pipe); }); |
| | | } |
| | | public virtual void AddPump(PumpModel pump) |
| | | { |
| | | CheckLinksExist(pump); |
| | | Links.Add(pump); |
| | | } |
| | | |
| | | public virtual void AddPumps(List<PumpModel> pumps) |
| | | { |
| | | pumps.ForEach(pump => { AddPump(pump); }); |
| | | } |
| | | public virtual void AddValve(ValveModel valve) |
| | | { |
| | | CheckLinksExist(valve); |
| | | Links.Add(valve); |
| | | } |
| | | |
| | | public virtual void AddValves(List<ValveModel> valves) |
| | | { |
| | | valves.ForEach(valve => { AddValve(valve); }); |
| | | } |
| | | public virtual void AddReservos(ReservoisModel reservois) |
| | | { |
| | | CheckNodesExist(reservois); |
| | | Nodes.Add(reservois); |
| | | } |
| | | public virtual void AddReservoss(List<ReservoisModel> reservoiss) |
| | | { |
| | | reservoiss.ForEach(reservois => { AddReservos(reservois); }); |
| | | } |
| | | public virtual void AddMeter(MeterModel meter) |
| | | { |
| | | CheckNodesExist(meter); |
| | | Nodes.Add(meter); |
| | | } |
| | | public virtual void AddMeters(List<MeterModel> meters) |
| | | { |
| | | meters.ForEach(meter => { AddMeter(meter); }); |
| | | } |
| | | public virtual void AddNozzle(NozzleModel nozzle) |
| | | { |
| | | CheckNodesExist(nozzle); |
| | | Nodes.Add(nozzle); |
| | | } |
| | | public virtual void AddNozzles(List<NozzleModel> nozzles) |
| | | { |
| | | nozzles.ForEach(nozzle => { AddNozzle(nozzle); }); |
| | | } |
| | | |
| | | private void CheckNodesExist(NodeCalcModel node) |
| | | { |
| | | if (Nodes.Any(d => d.ID == node.ID)) |
| | | throw new Exception("å·²åå¨éå¤ç对象"); |
| | | } |
| | | |
| | | private void CheckLinksExist(LinkCalcModel link) |
| | | { |
| | | if (Links.Any(d => d.ID == link.ID)) |
| | | throw new Exception("å·²åå¨éå¤ç对象"); |
| | | } |
| | | |
| | | public List<NodeCalcModel> Nodes { get; set; } = new List<NodeCalcModel>(); |
| | | public List<LinkCalcModel> Links { get; set; } = new List<LinkCalcModel>(); |
| | | |
| | | /// <summary> |
| | | /// æ ¹æ®INPæä»¶çæ |
| | | /// </summary> |
| | | /// <param name="InpPath"></param> |
| | | /// <returns></returns> |
| | | public virtual bool BuildFromInp(string InpPath) |
| | | { |
| | | if (InpPath == null || !File.Exists(InpPath)) return false; |
| | | List<Coor> points = new List<Coor>(); |
| | | StreamReader sr = new StreamReader(InpPath); |
| | | //try |
| | | { |
| | | string line; |
| | | string section = ""; |
| | | while ((line = sr.ReadLine()) != null) |
| | | { |
| | | if (line.Trim().StartsWith("[")) |
| | | { |
| | | section = line.TrimStart('[').TrimEnd(']'); |
| | | } |
| | | else |
| | | { |
| | | string s = line.Trim('\t').Trim(' '); |
| | | if (s.Length == 0 || s[0] == ';') continue; |
| | | line = line.Replace("\t\t", "\t_\t").Replace("\t \t", "\t_\t"); |
| | | Parts parts = new Parts(line.Split(new char[] { '\t', ' ', ';' }, StringSplitOptions.RemoveEmptyEntries)); |
| | | switch (section) |
| | | { |
| | | case "JUNCTIONS": |
| | | { |
| | | var ID = parts[0]; |
| | | float elev; |
| | | float.TryParse(parts[1], out elev); |
| | | var Elev = elev; |
| | | float demand; |
| | | float.TryParse(parts[2], out demand); |
| | | var Demand = demand; |
| | | var PatternID = parts[3]; |
| | | int level; |
| | | int.TryParse(parts[6], out level); |
| | | var Level = level; |
| | | |
| | | if (parts[5] == "Meter") |
| | | { |
| | | AddMeter(new MeterModel() |
| | | { |
| | | ID = ID, |
| | | Elev = Elev, |
| | | Demand = Demand, |
| | | PatternID = PatternID, |
| | | }); |
| | | } |
| | | else if (parts[5] == "Nozzle") |
| | | { |
| | | AddNozzle(new NozzleModel() |
| | | { |
| | | ID = ID, |
| | | Elev = Elev, |
| | | Demand = Demand, |
| | | PatternID = PatternID, |
| | | }); |
| | | } |
| | | else |
| | | { |
| | | AddJunction(new JunctionModel() |
| | | { |
| | | ID = ID, |
| | | Elev = Elev, |
| | | Demand = Demand, |
| | | PatternID = PatternID, |
| | | }); |
| | | } |
| | | |
| | | } |
| | | break; |
| | | case "RESERVOIRS": |
| | | { |
| | | ReservoisModel r = new ReservoisModel(); |
| | | r.ID = parts[0]; |
| | | float head; |
| | | if (float.TryParse(parts[1], out head)) |
| | | r.Head = head; |
| | | r.PatternID = parts.Length > 2 ? parts[2] : ""; |
| | | int level; |
| | | //if (int.TryParse(parts[3], out level)) |
| | | // r.Level = level; |
| | | AddReservos(r); |
| | | } |
| | | break; |
| | | case "TANKS": |
| | | { |
| | | //TankModel tank = new TankModel(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], parts[6], parts[7], parts[8]); |
| | | float initLevel = 0; |
| | | float.TryParse(parts[2], out initLevel); |
| | | |
| | | float minLevel = 0; |
| | | float.TryParse(parts[3], out minLevel); |
| | | |
| | | float maxLevel = 0; |
| | | float.TryParse(parts[4], out maxLevel); |
| | | |
| | | float diamter = 0; |
| | | float.TryParse(parts[5], out diamter); |
| | | |
| | | float minVol = 0; |
| | | float.TryParse(parts[6], out minVol); |
| | | var tank = new TankModel() |
| | | { |
| | | ID = parts[0], |
| | | Elev = float.Parse(parts[1]), |
| | | InitLevel = initLevel, |
| | | MinLevel = minLevel, |
| | | MaxLevel = maxLevel, |
| | | Diameter = diamter, |
| | | MinVol = minVol, |
| | | VolCurve = "", |
| | | IsOverFlow = true |
| | | }; |
| | | //int level; |
| | | //if (int.TryParse(parts[9], out level)) |
| | | // tank.Level = level; |
| | | AddTank(tank); |
| | | } |
| | | break; |
| | | case "PIPES": |
| | | { |
| | | PipeModel p = new PipeModel(); |
| | | p.ID = parts[0]; |
| | | p.Node1 = parts[1]; |
| | | p.Node2 = parts[2]; |
| | | float length; |
| | | if (float.TryParse(parts[3], out length)) |
| | | p.Length = length; |
| | | float diameter; |
| | | if (float.TryParse(parts[4], out diameter)) |
| | | p.Diameter = diameter; |
| | | float roughness; |
| | | if (float.TryParse(parts[5], out roughness)) |
| | | p.Roughness = roughness; |
| | | float minorLoss; |
| | | if (float.TryParse(parts[6], out minorLoss)) |
| | | p.MinorLoss = minorLoss; |
| | | p.Status = parts.Length > 7 ? StatusType.CLOSED : StatusType.DEFAULT; |
| | | //int level; |
| | | //if (int.TryParse(parts[8], out level)) |
| | | // p.Level = level; |
| | | AddPipe(p); |
| | | } |
| | | break; |
| | | case "VALVES": |
| | | { |
| | | ValveModel valve = new ValveModel(); |
| | | valve.ID = parts[0]; |
| | | |
| | | // ååºNode1åNode2ä¸ç忝é¨åï¼ä¾å¦âS201326593â被ååºä¸ºâ201326593â |
| | | valve.Node1 = parts[1]; // Regex.Replace(parts[1], "[^0-9]", ""); |
| | | valve.Node2 = parts[2]; // Regex.Replace(parts[2], "[^0-9]", ""); |
| | | |
| | | float diameter; |
| | | if (float.TryParse(parts[3], out diameter)) |
| | | valve.Diameter = diameter; |
| | | valve.Type = parts[4]; |
| | | valve.CurvSetting = parts[5]; |
| | | float minorLoss; |
| | | if (float.TryParse(parts[6], out minorLoss)) |
| | | valve.MinorLoss = minorLoss; |
| | | //int level; |
| | | //if (int.TryParse(parts[7], out level)) |
| | | // valve.Level = level; |
| | | AddValve(valve); |
| | | } |
| | | break; |
| | | case "REPEATERS": |
| | | { |
| | | //Repeater repeater = new Repeater(); |
| | | //repeater.ID = parts[0]; |
| | | //repeater.Node1 = parts[1]; |
| | | //repeater.Node2 = parts[2]; |
| | | //// ååºNode1åNode2ä¸ç忝é¨åï¼ä¾å¦âS201326593â被ååºä¸ºâ201326593â |
| | | //repeater.TemplateID = parts[3]; |
| | | //int repeatTimes; |
| | | //if (int.TryParse(parts[4], out repeatTimes)) |
| | | // repeater.RepeatTimes = repeatTimes; |
| | | //RepeatStatus status; |
| | | //if (Enum.TryParse(parts[5], out status)) |
| | | // repeater.Status = status; |
| | | //repeater.NetworkPreName = parts[6]; |
| | | //int networkPreStartNum; |
| | | //if (int.TryParse(parts[7], out networkPreStartNum)) |
| | | // repeater.NetworkPreStartNum = networkPreStartNum; |
| | | //bool networkIsAscNum; |
| | | //if (bool.TryParse(parts[8], out networkIsAscNum)) |
| | | // repeater.NetworkIsAscNum = networkIsAscNum; |
| | | //repeater.NetworkShowName = parts[9]; |
| | | //int level; |
| | | //if (int.TryParse(parts[10], out level)) |
| | | // repeater.Level = level; |
| | | //Links.Add(repeater); |
| | | } |
| | | break; |
| | | case "COORDINATES": |
| | | { |
| | | string id = parts[0]; |
| | | float x; |
| | | float y; |
| | | if (float.TryParse(parts[1], out x) && float.TryParse(parts[2], out y)) |
| | | { |
| | | points.Add(new Coor(id, new PointF(x, y))); |
| | | } |
| | | } |
| | | break; |
| | | } |
| | | } |
| | | } |
| | | sr.Close(); |
| | | |
| | | #region åæ å¹é
æ¹æ³ |
| | | #endregion |
| | | |
| | | #region å é¤ |
| | | //[Cloudflightä¿®æ¹]2023-11-27 äºé循ç¯å¹é
åæ é度太æ
¢ |
| | | ////读ååæ |
| | | //Junctions.ForEach(o => |
| | | //{ |
| | | // var p = points.Where(d => d.ID == o.ID).FirstOrDefault(); |
| | | // if (p != null) |
| | | // { |
| | | // o.X = p.Position.X; |
| | | // o.Y = p.Position.Y; |
| | | // } |
| | | //}); |
| | | |
| | | //Reservos.ForEach(o => |
| | | //{ |
| | | // var p = points.Where(d => d.ID == o.ID).FirstOrDefault(); |
| | | // if (p != null) |
| | | // { |
| | | // o.X = p.Position.X; |
| | | // o.Y = p.Position.Y; |
| | | // } |
| | | //}); |
| | | |
| | | //Tanks.ForEach(o => |
| | | //{ |
| | | // var p = points.Where(d => d.ID == o.ID).FirstOrDefault(); |
| | | // if (p != null) |
| | | // { |
| | | // o.X = p.Position.X; |
| | | // o.Y = p.Position.Y; |
| | | // } |
| | | //}); |
| | | |
| | | //Meters.ForEach(o => |
| | | //{ |
| | | // var p = points.Where(d => d.ID == o.ID).FirstOrDefault(); |
| | | // if (p != null) |
| | | // { |
| | | // o.X = p.Position.X; |
| | | // o.Y = p.Position.Y; |
| | | // } |
| | | //}); |
| | | |
| | | //Nozzles.ForEach(o => |
| | | //{ |
| | | // var p = points.Where(d => d.ID == o.ID).FirstOrDefault(); |
| | | // if (p != null) |
| | | // { |
| | | // o.X = p.Position.X; |
| | | // o.Y = p.Position.Y; |
| | | // } |
| | | //}); |
| | | #endregion |
| | | |
| | | #region ä¼åæ¹æ¡ |
| | | int k1 = 0; |
| | | int k2 = 0; |
| | | |
| | | |
| | | Nodes.Sort((a, b) => string.Compare(a.ID, b.ID)); |
| | | points.Sort((a, b) => string.Compare(a.ID, b.ID)); |
| | | k1 = 0; |
| | | k2 = 0; |
| | | while (k1 < Nodes.Count) |
| | | { |
| | | var J = Nodes[k1]; |
| | | var coor = points[k2]; |
| | | |
| | | while (J.ID != coor.ID && k2 < points.Count) |
| | | { |
| | | k2++; |
| | | if (k2 < points.Count) coor = points[k2]; |
| | | |
| | | } |
| | | if (k2 == points.Count) |
| | | { |
| | | throw new Exception($"æªæ¾å°Node[{J.ID}]çåæ "); |
| | | } |
| | | J.X = coor.Position.X; |
| | | J.Y = coor.Position.Y; |
| | | |
| | | k1++; |
| | | } |
| | | #endregion |
| | | |
| | | |
| | | |
| | | //建ç«ç¹çº¿å
³ç³»é¾è¡¨StartNodeï¼å
å°ç®¡çº¿ä»¥Node1ï¼èç¹1çIDï¼æåºï¼åå°NodesæIDæåºï¼å»ºç«ä¸¤ä¸ªæ¸¸æ k1ãk2ï¼æ£å䏿¬¡å¾ªç¯ï¼å»ºç«é¾è¡¨å
³ç³» |
| | | //æ¶é´å¤æåº¦ O(n) |
| | | Links.Sort((a, b) => string.Compare(a.Node1, b.Node1)); |
| | | k1 = 0; |
| | | k2 = 0; |
| | | while (k2 < Links.Count) |
| | | { |
| | | var p = Links[k2]; |
| | | var J = Nodes[k1]; |
| | | while (J.ID != p.Node1 && k1 < Nodes.Count) |
| | | { |
| | | k1++; |
| | | if (k1 < Nodes.Count) J = Nodes[k1]; |
| | | |
| | | } |
| | | if (k1 == Nodes.Count) |
| | | { |
| | | throw new Exception($"æªæ¾å°Link[{p.ID}]çèµ·å§èç¹[{p.Node1}]"); |
| | | } |
| | | //p.StartNode = J; |
| | | //if (J.MaxDiameter < p.Diameter) J.MaxDiameter = p.Diameter; |
| | | //J.Links.Add(p); |
| | | k2++; |
| | | } |
| | | |
| | | //建ç«ç¹çº¿å
³ç³»é¾è¡¨StartNodeï¼å
å°ç®¡çº¿ä»¥Node2ï¼èç¹1çIDï¼æåºï¼åå°NodesæIDæåºï¼å»ºç«ä¸¤ä¸ªæ¸¸æ k1ãk2ï¼æ£å䏿¬¡å¾ªç¯ï¼å»ºç«é¾è¡¨å
³ç³» |
| | | //æ¶é´å¤æåº¦ O(n) |
| | | Links.Sort((a, b) => string.Compare(a.Node2, b.Node2)); |
| | | k1 = 0; |
| | | k2 = 0; |
| | | while (k2 < Links.Count) |
| | | { |
| | | var p = Links[k2]; |
| | | var J = Nodes[k1]; |
| | | while (J.ID != p.Node2 && k1 < Nodes.Count) |
| | | { |
| | | k1++; |
| | | if (k1 < Nodes.Count) J = Nodes[k1]; |
| | | } |
| | | if (k1 == Nodes.Count) |
| | | { |
| | | throw new Exception($"æªæ¾å°Link[{p.ID}]çç»æ¢èç¹[{p.Node2}]"); |
| | | } |
| | | //p.EndNode = J; |
| | | //if (J.MaxDiameter < p.Diameter) J.MaxDiameter = p.Diameter; |
| | | //J.Links.Add(p); |
| | | k2++; |
| | | } |
| | | return true; |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// çæINPæä»¶ |
| | | /// </summary> |
| | | /// <param name="InpPath">Inpæä»¶è·¯å¾</param> |
| | | /// <param name="TemplateInpFullPath">Inpæ¨¡æ¿æä»¶ç»å¯¹è·¯å¾ï¼å¦æä¸ºç©ºå°±ç¨ç³»ç»é»è®¤æ¨¡æ¿æä»¶</param> |
| | | /// <exception cref="Exception"></exception> |
| | | public virtual void BuildToInp(string InpPath, string TemplateInpFullPath = "", string sourcePath = null, bool isReplace = false) |
| | | { |
| | | |
| | | string tempString = ""; |
| | | var tempPath = Path.Combine(Directory.GetCurrentDirectory(), @"template\inp\å¯¼åºæ¨¡æ¿.inp"); |
| | | if (!string.IsNullOrEmpty(TemplateInpFullPath)) |
| | | { |
| | | tempPath = TemplateInpFullPath; |
| | | } |
| | | if (!File.Exists(tempPath)) |
| | | { |
| | | throw new Exception("æ¨¡æ¿æä»¶ä¸åå¨," + tempPath); |
| | | } |
| | | |
| | | if (!File.Exists(InpPath)) |
| | | { |
| | | FileInfo fi=new FileInfo(InpPath); |
| | | if (!Directory.Exists(fi.DirectoryName)) |
| | | Directory.CreateDirectory(fi.DirectoryName); |
| | | File.Create(InpPath).Close(); |
| | | |
| | | } |
| | | tempString = File.ReadAllText(tempPath); |
| | | StringBuilder statusStringBuilder = new StringBuilder(); |
| | | statusStringBuilder.AppendLine(";ID \tStatus/Setting\r\n"); |
| | | |
| | | StringBuilder emitterStringBuilder = new StringBuilder(); |
| | | emitterStringBuilder.AppendLine(";Junction \tCoefficient"); |
| | | |
| | | StringBuilder coorStringBuilder = new StringBuilder(); |
| | | coorStringBuilder.AppendLine(";Node X-Coord Y-Coord"); |
| | | |
| | | Dictionary<string, string> dictExchange = new Dictionary<string, string>() { |
| | | {"{junctions}","{0}" }, |
| | | {"{reservoirs}","{1}" }, |
| | | {"{tanks}","{2}" }, |
| | | {"{pipes}","{3}" }, |
| | | {"{valves}","{4}" }, |
| | | {"{pumps}","{5}" }, |
| | | |
| | | {"{coor}","{6}" }, |
| | | {"{curve}","{7}" }, |
| | | }; |
| | | dictExchange.ToList().ForEach(m => tempString = tempString.Replace(m.Key, m.Value)); |
| | | |
| | | StringBuilder junctionStringBuilder = new StringBuilder(); |
| | | |
| | | junctionStringBuilder.AppendLine(";ID Elev Demand Pattern Type"); |
| | | |
| | | Junctions.ForEach(j => |
| | | { |
| | | junctionStringBuilder.AppendLine(j.ToString() + $"0\tJunction"); |
| | | coorStringBuilder.AppendLine(j.ToCoorString()); |
| | | |
| | | }); |
| | | Meters.ForEach(m => |
| | | { |
| | | junctionStringBuilder.AppendLine(m.ToString() + $"0\tMeters"); |
| | | coorStringBuilder.AppendLine(m.ToCoorString()); |
| | | }); |
| | | Nozzles.ForEach(no => |
| | | { |
| | | junctionStringBuilder.AppendLine(no.ToString() + $"0\tNozzle\t{no.FlowCoefficient}"); |
| | | emitterStringBuilder.Append(no.ToEmitterString()); |
| | | coorStringBuilder.AppendLine(no.ToCoorString()); |
| | | }); |
| | | |
| | | string junctionString = junctionStringBuilder.ToString(); |
| | | |
| | | StringBuilder reservoirStringBuilder = new StringBuilder(); |
| | | |
| | | reservoirStringBuilder.AppendLine(";ID Head Pattern "); |
| | | |
| | | Reservos.ForEach(o => |
| | | { |
| | | reservoirStringBuilder.AppendLine(o.ToString() + $"0\t{o.Elev}"); |
| | | coorStringBuilder.AppendLine(o.ToCoorString()); |
| | | }); |
| | | string reserverString = reservoirStringBuilder.ToString(); |
| | | |
| | | StringBuilder tankStringBuilder = new StringBuilder(); |
| | | |
| | | tankStringBuilder.AppendLine(";ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve Overflow"); |
| | | |
| | | Tanks.ForEach(o => |
| | | { |
| | | tankStringBuilder.AppendLine(o.ToString());// + $"0"); |
| | | coorStringBuilder.AppendLine(o.ToCoorString()); |
| | | }); |
| | | string tankString = tankStringBuilder.ToString(); |
| | | |
| | | StringBuilder pipeStringBuilder = new StringBuilder(); |
| | | |
| | | pipeStringBuilder.AppendLine(";ID Node1 Node2 Length Diameter Roughness MinorLoss Status"); |
| | | |
| | | Pipes.ForEach(p => |
| | | { |
| | | pipeStringBuilder.AppendLine(p.ToString());// + $"{p.Level}"); |
| | | statusStringBuilder.Append(p.ToStatusString()); |
| | | }); |
| | | |
| | | string pipeString = pipeStringBuilder.ToString(); |
| | | |
| | | StringBuilder valveStringBuilder = new StringBuilder(); |
| | | |
| | | valveStringBuilder.AppendLine(";ID Node1 Node2 Diameter Type Setting MinorLoss "); |
| | | |
| | | Valves.ForEach(o => |
| | | { |
| | | valveStringBuilder.AppendLine(o.ToString());// + $"0"); |
| | | statusStringBuilder.Append(o.ToStatusString()); |
| | | }); |
| | | string valveString = valveStringBuilder.ToString(); |
| | | |
| | | StringBuilder pumpStringBuilder = new StringBuilder(); |
| | | |
| | | pumpStringBuilder.AppendLine(";ID Node1 Node2 Diameter Type Setting MinorLoss "); |
| | | |
| | | Pumps.ForEach(o => |
| | | { |
| | | pumpStringBuilder.AppendLine(o.ToString());// + $"0"); |
| | | statusStringBuilder.Append(o.ToStatusString()); |
| | | }); |
| | | string pumpString = pumpStringBuilder.ToString(); |
| | | StringBuilder curveStringBuilder = new StringBuilder(); |
| | | curveStringBuilder.AppendLine(@";ID X-Value Y-Value |
| | | ;HEADLOSS: |
| | | GPVDefault 0 0 |
| | | GPVDefault 100 0 |
| | | ;PUMP: |
| | | PumpDefault 0 45.38 |
| | | PumpDefault 83.33333333 45.25 |
| | | PumpDefault 111.1111111 45.12 |
| | | PumpDefault 138.8888889 44.96 |
| | | PumpDefault 166.6666667 44.76 |
| | | PumpDefault 194.4444444 44.52 |
| | | PumpDefault 222.2222222 44.24 |
| | | PumpDefault 250 43.92 |
| | | PumpDefault 277.7777778 43.56 |
| | | PumpDefault 305.5555556 43.17 |
| | | PumpDefault 333.3333333 42.73 |
| | | PumpDefault 361.1111111 42.25 |
| | | PumpDefault 388.8888889 41.74 |
| | | PumpDefault 416.6666667 41.18 |
| | | PumpDefault 444.4444444 40.58 |
| | | PumpDefault 472.2222222 39.95 |
| | | PumpDefault 500 39.28 |
| | | PumpDefault 527.7777778 38.56 |
| | | PumpDefault 555.5555556 37.81 |
| | | PumpDefault 583.3333333 37.02 |
| | | PumpDefault 611.1111111 36.19 |
| | | PumpDefault 638.8888889 35.32 |
| | | PumpDefault 666.6666667 34.41 |
| | | PumpDefault 694.4444444 33.46 |
| | | PumpDefault 722.2222222 32.47 |
| | | PumpDefault 750 31.44 |
| | | PumpDefault 777.7777778 30.37 |
| | | PumpDefault 805.5555556 29.27 "); |
| | | |
| | | Pumps.ForEach(o => |
| | | { |
| | | curveStringBuilder.AppendLine(o.CreateFlowCurve()); |
| | | }); |
| | | string curveString = curveStringBuilder.ToString(); |
| | | string coorString = coorStringBuilder.ToString(); |
| | | string output = ""; |
| | | string emitterString = emitterStringBuilder.ToString(); |
| | | string statusString = statusStringBuilder.ToString(); |
| | | output = tempString; |
| | | output = ReplaceContent(output, "JUNCTIONS", junctionString); |
| | | output = ReplaceContent(output, "RESERVOIRS", reserverString); |
| | | output = ReplaceContent(output, "TANKS", tankString); |
| | | output = ReplaceContent(output, "PIPES", pipeString); |
| | | 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); |
| | | output = ReplaceContent(output, "STATUS", statusString); |
| | | string backupFolderPath = Path.Combine(Path.GetDirectoryName(InpPath), "bk"); |
| | | if (!Directory.Exists(backupFolderPath)) |
| | | Directory.CreateDirectory(backupFolderPath); |
| | | |
| | | string backupFileName = $"{Path.GetFileNameWithoutExtension(InpPath)}_{DateTime.Now:yyyyMMddHHmmss}{Path.GetExtension(InpPath)}"; |
| | | string backupFilePath = Path.Combine(backupFolderPath, backupFileName); |
| | | FileCopy.Copy(InpPath, backupFilePath, true); |
| | | |
| | | //Global.ClearFileReadOnly(InpPath); |
| | | File.WriteAllText(InpPath, output); |
| | | } |
| | | //public void BuildToInp(string filePath, string userCoorString = null, string sourcePath = null, bool isReplace = false) |
| | | //{ |
| | | |
| | | // if (sourcePath == null) sourcePath = filePath; |
| | | |
| | | // string tempString = ""; |
| | | // if (!isReplace) |
| | | // { |
| | | // var tempPath = Path.Combine(Directory.GetCurrentDirectory(), @"template\inp\å¯¼åºæ¨¡æ¿.inp"); |
| | | // if (!File.Exists(tempPath)) |
| | | // { |
| | | // //MessageBox.Show($"æ¨¡æ¿æä»¶ä¸åå¨[{tempPath}]"); |
| | | // return; |
| | | // } |
| | | // tempString = File.ReadAllText(tempPath); |
| | | // } |
| | | // else |
| | | // { |
| | | // tempString = File.ReadAllText(sourcePath); |
| | | // } |
| | | |
| | | |
| | | // Dictionary<string, string> dictExchange = new Dictionary<string, string>() { |
| | | // {"{junctions}","{0}" }, |
| | | // {"{reservoirs}","{1}" }, |
| | | // {"{tanks}","{2}" }, |
| | | // {"{pipes}","{3}" }, |
| | | // {"{valves}","{4}" }, |
| | | // {"{pumps}","{5}" }, |
| | | |
| | | // {"{coor}","{6}" }, |
| | | // {"{curve}","{7}" }, |
| | | // }; |
| | | // dictExchange.ToList().ForEach(m => tempString = tempString.Replace(m.Key, m.Value)); |
| | | |
| | | // StringBuilder junctionStringBuilder = new StringBuilder(); |
| | | |
| | | // junctionStringBuilder.AppendLine(";ID Elev Demand Pattern Type"); |
| | | |
| | | // Nodes.ForEach(o => |
| | | // { |
| | | // //if (!o.Visible) return; |
| | | // if (o is JunctionModel j) |
| | | // junctionStringBuilder.AppendLine(j.ToString() + $"0\tJunction"); |
| | | // else if (o is MeterModel m) |
| | | // junctionStringBuilder.AppendLine(m.ToString() + $"0\tMeter"); |
| | | // else if (o is NozzleModel no) |
| | | // junctionStringBuilder.AppendLine(no.ToString() + $"0\tNozzle\t{no.FlowCoefficient}"); |
| | | // }); |
| | | // string junctionString = junctionStringBuilder.ToString(); |
| | | |
| | | // StringBuilder reservoirStringBuilder = new StringBuilder(); |
| | | |
| | | // reservoirStringBuilder.AppendLine(";ID Head Pattern "); |
| | | |
| | | // Reservos.ForEach(o => |
| | | // { |
| | | // //if (!o.Visible) return; |
| | | // reservoirStringBuilder.AppendLine(o.ToString() + $"0\t{o.Elev}"); |
| | | // }); |
| | | // string reserverString = reservoirStringBuilder.ToString(); |
| | | |
| | | // StringBuilder tankStringBuilder = new StringBuilder(); |
| | | |
| | | // tankStringBuilder.AppendLine(";ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve Overflow"); |
| | | |
| | | // Tanks.ForEach(o => |
| | | // { |
| | | // //if (!o.Visible) return; |
| | | // tankStringBuilder.AppendLine(o.ToString() + $"0"); |
| | | // }); |
| | | // string tankString = tankStringBuilder.ToString(); |
| | | |
| | | // StringBuilder pipeStringBuilder = new StringBuilder(); |
| | | |
| | | // pipeStringBuilder.AppendLine(";ID Node1 Node2 Length Diameter Roughness MinorLoss Status"); |
| | | |
| | | // Links.ForEach(o => |
| | | // { |
| | | // //if (!o.Visible) return; |
| | | // if (o is PipeModel p) |
| | | // pipeStringBuilder.AppendLine(p.ToString() + $"0"); |
| | | // //else if (o is RepeaterViewModel r) |
| | | // // pipeStringBuilder.AppendLine(r.ToString()); |
| | | // }); |
| | | // string pipeString = pipeStringBuilder.ToString(); |
| | | |
| | | // StringBuilder valveStringBuilder = new StringBuilder(); |
| | | |
| | | // valveStringBuilder.AppendLine(";ID Node1 Node2 Diameter Type Setting MinorLoss "); |
| | | |
| | | // Valves.ForEach(o => |
| | | // { |
| | | // //if (!o.Visible) return; |
| | | // valveStringBuilder.AppendLine(o.ToString() + $"0"); |
| | | // }); |
| | | // string valveString = valveStringBuilder.ToString(); |
| | | |
| | | // StringBuilder pumpStringBuilder = new StringBuilder(); |
| | | |
| | | // pumpStringBuilder.AppendLine(";ID Node1 Node2 Diameter Type Setting MinorLoss "); |
| | | |
| | | // Pumps.ForEach(o => |
| | | // { |
| | | // //if (!o.Visible) return; |
| | | // pumpStringBuilder.AppendLine(o.ToString() + $"0"); |
| | | // }); |
| | | // string pumpString = pumpStringBuilder.ToString(); |
| | | |
| | | |
| | | // StringBuilder curveStringBuilder = new StringBuilder(); |
| | | |
| | | |
| | | |
| | | // //pumps.ForEach(o => |
| | | // //{ |
| | | // // if (!o.Visible || !o.Datasets.ContainsKey("æµéæ¬ç¨æ²çº¿")) return; |
| | | // // curveStringBuilder.AppendLine(o.Datasets["æµéæ¬ç¨æ²çº¿"].ToString()); |
| | | // //}); |
| | | // if (dict_dataset != null) |
| | | // 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())); |
| | | // } |
| | | // else |
| | | // { |
| | | // 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; |
| | | |
| | | // output = ReplaceContent(output, "JUNCTIONS", junctionString); |
| | | // output = ReplaceContent(output, "RESERVOIRS", reserverString); |
| | | // output = ReplaceContent(output, "TANKS", tankString); |
| | | // output = ReplaceContent(output, "PIPES", pipeString); |
| | | // 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); |
| | | // output = ReplaceContent(output, "STATUS", statusString); |
| | | // string backupFolderPath = Path.Combine(Path.GetDirectoryName(filePath), "bk"); |
| | | // if (!Directory.Exists(backupFolderPath)) |
| | | // { |
| | | // Directory.CreateDirectory(backupFolderPath); |
| | | // } |
| | | |
| | | // 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 |
| | | // { |
| | | // Global.ClearFileReadOnly(filePath); |
| | | |
| | | // File.WriteAllText(filePath, output); |
| | | // } |
| | | // catch (Exception ex) |
| | | // { |
| | | // MessageBox.Show(ex.Message); |
| | | // } |
| | | |
| | | // //MessageBox.Show($"ä¿åæå!"); |
| | | //} |
| | | /// <summary> |
| | | /// æ ¹æ®Inpæä»¶è®¡ç® |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public virtual List<TimePoint> Calc(string InpPath) |
| | | { |
| | | HydraulicModel.HydraulicCore epanet = new HydraulicModel.HydraulicCore(true); |
| | | var result = new List<TimePoint>(); |
| | | var err = epanet.open(InpPath, "", ""); |
| | | |
| | | if (err != 0) |
| | | { |
| | | throw new Exception($"æå¼è®¡ç®æä»¶å¤±è´¥ï¼{err}"); |
| | | } |
| | | var errCal = epanet.solveH(); |
| | | if (errCal != 0) |
| | | { |
| | | throw new Exception($"计ç®å¤±è´¥ï¼{errCal}"); |
| | | } |
| | | int nodeCount = 0, linkCount = 0; |
| | | epanet.getcount((int)CountType.Node, ref nodeCount); |
| | | epanet.getcount((int)CountType.Link, ref linkCount); |
| | | const int MAXID = 31; |
| | | |
| | | var sb = new StringBuilder(MAXID); |
| | | |
| | | for (int i = 1; i <= nodeCount; i++) |
| | | { |
| | | epanet.getnodeid(i, sb); |
| | | var arr = new string[] {"Press", "Head", "Demand" }; //System.Enum.GetValues(typeof(HydraulicModel.NodeValueType)); |
| | | var arrnum = new int[] { 10, 11, 9 }; |
| | | for (var j = 0; j < arr.Length; j++) |
| | | { |
| | | float v = 0; |
| | | var t = (HydraulicModel.NodeValueType)j; |
| | | epanet.getnodevalue(i, arrnum[j], ref v); |
| | | result.Add(new TimePoint() |
| | | { |
| | | Key = arr[j] + "_"+sb.ToString(), |
| | | Value = v, |
| | | }); |
| | | } |
| | | } |
| | | |
| | | for (int i = 1; i <= linkCount; i++) |
| | | { |
| | | epanet.getlinkid(i, sb); |
| | | //var arr = System.Enum.GetValues(typeof(HydraulicModel.LinkValueType)); |
| | | var arr = new string[] { "Flow", "Velocity", "Headloss" }; //System.Enum.GetValues(typeof(HydraulicModel.NodeValueType)); |
| | | var arrnum = new int[] { 8, 9, 10 }; |
| | | for (var j = 0; j < arr.Length; j++) |
| | | { |
| | | float v = 0; |
| | | var t = (HydraulicModel.LinkValueType)j; |
| | | epanet.getlinkvalue(i, arrnum[j], ref v); |
| | | result.Add(new TimePoint() |
| | | { |
| | | Key = arr[j] + "_" +sb.ToString(), |
| | | Value = v, |
| | | }); |
| | | } |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// å
çæInpæä»¶ï¼åè®¡ç® |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public virtual List<TimePoint> Calc() |
| | | { |
| | | |
| | | var inpPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"data\inp\calc.inp"); |
| | | BuildToInp(inpPath); |
| | | return Calc(inpPath); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// æ°æ®æææ§æ ¡éª |
| | | /// </summary> |
| | | /// <returns></returns> |
| | | public virtual CheckModel Check() |
| | | { |
| | | var result = new CheckModel(); |
| | | |
| | | return result; |
| | | } |
| | | |
| | | private string ReplaceContent(string text, string content, string replaceString) |
| | | { |
| | | |
| | | |
| | | string str = replaceString; |
| | | |
| | | string replacedText = ReplaceCoordinatesSection(text, content, str); |
| | | |
| | | return replacedText; |
| | | //Console.WriteLine(replacedText); |
| | | } |
| | | |
| | | public static string ReplaceCoordinatesSection(string text, string content, string str) |
| | | { |
| | | string pattern = $@"(\[{content}\]).*?(\[|$)"; |
| | | |
| | | string replacedText = Regex.Replace(text, pattern, match => |
| | | { |
| | | string section = match.Groups[2].Value.Trim(); |
| | | |
| | | if (!string.IsNullOrEmpty(section)) |
| | | { |
| | | return $"{match.Groups[1].Value}\n{str}\n["; |
| | | } |
| | | else |
| | | { |
| | | return $"{match.Groups[1].Value}\n{str}\n["; |
| | | } |
| | | }, RegexOptions.Singleline); |
| | | |
| | | return replacedText; |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | |
| | | } |