using DevExpress.XtraEditors; using NPOI.Util; namespace Yw.WinFrmUI.Phart { /// /// /// public partial class PumpChartPointImportCtrl : XtraUserControl { public PumpChartPointImportCtrl() { InitializeComponent(); this.comboBoxType.SelectedIndex = 0; this.sidePanel1.Visible = false; this.bar2.Visible = true; } private double _ratedn = -1; private List _def_qh_pt_list = null; private List _def_qe_pt_list = null; private List _def_qp_pt_list = null; private List _def_npsh_pt_list = null; private PumpQueryPointViewModel _work_point = null; /// /// 绑定数据 /// public void SetBindingData(double flow, double head, double speed, double? eff, double level, bool is_sxp) { this.txtFlow.EditValue = flow; this.txtHead.EditValue = head; this.txtSpeed.EditValue = speed; this.txtE.EditValue = eff; this.spinLevel.EditValue = level; this.cekIsSxp.Checked = is_sxp; } //是否是无效数据 private bool IsInvalidData() { if (this.txtFlow.EditValue==null) { return true; } if (this.txtHead.EditValue == null) { return true; } if (this.txtSpeed.EditValue == null) { return true; } if (this.spinLevel.EditValue==null) { return true; } return false; } //计算转速比 private void CalcNs() { if (IsInvalidData()) return; var flow = Convert.ToDouble(this.txtFlow.EditValue); var head = Convert.ToDouble(this.txtHead.EditValue); var speed = Convert.ToDouble(this.txtSpeed.EditValue); var level = Convert.ToInt32(this.spinLevel.EditValue); if (this.cekIsSxp.Checked) flow /= 2; var ns = PumpCalcHelper.CalculateNs(flow, head / level, speed); ns = Math.Round(ns, 2); this.txtNS.EditValue = ns; } public List GetFitPointListByExtend(List points, double ratioExtend, int pointNumber = 20) { if (points == null) return default; var express = new Yw.Geometry.CubicSpline2d(points); return express.GetPointListByXRatioRange(1, ratioExtend); } public double GetLineInsert(double X1, double X2, double Y1, double Y2, double X) { if (Math.Abs(X2 - X1) < 1E-06) { return 0.0; } if (Math.Abs(Y2 - Y1) < 1E-06) { return 0.0; } return Y1 + (Y2 - Y1) / (X2 - X1) * (X - X1); } #region 事件 private void txtQ_EditValueChanged(object sender, EventArgs e) { CalcNs(); } private void txtH_EditValueChanged(object sender, EventArgs e) { CalcNs(); } private void txtN_EditValueChanged(object sender, EventArgs e) { CalcNs(); } private void spinEditYLJS_EditValueChanged(object sender, EventArgs e) { CalcNs(); } private void labReckon_Click(object sender, EventArgs e) { //水力参数 try { if (string.IsNullOrEmpty(txtHead.Text) || string.IsNullOrEmpty(txtFlow.Text)) { MessageBox.Show("流量扬程不能为空"); return; } //转速 if (string.IsNullOrEmpty(txtSpeed.Text)) { MessageBox.Show("转速不能为空"); return; } _ratedn = Convert.ToDouble(txtSpeed.EditValue); if (_ratedn < 10) { MessageBox.Show("转速有这么小吗?"); return; } _work_point = new(); _work_point.Q = Convert.ToDouble(txtFlow.EditValue); _work_point.H = Convert.ToDouble(txtHead.EditValue); if (_work_point.H < 1 || _work_point.Q < 1) { MessageBox.Show("流量扬程有这么小吗?"); return; } } catch { MessageBox.Show("请输入数字"); return; } double eff = PumpCalcHelper.CalculateEByPumpType(_work_point.Q, _work_point.H, _ratedn, comboBoxType.SelectedIndex + 1); txtE.EditValue = Math.Round(eff,2) ; _work_point.E = eff; double NPSHr = PumpCalcHelper.CalculateNPSHrByPumpType(_work_point.Q, _work_point.H, _ratedn, comboBoxType.SelectedIndex + 1);//双吸离心泵 NPSHr = Math.Round(NPSHr, 1); txtNPSH.EditValue = NPSHr; } private void labCalcuE_Click(object sender, EventArgs e) { #region 得到参数 double Q, H, P; try { if (string.IsNullOrEmpty(txtHead.Text) || string.IsNullOrEmpty(txtFlow.Text) || string.IsNullOrEmpty(txtE.Text)) { MessageBox.Show("流量,扬程和功率,不能为空"); return; } H = Convert.ToDouble(txtHead.Text); Q = Convert.ToDouble(txtFlow.Text); P = Convert.ToDouble(txtP.Text); if (H < 1 || Q < 1 || P < 1) { MessageBox.Show("参数有这么小吗"); return; } } catch { MessageBox.Show("请输入数字"); return; } #endregion double E = PumpCalcHelper.CalculateE(Q, H, P); txtE.EditValue = Math.Round(E, 1); if (E > 99) { MessageBox.Show("功率是否输入有误?"); return; } } private void labCalcuP_Click(object sender, EventArgs e) { #region 得到参数 double Q, H, E; try { if (string.IsNullOrEmpty(txtHead.Text) || string.IsNullOrEmpty(txtFlow.Text) || string.IsNullOrEmpty(txtE.Text)) { MessageBox.Show("流量,扬程和功率,不能为空"); return; } H = Convert.ToDouble(txtHead.Text); Q = Convert.ToDouble(txtFlow.Text); E = Convert.ToDouble(txtE.Text); if (H < 0.1 || Q < 0.1 || E < 1) { MessageBox.Show("参数有这么小吗"); return; } } catch { MessageBox.Show("请输入数字"); return; } #endregion double P = PumpCalcHelper.CalculateP(Q, H, E); if (P < 1) { txtP.Text = string.Format("{0:0.000}", P); } else if (P < 10) { txtP.Text = string.Format("{0:0.00}", P); } else if (P < 100) { txtP.Text = string.Format("{0:0.0}", P); } else { txtP.Text = string.Format("{0:N0}", P); } } //生成曲线 private void btnCreate_Click(object sender, EventArgs e) { } #endregion public static List CalculateP(List pointQH, List pointQE) { if (pointQH == null || pointQH.Count() <= 2) return null; bool isFromZero = true; if (pointQH.First().X > 500 || pointQH.First().X > pointQH.Last().X * 0.2) isFromZero = false; return CalculateP_RefZero(pointQH, pointQE, Constant.WaterDensity, -1, isFromZero); } //有时 会把零流量点扬程传入 ref_zero_power public static List CalculateP_RefZero( List pointQH, List pointQE, double midu, double ref_zero_power, bool isFromZero) { if (pointQH == null || pointQH.Count < 3) return null; if (pointQE == null || pointQE.Count < 3) return null; var expressQH = new Yw.Geometry.CubicSpline2d(pointQH); var expressQE = new Yw.Geometry.CubicSpline2d(pointQE); var expressQP = CalculateP_RefZero(expressQH, expressQE, midu, ref_zero_power, isFromZero, false); return expressQP.GetPointList(pointQE.Count()); } public static Yw.Geometry.CubicSpline2d CalculateP_RefZero( Yw.Geometry.CubicSpline2d expressQH, Yw.Geometry.CubicSpline2d expressQE, double midu, double ref_zero_power, bool isFromZero, bool isSavePointInExpress) { if (expressQH == null) return null; if (expressQE == null) return null; int point_num = 16;//点不能太多 var pointQH = expressQH.GetPointList(point_num); if (pointQH == null || pointQH.Count < 3) return null; var pointQE = expressQE.GetPointList(point_num); if (pointQE == null || pointQE.Count < 3) return null; List pointQP = new List(); //间距 double min_flow = Math.Max(pointQH.First().X, pointQE.First().X); double max_flow = Math.Min(pointQH.Last().X, pointQE.Last().X); // double Q, H, E, P; double space = (max_flow - min_flow) / (point_num - 1); var fitCurveQE = expressQE.Copy(); var fitCurveQH = expressQH.Copy(); if (isFromZero) { #region 保证从0开始: 保证Q=0时,P不是计算出来的; for (int i = 5; i < point_num; i++)//前面几个点不要 { Q = pointQE.First().X + space * i; E = fitCurveQE.GetPointY(Q); H = fitCurveQH.GetPointY(Q); if (H < 0.1 || E < 0.5) continue; P = PumpCalcHelper.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); } pointQP.Add(new Yw.Geometry.Point2d(Q, P)); } pointQP = pointQP.GetFitPointList(point_num); if (pointQP == null) return null; if (ref_zero_power > 0.1) { pointQP.Insert(0, new Yw.Geometry.Point2d(0, ref_zero_power)); } else { if (pointQP[0].Y >= pointQP[1].Y) { pointQP[0].Y = pointQP[1].Y * 0.95; } double startP = Yw.Geometry.LineHelper.GetYbyX(pointQP[0].X, pointQP[0].Y, pointQP[1].X, pointQP[1].Y, 0); if (startP < 0.001) startP = pointQP[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); } pointQP.Insert(0, new Yw.Geometry.Point2d(0, startP)); } return new Yw.Geometry.CubicSpline2d(pointQP); #endregion } else { #region 保证从0开始: 保证Q=0时,P不是计算出来的; for (int i = 0; i < point_num; i++)//前面几个点不要 { Q = pointQE.First().X + space * i; E = fitCurveQE.GetPointY(Q); H = fitCurveQH.GetPointY(Q); if (H < 0.1 || E < 0.5) continue; P = PumpCalcHelper.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); } pointQP.Add(new Yw.Geometry.Point2d(Q, P)); } pointQP = pointQP.GetFitPointList(point_num); if (pointQP == null) return null; return new Yw.Geometry.CubicSpline2d(pointQP); #endregion } } //产生曲线 private void barBtnCreate_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { double? k0 = 0; if (this.txtK0.EditValue != null) { k0 = Convert.ToDouble(txtK0.EditValue); if (k0 < 1.001) { XtraMessageBox.Show("关死点系数不能小于1"); return; } } if (string.IsNullOrEmpty(this.txtFlow.Text) || string.IsNullOrEmpty(this.txtHead.Text)) { MessageBox.Show("流量扬程不能为空"); return; } if (string.IsNullOrEmpty(this.txtSpeed.Text)) { MessageBox.Show("转速不能为空"); return; } _ratedn =Convert.ToDouble(this.txtSpeed.EditValue); if (_ratedn < 10) { MessageBox.Show("转速有这么小吗?"); return; } _work_point = new PumpQueryPointViewModel(); _work_point.Q = Convert.ToDouble(this.txtFlow.EditValue); _work_point.H = Convert.ToDouble(this.txtHead.EditValue); if (_work_point.H < 1 || _work_point.Q < 1) { MessageBox.Show("流量扬程有这么小吗?"); return; } if (string.IsNullOrWhiteSpace(this.txtE.Text)) { double ns = PumpCalcHelper.CalculateNs(_work_point.Q, _work_point.H, _ratedn); double eff = PumpCalcHelper.CalculateEByPumpType(_work_point.Q, _work_point.H, _ratedn, comboBoxType.SelectedIndex + 1); _work_point.E = eff; this.txtE.EditValue = Math.Round(eff, 1); } else { _work_point.E = Convert.ToDouble(this.txtE.EditValue); } if (_work_point.E > 99) { MessageBox.Show("效率有这么大吗?"); return; } _work_point.P = PumpCalcHelper.CalculateP(_work_point.Q, _work_point.H, _work_point.E.Value); if (string.IsNullOrWhiteSpace(this.txtP.Text)) { this.txtP.EditValue = Math.Round(_work_point.P.Value, 1); } //汽蚀 double NPSHr = 0; if (!double.TryParse(this.txtNPSH.EditValue?.ToString(), out NPSHr)) { NPSHr = PumpCalcHelper.CalculateNPSHrByPumpType(_work_point.Q, _work_point.H, _ratedn, comboBoxType.SelectedIndex + 1);//双吸离心泵 NPSHr = Math.Round(NPSHr, 1); this.txtNPSH.EditValue = NPSHr; } //得到点位置 bool iOK = PumpDimensionlessCurvesHelper.CalcPoints(_work_point, _ratedn, k0, ref _def_qh_pt_list, ref _def_qe_pt_list, ref _def_qp_pt_list, ref _def_npsh_pt_list, cekIsSxp.Checked, Convert.ToInt32(spinLevel.Value)); if (!iOK) { XtraMessageBox.Show("Error:265"); return; } //消除驼峰 if (k0 == null || k0 < 0.1) { double spaceH = _work_point.H / 200;//200为预估值 for (int i = _def_qh_pt_list.Count - 2; i >= 0; i--) { if (_def_qh_pt_list[i].Y < _def_qh_pt_list[i + 1].Y) { _def_qh_pt_list[i].Y = _def_qh_pt_list[i + 1].Y + spaceH; } } } if (!string.IsNullOrEmpty(txtMaxRatio.Text)) { double qre = 0; if (double.TryParse(txtMaxRatio.EditValue?.ToString(), out qre)) { if (qre > 1.01 && qre < 1.8) { var ex_q = _work_point.Q * qre; var max_q = _def_qh_pt_list.Last().X; var ratio = ex_q / max_q; if (qre > 1.35) { var pointInfoQH2 = GetFitPointListByExtend(_def_qh_pt_list, ratio); var max_powert_E = GetLineInsert(_def_qe_pt_list[_def_qe_pt_list.Count - 2].X, _def_qe_pt_list[_def_qe_pt_list.Count - 1].X, _def_qe_pt_list[_def_qe_pt_list.Count - 2].Y, _def_qe_pt_list[_def_qe_pt_list.Count - 1].Y, qre * _work_point.Q); _def_qe_pt_list.Add(new Yw.Geometry.Point2d(qre * _work_point.Q, max_powert_E)); _def_qh_pt_list = pointInfoQH2; _def_qe_pt_list = _def_qe_pt_list.GetFitPointList(20); _def_qp_pt_list = CalculateP(_def_qh_pt_list, _def_qe_pt_list); } else { _def_qh_pt_list = GetFitPointListByExtend(_def_qh_pt_list, ratio); _def_qe_pt_list = GetFitPointListByExtend(_def_qe_pt_list, ratio); _def_qp_pt_list = GetFitPointListByExtend(_def_qp_pt_list, ratio); } } } } var vm = new PumpViewChartViewModel(); vm.CurveQH = _def_qh_pt_list; vm.CurveQE = _def_qe_pt_list; vm.CurveQP = _def_qp_pt_list; this.pumpViewChart1.SetBindingData(vm); } /// /// 获取数据 /// public bool Get( out List def_qh_pt_list, out List def_qe_pt_list, out List def_qp_pt_list, out Yw.Ahart.eFeatType feat_type_qh, out Yw.Ahart.eFeatType feat_type_qe, out Yw.Ahart.eFeatType feat_type_qp) { def_qh_pt_list = _def_qh_pt_list; def_qe_pt_list = _def_qe_pt_list; def_qp_pt_list = _def_qp_pt_list; feat_type_qh = Ahart.eFeatType.Cubic; feat_type_qe = Ahart.eFeatType.Cubic; feat_type_qp = Ahart.eFeatType.Cubic; if (def_qh_pt_list == null || !def_qh_pt_list.Any()) return false; return true; } } }