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<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>();
|
|
|
/// 根据INP文件生成
|
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);
|
|
{
|
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;
|
}
|
|
}
|
}
|