packages feed

accelerate-examples-0.12.0.0: examples/fluid/src/Main.hs

--
-- A stable fluid simulation
--
-- Jos Stam, "Real-time Fluid Dynamics for Games"
--

module Main where

import Config
import World
import Fluid
import Event
import Data.Label
import Criterion.Main
import System.Environment
import Graphics.Gloss.Interface.IO.Game

import Prelude                                  as P
import Data.Array.Accelerate                    as A


main :: IO ()
main = do
  (opt,noms)    <- processArgs =<< getArgs
  let -- configuration parameters
      --
      width     = get simulationWidth  opt * get displayScale opt
      height    = get simulationHeight opt * get displayScale opt
      fps       = get displayFramerate opt
      dp        = get viscosity opt
      dn        = get diffusion opt

      -- Prepare user-input density and velocity sources
      --
      sources s = let (ix, ss)  = P.unzip s
                      sh        = Z :. length ix
                  in  ( A.fromList sh ix, A.fromList sh ss )

      -- Prepare to execute the next step of the simulation.
      --
      -- Critically, we use the run1 execution form to ensure we bypass all
      -- front-end conversion phases.
      --
      simulate timestep world =
        let step        = run1 opt (fluid dp dn)
            dt          = A.fromList Z [timestep]
            ds          = sources (densitySource world)
            vs          = sources (velocitySource world)
            (df', vf')  = step ( dt, ds, vs, densityField world, velocityField world )
        in
        return $ world { densityField  = df', velocityField  = vf'
                       , densitySource = [],  velocitySource = [] }

  -- warming up...
  initialWorld  <- initialise opt
  _             <- simulate 0.1 initialWorld

  if get optBench opt
     -- benchmark
     then withArgs noms $ defaultMain
              [ bench "fluid" $ whnfIO (simulate 1.0 initialWorld) ]

     -- simulate
     else playIO
              (InWindow "accelerate-fluid" (width, height) (10, 20))
              black                     -- background colour
              fps                       -- display framerate
              initialWorld              -- initial state of the simulation
              (render opt)              -- render world state into a picture
              (react opt)               -- handle user events
              simulate                  -- one step of the simulation