Пример #1
0
        /// <summary>
        /// Initialize the simulator object.
        /// </summary>
        public FluidSimulator getSimulator(int ord)
        {
            DateTime       now = DateTime.UtcNow;
            FluidSimulator s   = new FluidSimulator(progress, new RandomJames(now.Ticks * (ord + 1)));

            return(s);
        }
Пример #2
0
 public WorkerThreadInit(FluidSimulator s, int n, double pptake, double deltat, double variancet)
 {
     sim   = s;
     nPart = n;
     ppt   = pptake;
     dt    = deltat;
     vart  = variancet;
 }
Пример #3
0
        /// <summary>
        /// Simple world containing two segments.
        /// </summary>
        public static void Roof(FluidSimulator sim)
        {
            sim.SetBounds(0.0, 3.0, 0.0, 1.0);

            sim.RemoveAllWalls();
            sim.AddWall(-0.01, 0.0, 3.0, 0.0);
            sim.AddWall(-0.01, 1.0, 3.0, 1.0);
            sim.AddWall(0.0, 0.0, 0.0, 1.0);

            sim.AddWall(0.5, 0.5, 0.9, 0.15);
            sim.AddWall(0.5, 0.5, 0.9, 0.85);
        }
Пример #4
0
        /// <summary>
        /// Simple world containing one rectangle.
        /// </summary>
        public static void Rectangle(FluidSimulator sim)
        {
            sim.SetBounds(0.0, 3.0, 0.0, 1.0);

            sim.RemoveAllWalls();
            sim.AddWall(-0.01, 0.0, 3.0, 0.0);
            sim.AddWall(-0.01, 1.0, 3.0, 1.0);
            sim.AddWall(0.0, 0.0, 0.0, 1.0);

            sim.AddWall(0.5, 0.2, 0.5, 0.8);
            sim.AddWall(0.5, 0.2, 1.1, 0.2);
            sim.AddWall(0.5, 0.8, 1.1, 0.8);
            sim.AddWall(1.1, 0.2, 1.1, 0.8);
        }
Пример #5
0
        /// <summary>
        /// Simple world with a maze.
        /// </summary>
        public static void Maze(FluidSimulator sim)
        {
            sim.SetBounds(0.0, 3.0, 0.0, 1.0);

            sim.RemoveAllWalls();
            sim.AddWall(-0.01, 0.0, 3.0, 0.0);
            sim.AddWall(-0.01, 1.0, 3.0, 1.0);
            sim.AddWall(0.0, 0.0, 0.0, 1.0);

            sim.AddWall(0.4, 0.0, 0.4, 0.8);
            sim.AddWall(0.6, 0.2, 0.6, 1.0);
            sim.AddWall(0.8, 0.0, 0.8, 0.8);
            sim.AddWall(1.0, 0.2, 1.0, 1.0);
            sim.AddWall(1.2, 0.0, 1.2, 0.8);
            sim.AddWall(1.4, 0.2, 1.4, 1.0);
        }
Пример #6
0
        /// <summary>
        /// Runs the simulation (in separate thread[s]).
        /// </summary>
        public void RunSimulation()
        {
            // allocate & init simulator array:
            int threads = Math.Max(1, Environment.ProcessorCount - 1);

            if (!UseMultithreading)
            {
                threads = 1;
            }
            sims = new List <FluidSimulator>(threads);
            int t;

            for (t = 0; t < threads; t++)
            {
                FluidSimulator fs = getSimulator(t);
                worldInitFunctions[SelectedWorld](fs);
                sims.Add(fs);
            }
            int origW = width;
            int origH = height;

            foreach (var sim in sims)
            {
                width  = origW;
                height = origH;
                sim.SetPresentationSize(ref width, ref height);
                sim.InitBuffers();
            }

            // output presentation image:
            if (form.outputImage != null)
            {
                form.outputImage.Dispose();
            }
            form.outputImage = new Bitmap(width, height, PixelFormat.Format24bppRgb);
            SyncObject so = new SyncObject();

            so.bmp = form.outputImage;

            if (dirty ||
                oldWidth != width ||
                oldHeight != height)
            {
                SimTime      = 0.0;
                TotalSpawned = 0L;
                cell         = new int[height, width];
                vx           = new double[height, width];
                vy           = new double[height, width];
                power        = new double[height, width];
                dirty        = false;
            }
            else
            {
                sims[0].SimTime      = SimTime;
                sims[0].TotalSpawned = TotalSpawned;
                System.Array.Copy(cell, sims[0].cell, width * height);
                System.Array.Copy(vx, sims[0].vx, width * height);
                System.Array.Copy(vy, sims[0].vy, width * height);
                System.Array.Copy(power, sims[0].power, width * height);
            }

            // progress & timer:
            progress.SyncInterval = ((width * (long)height) > (2L << 20)) ? 30000L : 10000L;
            progress.Reset();
            lock ( sw )
            {
                sw.Reset();
                sw.Start();
            }

            // run the simulators:
            Thread[] pool = new Thread[threads];
            for (t = 0; t < threads; t++)
            {
                pool[t] = new Thread(new ParameterizedThreadStart(this.SimulationWorker));
            }
            for (t = threads; --t >= 0;)
            {
                pool[t].Start(new WorkerThreadInit(sims[t], 8000, 4500.0f, 0.004, 0.004));
            }

            do
            {
                Thread.Sleep(2000);

                bool velocity = false;
                bool pressure = false;
                lock ( progress )
                {
                    if (!progress.Continue)
                    {
                        break;
                    }
                    if (!progress.NeedsSync())
                    {
                        continue;
                    }

                    velocity = progress.velocity;
                    pressure = progress.pressure;
                }

                // 1. collect data from all workers:
                int x, y;
                lock ( cell )
                {
                    lock (sims[0].cell)
                    {
                        TotalSpawned = sims[0].TotalSpawned;
                        SimTime      = sims[0].SimTime;
                        System.Array.Copy(sims[0].cell, cell, width * height);
                        System.Array.Copy(sims[0].vx, vx, width * height);
                        System.Array.Copy(sims[0].vy, vy, width * height);
                        System.Array.Copy(sims[0].power, power, width * height);
                    }
                    for (t = 1; t < threads; t++)
                    {
                        lock (sims[t].cell)
                        {
                            TotalSpawned += sims[t].TotalSpawned;
                            SimTime      += sims[t].SimTime;
                            for (y = 0; y < height; y++)
                            {
                                for (x = 0; x < width; x++)
                                {
                                    cell[y, x]  += sims[t].cell[y, x];
                                    vx[y, x]    += sims[t].vx[y, x];
                                    vy[y, x]    += sims[t].vy[y, x];
                                    power[y, x] += sims[t].power[y, x];
                                }
                            }
                        }
                    }
                }
                so.simTime      = SimTime;
                so.totalSpawned = TotalSpawned;

                // 2. visualizations - default (pressure/velocity) and/or custom
                if (progress.velocity ||
                    progress.pressure ||
                    progress.custom)
                {
                    maxV2N = 0.001;
                    double V2N;
                    maxV = 0.0;

                    int n;
                    for (y = 2; y < height - 2; y++) // avoid borders..
                    {
                        for (x = 2; x < width - 2; x++)
                        {
                            if ((n = cell[y, x]) > 0)
                            {
                                if ((V2N = n * power[y, x]) > maxV2N)
                                {
                                    maxV2N = V2N;
                                }
                                double mvx = Math.Abs(vx[y, x] / n);
                                double mvy = Math.Abs(vy[y, x] / n);
                                if (mvx > maxV)
                                {
                                    maxV = mvx;
                                }
                                if (mvy > maxV)
                                {
                                    maxV = mvy;
                                }
                            }
                        }
                    }

                    int origin = 0;
                    if (progress.velocity)
                    {
                        origin += height;
                    }
                    if (progress.pressure)
                    {
                        origin += height;
                    }
                    if (progress.custom)
                    {
                        origin += height;
                    }

                    if (origin > 0 && origin != form.outputImage.Height)
                    {
                        if (form.outputImage != null)
                        {
                            form.outputImage.Dispose();
                        }
                        so.bmp = form.outputImage = new Bitmap(width, origin, PixelFormat.Format24bppRgb);
                    }

                    origin = 0;
                    // individual visualizations - velocity
                    if (progress.velocity)
                    {
                        VisualizeVelocity(so, 0, origin);
                        origin += height;
                    }

                    // individual visualizations - pressure
                    if (progress.pressure)
                    {
                        VisualizePressure(so, 0, origin);
                        origin += height;
                    }

                    // individual visualizations - custom routine
                    if (progress.custom)
                    {
                        VisualizeCustom(so, 0, origin, progress.param);
                        origin += height;
                    }

                    progress.Sync(so);
                }
            }while (true);

            // wait for the simulator threads:
            for (t = 0; t < threads; t++)
            {
                pool[t].Join();
                pool[t] = null;
            }

            long elapsed;

            lock ( sw )
            {
                sw.Stop();
                elapsed = sw.ElapsedMilliseconds;
            }

            string msg = string.Format(CultureInfo.InvariantCulture,
                                       "{0:f1}s  [ {1}x{2}, mt{3}, sim{4:f1}s, spawned{5} ]",
                                       1.0e-3 * elapsed, width, height, threads,
                                       SimTime, Util.kmg(TotalSpawned));

            form.SetText(msg);
            Console.WriteLine("Simulation finished: " + msg);
            form.SetImage((Bitmap)form.outputImage.Clone());

            form.StopSimulation();
        }