using Hydro.CodeProvider;
|
using Hydro.CommonBase;
|
using Hydro.ConfigModel;
|
using Hydro.HydraulicModel;
|
using Hydro.ParrelControl;
|
using SolutionDBHelper_NS;
|
using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Security.Cryptography;
|
using System.Text;
|
using System.Text.RegularExpressions;
|
using System.Threading;
|
using System.Threading.Tasks;
|
//using WaterDistributioinManager;
|
using Hydro.ConfigModel;
|
|
namespace Hydro.HydraulicHelperNS
|
{
|
public partial class HydraulicHelper
|
{
|
|
|
public static List<HydraulicInputType> escapeType = new List<HydraulicInputType>() { HydraulicInputType.totalDemand, HydraulicInputType.Distribution_TotalDemand };
|
private int GetIndex(variable v)
|
{
|
if (!gParam.GlobalConfig.Ext.isWaterModelCalc || string.IsNullOrEmpty(v.modelObjectID)) return 1;
|
Regex r = new Regex(@"\{\|.*\|\}");
|
if ( r.IsMatch(v.modelObjectID)) return 0;
|
if (v.Type is HydraulicInputType && escapeType.IndexOf(v.Type)>=0) return 0;
|
var index = -1;
|
//if (v.Type == null) return index;
|
//int err = (v.isNode) ? epanet.getnodeindex(v.modelObjectID, ref index) : epanet.getlinkindex(v.modelObjectID, ref index);
|
if (v.isNode)
|
{
|
index = (int)param.map_node[v.modelObjectID]["index"];
|
}
|
else
|
{
|
index = (int)param.map_link[v.modelObjectID]["index"];
|
}
|
return index == 0 ? -1 : index;
|
}
|
|
|
|
public string CheckConstraintCondition(LogicModelParams param,int period)
|
{
|
|
string result = null;
|
double CalcValue_Calc;
|
param.约束变量.ForEach(v =>
|
{
|
if (result != null) return;
|
float value = -1f;
|
bool flag = true;
|
var v0 = GetValue(v, null,period);
|
switch (v.expressType)
|
{
|
case ">":
|
if (v0 <= double.Parse(v.expressString)) flag=false;
|
break;
|
case "<":
|
if (v0 >= double.Parse(v.expressString)) flag = false;
|
break;
|
case "∈":
|
if (double.Parse(v.expressString.Split(',')[0]) <= v0 && v0 <= double.Parse(v.expressString.Split(',')[1])) flag = true;
|
else flag = false;
|
break;
|
}
|
if (!flag) result = $"[{v.Name}]当前值为{v.Value0},不满足约束{v.expressType}[{v.expressString}]";
|
|
});
|
return result;
|
}
|
|
|
HydraulicOutputType GetOutputTypeByInput(HydraulicInputType inputType)
|
{
|
switch (inputType)
|
{
|
case HydraulicInputType.press:
|
return HydraulicOutputType.Head;
|
break;
|
case HydraulicInputType.demand:
|
return HydraulicOutputType.Demand;//需水量=跟流速一样都是9
|
break;
|
case HydraulicInputType.level:
|
return HydraulicOutputType.Head;
|
break;
|
case HydraulicInputType.initPumpRS:
|
return HydraulicOutputType.Settings;
|
break;
|
case HydraulicInputType.initSettings:
|
return HydraulicOutputType.Settings;
|
break;
|
case HydraulicInputType.initStatus:
|
return HydraulicOutputType.Status;
|
break;
|
case HydraulicInputType.diameter:
|
return HydraulicOutputType.Diameter;
|
break;
|
case HydraulicInputType.length:
|
return HydraulicOutputType.Length;
|
break;
|
}
|
return HydraulicOutputType.Head;
|
}
|
|
//private string setRandomDemand(variable VSet, float TotalDemand)
|
//{
|
// string result = null;
|
// Random r = new Random();
|
// //List<float> 用水设备 = new List<float>() { 0.15f, 0.1f, 0.2f };
|
// List<float> 用水设备 = new List<float>() { 0.36f, 0.54f, 0.72f };
|
// List<float> 每种设备最大分配流量 = new List<float>();
|
// List<double> 分配系数 = new List<double>();
|
// 用水设备.ForEach(v => 分配系数.Add(0));
|
// 用水设备.ForEach(v => 每种设备最大分配流量.Add(v * (VSet.Vars.Count)));
|
// float MaxTotalDemand = 0;
|
// 每种设备最大分配流量.ForEach(v => MaxTotalDemand += v);
|
// List<int> 分配数量 = new List<int>();
|
// if (TotalDemand > MaxTotalDemand)
|
// {
|
// return "最大分配水量超过:" + MaxTotalDemand.ToString();
|
// }
|
// double sum = 0;
|
// for (int i = 0; i < 分配系数.Count; i++)
|
// {
|
// 分配系数[i] = r.NextDouble();
|
// sum += 分配系数[i];
|
// }
|
// for (int i = 0; i < 分配系数.Count; i++)
|
// {
|
// 分配系数[i] = 分配系数[i] / sum * TotalDemand;
|
// }
|
// for (int i = 0; i < 分配系数.Count; i++)
|
// {
|
// if (分配系数[i] > 每种设备最大分配流量[i])
|
// {
|
// int t = i + 1; if (t >= 分配系数.Count) t = 0;
|
// 分配系数[t] += 分配系数[i] - 每种设备最大分配流量[i];
|
// 分配系数[i] = 每种设备最大分配流量[i];
|
// }
|
// }
|
// for (int i = 0; i < 分配系数.Count; i++)
|
// {
|
// if (分配系数[i] > 每种设备最大分配流量[i])
|
// {
|
// int t = i + 1; if (t >= 分配系数.Count) t = 0;
|
// 分配系数[t] += 分配系数[i] - 每种设备最大分配流量[i];
|
// 分配系数[i] = 每种设备最大分配流量[i];
|
// }
|
// }
|
// for (int i = 0; i < 分配系数.Count; i++)
|
// {
|
// 分配数量.Add((int)(分配系数[i] / 用水设备[i]));
|
// }
|
|
|
// for (int i = 0; i < VSet.Vars.Count; i++)
|
// {
|
// VSet.Vars[i].LogicValue = 0;
|
// }
|
|
// if (VSet.Vars[0].elevation == -9099)
|
// {
|
// VSet.Vars.ForEach(v => {
|
// float tempValue = -1;
|
// epanet.getnodevalue(v.modelIndex, HydraulicCore.Const_class.Const_Node.EN_ELEVATION, ref tempValue);
|
// v.elevation = tempValue;
|
// });
|
// }
|
|
|
// for (int i = 0; i < 分配系数.Count; i++)
|
// {
|
// VSet.Vars.ForEach(v => { v.accuracy = r.NextDouble() * v.elevation; });
|
// VSet.Vars.Sort(
|
// (a, b) => {
|
// return ((double)a.accuracy > (double)b.accuracy) ? -1 : 1;
|
// }
|
// );
|
|
// for (int j = 0; j < Math.Min(分配数量[i], 分配系数.Count); j++)
|
// {
|
// VSet.Vars[j].LogicValue += 用水设备[i];
|
// }
|
// };
|
|
// VSet.Vars.Sort(
|
// (a, b) => {
|
// return (a.modelIndex > b.modelIndex) ? 1 : -1;
|
// }
|
// );
|
|
// return result;
|
|
//}
|
|
/// <summary>
|
/// 设置试算变量
|
/// </summary>
|
/// <param name="param"></param>
|
/// <returns></returns>
|
public string setAtemptParams(LogicModelParams param, calcParam cParam)
|
{
|
#region 初始判断
|
|
string result = null;
|
int err = 0;
|
|
#endregion
|
//处理已知量
|
if (gParam.GlobalConfig.Ext.waterdistribute)
|
{
|
int cIndex = 0;
|
//for (int i=0;i<param.map_node.Count;i++)
|
//{
|
// var node = param.map_node[i];
|
// if (node["type"] == 0)
|
// {
|
// err = SetItemValue(i+1,0, HydraulicInputType.demand);
|
// if (err > 9) return ReportQuestion(err);
|
// }
|
|
//}
|
for (int i = 0; i < param.水量分配变量.Count; i++)
|
{
|
|
var v = param.水量分配变量[i];
|
if (v.IndicatorType != "当量分配") continue;
|
for (int j = 0; j < v.Vars.Count; j++)
|
{
|
var vv = v.Vars[j];
|
err = SetItemValue(vv.modelIndex, cParam.vars[cIndex], HydraulicInputType.demand);
|
if (err > 9) return ReportQuestion(err);
|
cIndex++;
|
}
|
|
|
}
|
}
|
else
|
{
|
for (int i = 0; i < param.试算变量.Count; i++)
|
{
|
var v = param.试算变量[i];
|
param.试算变量[i].Value_Set(param.Period, cParam.vars[i]);
|
#region [秦白云飞修订] 2023年2月15日 21:00:02
|
//if (v.modelIndex == 0 && v.logicType=="集合")
|
//{
|
|
// var ss = param.集合.Find(s => s.Name == v.modelObjectID.Trim('{').Trim('}').Trim('|'));
|
|
// result = setRandomDemand(ss, gParam.GlobalConfig.Ext.TotalDemand);
|
// if (result != null) return result;
|
// Random r = new Random();
|
// foreach (var vv in ss.Vars)
|
// {
|
// var value_set = vv.GetLogicValue();
|
// if (value_set != null)
|
// {
|
// err = SetItemValue(vv.modelIndex, value_set, (HydraulicInputType)v.Type);
|
// }
|
|
// //value_set=v.doubleRange.Min + r.NextDouble() * (v.doubleRange.Max - v.doubleRange.Min);
|
// if (err > 9) result = ReportQuestion(err);
|
// }
|
|
//}
|
//else
|
#endregion [秦白云飞修订] 2023年2月15日 21:00:02
|
err = SetItemValue(v.modelIndex, cParam.vars[i], (HydraulicInputType)v.Type);
|
if (err > 9) return ReportQuestion(err);
|
}
|
|
}
|
if (cParam.setVars != null)
|
{
|
foreach (var v in cParam.setVars)
|
{
|
if (v.isNode)
|
{
|
int index = 0;
|
////err = epanet.getnodeindex(v.ID, ref index);
|
////if (err > 9) return ReportQuestion(err);
|
index = (int)param.map_node[v.ID]["index"];
|
err = epanet.setnodevalue(index, v.type, v.value);
|
if (err > 9) return ReportQuestion(err);
|
}
|
else
|
{
|
int index = 0;
|
//err = epanet.getlinkindex(v.ID, ref index);
|
//if (err > 9) return ReportQuestion(err);
|
index = (int)param.map_link[v.ID]["index"];
|
err = epanet.setlinkvalue(index, v.type, v.value);
|
if (err > 9) return ReportQuestion(err);
|
}
|
|
}
|
}
|
return null;
|
}
|
/// <summary>
|
/// 当需要输出的时候,获取所有变量的值,顺便把值赋值到output中
|
/// </summary>
|
/// <param name="param"></param>
|
/// <param name="period"></param>
|
/// <returns></returns>
|
public string setVariableValue(LogicModelParams param, int period = 0)
|
{
|
string result = null;
|
param.初始条件.ForEach(v =>
|
{
|
v.Value_Set(period, GetValue(v, null, period, false));
|
});
|
param.下阶段条件.ForEach(v =>
|
{
|
v.Value_Set(period, GetValue(v, null, period, false));
|
});
|
param.变量.ForEach(v =>
|
{
|
v.Value_Set(period, GetValue(v, null, period, false));
|
});
|
param.试算变量.ForEach(v =>
|
{
|
v.Value_Set(period, GetValue(v, null, period, false));
|
});
|
param.约束变量.ForEach(v =>
|
{
|
v.Value_Set(period, GetValue(v, null, period, false));
|
});
|
param.集合.ForEach(v =>
|
{
|
if (v == null) return;
|
var arr = GetSetArr(v);
|
//var bestVal = arr.Max().Value;
|
//if (bestVal != null)
|
//{
|
// v.obj_Best = bestVal.modelObjectID;
|
//}
|
v.objListString = arr.ToString();
|
v.Value_Set(period, GetValue(v, null, period, false));
|
});
|
param.表达式.ForEach(v =>
|
{
|
if (v == null) return;
|
v.objListString = GetVarArr(v, period).ToString();
|
v.Value_Set(period, GetValue(v, null, period, false));
|
});
|
|
|
|
return null;
|
}
|
public string Init_VariableValue(LogicModelParams param, int times)
|
{
|
string result = null;
|
|
//param.变量全集.ForEach(v =>
|
//{
|
// v.Values = new double[times];
|
//});
|
return null;
|
}
|
public string output_VariableValue(LogicModelParams param, int period)
|
{
|
string result = null;
|
|
param.初始条件.ForEach(v =>
|
{
|
v.Value_Set(period, GetValue(v, null, period, true));
|
});
|
param.下阶段条件.ForEach(v =>
|
{
|
v.Value_Set(period, GetValue(v, null, period, true));
|
});
|
param.变量.ForEach(v =>
|
{
|
v.Value_Set(period, GetValue(v, null, period, true));
|
});
|
param.试算变量.ForEach(v =>
|
{
|
v.Value_Set(period, GetValue(v, null, period, true));
|
});
|
param.约束变量.ForEach(v =>
|
{
|
v.Value_Set(period, GetValue(v, null, period, true));
|
});
|
|
return null;
|
}
|
public string output_VariableValue_API(WdnmoParam wParam ,int period,double fitness=0)
|
{
|
//BookMark :输出变量值到接口
|
|
string result = null;
|
//wParam.Fitness=fitness;
|
bool fit_get = false;
|
wParam.ResultPoints.ForEach(r =>
|
{
|
|
if (r.Key.ToLower()=="fitness")
|
{
|
r.isNeedtoSave = true;
|
r.Value = fitness;
|
r.SaveKey = "fitness";
|
fit_get = true;
|
}
|
//[Cloudflight修改]2024-1-8
|
else if (!this.param.dict_OutPut.ContainsKey(r.Key))//this.param.接口变量.Find(v => v.expressString == r.Key)) == null)
|
{
|
result += $"未找到待输出量[{r.Name}]-[{r.Key}]\r\n";
|
}
|
else
|
{
|
var value = this.param.dict_OutPut[r.Key];
|
if (value.Length==1)
|
{
|
var va=value[0] as variable;
|
r.Value = GetValue(va, null, period, true);
|
r.Pattern = va.Values;
|
}
|
else
|
{
|
var va = value[0] as variable;
|
var vv = value[1];
|
r.Value = GetValue(va,vv, period, true);
|
/*[Cloudflight修改]2024-5-16
|
*
|
*/
|
//r.Pattern = vv.Values;
|
}
|
|
|
}
|
|
});
|
if (!fit_get)
|
{
|
wParam.ResultPoints.Add(new TimePoint()
|
{
|
Name="目标",
|
Key="fitness",
|
Value=fitness,
|
isNeedtoSave=true,
|
SaveKey="fitness",
|
});
|
}
|
|
return result;
|
}
|
public string output_VariableValue_API(WdnmoParam wParam, double fitness = 0)
|
{
|
//BookMark :输出变量值到接口
|
|
string result = null;
|
//wParam.Fitness=fitness;
|
bool fit_get = false;
|
wParam.ResultPoints.ForEach(r =>
|
{
|
|
if (r.Key.ToLower() == "fitness")
|
{
|
r.isNeedtoSave = true;
|
r.Value = fitness;
|
r.SaveKey = "fitness";
|
fit_get = true;
|
}
|
//[Cloudflight修改]2024-1-8
|
else if (!this.param.dict_OutPut.ContainsKey(r.Key))//this.param.接口变量.Find(v => v.expressString == r.Key)) == null)
|
{
|
result += $"未找到待输出量[{r.Name}]-[{r.Key}]\r\n";
|
}
|
else
|
{
|
var value = this.param.dict_OutPut[r.Key];
|
var va = value[0] as variable;
|
r.Pattern = va.Values;
|
|
|
|
}
|
|
});
|
if (!fit_get)
|
{
|
wParam.ResultPoints.Add(new TimePoint()
|
{
|
Name = "目标",
|
Key = "fitness",
|
Value = fitness,
|
isNeedtoSave = true,
|
SaveKey = "fitness",
|
});
|
}
|
|
return result;
|
}
|
public string getObjFunctionValue(int period = 0)
|
{
|
#region 初始判断
|
if (period < 0) period = 0;//多时刻计算的时候,暂时只统计第一个时刻的数值
|
string result = null;
|
int err = 0;
|
//ObjValue = 0;
|
#endregion
|
//处理已知量
|
var ObjValue=GetValue( param.OFunction.variable, null, period, false);
|
|
return null;
|
}
|
|
//if (param.OFunction.isUseExpression == true)//使用表达式
|
//{
|
// var func = param.OFunction;
|
// //var paramValues = new List<double>();
|
// //func.variable.Vars.ForEach(v =>
|
// //{
|
// // if (result != null) return;
|
// // double Value = v.GetValue(GetCalcValue, MultiTimes, true);
|
// // if (Value == variable.ErrNum) { result = $"{v.logicType}[{v.ID}]取值错误"; return; }
|
// // //if (GlobalModel.DEFINE_LOGICPOINT.Find(logic => logic.Name == "变量").Type_expression.IndexOf(v.expressType) < 3)//判断取计算值还是设定值
|
// // paramValues.Add(Value);
|
// //});
|
// var v = func.variable;
|
// List<double> doubles = new List<double>();
|
// List<double[]> patterns = new List<double[]>();
|
// for (int i = 0; i < v.Vars.Count; i++)
|
// {
|
// var e = v.Vars[i];
|
// double Value = 0;
|
// if (v.VarIndexs.ContainsKey(i))
|
// {
|
// Value = e.LogicValues[v.VarIndexs[i]];
|
// }
|
// else
|
// {
|
// //普通表达式只有在输出的时候会进行计算,函数计算需要刷新结果
|
// Value = e.GetValue(GetCalcValue, 0, true);
|
// }
|
|
|
// doubles.Add(Value);
|
// }
|
// for (int i = 0; i < v.PatternVars.Count; i++)
|
// {
|
// var e = v.PatternVars[i];
|
// double[] Value = e.LogicValues;
|
// patterns.Add(Value);
|
// }
|
|
|
// if (result != null) return result;
|
// var re = func.eval.getResult(doubles, patterns);
|
// if (re is double)
|
// {
|
// if (Double.IsNaN(re))
|
// return "返回值类型异常";
|
// //else if (re == 0)
|
// // return "返回值类型异常";
|
// else
|
// ObjValue = re;
|
// }
|
// else
|
// {
|
// return "函数表达式错误,返回值类型异常";
|
// }
|
// // param.OFunction.value = re;
|
// //else
|
// // return "函数值的类型错误";
|
//}
|
//else //不使用表达式
|
//{
|
// ObjValue = GetCalcValue(param.OFunction.variable);
|
//}
|
}
|
}
|