using NPOI.Util;
|
using Yw.Geometry;
|
|
namespace Yw.WinFrmUI.Phart
|
{
|
/// <summary>
|
/// 性能计算辅助类
|
/// </summary>
|
public static class PumpCalcHelper
|
{
|
#region 常规计算
|
|
#region 计算扬程
|
|
/// <summary>
|
/// 计算扬程
|
/// </summary>
|
/// <param name="q">瞬时流量 m³/h</param>
|
/// <param name="pr1">进口压力 mpa</param>
|
/// <param name="pr2">出口压力 mpa</param>
|
/// <param name="d1">进口口径 mm</param>
|
/// <param name="d2">出口口径 mm</param>
|
/// <param name="z1">进口标高 m</param>
|
/// <param name="z2">出口标高 m</param>
|
/// <returns>扬程 m</returns>
|
public static double CalculateH(double q, double pr1, double pr2, double d1, double d2, double z1, double z2)
|
{
|
var qa = q / 3600;
|
var pr1a = pr1 * 1000000;
|
var pr2a = pr2 * 1000000;
|
var d1a = d1 / 1000;
|
var d2a = d2 / 1000;
|
var v1 = qa * 4 / (Math.PI * Math.Pow(d1a, 2));
|
var v2 = qa * 4 / (Math.PI * Math.Pow(d2a, 2));
|
var distance = z2 - z1;
|
var pg = Constant.WaterDensity * Constant.g;
|
var g2 = 2 * Constant.g;
|
|
var h = (pr2a / pg - pr1a / pg) + (Math.Pow(v2, 2) / g2 - Math.Pow(v1, 2) / g2) + distance;
|
return h;
|
}
|
|
|
/// <summary>
|
/// 计算 OtherPress (测量扬程= 压差 + 表位差 + 流速)
|
/// </summary>
|
/// <param name="q">流量 m³/h </param>
|
/// <param name="inletPipeDia">进口管径 mm </param>
|
/// <param name="outletPipeDia">出口管径 mm </param>
|
/// <param name="inletElevation">进口标高 mm </param>
|
/// <param name="outletElevation">出口标高 mm </param>
|
/// <returns></returns>
|
public static double CalculateOtherPress(double? q, double? inletPipeDia, double? outletPipeDia, double? inletElevation, double? outletElevation)
|
{
|
if (q == null || q.Value < 0.05)
|
{
|
if (outletElevation == null || inletElevation == null)
|
return 0;
|
return outletElevation.Value - inletElevation.Value;
|
}
|
|
double flow = q.Value;
|
double inPipeV = 0;
|
if (inletPipeDia != null && inletPipeDia.Value > 0.1)
|
{
|
// 流速计算 pipeD =mm,pumpFlow=m3/p
|
inPipeV = Constant.OtherPressCoeff * flow / inletPipeDia.Value / inletPipeDia.Value;
|
}
|
|
double outPipeV = 0;
|
if (outletPipeDia != null && outletPipeDia.Value > 0.1)
|
{
|
// 流速计算 rPipeD =mm,rPumpFlow=m3/p
|
outPipeV = Constant.OtherPressCoeff * flow / outletPipeDia.Value / outletPipeDia.Value;
|
}
|
|
double differV = (outPipeV * outPipeV - inPipeV * inPipeV) / Constant.g / 2.0;
|
|
if (outletElevation == null || inletElevation == null)
|
return differV;
|
|
return differV + outletElevation.Value - inletElevation.Value;
|
}
|
|
#endregion
|
|
#region 计算效率
|
|
/// <summary>
|
/// 计算效率
|
/// </summary>
|
/// <param name="q"> 瞬时流量 m³/h</param>
|
/// <param name="h"> 扬程 m</param>
|
/// <param name="p"> 功率 kw</param>
|
/// <param name="ρ"> 密度 kg/m^3</param>
|
/// <param name="g"> 重力加速度 m/s^2</param>
|
/// <returns>百分数</returns>
|
public static double CalculateE(double q, double h, double p, double ρ, double g)
|
{
|
var qa = q / 3600;
|
var pa = p * 1000;
|
double e = 0;
|
if (pa < 0.1)
|
{
|
return e;
|
}
|
e = ρ * g * qa * h / pa;
|
return Math.Round(e * 100, 2);
|
}
|
|
/// <summary>
|
/// 计算效率
|
/// </summary>
|
/// <param name="q"> 瞬时流量 m³/h</param>
|
/// <param name="h"> 扬程 m</param>
|
/// <param name="p"> 功率 kw</param>
|
/// <returns>百分数</returns>
|
public static double CalculateE(double q, double h, double p)
|
{
|
return CalculateE(q, h, p, Constant.WaterDensity, Constant.g);
|
}
|
|
/// <summary>
|
/// 计算效率
|
/// </summary>
|
/// <param name="q"> 瞬时流量 m³/h</param>
|
/// <param name="h"> 扬程 m</param>
|
/// <param name="p"> 功率 kw</param>
|
/// <param name="ρ"> 密度 kg/m^3</param>
|
/// <returns>百分数</returns>
|
public static double CalculateE(double q, double h, double p, double ρ)
|
{
|
return CalculateE(q, h, p, ρ, Constant.g);
|
}
|
|
#endregion
|
|
#region 计算功率
|
|
/// <summary>
|
/// 计算功率
|
/// </summary>
|
/// <param name="q">瞬时流量 m³/h</param>
|
/// <param name="h">扬程 m</param>
|
/// <param name="e">效率 百分数</param>
|
/// <param name="ρ">密度kg/m³</param>
|
/// <param name="g">重力加速度 m/s²</param>
|
/// <returns>kw</returns>
|
public static double CalculateP(double q, double h, double e, double ρ, double g)
|
{
|
var qa = q / 3600;
|
var ea = e / 100;
|
double p = 0;
|
if (ea < 0.01)
|
{
|
return p;
|
}
|
p = ρ * g * qa * h / ea;
|
p = p / 1000;//换算成kw
|
if (p < 2)
|
{
|
return Math.Round(p, 4);
|
}
|
if (p < 30)
|
{
|
return Math.Round(p, 3);
|
}
|
if (p < 100)
|
{
|
return Math.Round(p, 2);
|
}
|
return Math.Round(p, 1);
|
|
}
|
|
/// <summary>
|
/// 计算功率
|
/// </summary>
|
/// <param name="q">瞬时流量 m³/h</param>
|
/// <param name="h">扬程 m</param>
|
/// <param name="e">效率 百分数</param>
|
/// <param name="ρ">密度kg/m³</param>
|
/// <returns>kw</returns>
|
public static double CalculateP(double q, double h, double e, double ρ)
|
{
|
return CalculateP(q, h, e, ρ, Constant.g);
|
}
|
|
/// <summary>
|
/// 计算功率
|
/// </summary>
|
/// <param name="q">瞬时流量 m³/h</param>
|
/// <param name="h">扬程 m</param>
|
/// <param name="e">效率 百分数</param>
|
/// <returns>kw</returns>
|
public static double CalculateP(double q, double h, double e)
|
{
|
return CalculateP(q, h, e, Constant.WaterDensity, Constant.g);
|
}
|
|
#endregion
|
|
#region Mpa<=>m
|
|
/// <summary>
|
/// Mpa=>m
|
/// </summary>
|
public static double Mpa2M(double mpa)
|
{
|
return mpa * Constant.WaterDensity / Constant.g;
|
}
|
|
/// <summary>
|
/// m=>Mpa
|
/// </summary>
|
public static double M2Mpa(double m)
|
{
|
return m * Constant.g / Constant.WaterDensity;
|
}
|
|
|
#endregion
|
|
#region 计算用电量
|
|
/// <summary>
|
/// 计算用电量
|
/// </summary>
|
/// <param name="p">功率kw</param>
|
/// <param name="t">时间h</param>
|
/// <returns>kw*h</returns>
|
public static double CalculateD(double p, double t)
|
{
|
return p * t;
|
}
|
|
#endregion
|
|
#region 计算累积流量
|
|
/// <summary>
|
/// 计算累积流量
|
/// </summary>
|
/// <param name="q">瞬时流量m³/h</param>
|
/// <param name="t">时间h</param>
|
/// <returns>m³</returns>
|
public static double CalculateQt(double q, double t)
|
{
|
return q * t;
|
}
|
|
#endregion
|
|
#region 计算能耗
|
|
/// <summary>
|
/// 计算千吨能耗
|
/// </summary>
|
/// <param name="p">功率kW</param>
|
/// <param name="q">瞬时流量m³/h</param>
|
/// <returns>kW·h/km³</returns>
|
public static double CalculateWP(double p, double q)
|
{
|
if (q < 0.1)
|
{
|
return default;
|
}
|
return p / q * 1000;
|
}
|
|
/// <summary>
|
/// 计算单位能耗
|
/// </summary>
|
/// <param name="p">功率kW</param>
|
/// <param name="q">瞬时流量m³/h</param>
|
/// <param name="h">扬程m</param>
|
/// <returns>kW·h/km³</returns>
|
public static double CalculateUWP(double p, double q, double h)
|
{
|
if (q < 0.1)
|
{
|
return default;
|
}
|
if (h < 0.1)
|
{
|
return default;
|
}
|
return p / q / h * 1000;
|
}
|
|
#endregion
|
|
#region 频率换算
|
|
/// <summary>
|
/// 根据频率计算流量
|
/// </summary>
|
/// <param name="q">瞬时流量 m³/h</param>
|
/// <param name="hz">频率</param>
|
/// <param name="hzr">额定频率</param>
|
/// <returns></returns>
|
public static double CalculateQByHz(double q, double hz, double hzr = 50)
|
{
|
if (hzr < 0.1)
|
{
|
return q;
|
}
|
if (hz < 0.1)
|
{
|
return q;
|
}
|
/* if (hz > hzr)
|
{
|
return q;
|
}*/
|
double f_ratio = hzr / hz;
|
|
return q * f_ratio;
|
}
|
|
/// <summary>
|
/// 根据频率计算扬程
|
/// </summary>
|
/// <param name="h">扬程 m</param>
|
/// <param name="hz">频率 </param>
|
/// <param name="hzr">额定频率</param>
|
/// <returns></returns>
|
public static double CalculateHByHz(double h, double hz, double hzr = 50)
|
{
|
if (hzr < 0.1)
|
{
|
return h;
|
}
|
if (hz < 0.1)
|
{
|
return h;
|
}
|
/* if (hz > hzr)
|
{
|
return h;
|
}*/
|
double f_ratio = hzr / hz;
|
return h * f_ratio * f_ratio;
|
}
|
|
/// <summary>
|
/// 根据频率计算 50hz功率
|
/// </summary>
|
/// <param name="p">功率 kw</param>
|
/// <param name="hz">频率 kw</param>
|
/// <param name="hzr">额定频率</param>
|
/// <returns></returns>
|
public static double CalculatePByHz(double p, double hz, double hzr = 50)
|
{
|
if (hzr < 0.1)
|
{
|
return p;
|
}
|
if (hz < 0.1)
|
{
|
return p;
|
}
|
/* if (hz > hzr)
|
{
|
return p;
|
}*/
|
double f_ratio = hzr / hz;
|
return p * f_ratio * f_ratio * f_ratio;
|
}
|
|
/// <summary>
|
/// 根据转速计算流量
|
/// </summary>
|
/// <param name="q">瞬时流量 m³/h</param>
|
/// <param name="n">转速 r/min</param>
|
/// <param name="nr">额定转速 r/min</param>
|
/// <returns></returns>
|
public static double CalculateQByN(double q, double n, double nr)
|
{
|
if (nr < 0.1)
|
{
|
return q;
|
}
|
if (n < 0.1)
|
{
|
return q;
|
}
|
double f_ratio = nr / n;
|
|
return q * f_ratio;
|
}
|
|
/// <summary>
|
/// 根据转速计算扬程
|
/// </summary>
|
/// <param name="h">扬程 m</param>
|
/// <param name="n">转速 r/min</param>
|
/// <param name="nr">额定转速 r/min</param>
|
/// <returns></returns>
|
public static double CalculateHByN(double h, double n, double nr)
|
{
|
if (nr < 0.1)
|
{
|
return h;
|
}
|
if (n < 0.1)
|
{
|
return h;
|
}
|
double f_ratio = nr / n;
|
|
return h * f_ratio * f_ratio;
|
}
|
|
/// <summary>
|
/// 根据转速计算功率
|
/// </summary>
|
/// <param name="p">功率 kw</param>
|
/// <param name="n">转速 r/min</param>
|
/// <param name="nr">额定转速 r/min</param>
|
/// <returns></returns>
|
public static double CalculatePByN(double p, double n, double nr)
|
{
|
if (nr < 0.1)
|
{
|
return p;
|
}
|
if (n < 0.1)
|
{
|
return p;
|
}
|
double f_ratio = nr / n;
|
|
return p * f_ratio * f_ratio * f_ratio;
|
}
|
|
#endregion
|
|
|
#endregion
|
|
#region 复杂计算
|
|
#region Simu
|
|
/// <summary>
|
/// 知道原始速度,以及原始的杨程H以及对应的变速后的杨程,求变速后的速度
|
/// </summary>
|
/// <param name="origin_"></param>
|
/// <param name="origin_h"></param>
|
/// <param name="change_h"></param>
|
/// <returns></returns>
|
public static double CalculateSimuByH(double origin_, double origin_h, double change_h)
|
{
|
double ratio = Math.Pow(origin_h / change_h, 1.0 / 2.0);
|
return origin_ / ratio;
|
}
|
|
/// <summary>
|
/// 知道原始速度,以及原始的流量Q以及对应的变速后的杨程,求变速后的速度
|
/// </summary>
|
/// <param name="origin_"></param>
|
/// <param name="origin_q"></param>
|
/// <param name="change_q"></param>
|
/// <returns></returns>
|
public static double CalculateSimuByQ(double origin_, double origin_q, double change_q)
|
{
|
double ratio = origin_q / change_q;
|
return origin_ / ratio;
|
}
|
#endregion
|
|
#region 相似换算
|
|
/// <summary>
|
/// 计算相似流量扬程曲线
|
/// </summary>
|
/// <param name="cubic_spline">三次样条曲线</param>
|
/// <param name="origin_hz">原始频率</param>
|
/// <param name="change_hz">换算频率</param>
|
/// <param name="point_count">拟合点数量</param>
|
/// <returns></returns>
|
public static Yw.Geometry.CubicSpline2d CalculateSimilarQH(Yw.Geometry.CubicSpline2d cubic_spline, double origin_hz, double change_hz, int point_count = 12)
|
{
|
if (cubic_spline == null)
|
return null;
|
if (change_hz < 1)
|
return null;
|
|
var fit_points = cubic_spline.GetPointList(point_count);
|
var ratio = change_hz / origin_hz;
|
var similar_pt_list = new List<Yw.Geometry.Point2d>();
|
foreach (Yw.Geometry.Point2d fit_point in fit_points)
|
{
|
var similar_point = new Yw.Geometry.Point2d();
|
similar_point.X = fit_point.X * ratio;
|
similar_point.Y = fit_point.Y * ratio * ratio;
|
similar_pt_list.Add(similar_point);
|
}
|
|
return new Yw.Geometry.CubicSpline2d(similar_pt_list);
|
}
|
|
/// <summary>
|
/// 计算相似流量功率曲线
|
/// </summary>
|
/// <param name="cubic_spline">三次样条曲线</param>
|
/// <param name="origin_hz">原始频率</param>
|
/// <param name="change_hz">换算频率</param>
|
/// <param name="point_count">拟合点数量</param>
|
/// <returns></returns>
|
public static Yw.Geometry.CubicSpline2d CalculateSimilarQP(Yw.Geometry.CubicSpline2d cubic_spline, double origin_hz, double change_hz, int point_count = 12)
|
{
|
if (cubic_spline == null)
|
return null;
|
if (change_hz < 1)
|
return null;
|
|
var fit_points = cubic_spline.GetPointList(point_count);
|
var ratio = change_hz / origin_hz;
|
var similar_pt_list = new List<Yw.Geometry.Point2d>();
|
foreach (Yw.Geometry.Point2d fit_point in fit_points)
|
{
|
var similar_point = new Yw.Geometry.Point2d();
|
similar_point.X = fit_point.X * ratio;
|
similar_point.Y = fit_point.Y * ratio * ratio * ratio;
|
similar_pt_list.Add(similar_point);
|
}
|
|
return new Yw.Geometry.CubicSpline2d(similar_pt_list);
|
}
|
|
/// <summary>
|
/// 计算相似流量效率曲线
|
/// </summary>
|
/// <param name="cubic_spline">三次样条曲线</param>
|
/// <param name="origin_hz">原始频率</param>
|
/// <param name="change_hz">换算频率</param>
|
/// <param name="point_count">拟合点数量</param>
|
/// <returns></returns>
|
public static Yw.Geometry.CubicSpline2d CalculateSimilarQE(Yw.Geometry.CubicSpline2d cubic_spline, double origin_hz, double change_hz, int point_count = 12)
|
{
|
if (cubic_spline == null)
|
return null;
|
if (change_hz < 1)
|
return null;
|
|
var fit_points = cubic_spline.GetPointList(point_count);
|
var ratio = change_hz / origin_hz;
|
var similar_pt_list = new List<Yw.Geometry.Point2d>();
|
foreach (Yw.Geometry.Point2d fit_point in fit_points)
|
{
|
var similar_point = new Yw.Geometry.Point2d();
|
similar_point.X = fit_point.X * ratio;
|
similar_point.Y = fit_point.Y;
|
similar_pt_list.Add(similar_point);
|
}
|
return new Yw.Geometry.CubicSpline2d(similar_pt_list);
|
}
|
|
/// <summary>
|
/// 计算相似流量扬程曲线点
|
/// </summary>
|
/// <param name="fit_points">曲线点</param>
|
/// <param name="origin_hz">原始频率</param>
|
/// <param name="change_hz">换算频率</param>
|
/// <param name="point_count">拟合点数量</param>
|
/// <returns></returns>
|
public static List<Yw.Geometry.Point2d> CalculateSimilarQH(List<Yw.Geometry.Point2d> fit_points, double origin_hz, double change_hz)
|
{
|
if (fit_points == null || !fit_points.Any())
|
return null;
|
if (change_hz < 1)
|
return null;
|
|
var ratio = change_hz / origin_hz;
|
var similar_pt_list = new List<Yw.Geometry.Point2d>();
|
foreach (Yw.Geometry.Point2d fit_point in fit_points)
|
{
|
var similar_point = new Yw.Geometry.Point2d();
|
similar_point.X = fit_point.X * ratio;
|
similar_point.Y = fit_point.Y * ratio * ratio;
|
similar_pt_list.Add(similar_point);
|
}
|
return similar_pt_list;
|
}
|
|
/// <summary>
|
/// 计算相似流量功率曲线点
|
/// </summary>
|
/// <param name="fit_points">曲线点</param>
|
/// <param name="origin_hz">原始频率</param>
|
/// <param name="change_hz">换算频率</param>
|
/// <param name="point_count">拟合点数量</param>
|
/// <returns></returns>
|
public static List<Yw.Geometry.Point2d> CalculateSimilarQP(List<Yw.Geometry.Point2d> fit_points, double origin_hz, double change_hz)
|
{
|
if (fit_points == null || !fit_points.Any())
|
return null;
|
if (change_hz < 1)
|
return null;
|
|
var ratio = change_hz / origin_hz;
|
var similar_pt_list = new List<Yw.Geometry.Point2d>();
|
foreach (Yw.Geometry.Point2d fit_point in fit_points)
|
{
|
var similar_point = new Yw.Geometry.Point2d();
|
similar_point.X = fit_point.X * ratio;
|
similar_point.Y = fit_point.Y * ratio * ratio * ratio;
|
similar_pt_list.Add(similar_point);
|
}
|
return similar_pt_list;
|
}
|
|
/// <summary>
|
/// 计算相似流量效率曲线点
|
/// </summary>
|
/// <param name="fit_points">曲线点</param>
|
/// <param name="origin_hz">原始频率</param>
|
/// <param name="change_hz">换算频率</param>
|
/// <param name="point_count">拟合点数量</param>
|
/// <returns></returns>
|
public static List<Yw.Geometry.Point2d> CalculateSimilarQE(List<Yw.Geometry.Point2d> fit_points, double origin_hz, double change_hz)
|
{
|
if (fit_points == null || !fit_points.Any())
|
return null;
|
if (change_hz < 1)
|
return null;
|
|
var ratio = change_hz / origin_hz;
|
var similar_pt_list = new List<Yw.Geometry.Point2d>();
|
foreach (Yw.Geometry.Point2d fit_point in fit_points)
|
{
|
var similar_point = new Yw.Geometry.Point2d();
|
similar_point.X = fit_point.X * ratio;
|
similar_point.Y = fit_point.Y;
|
similar_pt_list.Add(similar_point);
|
}
|
return similar_pt_list;
|
}
|
|
|
/// <summary>
|
/// 计算相似流量扬程点
|
/// </summary>
|
/// <param name="fit_point">点</param>
|
/// <param name="origin_hz">原始频率</param>
|
/// <param name="change_hz">换算频率</param>
|
/// <returns></returns>
|
public static Yw.Geometry.Point2d CalculateSimilarQH(Yw.Geometry.Point2d fit_point, double origin_hz, double change_hz)
|
{
|
if (fit_point == null)
|
return null;
|
if (change_hz < 1)
|
return null;
|
var ratio = change_hz / origin_hz;
|
var similar_point = new Yw.Geometry.Point2d();
|
similar_point.X = fit_point.X * ratio;
|
similar_point.Y = fit_point.Y * ratio * ratio;
|
return similar_point;
|
}
|
|
/// <summary>
|
/// 计算相似流量功率点
|
/// </summary>
|
/// <param name="fit_point">点</param>
|
/// <param name="origin_hz">原始频率</param>
|
/// <param name="change_hz">换算频率</param>
|
/// <returns></returns>
|
public static Yw.Geometry.Point2d CalculateSimilarQP(Yw.Geometry.Point2d fit_point, double origin_hz, double change_hz)
|
{
|
if (fit_point == null)
|
return null;
|
if (change_hz < 1)
|
return null;
|
var ratio = change_hz / origin_hz;
|
var similar_point = new Yw.Geometry.Point2d();
|
similar_point.X = fit_point.X * ratio;
|
similar_point.Y = fit_point.Y * ratio * ratio * ratio;
|
return similar_point;
|
}
|
|
/// <summary>
|
/// 计算相似流量效率点
|
/// </summary>
|
/// <param name="fit_point">点</param>
|
/// <param name="origin_hz">原始频率</param>
|
/// <param name="change_hz">换算频率</param>
|
/// <returns></returns>
|
public static Yw.Geometry.Point2d CalculateSimilarQE(Yw.Geometry.Point2d fit_point, double origin_hz, double change_hz)
|
{
|
if (fit_point == null)
|
return null;
|
if (change_hz < 1)
|
return null;
|
var ratio = change_hz / origin_hz;
|
var similar_point = new Yw.Geometry.Point2d();
|
similar_point.X = fit_point.X * ratio;
|
similar_point.Y = fit_point.Y;
|
|
return similar_point;
|
}
|
|
|
#endregion
|
|
#region 计算推荐参数
|
|
public enum eCalculatePumpType
|
{
|
单级单吸离心泵 = 1,
|
多级离心泵 = 2,
|
双吸离心泵 = 3,
|
化工泵 = 4,
|
渣浆泵 = 5,
|
长轴泵 = 6
|
}
|
|
//capacity
|
static double[] effq = new double[33] { 5, 10, 15, 20, 25, 30, 40, 50, 60, 70, 80, 90, 100, 150, 200, 300, 400, 500, 600, 700, 800, 900, 1000, 1500, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000 };
|
//1 single stage seriesEntity eff
|
static double[] singleeff = new double[33] { 58.0, 64.0, 67.2, 69.4, 70.9, 72.0, 73.8, 74.9, 75.8, 76.5, 77.0, 77.6, 78.0, 79.8, 80.8, 82.0, 83.0, 83.7, 84.2, 84.7, 85.0, 85.3, 85.7, 86.6, 87.2, 88.0, 88.6, 89.0, 89.2, 89.5, 89.7, 89.9, 90.0 };
|
//2 multi stage seriesEntity eff
|
static double[] multieff = new double[26] { 55.4, 59.4, 61.8, 63.5, 64.8, 65.9, 67.5, 68.9, 69.9, 70.9, 71.5, 72.3, 72.9, 75.3, 76.9, 79.2, 80.6, 81.5, 82.2, 82.8, 83.1, 83.5, 83.9, 84.8, 85.1, 85.5 };
|
//1 correct eff
|
static double[] effcorrect1 = new double[19] { 32, 25.5, 20.6, 17.3, 14.7, 12.5, 10.5, 9.0, 7.5, 6.0, 5.0, 4.0, 3.2, 2.5, 2.0, 1.5, 1.0, 0.5, 0 };
|
//2 correct eff
|
static double[] effcorrect2 = new double[10] { 0, 0.3, 0.7, 1.0, 1.3, 1.7, 1.9, 2.2, 2.7, 3.0 };
|
static double[] effns1 = new double[19] { 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, 100, 110, 120 };
|
static double[] effns2 = new double[10] { 210, 220, 230, 240, 250, 260, 270, 280, 290, 300 };
|
|
|
/// <summary>
|
/// 根据泵类型计算推荐效率
|
/// </summary>
|
/// <param name="q">流量</param>
|
/// <param name="h">扬程</param>
|
/// <param name="n">转速</param>
|
/// <param name="pumpType">泵类型<see cref="eCalculatePumpType" /></param>
|
/// <returns></returns>
|
public static double CalculateEByPumpType(double q, double h, double n, int pumpType)
|
{
|
double ns = CalculateNs(q, h, n);
|
|
double eff, qjs1, qjs2, qjs3, effjs1, effjs2, effjs3, correct = 1;
|
int i = 0;
|
double dltE = 0.0;
|
|
double q0 = q;
|
double h0 = h;
|
|
//
|
double t = 1000;
|
if (pumpType == (int)eCalculatePumpType.单级单吸离心泵)
|
t = 10000;
|
if (pumpType == (int)eCalculatePumpType.多级离心泵)
|
t = 300000;
|
if (pumpType == (int)eCalculatePumpType.双吸离心泵)
|
t = 10000;
|
if (pumpType == (int)eCalculatePumpType.化工泵)
|
t = 10000;
|
if (pumpType == (int)eCalculatePumpType.渣浆泵)
|
t = 10000;
|
if (pumpType == (int)eCalculatePumpType.长轴泵)
|
t = 10000;
|
if (q0 > t)
|
{
|
i = effq.Length - 1;
|
}
|
else if (q0 >= 1.5 && q0 <= t)
|
{
|
i = 0;
|
for (i = 0; effq[i] <= q0; i++)
|
{
|
if (i + 1 == effq.Count())
|
{
|
break;
|
}
|
}
|
}
|
else
|
{
|
return -1;
|
}
|
if (i >= effq.Length)
|
i = effq.Length - 1;
|
|
if (q0 >= 10)
|
{
|
qjs1 = effq[i];
|
qjs2 = effq[i - 1];
|
qjs3 = effq[i - 2];
|
switch (pumpType)
|
{
|
case 1:
|
if (i >= singleeff.Length)
|
i = singleeff.Length - 1;
|
effjs1 = singleeff[i];
|
effjs2 = singleeff[i - 1];
|
effjs3 = singleeff[i - 2];
|
break;
|
case 2:
|
if (i >= multieff.Length)
|
i = multieff.Length - 1;
|
effjs1 = multieff[i];
|
effjs2 = multieff[i - 1];
|
effjs3 = multieff[i - 2];
|
break;
|
case 3:
|
if (i >= singleeff.Length)
|
i = singleeff.Length - 1;
|
effjs1 = singleeff[i];
|
effjs2 = singleeff[i - 1];
|
effjs3 = singleeff[i - 2];
|
dltE = -2;
|
break;
|
case 4:
|
if (i >= singleeff.Length)
|
i = singleeff.Length - 1;
|
effjs1 = singleeff[i];
|
effjs2 = singleeff[i - 1];
|
effjs3 = singleeff[i - 2];
|
dltE = 5;
|
break;
|
case 5:
|
effjs1 = singleeff[i];
|
effjs2 = singleeff[i - 1];
|
effjs3 = singleeff[i - 2];
|
dltE = 8;
|
break;
|
default:
|
effjs1 = singleeff[i];
|
effjs2 = singleeff[i - 1];
|
effjs3 = singleeff[i - 2];
|
dltE = 3.5;
|
break;
|
}
|
}
|
else
|
{
|
qjs1 = effq[2];
|
qjs2 = effq[1];
|
qjs3 = effq[0];
|
switch (pumpType)
|
{
|
case 1:
|
effjs1 = singleeff[2];
|
effjs2 = singleeff[1];
|
effjs3 = singleeff[0];
|
break;
|
case 2:
|
effjs1 = multieff[2];
|
effjs2 = multieff[1];
|
effjs3 = multieff[0];
|
break;
|
case 3:
|
effjs1 = singleeff[2];
|
effjs2 = singleeff[1];
|
effjs3 = singleeff[0];
|
dltE = -2;
|
break;
|
case 4:
|
effjs1 = singleeff[2];
|
effjs2 = singleeff[1];
|
effjs3 = singleeff[0];
|
dltE = 5;
|
break;
|
case 5:
|
effjs1 = singleeff[2];
|
effjs2 = singleeff[1];
|
effjs3 = singleeff[0];
|
dltE = 8;
|
break;
|
default:
|
effjs1 = singleeff[2];
|
effjs2 = singleeff[1];
|
effjs3 = singleeff[0];
|
dltE = 3.5;
|
break;
|
}
|
}
|
|
eff = (q0 - qjs2) * (q0 - qjs3) * effjs1 / ((qjs1 - qjs2) * (qjs1 - qjs3)) +
|
(q0 - qjs1) * (q0 - qjs3) * effjs2 / ((qjs2 - qjs1) * (qjs2 - qjs3)) +
|
(q0 - qjs1) * (q0 - qjs2) * effjs3 / ((qjs3 - qjs1) * (qjs3 - qjs2)) - dltE;
|
|
if ((ns < 120 && ns >= 20) || (ns < 300 && ns > 210))
|
{
|
if (ns < 120 && ns >= 20)
|
{
|
for (i = 0; effns1[i] <= ns; i++)
|
{
|
}
|
if (ns >= 25)
|
{
|
qjs1 = effns1[i];
|
qjs2 = effns1[i - 1];
|
qjs3 = effns1[i - 2];
|
effjs1 = effcorrect1[i];
|
effjs2 = effcorrect1[i - 1];
|
effjs3 = effcorrect1[i - 2];
|
}
|
else
|
{
|
qjs1 = effns1[i + 1];
|
qjs2 = effns1[i];
|
qjs3 = effns1[i - 1];
|
effjs1 = effcorrect1[i + 1];
|
effjs2 = effcorrect1[i];
|
effjs3 = effcorrect1[i - 1];
|
}
|
}
|
if (ns < 300 && ns > 210)
|
{
|
for (i = 0; effns2[i] <= ns; i++)
|
{
|
}
|
if (ns >= 220)
|
{
|
qjs1 = effns2[i];
|
qjs2 = effns2[i - 1];
|
qjs3 = effns2[i - 2];
|
effjs1 = effcorrect2[i];
|
effjs2 = effcorrect2[i - 1];
|
effjs3 = effcorrect2[i - 2];
|
}
|
else
|
{
|
qjs1 = effns2[i + 1];
|
qjs2 = effns2[i];
|
qjs3 = effns2[i - 1];
|
effjs1 = effcorrect2[i + 1];
|
effjs2 = effcorrect2[i];
|
effjs3 = effcorrect2[i - 1];
|
}
|
}
|
correct = (ns - qjs2) * (ns - qjs3) * effjs1 / ((qjs1 - qjs2) * (qjs1 - qjs3)) +
|
(ns - qjs1) * (ns - qjs3) * effjs2 / ((qjs2 - qjs1) * (qjs2 - qjs3)) +
|
(ns - qjs1) * (ns - qjs2) * effjs3 / ((qjs3 - qjs1) * (qjs3 - qjs2));
|
}
|
if (ns >= 300)
|
correct = 3.0;
|
if (ns < 20)
|
correct = 32.0;
|
if (ns >= 120 && ns <= 210)
|
correct = 0;
|
eff = eff - correct;
|
|
return eff;
|
}
|
|
//计算推荐NPSHr
|
public static double CalculateNPSHrByPumpType(double Q, double H, double n, int iPumpType)
|
{
|
double ns = CalculateNs(Q, H, n);
|
double S_Q = 10;
|
if (iPumpType == 3)
|
S_Q = Q / 2;
|
else
|
S_Q = Q;
|
|
double K = Math.Pow(ns, 1.3333) * 216 / 1000000;
|
return K * H;
|
}
|
|
#endregion
|
|
#region 计算比转速度
|
|
public static double CalculateNs(double Q, double H, double n)
|
{
|
return 3.65 * n * Math.Sqrt(Q / 3600) / Math.Pow(H, 0.75);
|
}
|
|
public static decimal CalculateNs(decimal Q, decimal H, decimal n)
|
{
|
return Convert.ToDecimal(3.65 * Convert.ToDouble(n) * Math.Sqrt(Convert.ToDouble(Q) / 3600) / Math.Pow(Convert.ToDouble(H), 0.75));
|
}
|
|
#endregion
|
|
#region 计算功率
|
|
/// <summary>
|
/// 计算功率
|
/// </summary>
|
/// <param name="qh_pt_list">流量扬程点</param>
|
/// <param name="qe_pt_list">流量效率点</param>
|
/// <returns>流量功率点</returns>
|
public static List<Yw.Geometry.Point2d> CalculateP(List<Yw.Geometry.Point2d> qh_pt_list, List<Yw.Geometry.Point2d> qe_pt_list)
|
{
|
if (qh_pt_list == null || qh_pt_list.Count() <= 2)
|
return null;
|
bool is_x_start_0 = qh_pt_list.First().X > 500 || qh_pt_list.First().X > qh_pt_list.Last().X * 0.2;
|
return CalculateP(qh_pt_list, qe_pt_list, Constant.WaterDensity, -1, is_x_start_0);
|
}
|
|
/// <summary>
|
/// 计算功率
|
/// </summary>
|
/// <param name="qh_pt_list">流量扬程点</param>
|
/// <param name="qe_pt_list">流量效率点</param>
|
/// <param name="midu">水的密度</param>
|
/// <param name="zeroPower">流量为0时的功率</param>
|
/// <param name="is_x_start_0">流量是否为0</param>
|
/// <returns></returns>
|
public static List<Yw.Geometry.Point2d> CalculateP(
|
List<Yw.Geometry.Point2d> qh_pt_list,
|
List<Yw.Geometry.Point2d> qe_pt_list,
|
double midu,
|
double zeroPower,
|
bool is_x_start_0)
|
{
|
if (qh_pt_list == null || qh_pt_list.Count < 3)
|
return null;
|
if (qe_pt_list == null || qe_pt_list.Count < 3)
|
return null;
|
|
var curve_qh = new Yw.Geometry.CubicSpline2d(qh_pt_list);
|
var curve_qe = new Yw.Geometry.CubicSpline2d(qe_pt_list);
|
|
var qp = CalculateP(curve_qh, curve_qe, midu, zeroPower, is_x_start_0);
|
return qp.GetPointList(qe_pt_list.Count());
|
}
|
|
/// <summary>
|
/// 计算功率
|
/// </summary>
|
/// <param name="fitQP">流量功率线拟合方式</param>
|
/// <param name="curve_qh">流量扬程线</param>
|
/// <param name="curve_qe">流量效率线</param>
|
/// <param name="midu">水的密度</param>
|
/// <param name="zeroPower">流量为0时的功率</param>
|
/// <param name="is_x_start_0">流量是否为0</param>
|
/// <returns></returns>
|
public static Yw.Geometry.CubicSpline2d CalculateP(Yw.Geometry.CubicSpline2d curve_qh, Yw.Geometry.CubicSpline2d curve_qe, double midu, double zeroPower, bool is_x_start_0)
|
{
|
if (curve_qh == null || curve_qe == null)
|
return null;
|
int point_count = 16;//点不能太多
|
var qh_pt_list = curve_qh.GetPointList(point_count);
|
if (qh_pt_list == null || qh_pt_list.Count < 3)
|
return null;
|
var qe_pt_list = curve_qe.GetPointList(point_count);
|
if (qe_pt_list == null || qe_pt_list.Count < 3)
|
return null;
|
|
List<Yw.Geometry.Point2d> qp_pt_list = new List<Yw.Geometry.Point2d>();
|
//间距
|
double min_flow = Math.Max(qh_pt_list.First().X, qe_pt_list.First().X);
|
double max_flow = Math.Min(qh_pt_list.Last().X, qe_pt_list.Last().X);
|
|
//
|
double Q, H, E, P;
|
double space = (max_flow - min_flow) / (point_count - 1);
|
|
//保证从0开始: 保证Q=0时,P不是计算出来的;
|
if (is_x_start_0)
|
{
|
for (int i = 5; i < point_count; i++)//前面几个点不要
|
{
|
Q = qe_pt_list.First().X + space * i;
|
E = curve_qe.GetPointY(Q);
|
H = curve_qh.GetPointY(Q);
|
if (H < 0.1 || E < 0.5)
|
continue;
|
|
P = CalculateP(Q, H, E, midu);
|
if (P < 2)
|
{
|
P = Math.Round(P, 3);
|
}
|
else if (P < 30)
|
{
|
P = Math.Round(P, 2);
|
}
|
else if (P < 100)
|
{
|
P = Math.Round(P, 1);
|
}
|
else
|
{
|
P = Math.Round(P, 0);
|
}
|
qp_pt_list.Add(new Yw.Geometry.Point2d(Q, P));
|
}
|
|
|
qp_pt_list = qp_pt_list.GetFitPointList(point_count);
|
if (qp_pt_list == null)
|
return null;
|
|
|
if (zeroPower > 0.1)
|
{
|
qp_pt_list.Insert(0, new Yw.Geometry.Point2d(0, zeroPower));
|
}
|
else
|
{
|
if (qp_pt_list[0].Y >= qp_pt_list[1].Y)
|
{
|
qp_pt_list[0].Y = qp_pt_list[1].Y * 0.95;
|
}
|
double startP = Yw.Geometry.LineHelper.GetYbyX(qp_pt_list[0].X, qp_pt_list[0].Y, qp_pt_list[1].X, qp_pt_list[1].Y, 0);
|
if (startP < 0.001)
|
startP = qp_pt_list[0].Y;
|
|
if (startP < 2)
|
{
|
startP = Math.Round(startP, 3);
|
}
|
else if (startP < 30)
|
{
|
startP = Math.Round(startP, 2);
|
}
|
else if (startP < 100)
|
{
|
startP = Math.Round(startP, 1);
|
}
|
else
|
{
|
startP = Math.Round(startP, 0);
|
}
|
|
qp_pt_list.Insert(0, new Yw.Geometry.Point2d(0, startP));
|
}
|
|
|
return new Yw.Geometry.CubicSpline2d(qp_pt_list);
|
}
|
else
|
{
|
for (int i = 0; i < point_count; i++)//前面几个点不要
|
{
|
Q = qe_pt_list.First().X + space * i;
|
E = curve_qe.GetPointY(Q);
|
H = curve_qh.GetPointY(Q);
|
if (H < 0.1 || E < 0.5)
|
continue;
|
|
P = CalculateP(Q, H, E, midu);
|
if (P < 2)
|
{
|
P = Math.Round(P, 3);
|
}
|
else if (P < 30)
|
{
|
P = Math.Round(P, 2);
|
}
|
else if (P < 100)
|
{
|
P = Math.Round(P, 1);
|
}
|
else
|
{
|
P = Math.Round(P, 0);
|
}
|
qp_pt_list.Add(new Yw.Geometry.Point2d(Q, P));
|
}
|
|
qp_pt_list = qp_pt_list.GetFitPointList(point_count);
|
if (qp_pt_list == null)
|
return null;
|
|
return new Yw.Geometry.CubicSpline2d(qp_pt_list);
|
|
}
|
}
|
|
#endregion
|
|
#region 计算效率
|
|
public static Yw.Geometry.CubicSpline2d CalculateE(Yw.Geometry.CubicSpline2d qh, Yw.Geometry.CubicSpline2d qp)
|
{
|
return CalculateE(qh, qp, Constant.WaterDensity);
|
}
|
|
public static Yw.Geometry.CubicSpline2d CalculateE(Yw.Geometry.CubicSpline2d qh, Yw.Geometry.CubicSpline2d qp, bool is_x_start_0)
|
{
|
return CalculateE(qh, qp, Constant.WaterDensity, is_x_start_0);
|
}
|
|
public static Yw.Geometry.CubicSpline2d CalculateE(Yw.Geometry.CubicSpline2d qh, Yw.Geometry.CubicSpline2d qp, double midu)
|
{
|
if (qh == null)
|
return null;
|
|
bool is_x_start_0 = true;
|
if (qh.MinX > 500 || qh.MinX > qh.MaxX * 0.1)
|
{
|
is_x_start_0 = false;
|
}
|
else
|
{
|
is_x_start_0 = true;
|
}
|
|
return CalculateE(qh, qp, midu, is_x_start_0);
|
}
|
|
public static Yw.Geometry.CubicSpline2d CalculateE(Yw.Geometry.CubicSpline2d qh, Yw.Geometry.CubicSpline2d qp, double midu, bool is_x_start_0)
|
{
|
if (qh == null)
|
return null;
|
if (qp == null)
|
return null;
|
int point_count = 12;
|
List<Yw.Geometry.Point2d> qe_pt_list = new List<Yw.Geometry.Point2d>();
|
List<Yw.Geometry.Point2d> qp_pt_list = qp.GetPointList(point_count);
|
|
double Q, H, Eff, Power;
|
var fitCurve = new Yw.Geometry.CubicSpline2d(qh);
|
for (int i = 0; i < qp_pt_list.Count; i++)
|
{
|
Q = qp_pt_list[i].X;
|
Power = qp_pt_list[i].Y;
|
H = fitCurve.GetPointY(Q);
|
Eff = CalculateE(Q, H, Power, midu);
|
qe_pt_list.Add(new Yw.Geometry.Point2d(Q, Eff));
|
}
|
|
//保证Q=0时,Eff=0;
|
if (is_x_start_0)
|
{
|
qe_pt_list[0] = new Yw.Geometry.Point2d(0, 0);
|
qe_pt_list = qe_pt_list.GetFitPointList();
|
qe_pt_list = qe_pt_list.AmendByZeroPointY(qe_pt_list[3].X, 0);
|
return new Yw.Geometry.CubicSpline2d(qe_pt_list);
|
}
|
else
|
{
|
return new Yw.Geometry.CubicSpline2d(qe_pt_list);
|
}
|
}
|
|
public static List<Yw.Geometry.Point2d> CalculateEpoint(
|
|
Yw.Geometry.CubicSpline2d qh,
|
Yw.Geometry.CubicSpline2d qp,
|
int point_count,
|
double midu)
|
{
|
if (qh == null)
|
return null;
|
if (qp == null)
|
return null;
|
|
List<Yw.Geometry.Point2d> qe_pt_list = new List<Yw.Geometry.Point2d>();
|
List<Yw.Geometry.Point2d> qp_pt_list = qp.GetPointList(point_count);
|
|
double Q, H, Eff, Power;
|
var fitCurve = qh.Copy();
|
for (int i = 0; i < qp_pt_list.Count; i++)
|
{
|
Q = qp_pt_list[i].X;
|
Power = qp_pt_list[i].Y;
|
H = fitCurve.GetPointY(Q);
|
Eff = CalculateE(Q, H, Power, midu);
|
|
qe_pt_list.Add(new Yw.Geometry.Point2d(Q, Eff));
|
}
|
|
bool is_x_start_0 = true;
|
if (qe_pt_list.First().X > 500 || qe_pt_list.First().X > qe_pt_list.Last().X * 0.1)
|
{
|
is_x_start_0 = false;
|
}
|
else
|
{
|
is_x_start_0 = true;
|
}
|
|
//保证Q=0时,Eff=0;
|
if (is_x_start_0)
|
{
|
qe_pt_list[0] = new Yw.Geometry.Point2d(0, 0);
|
qe_pt_list = qe_pt_list.GetFitPointList();
|
return qe_pt_list.AmendByZeroPointY(qe_pt_list[3].X, 0);
|
}
|
else
|
{
|
return qe_pt_list.GetFitPointList();
|
}
|
}
|
|
/// <summary>
|
/// 注意此方法 返回的点没有拟合
|
/// </summary>
|
/// <param name="qh_pt_list"></param>
|
/// <param name="qp_pt_list"></param>
|
/// <param name="midu"></param>
|
/// <param name="is_x_start_0"></param>
|
/// <returns></returns>
|
public static List<Yw.Geometry.Point2d> CalculateE_AlignPointP(
|
List<Yw.Geometry.Point2d> qh_pt_list,
|
List<Yw.Geometry.Point2d> qp_pt_list,
|
double midu, bool is_x_start_0)
|
{
|
if (qh_pt_list == null || qh_pt_list.Count < 3)
|
return null;
|
if (qp_pt_list == null || qp_pt_list.Count < 3)
|
return null;
|
|
List<Yw.Geometry.Point2d> qe_pt_list = new List<Yw.Geometry.Point2d>();
|
|
if (qh_pt_list.IsEqualValueX(qp_pt_list))
|
{ //x都一致
|
for (int i = 0; i < qp_pt_list.Count; i++)
|
{
|
double Q, H, Eff, Power;
|
Q = qp_pt_list[i].X;
|
Power = qp_pt_list[i].Y;
|
H = qh_pt_list[i].Y;
|
Eff = CalculateE(Q, H, Power, midu);
|
qe_pt_list.Add(new Yw.Geometry.Point2d(Q, Eff));
|
}
|
}
|
else
|
{
|
var fitCurve_QP = new Yw.Geometry.CubicSpline2d(qp_pt_list);
|
var fitCurve_QH = new Yw.Geometry.CubicSpline2d(qh_pt_list);
|
for (int i = 0; i < qp_pt_list.Count; i++)
|
{
|
double Q, H, Eff, Power;
|
Q = qp_pt_list[i].X;
|
Power = fitCurve_QP.GetPointY(Q);
|
H = fitCurve_QH.GetPointY(Q);
|
Eff = CalculateE(Q, H, Power, midu);
|
qe_pt_list.Add(new Yw.Geometry.Point2d(Q, Eff));
|
}
|
}
|
|
|
//qe_pt_list = FitHelper.GetPointListByExtend(qe_pt_list);
|
|
//保证Q=0时,Eff=0;
|
if (is_x_start_0)
|
{
|
qe_pt_list[0] = new Yw.Geometry.Point2d(0, 0);
|
}
|
|
return qe_pt_list;
|
}
|
|
#endregion
|
|
#region 功率效率换算
|
|
|
/// <summary>
|
/// 计算效率 对其功率
|
/// </summary>
|
public static List<Yw.Geometry.Point2d> CalculateELineByP(List<Yw.Geometry.Point2d> qh_pt_list, List<Yw.Geometry.Point2d> qp_pt_list, bool is_x_start_0)
|
{
|
if (qh_pt_list == null || qh_pt_list.Count < 3)
|
{
|
return null;
|
}
|
|
if (qp_pt_list == null || qp_pt_list.Count < 3)
|
{
|
return null;
|
}
|
|
List<Yw.Geometry.Point2d> list = new List<Yw.Geometry.Point2d>();
|
if (qh_pt_list.IsEqualValueX(qp_pt_list))
|
{
|
for (int i = 0; i < qp_pt_list.Count; i++)
|
{
|
double x = qp_pt_list[i].X;
|
double y = qp_pt_list[i].Y;
|
double y2 = qh_pt_list[i].Y;
|
double y3 = CalculateE(x, y2, y, Constant.WaterDensity);
|
list.Add(new Yw.Geometry.Point2d(x, y3));
|
}
|
}
|
else
|
{
|
var qp = new Yw.Geometry.CubicSpline2d(qp_pt_list);
|
var qh = new Yw.Geometry.CubicSpline2d(qh_pt_list);
|
for (int j = 0; j < qp_pt_list.Count; j++)
|
{
|
double x2 = qp_pt_list[j].X;
|
double fit_pointY = qp.GetPointY(x2);
|
double fit_pointY2 = qh.GetPointY(x2);
|
double y4 = CalculateE(x2, fit_pointY2, fit_pointY, Constant.WaterDensity);
|
list.Add(new Yw.Geometry.Point2d(x2, y4));
|
}
|
}
|
|
if (is_x_start_0)
|
{
|
list[0] = new Yw.Geometry.Point2d(0, 0);
|
}
|
|
return list;
|
}
|
|
|
/// <summary>
|
/// 计算效率 对其效率
|
/// </summary>
|
public static List<Yw.Geometry.Point2d> CalculateP_AlignPointE(List<Yw.Geometry.Point2d> qh_pt_list, List<Yw.Geometry.Point2d> qe_pt_list, double midu, double ref_zero_power, bool is_x_start_0)
|
{
|
if (qh_pt_list == null || qh_pt_list.Count < 3)
|
{
|
return null;
|
}
|
|
if (qe_pt_list == null || qe_pt_list.Count < 3)
|
{
|
return null;
|
}
|
|
List<Yw.Geometry.Point2d> list = new List<Yw.Geometry.Point2d>();
|
if (qh_pt_list.IsEqualValueX(qe_pt_list))
|
{
|
for (int i = 0; i < qe_pt_list.Count(); i++)
|
{
|
double x = qe_pt_list[i].X;
|
double y = qe_pt_list[i].Y;
|
double y2 = qh_pt_list[i].Y;
|
if (!(y2 < 0.1) && !(y < 0.5))
|
{
|
double num = CalculateP(x, y2, y, midu);
|
num = ((num < 2.0) ? Math.Round(num, 3) : ((num < 30.0) ? Math.Round(num, 2) : ((!(num < 100.0)) ? Math.Round(num, 0) : Math.Round(num, 1))));
|
list.Add(new Yw.Geometry.Point2d(x, num));
|
}
|
}
|
}
|
else
|
{
|
var qe = new Yw.Geometry.CubicSpline2d(qe_pt_list);
|
var qh = new Yw.Geometry.CubicSpline2d(qh_pt_list);
|
for (int j = 0; j < qe_pt_list.Count(); j++)
|
{
|
double x2 = qe_pt_list[j].X;
|
double fit_pointY = qe.GetPointY(x2);
|
double fit_pointY2 = qh.GetPointY(x2);
|
if (!(fit_pointY2 < 0.09) && !(fit_pointY < 0.5))
|
{
|
double num2 = CalculateP(x2, fit_pointY2, fit_pointY, midu);
|
num2 = ((num2 < 2.0) ? Math.Round(num2, 3) : ((num2 < 30.0) ? Math.Round(num2, 2) : ((!(num2 < 100.0)) ? Math.Round(num2, 0) : Math.Round(num2, 1))));
|
list.Add(new Yw.Geometry.Point2d(x2, num2));
|
}
|
}
|
}
|
|
if (is_x_start_0)
|
{
|
if (list[0].X < 1.0)
|
{
|
if (ref_zero_power > 0.0)
|
{
|
list[0].X = 0.0;
|
list[0].Y = ref_zero_power;
|
}
|
else
|
{
|
list.RemoveAt(0);
|
var fit_points = list.GetFitPointList();
|
if (fit_points[0].Y >= fit_points[1].Y)
|
{
|
fit_points[0].Y = fit_points[1].Y * 0.95;
|
}
|
|
double num3 = Yw.Geometry.LineHelper.GetYbyX(fit_points[0].X, fit_points[0].Y, fit_points[1].X, fit_points[1].Y, 0.0);
|
if (num3 < 0.001)
|
{
|
num3 = fit_points[0].Y;
|
}
|
|
num3 = ((num3 < 2.0) ? Math.Round(num3, 3) : ((num3 < 30.0) ? Math.Round(num3, 2) : ((!(num3 < 100.0)) ? Math.Round(num3, 0) : Math.Round(num3, 1))));
|
list.Insert(0, new Yw.Geometry.Point2d(0.0, num3));
|
}
|
}
|
else if (ref_zero_power > 0.0)
|
{
|
list.Insert(0, new Yw.Geometry.Point2d(0.0, ref_zero_power));
|
}
|
else
|
{
|
var fit_points2 = list.GetFitPointList();
|
if (fit_points2[0].Y >= fit_points2[1].Y)
|
{
|
fit_points2[0].Y = fit_points2[1].Y * 0.95;
|
}
|
|
double num4 = Yw.Geometry.LineHelper.GetYbyX(fit_points2[0].X, fit_points2[0].Y, fit_points2[1].X, fit_points2[1].Y, 0.0);
|
if (num4 < 0.001)
|
{
|
num4 = fit_points2[0].Y;
|
}
|
|
num4 = ((num4 < 2.0) ? Math.Round(num4, 3) : ((num4 < 30.0) ? Math.Round(num4, 2) : ((!(num4 < 100.0)) ? Math.Round(num4, 0) : Math.Round(num4, 1))));
|
list.Insert(0, new Yw.Geometry.Point2d(0.0, num4));
|
}
|
}
|
|
return list;
|
}
|
|
|
#endregion
|
|
#endregion
|
|
#region 曲线与H=K*Q^i的交点
|
|
/// <summary>
|
/// 根据相似点设置相似曲线,相似点(选择点)的x:流量y:杨程
|
/// </summary>
|
public static double GetSimuValue(Yw.Geometry.CubicSpline2d cubic_spline, Yw.Geometry.Point2d simular_pt, double origin_value, double extend_ratio = 1)
|
{
|
if (cubic_spline == null)
|
return -3;
|
if (simular_pt.X < 0.1 || simular_pt.Y < 0.1)
|
return -2;
|
if (simular_pt.X > cubic_spline.MaxX * extend_ratio * 1.5)
|
return -4;
|
|
Yw.Geometry.Point2d sect_pt = GetSectPoint(cubic_spline, simular_pt, extend_ratio);
|
if (sect_pt == null || sect_pt.IsZeroPoint())
|
return -5;
|
|
//计算相似点的转速/直径
|
return CalculateSimuByH(origin_value, sect_pt.Y, simular_pt.Y);
|
}
|
|
//ratioIgnore:作用 当simularPoint超出曲线范围时,曲线扩大的倍数
|
public static Yw.Geometry.Point2d GetSectPoint(Yw.Geometry.CubicSpline2d cubic_spline, Yw.Geometry.Point2d simular_pt, double ratioIgnore)
|
{
|
return GetSectPointGeneral(cubic_spline, simular_pt, 2, ratioIgnore);
|
}
|
|
public static Yw.Geometry.Point2d GetSectPointParabola(Yw.Geometry.CubicSpline2d cubic_spline, Yw.Geometry.Point2d simular_pt)
|
{
|
var sect_pt = new Yw.Geometry.Point2d(0, 0);
|
if (cubic_spline == null)
|
return sect_pt;
|
var pt_list = cubic_spline.GetPointListByXRatioRange(1, 1.2, 50);
|
return GetSectPointParabola(pt_list, simular_pt);
|
}
|
|
//通过点simular_pt和点(0,0)的直线,与曲线Curve的交点(没有,返回Point(0,0))
|
public static Yw.Geometry.Point2d GetSectPointLine(List<Yw.Geometry.Point2d> CurvePoints, Yw.Geometry.Point2d simular_pt)
|
{
|
Yw.Geometry.Point2d sect_pt = new Yw.Geometry.Point2d(0, 0);
|
if (CurvePoints == null || CurvePoints.Count < 2)
|
return sect_pt;
|
|
//计算直线的K
|
if (simular_pt.X < 1)
|
return sect_pt;
|
double a = simular_pt.Y / simular_pt.X;
|
if (a < 0.0001)
|
return sect_pt;
|
|
//与2点连成直线的交点,判断交点是否在2点之间,即可是曲线的交点
|
double b, c;
|
double x;
|
for (int i = 0; i < CurvePoints.Count - 1; i++)
|
{
|
LineHelper.GetKandB(CurvePoints[i], CurvePoints[i + 1], out b, out c);
|
|
/*解方程
|
* y=ax
|
* y=bx+c
|
*/
|
if (Math.Abs(a - b) < 0.001)
|
continue;
|
|
x = c / (a - b);
|
if (UtilsHelper.IsMiddle(CurvePoints[i].X, CurvePoints[i + 1].X, x))
|
{
|
sect_pt.X = x;
|
sect_pt.Y = a * x;
|
return sect_pt;
|
}
|
}
|
|
return sect_pt;
|
}
|
|
//通过点simular_pt和点(0,0)的抛物线,与曲线Curve的交点(没有,返回Point(0,0))
|
//曲线公式:H=K*Q^2
|
public static Yw.Geometry.Point2d GetSectPointParabola(List<Yw.Geometry.Point2d> pt_list, Yw.Geometry.Point2d simular_pt)
|
{
|
return ParabolaCurveHelper.GetSectPoint(pt_list, simular_pt, 0);
|
}
|
|
public static Yw.Geometry.Point2d GetSectPointLine(this Yw.Geometry.CubicSpline2d cubic_spline, Yw.Geometry.Point2d simular_pt)
|
{
|
Yw.Geometry.Point2d sect_pt = new Yw.Geometry.Point2d(0, 0);
|
if (cubic_spline == null)
|
return sect_pt;
|
|
//计算直线的K
|
if (simular_pt.X < 1)
|
return sect_pt;
|
double a = simular_pt.Y / simular_pt.X;
|
if (a < 0.0001)
|
return sect_pt;
|
|
//点越多越精确
|
return GetSectPointLine(cubic_spline.GetPointList(100), simular_pt);
|
}
|
|
//曲线H=K*Q^i 与曲线Curve的交点(没有,返回Point(0,0))
|
public static Yw.Geometry.Point2d GetSectPointGeneral(List<Yw.Geometry.Point2d> pt_list, Yw.Geometry.Point2d simular_pt, double index)
|
{
|
Yw.Geometry.Point2d sect_pt = new Yw.Geometry.Point2d(0, 0);
|
if (pt_list == null || pt_list.Count < 2)
|
return sect_pt;
|
|
if (simular_pt.X < 0.1)
|
return sect_pt;
|
|
if (Math.Abs(index - 1) < 0.01)
|
return GetSectPointLine(pt_list, simular_pt);
|
if (Math.Abs(index - 2) < 0.01)
|
return GetSectPointParabola(pt_list, simular_pt);
|
|
//计算系数K
|
double fixK = simular_pt.Y / Math.Pow(simular_pt.X, index);
|
if (fixK < 0.000001)
|
return sect_pt;
|
|
//思路是从simular_pt开始逐个增加0.1,直到k值最接近fixK
|
double space = (pt_list.Last().X - simular_pt.X) / 1200;
|
double x = simular_pt.X;
|
double y, k;
|
do
|
{
|
x = x + space;
|
y = 0;
|
var y_pt_list = pt_list.GetInterPointsY(x);
|
if (y_pt_list == null || !y_pt_list.Any())
|
{
|
break;
|
}
|
y = y_pt_list.Last();
|
k = y / Math.Pow(x, index);
|
} while (k > fixK);
|
|
sect_pt.X = x;
|
sect_pt.Y = y;
|
return sect_pt;
|
}
|
|
|
//ratioIgnore:作用 当simular_pt超出范围时,扩大的倍数
|
public static Yw.Geometry.Point2d GetSectPointGeneral(this Yw.Geometry.CubicSpline2d cubic_spline, Yw.Geometry.Point2d simular_pt, double index, double ratioIgnore)
|
{
|
Yw.Geometry.Point2d sect_pt = new Yw.Geometry.Point2d(0, 0);
|
if (cubic_spline == null)
|
return sect_pt;
|
|
if (simular_pt.X < 1)
|
return sect_pt;
|
var cubic_spline_ex = cubic_spline.Copy();
|
//检查是否在曲线的区域范围内
|
double max_flow = cubic_spline_ex.MaxX;
|
double max_head = cubic_spline_ex.GetPointY(max_flow);
|
double k1 = max_head / Math.Pow(max_flow, index);
|
double k2 = simular_pt.Y / Math.Pow(simular_pt.X, index);
|
if (k1 > k2)
|
{
|
cubic_spline_ex.MaxX = cubic_spline_ex.MaxX * ratioIgnore;//放大1.2倍
|
}
|
|
if (Math.Abs(index - 1) < 0.01)
|
return GetSectPointLine(cubic_spline_ex, simular_pt);
|
if (Math.Abs(index - 2) < 0.01)
|
return GetSectPointParabola(cubic_spline_ex, simular_pt);
|
|
//计算系数K
|
double fixK = simular_pt.Y / Math.Pow(simular_pt.X, index);
|
if (fixK < 0.000001)
|
return sect_pt;
|
|
//思路是从simular_pt开始逐个增加0.1,直到k值最接近fixK
|
double space = (cubic_spline_ex.MaxX - simular_pt.X) / 1000;
|
double x = simular_pt.X;
|
double y, k;
|
do
|
{
|
x = x + space;
|
y = cubic_spline_ex.GetPointY(x);
|
k = y / Math.Pow(x, index);
|
} while (k > fixK);
|
|
sect_pt.X = x;
|
sect_pt.Y = y;
|
return sect_pt;
|
}
|
|
#endregion 曲线与H=K*Q^i的交点 protect类型,给子类调用,怎么覆盖GetSectPoint
|
}
|
}
|