using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace IStation.Calculation.Epanet { /// /// 计算 (长兴岛) public class CalcCxd { private string _inpFilePath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "EpanetFile", "cxd_method1_2_3.inp"); #region 方法1 public EpanetSchemeDto CalcuPressByLevelAndFlow(EpanetMethod1ContextItem context) { if (context == null) return default; var nodeList = new List(); nodeList.Add(GetInputModel("987319", EpanetNode.eType.level, (float)context.Level));//水池水位 nodeList.Add(GetInputModel("975126", EpanetNode.eType.flow, (float)context.Flow1));//出站流量1 nodeList.Add(GetInputModel("975197", EpanetNode.eType.flow, (float)context.Flow2));//出站流量2 nodeList.Add(GetInputModel("971898", EpanetNode.eType.pump_run, (float)context.Hz1));//1号泵 nodeList.Add(GetInputModel("971861", EpanetNode.eType.pump_run, (float)context.Hz2));//2号泵 nodeList.Add(GetInputModel("971824", EpanetNode.eType.pump_run, (float)context.Hz3));//3号泵 nodeList.Add(GetInputModel("970046", EpanetNode.eType.pump_run, (float)context.Hz4));//4号泵 nodeList.Add(GetInputModel("1", EpanetNode.eType.valve_initstatus, context.valve1));//1号阀门(模型里是节点) nodeList.Add(GetInputModel("2", EpanetNode.eType.valve_initstatus, context.valve2));//2号阀门(模型里是管线) nodeList.Add(GetInputModel("975057", EpanetNode.eType.valve_initstatus, context.valve3));//中间阀门 var helper = new CalcPressByLevelAndFlowHelper(); helper.Initial(_inpFilePath); var shceme = helper.CalcPressByLevelAndFlow(nodeList); if (shceme == null) return default; var dto = new EpanetSchemeDto(); dto.Energy = shceme.Energy; dto.FrequencyCombine = shceme.FrequencyCombine; dto.OutputLinkList = new List(); shceme.OutputLinkList?.ForEach(link => { var linkDto = new EpanetNodeOutputLinkDto(); linkDto.ObjectID = link.ObjectID; linkDto.Type = (eEpanetNodeOutputType)link.Type; linkDto.EN_DIAMETER = link.EN_DIAMETER; linkDto.EN_LENGTH = link.EN_LENGTH; linkDto.EN_FLOW = link.EN_FLOW; linkDto.EN_VELOCITY = link.EN_VELOCITY; linkDto.EN_HEADLOSS = link.EN_HEADLOSS; linkDto.EN_STATUS = link.EN_STATUS; linkDto.EN_SETTING = link.EN_SETTING; linkDto.EN_ENERGY = link.EN_ENERGY; dto.OutputLinkList.Add(linkDto); }); dto.OutputNodeList = new List(); shceme.OutputNodeList?.ForEach(node => { var nodeDto = new EpanetNodeOutputNodeDto(); nodeDto.ObjectID = node.ObjectID; nodeDto.Type = (eEpanetNodeOutputType)node.Type; nodeDto.EN_ELEVATION = node.EN_ELEVATION; nodeDto.EN_BASEDEMAND = node.EN_BASEDEMAND; nodeDto.EN_DEMAND = node.EN_DEMAND; nodeDto.EN_HEAD = node.EN_HEAD; nodeDto.EN_PRESSURE = node.EN_PRESSURE; dto.OutputNodeList.Add(nodeDto); }); return dto; } #endregion #region 方法2 public EpanetSchemeDto CalcuFlowByPressAndPumpStatus(EpanetMethod2ContextItem context) { var nodeList = new List(); nodeList.Add(GetInputModel("987319", EpanetNode.eType.level, (float)context.Level));//水池水位 nodeList.Add(GetInputModel("P1", EpanetNode.eType.press_out, (float)context.Press1));//出站压力1 nodeList.Add(GetInputModel("P2", EpanetNode.eType.press_out, (float)context.Press2));//出站压力2 nodeList.Add(GetInputModel("971898", EpanetNode.eType.pump_run, (float)context.Hz1));//1号泵 nodeList.Add(GetInputModel("971861", EpanetNode.eType.pump_run, (float)context.Hz2));//2号泵 nodeList.Add(GetInputModel("971824", EpanetNode.eType.pump_run, (float)context.Hz3));//3号泵 nodeList.Add(GetInputModel("970046", EpanetNode.eType.pump_run, (float)context.Hz4));//4号泵 nodeList.Add(GetInputModel("1", EpanetNode.eType.valve_initstatus, context.valve1));//1号阀门(模型里是节点) nodeList.Add(GetInputModel("2", EpanetNode.eType.valve_initstatus, context.valve2));//2号阀门(模型里是管线) nodeList.Add(GetInputModel("975057", EpanetNode.eType.valve_initstatus, context.valve3));//中间阀门 var helper = new GetFlowByPressAndPumpStatusHelper(); helper.Initial(_inpFilePath); var shceme = helper.GetFlowByPressAndPumpStatus(nodeList); if (shceme == null) return default; var dto = new EpanetSchemeDto(); dto.Energy = shceme.Energy; dto.FrequencyCombine = shceme.FrequencyCombine; dto.OutputLinkList = new List(); shceme.OutputLinkList?.ForEach(link => { var linkDto = new EpanetNodeOutputLinkDto(); linkDto.ObjectID = link.ObjectID; linkDto.Type = (eEpanetNodeOutputType)link.Type; linkDto.EN_DIAMETER = link.EN_DIAMETER; linkDto.EN_LENGTH = link.EN_LENGTH; linkDto.EN_FLOW = link.EN_FLOW; linkDto.EN_VELOCITY = link.EN_VELOCITY; linkDto.EN_HEADLOSS = link.EN_HEADLOSS; linkDto.EN_STATUS = link.EN_STATUS; linkDto.EN_SETTING = link.EN_SETTING; linkDto.EN_ENERGY = link.EN_ENERGY; dto.OutputLinkList.Add(linkDto); }); dto.OutputNodeList = new List(); shceme.OutputNodeList?.ForEach(node => { var nodeDto = new EpanetNodeOutputNodeDto(); nodeDto.ObjectID = node.ObjectID; nodeDto.Type = (eEpanetNodeOutputType)node.Type; nodeDto.EN_ELEVATION = node.EN_ELEVATION; nodeDto.EN_BASEDEMAND = node.EN_BASEDEMAND; nodeDto.EN_DEMAND = node.EN_DEMAND; nodeDto.EN_HEAD = node.EN_HEAD; nodeDto.EN_PRESSURE = node.EN_PRESSURE; dto.OutputNodeList.Add(nodeDto); }); return dto; } #endregion #region 方法3 public List CalcuPumpStatusByFlowAndPress(EpanetMethod3ContextItem context) { var nodeList = new List(); List openPumpIds = new List(); nodeList.Add(GetInputModel("987319", EpanetNode.eType.level, (float)context.Level));//水池水位 if (context.RunStatus1) { nodeList.Add(GetInputModel("971898", EpanetNode.eType.pump_isFrequece, 1));//1号泵 openPumpIds.Add("971898"); } else { nodeList.Add(GetInputModel("971898", EpanetNode.eType.pump_isFrequece, 0));//1号泵 } if (context.RunStatus2) { nodeList.Add(GetInputModel("971861", EpanetNode.eType.pump_isFrequece, 1));//2号泵 openPumpIds.Add("971861"); } else { nodeList.Add(GetInputModel("971861", EpanetNode.eType.pump_isFrequece, 0));//2号泵 } if (context.RunStatus3) { nodeList.Add(GetInputModel("971824", EpanetNode.eType.pump_isFrequece, 1));//3号泵 openPumpIds.Add("971824"); } else { nodeList.Add(GetInputModel("971824", EpanetNode.eType.pump_isFrequece, 0));//3号泵 } if (context.RunStatus4) { nodeList.Add(GetInputModel("970046", EpanetNode.eType.pump_isFrequece, 1));//4号泵 openPumpIds.Add("970046"); } else { nodeList.Add(GetInputModel("970046", EpanetNode.eType.pump_isFrequece, 0));//4号泵 } nodeList.Add(GetInputModel("975126", EpanetNode.eType.press_out, (float)context.Press1));//出站压力1 nodeList.Add(GetInputModel("975197", EpanetNode.eType.press_out, (float)context.Press2));//出站压力2 nodeList.Add(GetInputModel("975126", EpanetNode.eType.flow, (float)context.Flow1));//出站流量1 nodeList.Add(GetInputModel("975197", EpanetNode.eType.flow, (float)context.Flow2));//出站流量2 nodeList.Add(GetInputModel("1", EpanetNode.eType.valve_initstatus, context.valve1));//1号阀门(模型里是节点) nodeList.Add(GetInputModel("2", EpanetNode.eType.valve_initstatus, context.valve2));//2号阀门(模型里是管线) nodeList.Add(GetInputModel("975057", EpanetNode.eType.valve_initstatus, context.valve3));//中间阀门 var helper = new GetPumpStatusByFlowAndPressHelper(); helper.Initial(_inpFilePath); var shcemeList = helper.GetPumpStatusByFlowAndPress(nodeList, new List>() { openPumpIds }); if (shcemeList == null) return default; var dtoList = new List(); foreach (var scheme in shcemeList) { var dto = new EpanetSchemeDto(); dto.Energy = scheme.Energy; dto.FrequencyCombine = scheme.FrequencyCombine; dto.OutputLinkList = new List(); scheme.OutputLinkList?.ForEach(link => { var linkDto = new EpanetNodeOutputLinkDto(); linkDto.ObjectID = link.ObjectID; linkDto.Type = (eEpanetNodeOutputType)link.Type; linkDto.EN_DIAMETER = link.EN_DIAMETER; linkDto.EN_LENGTH = link.EN_LENGTH; linkDto.EN_FLOW = link.EN_FLOW; linkDto.EN_VELOCITY = link.EN_VELOCITY; linkDto.EN_HEADLOSS = link.EN_HEADLOSS; linkDto.EN_STATUS = link.EN_STATUS; linkDto.EN_SETTING = link.EN_SETTING; linkDto.EN_ENERGY = link.EN_ENERGY; dto.OutputLinkList.Add(linkDto); }); dto.OutputNodeList = new List(); scheme.OutputNodeList?.ForEach(node => { var nodeDto = new EpanetNodeOutputNodeDto(); nodeDto.ObjectID = node.ObjectID; nodeDto.Type = (eEpanetNodeOutputType)node.Type; nodeDto.EN_ELEVATION = node.EN_ELEVATION; nodeDto.EN_BASEDEMAND = node.EN_BASEDEMAND; nodeDto.EN_DEMAND = node.EN_DEMAND; nodeDto.EN_HEAD = node.EN_HEAD; nodeDto.EN_PRESSURE = node.EN_PRESSURE; dto.OutputNodeList.Add(nodeDto); }); dtoList.Add(dto); } return dtoList; } #endregion /// /// 获取类 /// EpanetNode GetInputModel(string objId, EpanetNode.eType type, float value) { var model = new EpanetNode(); model.ObjectID = objId; model.Type = type; model.Value = value; return model; } } } /*算法注意事项: 1.节点压力单位(M) 2.每个算法对输入输出的要求不一样 3.算法2只会计算出节点的压力,不会返回流量 4.方法1、2 控制泵的开关是 pump_run 5. 方法3 控制泵的开关是 pump_isFrequece 6. 方法3 关闭中间阀的情况下 (1号管流量太小—计算失败) (2号管与预期流量不符) */ /* 问题: 1.止回阀的起始节点和终止节点有没有影响? 2. 关阀后 2号管的流量控制不了,入参2000方 出参4000方(解决) 3.模型算出来的负值 算法返回来0 (解决) 4. 模型 管路中的歪斜程度会不会影响 流量 (不会) 5. 方法3的用法 */ /* 注意事项 * 1.方法1 方法3 只需要控制中间阀 管道的限定 需要根据流量值大小来判断 (关闭1号管 1号管路入参流量设置为0) * 2.方法2 出口压力定在水库上 可以控制3个阀门 * 3.方法3 出站压力和出站流量定在水库上 * 4.方法3 能耗越低小 * 5.方法2 两个管路的压力值 不能相差太大 不然计算精度有偏差 */ /*错误 * 1 开停机状态是要输入频率的 * * */