示例#1
0
        private void calculate(double lower, double upper)
        {
            if (rb_Math.Checked == true)
            {
                DrawCurve       math1 = new DrawCurve();
                MathematicaLink math2 = new MathematicaLink();
                this.Cursor = Cursors.WaitCursor;
                HookUp(math1);
                int choice = lb_curvature.SelectedIndex;
                rangeV         = range[choice];
                txt_range.Text = rangeV.ToString();
                math1.SolveAcurate(math2, kappa[choice], rangeV.ToString());

                this.Cursor = Cursors.Arrow;
            }
            else if (rb_Euler.Checked == true)
            {
                DrawCurve rk4 = new DrawCurve();
                this.Cursor = Cursors.WaitCursor;
                HookUp(rk4);
                int choice = lb_curvature.SelectedIndex + 1;
                rk4.SolveFast(rk4, choice, lower, upper);
                this.Cursor = Cursors.Arrow;
            }
        }
示例#2
0
        //Hookup
        public void HookUp(DrawCurve data)
        {
            currentData                         = data;
            chr_2Dcurve.DataSource              = currentData.Bsdata;
            chr_2Dcurve.Series[0].XValueMember  = "X";
            chr_2Dcurve.Series[0].YValueMembers = "Y";

            currentData.Bsdata.ListChanged += new ListChangedEventHandler(Bsdata_ListChanged);
        }
示例#3
0
        public void SolveFast(DrawCurve instance, int choice, double lower, double upper)
        {
            List <Vector>[] out1;
            List <Vector>   out2 = new List <Vector>();

            solution.Clear();
            bsdata.DataSource = null;
            List <Vector>[] test  = this.RK4(new double[] { 0, 1, 0 }, lower, upper, 10000, choice);
            List <Vector>[] test2 = this.RK4(new double[] { 0, 0, 0.1 }, lower, upper, 10000, choice);
            //List<Vector>[] test = this.RKF(new double[] { 0, 1, 0 }, lower, upper, 10000, choice);
            //List<Vector>[] test2 = this.RKF(new double[] { 0, 0, 0.1 }, lower, upper, 10000, choice);
            for (int i = 0; i < test[0].Count; i++)
            {
                out2.Add(new Vector(test[0][i].Y, test2[0][i].Y, 0));
                solution.Add(new Vector(Math.Round(test[0][i].Y, 5), Math.Round(test2[0][i].Y, 5), 0));
            }
            out1 = new List <Vector>[] { out2 };
            OutputToFile(out1, "testOut", new double[] { 0, 6 }, 10);
            bsdata.DataSource = solution;
        }
示例#4
0
        /// <summary>
        /// A method for computing a solution to a third order IVP ODE using RK4
        /// </summary>
        /// <param name="f1">The first function to be solved</param>
        /// <param name="f2">The second function to be solved</param>
        /// <param name="f3">The third function to be solved</param>
        /// <param name="y0">The initial values for the system</param>
        /// <param name="a">The lower bound to the range</param>
        /// <param name="b">The upper bound to the range</param>
        /// <param name="NumSteps">The number of steps to take in the range</param>
        /// <returns>A list of points calculated by the function</returns>
        public List <Vector>[] RK4(double[] y0, double a, double b, int NumSteps, int choice)
        {
            List <Vector> odesol1 = new List <Vector>();

            double h  = (Math.Max(a, b) - Math.Min(a, b)) / (NumSteps - 1.0);
            double xt = a;

            double[] yNew  = y0, yOld = new double[yNew.Length];
            int      i     = 0;
            double   deriv = 0;


            Function udash  = x => x[2];
            Function u2dash = x => x[3];
            Function u3dash = x => x[0];
            Function kappa1 = x => (1.0 / 3.0) + Math.Sin(x[0]);
            Function kappa2 = x => (1.0 / 5.0) + 2 * Math.Sin(x[0]) + 3 * Math.Cos(x[0] / 3.0);
            Function kappa3 = x => (1.0 / 5.0) + Math.Sin(x[0] / 2.0) - Math.Cos(x[0] / 3.0);
            Function kappa4 = x => (1.0 / 5.0) + Math.Sin(x[0] / 3.0) + 2 * Math.Cos(x[0] / 2.0);
            Function kappa5 = x => (1.0 / 10.0) + Math.Sin(x[0]);
            Function kappa6 = x => 1 + (3.0 / (5 + 4 * Math.Cos(x[0]))) * (3);
            Function kappa7 = x => 1 + (3.0 / (5 + 4 * Math.Cos(x[0]))) * (4);

            while (i < NumSteps)
            {
                switch (choice)
                {
                case (1):
                    deriv  = DrawCurve.RichardsonWithError(kappa1, xt, 1E-6, 10000, 1E-9);
                    u3dash = x => (deriv / ((1.0 / 3.0) + Math.Sin(x[0]))) * x[3] - (((1.0 / 3.0) + Math.Sin(x[0])) * ((1.0 / 3.0) + Math.Sin(x[0])) * x[2]);
                    break;

                case (2):
                    deriv  = DrawCurve.RichardsonWithError(kappa2, xt, 1E-6, 10000, 1E-9);
                    u3dash = x => (deriv / ((1.0 / 5.0) + 2 * Math.Sin(x[0]) + 3 * Math.Cos(x[0] / 3.0))) * x[3] - (((1.0 / 5.0) + 2 * Math.Sin(x[0]) + 3 * Math.Cos(x[0] / 3.0)) * ((1.0 / 5.0) + 2 * Math.Sin(x[0]) + 3 * Math.Cos(x[0] / 3.0)) * x[2]);;
                    break;

                case (3):
                    deriv  = DrawCurve.RichardsonWithError(kappa3, xt, 1E-6, 10000, 1E-9);
                    u3dash = x => (deriv / ((1.0 / 5.0) + Math.Sin(x[0] / 2.0) - Math.Cos(x[0] / 3.0))) * x[3] - (((1.0 / 5.0) + Math.Sin(x[0] / 2.0) - Math.Cos(x[0] / 3.0)) * ((1.0 / 5.0) + Math.Sin(x[0] / 2.0) - Math.Cos(x[0] / 3.0)) * x[2]);
                    break;

                case (4):
                    deriv  = DrawCurve.RichardsonWithError(kappa4, xt, 1E-6, 10000, 1E-9);
                    u3dash = x => (deriv / ((1.0 / 5.0) + Math.Sin(x[0] / 3.0) + 2 * Math.Cos(x[0] / 2.0))) * x[3] - (((1.0 / 5.0) + Math.Sin(x[0] / 3.0) + 2 * Math.Cos(x[0] / 2.0)) * ((1.0 / 5.0) + Math.Sin(x[0] / 3.0) + 2 * Math.Cos(x[0] / 2.0)) * x[2]);
                    break;

                case (5):
                    deriv  = DrawCurve.RichardsonWithError(kappa5, xt, 1E-6, 10000, 1E-9);
                    u3dash = x => (deriv / ((1.0 / 10.0) + Math.Sin(x[0]))) * x[3] - (((1.0 / 10.0) + Math.Sin(x[0])) * ((1.0 / 10.0) + Math.Sin(x[0])) * x[2]);
                    break;

                case (6):
                    deriv  = DrawCurve.RichardsonWithError(kappa6, xt, 1E-6, 10000, 1E-9);
                    u3dash = x => (deriv / (1 + (3.0 / (5 + 4 * Math.Cos(x[0]))) * (3))) * x[3] - ((1 + (3.0 / (5 + 4 * Math.Cos(x[0]))) * (3)) * (1 + (3.0 / (5 + 4 * Math.Cos(x[0]))) * (3)) * x[2]);
                    break;

                case (7):
                    deriv  = DrawCurve.RichardsonWithError(kappa7, xt, 1E-6, 10000, 1E-9);
                    u3dash = x => (deriv / (1 + (3.0 / (5 + 4 * Math.Cos(x[0]))) * (4))) * x[3] - ((1 + (3.0 / (5 + 4 * Math.Cos(x[0]))) * (4)) * (1 + (3.0 / (5 + 4 * Math.Cos(x[0]))) * (4)) * x[2]);
                    break;

                default:
                    deriv  = DrawCurve.RichardsonWithError(kappa1, xt, 1E-6, 10000, 1E-9);
                    u3dash = x => (deriv / ((1.0 / 3.0) + Math.Sin(x[0]))) * x[3] - (((1.0 / 3.0) + Math.Sin(x[0])) * ((1.0 / 3.0) + Math.Sin(x[0])) * x[2]);
                    break;
                }
                odesol1.Add(new Vector(xt, yNew[0], 0));
                for (int j = 0; j < yNew.Length; j++)
                {
                    yOld[j] = yNew[j];
                }
                yNew = RK4Step(udash, u2dash, u3dash, xt, h, yOld);
                xt   = xt + h;
                i++;
            }
            return(new List <Vector>[] { odesol1 });
        }
示例#5
0
        /// <summary>
        /// A method for computing a solution to a third order IVP ODE using RKF
        /// </summary>
        /// <param name="f1">The first function to be solved</param>
        /// <param name="f2">The second function to be solved</param>
        /// <param name="f3">The third function to be solved</param>
        /// <param name="y0">The initial values for the system</param>
        /// <param name="a">The lower bound to the range</param>
        /// <param name="b">The upper bound to the range</param>
        /// <param name="NumSteps">The number of steps to take in the range</param>
        /// <returns>A list of points calculated by the function</returns>
        public List <Vector>[] RKF(double[] y0, double a, double b, int NumSteps, int choice)
        {
            List <Vector> odesol1 = new List <Vector>();
            double        h = (Math.Max(a, b) - Math.Min(a, b)) / (NumSteps - 1.0);
            double        xt = a, x0 = 0;

            double[]        yNew       = y0, yOld = new double[yNew.Length];
            int             i          = 0;
            double          deriv      = 0;
            List <double[]> resultStep = new List <double[]>();
            //double tolerance = 1E-9;
            double err = 0, tol = 1E-4, /*maxErr = 0, delta = 0,*/ s = 0;

            double hmin = 1E-9;
            double hmax = 5;

            Function udash  = x => x[2];
            Function u2dash = x => x[3];
            Function u3dash = x => x[0];
            Function kappa1 = x => (1.0 / 3.0) + Math.Sin(x[0]);
            Function kappa2 = x => (1.0 / 5.0) + 2 * Math.Sin(x[0]) + 3 * Math.Cos(x[0] / 3.0);
            Function kappa3 = x => (1.0 / 5.0) + Math.Sin(x[0] / 2.0) - Math.Cos(x[0] / 3.0);
            Function kappa4 = x => (1.0 / 5.0) + Math.Sin(x[0] / 3.0) + 2 * Math.Cos(x[0] / 2.0);
            Function kappa5 = x => (1.0 / 10.0) + Math.Sin(x[0]);
            Function kappa6 = x => 1 + (3.0 / (5 + 4 * Math.Cos(x[0]))) * (3);
            Function kappa7 = x => 1 + (3.0 / (5 + 4 * Math.Cos(x[0]))) * (4);

            while (i < NumSteps)
            {
                /*if (i >= NumSteps)
                 * {
                 *  break;
                 * }*/

                switch (choice)
                {
                case (1):
                    deriv  = DrawCurve.RichardsonWithError(kappa1, xt, 1E-6, 10000, 1E-9);
                    u3dash = x => (deriv / ((1.0 / 3.0) + Math.Sin(x[0]))) * x[3] - (((1.0 / 3.0) + Math.Sin(x[0])) * ((1.0 / 3.0) + Math.Sin(x[0])) * x[2]);
                    break;

                case (2):
                    deriv  = DrawCurve.RichardsonWithError(kappa2, xt, 1E-6, 10000, 1E-9);
                    u3dash = x => (deriv / ((1.0 / 5.0) + 2 * Math.Sin(x[0]) + 3 * Math.Cos(x[0] / 3.0))) * x[3] - (((1.0 / 5.0) + 2 * Math.Sin(x[0]) + 3 * Math.Cos(x[0] / 3.0)) * ((1.0 / 5.0) + 2 * Math.Sin(x[0]) + 3 * Math.Cos(x[0] / 3.0)) * x[2]);;
                    break;

                case (3):
                    deriv  = DrawCurve.RichardsonWithError(kappa3, xt, 1E-6, 10000, 1E-9);
                    u3dash = x => (deriv / ((1.0 / 5.0) + Math.Sin(x[0] / 2.0) - Math.Cos(x[0] / 3.0))) * x[3] - (((1.0 / 5.0) + Math.Sin(x[0] / 2.0) - Math.Cos(x[0] / 3.0)) * ((1.0 / 5.0) + Math.Sin(x[0] / 2.0) - Math.Cos(x[0] / 3.0)) * x[2]);
                    break;

                case (4):
                    deriv  = DrawCurve.RichardsonWithError(kappa4, xt, 1E-6, 10000, 1E-9);
                    u3dash = x => (deriv / ((1.0 / 5.0) + Math.Sin(x[0] / 3.0) + 2 * Math.Cos(x[0] / 2.0))) * x[3] - (((1.0 / 5.0) + Math.Sin(x[0] / 3.0) + 2 * Math.Cos(x[0] / 2.0)) * ((1.0 / 5.0) + Math.Sin(x[0] / 3.0) + 2 * Math.Cos(x[0] / 2.0)) * x[2]);
                    break;

                case (5):
                    deriv  = DrawCurve.RichardsonWithError(kappa5, xt, 1E-6, 10000, 1E-9);
                    u3dash = x => (deriv / ((1.0 / 10.0) + Math.Sin(x[0]))) * x[3] - (((1.0 / 10.0) + Math.Sin(x[0])) * ((1.0 / 10.0) + Math.Sin(x[0])) * x[2]);
                    break;

                case (6):
                    deriv  = DrawCurve.RichardsonWithError(kappa6, xt, 1E-6, 10000, 1E-9);
                    u3dash = x => (deriv / (1 + (3.0 / (5 + 4 * Math.Cos(x[0]))) * (3))) * x[3] - ((1 + (3.0 / (5 + 4 * Math.Cos(x[0]))) * (3)) * (1 + (3.0 / (5 + 4 * Math.Cos(x[0]))) * (3)) * x[2]);
                    break;

                case (7):
                    deriv  = DrawCurve.RichardsonWithError(kappa7, xt, 1E-6, 10000, 1E-9);
                    u3dash = x => (deriv / (1 + (3.0 / (5 + 4 * Math.Cos(x[0]))) * (4))) * x[3] - ((1 + (3.0 / (5 + 4 * Math.Cos(x[0]))) * (4)) * (1 + (3.0 / (5 + 4 * Math.Cos(x[0]))) * (4)) * x[2]);
                    break;

                default:
                    deriv  = DrawCurve.RichardsonWithError(kappa5, xt, 1E-6, 10000, 1E-9);
                    u3dash = x => (deriv / ((1.0 / 10.0) + Math.Sin(x[0]))) * x[3] - (((1.0 / 10.0) + Math.Sin(x[0])) * ((1.0 / 10.0) + Math.Sin(x[0])) * x[2]);
                    break;
                }
                odesol1.Add(new Vector(xt, yNew[0], 0));
                for (int j = 0; j < yNew.Length; j++)
                {
                    yOld[j] = yNew[j];
                }
                resultStep = RKFStep(udash, u2dash, u3dash, xt, h, yOld);

                /*for (int j = 0; j < 3; j++)
                 * {
                 *  err = Math.Max(err, resultStep[2][j]);
                 * }*/
                err = resultStep[2][0];
                s   = Math.Pow(0.5 * tol / err, 0.25);

                if (err < tol)
                {
                    yNew = resultStep[0];
                    xt   = x0 + h;
                    x0   = xt;
                }
                if (s < 0.1)
                {
                    s = 0.1;
                }
                else if (s > 4.0)
                {
                    s = 4.0;
                }
                h *= s;
                if (h > b - x0)
                {
                    h = b - x0;
                }
                if (h > hmax)
                {
                    h = hmax;
                }
                else if (h < hmin)
                {
                    h = hmin;
                }
                i++;
                err = 0;
            }
            deriv = 0;
            return(new List <Vector>[] { odesol1 });
        }