Shuxia Ning
2025-01-14 0f99d4d12f2eae29bbe343f4b3131f2faeccda5d
WinFrmUI/Yw.WinFrmUI.Hydro.Core/00-core/05-extensions/HydroModelInfoExtensions.cs
@@ -1,273 +1,579 @@
using Yw.EPAnet;
using Yw.Hydro;
using Yw.Hydro;
using Yw.Model;
namespace Yw.WinFrmUI
{
    /// <summary>
    ///
    /// 水力信息拓展
    /// </summary>
    public static class HydroModelInfoExtensions
    {
        /// <summary>
        /// 获取可见字典
        /// </summary>
        public static Dictionary<string, HydroVisualInfo> GetVisualDict(this Yw.Model.HydroModelInfo hydroInfo)
        {
            if (hydroInfo == null)
            {
                return default;
            }
            var allVisualList = hydroInfo.GetAllVisuals();
            return allVisualList?.ToDictionary(x => x.Code);
        }
        #region 修复参数
        private const double _pipe_roughness_default = 110;//管道默认粗糙系数
        private const double _translation_roughness_default = 120;//过渡件默认粗糙系数
        private const double _translation_minorloss_default = 0.3;//过渡件默认局阻系数
        private const double _valve_minorloss_default = 0.3d; //阀门默认局阻系数
        private const double _resistance_minorloss_default = 9d;//阻件默认局阻系数
        private const double _blunthead_minorloss_default = 0.1d;//闷头局部阻力系数
        private const double _cooling_coefficient_default = 100000d;//冷却塔流量系数
        /// <summary>
        /// 计算
        /// 修复参数
        /// </summary>
        public static HydroCalcuResult Calcu(this Yw.Model.HydroModelInfo hydroInfo, string calcuMode = Yw.EPAnet.CalcuMode.Simple)
        {
            var network = hydroInfo.ToNetwork();
            if (network == null)
            {
                return default;
            }
            var calcuResult = network.Calcu(calcuMode);
            if (calcuResult == null)
            {
                return default;
            }
            return hydroInfo.GetCalcuResult(calcuResult);
        }
        /// <summary>
        /// 获取计算结果
        /// </summary>
        public static HydroCalcuResult GetCalcuResult(this Yw.Model.HydroModelInfo hydroInfo, Yw.EPAnet.CalcuResult calcuResult)
        {
            if (hydroInfo == null)
            {
                return default;
            }
            if (calcuResult == null)
            {
                return default;
            }
            var hydroCalcuResult = new HydroCalcuResult(calcuResult);
            //流量计
            var allFlowmeterList = hydroInfo.Flowmeters;
            if (allFlowmeterList != null && allFlowmeterList.Count > 0)
            {
                var allLinkList = hydroInfo.GetAllLinks();
                foreach (var flowmeter in allFlowmeterList)
                {
                    var calcuFlowmeterResult = hydroCalcuResult.NodeList?.Find(x => x.Code == flowmeter.Code);
                    if (calcuFlowmeterResult != null)
                    {
                        var calcuFlowmeterNewResult = new HydroCalcuFlowmeterResult(calcuFlowmeterResult);
                        var calcuFlowmeterLinkResultList = new List<HydroCalcuLinkResult>();
                        var flowmeterLinkList = allLinkList?.Where(x => x.StartCode == flowmeter.Code || x.EndCode == flowmeter.Code).ToList();
                        if (flowmeterLinkList != null && flowmeterLinkList.Count > 0)
                        {
                            foreach (var flowmeterLink in flowmeterLinkList)
                            {
                                var calcuFlowmeterLinkResult = hydroCalcuResult.LinkList?.Find(x => x.Code == flowmeterLink.Code);
                                if (calcuFlowmeterLinkResult != null)
                                {
                                    calcuFlowmeterLinkResultList.Add(calcuFlowmeterLinkResult);
                                }
                            }
                        }
                        if (calcuFlowmeterLinkResultList.Exists(x => x.CalcuFlow.HasValue))
                        {
                            calcuFlowmeterNewResult.CalcuQ = calcuFlowmeterLinkResultList.Where(x => x.CalcuFlow.HasValue).Average(x => x.CalcuFlow.Value);
                        }
                        hydroCalcuResult.NodeList.Remove(calcuFlowmeterResult);
                        hydroCalcuResult.NodeList.Add(calcuFlowmeterNewResult);
                    }
                }
            }
            //压力表
            var allPressmeterList = hydroInfo.Pressmeters;
            if (allPressmeterList != null && allPressmeterList.Count > 0)
            {
                foreach (var pressmeter in allPressmeterList)
                {
                    var calcuPressmeterResult = hydroCalcuResult.NodeList?.Find(x => x.Code == pressmeter.Code);
                    if (calcuPressmeterResult != null)
                    {
                        var calcuPressmeterNewResult = new HydroCalcuPressmeterResult(calcuPressmeterResult);
                        calcuPressmeterNewResult.CalcuPr = calcuPressmeterResult.CalcuPress;
                        hydroCalcuResult.NodeList.Remove(calcuPressmeterResult);
                        hydroCalcuResult.NodeList.Add(calcuPressmeterNewResult);
                    }
                }
            }
            //水泵
            var allPumpList = hydroInfo.Pumps;
            if (allPumpList != null && allPumpList.Count > 0)
            {
                foreach (var pump in allPumpList)
                {
                    var calcuPumpResult = hydroCalcuResult.LinkList.Find(x => x.Code == pump.Code);
                    if (calcuPumpResult != null)
                    {
                        var calcuPumpNewResult = new HydroCalcuPumpResult(calcuPumpResult);
                        calcuPumpNewResult.CalcuQ = calcuPumpResult.CalcuFlow;
                        if (calcuPumpNewResult.CalcuQ.HasValue)
                        {
                            var calcuNodeStartResult = hydroCalcuResult.NodeList?.Find(x => x.Code == pump.StartCode);
                            var calcuNodeEndResult = hydroCalcuResult.NodeList?.Find(x => x.Code == pump.EndCode);
                            if (calcuNodeStartResult != null && calcuNodeEndResult != null)
                            {
                                if (calcuNodeStartResult.CalcuPress.HasValue && calcuNodeEndResult.CalcuPress.HasValue)
                                {
                                    calcuPumpNewResult.CalcuH = Math.Abs(calcuNodeStartResult.CalcuPress.Value - calcuNodeEndResult.CalcuPress.Value);
                                }
                                if (pump.LinkStatus == Yw.Hydro.PumpStatus.Open && pump.RatedN.HasValue)
                                {
                                    var curveqp = hydroInfo.Curves?.Find(x => x.Code == pump.CurveQP);
                                    if (curveqp != null)
                                    {
                                        if (curveqp.CurveData != null && curveqp.CurveData.Count > 3)
                                        {
                                            var point2dList = curveqp.CurveData.Select(x => new Yw.Geometry.Point2d(x.X, x.Y)).ToList();
                                            var point2dSimularList = point2dList.GetQPPointListByN(pump.RatedN.Value, pump.RatedN.Value * pump.SpeedRatio);
                                            var pumpCurveQp = new Yw.Pump.CurveQP(eFeatType.Cubic, point2dSimularList);
                                            calcuPumpNewResult.CalcuP = pumpCurveQp.FeatCurve.GetPointY(calcuPumpNewResult.CalcuQ.Value);
                                        }
                                    }
                                }
                                if (calcuPumpNewResult.CalcuH.HasValue && calcuPumpNewResult.CalcuP.HasValue)
                                {
                                    calcuPumpNewResult.CalcuE = Yw.Pump.CalculationHelper.CalcuE(calcuPumpNewResult.CalcuQ.Value, calcuPumpNewResult.CalcuH.Value, calcuPumpNewResult.CalcuP.Value);
                                }
                            }
                        }
                        hydroCalcuResult.LinkList.Remove(calcuPumpResult);
                        hydroCalcuResult.LinkList.Add(calcuPumpNewResult);
                        switch (pump.LinkStatus)
                        {
                            case Yw.Hydro.PumpStatus.Open:
                                {
                                    if (calcuPumpNewResult.CalcuFlow.HasValue)
                                    {
                                        if (calcuPumpNewResult.CalcuFlow.Value <= 0)
                                        {
                                            hydroCalcuResult.WainingList.Add(new HydroCalcuWarning()
                                            {
                                                Code = pump.Code,
                                                Message = $"[{pump.Name}]不满足当前工况 "
                                            });
                                        }
                                    }
                                    else
                                    {
                                        hydroCalcuResult.WainingList.Add(new HydroCalcuWarning()
                                        {
                                            Code = pump.Code,
                                            Message = $"[{pump.Name}]流量计算失败 "
                                        });
                                    }
                                }
                                break;
                            case Yw.Hydro.PumpStatus.Closed:
                                {
                                    if (calcuPumpNewResult.CalcuFlow.HasValue)
                                    {
                                        if (calcuPumpNewResult.CalcuFlow.Value > 0)
                                        {
                                            hydroCalcuResult.WainingList.Add(new HydroCalcuWarning()
                                            {
                                                Code = pump.Code,
                                                Message = $"[{pump.Name}]不满足当前工况 "
                                            });
                                        }
                                    }
                                    else
                                    {
                                        hydroCalcuResult.WainingList.Add(new HydroCalcuWarning()
                                        {
                                            Code = pump.Code,
                                            Message = $"[{pump.Name}]流量计算失败 "
                                        });
                                    }
                                }
                                break;
                            default: break;
                        }
                    }
                }
            }
            return hydroCalcuResult;
        }
        /// <summary>
        /// 修复
        /// </summary>
        public static bool Repair(this Yw.Model.HydroModelInfo hydroInfo, out string msg)
        public static void RepairParas
            (
                this Yw.Model.HydroModelInfo hydroInfo,
                HydroPropStatusHelper propStatusHelper,
                out string msg
            )
        {
            msg = string.Empty;
            if (hydroInfo == null)
            {
                return false;
                return;
            }
            var checkResult = hydroInfo.Check();
            if (!checkResult.Succeed)
            {
                msg = "检查失败导致无法进行试算,停止管网修复!";
                return false;
            }
            var allNodes = hydroInfo.GetAllNodes();
            var allLinks = hydroInfo.GetAllLinks();
            var calcuResult = hydroInfo.Calcu(Yw.EPAnet.CalcuMode.Simple);
            if (!calcuResult.Succeed)
            //管道
            if (hydroInfo.Pipes != null && hydroInfo.Pipes.Count > 0)
            {
                msg = "试算失败,停止管网修复!";
                return false;
            }
            var allLinkList = hydroInfo.GetAllLinks();
            if (allLinkList != null && allLinkList.Count < 1)
            {
                msg = "模型中未包含管段信息,停止管网修复!";
                return false;
            }
            int count = 0;
            foreach (var link in allLinkList)
            {
                var calcuLink = calcuResult.LinkList?.Find(x => x.Code == link.Code);
                if (calcuLink == null)
                foreach (var pipe in hydroInfo.Pipes)
                {
                    continue;
                }
                if (!calcuLink.CalcuFlow.HasValue)
                {
                    continue;
                }
                if (calcuLink.CalcuFlow.Value < 0)
                {
                    var tempCode = link.StartCode;
                    link.StartCode = link.EndCode;
                    link.EndCode = tempCode;
                    count++;
                    if (pipe.Roughness <= 0)
                    {
                        pipe.Roughness = _pipe_roughness_default;
                        propStatusHelper.UpdatePropStatus(pipe, nameof(pipe.Roughness), ePropStatus.Abnormal, "【粗糙系数】数据异常");
                    }
                }
            }
            msg = $"修复完成,共修复管段({count})个!";
            return true;
            //过渡件
            if (hydroInfo.Translations != null && hydroInfo.Translations.Count > 0)
            {
                foreach (var translation in hydroInfo.Translations)
                {
                    double? tempDiameter = null;
                    var startNode = allNodes.Find(x => x.Code == translation.StartCode);
                    if (startNode != null)
                    {
                        var startLink = allLinks
                            .Find(x => (x.StartCode == startNode.Code || x.EndCode == startNode.Code) && x.Code != translation.Code);
                        if (startLink != null)
                        {
                            var startPipe = startLink as Yw.Model.HydroPipeInfo;
                            if (startPipe != null)
                            {
                                tempDiameter = startPipe.Diameter;
                                if (translation.StartDiameter != startPipe.Diameter)
                                {
                                    translation.StartDiameter = startPipe.Diameter;
                                }
                            }
                        }
                    }
                    var endNode = allNodes.Find(x => x.Code == translation.EndCode);
                    if (endNode != null)
                    {
                        var endLink = allLinks
                            .Find(x => (x.StartCode == endNode.Code || x.EndCode == endNode.Code) && x.Code != translation.Code);
                        if (endLink != null)
                        {
                            var endPipe = endLink as Yw.Model.HydroPipeInfo;
                            if (endPipe != null)
                            {
                                if (translation.EndDiameter != endPipe.Diameter)
                                {
                                    tempDiameter = endPipe.Diameter;
                                    translation.EndDiameter = endPipe.Diameter;
                                }
                            }
                        }
                    }
                    if (translation.StartDiameter <= 0)
                    {
                        if (tempDiameter.HasValue)
                        {
                            translation.StartDiameter = tempDiameter.Value;
                        }
                    }
                    if (translation.EndDiameter <= 0)
                    {
                        if (tempDiameter.HasValue)
                        {
                            translation.EndDiameter = tempDiameter.Value;
                        }
                    }
                }
            }
            //阀门
            if (hydroInfo.Valves != null && hydroInfo.Valves.Count > 0)
            {
                foreach (var valve in hydroInfo.Valves)
                {
                    if (valve.MinorLoss <= 0)
                    {
                        valve.MinorLoss = _valve_minorloss_default;
                    }
                    if (valve.Diameter <= 0)
                    {
                        var startNode = allNodes.Find(x => x.Code == valve.StartCode);
                        if (startNode != null)
                        {
                            var startPipe = allLinks
                                .Find(x => (x.StartCode == startNode.Code || x.EndCode == startNode.Code) && x.Code != valve.Code)
                                as Yw.Model.HydroPipeInfo;
                            if (startPipe != null)
                            {
                                valve.Diameter = startPipe.Diameter;
                            }
                            else
                            {
                                var endNode = allNodes.Find(x => x.Code == valve.EndCode);
                                if (endNode != null)
                                {
                                    var endPipe = allLinks
                                        .Find(x => (x.StartCode == endNode.Code || x.EndCode == endNode.Code) && x.Code != valve.Code)
                                        as Yw.Model.HydroPipeInfo;
                                    if (endPipe != null)
                                    {
                                        valve.Diameter = endPipe.Diameter;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            //阻件
            var allResistanceList = hydroInfo.GetAllResistances();
            if (allResistanceList != null && allResistanceList.Count > 0)
            {
                foreach (var resistance in allResistanceList)
                {
                    if (resistance.MinorLoss <= 0)
                    {
                        resistance.MinorLoss = _resistance_minorloss_default;
                    }
                    var startNode = allNodes.Find(x => x.Code == resistance.StartCode);
                    if (startNode != null)
                    {
                        var startPipe = allLinks
                            .Find(x => (x.StartCode == startNode.Code || x.EndCode == startNode.Code) && x.Code != resistance.Code)
                                as Yw.Model.HydroPipeInfo;
                        if (startPipe != null)
                        {
                            resistance.Diameter = startPipe.Diameter;
                        }
                        else
                        {
                            var endNode = allNodes.Find(x => x.Code == resistance.EndCode);
                            if (endNode != null)
                            {
                                var endPipe = allLinks
                                    .Find(x => (x.StartCode == endNode.Code || x.EndCode == endNode.Code) && x.Code != resistance.Code)
                                     as Yw.Model.HydroPipeInfo;
                                if (endPipe != null)
                                {
                                    resistance.Diameter = endPipe.Diameter;
                                }
                            }
                        }
                    }
                }
            }
            //闷头
            if (hydroInfo.Bluntheads != null && hydroInfo.Bluntheads.Count > 0)
            {
                foreach (var visual in hydroInfo.Bluntheads)
                {
                    if (visual.MinorLoss <= 0)
                    {
                        visual.MinorLoss = _blunthead_minorloss_default;
                    }
                    if (visual.Caliber < 1)
                    {
                        var link = allLinks.Find(x => x.StartCode == visual.Code || x.EndCode == visual.Code);
                        if (link != null)
                        {
                            if (link is HydroResistanceInfo resistance)
                            {
                                visual.Caliber = resistance.Diameter;
                            }
                            else if (link is HydroValveInfo valve)
                            {
                                visual.Caliber = valve.Diameter;
                            }
                            else if (link is HydroTranslationInfo translation)
                            {
                            }
                            else if (link is HydroPipeInfo pipe)
                            {
                                visual.Caliber = pipe.Diameter;
                            }
                        }
                    }
                }
            }
            #region 弯头
            if (hydroInfo.Elbows != null && hydroInfo.Elbows.Count > 0)
            {
                foreach (var visual in hydroInfo.Elbows)
                {
                    if (visual.MinorLoss <= 0)
                    {
                        visual.MinorLoss = _blunthead_minorloss_default;
                    }
                    if (visual.Caliber < 1)
                    {
                        var link = allLinks.Find(x => x.StartCode == visual.Code || x.EndCode == visual.Code);
                        if (link != null)
                        {
                            if (link is HydroResistanceInfo resistance)
                            {
                                visual.Caliber = resistance.Diameter;
                            }
                            else if (link is HydroValveInfo valve)
                            {
                                visual.Caliber = valve.Diameter;
                            }
                            else if (link is HydroTranslationInfo translation)
                            {
                            }
                            else if (link is HydroPipeInfo pipe)
                            {
                                visual.Caliber = pipe.Diameter;
                            }
                        }
                    }
                }
            }
            #endregion
            #region 冷却塔
            if (hydroInfo.Coolings != null && hydroInfo.Coolings.Count > 0)
            {
                foreach (var cooling in hydroInfo.Coolings)
                {
                    if (cooling.Coefficient < 1)
                    {
                        cooling.Coefficient = _cooling_coefficient_default;
                        propStatusHelper.UpdatePropStatus(cooling.Code, nameof(cooling.Coefficient), ePropStatus.Abnormal, $"【流量系数】数据异常,使用默认值[{_cooling_coefficient_default}]修复");
                    }
                    if (cooling.Caliber < 1)
                    {
                        var link = allLinks.Find(x => x.StartCode == cooling.Code || x.EndCode == cooling.Code);
                        if (link != null)
                        {
                            if (link is HydroPipeInfo pipe)
                            {
                                if (pipe.Diameter > 0)
                                {
                                    cooling.Caliber = pipe.Diameter;
                                    propStatusHelper.UpdatePropStatus(cooling.Code, nameof(cooling.Caliber), ePropStatus.Abnormal, $"【口径】数据异常,使用相邻管道修复");
                                }
                            }
                        }
                    }
                }
            }
            #endregion
        }
        #endregion
        #region 装置计算
        /// <summary>
        /// 获取开始压力(m)
        /// </summary>
        public static double GetStartHead(this Yw.Model.HydroModelInfo hydroInfo)
        {
            if (hydroInfo == null)
            {
                return default;
            }
            double startHeadValue = 0;
            var allSourceList = hydroInfo.GetAllSources();
            if (allSourceList != null && allSourceList.Count > 0)
            {
                var startSource = allSourceList.Matching(new List<string>()
                {
                    Yw.Hydro.Flags.水源,
                    Yw.Hydro.Flags.始端,
                    Yw.Hydro.Flags.默认
                });
                if (startSource == null)
                {
                    startSource = allSourceList.Matching(new List<string>()
                    {
                        Yw.Hydro.Flags.水源,
                        Yw.Hydro.Flags.始端
                    });
                }
                if (startSource != null)
                {
                    if (startSource is HydroTankInfo tank)
                    {
                        startHeadValue = tank.PoolElev + tank.InitLevel;
                    }
                }
            }
            return startHeadValue;
        }
        /// <summary>
        /// 获取结束压力(m)
        /// </summary>
        public static double GetEndHead(this Yw.Model.HydroModelInfo hydroInfo)
        {
            if (hydroInfo == null)
            {
                return default;
            }
            double endHeadValue = 0;
            var allNodeList = hydroInfo.GetAllNodes();
            if (allNodeList != null && allNodeList.Count > 0)
            {
                var endSource = allNodeList.Matching(new List<string>()
                {
                    Yw.Hydro.Flags.水源,
                    Yw.Hydro.Flags.末端,
                    Yw.Hydro.Flags.默认
                });
                if (endSource == null)
                {
                    endSource = allNodeList.Matching(new List<string>()
                    {
                        Yw.Hydro.Flags.水源,
                        Yw.Hydro.Flags.末端
                    });
                }
                if (endSource != null)
                {
                    if (endSource is HydroTankInfo tank)
                    {
                        endHeadValue = tank.PoolElev + tank.InitLevel;
                    }
                    else if (endSource is HydroEmitterInfo emitter)
                    {
                        endHeadValue = emitter.Elev;
                    }
                }
            }
            return endHeadValue;
        }
        /// <summary>
        /// 获取扬程
        /// </summary>
        public static double GetHead(this Yw.Model.HydroModelInfo hydroInfo)
        {
            if (hydroInfo == null)
            {
                return default;
            }
            var startHeadValue = GetStartHead(hydroInfo);
            var endHeadValue = GetEndHead(hydroInfo);
            return endHeadValue - startHeadValue;
        }
        /// <summary>
        /// 获取总管流量
        /// </summary>
        public static double? GetPipeQ(this Yw.Model.HydroModelInfo hydroInfo, HydroCalcuResult calcuResult)
        {
            return GetPipeQ(hydroInfo, calcuResult?.GetVisualDict());
        }
        /// <summary>
        /// 获取总管流量
        /// </summary>
        public static double? GetPipeQ(this Yw.Model.HydroModelInfo hydroInfo, Dictionary<string, HydroCalcuVisualResult> allCalcuVisualDict)
        {
            if (hydroInfo == null)
            {
                return default;
            }
            if (allCalcuVisualDict == null || allCalcuVisualDict.Count < 1)
            {
                return default;
            }
            var allLinkList = hydroInfo.GetAllLinks();
            if (allLinkList == null || allLinkList.Count < 1)
            {
                return default;
            }
            var link = allLinkList.Matching(new List<string>()
            {
                Yw.Hydro.Flags.总管,
                Yw.Hydro.Flags.出口,
                Yw.Hydro.Flags.默认
            });
            if (link == null)
            {
                link = allLinkList.Matching(new List<string>()
                {
                    Yw.Hydro.Flags.总管,
                    Yw.Hydro.Flags.出口
                });
            }
            if (link == null)
            {
                return default;
            }
            var calcuVisualResult = allCalcuVisualDict.GetValue(link.Code);
            if (calcuVisualResult == null)
            {
                return default;
            }
            var calcuValue = calcuVisualResult.GetCalcuValue(Yw.Hydro.VisualCalcuProp.CalcuFlow);
            if (calcuValue == null)
            {
                return default;
            }
            return Math.Round(Math.Abs(calcuValue.Value), 1);
        }
        /// <summary>
        /// 获取总管结束压力(绝对压力)
        /// </summary>
        public static double? GetPipeEndHead(this Yw.Model.HydroModelInfo hydroInfo, Dictionary<string, HydroCalcuVisualResult> allCalcuVisualDict)
        {
            if (hydroInfo == null)
            {
                return default;
            }
            if (allCalcuVisualDict == null || allCalcuVisualDict.Count < 1)
            {
                return default;
            }
            var allNodeList = hydroInfo.GetAllNodes();
            if (allNodeList == null || allNodeList.Count < 1)
            {
                return default;
            }
            var node = allNodeList.Matching(new List<string>()
            {
                Yw.Hydro.Flags.总管,
                Yw.Hydro.Flags.出口,
                Yw.Hydro.Flags.默认
            });
            if (node == null)
            {
                node = allNodeList.Matching(new List<string>()
                {
                    Yw.Hydro.Flags.总管,
                    Yw.Hydro.Flags.出口
                });
            }
            if (node == null)
            {
                return default;
            }
            var calcuVisualResult = allCalcuVisualDict.GetValue(node.Code);
            if (calcuVisualResult == null)
            {
                return default;
            }
            var calcuValue = calcuVisualResult.GetCalcuValue(Yw.Hydro.VisualCalcuProp.CalcuHead);
            if (calcuValue == null)
            {
                return default;
            }
            return Math.Round(calcuValue.Value, 2);
        }
        /// <summary>
        /// 获取总管结束压力(绝对压力)
        /// </summary>
        public static double? GetPipeEndHead(this Yw.Model.HydroModelInfo hydroInfo, HydroCalcuResult calcuResult)
        {
            return GetPipeEndHead(hydroInfo, calcuResult?.GetVisualDict());
        }
        /// <summary>
        /// 获取总管压力(绝对压力)
        /// </summary>
        public static double? GetPipeHead(this Yw.Model.HydroModelInfo hydroInfo, HydroCalcuResult calcuResult)
        {
            return GetPipeHead(hydroInfo, calcuResult?.GetVisualDict());
        }
        /// <summary>
        /// 获取总管压力(绝对压力)
        /// </summary>
        public static double? GetPipeHead(this Yw.Model.HydroModelInfo hydroInfo, Dictionary<string, HydroCalcuVisualResult> allCalcuVisualDict)
        {
            if (hydroInfo == null)
            {
                return default;
            }
            if (allCalcuVisualDict == null || allCalcuVisualDict.Count < 1)
            {
                return default;
            }
            var allNodeList = hydroInfo.GetAllNodes();
            if (allNodeList == null || allNodeList.Count < 1)
            {
                return default;
            }
            var node = allNodeList.Matching(new List<string>()
            {
                Yw.Hydro.Flags.总管,
                Yw.Hydro.Flags.出口,
                Yw.Hydro.Flags.默认
            });
            if (node == null)
            {
                node = allNodeList.Matching(new List<string>()
                {
                    Yw.Hydro.Flags.总管,
                    Yw.Hydro.Flags.出口
                });
            }
            if (node == null)
            {
                return default;
            }
            var calcuVisualResult = allCalcuVisualDict.GetValue(node.Code);
            if (calcuVisualResult == null)
            {
                return default;
            }
            var calcuValue = calcuVisualResult.GetCalcuValue(Yw.Hydro.VisualCalcuProp.CalcuHead);
            if (calcuValue == null)
            {
                return default;
            }
            var endHeadValue = calcuValue.Value;
            var startHeadValue = GetStartHead(hydroInfo);
            return Math.Round(endHeadValue - startHeadValue, 2);
        }
        #endregion
    }
}