using System.Text.RegularExpressions; namespace HydroUI { [Serializable] public class NetWork { public NetWork() { } public virtual void AddJunction(JunctionModel junction) { CheckNodesExist(junction); Nodes.Add(junction); } public virtual void AddJunctions(List junctions) { junctions.ForEach(junction => { AddJunction(junction); }); } public virtual void AddTank(TankModel tank) { CheckNodesExist(tank); Nodes.Add(tank); } public virtual void AddTanks(List tanks) { tanks.ForEach(tank => { AddTank(tank); }); } public virtual void AddPipe(PipeModel pipe) { CheckLinksExist(pipe); Links.Add(pipe); } public virtual void AddPipes(List pipes) { pipes.ForEach(pipe => { AddPipe(pipe); }); } public virtual void AddPump(PumpModel pump) { CheckLinksExist(pump); Links.Add(pump); } public virtual void AddPumps(List pumps) { pumps.ForEach(pump => { AddPump(pump); }); } public virtual void AddValve(ValveModel valve) { CheckLinksExist(valve); Links.Add(valve); } public virtual void AddValves(List valves) { valves.ForEach(valve => { AddValve(valve); }); } public virtual void AddReservos(ReservoisModel reservois) { CheckNodesExist(reservois); Nodes.Add(reservois); } public virtual void AddReservoss(List reservoiss) { reservoiss.ForEach(reservois => { AddReservos(reservois); }); } public virtual void AddMeter(MeterModel meter) { CheckNodesExist(meter); Nodes.Add(meter); } public virtual void AddMeters(List meters) { meters.ForEach(meter => { AddMeter(meter); }); } public virtual void AddNozzle(NozzleModel nozzle) { CheckNodesExist(nozzle); Nodes.Add(nozzle); } public virtual void AddNozzles(List 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 Nodes { get; set; } = new List(); public List Links { get; set; } = new List(); /// 根据INP文件生成 public virtual bool BuildFromInp(string InpPath) { if (InpPath == null || !File.Exists(InpPath)) return false; List points = new List(); StreamReader sr = new StreamReader(InpPath); { 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; AddReservos(r); } break; case "TANKS": { 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 }; 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; AddPipe(p); } break; case "VALVES": { ValveModel valve = new ValveModel(); valve.ID = parts[0]; valve.Node1 = parts[1]; valve.Node2 = parts[2]; 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; AddValve(valve); } break; case "REPEATERS": { } 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 优化方案 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 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}]"); } k2++; } 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}]"); } k2++; } return true; } } 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; } } }