示例#1
0
        /// <summary>
        /// Iteration methord host
        /// </summary>
        /// <param name="impellerInput">Input impeller</param>
        /// <returns>Impeller with calculated data</returns>
        public Impeller Iteration(Impeller impellerInput)
        {
            var impeller = new Impeller(impellerInput);
            var impellerNew = new Impeller();

            //initial the Y(x) array
            //get Y(x) array
            impeller.Y = new List<double>(impeller.PSections.Count);
            for (int i = 0; i < impeller.PSections.Count; i++)
            {
                //Type 1 : Y(x) = (x / height)^2
                impeller.Y.Add( Math.Pow(impeller.PSections[i].Position / impeller.Height, 2));
            }

            int iterationCount = 0;
            while (true)
            {
                iterationCount++;
                //get new impeller Y
                impellerNew = IterationCalculater(impeller);
                impellerNew.IterationCount = iterationCount;
                //if impeller Y is precise enough or if cycled too many times, quit iteration
                if (ImpellerDifference(impeller, impellerNew) < impeller.MinTolerance
                    || iterationCount > impeller.MaxIterationCount)
                {
                    impeller = impellerNew;
                    break;
                }
                impeller = impellerNew;
            }

            return impeller;
        }
示例#2
0
        /// <summary>
        /// Iteration methord host
        /// </summary>
        /// <param name="impellerInput">Input impeller</param>
        /// <returns>Impeller with calculated data</returns>
        public Impeller Iteration(Impeller impellerInput, AssumeDeflectionFunction deflectionFunc)
        {
            var impeller = new Impeller(impellerInput);
            var impellerNew = new Impeller();

            //initial the Y(x) array
            //get Y(x) array
            try
            {
                impeller.Y = deflectionFunc(impeller.PSections, impeller.Height);
            }
            catch
            {
                throw;
            }

            int iterationCount = 0;
            while (true)
            {
                iterationCount++;
                //get new impeller Y
                impellerNew = IterationCalculater(impeller);
                impellerNew.IterationCount = iterationCount;
                //if impeller Y is precise enough or if cycled too many times, quit iteration
                if (ImpellerDifference(impeller, impellerNew) < impeller.MinTolerance
                    || iterationCount > impeller.MaxIterationCount)
                {
                    impeller = impellerNew;
                    break;
                }
                impeller = impellerNew;
            }

            return impeller;
        }
示例#3
0
        /// <summary>
        /// Rayleigh methord host
        /// </summary>
        /// <param name="impellerInput">Input impeller</param>
        /// <param name="g">Gravitational acceleration, m/s^2</param>
        /// <returns>Impeller with calculated data</returns>
        public Impeller Rayleigh(Impeller impellerInput, double g)
        {
            var impeller = RayleighCalculater(impellerInput, g);

            double uTemp = 0;
            double dTemp = 0;
            for (var i = 0; i < impeller.MSections.Count; i++)
            {
                uTemp += impeller.MSections[i].Mass * impeller.Y[i];
                dTemp += impeller.MSections[i].Mass * Math.Pow(impeller.Y[i], 2);
            }
            //ω = sqrt( g * ∑(mi*Yi) / ∑(mi*Yi^2) )
            impeller.LegacyVibrationFrequency = Math.Sqrt(g * uTemp / dTemp) / (2 * Math.PI);

            return impeller;
        }
示例#4
0
 /// <summary>
 /// Make a copy from existed impeller
 /// </summary>
 /// <param name="impeller">Impeller copy</param>
 public Impeller(Impeller impeller)
 {
     this.Comment = impeller.Comment;
     if (impeller.Density >= 0) this.Density = impeller.Density;
     if (impeller.E >= 0) this.E = impeller.E;
     if (impeller.Height >= 0) this.Height = impeller.Height;
     if (impeller.IterationCount >= 0) this.IterationCount = impeller.IterationCount;
     if (impeller.LegacyVibrationFrequency >= 0) this.LegacyVibrationFrequency = impeller.LegacyVibrationFrequency;
     if (impeller.MaxIterationCount >= 0) this.MaxIterationCount = impeller.MaxIterationCount;
     if (impeller.MaxProhlOmegaSearchCount >= 0) this.MaxProhlOmegaSearchCount = impeller.MaxProhlOmegaSearchCount;
     if (impeller.MaxProhlSearchCount >= 0) this.MaxProhlSearchCount = impeller.MaxProhlSearchCount;
     if (impeller.MinStepDiff > 0) this.MinStepDiff = impeller.MinStepDiff;
     if (impeller.MinTolerance > 0) this.MinTolerance = impeller.MinTolerance;
     if (impeller.MSections != null) this.MSections = impeller.MSections;
     if (impeller.PSections != null) this.PSections = impeller.PSections;
     if (impeller.VibrationFrequency != null) this.VibrationFrequency = impeller.VibrationFrequency;
     if (impeller.Y != null) this.Y = impeller.Y;
 }
示例#5
0
        /// <summary>
        /// Impeller vibration frequency calculater with iteration method
        /// </summary>
        /// <param name="impeller">Input impeller</param>
        /// <returns>Calculated impeller</returns>
        private Impeller IterationCalculater(Impeller impeller)
        {
            //cache result array
            var resultCache = new List<double>(new double[impeller.PSections.Count]);
            var resultCache2 = new List<double>(new double[impeller.PSections.Count]);
            var resultImpeller = new Impeller(impeller);

            // (A*Y_ij)_k or q_k/pw^2
            for (int i = 0; i < impeller.PSections.Count; i++)
            {
                resultCache[i] = impeller.Y[i] * impeller.PSections[i].Area;
            }

            //first and second integral
            for (int integralCount = 2; integralCount > 0; integralCount--)
            {
                for (int i = 0; i < impeller.PSections.Count; i++)
                {
                    if (i == 0)
                    {
                        resultCache2[i] = 0;
                    }
                    else
                    {
                        // (2/pw^2)*q_mk  then  4Q_mk/(pw^2*Δx)
                        resultCache2[i] = resultCache[i] + resultCache[i - 1];
                    }
                }
                for (int i = impeller.PSections.Count - 1; i >= 0; i--)
                {
                    if (i == impeller.PSections.Count - 1)
                    {
                        resultCache[i] = 0;
                    }
                    else
                    {
                        // 2Q_k/(pw^2*Δx) then  (4/(pw^2*Δx^2))*M_k
                        resultCache[i] = resultCache[i + 1] + resultCache2[i + 1];
                    }
                }
            }

            // (4E/(pw^2*Δx^2))*(ΔY')/Δx
            for (int i = 0; i < impeller.PSections.Count; i++)
            {
                resultCache[i] = resultCache[i] / impeller.PSections[i].InertiaMoment;
            }
            //third and fourth integral
            for (int integralCount = 2; integralCount > 0; integralCount--)
            {
                for (int i = 0; i < impeller.PSections.Count; i++)
                {
                    if (i == 0)
                    {
                        resultCache2[i] = 0;
                    }
                    else
                    {
                        // (8E/(pw^2*Δx^2))*(ΔY')_m/Δx^2  then  (16E/(pw^2*Δx^3))*(ΔY')_m/Δx
                        resultCache2[i] = resultCache[i] + resultCache[i - 1];
                    }
                }
                for (int i = 0; i < impeller.PSections.Count; i++)
                {
                    if (i == 0)
                    {
                        resultCache[i] = 0;
                    }
                    else
                    {
                        // (8E/(pw^2*Δx^3))*(ΔY')/Δx^2  then  (16E/(pw^2*Δx^4))*ΔY'
                        resultCache[i] = resultCache[i - 1] + resultCache2[i];
                    }
                }
            }

            // ΔY', i.e. impeller Y New = (cache1[i] / max(cache1) )
            double maxResult = resultCache.Max();
            for (int i = 0; i < resultCache.Count; i++)
            {
                resultCache[i] = resultCache[i] / maxResult;
            }
            resultImpeller.Y = resultCache;

            //ω = (4 / Δx^2) * (sqrt(E/(ρZ)))
            resultImpeller.LegacyVibrationFrequency = 4 / Math.Pow(impeller.PAvePieceLength, 2)
                 * Math.Sqrt(impeller.E / (impeller.Density * maxResult));
            //f = ω / 2π
            resultImpeller.LegacyVibrationFrequency /= (2 * Math.PI);

            return resultImpeller;
        }
示例#6
0
 /// <summary>
 /// Check the difference between two impeller Y
 /// </summary>
 /// <param name="impellerYA">The first impeller Y array</param>
 /// <param name="impellerYB">The second impeller Y array</param>
 /// <returns>Total difference</returns>
 private double ImpellerDifference(Impeller impellerA, Impeller impellerB)
 {
     double totalMess = 0;
     if (impellerA.Y.Count != impellerB.Y.Count)
     {
         return -1;
     }
     for (int i = 0; i < impellerA.Y.Count; i++)
     {
         totalMess += Math.Abs(impellerA.Y[i] - impellerB.Y[i]);
     }
     return totalMess;
 }
示例#7
0
        /// <summary>
        /// Impeller vibration frequency calculater with Rayleigh method
        /// </summary>
        /// <param name="impeller">Input impeller</param>
        /// <returns>Calculated impeller</returns>
        private Impeller RayleighCalculater(Impeller impeller, double g)
        {
            //cache result array
            var resultCache = new List<double>(new double[impeller.MSections.Count]);
            var resultCache2 = new List<double>(new double[impeller.MSections.Count]);

            for (int i = 0; i < impeller.MSections.Count; i++)
            {
                if (i == 0)
                {
                    resultCache[i] = impeller.MSections[i+1].Mass / impeller.MSections[i+1].Position;
                }
                else
                {
                    resultCache[i] = impeller.MSections[i].Mass
                        / (impeller.MSections[i].Position - impeller.MSections[i-1].Position);
                }
            }

            //first and second integral
            for (int integralCount = 2; integralCount > 0; integralCount--)
            {
                for (int i = 0; i < impeller.MSections.Count; i++)
                {
                    if (i == 0)
                    {
                        resultCache2[i] = 0;
                    }
                    else
                    {
                        resultCache2[i] = (resultCache[i] + resultCache[i - 1]) / 2;
                    }
                }
                for (int i = impeller.MSections.Count - 1; i >= 0; i--)
                {
                    if (i == impeller.MSections.Count - 1)
                    {
                        resultCache[i] = 0;
                    }
                    else
                    {
                        resultCache[i] = resultCache[i + 1]
                            + resultCache2[i + 1] * (impeller.MSections[i + 1].Position - impeller.MSections[i].Position);
                    }
                }
            }

            for (int i = 0; i < impeller.MSections.Count; i++)
            {
                resultCache[i] = resultCache[i] / impeller.MSections[i].InertiaMoment;
            }
            //third and fourth integral
            for (int integralCount = 2; integralCount > 0; integralCount--)
            {
                for (int i = 0; i < impeller.MSections.Count; i++)
                {
                    if (i == 0)
                    {
                        resultCache2[i] = 0;
                    }
                    else
                    {
                        resultCache2[i] = (resultCache[i] + resultCache[i - 1]) / 2;
                    }
                }
                for (int i = 0; i < impeller.MSections.Count; i++)
                {
                    if (i == 0)
                    {
                        resultCache[i] = 0;
                    }
                    else
                    {
                        resultCache[i] = resultCache[i - 1]
                            + resultCache2[i] * (impeller.MSections[i].Position - impeller.MSections[i-1].Position);
                    }
                }
            }

            for (var i = 0; i < resultCache.Count; i++)
            {
                resultCache[i] = resultCache[i] * g / impeller.E;
            }

            impeller.Y = resultCache;

            return impeller;
        }
示例#8
0
        /// <summary>
        /// Iteration frequency founder
        /// </summary>
        /// <param name="impeller">Input impeller</param>
        /// <param name="state">State object</param>
        private double ProhlFound(Impeller impeller, ProhlState state)
        {
            int searchCount = 0;
            double step = state.ProhlStep;
            int jumpSign = Math.Sign(state.residualMoment);
            int landSign = jumpSign;
            int direction = -1; // -1 = backwards , 1 = forwards

            while (step > impeller.MinStepDiff && searchCount < impeller.MaxProhlOmegaSearchCount)
            {
                step /= 2;
                state.Omega += direction * step;

                //caculate transfer matrix and residual moment
                ProhlCalculator(impeller, state);

                landSign = Math.Sign(state.residualMoment);

                if (jumpSign != landSign)
                {
                    direction *= -1;
                    jumpSign = landSign;
                }
                searchCount++;
            }
            impeller.IterationCount = searchCount;
            state.TempOmegaPoint = state.Omega;
            return state.Omega;
        }
示例#9
0
        /// <summary>
        /// Prohl matrix methord host
        /// </summary>
        /// <param name="impellerInput">Input impeller</param>
        /// <param name="state">Some settings and states</param>
        /// <returns>Impeller with calculated data</returns>
        public Impeller Prohl(Impeller impellerInput, ProhlState state)
        {
            var impeller = new Impeller(impellerInput);
            var freqPoints = new Dictionary<double,int>();
            int mainLoopCount = 0;
            state.Omega = state.CheckFromOmega;
            state.residualMoment = 0;

            if (state.Omega > state.CheckToOmega)
            {
                ProhlCalculator(impeller, state);
            }
            else
            {
                int anchorSign; //store the residualMoment sign
                double anchor; //store the freq
                double determinantAnchor; //store the residualMoment
                double freqPoint;
                while (state.Omega <= state.CheckToOmega && mainLoopCount++ < impeller.MaxProhlSearchCount)
                {
                    //search the frequency point
                    anchorSign = Math.Sign(state.residualMoment);
                    ProhlCalculator(impeller, state);

                    if (Math.Sign(state.residualMoment) * anchorSign < 0)
                    {
                        anchor = state.Omega;
                        determinantAnchor = state.residualMoment;

                        //find freq point
                        freqPoint = ProhlFound(impeller, state);

                        if (impeller.VibrationFrequency.IndexOf(freqPoint) < 0)
                        {
                            impeller.VibrationFrequency.Add(freqPoint);
                            freqPoints.Add(freqPoint, impeller.IterationCount);
                        }
                        state.Omega = anchor + state.ProhlStep;
                        state.residualMoment = determinantAnchor;
                        if (ProhlOmega_Changed != null)
                        {
                            ProhlOmega_Changed(impeller, state);
                            //System.Windows.MessageBox.Show("");
                        }
                    }
                    else
                    {
                        state.Omega += state.ProhlStep;
                        if (ProhlOmega_Changed != null)
                        {
                            ProhlOmega_Changed(impeller, state);
                            //System.Windows.MessageBox.Show("");
                        }
                    }
                }
            }
            impeller.VibrationFrequency = new List<double>();
            foreach( var freqPoint in freqPoints){
                impeller.VibrationFrequency.Add(freqPoint.Key / (2 * Math.PI));
            }
            impeller.IterationCount = mainLoopCount;

            return impeller;
        }
示例#10
0
        /// <summary>
        /// Impeller vibration frequency calculater with Prohl method
        /// </summary>
        /// <param name="impeller">Input impeller</param>
        /// <param name="state">State object</param>
        private void ProhlCalculator(Impeller impeller, ProhlState state)
        {
            #if TRACER
            watch.Start();
            #endif
            // the non-zero numbers of root state vector
            const int ROOT_STATE_VECTOR_SIZE = 2;
            var transferMatrix = new Matrix(4, 4);
            var residualMatrix = new Matrix(2, 2);
            //vibration frequency order
            var rootStateVector = new Matrix[2]{
                new Matrix(
                    new double[][]{
                        new double[] {0},
                        new double[] {0},
                        new double[] {1},
                        new double[] {0}
                    }
                ),
                new Matrix(
                    new double[][]{
                        new double[] {0},
                        new double[] {0},
                        new double[] {0},
                        new double[] {1}
                    }
                )
            };
            //section transfer matrix and hole transfer matrix(from root to end)
            var sectionTransferMatrix = new Matrix(
                new double[][]{
                    new double[] {1,1,1,1},
                    new double[] {0,1,1,1},
                    new double[] {0,0,1,1},
                    new double[] {1,1,1,1}
                }
            );

            #if TRACER
            long step1 = watch.ElapsedTicks;
            #endif
            double freq2 = state.Omega * state.Omega;
            for (var j = 0; j < ROOT_STATE_VECTOR_SIZE; j++)
            {
                for (var i = 0; i < impeller.MSections.Count; i++)
                {
                    double L = (i == 0 ? impeller.MSections[0].Position
                        : impeller.MSections[i].Position - impeller.MSections[i - 1].Position);
                    //L_EJ = L / EJ
                    double L_EJ = L / (impeller.E * impeller.MSections[i].InertiaMoment);
                    double m = impeller.MSections[i].Mass;
                    //freq2xm = freq2
                    double freq2xm = freq2 * m;

                    sectionTransferMatrix[3, 0] = freq2xm;

                    sectionTransferMatrix[0, 1] = L;
                    sectionTransferMatrix[3, 1] = freq2xm * L;

                    sectionTransferMatrix[0, 2] = L * L_EJ / 2;
                    sectionTransferMatrix[1, 2] = L_EJ;
                    sectionTransferMatrix[3, 2] = freq2xm * L * L_EJ / 2;

                    sectionTransferMatrix[0, 3] = L * L * L_EJ / 6;
                    sectionTransferMatrix[1, 3] = L * L_EJ / 2;
                    sectionTransferMatrix[2, 3] = L;
                    sectionTransferMatrix[3, 3] = 1 + freq2xm * L * L * L_EJ / 6;

                    transferMatrix = (i == 0 ? sectionTransferMatrix.Clone()
                        : sectionTransferMatrix.Multiply(transferMatrix));
                }

                state.TransferMatrix = transferMatrix;
                state.StateVector = transferMatrix.Multiply(rootStateVector[j]);

                for (var i = 0; i < state.EndStateVector.RowCount; i++)
                {
                    if (state.EndStateVector[i, 0] == 0 )
                    {
                        if (residualMatrix[0, j] == 0)
                        {
                            residualMatrix[0, j] = state.StateVector[i, 0];
                            continue;
                        }
                        residualMatrix[1, j] = state.StateVector[i, 0];
                        break;
                    }
                }
            }
            #if TRACER
            long step2 = watch.ElapsedTicks;
            watch.Reset();
            System.Windows.MessageBox.Show(
                "Run time" +
                "\nstep1: " + step1 +
                "\nstep2: " + (step2 - step1)
            );
            #endif
            state.residualMoment = residualMatrix.Determinant();
        }
示例#11
0
		private PointCollection GetPointsFromY(Impeller impeller, double canvasHeight, double canvasWidth)
		{
			var points = new List<Point>(impeller.Y.Count);
			double heightScale = canvasHeight / impeller.Y.Max();
			double widthScale = canvasWidth / impeller.MSections.Max(sec => sec.Position);

			points.Add(new Point(0, canvasHeight));
			for (int i = 0; i < impeller.Y.Count; i++)
			{
				points.Add(new Point(impeller.MSections[i].Position * widthScale, canvasHeight - impeller.Y[i] * heightScale));
			}
			return new PointCollection(points);
		}
示例#12
0
		private Impeller FullSectionsDepartor(List<FullSection> fullSections, Impeller target)
		{
			fullSections = fullSections.OrderBy(sec => sec.Position).ToList();

			target.MSections = new List<MechanicalSection>(fullSections.Count);
			target.PSections = new List<PhysicalSection>(fullSections.Count);
			foreach (var section in fullSections)
			{
				target.MSections.Add(new MechanicalSection(section.Position, section.InertiaMoment, section.Mass));
				target.PSections.Add(new PhysicalSection(section.Position, section.InertiaMoment, section.Area));
			}
			return target;
		}
示例#13
0
		private void ShowProgressBar(Impeller impeller, ProhlState state)
		{
			progressBar.Dispatcher.Invoke(new Action(() =>
			{
				progressBar.Value = state.Omega;
			}), System.Windows.Threading.DispatcherPriority.ContextIdle);
		}
示例#14
0
		private string ShowResult(Impeller impeller, CalculateMethod method)
		{
			string resultString = "";
			StringBuilder yString = new StringBuilder();

			switch (method)
			{
				case CalculateMethod.Rayleigh:
					for (int i = 0; i < Impeller.InnerImpeller.Y.Count; i++)
					{
						yString
							.Append(Impeller.InnerImpeller.MSections[i].Position.ToString())
							.Append(" : ")
							.Append(Impeller.InnerImpeller.Y[i].ToString())
							.Append("\n");
					}
					resultString = "计算方法:Rayleigh法"
						+ "\n一阶固有频率:" + Impeller.InnerImpeller.LegacyVibrationFrequency.ToString() + " Hz"
						+ "\n\n振型(位置,单位m : 振幅,单位m)\n"
						+ yString.ToString();
					break;
				case CalculateMethod.Iteration:
					for (int i = 0; i < Impeller.InnerImpeller.Y.Count; i++)
					{
						yString
							.Append(Impeller.InnerImpeller.PSections[i].Position.ToString())
							.Append(" : ")
							.Append(Impeller.InnerImpeller.Y[i].ToString())
							.Append("\n");
					}
					resultString = "计算方法:振型迭代法"
						+ "\n迭代次数:" + Impeller.InnerImpeller.IterationCount
						+ "\n一阶固有频率: " + Impeller.InnerImpeller.LegacyVibrationFrequency.ToString() + " Hz"
						+ "\n\n振型(位置,单位m : 振幅,相对值)\n"
						+ yString.ToString();
					break;
				case CalculateMethod.Prohl:
					int power = 1;
					resultString = "计算方法:Prohl传递矩阵法"
						+ "\n检测次数:" + (Impeller.InnerImpeller.IterationCount + 1).ToString();
					foreach (var freq in Impeller.InnerImpeller.VibrationFrequency)
					{
						resultString += "\n" + (power++) + "阶固有频率: " + freq + " Hz";
					}
					break;
				default:
					break;
			}

			return resultString;
		}