using Hydro.CodeProvider;
using Hydro.CommonBase;
using Hydro.ConfigModel;
using Hydro.HydraulicModel;
using Hydro.ParrelControl;
using Hydro.ParrelControl;
using SolutionDBHelper_NS;
using System;
using System.CodeDom;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;
//using WaterDistributioinManager;
using Hydro.ConfigModel;
using static System.Net.Mime.MediaTypeNames;
namespace Hydro.HydraulicHelperNS
{
public partial class HydraulicHelper
{
#region 构造、析构
public HydraulicHelper()
{
//return ReportQuestion(err);
}
public string Init(HydraulicCore epanet, string file,int projectID, LogicModelParams param,GeneticParams gParam,WdnmoParam wParam, bool isEPAOpenH = true, bool isPrim=true, EPAParrelController Controller=null)
{
string result = null;
this.epanet = epanet;
this.projectID = projectID;
this.gParam= gParam;
this.param = param;
// var file = System.IO.Directory.GetCurrentDirectory() + "\\inpFile\\pump.inp";
// "inp 不存在";
int err = 0;
if (gParam.GlobalConfig.Ext.isWaterModelCalc)
{
if (!System.IO.File.Exists(file))
{
return "inp 不存在";
}
err = epanet.open(file, "", "");
Log.Add($"[{gParam.GlobalConfig.ModelObjectID}] 开始open文件{isPrim}", "初始化");
//if (err != 0 && new System.IO.FileInfo(file).Length<=10)
//{
// 预处理(file);
// err = epanet.open(file, "", "");
//}
if (err > 9) return "加载模型失败" + ReportQuestion(err);
}
if (isPrim)
{
result = Init_Time();
if (result != null) return result;
}
isInited = true;
if (gParam.GlobalConfig.Ext.isWaterModelCalc && isEPAOpenH)
{
//设置不产生报告
Log.Add($"[{gParam.GlobalConfig.ModelObjectID}] 完成open文件{isPrim}", "初始化");
Log.Add($"[{gParam.GlobalConfig.ModelObjectID}] 开始openH文件{isPrim}", "初始化");
err = epanet.openH();
if (err != 0) return "初始化失败\r\n"+ReportQuestion(err);
}
isOpenH = true;
//err = epanet.initH( 0);
Log.Add($"[{gParam.GlobalConfig.ModelObjectID}] 完成openH文件{isPrim}", "初始化");
if (isPrim)
{
this.param = param;
}
else
{
Log.Add($"[{gParam.GlobalConfig.ModelObjectID}] 开始Clone参数{isPrim}", "初始化");
this.param = CloneModelParams(param);
Log.Add($"[{gParam.GlobalConfig.ModelObjectID}] 完成Clone参数{isPrim}", "初始化");
this.gParam = gParam.DeepCopy();
}
this.gParam = gParam;
this.Controller = Controller;
return null;
}
public string Init_Time()
{
int EN_Duration = 0;
int EN_Step = 0;
int err = 0;
if (gParam.GlobalConfig.Ext.isWaterModelCalc )
{
err = epanet.gettimeparam(HydraulicCore.Const_class.Const_Time.EN_DURATION, ref EN_Duration);//获取模拟总时长(秒)
if (err > 9) return ReportQuestion(err);
err = epanet.gettimeparam(HydraulicCore.Const_class.Const_Time.EN_HYDSTEP, ref EN_Step);//获取水力计算的步长(秒)
if (err > 9) return ReportQuestion(err);
int period_Count = 0;//(总时刻数)
int EN_CurrentStep = 0;//当前的时间(秒)
while (EN_CurrentStep <= EN_Duration)
{
period_Count += 1;
EN_CurrentStep += EN_Step;
}
gParam.GlobalConfig.Ext.TimeStep = EN_Step / 60;
gParam.GlobalConfig.Ext.TimeDuration = EN_Duration / 60;
gParam.GlobalConfig.Ext.EPAPeriodCount = period_Count;
if (gParam.GlobalConfig.Ext.MultiTimes>=0)
gParam.GlobalConfig.Ext.PeriodCount = 1;
else
gParam.GlobalConfig.Ext.PeriodCount = period_Count;
}
param.时间刻度 = new EN_Times();
param.时间刻度.step = gParam.GlobalConfig.Ext.TimeStep;
param.时间刻度.duration = gParam.GlobalConfig.Ext.TimeDuration;
param.时间刻度.Ntimes = gParam.GlobalConfig.Ext.PeriodCount;
param.变量全集.ForEach(v => v.PeriodCount= gParam.GlobalConfig.Ext.PeriodCount);
return null;
}
///
/// 将param深度复制一份;
///
///
///
public static LogicModelParams CloneModelParams(LogicModelParams param)
{
//BookMark :多线程克隆
var param_new = new LogicModelParams();
{
param_new.map_node=param.map_node;
param_new.map_link=param.map_link;
//2023年5月15日
//是否要深度拷贝,取决于是否需要存储不一样的计算结果
//加入了子方案之后,每个量取值的变量可能都需要进行深度拷贝
param_new.初始条件 = new List(param.初始条件);
param_new.下阶段条件 = new List(param.下阶段条件);
param_new.约束变量 = new List(param.约束变量);
#region [秦白云飞修订] 2023年2月15日 19:28:37
param_new.试算变量 = param.试算变量.DeepCopyByBinVariable();
param_new.试算变量.ForEach(vv => vv.Vars = param.dict_ID[vv.ID].Vars);
//试算变量 = param.试算变量.DeepCopyByBinVariable();
param_new.水量分配变量 = param.水量分配变量.DeepCopyByBinVariable();
param_new.水量分配变量.ForEach(vv => vv.Vars = param.dict_ID[vv.ID].Vars);
//param_new.水量分配集合 = param.水量分配集合.DeepCopyByBinVariable();
#endregion [秦白云飞修订] 2023年2月15日 19:28:37
param_new.变量 = param.变量.DeepCopyByBinVariable();// DeepCopyByBin>();
param_new.变量.ForEach(vv => vv.Vars = param.dict_ID[vv.ID].Vars);
param_new.集合 = param.集合.DeepCopyByBinVariable();
param_new.集合.ForEach(vv => vv.Vars = param.dict_ID[vv.ID].Vars);
param_new.表达式 = param.表达式.DeepCopyByBinVariable();
param_new.预处理插件 = param.预处理插件.DeepCopyByBinVariable();// new List(param.预处理插件);
#if DEBUG
//if (result!=null) throw new Exception(result);
#endif
/*[Cloudflight修改]2024-6-19
* //result = HydraulicHelper.CreatePreToolAssembly(param_new, param_new.预处理插件);
*/
#if DEBUG
//if (result != null) throw new Exception(result);
#endif
//for (int i = 0; i < param_new.表达式.Count; i++)
//{
//var exp_new = param_new.表达式[i];
//var exp = param.表达式[i];
//exp.Vars.ForEach(vv =>
//{
// if (vv is variable vvar)
// exp_new.Vars.Add(param_new.dict_ID[vvar.ID]);
//});
//exp_new.VarIndexs = exp.VarIndexs;
//exp.PatternVars.ForEach(vv =>
//{
// exp_new.PatternVars.Add(param_new.dict_ID[vv.ID]);
//});
//exp_new.Eval = exp.Eval;
//}
if (param.OFunction != null)
{
var o = param.OFunction;
var v = o.variable;
param_new.OFunction = new OBJFunction()
{
Text_origin = o.Text_origin,
Text = o.Text,
Name = o.Name,
ExpressType = o.ExpressType,
tolerance = o.tolerance,
isUseExpression = o.isUseExpression,
isUseOriginValue = o.isUseOriginValue,
};
param_new.OFunction.variable = param_new.表达式.Find(vv => vv.ID == v.ID);
}
if (param.ChildParam != null)
{
param_new.ChildParam = new Dictionary();
foreach (var kp in param.ChildParam)
{
string childName = kp.Key;
string childSaveName = kp.Value.childSaveName;
param_new.ChildParam.Add(childName, new childSolutionParam());
var cpNew = param_new.ChildParam[childName];
var cp = kp.Value;
////[Cloudflight修改]2023-12-29
//cpNew.wParam = cp.wParam.DeepCopyByBin();
cpNew.wParam = cp.wParam.Copy();
cpNew.childSaveName = cp.childSaveName;
var list = param_new.变量全集.FindAll(vv => vv.childSolution != "");
var l1 = list.FindAll(vv => vv.childSolution == childSaveName && vv.childType == "传入");
var l2 = list.FindAll(vv => vv.childSolution == childSaveName && vv.childType == "返回");
cpNew.childFitness_Out = (l2.FindAll(vv => vv.childTag.ToLower() == "fitness")[0]);
cpNew.childVars_In = l1;
cpNew.childVars_Out = l2;
}
}
param_new.buildDict();
string result = HydraulicHelper.CreateExpressAssembly(param_new);
}
return param_new;
}
private GeneticParams CloneGeneticParams(GeneticParams gParam)
{
//将gParam深度复制一份;
//var gParam_new = new GeneticParams(gParam.Level);
//gParam_new.GlobalConfig = gParam.GlobalConfig.DeepCopyByBin();
//gParam_new.Db= gParam.Db;
//gParam_new.ranges = new List(gParam.ranges.ToArray());
//gParam_new.accuracyNum = gParam.accuracyNum;
//gParam_new.accuracys = new List(gParam.accuracys.ToArray());
var gParam_new = gParam.DeepCopyByBin();
return gParam_new;
}
///
/// 将param深度复制一份;
///
///
///
private string CopyValueParams(LogicModelParams param_new, LogicModelParams param)
{
string result = null;
//2023年5月15日
//是否要深度拷贝,取决于是否需要存储不一样的计算结果
//加入了子方案之后,每个量取值的变量可能都需要进行深度拷贝
var list1 = param_new.变量全集;
list1.Sort((a, b) => a.ID > b.ID ? 1 : (a.ID==b.ID?0:-1));
var list2 = param.变量全集;
list2.Sort((a, b) => a.ID > b.ID ? 1 : (a.ID == b.ID ? 0 : -1));
int j = 0;
for (int i = 0; i < list1.Count; i++)
{
if (variable.list_接口输入值.IndexOf(list1[i].expressType) < 0) continue;
while (j < list2.Count && list1[i].ID != list2[j].ID) j++;
if (j >= list2.Count) return $"参数错误[{list1[i].Name}]";
list1[i].LogicValue = list2[j].LogicValue;
list1[i].LogicValues = list2[j].LogicValues;
}
return null;
}
public string CopyValueby(HydraulicHelper hel)
{
return CopyValueParams(this.param, hel.param);
}
/////
///// 从集合变量中生成虚拟变量
/////
/////
/////
//private void SetVarByVset(variable v, variable source)
//{
// v.ID = source.ID;
// v.IndicatorType = source.IndicatorType;
// v.Type = source.Type;
// v.expressType = source.expressType;
// v.expressString = source.expressString;
// v.arrgFuncType = source.arrgFuncType;
// v.isNode = source.isNode;
// v.ObjType = source.ObjType;
// v.logicType = source.logicType;
// v.小数位数 = source.小数位数;
// v.virturl = true;
// v.doubleRange = source.doubleRange;
// v.accuracy = source.accuracy;
//}
///
/// 从集合变量中生成虚拟变量
///
///
///
private void SetVarOutputByVset(variable v, variable source)
{
v.ID = source.ID;
v.IndicatorType = source.IndicatorType;
v.Type = source.Type;
v.expressType = source.expressType;
v.Name= v.expressString = source.expressString+"_"+v.modelObjectID;
v.arrgFuncType = source.arrgFuncType;
v.isNode = source.isNode;
v.ObjType = source.ObjType;
v.logicType = source.logicType;
v.小数位数 = source.小数位数;
v.virturl = true;
v.doubleRange = source.doubleRange;
v.accuracy = source.accuracy;
}
private void 预处理(string file)
{
System.IO.StreamReader sr = new System.IO.StreamReader(file);
Regex r = new Regex(@"CLOSE(?!D)");
Regex r_乱码 = new Regex(@"[^ -~\u2E80-\u2FDF\u3040-\u318F\u31A0-\u31BF\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FFF\uA960-\uA97F\uAC00-\uD7FF\u3002\u00a5\uff1f\uff01\uff0c\u3001\uff1b\uff1a\u201c\u201d\u2018\u2019\uff08\uff09\u300a\u300b\u3008\u3009\u3010\u3011\u300e\u300f\u300c\u300d\ufe43\ufe44\u3014\u3015\u2026\u2014\uff5e\ufe4f\uffe5]+.*");
string line = null;
StringBuilder s =new StringBuilder("");
while ((line = sr.ReadLine()) != null)
{
if (r.Match(line).Success)
{
line = r.Replace(line, "CLOSED");
}
//if (r_乱码.Match(line).Success)
//{
// line = r_乱码.Replace(line,"");
//}
s.AppendLine( line);
}
sr.Close();
System.IO.StreamWriter sw = new System.IO.StreamWriter(file);
sw.Write(s.ToString());
sw.Close();
}
public string AddNode(string id, double elevation, double[] coordinate, double baseDemand = 0, int demandModeIndex = -1)
{
int index = -1;
var err = epanet.addnode(id, HydraulicCore.Const_class.Const_Node_Type.EN_JUNCTION, ref index);
if (err != 0) return ReportQuestion(err) + "\r\n" + $"添加节点{id}失败";
err = epanet.setnodevalue(index, HydraulicCore.Const_class.Const_Node.EN_ELEVATION, (float)elevation);
if (err != 0) return ReportQuestion(err) + "\r\n" + $"设置节点{id}标高失败";
err = epanet.setcoord(index, coordinate[0], coordinate[1]);
if (err != 0) return ReportQuestion(err) + "\r\n" + $"设置节点{id}坐标失败";
err = epanet.setnodevalue(index, HydraulicCore.Const_class.Const_Node.EN_BASEDEMAND, (float)baseDemand);
if (err != 0) return ReportQuestion(err) + "\r\n" + $"设置节点{id}基准水量失败";
if (demandModeIndex >= 0)
{
err = epanet.setnodevalue(index, HydraulicCore.Const_class.Const_Node.EN_PATTERN, demandModeIndex);
if (err != 0) return ReportQuestion(err) + "\r\n" + $"设置节点{id}用水模式失败";
}
return null;
}
public string AddLink(string id, string fromNode, string toNode, double diameter)
{
int index = -1;
var err = epanet.addlink(id, HydraulicCore.Const_class.Const_Link_types.EN_PIPE, fromNode, toNode, ref index);
if (err != 0) return ReportQuestion(err) + "\r\n" + $"添加管线{id}失败";
err = epanet.setlinkvalue(index, HydraulicCore.Const_class.Const_Link.EN_DIAMETER, (float)diameter);
if (err != 0) return ReportQuestion(err) + "\r\n" + $"设置管线{id}管径失败";
return null;
}
public double GetNodeValue(string id, int mode)
{
int index = -1;
float result = 0;
//var err = epanet.getnodeindex(id, ref index);
//if (err != 0) return -99999999;
index = (int)param.map_node[id]["index"];
int err = epanet.getnodevalue(index, mode, ref result);
if (err != 0) return -99999999;
return (double)result;
}
private string 预处理集合变量()
{
string result = null;
int err = 0;
return result;
}
public string SaveInp(string path)
{
int index = -1;
float result = 0;
var err = epanet.saveinpfile(path);
if (err != 0) return ReportQuestion(err) + "\r\n" + "保存失败";
return null;
}
public double[] GetNodeCoord(string id)
{
int index = -1;
float result = 0;
double x = 0, y = 0;
//var err = epanet.getnodeindex(id, ref index);
index = (int)param.map_node[id]["index"];
int err = epanet.getcoord(index, ref x, ref y);
return new double[] { x, y };
}
public string Close()
{
string result = null;
int err = 0;
if (isInited)
{
isInited = false;
err = epanet.closeH();
if (err > 0) result = ReportQuestion(err);
err = epanet.close();
if (err > 0) result = ReportQuestion(err);
return result;
}
else
return ReportQuestion(err) + "\r\n" + "未初始化";
}
#endregion
}
}