using System.Text;
|
|
namespace Yw.EPAnet
|
{
|
/// <summary>
|
/// 管网计算拓展
|
/// </summary>
|
public static class NetworkCalcuExtensions
|
{
|
/// <summary>
|
/// 简单计算
|
/// </summary>
|
public static CalcuResult CalcuSimple(this Network network)
|
{
|
var result = new CalcuResult();
|
|
//Null验证
|
if (network == null)
|
{
|
result.Succeed = false;
|
return result;
|
}
|
|
var linkdict = network.GetAllLinks().ToDictionary(p => p.Id);
|
var nodedict = network.GetAllNodes().ToDictionary(p => p.Id);
|
|
//获取系统临时文件目录,创建inp临时文件
|
var inpFilePath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N") + ".inp");
|
//inp文本写入
|
var inpString = network.ToInpString();
|
File.WriteAllText(inpFilePath, inpString);
|
|
//加载管网
|
var epanet = new HydraulicCore(true);
|
var errOpen = epanet.open(inpFilePath, "", "");
|
if (errOpen != 0)
|
{
|
string errorMsg = epanet.geterrormsg();
|
result.Succeed = false;
|
result.FailedList.Add(new CalcuFailed()
|
{
|
Code = errOpen,
|
Message = $"{errorMsg}"
|
});
|
return result;
|
}
|
|
//水力计算
|
var errCalcu = epanet.solveH();
|
if (errCalcu != 0)
|
{
|
string errorMsg = epanet.geterrormsg();
|
result.Succeed = false;
|
result.FailedList.Add(new CalcuFailed()
|
{
|
Code = errCalcu,
|
Message = $"{errorMsg}"
|
});
|
return result;
|
}
|
|
int nodeCount = 0;
|
int linkCount = 0;
|
epanet.getcount((int)eCountType.Node, ref nodeCount);
|
epanet.getcount((int)eCountType.Link, ref linkCount);
|
|
const int MAXID = 31;
|
|
var sb = new StringBuilder(MAXID);
|
|
for (int i = 1; i <= nodeCount; i++)
|
{
|
epanet.getnodeid(i, sb);
|
var arr = new string[] { "Head", "Press", "Demand" }; //System.Enum.GetValues(typeof(HydraulicModel.NodeValueType));
|
var arrnum = new int[] { 10, 11, 9 };
|
var calcuNode = new CalcuNode()
|
{
|
Id = sb.ToString(),
|
};
|
for (var j = 0; j < arr.Length; j++)
|
{
|
float v = 0;
|
//var t = (EPAcore.Core.NodeValueType)j;
|
epanet.getnodevalue(i, arrnum[j], ref v);
|
switch (arr[j])
|
{
|
case "Head":
|
calcuNode.Head = v;
|
break;
|
case "Press":
|
calcuNode.Press = v;
|
break;
|
case "Demand":
|
calcuNode.Demand = v;
|
break;
|
}
|
}
|
result.NodeList.Add(calcuNode);
|
}
|
var nodeResultDict = result.NodeList.ToDictionary(p => p.Id);
|
for (int i = 1; i <= linkCount; i++)
|
{
|
epanet.getlinkid(i, sb);
|
//var arr = System.Enum.GetValues(typeof(HydraulicModel.LinkValueType));
|
var arr = new string[] { "Flow", "Velocity", "Headloss" }; //System.Enum.GetValues(typeof(HydraulicModel.NodeValueType));
|
var arrnum = new int[] { 8, 9, 10 };
|
var calcuLink = new CalcuLink()
|
{
|
Id = sb.ToString(),
|
};
|
for (var j = 0; j < arr.Length; j++)
|
{
|
float v = 0;
|
//var t = (EPAcore.Core.NodeValueType)j;
|
epanet.getlinkvalue(i, arrnum[j], ref v);
|
switch (arr[j])
|
{
|
case "Flow":
|
calcuLink.Flow = v;
|
break;
|
case "Velocity":
|
calcuLink.Velocity = v;
|
break;
|
case "Headloss":
|
calcuLink.HeadLoss = v;
|
break;
|
|
}
|
if (linkdict[calcuLink.Id] is Pipe p)
|
{
|
double minorloss1 = p.StartMinorloss * Math.Pow(calcuLink.Velocity, 2) / 2 / 9.81;
|
double minorloss2 = p.EndMinorloss * Math.Pow(calcuLink.Velocity, 2) / 2 / 9.81;
|
double minorloss = p.MinorLoss * Math.Pow(calcuLink.Velocity, 2) / 2 / 9.81;
|
calcuLink.HeadLoss -= minorloss1 + minorloss2;
|
calcuLink.MinorLoss = minorloss;
|
calcuLink.FrictionLoss = calcuLink.HeadLoss - minorloss;
|
//if (nodedict[p.StartNode.Id] is Elbow)
|
{
|
nodeResultDict[p.StartNode.Id].MinorLoss += minorloss1;
|
}
|
//if (nodedict[p.EndNode.Id] is Elbow)
|
{
|
nodeResultDict[p.EndNode.Id].MinorLoss += minorloss2;
|
}
|
|
}
|
}
|
result.LinkList.Add(calcuLink);
|
}
|
|
return result;
|
}
|
|
/// <summary>
|
/// 计算局阻系数
|
/// network中的局部损失会被修改
|
/// </summary>
|
public static CalcuResult CalcuMinorLoss(this Network network)
|
{
|
var calcuResult = network.CalcuSimple();
|
if (!calcuResult.Succeed)
|
{
|
return calcuResult;
|
}
|
|
var allCalcuLinks = calcuResult.LinkList;
|
var allNodeList = network.GetAllNodes();
|
var allLinkList = network.GetAllLinks();
|
foreach (var link in allLinkList)
|
{
|
if (link is Pipe p)
|
{
|
p.StartMinorloss = 0;
|
p.EndMinorloss = 0;
|
}
|
}
|
foreach (var node in allNodeList)
|
{
|
var prevLinks = node.GetPrevLinks(allCalcuLinks);
|
if (prevLinks == null || prevLinks.Count < 1)
|
{
|
continue;
|
}
|
var nextLinks = node.GetNextLinks(allCalcuLinks);
|
if (nextLinks == null || nextLinks.Count < 1)
|
{
|
continue;
|
}
|
if (node is Elbow elbow)
|
{
|
//弯头
|
if (!elbow.MinorLoss.HasValue)
|
{
|
continue;
|
}
|
if (prevLinks.Count != 1)
|
{
|
continue;
|
}
|
var prevLink = prevLinks[0] as Pipe;
|
if (prevLink != null)
|
{
|
prevLink.EndMinorloss = elbow.MinorLoss.Value / 2f;
|
}
|
if (nextLinks.Count != 1)
|
{
|
continue;
|
}
|
var nextLink = nextLinks[0] as Pipe;
|
if (nextLink != null)
|
{
|
nextLink.StartMinorloss = elbow.MinorLoss.Value / 2f;
|
}
|
}
|
else if (node is Threelink threelink)
|
{
|
//三通
|
var linkCount = prevLinks.Count + nextLinks.Count;
|
if (linkCount != 3)
|
{
|
continue;
|
}
|
Link mainLink = null;//主管
|
List<Link> branchLinks = null;//支管列表
|
bool isNext = prevLinks.Count == 1;
|
if (isNext)//1进2出
|
{
|
mainLink = prevLinks[0];
|
branchLinks = nextLinks;
|
}
|
else//2进1出
|
{
|
mainLink = nextLinks[0];
|
branchLinks = prevLinks;
|
}
|
var mainPipe = mainLink as Pipe;
|
if (mainPipe == null)
|
{
|
continue;
|
}
|
foreach (var branchLink in branchLinks)
|
{
|
var branchPipe = branchLink as Pipe;
|
if (branchPipe == null)
|
{
|
continue;
|
}
|
if (branchPipe.Diameter == mainPipe.Diameter)
|
{
|
var minorLoss = threelink.RunningThroughLoss;
|
if (!minorLoss.HasValue)
|
{
|
minorLoss = threelink.MinorLoss;
|
if (minorLoss.HasValue)
|
{
|
if (isNext)
|
branchPipe.StartMinorloss = minorLoss.Value;
|
else
|
branchPipe.EndMinorloss = minorLoss.Value;
|
}
|
}
|
}
|
else
|
{
|
var minorLoss = threelink.BranchThroughLoss;
|
if (!minorLoss.HasValue)
|
{
|
minorLoss = threelink.MinorLoss;
|
if (minorLoss.HasValue)
|
{
|
if (isNext)
|
branchPipe.StartMinorloss = minorLoss.Value;
|
else
|
branchPipe.EndMinorloss = minorLoss.Value;
|
|
}
|
}
|
}
|
}
|
|
}
|
else if (node is Fourlink fourlink)
|
{
|
//四通
|
if (!fourlink.MinorLoss.HasValue)
|
{
|
continue;
|
}
|
var linkCount = prevLinks.Count + nextLinks.Count;
|
if (linkCount != 4)
|
{
|
continue;
|
}
|
|
bool isNext = prevLinks.Count < nextLinks.Count;
|
|
var branchLinks = isNext ? nextLinks : prevLinks;
|
foreach (var branchLink in branchLinks)
|
{
|
var pipe = branchLink as Pipe;
|
if (pipe != null)
|
{
|
if (isNext)
|
{
|
pipe.StartMinorloss = fourlink.MinorLoss.Value;
|
}
|
else
|
{
|
pipe.EndMinorloss = fourlink.MinorLoss.Value;
|
}
|
|
}
|
}
|
}
|
}
|
|
calcuResult = network.CalcuSimple();
|
return calcuResult;
|
}
|
|
/// <summary>
|
/// 计算
|
/// </summary>
|
public static CalcuResult Calcu(this Network network, string calcuMode)
|
{
|
CalcuResult result = null;
|
switch (calcuMode)
|
{
|
case CalcuMode.Simple:
|
{
|
result = network.CalcuSimple();
|
}
|
break;
|
case CalcuMode.MinorLoss:
|
{
|
result = network.CalcuMinorLoss();
|
}
|
break;
|
default:
|
{
|
result = network.CalcuSimple();
|
}
|
break;
|
}
|
return result;
|
}
|
|
|
|
|
}
|
}
|