Ejemplo n.º 1
0
        public static System.Double SolveDouble(long timesteps, DataDouble data)
        {
            //Convenience indices
            R RN  = R.El(data.N);          //Same as [n]
            R RN1 = R.El(data.N + 1);      //Same as [n+1]

            System.Double g       = 9.8f;  // gravitational constant
            System.Double dt      = 0.02f; // hardwired timestep
            System.Double dx      = 1.0f;
            System.Double dy      = 1.0f;
            long          droploc = data.N / 4;

            var H  = data.H;
            var U  = data.U;
            var V  = data.V;
            var Hx = data.Hx;
            var Ux = data.Ux;
            var Vx = data.Vx;
            var Hy = data.Hy;
            var Uy = data.Uy;
            var Vy = data.Vy;

            //Splash!!!
            H[droploc, droploc] += 5.0f;

            for (int i = 0; i < timesteps; i++)
            {
                H.Flush();
                // Reflecting boundary conditions
                H[ALL, FIRST] = H[ALL, SECOND];
                U[ALL, FIRST] = U[ALL, SECOND];
                V[ALL, FIRST] = -V[ALL, SECOND];
                H[ALL, RN1]   = H[ALL, RN];
                U[ALL, RN1]   = U[ALL, RN];
                V[ALL, RN1]   = -V[ALL, RN];
                H[FIRST, ALL] = H[SECOND, ALL];
                U[FIRST, ALL] = -U[SECOND, ALL];
                V[FIRST, ALL] = V[SECOND, ALL];
                H[RN1, ALL]   = H[RN, ALL];
                U[RN1, ALL]   = -U[RN, ALL];
                V[RN1, ALL]   = V[RN, ALL];

                //First half-step

                //Height
                Hx[ALL, R.Slice(0, -1)] = (H[SKIP1, INNER] + H[ZM1, INNER]) / 2 -
                                          dt / (2 * dx) * (U[SKIP1, INNER] - U[ZM1, INNER]);

                //x momentum
                Ux[ALL, R.Slice(0, -1)] = (U[SKIP1, INNER] + U[ZM1, INNER]) / 2 -
                                          dt / (2 * dx) * ((U[SKIP1, INNER].Pow(2) / H[SKIP1, INNER] +
                                                            g / 2 * H[SKIP1, INNER].Pow(2)) -
                                                           (U[ZM1, INNER].Pow(2) / H[ZM1, INNER] +
                                                            g / 2 * H[ZM1, INNER].Pow(2)));

                // y momentum
                Vx[ALL, ZM1] = (V[SKIP1, INNER] + V[ZM1, INNER]) / 2 -
                               dt / (2 * dx) * ((U[SKIP1, INNER] *
                                                 V[SKIP1, INNER] / H[SKIP1, INNER]) -
                                                (U[ZM1, INNER] *
                                                 V[ZM1, INNER] / H[ZM1, INNER]));



                // height
                Hy[ZM1, ALL] = (H[INNER, SKIP1] + H[INNER, ZM1]) / 2 -
                               dt / (2 * dy) * (V[INNER, SKIP1] - V[INNER, ZM1]);

                // x momentum
                Uy[ZM1, ALL] = (U[INNER, SKIP1] + U[INNER, ZM1]) / 2 -
                               dt / (2 * dy) * ((V[INNER, SKIP1] *
                                                 U[INNER, SKIP1] / H[INNER, SKIP1]) -
                                                (V[INNER, ZM1] *
                                                 U[INNER, ZM1] / H[INNER, ZM1]));
                // y momentum
                Vy[ZM1, ALL] = (V[INNER, SKIP1] + V[INNER, ZM1]) / 2 -
                               dt / (2 * dy) * ((V[INNER, SKIP1].Pow(2) / H[INNER, SKIP1] +
                                                 g / 2 * H[INNER, SKIP1].Pow(2)) -
                                                (V[INNER, ZM1].Pow(2) / H[INNER, ZM1] +
                                                 g / 2 * H[INNER, ZM1].Pow(2)));

                // Second half step

                // height
                H[INNER, INNER] = H[INNER, INNER] -
                                  (dt / dx) * (Ux[SKIP1, ZM1] - Ux[ZM1, ZM1]) -
                                  (dt / dy) * (Vy[ZM1, SKIP1] - Vy[ZM1, ZM1]);

                // x momentum
                U[INNER, INNER] = U[INNER, INNER] -
                                  (dt / dx) * ((Ux[SKIP1, ZM1].Pow(2) / Hx[SKIP1, ZM1] +
                                                g / 2 * Hx[SKIP1, ZM1].Pow(2)) -
                                               (Ux[ZM1, ZM1].Pow(2) / Hx[ZM1, ZM1] +
                                                g / 2 * Hx[ZM1, ZM1].Pow(2))) -
                                  (dt / dy) * ((Vy[ZM1, SKIP1] *
                                                Uy[ZM1, SKIP1] / Hy[ZM1, SKIP1]) -
                                               (Vy[ZM1, ZM1] *
                                                Uy[ZM1, ZM1] / Hy[ZM1, ZM1]));
                // y momentum
                V[R.Slice(1, -1), R.Slice(1, -1)] = V[R.Slice(1, -1), R.Slice(1, -1)] -
                                                    (dt / dx) * ((Ux[SKIP1, ZM1] *
                                                                  Vx[SKIP1, ZM1] / Hx[SKIP1, ZM1]) -
                                                                 (Ux[ZM1, ZM1] * Vx[ZM1, ZM1] / Hx[ZM1, ZM1])) -
                                                    (dt / dy) * ((Vy[ZM1, SKIP1].Pow(2) / Hy[ZM1, SKIP1] +
                                                                  g / 2 * Hy[ZM1, SKIP1].Pow(2)) -
                                                                 (Vy[ZM1, ZM1].Pow(2) / Hy[ZM1, ZM1] +
                                                                  g / 2 * Hy[ZM1, ZM1].Pow(2)));
            }
            //Make sure we have the actual data and use it as a checksum
            return(NumCIL.Double.Add.Reduce(NumCIL.Double.Add.Reduce(H / data.N)).Value[0]);
        }
Ejemplo n.º 2
0
        public static T Solve(long n, long timesteps)
        {
            //Convenience indices
            R RN  = R.El(n);      //Same as [n]
            R RN1 = R.El(n + 1);  //Same as [n+1]

            T    g       = 9.8f;  // gravitational constant
            T    dt      = 0.02f; // hardwired timestep
            T    dx      = 1.0f;
            T    dy      = 1.0f;
            long droploc = n / 4;

            var H  = Generate.Ones(n + 2, n + 2);
            var U  = Generate.Ones(n + 2, n + 2);
            var V  = Generate.Ones(n + 2, n + 2);
            var Hx = Generate.Ones(n + 1, n + 1);
            var Ux = Generate.Ones(n + 1, n + 1);
            var Vx = Generate.Ones(n + 1, n + 1);
            var Hy = Generate.Ones(n + 1, n + 1);
            var Uy = Generate.Ones(n + 1, n + 1);
            var Vy = Generate.Ones(n + 1, n + 1);

            //Splash!!!
            H[droploc, droploc] += 5.0f;

            for (int i = 0; i < timesteps; i++)
            {
                H.Flush();

                // Reflecting boundary conditions
                H[ALL, FIRST] = H[ALL, SECOND];
                U[ALL, FIRST] = U[ALL, SECOND];
                V[ALL, FIRST] = -V[ALL, SECOND];
                H[ALL, RN1]   = H[ALL, RN];
                U[ALL, RN1]   = U[ALL, RN];
                V[ALL, RN1]   = -V[ALL, RN];
                H[FIRST, ALL] = H[SECOND, ALL];
                U[FIRST, ALL] = -U[SECOND, ALL];
                V[FIRST, ALL] = V[SECOND, ALL];
                H[RN1, ALL]   = H[RN, ALL];
                U[RN1, ALL]   = -U[RN, ALL];
                V[RN1, ALL]   = V[RN, ALL];

                //First half-step

                //Height
                Hx[ALL, R.Slice(0, -1)] = (H[SKIP1, INNER] + H[ZM1, INNER]) / 2 -
                                          dt / (2 * dx) * (U[SKIP1, INNER] - U[ZM1, INNER]);

                //x momentum
                Ux[ALL, R.Slice(0, -1)] = (U[SKIP1, INNER] + U[ZM1, INNER]) / 2 -
                                          dt / (2 * dx) * ((U[SKIP1, INNER].Pow(2) / H[SKIP1, INNER] +
                                                            g / 2 * H[SKIP1, INNER].Pow(2)) -
                                                           (U[ZM1, INNER].Pow(2) / H[ZM1, INNER] +
                                                            g / 2 * H[ZM1, INNER].Pow(2)));

                // y momentum
                Vx[ALL, ZM1] = (V[SKIP1, INNER] + V[ZM1, INNER]) / 2 -
                               dt / (2 * dx) * ((U[SKIP1, INNER] *
                                                 V[SKIP1, INNER] / H[SKIP1, INNER]) -
                                                (U[ZM1, INNER] *
                                                 V[ZM1, INNER] / H[ZM1, INNER]));



                // height
                Hy[ZM1, ALL] = (H[INNER, SKIP1] + H[INNER, ZM1]) / 2 -
                               dt / (2 * dy) * (V[INNER, SKIP1] - V[INNER, ZM1]);

                // x momentum
                Uy[ZM1, ALL] = (U[INNER, SKIP1] + U[INNER, ZM1]) / 2 -
                               dt / (2 * dy) * ((V[INNER, SKIP1] *
                                                 U[INNER, SKIP1] / H[INNER, SKIP1]) -
                                                (V[INNER, ZM1] *
                                                 U[INNER, ZM1] / H[INNER, ZM1]));
                // y momentum
                Vy[ZM1, ALL] = (V[INNER, SKIP1] + V[INNER, ZM1]) / 2 -
                               dt / (2 * dy) * ((V[INNER, SKIP1].Pow(2) / H[INNER, SKIP1] +
                                                 g / 2 * H[INNER, SKIP1].Pow(2)) -
                                                (V[INNER, ZM1].Pow(2) / H[INNER, ZM1] +
                                                 g / 2 * H[INNER, ZM1].Pow(2)));

                // Second half step

                // height
                H[INNER, INNER] = H[INNER, INNER] -
                                  (dt / dx) * (Ux[SKIP1, ZM1] - Ux[ZM1, ZM1]) -
                                  (dt / dy) * (Vy[ZM1, SKIP1] - Vy[ZM1, ZM1]);

                // x momentum
                U[INNER, INNER] = U[INNER, INNER] -
                                  (dt / dx) * ((Ux[SKIP1, ZM1].Pow(2) / Hx[SKIP1, ZM1] +
                                                g / 2 * Hx[SKIP1, ZM1].Pow(2)) -
                                               (Ux[ZM1, ZM1].Pow(2) / Hx[ZM1, ZM1] +
                                                g / 2 * Hx[ZM1, ZM1].Pow(2))) -
                                  (dt / dy) * ((Vy[ZM1, SKIP1] *
                                                Uy[ZM1, SKIP1] / Hy[ZM1, SKIP1]) -
                                               (Vy[ZM1, ZM1] *
                                                Uy[ZM1, ZM1] / Hy[ZM1, ZM1]));
                // y momentum
                V[R.Slice(1, -1), R.Slice(1, -1)] = V[R.Slice(1, -1), R.Slice(1, -1)] -
                                                    (dt / dx) * ((Ux[SKIP1, ZM1] *
                                                                  Vx[SKIP1, ZM1] / Hx[SKIP1, ZM1]) -
                                                                 (Ux[ZM1, ZM1] * Vx[ZM1, ZM1] / Hx[ZM1, ZM1])) -
                                                    (dt / dy) * ((Vy[ZM1, SKIP1].Pow(2) / Hy[ZM1, SKIP1] +
                                                                  g / 2 * Hy[ZM1, SKIP1].Pow(2)) -
                                                                 (Vy[ZM1, ZM1].Pow(2) / Hy[ZM1, ZM1] +
                                                                  g / 2 * Hy[ZM1, ZM1].Pow(2)));
            }

            //Make sure we have the actual data and use it as a checksum
            return(Add.Reduce(Add.Reduce(H / n)).Value[0]);
        }