| | |
| | | private NodeViewModelList _nodes = new NodeViewModelList(); |
| | | public NodeViewModelList Nodes { get { return _nodes; }set { base.Nodes = _nodes = value; } } |
| | | |
| | | private List<AreaViewModel> _areas = new List<AreaViewModel>(); |
| | | public List<AreaViewModel> Areas { get { return _areas; } set { _areas = value; } } |
| | | |
| | | public NodeViewModel StartPoint { get; set; } |
| | | |
| | | public NodeViewModel EndPoint { get; set; } |
| | | |
| | | public double[] getMinMax(ColourType colourType) |
| | | { |
| | | //根据当前选中的ColourType,判断是否有对应的网络数据 |
| | | |
| | | double max = 0; |
| | | double min = 0; |
| | | |
| | | switch (colourType) |
| | | { |
| | | case ColourType.节点自由压力: |
| | | max = Nodes.Where(node => !(node is ReservoirViewModel || node is TankViewModel)).Max(node => node.EN_PRESSURE); |
| | | min = Nodes.Where(node => !(node is ReservoirViewModel || node is TankViewModel)).Min(node => node.EN_PRESSURE); |
| | | break; |
| | | case ColourType.节点绝对压力: |
| | | max = Nodes.Where(node => !(node is ReservoirViewModel || node is TankViewModel)).Max(node => node.EN_PRESSURE); |
| | | min = Nodes.Where(node => !(node is ReservoirViewModel || node is TankViewModel)).Min(node => node.EN_PRESSURE); |
| | | break; |
| | | case ColourType.节点需水量: |
| | | max = Nodes.Where(node => !(node is ReservoirViewModel || node is TankViewModel)).Max(node => node.EN_DEMAND); |
| | | min = Nodes.Where(node => !(node is ReservoirViewModel || node is TankViewModel)).Min(node => node.EN_DEMAND); |
| | | break; |
| | | case ColourType.管线流量: |
| | | max = Links.Max(link => link.EN_FLOW); |
| | | min = Links.Min(link => link.EN_FLOW); |
| | | break; |
| | | case ColourType.管线流速: |
| | | max = Links.Max(link => link.EN_VELOCITY); |
| | | min = Links.Min(link => link.EN_VELOCITY); |
| | | break; |
| | | default: |
| | | break; |
| | | |
| | | } |
| | | return new double[] { min, max }; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 当量集合,当量模板ID,<器具ID,数量> |
| | |
| | | |
| | | public List<TimePoint> Calc(string inpPath, string configPath = null) |
| | | { |
| | | bool CalcByConfig = false; |
| | | List<TimePoint> list = new List<TimePoint>(); |
| | | if (CalcByConfig) |
| | | { |
| | | |
| | | WdnmoParam wdnmoParam = new WdnmoParam(); |
| | | Nodes.ForEach(n => |
| | | { |
| | | //if (n is JunctionViewModel || n is MeterViewModel || n is NozzleViewModel) |
| | | { |
| | | wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Press_{n.ID}" }); |
| | | wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Head_{n.ID}" }); |
| | | wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Demand_{n.ID}" }); |
| | | } |
| | | }); |
| | | Links.ForEach(n => |
| | | { |
| | | //if (n is PipeViewModel || n is PumpViewModel || n is ValveViewModel) |
| | | { |
| | | wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Flow_{n.ID}" }); |
| | | wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Velocity_{n.ID}" }); |
| | | wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Headloss_{n.ID}" }); |
| | | |
| | | } |
| | | }); |
| | | |
| | | calc c = new calc(); |
| | | list = c.GetCalcResult(inpPath, wdnmoParam, configPath); |
| | | if (list == null) return list; |
| | | } |
| | | else |
| | | { |
| | | list= base.Calc(inpPath); |
| | | } |
| | | |
| | | |
| | | |
| | | list.Sort((a, b) => string.Compare(a.Key, b.Key)); |
| | | Nodes.Sort((a, b) => string.Compare(a.ID, b.ID)); |
| | | Links.Sort((a, b) => string.Compare(a.ID, b.ID)); |
| | | SetNodeFromWparam(this, list, "Press"); |
| | | SetNodeFromWparam(this, list, "Head"); |
| | | SetNodeFromWparam(this, list, "Demand"); |
| | | |
| | | SetLinkFromWparam(this, list, "Flow"); |
| | | SetLinkFromWparam(this, list, "Velocity"); |
| | | SetLinkFromWparam(this, list, "Headloss"); |
| | | |
| | | Links.ForEach(l=> |
| | | { |
| | | l.EN_HEADLOSS_MINOR = (float)Math.Round(l.MinorLoss * Math.Pow(l.EN_VELOCITY, 2) / 2 / 9.8, 4); |
| | | l.EN_HEADLOSS_LINE = l.EN_HEADLOSS - l.EN_HEADLOSS_MINOR; |
| | | }); |
| | | this._isCalculated = true; |
| | | return list; |
| | | //return new List<TimePoint>(); |
| | | } |
| | | public List<TimePoint> WaterDistribution(string inpPath, string configPath = null,List<WaterEquivalentSettings> settings=null,double TotalDemand=-1,double InitPress=100) |
| | | { |
| | | if (TotalDemand < 0) |
| | | { |
| | | throw new Exception("TotalDemand must be set"); |
| | | } |
| | | WdnmoParam wdnmoParam = new WdnmoParam(); |
| | | |
| | | |
| | | wdnmoParam.UpdateWParamByWaterEquivalentSettings(settings, TotalDemand); |
| | | wdnmoParam.ScadaPoints.Add(new TimePoint { Key = "initPress", Value= InitPress }); |
| | | Nodes.ForEach(n => |
| | | { |
| | | //if (n is JunctionViewModel || n is MeterViewModel || n is NozzleViewModel) |
| | |
| | | SetLinkFromWparam(this, list, "Velocity"); |
| | | SetLinkFromWparam(this, list, "Headloss"); |
| | | |
| | | Links.ForEach(l=> |
| | | Links.ForEach(l => |
| | | { |
| | | l.EN_HEADLOSS_MINOR = (float)Math.Round(l.MinorLoss * Math.Pow(l.EN_VELOCITY, 2) / 2 / 9.8, 4); |
| | | l.EN_HEADLOSS_LINE = l.EN_HEADLOSS - l.EN_HEADLOSS_MINOR; |
| | | }); |
| | | Nodes.ForEach(n => n.Demand = n.EN_DEMAND); |
| | | this._isCalculated = true; |
| | | return list; |
| | | //return new List<TimePoint>(); |
| | | } |
| | | |
| | | |
| | | |
| | | public List<TimePoint> CalcByVal(WDNModelOptimizer wdo, Result val) |
| | | { |
| | |
| | | return list; |
| | | //return new List<TimePoint>(); |
| | | } |
| | | public string CheckValidate() |
| | | { |
| | | BuildRelation(); |
| | | string result = null; |
| | | StringBuilder result_sb=new StringBuilder(); |
| | | //to-do |
| | | var objs = new List<LinkViewModel>() { Links[0] }; //Links.FindAll(o => o is LinkViewModel).Select(o => o as LinkViewModel).ToList(); |
| | | //objs去掉重复的元素 |
| | | objs = objs.Distinct().ToList(); |
| | | var visitedNodes = new HashSet<NodeViewModel>(); |
| | | FindObjs = new HashSet<IBaseViewModel>(); |
| | | objs.ForEach(o => TraversePipeNetworkALL(o, visitedNodes)); |
| | | |
| | | for(int i=0;i<Nodes.Count;i++) |
| | | { |
| | | if (!FindObjs.Contains(Nodes[i])) result_sb .AppendLine($"节点{Nodes[i].ID}是孤立点"); |
| | | } |
| | | //属性判断 |
| | | |
| | | pipes.ForEach(p => |
| | | { |
| | | if (p.StartNode == null || p.EndNode == null) |
| | | { |
| | | result_sb.AppendLine($"{p.ID}管道未连接"); |
| | | } |
| | | if (p.Length<=0) |
| | | { |
| | | result_sb.AppendLine($"{p.ID}管道长度小于等于0"); |
| | | } |
| | | if (p.Roughness<=0.1 || p.Roughness>10000) |
| | | { |
| | | result_sb.AppendLine($"{p.ID}粗糙系数设置错误"); |
| | | } |
| | | if (p.Diameter<=0.1 || p.Diameter>10000) |
| | | { |
| | | result_sb.AppendLine($"{p.ID}管径设置错误"); |
| | | } |
| | | |
| | | }); |
| | | return result_sb.ToString(); |
| | | |
| | | |
| | | |
| | | } |
| | | HashSet<IBaseViewModel> FindObjs; |
| | | private void TraversePipeNetworkALL(LinkViewModel startLink, HashSet<NodeViewModel> visitedNodes = null, int direction = 0) |
| | | { |
| | | |
| | | Queue<LinkViewModel> queue = new Queue<LinkViewModel>(); |
| | | |
| | | |
| | | |
| | | queue.Enqueue(startLink); |
| | | if (visitedNodes == null) |
| | | visitedNodes = new HashSet<NodeViewModel>(); |
| | | //visitedNodes.Add(startLink.StartNode); |
| | | //visitedNodes.Add(startLink.EndNode); |
| | | |
| | | while (queue.Count > 0) |
| | | { |
| | | LinkViewModel currentLink = queue.Dequeue(); |
| | | //Console.WriteLine("Traversing Link: " + currentLink.ID); |
| | | |
| | | foreach (var node in new NodeViewModel[] { currentLink.StartNode, currentLink.EndNode }) |
| | | { |
| | | if (direction == 1 && currentLink.EN_FLOW >= 0 && node == currentLink.StartNode) continue; |
| | | if (direction == -1 && currentLink.EN_FLOW <= 0 && node == currentLink.EndNode) continue; |
| | | if (node != null && !visitedNodes.Contains(node)) |
| | | { |
| | | visitedNodes.Add(node); |
| | | if (!FindObjs.Contains(node)) FindObjs.Add(node); |
| | | |
| | | |
| | | //Console.WriteLine("Visiting Node: " + node.ID); |
| | | foreach (var link in node.ViewLinks) |
| | | { |
| | | if (!visitedNodes.Contains(link.StartNode) || !visitedNodes.Contains(link.EndNode)) |
| | | { |
| | | |
| | | if (!FindObjs.Contains(link)) FindObjs.Add(link); |
| | | queue.Enqueue(link); |
| | | |
| | | |
| | | |
| | | |
| | | } |
| | | } |
| | | } |
| | | } |
| | | |
| | | } |
| | | |
| | | |
| | | |
| | | } |
| | | |
| | | public List<TimePoint> CalcByValAndHead(WDNModelOptimizer wdo, Result val,double Head) |
| | | { |
| | | |
| | | WdnmoParam wdnmoParam = new WdnmoParam(); |
| | | |
| | | |
| | | Nodes.ForEach(n => |
| | | { |
| | | //if (n is JunctionViewModel || n is MeterViewModel || n is NozzleViewModel) |
| | | { |
| | | wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Press_{n.ID}" }); |
| | | wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Head_{n.ID}" }); |
| | | wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Demand_{n.ID}" }); |
| | | } |
| | | }); |
| | | Links.ForEach(n => |
| | | { |
| | | //if (n is PipeViewModel || n is PumpViewModel || n is ValveViewModel) |
| | | { |
| | | wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Flow_{n.ID}" }); |
| | | wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Velocity_{n.ID}" }); |
| | | wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Headloss_{n.ID}" }); |
| | | |
| | | } |
| | | }); |
| | | calcParam calcParam = new calcParam(); |
| | | calcParam.vars = val.arrayTryValue; |
| | | calcParam.setVars = new List<SetVar>(); |
| | | reservoirs.ForEach(r => |
| | | { |
| | | calcParam.setVars.Add(new SetVar(r.ID, true, (int)EpanetEnum.NodeValueType.水池水位, (float)Head)); |
| | | }); |
| | | |
| | | wdnmoParam = wdo.CalcbyResult(calcParam, wdnmoParam); |
| | | var list = wdnmoParam.ResultPoints; |
| | | if (list == null) return list; |
| | | list.Sort((a, b) => string.Compare(a.Key, b.Key)); |
| | | Nodes.Sort((a, b) => string.Compare(a.ID, b.ID)); |
| | | Links.Sort((a, b) => string.Compare(a.ID, b.ID)); |
| | | SetNodeFromWparam(this, list, "Press"); |
| | | SetNodeFromWparam(this, list, "Head"); |
| | | SetNodeFromWparam(this, list, "Demand"); |
| | | |
| | | SetLinkFromWparam(this, list, "Flow"); |
| | | SetLinkFromWparam(this, list, "Velocity"); |
| | | SetLinkFromWparam(this, list, "Headloss"); |
| | | this._isCalculated = true; |
| | | return list; |
| | | //return new List<TimePoint>(); |
| | | } |
| | | |
| | | private void SetNodeFromWparam(MapViewNetWork net, List<TimePoint> list, string valueType) |
| | | { |