duheng
2024-12-24 f47abf649b85ce5fd21725fedaebba359a6dfd1d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
using System.Net.Http.Headers;
 
namespace Yw.EPAnet
{
    /// <summary>
    /// 管网能耗分析拓展
    /// </summary>
    public static class NetworkEnergyAnalyseExtensions
    {
 
        /// <summary>
        /// 分析整个管网的能量
        /// </summary>
        public static List<EnergyPoint> AnalyzeEnergy(this Network network,CalcuResult calcuResult)
        {
            var dictLinks = calcuResult.LinkList.ToDictionary(p => p.Id);
            var dictNodes = calcuResult.NodeList.ToDictionary(p => p.Id);
            var points=new List<EnergyPoint>();
            var result = new EnergyResult();
            //找到管网中需水量为负的节点
            var negativeDemandNodes = network.GetAllNodes().Where(n => 
            {
                if (n is Node node)
                {
                    return dictNodes[node.Id].Demand < 0;
                }
                return false;
            }).ToList();
 
            //找到管网中需水量为正的节点
            var positiveDemandNodes = network.GetAllNodes().Where(n =>
            {
                if (n is Node node)
                {
                    return dictNodes[node.Id].Demand > 0;
                }
                return false;
            }).ToList();
 
            double minElev = 99999999;
 
            List<Node> DemandNodes=new List<Node>();
            DemandNodes.AddRange(negativeDemandNodes);
            DemandNodes.AddRange(positiveDemandNodes);
            foreach (var node in DemandNodes)
            {
                if (node is Junction n)
                {
                    if (n.Elev < minElev)
                    {
                        minElev = n.Elev;
                    }
                }
                else if (node is Tank t)
                {
                    if (t.PoolElev < minElev)
                    {
                        minElev = t.PoolElev;
                    }
                }
                else if (node is Reservoir r)
                {
                    var elev = r.PoolElev == null ? 0 : (double)r.PoolElev;
                    if (elev < minElev)
                    {
                        minElev = elev;
                    }
                }
            }
 
 
 
 
 
            //计算这些节点的势能,势能计算公式为:势能=需水量*节点水头
 
            foreach (var node in negativeDemandNodes)
            {
                if (node is Node n)
                {
                    double energyInW = GetEnergyPowerByQH(Math.Abs(dictNodes[n.Id].Demand), dictNodes[n.Id].Head- minElev);
                    var energyPoint = new EnergyPoint
                    {
                        Id = n.Id,
                        EnergyType = eEnergyType.Input,
                        EnergyPower = energyInW,
 
                    };
                    points.Add(energyPoint);
                    result.InputEnergy.Add(n.Id, new List<EnergyPoint> { energyPoint });
                    result.InputTotalEnerge += energyInW;
                }
            }
 
 
            foreach (var node in positiveDemandNodes)
            {
                if (node is Node n)
                {
                    double energyInW =  GetEnergyPowerByQH(Math.Abs(dictNodes[n.Id].Demand), dictNodes[n.Id].Head- minElev);
                    var energyPoint = new EnergyPoint
                    {
                        Id = n.Id,
                        EnergyType = eEnergyType.Output,
                        EnergyPower = energyInW,
                     
                    };
                    points.Add(energyPoint);
                    result.OutputEnergy.Add(n.Id, new List<EnergyPoint> { energyPoint });
                    result.OutputTotalEnerge += energyInW;
                }
            }
 
            foreach (var link in network.GetAllLinks())
            {
                if (link is Pipe p)
                {
 
                    var cStartnode = (dictLinks[ link.Id].Flow > 0 ? link.StartNode : link.EndNode) as Node;
                    var cEndnode = (dictLinks[link.Id].Flow > 0 ? link.EndNode : link.StartNode) as Node;
                    var endNodeMinorlossCoff = p.EndMinorLossCoeff;
                    var startNodeMinorlossCoff = p.StartMinorLossCoeff;
                    //根据p.diameter和p.flow计算流速
                    double velocity = dictLinks[p.Id].Flow / (Math.PI * Math.Pow(p.Diameter / 2, 2));
                    var flow = Math.Abs(dictLinks[p.Id].Flow);
                    if (p.StartMinorLossCoeff!=0)
                    {
                        //根据流速计算局部水头损失
                        double headminorloss1 = p.StartMinorLossCoeff * Math.Pow(velocity, 2) / 2 / 9.81;
                        double energypower=GetEnergyPowerByQH(flow, headminorloss1);
                        var Id = cStartnode.Id;
                        if (!result.LossEnergy.ContainsKey(Id)) result.LossEnergy.Add(Id, new List<EnergyPoint>());
                        var energypoint=new EnergyPoint
                        {
                            Id = Id,
                            EnergyType = eEnergyType.MinorLoss,
                            EnergyPower = energypower,
                           
                        };
 
                        result.MinorLossTotalEnerge += energypower; 
                        //如果存在多个局部水头损失,需要累加合并
                        if (result.LossEnergy[Id].Any(e => e.EnergyType == eEnergyType.MinorLoss))
                        {
                            var exist = result.LossEnergy[Id].First(e => e.EnergyType == eEnergyType.MinorLoss);
                            exist.EnergyPower += energypower;
                        }
                        else
                        {
                            result.LossEnergy[Id].Add(energypoint);
                        }
                        var point = result.LossEnergy[Id].First(e => e.EnergyType == eEnergyType.MinorLoss);
                        points.Add(point);
                    }
 
                    if (p.EndMinorLossCoeff != 0)
                    {
                        //根据流速计算局部水头损失
                        double headminorloss2 = p.EndMinorLossCoeff * Math.Pow(velocity, 2) / 2 / 9.81;
                        double energypower = GetEnergyPowerByQH(flow, headminorloss2);
                        var Id = cEndnode.Id;
                        if (!result.LossEnergy.ContainsKey(Id)) result.LossEnergy.Add(Id, new List<EnergyPoint>());
                        var energypoint = new EnergyPoint
                        {
                            Id = Id,
                            EnergyType = eEnergyType.MinorLoss,
                            EnergyPower = energypower,
                          
                        };
                        result.MinorLossTotalEnerge += energypower;
                        //如果存在多个局部水头损失,需要累加合并
                        if (result.LossEnergy[Id].Any(e => e.EnergyType == eEnergyType.MinorLoss))
                        {
                            var exist = result.LossEnergy[Id].First(e => e.EnergyType == eEnergyType.MinorLoss);
                            exist.EnergyPower += energypower;
                        }
                        else
                        {
                            result.LossEnergy[Id].Add(energypoint);
                        }
                        var point = result.LossEnergy[Id].First(e => e.EnergyType == eEnergyType.MinorLoss);
                        points.Add(point);
                    }
 
                    double pipeheadminorloss = 0;
                    if (p.MinorLossCoeff!=0)
                    {
                        //根据流速计算局部水头损失
                        pipeheadminorloss = p.MinorLossCoeff * Math.Pow(velocity, 2) / 2 / 9.81;
                        double energypower = GetEnergyPowerByQH(flow, pipeheadminorloss);
                        var Id = p.Id;
                        if (!result.LossEnergy.ContainsKey(Id)) result.LossEnergy.Add(Id, new List<EnergyPoint>());
                        var energypoint = new EnergyPoint
                        {
                            Id = Id,
                            EnergyType = eEnergyType.MinorLoss,
                            EnergyPower = energypower,
 
                        };
                        result.LossEnergy[Id].Add(energypoint);
                        result.MinorLossTotalEnerge += energypower;
                        points.Add(energypoint);
                    }
 
                    
                    {
                        double headlossFriction =Math.Abs(dictLinks[p.Id].HeadLoss) - pipeheadminorloss;
                        double energypower = GetEnergyPowerByQH(flow, headlossFriction);
                        var Id = p.Id;
                        if (!result.LossEnergy.ContainsKey(Id)) result.LossEnergy.Add(Id, new List<EnergyPoint>());
                        var energypoint = new EnergyPoint
                        {
                            Id = Id,
                            EnergyType = eEnergyType.FrictionalLoss,
                            EnergyPower = energypower,
 
                        };
                        result.LossEnergy[Id].Add(energypoint);
                        result.FrictionalLossTotalEnerge += energypower;
                        points.Add(energypoint);
                    }
 
 
                    
                }
                else if (link is Valve || link is Pump || link is Resistance)
                {
                    //只计算阀门本身的局部水头损失
                    var flow = Math.Abs(dictLinks[link.Id].Flow);
                    //根据流速计算局部水头损失
                    double headminorloss1 =Math.Abs(dictNodes[link.StartNode.Id].Head - dictNodes[link.EndNode.Id].Head);
                    double energypower = GetEnergyPowerByQH(flow, headminorloss1);
                    var Id = link.Id;
 
                    if (link is Pump)
                    {
                        var Type = eEnergyType.Promote;
                        if (!result.InputEnergy.ContainsKey(Id)) result.InputEnergy.Add(Id, new List<EnergyPoint>());
                        var energypoint = new EnergyPoint
                        {
                            Id = Id,
                            EnergyType = Type,
                            EnergyPower = energypower,
 
                        };
                        result.InputEnergy[Id].Add(energypoint);
                        result.InputTotalEnerge += energypower;
                        points.Add(energypoint);
                    }
                    else
                    {
                        var Type = eEnergyType.MinorLoss;
                        if (!result.LossEnergy.ContainsKey(Id)) result.LossEnergy.Add(Id, new List<EnergyPoint>());
                        EnergyPoint energypoint = new EnergyPoint
                        {
                            Id = Id,
                            EnergyType = Type,
                            EnergyPower = energypower,
 
                        };
                        result.LossEnergy[Id].Add(energypoint);
                        result.MinorLossTotalEnerge += energypower;
                        points.Add(energypoint);
                    }
                    
                }
            }
 
            return points;
        }
 
        private static double GetEnergyPowerByQH(double flowQ,double head)
        {
            // 计算将 1 m³的水,提升 1 m 的高度所需要的能量
            // 1 m³的水受到重力G=1m³ * 1000 kg/m³(密度) * 9.81 m/s² (重力加速度) = 9810 N
            // 能量 = 力 * 距离 = 9810 N * 1 m = 9810 J
            // 势能等效功率 = 能量 / 时间 = 9810 J / 1 h = 9810 J/h = 9810/3600 J/s= 9810/3600 W
            double energyInM4PerH = flowQ * head;
            double energyInW = energyInM4PerH * 1000 * 9.81 / 3600;
            return energyInW;
        }
 
 
    }
 
    public class EnergyPoint
    {
        public string Id { get; set; }
        public eEnergyType EnergyType { get; set; }
        /// <summary>
        /// 单位时间内的能量,单位:瓦特W=焦耳J/秒s
        /// </summary>
        public double EnergyPower { get; set; }
 
    }
 
    public class EnergyResult
    {
 
        public Dictionary<string, List<EnergyPoint>> InputEnergy { get; set; }
        public Dictionary<string, List<EnergyPoint>> LossEnergy { get; set; }
        public Dictionary<string, List<EnergyPoint>> OutputEnergy { get; set; }
 
        public double InitTotalEnerge { get; set; }
 
        public double InputTotalEnerge { get; set; }
 
        public double MinorLossTotalEnerge { get; set; }
 
        public double FrictionalLossTotalEnerge { get; set; }
 
        public double OutputTotalEnerge { get; set; }
 
        public EnergyResult()
        {
            InputEnergy = new Dictionary<string, List<EnergyPoint>>();
            LossEnergy = new Dictionary<string, List<EnergyPoint>>();
            OutputEnergy = new Dictionary<string, List<EnergyPoint>>();
            InputTotalEnerge = 0;
            MinorLossTotalEnerge = 0;
            FrictionalLossTotalEnerge = 0;
            OutputTotalEnerge = 0;
        }
 
 
    }
 
    public enum eEnergyType
    {
        /// <summary>
        /// 重力势能输入:水池、水库
        /// </summary>
        Input,
 
        /// <summary>
        /// 重力势能输出:水池、水库、扩散器
        /// </summary>
        Output,
 
        /// <summary>
        /// 水泵提升能量(输入系统的有效功率),不考虑效率
        /// </summary>
        Promote,
 
        /// <summary>
        /// 局部摩擦阻力带来的能量损失:阀门、连接节点、管道、设备(换热器、空压机)
        /// </summary>
        MinorLoss,
 
        /// <summary>
        /// 沿程摩擦阻力带来的能量损失:管道
        /// </summary>
        FrictionalLoss,
    }
 
  
}