namespace IStation.Algorithm
|
{
|
/// <summary>
|
/// 调度分析辅助类
|
/// </summary>
|
public partial class ScheduleHelper
|
{
|
readonly decimal _frequency_min = 25;
|
readonly decimal _frequency_max = 50;
|
readonly decimal _frequency_space = 0.1m;//频率间隔
|
|
readonly double _start_stop_loss_coefficient = 0.95;//泵启停损失系数
|
|
readonly double _sel_opt_flow_deviation_ratio = 0.05;//可选方案的流量偏差比
|
readonly double _sel_opt_reasonable_flow_deviation_ratio = 0.005;//合理的方案的流量偏差比
|
|
readonly Service.AnalysisCombine _service_analysis_combine = new();
|
readonly Service.AnalysisConclusion _service_analysis_conclusion = new();
|
readonly Service.AnalysisLog _service_analysis_log = new();
|
|
|
List<int> _current_open_flag_list = null;// 当前开泵列表
|
List<int> _must_open_flag_list = null; // 必开泵列表
|
List<int> _must_close_flag_list = null; // 必关泵列表
|
List<List<int>> _forbidden_flag_combine_list = null; // 禁用泵组合
|
List<List<int>> _associative_flag_combine_list = null; // 关联泵组合
|
List<List<int>> _same_section_flag_combine_list = null; // 同段泵组合
|
List<Model.WaterSupplyLimit> _water_supply_limit_list = null; //供水限制列表
|
List<Model.FrequencyLimit> _frequency_limit_list = null; // 频率限制列表
|
//List<int> _priority_order_flag_list = null; // 优先度排序 暂未考虑
|
|
/// <summary>
|
/// 初始化
|
/// </summary>
|
public void Initial(List<int> current_open_flag_list, Model.ScheduleConfig schedule_config)
|
{
|
_current_open_flag_list = current_open_flag_list;
|
_must_open_flag_list = null;
|
_must_close_flag_list = null;
|
_forbidden_flag_combine_list = null;
|
_associative_flag_combine_list = null;
|
_same_section_flag_combine_list = null;
|
_water_supply_limit_list = null;
|
_frequency_limit_list = null;
|
if (schedule_config != null)
|
{
|
_must_open_flag_list = schedule_config.MustOpenFlagList;
|
_must_close_flag_list = schedule_config.MustCloseFlagList;
|
_forbidden_flag_combine_list = schedule_config.ForbiddenFlagCombineList;
|
_associative_flag_combine_list = schedule_config.AssociativeFlagCombineList;
|
_same_section_flag_combine_list = schedule_config.SameSectionFlagCombineList;
|
_water_supply_limit_list = schedule_config.WaterSupplyLimitList;
|
_frequency_limit_list = schedule_config.FrequencyLimitList;
|
}
|
|
}
|
|
|
/// <summary>
|
/// 计算
|
/// </summary>
|
/// <param name="pumps"></param>
|
/// <param name="flags"></param>
|
/// <param name="flags_part2"></param>
|
/// <param name="target_flow"></param>
|
/// <param name="target_head"></param>
|
/// <returns></returns>
|
public AnaOptimalCombine Calc(List<Model.Pump> pumps, List<int> flags, List<int> flags_part2, double target_flow, double target_head)
|
{
|
var current_open_flag_list = _current_open_flag_list;
|
var must_open_flag_list = _must_open_flag_list;
|
var must_close_flag_list = _must_close_flag_list;
|
var forbidden_flag_combine_list = _forbidden_flag_combine_list;
|
var associative_flag_combine_list = _associative_flag_combine_list;
|
var same_section_flag_combine_list = _same_section_flag_combine_list;
|
var water_supply_limit_list = _water_supply_limit_list;
|
var frequency_limit_list = _frequency_limit_list;
|
|
if (pumps == null || !pumps.Any())
|
{
|
return default;
|
}
|
target_flow = Math.Round(target_flow, 1);
|
target_head = Math.Round(target_head, 1);
|
|
#region 存在-当前开泵列表
|
|
var exist_current_open_flag_list = current_open_flag_list != null && current_open_flag_list.Count > 0;
|
|
#endregion
|
|
#region 存在-必开泵列表
|
|
var must_open_flag_list_remark = string.Empty;
|
var exist_must_open_flag_list = must_open_flag_list != null && must_open_flag_list.Count > 0;
|
if (exist_must_open_flag_list)
|
{
|
must_open_flag_list = must_open_flag_list.OrderBy(x => x).ToList();
|
must_open_flag_list_remark = IntListHelper.ToString(must_open_flag_list);
|
}
|
|
#endregion
|
|
#region 存在-必关泵列表
|
|
var exist_must_close_flag_list = must_close_flag_list != null && must_close_flag_list.Count > 0;
|
|
#endregion
|
|
#region 存在-禁用组合
|
|
var exist_forbidden_flag_combine_list = forbidden_flag_combine_list != null && forbidden_flag_combine_list.Count > 0;
|
|
#endregion
|
|
#region 存在-关联组合
|
|
var exist_associative_flag_combine_list = associative_flag_combine_list != null && associative_flag_combine_list.Count > 0;
|
|
#endregion
|
|
#region 存在-同段泵组合
|
|
Dictionary<int, List<int[]>> same_section_combine_dict = new();
|
var exist_same_section_flag_combine_list = _same_section_flag_combine_list != null && _same_section_flag_combine_list.Count > 0;
|
if (exist_same_section_flag_combine_list)
|
{
|
for (int pump_count = 1; pump_count <= pumps.Count; pump_count++)
|
{
|
same_section_combine_dict[pump_count] = new List<int[]>();
|
switch (pump_count)
|
{
|
case 2:
|
{
|
foreach (var same_section_flag_combine in same_section_flag_combine_list)
|
{
|
var combine_list = GetCombineList(same_section_flag_combine, 2);
|
same_section_combine_dict[pump_count].AddRange(combine_list);
|
}
|
}
|
break;
|
case 3:
|
{
|
foreach (var same_section in same_section_flag_combine_list)
|
{
|
var combine_list = GetCombineList(same_section, 3);
|
same_section_combine_dict[pump_count].AddRange(combine_list);
|
}
|
}
|
break;
|
case 4:
|
{
|
foreach (var same_section in same_section_flag_combine_list)
|
{
|
var combine_list3 = GetCombineList(same_section, 3);
|
same_section_combine_dict[pump_count].AddRange(combine_list3);
|
if (same_section.Count > 3)
|
{
|
var combine_list = GetCombineList(same_section, 4);
|
same_section_combine_dict[pump_count].AddRange(combine_list);
|
}
|
}
|
}
|
break;
|
case 5:
|
{
|
foreach (var same_section in same_section_flag_combine_list)
|
{
|
if (same_section.Count > 3)
|
{
|
var combine_list = GetCombineList(same_section, 4);
|
same_section_combine_dict[pump_count].AddRange(combine_list);
|
}
|
}
|
}
|
break;
|
case 6:
|
{
|
foreach (var same_section in same_section_flag_combine_list)
|
{
|
if (same_section.Count > 3)
|
{
|
var combine_list = GetCombineList(same_section, 4);
|
same_section_combine_dict[pump_count].AddRange(combine_list);
|
}
|
}
|
}
|
break;
|
default:
|
break;
|
}
|
}
|
}
|
#endregion
|
|
#region 存在-供水限制
|
|
var exist_water_supply_limit_list = water_supply_limit_list != null && water_supply_limit_list.Count > 0;
|
|
#endregion
|
|
#region 存在-频率限制
|
var frequency_limit_flag_dict = new Dictionary<int, Model.FrequencyLimit>();
|
var exist_frequency_limit_list = frequency_limit_list != null && frequency_limit_list.Count > 0;
|
if (exist_frequency_limit_list)
|
{
|
frequency_limit_flag_dict = frequency_limit_list.ToDictionary(x => x.Flag, x => x);
|
}
|
|
#endregion
|
|
#region 存在-优先度排序 暂未考虑
|
|
// var exist_priority_order_flag_list = priority_order_flag_list != null && priority_order_flag_list.Count > 0;
|
|
#endregion
|
|
var pump_bp_dict = pumps.ToDictionary(x => x.Flag, x => x.IsBp);
|
var pump_nr_dict = pumps.ToDictionary(x => x.Flag, x => x.Nr);
|
var pump_flag_list = pumps.Select(x => x.Flag).ToList();
|
var optimal_combine_list = new List<AnaOptimalCombine>();
|
for (int pumpCount = 1; pumpCount <= pumps.Count; pumpCount++)
|
{
|
if (pumpCount == 1)
|
{
|
var max_total_flow = pumps.Max(x => x.Qr);
|
if (max_total_flow < target_flow)
|
continue;
|
}
|
|
//供水限制
|
if (exist_water_supply_limit_list)
|
{
|
var exist_limit = false;
|
foreach (var limit in water_supply_limit_list)
|
{
|
if (target_flow >= limit.Min && target_flow <= limit.Max)
|
{
|
if (limit.PumpCount != pumpCount)
|
{
|
exist_limit = true;
|
break;
|
}
|
}
|
}
|
if (exist_limit)
|
continue;
|
}
|
|
var combine_list = Curve.PermutationAndCombination<int>.GetCombination(pump_flag_list.ToArray(), pumpCount);//排列组合
|
foreach (var combine in combine_list)
|
{
|
double combine_merit_ratio = 1;//组合择优率
|
|
//必开
|
if (exist_must_open_flag_list)
|
{
|
var combine_remark = IntListHelper.ToString(combine.OrderBy(x => x));
|
if (!combine_remark.Contains(must_open_flag_list_remark))
|
continue;
|
}
|
|
//必关
|
if (exist_must_close_flag_list)
|
{
|
var exist_intersected = combine.Intersect(must_close_flag_list).Count() > 0;
|
if (exist_intersected)
|
continue;
|
}
|
|
//禁用组合
|
if (exist_forbidden_flag_combine_list)
|
{
|
var exist_equal = false;
|
foreach (var flag_list in forbidden_flag_combine_list)
|
{
|
if (combine.SequenceEqual(flag_list))
|
{
|
exist_equal = true;
|
break;
|
}
|
}
|
if (exist_equal)
|
continue;
|
}
|
|
//同段泵组合
|
if (exist_same_section_flag_combine_list)
|
{
|
var exist_equal = false;
|
foreach (var flag_list in same_section_combine_dict[pumpCount])
|
{
|
//相同
|
if (combine.SequenceEqual(flag_list))
|
{
|
exist_equal = true;
|
break;
|
}
|
|
//包含
|
if (flag_list.Intersect(combine).Count() == flag_list.Length)
|
{
|
exist_equal = true;
|
break;
|
}
|
}
|
if (exist_equal)
|
continue;
|
}
|
|
//关联组合
|
if (exist_associative_flag_combine_list)
|
{
|
var exist_intersected = false;
|
foreach (var flag_list in associative_flag_combine_list)
|
{
|
var except_count = combine.Except(flag_list).Count();
|
if (except_count != flag_list.Count && except_count > 0)
|
{
|
exist_intersected = true;
|
}
|
}
|
if (exist_intersected)
|
continue;
|
}
|
|
int start_stop_count = 0;//启停数量
|
if (exist_current_open_flag_list)
|
{
|
var start_pump_count = combine.Except(current_open_flag_list).Count();
|
var close_pump_count = current_open_flag_list.Except(combine).Count();
|
start_stop_count = start_pump_count + close_pump_count;//启停数量
|
}
|
else
|
{
|
start_stop_count = combine.Count();
|
if (exist_must_open_flag_list)
|
{
|
start_stop_count = combine.Except(must_open_flag_list).Count();
|
}
|
}
|
|
var total_loss_ratio = Math.Pow(_start_stop_loss_coefficient, start_stop_count);//启停一次损失些能耗
|
combine_merit_ratio *= total_loss_ratio;
|
List<int> combine_flag_list_part1 = new();
|
List<int> combine_flag_list_part2 = new();
|
foreach (var pump in combine)
|
{
|
if (flags.Contains(pump))
|
{
|
combine_flag_list_part1.Add(pump);
|
}
|
else
|
{
|
combine_flag_list_part2.Add(pump);
|
}
|
}
|
|
//区分同型号泵
|
List<AnaFreCombine> fre_combine_list_part1 = new();
|
List<AnaFreCombine> fre_combine_list_part2 = new();
|
|
if (combine_flag_list_part1.Count > 0)
|
{
|
var conclusion_list_dic = new Dictionary<int, List<Model.AnalysisConclusion>>();
|
foreach (var flag in combine_flag_list_part1)
|
{
|
var runFlag = RunFlagHelper.GetRunFlag(flag, pump_bp_dict[flag]);
|
if (conclusion_list_dic.ContainsKey(flag))
|
continue;
|
|
//频率限制
|
var conclusionList = new List<Model.AnalysisConclusion>();
|
if (exist_frequency_limit_list && frequency_limit_flag_dict.ContainsKey(flag))
|
{
|
var limit = frequency_limit_flag_dict[flag];
|
conclusionList = _service_analysis_conclusion.GetList(runFlag, limit.Min, limit.Max, target_head);
|
}
|
else
|
{
|
conclusionList = _service_analysis_conclusion.GetList(runFlag, target_head);
|
}
|
conclusion_list_dic[flag] = conclusionList;
|
}
|
if (conclusion_list_dic.Count < 1)
|
continue;
|
|
for (decimal fre = _frequency_max; fre >= _frequency_min; fre -= _frequency_space)
|
{
|
var freCombine = new AnaFreCombine();
|
freCombine.Frequency = (double)fre;
|
freCombine.Flags = new List<int>();
|
freCombine.FrePumps = new List<AnaFrePump>();
|
foreach (var item in conclusion_list_dic)
|
{
|
var conclusion = item.Value?.Find(x => x.Pump1 == (double)fre);
|
if (conclusion != null)
|
{
|
freCombine.Flags.Add(item.Key);
|
freCombine.Flow += conclusion.Flow;
|
freCombine.Power += conclusion.Power;
|
freCombine.RunCount++;
|
|
var fre_pump = new AnaFrePump();
|
fre_pump.Flag = item.Key;
|
fre_pump.Flow = conclusion.Flow;
|
fre_pump.Head = target_head;
|
fre_pump.Power = conclusion.Power;
|
fre_pump.Efficiency = Curve.PumpCalculateHelper.CalculateE(fre_pump.Flow, fre_pump.Head, fre_pump.Power);
|
fre_pump.Frequency = freCombine.Frequency;
|
fre_pump.Speed = (double)fre / 50 * pump_nr_dict[item.Key];
|
freCombine.FrePumps.Add(fre_pump);
|
}
|
}
|
if (freCombine.Flags.Count < 1)
|
continue;
|
fre_combine_list_part1.Add(freCombine);
|
}
|
}
|
if (combine_flag_list_part2.Count > 0)
|
{
|
var conclusion_list_dic = new Dictionary<int, List<Model.AnalysisConclusion>>();
|
foreach (var flag in combine_flag_list_part2)
|
{
|
var runFlag = RunFlagHelper.GetRunFlag(flag, pump_bp_dict[flag]);
|
if (conclusion_list_dic.ContainsKey(flag))
|
continue;
|
|
//频率限制
|
var conclusionList = new List<Model.AnalysisConclusion>();
|
//if (pump_bp_dict[flag] == false)
|
//{
|
// conclusionList = _service_analysis_conclusion.GetList(runFlag);
|
//}else
|
if (exist_frequency_limit_list && frequency_limit_flag_dict.ContainsKey(flag))
|
{
|
var limit = frequency_limit_flag_dict[flag];
|
conclusionList = _service_analysis_conclusion.GetList(runFlag, limit.Min, limit.Max, target_head);
|
}
|
else
|
{
|
conclusionList = _service_analysis_conclusion.GetList(runFlag, target_head);
|
}
|
conclusion_list_dic[flag] = conclusionList;
|
}
|
|
if (conclusion_list_dic.Count < 1)
|
{
|
continue;
|
}
|
|
for (decimal fre = _frequency_max; fre >= _frequency_min; fre -= _frequency_space)
|
{
|
var freCombine = new AnaFreCombine();
|
freCombine.Frequency = (double)fre;
|
freCombine.Flags = new List<int>();
|
freCombine.FrePumps = new List<AnaFrePump>();
|
foreach (var item in conclusion_list_dic)
|
{
|
var conclusion = item.Value?.Find(x => x.Pump1 == (double)fre);
|
if (conclusion != null)
|
{
|
freCombine.Flags.Add(item.Key);
|
freCombine.Flow += conclusion.Flow;
|
freCombine.Power += conclusion.Power;
|
freCombine.RunCount++;
|
|
var fre_pump = new AnaFrePump();
|
fre_pump.Flag = item.Key;
|
fre_pump.Flow = conclusion.Flow;
|
fre_pump.Head = target_head;
|
fre_pump.Power = conclusion.Power;
|
fre_pump.Efficiency = Curve.PumpCalculateHelper.CalculateE(fre_pump.Flow, fre_pump.Head, fre_pump.Power);
|
fre_pump.Frequency = freCombine.Frequency;
|
fre_pump.Speed = (double)fre / 50 * pump_nr_dict[item.Key];
|
freCombine.FrePumps.Add(fre_pump);
|
}
|
}
|
if (freCombine.Flags.Count < 1)
|
continue;
|
fre_combine_list_part2.Add(freCombine);
|
}
|
}
|
|
if (fre_combine_list_part1.Count == 0 && fre_combine_list_part2.Count == 0)
|
continue;
|
|
double total_flow_deviation = target_flow;//总流量偏差
|
double total_power = double.MaxValue;//总功率
|
double total_flow = double.MaxValue;//总流量
|
|
AnaFreCombine optimal_combine_part1 = null;
|
AnaFreCombine optimal_combine_part2 = null;
|
if (fre_combine_list_part1.Count < 1 || fre_combine_list_part2.Count < 1)
|
{
|
if (fre_combine_list_part1.Count < 1)
|
{
|
fre_combine_list_part1 = fre_combine_list_part2;
|
}
|
for (int Index_part1 = 0; Index_part1 < fre_combine_list_part1.Count; Index_part1++)
|
{
|
var fre_combine1 = fre_combine_list_part1[Index_part1];
|
var current_flow = fre_combine1.Flow;
|
var current_power = fre_combine1.Power;
|
|
var diff_flow = Math.Abs(current_flow - target_flow);
|
if (diff_flow < total_flow_deviation)
|
{
|
optimal_combine_part1 = fre_combine1;
|
total_power = fre_combine1.Power;
|
total_flow = current_flow;
|
total_flow_deviation = diff_flow;
|
}
|
|
if (diff_flow < target_flow * 0.01 && current_power < total_power)
|
{
|
optimal_combine_part1 = fre_combine1;
|
total_power = fre_combine1.Power;
|
total_flow = current_flow;
|
}
|
}
|
}
|
else
|
{
|
for (int Index_part1 = 0; Index_part1 < fre_combine_list_part1.Count; Index_part1++)
|
{
|
for (int Index_part2 = 0; Index_part2 < fre_combine_list_part2.Count; Index_part2++)
|
{
|
var fre_combine1 = fre_combine_list_part1[Index_part1];
|
var fre_combine2 = fre_combine_list_part2[Index_part2];
|
|
var current_flow = fre_combine1.Flow + fre_combine2.Flow;
|
var current_power = fre_combine1.Power + fre_combine2.Power;
|
|
var diff_flow = Math.Abs(current_flow - target_flow);
|
if (diff_flow < total_flow_deviation)
|
{
|
optimal_combine_part1 = fre_combine1;
|
optimal_combine_part2 = fre_combine2;
|
total_power = fre_combine1.Power + fre_combine2.Power;
|
total_flow = current_flow;
|
total_flow_deviation = diff_flow;
|
}
|
|
if (diff_flow < target_flow * 0.01 && current_power < total_power)
|
{
|
optimal_combine_part1 = fre_combine1;
|
optimal_combine_part2 = fre_combine2;
|
total_power = fre_combine1.Power + fre_combine2.Power;
|
total_flow = current_flow;
|
}
|
|
}
|
}
|
}
|
if (total_flow < target_flow*0.99)
|
continue;
|
|
if (optimal_combine_part1 == null && optimal_combine_part2 == null)
|
continue;
|
|
var total_flow_deviation_ratio = Math.Abs((1 - Math.Abs((total_flow / target_flow))));
|
if (total_flow_deviation_ratio > _sel_opt_flow_deviation_ratio)
|
continue;
|
if (total_flow_deviation_ratio > _sel_opt_reasonable_flow_deviation_ratio)
|
{
|
combine_merit_ratio -= total_flow_deviation_ratio;
|
}
|
|
|
var efficiency = Curve.PumpCalculateHelper.CalculateE(total_flow, target_head, total_power);
|
var wp = Curve.PumpCalculateHelper.CalculateWP(total_power, total_flow);
|
var uwp = Curve.PumpCalculateHelper.CalculateUWP(total_power, total_flow, target_head);
|
|
#region 分析最优组合方案
|
|
var optimal_combine = new AnaOptimalCombine();
|
optimal_combine.Combines = new List<AnaFreCombine>();
|
optimal_combine.Flags = new List<int>();
|
if (optimal_combine_part1 != null)
|
{
|
optimal_combine.Combines.Add(optimal_combine_part1);
|
optimal_combine.Flags.AddRange(optimal_combine_part1.Flags);
|
}
|
if (optimal_combine_part2 != null)
|
{
|
optimal_combine.Combines.Add(optimal_combine_part2);
|
optimal_combine.Flags.AddRange(optimal_combine_part2.Flags);
|
}
|
optimal_combine.Flow = total_flow;
|
optimal_combine.Head = target_head;
|
optimal_combine.Power = total_power;
|
optimal_combine.Efficiency = efficiency;
|
optimal_combine.WP = wp;
|
optimal_combine.UWP = uwp;
|
|
optimal_combine.Flags = optimal_combine.Flags.OrderBy(x => x).ToList();
|
optimal_combine.FlagCount = optimal_combine.Flags.Count;
|
optimal_combine.Remark = IntListHelper.ToString(optimal_combine.Flags);
|
optimal_combine.MeritRatio = combine_merit_ratio;
|
optimal_combine_list.Add(optimal_combine);
|
|
#endregion
|
}
|
}
|
|
if (optimal_combine_list.Count < 1)
|
return default;
|
|
optimal_combine_list = optimal_combine_list.OrderByDescending(x => x.MeritRatio).ToList();
|
var opt = optimal_combine_list.First();
|
opt.Round();
|
return opt;
|
}
|
|
/// <summary>
|
/// 获取组合
|
/// </summary>
|
/// <param name="flags"></param>
|
/// <param name="count"></param>
|
/// <returns></returns>
|
private List<int[]> GetCombineList(List<int> flags, int count)
|
{
|
var combine = IStation.Curve.PermutationAndCombination<int>.GetCombination(flags.ToArray(), count);
|
return combine;
|
}
|
|
|
/// <summary>
|
/// 根据工况计算
|
/// </summary>
|
/// <param name="pumps"></param>
|
/// <param name="flag_rpm_dic"></param>
|
/// <param name="flag_head_dic"></param>
|
/// <param name="target_flow"></param>
|
/// <param name="target_head"></param>
|
/// <returns></returns>
|
public AnaOptimalCombine WorkingCalc(List<Model.Pump> pumps, Dictionary<int, double> flag_rpm_dic, Dictionary<int, double> flag_head_dic, double target_flow, double target_head)
|
{
|
if (pumps == null || !pumps.Any())
|
{
|
return default;
|
}
|
|
if (flag_rpm_dic == null || !flag_rpm_dic.Any())
|
{
|
return default;
|
}
|
target_flow = Math.Round(target_flow, 1);
|
target_head = Math.Round(target_head, 1);
|
|
var freCombine = new AnaFreCombine();
|
freCombine.FrePumps = new List<AnaFrePump>();
|
foreach (var item in flag_rpm_dic)
|
{
|
var pump = pumps.Find(x => x.Flag == item.Key);
|
if (pump == null)
|
continue;
|
var rpm = Math.Round(item.Value, 1);
|
if (rpm == 0)
|
continue;
|
var curveQH = Curve.PumpCalculateHelper.CalculateSimilarQH(pump.CurveQH, pump.Nr, rpm);
|
var curveQP = Curve.PumpCalculateHelper.CalculateSimilarQP(pump.CurveQP, pump.Nr, rpm);
|
|
double flow = 0, head = target_head;
|
if (flag_head_dic != null && flag_head_dic.ContainsKey(pump.Flag))
|
head = flag_head_dic[pump.Flag];
|
|
flow = curveQH.GetInterPointLastX(head) ?? 0;
|
if (flow < 0)
|
continue;
|
|
var fre_pump = new AnaFrePump();
|
fre_pump.Flag = item.Key;
|
fre_pump.Flow = flow;
|
fre_pump.Head = target_head;
|
fre_pump.Power = curveQP.GetFitPointY(flow);
|
fre_pump.Efficiency = Curve.PumpCalculateHelper.CalculateE(fre_pump.Flow, fre_pump.Head, fre_pump.Power);
|
fre_pump.Frequency = rpm;
|
fre_pump.Speed = (double)rpm / 50 * pump.Nr;
|
|
freCombine.FrePumps.Add(fre_pump);
|
freCombine.Flow += flow;
|
freCombine.Power += fre_pump.Power;
|
}
|
|
var total_flow = freCombine.Flow;
|
var total_power = freCombine.Power;
|
var efficiency = Curve.PumpCalculateHelper.CalculateE(total_flow, target_head, total_power);
|
var wp = Curve.PumpCalculateHelper.CalculateWP(total_power, total_flow);
|
var uwp = Curve.PumpCalculateHelper.CalculateUWP(total_power, total_flow, target_head);
|
|
var opt = new AnaOptimalCombine();
|
opt.Combines = new List<AnaFreCombine>() { freCombine };
|
opt.Flags = new List<int>();
|
opt.Flow = total_flow;
|
opt.Head = target_head;
|
opt.Power = total_power;
|
opt.Efficiency = efficiency;
|
opt.WP = wp;
|
opt.UWP = uwp;
|
|
opt.Flags = opt.Flags.OrderBy(x => x).ToList();
|
opt.FlagCount = opt.Flags.Count;
|
opt.Remark = IntListHelper.ToString(opt.Flags);
|
opt.MeritRatio = 1;
|
|
opt.Round();
|
return opt;
|
}
|
|
|
}
|
}
|