Ejemplo n.º 1
0
        private unsafe void IntersectionSearch(double *y, double *dydx, double hupper, KerrBlackHoleEquation equation)
        {
            double hlower = 0.0;

            equation.Function(y, dydx);

            while ((y[0] > equation.Rhor) && (y[0] < equation.R0 * 2))
            {
                double *yout = stackalloc double[equation.N];
                double *yerr = stackalloc double[equation.N];

                double hdiff = hupper - hlower;

                if (Math.Abs(hdiff) < 1e-7)
                {
                    RungeKutta.IntegrateStep(equation, y, dydx, hupper, yout, yerr);

                    Util.memcpy((IntPtr)y, (IntPtr)yout, equation.N * sizeof(double));
                    return;
                }

                double hmid = (hupper + hlower) / 2;

                RungeKutta.IntegrateStep(equation, y, dydx, hmid, yout, yerr);

                if (yout[0] < equation.R0)
                {
                    hlower = hmid;
                }
                else
                {
                    hupper = hmid;
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Use Runge-Kutta steps to find intersection with horizontal plane of the scene.
        /// This is necessary to stop integrating when the ray hits the accretion disc.
        /// </summary>
        private unsafe void IntersectionSearch(double *y, double *dydx, double hupper, KerrBlackHoleEquation equation)
        {
            double hlower = 0.0;

            int side;

            if (y[1] > Math.PI / 2)
            {
                side = 1;
            }
            else if (y[1] < Math.PI / 2)
            {
                side = -1;
            }
            else
            {
                // unlikely, but needs to handle a situation when ray hits the plane EXACTLY
                return;
            }

            equation.Function(y, dydx);

            while ((y[0] > equation.Rhor) && (y[0] < equation.R0) && (side != 0))
            {
                double *yout = stackalloc double[equation.N];
                double *yerr = stackalloc double[equation.N];

                double hdiff = hupper - hlower;

                if (Math.Abs(hdiff) < 1e-7)
                {
                    RungeKutta.IntegrateStep(equation, y, dydx, hupper, yout, yerr);

                    Util.memcpy((IntPtr)y, (IntPtr)yout, equation.N * sizeof(double));

                    return;
                }

                double hmid = (hupper + hlower) / 2;

                RungeKutta.IntegrateStep(equation, y, dydx, hmid, yout, yerr);

                if (side * (yout[1] - Math.PI / 2) > 0)
                {
                    hlower = hmid;
                }
                else
                {
                    hupper = hmid;
                }
            }
        }
Ejemplo n.º 3
0
        protected unsafe void IntersectionSearch(double *y, double *dydx, double hupper, KerrBlackHoleEquation equation)
        {
            double hlower = 0.0;
            double tempX = 0, tempY = 0, tempZ = 0;

            equation.Function(y, dydx);

            while ((y[0] > equation.Rhor) && (y[0] < equation.R0))
            {
                double *yout = stackalloc double[equation.N];
                double *yerr = stackalloc double[equation.N];

                double hdiff = hupper - hlower;

                if (Math.Abs(hdiff) < 1e-7)
                {
                    RungeKutta.IntegrateStep(equation, y, dydx, hupper, yout, yerr);

                    Util.memcpy((IntPtr)y, (IntPtr)yout, equation.N * sizeof(double));
                    return;
                }

                double hmid = (hupper + hlower) / 2;

                RungeKutta.IntegrateStep(equation, y, dydx, hmid, yout, yerr);

                Util.ToCartesian(yout[0], yout[1], yout[2], ref tempX, ref tempY, ref tempZ);
                double distance = Math.Sqrt((tempX - centerX) * (tempX - centerX)
                                            + (tempY - centerY) * (tempY - centerY)
                                            + (tempZ - centerZ) * (tempZ - centerZ));

                if (distance > radius)
                {
                    hlower = hmid;
                }
                else
                {
                    hupper = hmid;
                }
            }
        }