コード例 #1
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object can be used to retrieve data from input parameters and
        /// to store data in output parameters.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            //// *********************************************************************************
            ////grasshopper current document
            //// *********************************************************************************
            //Component = this;
            //doc = Component.OnPingDocument();



            // *********************************************************************************
            // get info from grasshopper
            // *********************************************************************************
            List <double> xyzsize = new List <double>();

            if (!DA.GetDataList(0, xyzsize))
            {
                return;
            }
            ;

            List <int> Nxyz = new List <int>();

            if (!DA.GetDataList(1, Nxyz))
            {
                return;
            }
            ;
            int Nx = Nxyz[0];
            int Ny = Nxyz[1];
            int Nz = Nxyz[2];


            List <double[]> geom = new List <double[]>();

            if (!DA.GetDataList(2, geom))
            {
                return;
            }
            ;


            // time step
            double dt = 0.1;

            if (!DA.GetData(3, ref dt))
            {
                return;
            }


            // wind speed
            double Vmet = 10;

            if (!DA.GetData(4, ref Vmet))
            {
                return;
            }

            //terrain type
            int terrain = 0;

            if (!DA.GetData(5, ref terrain))
            {
                return;
            }


            bool run = false;

            if (!DA.GetData(6, ref run))
            {
                return;
            }



            //List<Mesh> mshCp = new List<Mesh>();
            //DA.GetDataList(10, mshCp);
            bool writeresults = false;

            DA.GetData(7, ref writeresults);


            DA.GetData(9, ref resetFFD);


            double nu = 1.511e-5;       // increase viscosity to impose turbulence. the higher velocity, the higher visc., 1e-3

            DA.GetData(10, ref nu);


            // *********************************************************************************
            //from Lukas
            // *********************************************************************************


            // Set initial velocity 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];

            // Create empty arrays for body forces
            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];

            // Create structure for solver parameters
            FluidSolver.solver_struct solver_prams = new FluidSolver.solver_struct();
            solver_prams.tol             = 1e-4;
            solver_prams.min_iter        = 1;
            solver_prams.max_iter        = 30;
            solver_prams.verbose         = false;
            solver_prams.backtrace_order = 2;
            solver_prams.mass_correction = false;
            solver_prams.mass_corr_alpha = 0.7;


            // Create FFD solver and domain
            if (ffd == null)
            {
                omega = new WindInflow(Nx + 2, Ny + 2, Nz + 2, xyzsize[0], xyzsize[1], xyzsize[2], Vmet, terrain);
                foreach (double[] geo in geom)
                {
                    omega.add_obstacle(geo[0], geo[1], geo[2], geo[3], geo[4], geo[5]);
                }

                ffd = new FluidSolver(omega, dt, nu, u0, v0, w0, solver_prams);
                de  = new DataExtractor(omega, ffd);
                t   = 0;
            }

            //reset FFD solver and domain
            if (resetFFD)
            {
                omega = new WindInflow(Nx + 2, Ny + 2, Nz + 2, xyzsize[0], xyzsize[1], xyzsize[2], Vmet, terrain);
                foreach (double[] geo in geom)
                {
                    omega.add_obstacle(geo[0], geo[1], geo[2], geo[3], geo[4], geo[5]);
                }

                ffd      = new FluidSolver(omega, dt, nu, u0, v0, w0, solver_prams);
                de       = new DataExtractor(omega, ffd);
                t        = 0;
                resetFFD = false;
            }



            //run solver. the solving-loop (new timestep) is executed in Grasshopper with a timer-component.
            if (run)
            {
                ffd.time_step(f_x, f_y, f_z);
            }



            // *******************************************************************************************
            // *******************************************************************************************
            // TO DO:   fix this loop with
            //   pp.export_data_vtk(String.Concat("lid_driven_cavity_", tstep, ".vtk"), Nx, Ny, Nz, tstep );
            //bool run2 = (bool)Component.Params.Input[5].Sources[0].VolatileData;
            //while (true)



            //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            // I could move all this shit away, an only output de data extractor

            // *******************************************************************************************
            // *********************************     Output Results       ********************************
            double[, ,] p  = new double[Nx, Ny, Nz];
            double[, ,] vu = new double[Nx, Ny, Nz];
            double[, ,] vv = new double[Nx, Ny, Nz];
            double[, ,] vw = new double[Nx, Ny, Nz];

            double[, ,] pstag  = new double[Nx + 1, Ny + 1, Nz + 1];
            double[, ,] vustag = new double[Nx + 1, Ny + 1, Nz + 1];
            double[, ,] vvstag = new double[Nx + 1, Ny + 1, Nz + 1];
            double[, ,] vwstag = new double[Nx + 1, Ny + 1, Nz + 1];

            for (int i = 0; i < Nx; i++)
            {
                for (int j = 0; j < Ny; j++)
                {
                    for (int k = 0; k < Nz; k++)
                    {
                        if (omega.obstacle_cells[i + 1, j + 1, k + 1] != 1)
                        {
                            p[i, j, k] = de.get_pressure(i * omega.hx + 0.5 * omega.hx, j * omega.hy + 0.5 * omega.hy, k * omega.hz + 0.5 * omega.hz);
                            double[] vel = de.get_velocity(i * omega.hx + 0.5 * omega.hx, j * omega.hy + 0.5 * omega.hy, k * omega.hz + 0.5 * omega.hz);
                            vu[i, j, k] = vel[0];
                            vv[i, j, k] = vel[1];
                            vw[i, j, k] = vel[2];

                            pstag[i, j, k] = de.get_pressure(i * omega.hx, j * omega.hy, k * omega.hz);
                            double[] velcen = de.get_velocity(i * omega.hx, j * omega.hy, k * omega.hz);
                            vustag[i, j, k] = velcen[0];
                            vvstag[i, j, k] = velcen[1];
                            vwstag[i, k, k] = velcen[2];
                        }
                        else
                        {
                            p[i, j, k]  = 0;
                            vu[i, j, k] = 0;
                            vv[i, j, k] = 0;
                            vw[i, j, k] = 0;

                            //pstag[i, j, k] = 0;
                            //vustag[i, j, k] = 0;
                            //vvstag[i, j, k] = 0;
                            //vwstag[i, k, k] = 0;

                            pstag[i, j, k] = de.get_pressure(i * omega.hx, j * omega.hy, k * omega.hz);
                            double[] velcen = de.get_velocity(i * omega.hx, j * omega.hy, k * omega.hz);
                            vustag[i, j, k] = velcen[0];
                            vvstag[i, j, k] = velcen[1];
                            vwstag[i, k, k] = velcen[2];
                        }
                    }
                }
            }

            //last x slice
            for (int j = 0; j < Ny + 1; j++)
            {
                for (int k = 0; k < Nz + 1; k++)
                {
                    pstag[Nx, j, k] = de.get_pressure((Nx) * omega.hx, j * omega.hy, k * omega.hz);
                    double[] vcen = de.get_velocity((Nx) * omega.hx, j * omega.hy, k * omega.hz);
                    vustag[Nx, j, k] = vcen[0];
                    vvstag[Nx, j, k] = vcen[1];
                    vwstag[Nx, j, k] = vcen[2];
                }
            }

            //last y slice
            for (int i = 0; i < Nx + 1; i++)
            {
                for (int k = 0; k < Nz + 1; k++)
                {
                    pstag[i, Ny, k] = de.get_pressure(i * omega.hx, (Ny) * omega.hy, k * omega.hz);
                    double[] vcen = de.get_velocity(i * omega.hx, (Ny) * omega.hy, k * omega.hz);
                    vustag[i, Ny, k] = vcen[0];
                    vvstag[i, Ny, k] = vcen[1];
                    vwstag[i, Ny, k] = vcen[2];
                }
            }

            //last z slice
            for (int i = 0; i < Nx + 1; i++)
            {
                for (int j = 0; j < Ny + 1; j++)
                {
                    pstag[i, j, Nz] = de.get_pressure(i * omega.hx, j * omega.hy, (Nz) * omega.hz);
                    double [] vcen = de.get_velocity(i * omega.hx, j * omega.hy, (Nz) * omega.hz);
                    vustag[i, j, Nz] = vcen[0];
                    vvstag[i, j, Nz] = vcen[1];
                    vwstag[i, j, Nz] = vcen[2];
                }
            }

            List <double[, , ]> veloutCen = new List <double[, , ]> {
            };

            veloutCen.Add(vu);
            veloutCen.Add(vv);
            veloutCen.Add(vw);

            List <double[, , ]> veloutStag = new List <double[, , ]> {
            };

            veloutStag.Add(vustag);
            veloutStag.Add(vvstag);
            veloutStag.Add(vwstag);


            DA.SetDataList(0, veloutCen);
            DA.SetData(1, p);
            DA.SetDataList(2, veloutStag);
            DA.SetData(3, pstag);



            // *******************************************************************************************
            // *******************************      Output Cp values on Surfaces   ***********************
            //if (mshCp.Count > 0)
            if (writeresults)
            {
                ////generate list of objects
                ////  each item contains:
                ////      - 2d matrix of Cp values for each node of the analysis mesh
                ////      - mesh itself
                //List<object[]> mshCpOUT = new List<object[]>();
                //foreach (Mesh msh in mshCp)
                //{
                //    object[] _mshCpout = new object[2] ;
                //    _mshCpout[0] = msh;
                //    //_mshCpout[1]
                //     double [] Cps = new double[msh.Vertices.Count];        //this will be the Cp values. size of array corresponds to mesh vertices
                //    for (int u = 0; u < msh.Vertices.Count; u++)
                //    {
                //        double pref = de.get_pressure(0, msh.Vertices[u].Y, msh.Vertices[u].Z);     //!!! adjust msh to origin and discretisationj
                //        double cp = de.get_pressure(msh.Vertices[u].X, msh.Vertices[u].Y, msh.Vertices[u].Z);
                //        Cps[u] = 1;
                //    }

                //}
                //DA.SetDataList(4, mshCp);


                DA.SetData(4, de);
            }



            // _____________________________________________________________________________________
            // // THIS SHOWS HOW TO ADD A FORM
            //if (f == null)
            //{
            //    f = new LEGACY_Form1();
            //    f.Show(Grasshopper.Instances.DocumentEditor);
            //    Grasshopper.Instances.DocumentEditor.FormShepard.RegisterForm(f);
            //    f.checkBox1.Text = "run the solver";
            //}



            // _____________________________________________________________________________________
            // // THIS SHOWS HOW TO DYNAMICALLY USE GRASSHOPPER SLIDER INPUTS
            //List<Grasshopper.Kernel.Special.GH_NumberSlider> sliders = new List<Grasshopper.Kernel.Special.GH_NumberSlider>();
            //foreach (IGH_Param param in Component.Params.Input)
            //{
            //    Grasshopper.Kernel.Special.GH_NumberSlider slider = param.Sources[0] as Grasshopper.Kernel.Special.GH_NumberSlider;
            //    if (slider != null)
            //    {
            //        sliders.Add(slider);
            //        x = (int)slider.CurrentValue;
            //    }
            //}

            //while (terminate != true)
            //{
            //    doc.NewSolution(false);

            //    fx = x * 10;
            //    maximize(x, fx);
            //    sliders[0].TickValue = xNew;
            //    x = xNew;
            //}
        }
コード例 #2
0
ファイル: GHFFDSolverAytac.cs プロジェクト: whoxinyi/GH_Wind
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            //// *********************************************************************************
            ////grasshopper current document
            //// *********************************************************************************
            //Component = this;
            //doc = Component.OnPingDocument();



            // *********************************************************************************
            // get info from grasshopper
            // *********************************************************************************
            List <double> xyzsize = new List <double>();

            if (!DA.GetDataList(0, xyzsize))
            {
                return;
            }
            ;

            List <int> Nxyz = new List <int>();

            if (!DA.GetDataList(1, Nxyz))
            {
                return;
            }
            ;
            int Nx = Nxyz[0];
            int Ny = Nxyz[1];
            int Nz = Nxyz[2];


            List <double[]> geom = new List <double[]>();

            if (!DA.GetDataList(2, geom))
            {
                return;
            }
            ;


            // time step
            double dt = 0.1;

            if (!DA.GetData(3, ref dt))
            {
                return;
            }


            // wind speed
            double Vmet = 10;

            DA.GetData(4, ref Vmet);

            //terrain type
            int terrain = 0;

            DA.GetData(5, ref terrain);


            bool run = false;

            if (!DA.GetData(6, ref run))
            {
                return;
            }



            //List<Mesh> mshCp = new List<Mesh>();
            //DA.GetDataList(10, mshCp);
            bool writeresults = false;

            DA.GetData(7, ref writeresults);


            DA.GetData(9, ref resetFFD);


            double nu = 1.511e-5;       // increase viscosity to impose turbulence. the higher velocity, the higher visc., 1e-3

            DA.GetData(10, ref nu);


            // *********************************************************************************
            //from Lukas
            // *********************************************************************************


            // Set initial velocity 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];

            // Create empty arrays for body forces
            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];

            // Create structure for solver parameters
            FluidSolver.solver_struct solver_prams = new FluidSolver.solver_struct();
            solver_prams.tol             = 1e-4;
            solver_prams.min_iter        = 1;
            solver_prams.max_iter        = 30;
            solver_prams.verbose         = false;
            solver_prams.backtrace_order = 2;
            solver_prams.mass_correction = false;
            solver_prams.mass_corr_alpha = 0.7;


            // Create FFD solver and domain
            if (ffd == null)
            {
                omega = new WindInflowAytac(Nx + 2, Ny + 2, Nz + 2, xyzsize[0], xyzsize[1], xyzsize[2]);
                foreach (double[] geo in geom)
                {
                    omega.add_obstacle(geo[0], geo[1], geo[2], geo[3], geo[4], geo[5]);
                }

                ffd = new FluidSolver(omega, dt, nu, u0, v0, w0, solver_prams);
                de  = new DataExtractor(omega, ffd);
                t   = 0;
            }

            //reset FFD solver and domain
            if (resetFFD)
            {
                omega = new WindInflowAytac(Nx + 2, Ny + 2, Nz + 2, xyzsize[0], xyzsize[1], xyzsize[2]);
                foreach (double[] geo in geom)
                {
                    omega.add_obstacle(geo[0], geo[1], geo[2], geo[3], geo[4], geo[5]);
                }

                ffd      = new FluidSolver(omega, dt, nu, u0, v0, w0, solver_prams);
                de       = new DataExtractor(omega, ffd);
                t        = 0;
                resetFFD = false;
            }



            //run solver. the solving-loop (new timestep) is executed in Grasshopper with a timer-component.
            if (run)
            {
                ffd.time_step(f_x, f_y, f_z);
            }



            // *******************************************************************************************
            // *******************************************************************************************
            // TO DO:   fix this loop with
            //   pp.export_data_vtk(String.Concat("lid_driven_cavity_", tstep, ".vtk"), Nx, Ny, Nz, tstep );
            //bool run2 = (bool)Component.Params.Input[5].Sources[0].VolatileData;
            //while (true)



            //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
            // I could move all this shit away, an only output de data extractor

            // *******************************************************************************************
            // *********************************     Output Results       ********************************
            double[, ,] p  = new double[Nx, Ny, Nz];
            double[, ,] vu = new double[Nx, Ny, Nz];
            double[, ,] vv = new double[Nx, Ny, Nz];
            double[, ,] vw = new double[Nx, Ny, Nz];

            double[, ,] pstag  = new double[Nx + 1, Ny + 1, Nz + 1];
            double[, ,] vustag = new double[Nx + 1, Ny + 1, Nz + 1];
            double[, ,] vvstag = new double[Nx + 1, Ny + 1, Nz + 1];
            double[, ,] vwstag = new double[Nx + 1, Ny + 1, Nz + 1];

            for (int i = 0; i < Nx; i++)
            {
                for (int j = 0; j < Ny; j++)
                {
                    for (int k = 0; k < Nz; k++)
                    {
                        if (omega.obstacle_cells[i + 1, j + 1, k + 1] != 1)
                        {
                            p[i, j, k] = de.get_pressure(i * omega.hx + 0.5 * omega.hx, j * omega.hy + 0.5 * omega.hy, k * omega.hz + 0.5 * omega.hz);
                            double[] vel = de.get_velocity(i * omega.hx + 0.5 * omega.hx, j * omega.hy + 0.5 * omega.hy, k * omega.hz + 0.5 * omega.hz);
                            vu[i, j, k] = vel[0];
                            vv[i, j, k] = vel[1];
                            vw[i, j, k] = vel[2];

                            pstag[i, j, k] = de.get_pressure(i * omega.hx, j * omega.hy, k * omega.hz);
                            double[] velcen = de.get_velocity(i * omega.hx, j * omega.hy, k * omega.hz);
                            vustag[i, j, k] = velcen[0];
                            vvstag[i, j, k] = velcen[1];
                            vwstag[i, k, k] = velcen[2];
                        }
                        else
                        {
                            p[i, j, k]  = 0;
                            vu[i, j, k] = 0;
                            vv[i, j, k] = 0;
                            vw[i, j, k] = 0;

                            //pstag[i, j, k] = 0;
                            //vustag[i, j, k] = 0;
                            //vvstag[i, j, k] = 0;
                            //vwstag[i, k, k] = 0;

                            pstag[i, j, k] = de.get_pressure(i * omega.hx, j * omega.hy, k * omega.hz);
                            double[] velcen = de.get_velocity(i * omega.hx, j * omega.hy, k * omega.hz);
                            vustag[i, j, k] = velcen[0];
                            vvstag[i, j, k] = velcen[1];
                            vwstag[i, k, k] = velcen[2];
                        }
                    }
                }
            }

            //last x slice
            for (int j = 0; j < Ny + 1; j++)
            {
                for (int k = 0; k < Nz + 1; k++)
                {
                    pstag[Nx, j, k] = de.get_pressure((Nx) * omega.hx, j * omega.hy, k * omega.hz);
                    double[] vcen = de.get_velocity((Nx) * omega.hx, j * omega.hy, k * omega.hz);
                    vustag[Nx, j, k] = vcen[0];
                    vvstag[Nx, j, k] = vcen[1];
                    vwstag[Nx, j, k] = vcen[2];
                }
            }

            //last y slice
            for (int i = 0; i < Nx + 1; i++)
            {
                for (int k = 0; k < Nz + 1; k++)
                {
                    pstag[i, Ny, k] = de.get_pressure(i * omega.hx, (Ny) * omega.hy, k * omega.hz);
                    double[] vcen = de.get_velocity(i * omega.hx, (Ny) * omega.hy, k * omega.hz);
                    vustag[i, Ny, k] = vcen[0];
                    vvstag[i, Ny, k] = vcen[1];
                    vwstag[i, Ny, k] = vcen[2];
                }
            }

            //last z slice
            for (int i = 0; i < Nx + 1; i++)
            {
                for (int j = 0; j < Ny + 1; j++)
                {
                    pstag[i, j, Nz] = de.get_pressure(i * omega.hx, j * omega.hy, (Nz) * omega.hz);
                    double[] vcen = de.get_velocity(i * omega.hx, j * omega.hy, (Nz) * omega.hz);
                    vustag[i, j, Nz] = vcen[0];
                    vvstag[i, j, Nz] = vcen[1];
                    vwstag[i, j, Nz] = vcen[2];
                }
            }

            List <double[, , ]> veloutCen = new List <double[, , ]> {
            };

            veloutCen.Add(vu);
            veloutCen.Add(vv);
            veloutCen.Add(vw);

            List <double[, , ]> veloutStag = new List <double[, , ]> {
            };

            veloutStag.Add(vustag);
            veloutStag.Add(vvstag);
            veloutStag.Add(vwstag);


            DA.SetDataList(0, veloutCen);
            DA.SetData(1, p);
            DA.SetDataList(2, veloutStag);
            DA.SetData(3, pstag);



            // *******************************************************************************************
            // *******************************      Output Cp values on Surfaces   ***********************
            //if (mshCp.Count > 0)
            if (writeresults)
            {
                DA.SetData(4, de);
            }
        }
コード例 #3
0
ファイル: FFDSolver.cs プロジェクト: HannaIsabella/GH_Wind
        public bool Run()
        {
            if (xyzsize.Count == 0)
            {
                Rhino.RhinoApp.WriteLine($"{id} - Error");
                return(false);
            }


            run = true;

            counter  = 0;
            timestep = 0;



            double nu = 1.511e-5;       // increase viscosity to impose turbulence. the higher velocity, the higher visc., 1e-3

            FluidSolver.solver_struct solver_params = new FluidSolver.solver_struct();
            double z0;

            if (str_params != null)
            {
                nu = Convert.ToDouble(str_params[0]);
                solver_params.tol             = Convert.ToDouble(str_params[1]);
                solver_params.min_iter        = Convert.ToInt16(str_params[2]);
                solver_params.max_iter        = Convert.ToInt16(str_params[3]);
                solver_params.backtrace_order = Convert.ToInt16(str_params[4]);
                solver_params.mass_correction = str_params[5].Equals("false") ? false : true;
                solver_params.mass_corr_alpha = Convert.ToDouble(str_params[6]);
                solver_params.verbose         = str_params[7].Equals("false") ? false : true;
                z0 = Convert.ToDouble(str_params[8]);
            }
            else
            {
                solver_params.tol             = 1e-4;
                solver_params.min_iter        = 1;
                solver_params.max_iter        = 30;
                solver_params.backtrace_order = 2;
                solver_params.mass_correction = false;
                solver_params.mass_corr_alpha = 0.7;
                solver_params.verbose         = false;
                z0 = 0.1;
            }



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

            // Create empty arrays for body forces
            f_x = new double[Nx + 1, Ny + 2, Nz + 2];
            f_y = new double[Nx + 2, Ny + 1, Nz + 2];
            f_z = new double[Nx + 2, Ny + 2, Nz + 1];



            // Create FFD solver and domain
            //if (ffd == null || resetFFD)
            //{
            Rhino.RhinoApp.WriteLine($"{id} - " + "{0}, {1}, {2}", xyzsize[0], xyzsize[1], xyzsize[2]);
            if (terrain == 4)
            {
                omega = new WindInflowOpenFoam(Nx + 2, Ny + 2, Nz + 2, xyzsize[0], xyzsize[1], xyzsize[2], Vmet, z0);
            }
            else
            {
                omega = new WindInflow(Nx + 2, Ny + 2, Nz + 2, xyzsize[0], xyzsize[1], xyzsize[2], Vmet, terrain);
            }

            //Rhino.RhinoApp.WriteLine("M0005");

            foreach (double[] geo in geom)
            {
                omega.add_obstacle(geo[0], geo[1], geo[2], geo[3], geo[4], geo[5]);
            }

            //Rhino.RhinoApp.WriteLine("M0005a");

            ffd = new FluidSolver(omega, dt, nu, u0, v0, w0, solver_params);
            de  = new DataExtractor(omega, ffd);
            t   = 0;

            //Rhino.RhinoApp.WriteLine("M0006");

            pp = new PostProcessor(ffd, omega);


            //if (resetFFD) resetFFD = false;            //reset FFD solver and domain
            if (id == 0)
            {
                Rhino.RhinoApp.WriteLine($"{id} - " + "GRASSHOPPER FFD Air Flow Simulation.");
                Rhino.RhinoApp.WriteLine($"{id} - " + "GH Plug-in: https://github.com/christophwaibel/GH_Wind");
                Rhino.RhinoApp.WriteLine($"{id} - " + "FFD Solver: https://github.com/lukasbystricky/GSoC_FFD");
                Rhino.RhinoApp.WriteLine($"{id} - " + "________________________________________________________");
                Rhino.RhinoApp.WriteLine($"{id} - " + "...Domain initialized");
                Rhino.RhinoApp.WriteLine($"{id} - " + "________________________________________________________");
            }

            //}


            if (run)
            {
                if (writeVTK)
                {
                    pp.export_geometry_vtk(filepath + @"\\vtk_geometry.vtk", 0);
                }

                counter  = 0;
                timestep = 0;
                ffd_old  = new FluidSolver[m];

                if (calcres)
                {
                    File.AppendAllText(residualstxt, "pmin; pmax; pavg; umin; umax; uavg; vmin; vmax; vavg; wmin; wmax; wavg;\n");
                }


                while (t < t_end)
                {
                    //  only works if in the gh component and not in this class.
                    //if (GH_Document.IsEscapeKeyDown())
                    //{
                    //    Rhino.RhinoApp.WriteLine("Cancelled by user");
                    //    //GH_Document GHDocument = OnPingDocument();
                    //    //GHDocument.RequestAbortSolution();
                    //    break;
                    //}

                    if (run != true)
                    {
                        break;
                    }


                    RunStep(ref timestep, ref counter);


                    // doesnt work because the gh component doesnt update.
                    //if (t % 10 == 0)
                    //{
                    //    UpdateOutput();
                    //}
                }
            }

            UpdateOutput();


            return(true); //returns to the task manager and updates GH component
        }
コード例 #4
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();
                }
            }
        }
コード例 #5
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            string filepath;

            Domain        omega;
            FluidSolver   ffd;
            DataExtractor de;

            double t;
            bool   resetFFD;


            // current filepath
            filepath = Path.GetDirectoryName(this.OnPingDocument().FilePath);
            string residualstxt = filepath + @"\\residual.txt";


            // *********************************************************************************
            // Inputs
            // *********************************************************************************
            List <double> xyzsize = new List <double>();

            if (!DA.GetDataList(0, xyzsize))
            {
                return;
            }
            ;

            List <int> Nxyz = new List <int>();

            if (!DA.GetDataList(1, Nxyz))
            {
                return;
            }
            ;
            int Nx = Nxyz[0];
            int Ny = Nxyz[1];
            int Nz = Nxyz[2];


            List <double[]> geom = new List <double[]>();

            if (!DA.GetDataList(2, geom))
            {
                return;
            }
            ;


            // time step
            double dt = 0.1;

            if (!DA.GetData(3, ref dt))
            {
                return;
            }

            // horizon
            double t_end = 1;

            if (!DA.GetData(4, ref t_end))
            {
                return;
            }

            // wind speed
            double Vmet = 10;

            if (!DA.GetData(5, ref Vmet))
            {
                return;
            }

            //terrain type
            int terrain = 0;

            if (!DA.GetData(6, ref terrain))
            {
                return;
            }


            bool run = false;

            if (!DA.GetData(7, ref run))
            {
                return;
            }



            //List<Mesh> mshCp = new List<Mesh>();
            //DA.GetDataList(10, mshCp);
            bool writeresults = false;

            DA.GetData(8, ref writeresults);

            bool writeVTK = false;

            DA.GetData(9, ref writeVTK);


            //DA.GetData(10, ref resetFFD);

            bool calcres = false;

            DA.GetData(12, ref calcres);

            int m = 10;

            DA.GetData(13, ref m);

            string strparam = null;

            DA.GetData(11, ref strparam);

            string[] str_params = null;
            if (strparam != null)
            {
                str_params = strparam.Split(';');
            }

            double nu = 1.511e-5;       // increase viscosity to impose turbulence. the higher velocity, the higher visc., 1e-3

            FluidSolver.solver_struct solver_params = new FluidSolver.solver_struct();
            double z0;

            if (str_params != null)
            {
                nu = Convert.ToDouble(str_params[0]);
                solver_params.tol             = Convert.ToDouble(str_params[1]);
                solver_params.min_iter        = Convert.ToInt16(str_params[2]);
                solver_params.max_iter        = Convert.ToInt16(str_params[3]);
                solver_params.backtrace_order = Convert.ToInt16(str_params[4]);
                solver_params.mass_correction = str_params[5].Equals("false") ? false : true;
                solver_params.mass_corr_alpha = Convert.ToDouble(str_params[6]);
                solver_params.verbose         = str_params[7].Equals("false") ? false : true;
                z0 = Convert.ToDouble(str_params[8]);
            }
            else
            {
                solver_params.tol             = 1e-4;
                solver_params.min_iter        = 1;
                solver_params.max_iter        = 30;
                solver_params.backtrace_order = 2;
                solver_params.mass_correction = false;
                solver_params.mass_corr_alpha = 0.7;
                solver_params.verbose         = false;
                z0 = 0.1;
            }



            // *********************************************************************************
            // Set-up FFD Solver
            // *********************************************************************************
            // Set initial velocity 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];

            // Create empty arrays for body forces
            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];



            // Create FFD solver and domain
            //if (ffd == null || resetFFD)
            //{
            if (terrain == 4)
            {
                omega = new WindInflowOpenFoam(Nx + 2, Ny + 2, Nz + 2, xyzsize[0], xyzsize[1], xyzsize[2], Vmet, z0);
            }
            else
            {
                omega = new WindInflow(Nx + 2, Ny + 2, Nz + 2, xyzsize[0], xyzsize[1], xyzsize[2], Vmet, terrain);
            }
            foreach (double[] geo in geom)
            {
                omega.add_obstacle(geo[0], geo[1], geo[2], geo[3], geo[4], geo[5]);
            }

            ffd = new FluidSolver(omega, dt, nu, u0, v0, w0, solver_params);
            de  = new DataExtractor(omega, ffd);
            t   = 0;

            PostProcessor pp = new PostProcessor(ffd, omega);

            //if (resetFFD) resetFFD = false;            //reset FFD solver and domain

            Rhino.RhinoApp.WriteLine("GRASSHOPPER FFD Air Flow Simulation.");
            Rhino.RhinoApp.WriteLine("GH Plug-in: https://github.com/christophwaibel/GH_Wind");
            Rhino.RhinoApp.WriteLine("FFD Solver: https://github.com/lukasbystricky/GSoC_FFD");
            Rhino.RhinoApp.WriteLine("________________________________________________________");
            Rhino.RhinoApp.WriteLine("...Domain initialized");
            Rhino.RhinoApp.WriteLine("________________________________________________________");
            //}



            // *******************************************************************************************
            // Run each time GH is updated
            // *******************************************************************************************
            //run solver. the solving-loop (new timestep) is executed in Grasshopper with a timer-component.
            //!!!!!!!!!!!!!!! CHANGE
            if (run)
            {
                if (writeVTK)
                {
                    pp.export_geometry_vtk(filepath + @"\\vtk_geometry.vtk", 0);
                }

                int           counter  = 0;
                int           timestep = 0;
                FluidSolver[] ffd_old  = new FluidSolver[m];

                if (calcres)
                {
                    File.AppendAllText(residualstxt, "pmin; pmax; pavg; umin; umax; uavg; vmin; vmax; vavg; wmin; wmax; wavg;\n");
                }

                # region whileloop

                while (t < t_end)
                {
                    if (GH_Document.IsEscapeKeyDown())
                    {
                        Rhino.RhinoApp.WriteLine("Cancelled by user");
                        GH_Document GHDocument = OnPingDocument();
                        GHDocument.RequestAbortSolution();
                        break;
                    }

                    Rhino.RhinoApp.WriteLine(Convert.ToString(t) + " of " + Convert.ToString(t_end));

                    double[,,] p_t2 = new double[ffd.p.GetLength(0), ffd.p.GetLength(1), ffd.p.GetLength(2)];
                    Array.Copy(ffd.p, 0, p_t2, 0, ffd.p.Length);
                    double[,,] u_t2 = new double[ffd.u.GetLength(0), ffd.u.GetLength(1), ffd.u.GetLength(2)];
                    Array.Copy(ffd.u, 0, u_t2, 0, ffd.u.Length);
                    double[,,] v_t2 = new double[ffd.v.GetLength(0), ffd.v.GetLength(1), ffd.v.GetLength(2)];
                    Array.Copy(ffd.v, 0, v_t2, 0, ffd.v.Length);
                    double[,,] w_t2 = new double[ffd.w.GetLength(0), ffd.w.GetLength(1), ffd.w.GetLength(2)];
                    Array.Copy(ffd.w, 0, w_t2, 0, ffd.w.Length);

                    ffd.time_step(f_x, f_y, f_z);
                    if (t > dt && calcres)
                    {
                        double[] p_residuals;
                        double[,,] p_t1 = ffd.p;
                        FastFluidSolverMT.Utilities.calculate_residuals(p_t1, p_t2, out p_residuals);
                        Rhino.RhinoApp.WriteLine("p residuals: {0};{1};{2}", p_residuals[0], p_residuals[1], p_residuals[2]);
                        double[] u_residuals;
                        double[,,] u_t1 = ffd.u;
                        FastFluidSolverMT.Utilities.calculate_residuals(u_t1, u_t2, out u_residuals);
                        Rhino.RhinoApp.WriteLine("u residuals: {0};{1};{2}", u_residuals[0], u_residuals[1], u_residuals[2]);
                        double[] v_residuals;
                        double[,,] v_t1 = ffd.v;
                        FastFluidSolverMT.Utilities.calculate_residuals(v_t1, v_t2, out v_residuals);
                        Rhino.RhinoApp.WriteLine("v residuals: {0};{1};{2}", v_residuals[0], v_residuals[1], v_residuals[2]);
                        double[] w_residuals;
                        double[,,] w_t1 = ffd.w;
                        FastFluidSolverMT.Utilities.calculate_residuals(w_t1, w_t2, out w_residuals);
                        Rhino.RhinoApp.WriteLine("w residuals: {0};{1};{2}", w_residuals[0], w_residuals[1], w_residuals[2]);

                        File.AppendAllText(residualstxt, Convert.ToString(p_residuals[0]) + ";" + Convert.ToString(p_residuals[1]) + ";" + Convert.ToString(p_residuals[2]) + ";" +
                                           Convert.ToString(u_residuals[0]) + ";" + Convert.ToString(u_residuals[1]) + ";" + Convert.ToString(u_residuals[2]) + ";" +
                                           Convert.ToString(v_residuals[0]) + ";" + Convert.ToString(v_residuals[1]) + ";" + Convert.ToString(v_residuals[2]) + ";" +
                                           Convert.ToString(w_residuals[0]) + ";" + Convert.ToString(w_residuals[1]) + ";" + Convert.ToString(w_residuals[2]) + "\n");
                    }

                    if (t >= t_end - m * dt)
                    {
                        ffd_old[counter] = new FluidSolver(ffd);
                        counter++;
                    }
                    if (writeVTK)
                    {
                        pp.export_data_vtk(filepath + @"\\vtk_" + timestep + ".vtk", t, false);
                    }
                    t += dt;
                    timestep++;
                }
                #endregion whileloop


                //averaging results
                FluidSolver ffd_mean = new FluidSolver(ffd);
                ffd_mean.p = new double[ffd.p.GetLength(0), ffd.p.GetLength(1), ffd.p.GetLength(2)];
                ffd_mean.u = new double[ffd.u.GetLength(0), ffd.u.GetLength(1), ffd.u.GetLength(2)];
                ffd_mean.v = new double[ffd.v.GetLength(0), ffd.v.GetLength(1), ffd.v.GetLength(2)];
                ffd_mean.w = new double[ffd.w.GetLength(0), ffd.w.GetLength(1), ffd.w.GetLength(2)];
                for (int i = 0; i < ffd_mean.p.GetLength(0); i++)
                {
                    for (int j = 0; j < ffd_mean.p.GetLength(1); j++)
                    {
                        for (int k = 0; k < ffd_mean.p.GetLength(2); k++)
                        {
                            for (int u = 0; u < counter; u++)
                            {
                                ffd_mean.p[i, j, k] += ffd_old[u].p[i, j, k];
                            }
                            ffd_mean.p[i, j, k] /= counter;
                        }
                    }
                }

                for (int i = 0; i < ffd_mean.u.GetLength(0); i++)
                {
                    for (int j = 0; j < ffd_mean.u.GetLength(1); j++)
                    {
                        for (int k = 0; k < ffd_mean.u.GetLength(2); k++)
                        {
                            for (int u = 0; u < counter; u++)
                            {
                                ffd_mean.u[i, j, k] += ffd_old[u].u[i, j, k];
                            }
                            ffd_mean.u[i, j, k] /= counter;
                        }
                    }
                }

                for (int i = 0; i < ffd_mean.v.GetLength(0); i++)
                {
                    for (int j = 0; j < ffd_mean.v.GetLength(1); j++)
                    {
                        for (int k = 0; k < ffd_mean.v.GetLength(2); k++)
                        {
                            for (int u = 0; u < counter; u++)
                            {
                                ffd_mean.v[i, j, k] += ffd_old[u].v[i, j, k];
                            }
                            ffd_mean.v[i, j, k] /= counter;
                        }
                    }
                }

                for (int i = 0; i < ffd_mean.w.GetLength(0); i++)
                {
                    for (int j = 0; j < ffd_mean.w.GetLength(1); j++)
                    {
                        for (int k = 0; k < ffd_mean.w.GetLength(2); k++)
                        {
                            for (int u = 0; u < counter; u++)
                            {
                                ffd_mean.w[i, j, k] += ffd_old[u].w[i, j, k];
                            }
                            ffd_mean.w[i, j, k] /= counter;
                        }
                    }
                }

                de = new DataExtractor(omega, ffd_mean);
            }
コード例 #6
0
ファイル: CavityDriver.cs プロジェクト: polytronicgr/GSoC_FFD
        static void Main()
        {
            // Set mesh parameters, here we ask for Nx cells in the x direction
            // Ny cells in the y direction and Nz cells in the z direction (ignoring ghost cells)
            int Nx = 20;
            int Ny = 20;
            int Nz = 20;

            // Set time step and viscosity
            double dt = 0.01;
            double nu = 1e-2;

            // Set simulation start and finish times
            double tf = 100;
            double t  = 0;

            // Set 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];

            // Create empty arrays for body forces
            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];

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

            solver_prams.tol             = 1e-4;
            solver_prams.min_iter        = 0;
            solver_prams.max_iter        = 30;
            solver_prams.verbose         = true;
            solver_prams.backtrace_order = 2;

            // Create domain
            // Pass in the number of cells in x, y and z direction (now including ghost cells)
            CavityDomain omega = new CavityDomain(Nx + 2, Ny + 2, Nz + 2);

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

            // Create post processor, export intial conditions and geometry information
            PostProcessor pp = new PostProcessor(ffd, omega);

            int tstep = 0;

            pp.export_data_vtk(String.Concat("cavity_", tstep, ".vtk"), 0, false);
            pp.export_geometry_vtk("cavity_geometry.vtk", 0);

            // Begin time loop
            while (t < tf)
            {
                t += dt;
                tstep++;

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

                // Solve single time step and export results
                ffd.time_step(f_x, f_y, f_z);
                pp.export_data_vtk(String.Concat("cavity_", tstep, ".vtk"), t, false);
            }
        }
コード例 #7
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            // *********************************************************************************
            // get info from grasshopper
            // *********************************************************************************
            List <double> xyzsize = new List <double>();

            if (!DA.GetDataList(0, xyzsize))
            {
                return;
            }
            ;

            List <int> Nxyz = new List <int>();

            if (!DA.GetDataList(1, Nxyz))
            {
                return;
            }
            ;
            int Nx = Nxyz[0];
            int Ny = Nxyz[1];
            int Nz = Nxyz[2];


            // time step
            double dt = 0.1;

            if (!DA.GetData(2, ref dt))
            {
                return;
            }


            bool run = false;

            if (!DA.GetData(3, ref run))
            {
                return;
            }



            DA.GetData(6, ref resetFFD);

            double re = 400;

            if (!DA.GetData(7, ref re))
            {
                return;
            }



            // *********************************************************************************
            //from Lukas
            // *********************************************************************************
            double nu = 1 / re;       // increase viscosity to impose turbulence. the higher velocity, the higher visc., 1e-3

            // Set initial velocity 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];

            // Create empty arrays for body forces
            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];

            // Create structure for solver parameters
            FluidSolver.solver_struct solver_prams = new FluidSolver.solver_struct();
            solver_prams.tol             = 1e-4;
            solver_prams.min_iter        = 1;
            solver_prams.max_iter        = 30;
            solver_prams.verbose         = false;
            solver_prams.backtrace_order = 2;
            solver_prams.mass_correction = false;
            solver_prams.mass_corr_alpha = 0.7;


            // Create FFD solver and domain
            if (ffd == null)
            {
                // Create domain
                // Pass in the number of cells in x, y and z direction (now including ghost cells)
                omega = new CavityDomain(Nx + 2, Ny + 2, Nz + 2);
                ffd   = new FluidSolver(omega, dt, nu, u0, v0, w0, solver_prams);
                de    = new DataExtractor(omega, ffd);
                t     = 0;
            }

            //reset FFD solver and domain
            if (resetFFD)
            {
                omega    = new CavityDomain(Nx + 2, Ny + 2, Nz + 2);
                ffd      = new FluidSolver(omega, dt, nu, u0, v0, w0, solver_prams);
                de       = new DataExtractor(omega, ffd);
                t        = 0;
                resetFFD = false;
            }



            //run solver. the solving-loop (new timestep) is executed in Grasshopper with a timer-component.
            if (run)
            {
                ffd.time_step(f_x, f_y, f_z);
            }



            // *******************************************************************************************
            // *********************************     Output Results       ********************************
            double[, ,] p  = new double[Nx, Ny, Nz];
            double[, ,] vu = new double[Nx, Ny, Nz];
            double[, ,] vv = new double[Nx, Ny, Nz];
            double[, ,] vw = new double[Nx, Ny, Nz];

            double[, ,] pstag  = new double[Nx + 1, Ny + 1, Nz + 1];
            double[, ,] vustag = new double[Nx + 1, Ny + 1, Nz + 1];
            double[, ,] vvstag = new double[Nx + 1, Ny + 1, Nz + 1];
            double[, ,] vwstag = new double[Nx + 1, Ny + 1, Nz + 1];

            for (int i = 0; i < Nx; i++)
            {
                for (int j = 0; j < Ny; j++)
                {
                    for (int k = 0; k < Nz; k++)
                    {
                        if (omega.obstacle_cells[i + 1, j + 1, k + 1] != 1)
                        {
                            p[i, j, k] = de.get_pressure(i * omega.hx + 0.5 * omega.hx, j * omega.hy + 0.5 * omega.hy, k * omega.hz + 0.5 * omega.hz);
                            double[] vel = de.get_velocity(i * omega.hx + 0.5 * omega.hx, j * omega.hy + 0.5 * omega.hy, k * omega.hz + 0.5 * omega.hz);
                            vu[i, j, k] = vel[0];
                            vv[i, j, k] = vel[1];
                            vw[i, j, k] = vel[2];

                            pstag[i, j, k] = de.get_pressure(i * omega.hx, j * omega.hy, k * omega.hz);
                            double[] velcen = de.get_velocity(i * omega.hx, j * omega.hy, k * omega.hz);
                            vustag[i, j, k] = velcen[0];
                            vvstag[i, j, k] = velcen[1];
                            vwstag[i, k, k] = velcen[2];
                        }
                        else
                        {
                            p[i, j, k]  = 0;
                            vu[i, j, k] = 0;
                            vv[i, j, k] = 0;
                            vw[i, j, k] = 0;

                            //pstag[i, j, k] = 0;
                            //vustag[i, j, k] = 0;
                            //vvstag[i, j, k] = 0;
                            //vwstag[i, k, k] = 0;

                            pstag[i, j, k] = de.get_pressure(i * omega.hx, j * omega.hy, k * omega.hz);
                            double[] velcen = de.get_velocity(i * omega.hx, j * omega.hy, k * omega.hz);
                            vustag[i, j, k] = velcen[0];
                            vvstag[i, j, k] = velcen[1];
                            vwstag[i, k, k] = velcen[2];
                        }
                    }
                }
            }

            //last x slice
            for (int j = 0; j < Ny + 1; j++)
            {
                for (int k = 0; k < Nz + 1; k++)
                {
                    pstag[Nx, j, k] = de.get_pressure((Nx) * omega.hx, j * omega.hy, k * omega.hz);
                    double[] vcen = de.get_velocity((Nx) * omega.hx, j * omega.hy, k * omega.hz);
                    vustag[Nx, j, k] = vcen[0];
                    vvstag[Nx, j, k] = vcen[1];
                    vwstag[Nx, j, k] = vcen[2];
                }
            }

            //last y slice
            for (int i = 0; i < Nx + 1; i++)
            {
                for (int k = 0; k < Nz + 1; k++)
                {
                    pstag[i, Ny, k] = de.get_pressure(i * omega.hx, (Ny) * omega.hy, k * omega.hz);
                    double[] vcen = de.get_velocity(i * omega.hx, (Ny) * omega.hy, k * omega.hz);
                    vustag[i, Ny, k] = vcen[0];
                    vvstag[i, Ny, k] = vcen[1];
                    vwstag[i, Ny, k] = vcen[2];
                }
            }

            //last z slice
            for (int i = 0; i < Nx + 1; i++)
            {
                for (int j = 0; j < Ny + 1; j++)
                {
                    pstag[i, j, Nz] = de.get_pressure(i * omega.hx, j * omega.hy, (Nz) * omega.hz);
                    double[] vcen = de.get_velocity(i * omega.hx, j * omega.hy, (Nz) * omega.hz);
                    vustag[i, j, Nz] = vcen[0];
                    vvstag[i, j, Nz] = vcen[1];
                    vwstag[i, j, Nz] = vcen[2];
                }
            }

            List <double[, , ]> veloutCen = new List <double[, , ]> {
            };

            veloutCen.Add(vu);
            veloutCen.Add(vv);
            veloutCen.Add(vw);

            List <double[, , ]> veloutStag = new List <double[, , ]> {
            };

            veloutStag.Add(vustag);
            veloutStag.Add(vvstag);
            veloutStag.Add(vwstag);


            DA.SetDataList(0, veloutCen);
            DA.SetData(1, p);
            DA.SetDataList(2, veloutStag);
            DA.SetData(3, pstag);



            List <double> ulist = new List <double>();
            List <double> vlist = new List <double>();

            //u velocities. (y called) z-section, in the vertical center... x=0.5Nx, y=0.5Ny
            //(Ny+1) / 2
            for (int k = 0; k < Nz + 1; k++)
            {
                double[] vcen = de.get_velocity((Nx / 2) * omega.hx + 0.5 * omega.hx,
                                                (Ny / 2) * omega.hy + 0.5 * omega.hy,
                                                k * omega.hz);
                ulist.Add(vcen[0]);
            }

            for (int i = 0; i < Nx + 1; i++)
            {
                double[] vcen = de.get_velocity(i * omega.hx,
                                                (Ny / 2) * omega.hy + 0.5 * omega.hy,
                                                (Nz / 2) * omega.hz + 0.5 * omega.hz);

                vlist.Add(vcen[2]);
            }


            DA.SetDataList(4, ulist);
            DA.SetDataList(5, vlist);
        }
コード例 #8
0
        static void Main()
        {
            // Set mesh parameters, here we ask for Nx cells in the x direction
            // Ny cells in the y direction and Nz cells in the z direction (ignoring ghost cells)
            int Nx = 100;
            int Ny = 45;
            int Nz = 30;

            // Set time step and viscosity
            double dt = 0.1;
            double nu = 1e-5;

            // Set simulation start and finish times
            double tf = 100;
            double t  = 0;

            // Set 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];

            // Create empty arrays for body forces
            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];

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

            solver_prams.tol             = 1e-3;
            solver_prams.min_iter        = 1;
            solver_prams.max_iter        = 30;
            solver_prams.verbose         = true;
            solver_prams.backtrace_order = 2;

            // Create domain
            WindInflow omega = new WindInflow(Nx + 2, Ny + 2, Nz + 2, 100, 45, 30);

            // Add buildings
            omega.add_obstacle(15, 20, 15, 20, 0, 5);
            omega.add_obstacle(15, 18, 18, 20, 5, 12);

            omega.add_obstacle(18, 25, 25, 30, 0, 8);
            omega.add_obstacle(30, 40, 15, 25, 0, 10);

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

            // Create post processor and export initial conditions and geometry information
            PostProcessor pp = new PostProcessor(ffd, omega);

            int tstep = 0;

            pp.export_data_vtk(String.Concat("city_test_", tstep, ".vtk"), 0, false);
            pp.export_geometry_vtk("city_test_geometry.vtk", 0);

            // Run time loop
            while (t < tf)
            {
                t += dt;
                tstep++;

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

                // Solve single time step and export results
                ffd.time_step(f_x, f_y, f_z);
                pp.export_data_vtk(String.Concat("city_test_", tstep, ".vtk"), t, false);
            }
        }
コード例 #9
0
ファイル: GHFFDSolverV2.cs プロジェクト: whoxinyi/GH_Wind
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            string filepath;

            Domain        omega;
            FluidSolver   ffd;
            DataExtractor de;

            double t;
            bool   resetFFD;


            // current filepath
            filepath = Path.GetDirectoryName(this.OnPingDocument().FilePath);
            string residualstxt = filepath + @"\\residual.txt";


            // *********************************************************************************
            // Inputs
            // *********************************************************************************
            List <double> xyzsize = new List <double>();

            if (!DA.GetDataList(0, xyzsize))
            {
                return;
            }
            ;

            List <int> Nxyz = new List <int>();

            if (!DA.GetDataList(1, Nxyz))
            {
                return;
            }
            ;
            int Nx = Nxyz[0];
            int Ny = Nxyz[1];
            int Nz = Nxyz[2];


            List <double[]> geom = new List <double[]>();

            if (!DA.GetDataList(2, geom))
            {
                return;
            }
            ;


            // time step
            double dt = 0.1;

            if (!DA.GetData(3, ref dt))
            {
                return;
            }

            // horizon
            double t_end = 1;

            if (!DA.GetData(4, ref t_end))
            {
                return;
            }

            // wind speed
            double Vmet = 10;

            if (!DA.GetData(5, ref Vmet))
            {
                return;
            }

            //terrain type
            int terrain = 0;

            if (!DA.GetData(6, ref terrain))
            {
                return;
            }


            bool run = false;

            if (!DA.GetData(7, ref run))
            {
                return;
            }



            //List<Mesh> mshCp = new List<Mesh>();
            //DA.GetDataList(10, mshCp);
            bool writeresults = false;

            DA.GetData(8, ref writeresults);

            bool writeVTK = false;

            DA.GetData(9, ref writeVTK);


            //DA.GetData(10, ref resetFFD);

            bool calcres = false;

            DA.GetData(12, ref calcres);

            int m = 10;

            DA.GetData(13, ref m);

            string strparam = null;

            DA.GetData(11, ref strparam);

            string[] str_params = null;
            if (strparam != null)
            {
                str_params = strparam.Split(';');
            }

            double nu = 1.511e-5;       // increase viscosity to impose turbulence. the higher velocity, the higher visc., 1e-3

            FluidSolver.solver_struct solver_params = new FluidSolver.solver_struct();
            double z0;

            if (str_params != null)
            {
                nu = Convert.ToDouble(str_params[0]);
                solver_params.tol             = Convert.ToDouble(str_params[1]);
                solver_params.min_iter        = Convert.ToInt16(str_params[2]);
                solver_params.max_iter        = Convert.ToInt16(str_params[3]);
                solver_params.backtrace_order = Convert.ToInt16(str_params[4]);
                solver_params.mass_correction = str_params[5].Equals("false") ? false : true;
                solver_params.mass_corr_alpha = Convert.ToDouble(str_params[6]);
                solver_params.verbose         = str_params[7].Equals("false") ? false : true;
                z0 = Convert.ToDouble(str_params[8]);
            }
            else
            {
                solver_params.tol             = 1e-4;
                solver_params.min_iter        = 1;
                solver_params.max_iter        = 30;
                solver_params.backtrace_order = 2;
                solver_params.mass_correction = false;
                solver_params.mass_corr_alpha = 0.7;
                solver_params.verbose         = false;
                z0 = 0.1;
            }



            // *********************************************************************************
            // Set-up FFD Solver
            // *********************************************************************************
            // Set initial velocity 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];

            // Create empty arrays for body forces
            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];



            // Create FFD solver and domain
            //if (ffd == null || resetFFD)
            //{
            if (terrain == 4)
            {
                omega = new WindInflowOpenFoam(Nx + 2, Ny + 2, Nz + 2, xyzsize[0], xyzsize[1], xyzsize[2], Vmet, z0);
            }
            else
            {
                omega = new WindInflow(Nx + 2, Ny + 2, Nz + 2, xyzsize[0], xyzsize[1], xyzsize[2], Vmet, terrain);
            }
            foreach (double[] geo in geom)
            {
                omega.add_obstacle(geo[0], geo[1], geo[2], geo[3], geo[4], geo[5]);
            }

            ffd = new FluidSolver(omega, dt, nu, u0, v0, w0, solver_params);
            de  = new DataExtractor(omega, ffd);
            t   = 0;

            PostProcessor pp = new PostProcessor(ffd, omega);

            //if (resetFFD) resetFFD = false;            //reset FFD solver and domain

            Rhino.RhinoApp.WriteLine("GRASSHOPPER FFD Air Flow Simulation.");
            Rhino.RhinoApp.WriteLine("GH Plug-in: https://github.com/christophwaibel/GH_Wind");
            Rhino.RhinoApp.WriteLine("FFD Solver: https://github.com/lukasbystricky/GSoC_FFD");
            Rhino.RhinoApp.WriteLine("________________________________________________________");
            Rhino.RhinoApp.WriteLine("...Domain initialized");
            Rhino.RhinoApp.WriteLine("________________________________________________________");
            //}



            // *******************************************************************************************
            // Run each time GH is updated
            // *******************************************************************************************
            //run solver. the solving-loop (new timestep) is executed in Grasshopper with a timer-component.
            //!!!!!!!!!!!!!!! CHANGE
            if (run)
            {
                if (writeVTK)
                {
                    pp.export_geometry_vtk(filepath + @"\\vtk_geometry.vtk", 0);
                }

                int           counter  = 0;
                int           timestep = 0;
                FluidSolver[] ffd_old  = new FluidSolver[m];

                if (calcres)
                {
                    File.AppendAllText(residualstxt, "pmin; pmax; pavg; umin; umax; uavg; vmin; vmax; vavg; wmin; wmax; wavg;\n");
                }

                while (t < t_end)
                {
                    Rhino.RhinoApp.WriteLine(Convert.ToString(t) + " of " + Convert.ToString(t_end));

                    double[,,] p_t2 = new double[ffd.p.GetLength(0), ffd.p.GetLength(1), ffd.p.GetLength(2)];
                    Array.Copy(ffd.p, 0, p_t2, 0, ffd.p.Length);
                    double[,,] u_t2 = new double[ffd.u.GetLength(0), ffd.u.GetLength(1), ffd.u.GetLength(2)];
                    Array.Copy(ffd.u, 0, u_t2, 0, ffd.u.Length);
                    double[,,] v_t2 = new double[ffd.v.GetLength(0), ffd.v.GetLength(1), ffd.v.GetLength(2)];
                    Array.Copy(ffd.v, 0, v_t2, 0, ffd.v.Length);
                    double[,,] w_t2 = new double[ffd.w.GetLength(0), ffd.w.GetLength(1), ffd.w.GetLength(2)];
                    Array.Copy(ffd.w, 0, w_t2, 0, ffd.w.Length);

                    ffd.time_step(f_x, f_y, f_z);
                    if (t > dt && calcres)
                    {
                        double[] p_residuals;
                        double[,,] p_t1 = ffd.p;
                        FastFluidSolverMT.Utilities.calculate_residuals(p_t1, p_t2, out p_residuals);
                        Rhino.RhinoApp.WriteLine("p residuals: {0};{1};{2}", p_residuals[0], p_residuals[1], p_residuals[2]);
                        double[] u_residuals;
                        double[,,] u_t1 = ffd.u;
                        FastFluidSolverMT.Utilities.calculate_residuals(u_t1, u_t2, out u_residuals);
                        Rhino.RhinoApp.WriteLine("u residuals: {0};{1};{2}", u_residuals[0], u_residuals[1], u_residuals[2]);
                        double[] v_residuals;
                        double[,,] v_t1 = ffd.v;
                        FastFluidSolverMT.Utilities.calculate_residuals(v_t1, v_t2, out v_residuals);
                        Rhino.RhinoApp.WriteLine("v residuals: {0};{1};{2}", v_residuals[0], v_residuals[1], v_residuals[2]);
                        double[] w_residuals;
                        double[,,] w_t1 = ffd.w;
                        FastFluidSolverMT.Utilities.calculate_residuals(w_t1, w_t2, out w_residuals);
                        Rhino.RhinoApp.WriteLine("w residuals: {0};{1};{2}", w_residuals[0], w_residuals[1], w_residuals[2]);

                        File.AppendAllText(residualstxt, Convert.ToString(p_residuals[0]) + ";" + Convert.ToString(p_residuals[1]) + ";" + Convert.ToString(p_residuals[2]) + ";" +
                                           Convert.ToString(u_residuals[0]) + ";" + Convert.ToString(u_residuals[1]) + ";" + Convert.ToString(u_residuals[2]) + ";" +
                                           Convert.ToString(v_residuals[0]) + ";" + Convert.ToString(v_residuals[1]) + ";" + Convert.ToString(v_residuals[2]) + ";" +
                                           Convert.ToString(w_residuals[0]) + ";" + Convert.ToString(w_residuals[1]) + ";" + Convert.ToString(w_residuals[2]) + "\n");
                    }

                    if (t >= t_end - m * dt)
                    {
                        ffd_old[counter] = new FluidSolver(ffd);
                        counter++;
                    }
                    if (writeVTK)
                    {
                        pp.export_data_vtk(filepath + @"\\vtk_" + timestep + ".vtk", t, false);
                    }
                    t += dt;
                    timestep++;
                }

                //averaging results
                FluidSolver ffd_mean = new FluidSolver(ffd);
                ffd_mean.p = new double[ffd.p.GetLength(0), ffd.p.GetLength(1), ffd.p.GetLength(2)];
                ffd_mean.u = new double[ffd.u.GetLength(0), ffd.u.GetLength(1), ffd.u.GetLength(2)];
                ffd_mean.v = new double[ffd.v.GetLength(0), ffd.v.GetLength(1), ffd.v.GetLength(2)];
                ffd_mean.w = new double[ffd.w.GetLength(0), ffd.w.GetLength(1), ffd.w.GetLength(2)];
                for (int i = 0; i < ffd_mean.p.GetLength(0); i++)
                {
                    for (int j = 0; j < ffd_mean.p.GetLength(1); j++)
                    {
                        for (int k = 0; k < ffd_mean.p.GetLength(2); k++)
                        {
                            for (int u = 0; u < counter; u++)
                            {
                                ffd_mean.p[i, j, k] += ffd_old[u].p[i, j, k];
                            }
                            ffd_mean.p[i, j, k] /= counter;
                        }
                    }
                }

                for (int i = 0; i < ffd_mean.u.GetLength(0); i++)
                {
                    for (int j = 0; j < ffd_mean.u.GetLength(1); j++)
                    {
                        for (int k = 0; k < ffd_mean.u.GetLength(2); k++)
                        {
                            for (int u = 0; u < counter; u++)
                            {
                                ffd_mean.u[i, j, k] += ffd_old[u].u[i, j, k];
                            }
                            ffd_mean.u[i, j, k] /= counter;
                        }
                    }
                }

                for (int i = 0; i < ffd_mean.v.GetLength(0); i++)
                {
                    for (int j = 0; j < ffd_mean.v.GetLength(1); j++)
                    {
                        for (int k = 0; k < ffd_mean.v.GetLength(2); k++)
                        {
                            for (int u = 0; u < counter; u++)
                            {
                                ffd_mean.v[i, j, k] += ffd_old[u].v[i, j, k];
                            }
                            ffd_mean.v[i, j, k] /= counter;
                        }
                    }
                }

                for (int i = 0; i < ffd_mean.w.GetLength(0); i++)
                {
                    for (int j = 0; j < ffd_mean.w.GetLength(1); j++)
                    {
                        for (int k = 0; k < ffd_mean.w.GetLength(2); k++)
                        {
                            for (int u = 0; u < counter; u++)
                            {
                                ffd_mean.w[i, j, k] += ffd_old[u].w[i, j, k];
                            }
                            ffd_mean.w[i, j, k] /= counter;
                        }
                    }
                }

                de = new DataExtractor(omega, ffd_mean);
            }



            // *******************************************************************************************
            // *******************************************************************************************
            // TO DO:   vtk export
            //   pp.export_data_vtk(String.Concat("lid_driven_cavity_", tstep, ".vtk"), Nx, Ny, Nz, tstep );
            //bool run2 = (bool)Component.Params.Input[5].Sources[0].VolatileData;
            //while (true)



            // *******************************************************************************************
            // Redraw on or off
            // *******************************************************************************************
            //return mean over m*dt, instead of only one snapshot
            if (writeresults)
            {
                //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
                // I could move all this away, an only output de data extractor
                double[,,] p  = new double[Nx, Ny, Nz];
                double[,,] vu = new double[Nx, Ny, Nz];
                double[,,] vv = new double[Nx, Ny, Nz];
                double[,,] vw = new double[Nx, Ny, Nz];

                double[,,] pstag  = new double[Nx + 1, Ny + 1, Nz + 1];
                double[,,] vustag = new double[Nx + 1, Ny + 1, Nz + 1];
                double[,,] vvstag = new double[Nx + 1, Ny + 1, Nz + 1];
                double[,,] vwstag = new double[Nx + 1, Ny + 1, Nz + 1];

                for (int i = 0; i < Nx; i++)
                {
                    for (int j = 0; j < Ny; j++)
                    {
                        for (int k = 0; k < Nz; k++)
                        {
                            if (omega.obstacle_cells[i + 1, j + 1, k + 1] != 1)
                            {
                                p[i, j, k] = de.get_pressure(i * omega.hx + 0.5 * omega.hx, j * omega.hy + 0.5 * omega.hy, k * omega.hz + 0.5 * omega.hz);
                                double[] vel = de.get_velocity(i * omega.hx + 0.5 * omega.hx, j * omega.hy + 0.5 * omega.hy, k * omega.hz + 0.5 * omega.hz);
                                vu[i, j, k] = vel[0];
                                vv[i, j, k] = vel[1];
                                vw[i, j, k] = vel[2];
                            }
                            else
                            {
                                p[i, j, k]  = 0;
                                vu[i, j, k] = 0;
                                vv[i, j, k] = 0;
                                vw[i, j, k] = 0;
                            }
                            pstag[i, j, k] = de.get_pressure(i * omega.hx, j * omega.hy, k * omega.hz);
                            double[] velcen = de.get_velocity(i * omega.hx, j * omega.hy, k * omega.hz);
                            vustag[i, j, k] = velcen[0];
                            vvstag[i, j, k] = velcen[1];
                            vwstag[i, j, k] = velcen[2];
                        }
                    }
                }

                //last x slice
                for (int j = 0; j < Ny + 1; j++)
                {
                    for (int k = 0; k < Nz + 1; k++)
                    {
                        pstag[Nx, j, k] = de.get_pressure((Nx) * omega.hx, j * omega.hy, k * omega.hz);
                        double[] vcen = de.get_velocity((Nx) * omega.hx, j * omega.hy, k * omega.hz);
                        vustag[Nx, j, k] = vcen[0];
                        vvstag[Nx, j, k] = vcen[1];
                        vwstag[Nx, j, k] = vcen[2];
                    }
                }

                //last y slice
                for (int i = 0; i < Nx + 1; i++)
                {
                    for (int k = 0; k < Nz + 1; k++)
                    {
                        pstag[i, Ny, k] = de.get_pressure(i * omega.hx, (Ny) * omega.hy, k * omega.hz);
                        double[] vcen = de.get_velocity(i * omega.hx, (Ny) * omega.hy, k * omega.hz);
                        vustag[i, Ny, k] = vcen[0];
                        vvstag[i, Ny, k] = vcen[1];
                        vwstag[i, Ny, k] = vcen[2];
                    }
                }

                //last z slice
                for (int i = 0; i < Nx + 1; i++)
                {
                    for (int j = 0; j < Ny + 1; j++)
                    {
                        pstag[i, j, Nz] = de.get_pressure(i * omega.hx, j * omega.hy, (Nz) * omega.hz);
                        double[] vcen = de.get_velocity(i * omega.hx, j * omega.hy, (Nz) * omega.hz);
                        vustag[i, j, Nz] = vcen[0];
                        vvstag[i, j, Nz] = vcen[1];
                        vwstag[i, j, Nz] = vcen[2];
                    }
                }

                List <double[, , ]> veloutCen = new List <double[, , ]> {
                };
                veloutCen.Add(vu);
                veloutCen.Add(vv);
                veloutCen.Add(vw);

                List <double[, , ]> veloutStag = new List <double[, , ]> {
                };
                veloutStag.Add(vustag);
                veloutStag.Add(vvstag);
                veloutStag.Add(vwstag);



                DA.SetDataList(0, veloutCen);
                DA.SetData(1, p);
                DA.SetDataList(2, veloutStag);
                DA.SetData(3, pstag);
                DA.SetData(4, de);

                DA.SetData(5, omega.obstacle_cells);
            }
        }
コード例 #10
0
        public bool Run()
        {
            if (xyzsize.Count == 0)
            {
                Rhino.RhinoApp.WriteLine($"\n[{id}] - Error\n");
                return(false);
            }



            run = true;

            counter  = 0;
            timestep = 0;



            double nu = 1.511e-5;       // increase viscosity to impose turbulence. the higher velocity, the higher visc., 1e-3

            FluidSolver.solver_struct solver_params = new FluidSolver.solver_struct();
            double z0;

            if (str_params != null)
            {
                nu = Convert.ToDouble(str_params[0]);
                solver_params.tol             = Convert.ToDouble(str_params[1]);
                solver_params.min_iter        = Convert.ToInt16(str_params[2]);
                solver_params.max_iter        = Convert.ToInt16(str_params[3]);
                solver_params.backtrace_order = Convert.ToInt16(str_params[4]);
                solver_params.mass_correction = str_params[5].Equals("false") ? false : true;
                solver_params.mass_corr_alpha = Convert.ToDouble(str_params[6]);
                solver_params.verbose         = str_params[7].Equals("false") ? false : true;
                z0 = Convert.ToDouble(str_params[8]);
            }
            else
            {
                solver_params.tol             = 1e-4;
                solver_params.min_iter        = 1;
                solver_params.max_iter        = 30;
                solver_params.backtrace_order = 2;
                solver_params.mass_correction = false;
                solver_params.mass_corr_alpha = 0.7;
                solver_params.verbose         = false;
                z0 = 0.1;
            }



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

            // Create empty arrays for body forces
            f_x = new double[Nx + 1, Ny + 2, Nz + 2];
            f_y = new double[Nx + 2, Ny + 1, Nz + 2];
            f_z = new double[Nx + 2, Ny + 2, Nz + 1];



            // Create FFD solver and domain
            //if (ffd == null || resetFFD)
            //{
            //Rhino.RhinoApp.WriteLine($"{id} - "+ "{0}, {1}, {2}", xyzsize[0], xyzsize[1], xyzsize[2]);
            if (terrain == 4)
            {
                omega = new WindInflowOpenFoam(Nx + 2, Ny + 2, Nz + 2, xyzsize[0], xyzsize[1], xyzsize[2], Vmet, z0);
            }
            else
            {
                omega = new WindInflow(Nx + 2, Ny + 2, Nz + 2, xyzsize[0], xyzsize[1], xyzsize[2], Vmet, terrain);
            }

            foreach (double[] geo in geom)
            {
                omega.add_obstacle(geo[0], geo[1], geo[2], geo[3], geo[4], geo[5]);
            }



            ffd = new FluidSolver(omega, dt, nu, u0, v0, w0, solver_params);
            de  = new DataExtractor(omega, ffd);
            t   = 0;

            pp = new PostProcessor(ffd, omega);

            if (id == 0)
            {
                Rhino.RhinoApp.WriteLine($"[{id+1}/{maxSolvers}] - " + "GRASSHOPPER FFD Air Flow Simulation.");
                Rhino.RhinoApp.WriteLine($"[{id+1}/{maxSolvers}] - " + "GH Plug-in: https://github.com/christophwaibel/GH_Wind");
                Rhino.RhinoApp.WriteLine($"[{id+1}/{maxSolvers}] - " + "FFD Solver: https://github.com/lukasbystricky/GSoC_FFD");
                //Rhino.RhinoApp.WriteLine($"[{id+1}/{maxSolvers}] - " + "________________________________________________________");
                //Rhino.RhinoApp.WriteLine($"[{id+1}/{maxSolvers}] - " + "...Domain initialized");
                //Rhino.RhinoApp.WriteLine($"[{id+1}/{maxSolvers}] - " + "________________________________________________________");
            }



            if (run)
            {
                if (writeVTK)
                {
                    pp.export_geometry_vtk(filepath + @"\\vtk_geometry.vtk", 0);
                }

                counter  = 0;
                timestep = 0;
                ffd_old  = new FluidSolver[m];

                //watch.Start();
                //startTime = DateTime.Now;

                while (t < t_end)
                {
                    if (run != true)
                    {
                        break;
                    }

                    RunStep(ref timestep, ref counter);
                }

                //watch.Stop();
            }

            UpdateOutput();

            Rhino.RhinoApp.WriteLine($"[{id+1}/{maxSolvers}] Updated output");

            return(true); //returns to the task manager and updates GH component
        }