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 } }