accelerate-examples-1.1.0.0: examples/fluid/src-acc/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 Control.Exception
import Graphics.Gloss.Interface.IO.Game
import Prelude as P
import Data.Array.Accelerate as A
import Data.Array.Accelerate.Examples.Internal as A
main :: IO ()
main = do
beginMonitoring
(conf, opts, rest) <- initialiseConfig =<< parseArgs options defaults header footer
let -- configuration parameters
--
width = get simulationWidth conf * get displayScale conf
height = get simulationHeight conf * get displayScale conf
steps = get simulationSteps conf
fps = get displayFramerate conf
dp = get viscosity conf
dn = get diffusion conf
dt = get timestep conf
backend = get optBackend opts
-- Prepare user-input density and velocity sources
--
sources s = let (ix, ss) = P.unzip s
sh = Z :. P.length ix
in ( A.fromList sh ix, A.fromList sh ss )
-- for benchmarking
--
force w =
indexArray (densityField w) (Z:.0:.0) `seq`
indexArray (velocityField w) (Z:.0:.0) `seq` w
-- 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.
--
step = run1 backend (fluid steps dt dp dn)
simulate world =
let ds = sources (densitySource world)
vs = sources (velocitySource world)
(df', vf') = step ( ds, vs, densityField world, velocityField world )
in
force $ world { densityField = df', velocityField = vf'
, densitySource = [], velocitySource = [] }
-- warming up...
--
initialWorld <- evaluate (initialise conf)
_ <- evaluate (simulate initialWorld)
runBenchmarks opts rest
[ bench "fluid" $ whnf simulate initialWorld ]
runInteractive opts rest
$ playIO
(InWindow "accelerate-fluid" (width, height) (10, 20))
black -- background colour
fps -- display framerate
initialWorld -- initial state of the simulation
(render conf) -- render world state into a picture
(react conf) -- handle user events
(\_ -> return . simulate) -- one step of the simulation