/// <summary>
        /// Copy constructor
        /// </summary>
        public EthierSteinmanDomain(EthierSteinmanDomain old)
        {
            Nx = old.Nx;
            Ny = old.Ny;
            Nz = old.Nz;

            hx = old.hx;
            hy = old.hy;
            hz = old.hz;

            length_x = old.length_x;
            length_y = old.length_y;
            length_z = old.length_z;

            boundary_cells    = old.boundary_cells;
            obstacle_cells    = old.obstacle_cells;
            boundary_normal_x = old.boundary_normal_x;
            boundary_normal_y = old.boundary_normal_y;
            boundary_normal_z = old.boundary_normal_z;
            boundary_u        = old.boundary_u;
            boundary_v        = old.boundary_v;
            boundary_w        = old.boundary_w;
        }
Beispiel #2
0
        static void Main()
        {
            const double EPS = 1e-8;

            // This test varies dt and viscosity while keeping N fixed
            int N = 64;

            double[] dt = new double[] { 1.0 / 50, 1.0 / 100, 1.0 / 200, 1.0 / 400 };
            double[] nu = new double[] { 1, 0.1, 0.01, 0.001 };

            String fname = "convergence_h64_t.txt";

            // Constants needed for exact solution
            double a = 1.25;
            double d = 2.25;

            double tf = 1.0 / 10;

            // Create structure for solver parameters
            FluidSolver.solver_struct solver_prams = new FluidSolver.solver_struct();

            solver_prams.tol             = 1e-5;
            solver_prams.min_iter        = 1;
            solver_prams.max_iter        = 20;
            solver_prams.verbose         = false;
            solver_prams.backtrace_order = 2;

            using (StreamWriter sw = new StreamWriter(fname))
            {
                // Loop over viscosities
                for (int r = 0; r < nu.Length; r++)
                {
                    sw.WriteLine("nu = {0}", nu[r]);

                    // Loop over time step sizes
                    for (int n = 0; n < dt.Length; n++)
                    {
                        Console.WriteLine("Starting simulation for dt = {0} and nu = {1}", dt[n], nu[r]);

                        sw.WriteLine("N dt  err_l2_u  err_l2_v    err_l2_w    err_l2_p    " +
                                     "err_inf_u   err_inf_v   err_inf_w   err_inf_p");

                        double t = 0;
                        int    Nx, Ny, Nz;
                        Nx = Ny = Nz = N;

                        double err_l2_u, err_l2_v, err_l2_w, err_l2_p;
                        double err_inf_u, err_inf_v, err_inf_w, err_inf_p;

                        double hx = 1.0 / Nx;
                        double hy = 1.0 / Ny;
                        double hz = 1.0 / Nz;

                        /*****************************************************************************************
                        * Set up initial conditions
                        *****************************************************************************************/
                        double[, ,] u0 = new double[Nx + 1, Ny + 2, Nz + 2];
                        double[, ,] v0 = new double[Nx + 2, Ny + 1, Nz + 2];
                        double[, ,] w0 = new double[Nx + 2, Ny + 2, Nz + 1];

                        double[, ,] f_x = new double[Nx + 1, Ny + 2, Nz + 2];
                        double[, ,] f_y = new double[Nx + 2, Ny + 1, Nz + 2];
                        double[, ,] f_z = new double[Nx + 2, Ny + 2, Nz + 1];

                        for (int i = 0; i < Nx + 1; i++)
                        {
                            for (int j = 0; j < Ny + 2; j++)
                            {
                                for (int k = 0; k < Nz + 2; k++)
                                {
                                    double x = i * hx;
                                    double y = (j - 0.5) * hy;
                                    double z = (k - 0.5) * hz;

                                    u0[i, j, k] = -a * (Math.Exp(a * x) * Math.Sin(a * y + d * z) +
                                                        Math.Exp(a * z) * Math.Cos(a * x + d * y));
                                }
                            }
                        }

                        for (int i = 0; i < Nx + 2; i++)
                        {
                            for (int j = 0; j < Ny + 1; j++)
                            {
                                for (int k = 0; k < Nz + 2; k++)
                                {
                                    double x = (i - 0.5) * hx;
                                    double y = j * hy;
                                    double z = (k - 0.5) * hz;

                                    v0[i, j, k] = -a * (Math.Exp(a * y) * Math.Sin(a * z + d * x) +
                                                        Math.Exp(a * x) * Math.Cos(a * y + d * z));
                                }
                            }
                        }

                        for (int i = 0; i < Nx + 2; i++)
                        {
                            for (int j = 0; j < Ny + 2; j++)
                            {
                                for (int k = 0; k < Nz + 1; k++)
                                {
                                    double x = (i - 0.5) * hx;
                                    double y = (j - 0.5) * hy;
                                    double z = k * hz;

                                    w0[i, j, k] = -a * (Math.Exp(a * z) * Math.Sin(a * x + d * y) +
                                                        Math.Exp(a * y) * Math.Cos(a * z + d * x));
                                }
                            }
                        }

                        // Create domain
                        EthierSteinmanDomain omega = new EthierSteinmanDomain(Nx + 2, Ny + 2, Nz + 2, nu[r], a, d);

                        // Create FFD solver
                        FluidSolver ffd = new FluidSolver(omega, dt[n], nu[r], u0, v0, w0, solver_prams);

                        /********************************************************************************
                         * Run time loop
                         **********************************************************************************/
                        while (Math.Abs(t - tf) > EPS)
                        {
                            t += dt[n];

                            Console.WriteLine("Time t = {0}", t);

                            // Update boundary conditions and solve single time step
                            omega.update_boundary_conditions(t);
                            ffd.time_step(f_x, f_y, f_z);
                        }

                        /*************************************************************************************
                         * Caclulate errors
                         ************************************************************************************/
                        Utilities.calculate_errors(ffd, omega, out err_l2_u, out err_inf_u, t, 2);
                        Utilities.calculate_errors(ffd, omega, out err_l2_v, out err_inf_v, t, 3);
                        Utilities.calculate_errors(ffd, omega, out err_l2_w, out err_inf_w, t, 4);
                        Utilities.calculate_errors(ffd, omega, out err_l2_p, out err_inf_p, t, 1);

                        Console.WriteLine("u : L2 error = {0}, L infinity error = {1}", err_l2_u, err_inf_u);
                        Console.WriteLine("v : L2 error = {0}, L infinity error = {1}", err_l2_v, err_inf_v);
                        Console.WriteLine("w : L2 error = {0}, L infinity error = {1}", err_l2_w, err_inf_w);
                        Console.WriteLine("p : L2 error = {0}, L infinity error = {1}", err_l2_p, err_inf_p);

                        sw.WriteLine("{0}  {1} {2} {3} {4} {5} {6} {7} {8}  {9}", N, dt[n], err_l2_u, err_l2_v, err_l2_w,
                                     err_l2_p, err_inf_u, err_inf_v, err_inf_w, err_inf_p);

                        sw.Flush();
                    }

                    sw.WriteLine();
                }
            }
        }