using Accord;
using Accord.Genetic;
using Optimization1D;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace IStation
{
public class EpanetHelper
{
EPAFunctionGUI epaFunction;
const float MAX_ENERGE = 99999999999;
///
/// err问题
///
private string ReportQuestion(int err)
{
ErrorDefine errorDefine = new ErrorDefine();
#region [秦白云飞修订]2021-4-30
//新增目的:查看报错问题
//新增
#if DEBUG
throw (new Exception(errorDefine.getErrorTxt(err)));
#endif
#endregion [秦白云飞修订]2021-4-30
return errorDefine.getErrorTxt(err);
}
#region const_mode
public const int EN_ELEVATION = 0; // { Mode parameters }
public const int EN_BASEDEMAND = 1;
public const int EN_PATTERN = 2;
public const int EN_EMITTER = 3;
public const int EN_INITQUAL = 4;
public const int EN_SOURCEQUAL = 5;
public const int EN_SOURCEPAT = 6;
public const int EN_SOURCETYPE = 7;
public const int EN_TANKLEVEL = 8;
public const int EN_DEMAND = 9;
public const int EN_HEAD = 10;
public const int EN_PRESSURE = 11;
public const int EN_QUALITY = 12;
public const int EN_SOURCEMASS = 13;
public const int EN_INITVOLUME = 14;
public const int EN_MIXMODEL = 15;
public const int EN_MIXZONEVOL = 16;
#endregion
#region type_model
enum Type_EPAObject
{
Node = 0,
Link = 1,
Pump = 2,
Tank = 3
}
#endregion
#region other
Dictionary Typelist = new Dictionary() { { ModelInput.eType.level, Type_EPAObject.Tank }, { ModelInput.eType.flow, Type_EPAObject.Node }, { ModelInput.eType.press_out, Type_EPAObject.Tank }, { ModelInput.eType.pump_run, Type_EPAObject.Pump }, { ModelInput.eType.press_in, Type_EPAObject.Tank }, { ModelInput.eType.valve_initstatus, Type_EPAObject.Link } };
List const_list_nodeType = new List { ModelOutput.eType.EN_JUNCTION, ModelOutput.eType.EN_RESERVOIR, ModelOutput.eType.EN_TANK };
List const_list_linkType = new List { ModelOutput.eType.EN_CVPIPE, ModelOutput.eType.EN_PIPE, ModelOutput.eType.EN_PUMP, ModelOutput.eType.EN_PRV, ModelOutput.eType.EN_PSV, ModelOutput.eType.EN_FCV, ModelOutput.eType.EN_TCV, ModelOutput.eType.EN_GPV };
enum Method
{
Count = 0,
Sum = 1,
Avg = 2
}
string GetTypeValue(int typeCode, int ObjType, Method method, out float Value, int valueCode = -1)
{
Value = -1;
List listValue = new List();
float result = 0;
int err = 0;
if (ObjType == 0)
{
int NLink1 = 0;
err = EpanetBase.ENgetcount(EpanetBase.Const_class.Const_Component.EN_NODECOUNT, ref NLink1);
if (err > 9) return ReportQuestion(err);
for (int i = 1; i < NLink1; i++)
{
int type = -1;
err = EpanetBase.ENgetnodetype(i, ref type);
if (err > 9) return ReportQuestion(err);
if (type == typeCode)
{
if (method == Method.Count)
result++;
else
{
float value = -1;
err = EpanetBase.ENgetnodevalue(i, valueCode, ref value);
if (err > 9) return ReportQuestion(err);
listValue.Add(value);
}
}
}
}
else
{
int NLink1 = 0; //int pump_count = 0;
err = EpanetBase.ENgetcount(EpanetBase.Const_class.Const_Component.EN_LINKCOUNT, ref NLink1);
if (err > 9) return ReportQuestion(err);
for (int i = 1; i < NLink1; i++)
{
int type = -1;
err = EpanetBase.ENgetlinktype(i, ref type);
if (err > 9) return ReportQuestion(err);
if (type == typeCode)
{
if (method == Method.Count)
result++;
else
{
float value = -1;
err = EpanetBase.ENgetlinkvalue(i, valueCode, ref value);
if (err > 9) return ReportQuestion(err);
listValue.Add(value);
}
}
}
}
if (method == Method.Sum)
{
result = 0;
for (int i = 0; i < listValue.Count; i++)
result += listValue[i];
}
else if (method == Method.Avg)
{
result = 0;
for (int i = 0; i < listValue.Count; i++)
result += listValue[i];
result /= listValue.Count;
}
Value = result;
return null;
}
string SetPumpValue(List isfreq, float value, List Combine)
{
int err = 0;
if (value != -1)
for (int i = 0; i < Combine.Count; i++)
{
if (!isfreq[i]) //工频泵
{
if (value > 0)
{
err = SetItemValue(Combine[i], 1, Type_EPAObject.Pump);
if (err > 9) return ReportQuestion(err);
return null;
}
else
{
err = SetItemValue(Combine[i], 0, Type_EPAObject.Pump);
if (err > 9) return ReportQuestion(err);
return null;
}
}
err = SetItemValue(Combine[i], value / 50.0, Type_EPAObject.Pump);
if (err > 9) return ReportQuestion(err);
}
return null;
}
string SetPumpValue(List isfreq, double[] value, List Combine)
{
int err = 0;
for (int i = 0; i < Combine.Count; i++)
{
if (!isfreq[i]) //工频泵
{
if (value[i] > 0)
{
err = SetItemValue(Combine[i], 1, Type_EPAObject.Pump);
if (err > 9) return ReportQuestion(err);
return null;
}
else
{
err = SetItemValue(Combine[i], 0, Type_EPAObject.Pump);
if (err > 9) return ReportQuestion(err);
return null;
}
}
err = SetItemValue(Combine[i], value[i] / 50.0, Type_EPAObject.Pump);
if (err > 9) return ReportQuestion(err);
}
return null;
}
int SetTypeValue(List InputData, ModelInput.eType type, float value = -1, int Num = 0)
{
int err = 0;
var InputData_type = (InputData as List).FindAll(m => (m.Type == type));
if (value == -1)
for (int i = 0; i < InputData_type.Count; i++)
{
err = SetItemValue(InputData_type[i].ObjectID, InputData_type[i].Value, Typelist[type]);
if (err > 9) return err;
}
if (value != -1)
for (int i = 1; i <= Num; i++)
{
err = SetItemValue(type + "_" + i.ToString(), value, Typelist[type]);
if (err > 9) return err;
}
return err;
}
int SetItemValue(string ID, dynamic value, Type_EPAObject type_Obj)
{
int Index = -1;
int err = 0;
switch (type_Obj)
{
case (Type_EPAObject.Tank):
err = EpanetBase.ENgetnodeindex(ID, ref Index);
err = EpanetBase.ENsetnodevalue(Index, EN_TANKLEVEL, value); //源头压力基数
break;
case (Type_EPAObject.Node):
err = EpanetBase.ENgetnodeindex(ID, ref Index);
err = EpanetBase.ENsetnodevalue(Index, EN_BASEDEMAND, value); //源头压力基数
break;
case (Type_EPAObject.Pump):
float speed = (float.Parse(value.ToString()));
if (speed < 0.1) speed = 0;
if (speed > 0)
err = EpanetBase.ENsetlinkvalue(Index, 4, 1);
else
err = EpanetBase.ENsetlinkvalue(Index, 4, 0);
//float speed = float.Parse(value.ToString());
err = EpanetBase.ENgetlinkindex(ID, ref Index);
//err = EpanetBase.ENsetlinkvalue(Index, 5, speed);
err = EpanetBase.ENsetinistatus(ID, speed.ToString());
//err = EpanetBase.ENsaveinpfile("C:\\EPA\\修改后" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".inp");
if (err > 9) return err;
break;
case (Type_EPAObject.Link):
err = EpanetBase.ENgetlinkindex(ID, ref Index);
err = EpanetBase.ENsetlinkvalue(Index, EpanetBase.Const_class.Const_Link.EN_INITSTATUS, value);
break;
default:
err = -1;
break;
}
return err;
}
///
///
///
///
public int GetOutputString(out List ListOutputNode, out List ListOutputLink)
{
int err = 0;
//string result = null;
ListOutputNode = new List();
ListOutputLink = new List();
int Njunction = 0;
err = EpanetBase.ENgetcount(EpanetBase.Const_class.Const_Component.EN_NODECOUNT, ref Njunction);
if (err > 9) return err;
int NLink = 0;
err = EpanetBase.ENgetcount(EpanetBase.Const_class.Const_Component.EN_LINKCOUNT, ref NLink);
if (err > 9) return err;
List output = new List() { Njunction, NLink };
for (int i = 1; i <= Njunction; i++)
{
ModelOutputNode mOutput = new ModelOutputNode();
StringBuilder ID = new StringBuilder();
float Value = 0; int type = -1;
err = EpanetBase.ENgetnodeid(i, ID);
if (err > 9) return err;
mOutput.ObjectID = ID.ToString();
err = EpanetBase.ENgetnodetype(i, ref type);
if (err > 9) return err;
mOutput.Type = (ModelOutputNode.eType)type;
var list_ValueIndex = mOutput.Get_list_ValueIndex();
for (int j = 0; j < list_ValueIndex.Length; j++)
{
err = EpanetBase.ENgetnodevalue(i, list_ValueIndex[j], ref Value); //源头压力基数
if (err > 9) return err;
//if (Value <= 0.0001) Value = 0;
mOutput.SetValue(j, Value);
}
ListOutputNode.Add(mOutput);
}
for (int i = 1; i <= NLink; i++)
{
ModelOutputLink mOutput = new ModelOutputLink();
StringBuilder idBuilder = new StringBuilder();
//mOutput.Value = new List();
float Value = 0; int type = -1;
err = EpanetBase.ENgetlinkid(i, idBuilder); //源头压力基数
if (err > 9) return err;
mOutput.ObjectID = idBuilder.ToString();
err = EpanetBase.ENgetlinktype(i, ref type);
if (err > 9) return err;
mOutput.Type = (ModelOutputLink.eType)(type + 10);
var list_ValueIndex = mOutput.Get_list_ValueIndex();
for (int j = 0; j < list_ValueIndex.Length; j++)
{
err = EpanetBase.ENgetlinkvalue(i, list_ValueIndex[j], ref Value); //源头压力基数
if (err > 9) return err;
//if (Value <= 0.0001) Value = 0;
mOutput.SetValue(j, Value);
}
ListOutputLink.Add(mOutput);
}
return err;
}
private string SetPumpStatus()
{
int NLink = 0; int err = 0;
err = EpanetBase.ENgetcount(EpanetBase.Const_class.Const_Component.EN_LINKCOUNT, ref NLink);
if (err > 9) return ReportQuestion(err);
for (int i = 1; i <= NLink; i++)
{
//ModelOutputLink mOutput = new ModelOutputLink();
//StringBuilder idBuilder = new StringBuilder();
////mOutput.Value = new List();
//float Value = 0;
//err = EpanetBase.ENgetlinkid(i, idBuilder); //源头压力基数
//if (err > 9) return ReportQuestion(err);
//mOutput.ObjectID = idBuilder.ToString();
int type = -1;
err = EpanetBase.ENgetlinktype(i, ref type);
if (err > 9) return ReportQuestion(err);
if (type == EpanetBase.Const_class.Const_Link_types.EN_PUMP)
{
err = EpanetBase.ENsetlinkvalue(i, EpanetBase.Const_class.Const_Link.EN_INITSTATUS, 0);
}
}
return null;
}
#endregion
private bool _isInitialSuccess = false;
///
/// 初始化
///
///
///
public string Initial(string file)
{
if (!System.IO.File.Exists(file))
return "inp 不存在";
var err = EpanetBase.ENopen(file, "0.rpt", "0.bin");
if (err == 0)
{
_isInitialSuccess = true;
return null;
}
return ReportQuestion(err);
}
public string GetResultByFlowAndPumpStatus(List InputData, out List modelOutputNodes, out List modelOutputLinks)
{
#region 初始判断
modelOutputLinks = null;
modelOutputNodes = null;
int err = 0;
//string result = null;
if (!_isInitialSuccess)
return "初始化不成功";
if (InputData == null)
return "输入参数为空";
#endregion
#region 传参计算
err = SetTypeValue(InputData, ModelInput.eType.press_in);
if (err > 9) return ReportQuestion(err);
err = SetTypeValue(InputData, ModelInput.eType.flow);
if (err > 9) return ReportQuestion(err);
err = SetTypeValue(InputData, ModelInput.eType.pump_run);
if (err > 9) return ReportQuestion(err);
err = SetTypeValue(InputData, ModelInput.eType.level);
if (err > 9) return ReportQuestion(err);
err = SetTypeValue(InputData, ModelInput.eType.valve_initstatus);
if (err > 9) return ReportQuestion(err);
err = EpanetBase.ENsolveH();
if (err > 9) return ReportQuestion(err);
#endregion
/* var path = System.IO.Directory.GetCurrentDirectory() + @"\model\out.inp";
err = EpanetBase.ENsaveinpfile(path);
if (err > 9) return ReportQuestion(err);*/
#region 返回结果
err = GetOutputString(out modelOutputNodes, out modelOutputLinks);
if (err > 9) return ReportQuestion(err);
return null;
#endregion
}
public string GetResultByPressAndPumpStatus(List InputData, out List modelOutputNodes, out List modelOutputLinks)
{
#region 初始判断
modelOutputLinks = null;
modelOutputNodes = null;
//string result = null;
int err = 0;
if (!_isInitialSuccess)
return "初始化不成功";
if (InputData == null)
return "输入参数为空";
#endregion
#region 传参计算
err = SetTypeValue(InputData, ModelInput.eType.press_in);
if (err > 9) return ReportQuestion(err);
err = SetTypeValue(InputData, ModelInput.eType.press_out);
if (err > 9) return ReportQuestion(err);
err = SetTypeValue(InputData, ModelInput.eType.pump_run);
if (err > 9) return ReportQuestion(err);
err = SetTypeValue(InputData, ModelInput.eType.level);
if (err > 9) return ReportQuestion(err);
err = SetTypeValue(InputData, ModelInput.eType.valve_initstatus);
if (err > 9) return ReportQuestion(err);
err = EpanetBase.ENsolveH();
if (err > 9) return ReportQuestion(err);
#endregion
/* var path = System.IO.Directory.GetCurrentDirectory() + @"\model\out.inp";
err = EpanetBase.ENsaveinpfile(path);
if (err > 9) return ReportQuestion(err);*/
#region 返回结果
err = GetOutputString(out modelOutputNodes, out modelOutputLinks);
if (err > 9) return ReportQuestion(err);
return null;
#endregion
}
///
/// 获取水泵转速比组合
///
///
///
///
///
///
///
///
///
///
///
///
public string GetResultByFlowAndPress(List InputData, List> List_Combine,
out List> List_modelOutputNodes, out List> List_modelOutputLinks,
out List> opt_combines, out List opt_energes, double rangeMin = 0.8, double rangeMax = 1,
int populationSize = 40, int iterations = 20, double accuracy = 0.1)
{
#region 初始判断
List_modelOutputNodes = new List>();
List_modelOutputLinks = new List>();
opt_combines = new List>();
opt_energes = new List();
string result = null;
var range = new DoubleRange(rangeMin, rangeMax);
if (!_isInitialSuccess)
return "初始化不成功";
if (InputData == null)
return "输入参数为空";
#endregion
//float min_energe = MAX_ENERGE;
for (int i = 0; i < List_Combine.Count; i++)
{
List modelOutputNodes;
List modelOutputLinks;
List opt_combine = new List();
double energe;
calcParms parms;
var dr = new DoubleRange(range.Min * 50, range.Max * 50);
result = InputInit(InputData, List_Combine[i], out parms, dr.Min, dr.Max);
if (result != null)
return result;
string result0 = _GetResultByFlowAndPress(InputData, List_Combine[i], out modelOutputNodes, out modelOutputLinks, out opt_combine, out energe, dr.Min, dr.Max, populationSize, iterations, accuracy);
List_modelOutputNodes.Add(modelOutputNodes);
List_modelOutputLinks.Add(modelOutputLinks);
for (var j = 0; j < opt_combine.Count; j++) opt_combine[j] /= 50.0;
opt_combines.Add(opt_combine);
opt_energes.Add(energe);
}
return result;
}
#region other
public void GetResult(double[] list_bestresult)
{
List nodes = null;
List links = null;
List pumpflows = null;
//double out_energe = 999999999f;
double[] li = new double[list_bestresult.Length];
for (int i = 0; i < li.Length; i++) li[i] = list_bestresult[i];
this.epaFunction.GetResult(li, out nodes, out links, out pumpflows, true);
}
private string _GetResultByFlowAndPress(List InputData, List combine, out List modelOutputNodes, out List modelOutputLinks, out List List_Hz, out double energe, double rangeMin = 0.8, double rangeMax = 1, int populationSize = 40, int iterations = 20, double accuracy = 0.1)
{
#region 初始判断
modelOutputNodes = null;
modelOutputLinks = null;
//string result = null;
//int err = 0;
List_Hz = new List();
energe = 9999999999;
#endregion
#region 初始设置
SetPumpStatus();
#endregion
var range = new DoubleRange(rangeMin, rangeMax);
SearchSolution(combine, out List_Hz, out modelOutputNodes, out modelOutputLinks, out energe, rangeMin, rangeMax, populationSize, iterations, accuracy);
return "";
}
private void SearchSolution(List combine, out List list_BestHzs, out List modelOutputNodes, out List modelOutputLinks, out double energe, double rangeMin = 0.8, double rangeMax = 1, int populationSize = 40, int iterations = 20, double accuracy = 0.1)
{
var list_BestEnerge = new List();
list_BestHzs = new List();
var list_AvgHz = new List();
modelOutputNodes = null;
modelOutputLinks = null;
energe = 999999999f;
var range = new DoubleRange(rangeMin, rangeMax);
var num_Total = range.Length / accuracy;
var LENGTH_PUMP = 0;
var value_LENGTH_PUMP = 1;
var i = 0;
while (value_LENGTH_PUMP < num_Total && i < 1000)
{
value_LENGTH_PUMP *= 2;
LENGTH_PUMP += 1;
i++;
}
var chromosomeLength = combine.Count * LENGTH_PUMP;
BinaryChromosome ancestor = new BinaryChromosome(chromosomeLength);
EPAFunctionGUI fitnessFunction = this.epaFunction;
var IntselectionMethod = 0;
object obj;
if (IntselectionMethod != 0)
{
if (IntselectionMethod != 1)
{
ISelectionMethod selectionMethod = new RouletteWheelSelection();
obj = selectionMethod;
}
else
{
obj = new RankSelection();
}
}
else
{
obj = new EliteSelection();
}
var optimizationMode = 1;
epaFunction.Mode = ((optimizationMode != 0) ? OptimizationFunctionXD.Modes.Minimization : OptimizationFunctionXD.Modes.Maximization);
Population population = new Population(populationSize, ancestor, fitnessFunction, (ISelectionMethod)obj);
int num = 1;
//double[,] array = new double[showOnlyBest ? 1 : populationSize, 2];
List list_result = new List();
//float[,] array = new double[showOnlyBest ? 1 : populationSize,combine.Count+1];
bool needToStop = false;
bool showOnlyBest = true;
while (!needToStop)
{
population.RunEpoch();
list_result.Clear();
if (showOnlyBest)
{
list_result.Add(new ResultCombine());
list_result[0].arrayHz = epaFunction.Translate(population.BestChromosome);
list_result[0].totalEnerge = epaFunction.OptimizationFunction(list_result[0].arrayHz);
Console.WriteLine($"迭代次数{num},总能耗{list_result[0].totalEnerge}");
}
else
{
for (int j = 0; j < populationSize; j++)
{
list_result.Add(new ResultCombine());
list_result[j].arrayHz = epaFunction.Translate(population[j]);
list_result[j].totalEnerge = epaFunction.OptimizationFunction(list_result[j].arrayHz);
}
}
//chart.UpdateDataSeries("avg", array);
//SetText(currentIterationBox, num.ToString());
double[] list_bestresult = (epaFunction.Translate(population.BestChromosome));
double bestEnerge = epaFunction.OptimizationFunction(list_bestresult);
//SetText(currentValueBox, bestEnerge.ToString());
List pumpflows = null;
this.epaFunction.GetResult(list_bestresult, out modelOutputNodes, out modelOutputLinks, out pumpflows, false);
double sum = 0;
energe = bestEnerge;
sum /= list_bestresult.Length;
list_BestEnerge.Add(bestEnerge);
list_AvgHz.Add(sum);
list_BestHzs = list_bestresult.ToList();
num++;
if (iterations != 0 && num > iterations)
{
break;
}
}
}
public string InputInit(List InputData, List combine, out calcParms parms, double rangeMin = 0.8, double rangeMax = 1)
{
string result = null;
#region 初始判断
parms = null;
//string result = null;
int err = 0;
var doubleRange = new DoubleRange(rangeMin, rangeMax);
#endregion
err = SetTypeValue(InputData, ModelInput.eType.press_in);
if (err > 9) return ReportQuestion(err);
err = SetTypeValue(InputData, ModelInput.eType.flow);
if (err > 9) return ReportQuestion(err);
err = SetTypeValue(InputData, ModelInput.eType.level);
if (err > 9) return ReportQuestion(err);
err = SetTypeValue(InputData, ModelInput.eType.valve_initstatus);
if (err > 9) return ReportQuestion(err);
List list_isfrequence = new List();
combine.ForEach(ID => { bool isFre = InputData.Find(data => data.ObjectID == ID).Value == 1; list_isfrequence.Add(isFre); });
var pressOutPoit = InputData.FindAll((m) => m.Type == ModelInput.eType.press_out).Select(p => (double)p.Value).ToList();
var flowPointID = InputData.FindAll((m) => m.Type == ModelInput.eType.flow).Select(f => f.ObjectID).ToList();
List flowPointIndex = new List();
flowPointID.ForEach(FID =>
{
if (result != null) return;
int index = -1;
err = EpanetBase.ENgetnodeindex(FID, ref index);
flowPointIndex.Add(index);
if (err > 9) result = ReportQuestion(err);
});
if (result != null) return result;
parms = new calcParms
{
list_isfrequence = list_isfrequence,
flowPointIndex = flowPointIndex,
demandPress = pressOutPoit
};
#region 计算单泵的长度
var range = doubleRange;
double accuracy = 0.1;
var num_Total = range.Length / accuracy;
var LENGTH_PUMP = 0;
var value_LENGTH_PUMP = 1;
var i = 0;
while (value_LENGTH_PUMP < num_Total && i < 1000)
{
value_LENGTH_PUMP *= 2;
LENGTH_PUMP += 1;
i++;
}
#endregion
List drs = new List();
combine.ForEach(m => { drs.Add(range); });
epaFunction = new EPAFunctionGUI(drs.ToArray(), LENGTH_PUMP, parms, this, combine);
return null;
}
float accur = 0.1f;
//
/// 二分查找
///
///
/// 开始索引 0
/// 结束索引
/// 要查找的对象
///
private float BinarySearch(List combine, List list_isfrequence, int flowPointIndex, float lowHz, float highHz, float pressure)
{
string result = null;
float mid = (lowHz + highHz) / 2;
if (lowHz > highHz)
return -1;
else
{
if (highHz - lowHz <= accur)
{
return mid;
}
}
float press_out;
float energe;
result = getPressByPumps(combine, list_isfrequence, mid, flowPointIndex, out press_out, out energe);
if (result != null) return -1;
if (press_out > pressure)
return BinarySearch(combine, list_isfrequence, flowPointIndex, lowHz, mid, pressure);
else
return BinarySearch(combine, list_isfrequence, flowPointIndex, mid, highHz, pressure);
}
private string getPressByPumps(List combine, List isfrequence, float Hz, int flowPointIndex, out float press, out float energe)
{
int err = 0;
#region 初始判断
press = 0;
energe = 99999999f;
string result = null;
#endregion
var PressNodeID = -1;
result = SetPumpValue(isfrequence, 0, combine);
if (result != null) return result;
result = SetPumpValue(isfrequence, ((float)Hz), combine);
if (result != null) return result;
//err = EpanetBase.ENsaveinpfile(@"D:\Desktop\C程序设计\项目源码\水力建模\eptools\out.inp");
float PressValue = -1;
int t = 0;
//err = EpanetBase.ENinitH(0);
//err = EpanetBase.ENrunH(ref t);
err = EpanetBase.ENsolveH();
if (err > 9) return ReportQuestion(err);
err = EpanetBase.ENgetnodevalue(flowPointIndex, EpanetBase.Const_class.Const_Node.EN_HEAD, ref PressValue);
if (err > 9) return ReportQuestion(err);
press = PressValue;
float TotalEnerge = 9999999999f;
result = GetTypeValue(EpanetBase.Const_class.Const_Link_types.EN_PUMP, 1, Method.Sum, out TotalEnerge, EpanetBase.Const_class.Const_Link.EN_ENERGY);
if (result != null) return result;
energe = TotalEnerge;
return result;
}
public string getPressByPumps(List combine, List isfrequence, double[] list_Hz, List flowPointIndex, out List press, out double energe, out List modelOutputNodes, out List modelOutputLinks, out List pumpflows, bool isNeedOutput = false, string path = null)
{
int err = 0;
#region 初始判断
modelOutputNodes = null;
modelOutputLinks = null;
pumpflows = null;
press = new List();
energe = 99999999f;
string result = null;
#endregion
var PressNodeID = -1;
result = SetPumpValue(isfrequence, 0, combine);
if (result != null) return result;
result = SetPumpValue(isfrequence, list_Hz, combine);
if (result != null) return result;
//err = EpanetBase.ENsaveinpfile(@"D:\Desktop\C程序设计\项目源码\水力建模\eptools\out.inp");
List PressValue = new List();
int t = 0;
//err = EpanetBase.ENinitH(0);
//err = EpanetBase.ENrunH(ref t);
//path = @"D:\Desktop\C程序设计\项目源码\水力建模\eptools_v2\Debug\model\out.inp";
//EpanetBase.ENsaveinpfile(path);
err = EpanetBase.ENsolveH();
if (err > 9) return ReportQuestion(err);
if (result != null) return result;
var press0 = new List();
flowPointIndex.ForEach(FIndex =>
{
if (result != null) return;
float PressValue0 = -1;
err = EpanetBase.ENgetnodevalue(FIndex, EpanetBase.Const_class.Const_Node.EN_HEAD, ref PressValue0);
press0.Add(PressValue0);
if (err > 9) result = ReportQuestion(err);
});
press = press0;
float TotalEnerge = 9999999999f;
result = GetTypeValue(EpanetBase.Const_class.Const_Link_types.EN_PUMP, 1, Method.Sum, out TotalEnerge, EpanetBase.Const_class.Const_Link.EN_ENERGY);
if (result != null) return result;
bool isCannotDeliver = false;
combine.ForEach(pump_id =>
{
if (isCannotDeliver) return;
int pumpindex = -1;
if ((err = EpanetBase.ENgetlinkindex(pump_id, ref pumpindex)) > 9) { result = ReportQuestion(err); return; }
float pumpstatus = -1;
if ((err = EpanetBase.ENgetlinkvalue(pumpindex, EpanetBase.Const_class.Const_Link.EN_STATUS, ref pumpstatus)) > 9) { result = ReportQuestion(err); return; }
float pumpFlow = -1;
err = EpanetBase.ENgetlinkvalue(pumpindex, EpanetBase.Const_class.Const_Link.EN_FLOW, ref pumpFlow);
if (pumpstatus == 0 || pumpFlow <= 50) isCannotDeliver = true;
});
if (isCannotDeliver) return null;
energe = TotalEnerge;
if (isNeedOutput)
{
var pf = new List();
combine.ForEach(pump_id =>
{
int pumpindex = -1;
err = EpanetBase.ENgetlinkindex(pump_id, ref pumpindex); if (err > 9) ;
float pumpFlow = -1;
err = EpanetBase.ENgetlinkvalue(pumpindex, EpanetBase.Const_class.Const_Link.EN_FLOW, ref pumpFlow);
pf.Add(pumpFlow);
});
pumpflows = pf;
EpanetBase.ENsaveinpfile(path);
GetOutputString(out modelOutputNodes, out modelOutputLinks);
}
return result;
}
public string GetPumpList(out List pumps)
{
#region 初始判断
//modelOutputLinks = null;
//modelOutputNodes = null;
string result = null;
int err = 0;
pumps = new List();
if (!_isInitialSuccess)
return "初始化不成功";
//if (InputData == null)
// return "输入参数为空";
#endregion
#region 获取
int NLink1 = 0;
err = EpanetBase.ENgetcount(EpanetBase.Const_class.Const_Component.EN_NODECOUNT, ref NLink1);
if (err > 9) return ReportQuestion(err);
for (int i = 1; i <= NLink1; i++)
{
int type = -1;
err = EpanetBase.ENgetnodetype(i, ref type);
if (err > 9) return ReportQuestion(err);
if (type == EpanetBase.Const_class.Const_Link_types.EN_PUMP)
{
Pump pump = new Pump();
err = EpanetBase.ENgetlinkvalue(i, EpanetBase.Const_class.Const_Link.EN_STATUS, ref pump.value);
if (err > 9) return ReportQuestion(err);
StringBuilder s = new StringBuilder();
err = EpanetBase.ENgetlinkid(i, s);
pump.ID = s.ToString();
if (err > 9) return ReportQuestion(err);
pump.index = i;
pumps.Add(pump);
}
}
return null;
#endregion
}
}
public class Pump
{
public string ID = null;
public int index;
public float value;
}
public class calcParms
{
public List list_isfrequence = null;
public List flowPointIndex = null;
public List demandPress = null;
}
public class ResultCombine
{
public double[] arrayHz ;
public double totalEnerge;
}
#endregion
}