{-# LANGUAGE BangPatterns #-} module Stage.Diffusion ( DiffSolver (..) , diffusion) where import Model import FieldElt import Stage.Linear import Data.Array.Repa as R import Data.Array.Repa.Eval as R import Data.Vector.Unboxed data DiffSolver = DiffStable Int | DiffUnstable -- | Diffuse a field at a certain rate. diffusion :: (FieldElt a, Num a, Elt a, Unbox a) => DiffSolver -> Delta -> Rate -> Field a -> IO (Field a) diffusion !solver !delta !rate field = {-# SCC diffusion #-} field `deepSeqArray` let _ :. _ :. width' = R.extent field !width = fromIntegral width' in case solver of DiffUnstable -> let !a = delta * rate * width * width in unstableSolver field field a DiffStable iters -> let !a = delta * rate * width * width !c = 1 + 4 * a in linearSolver field field a c iters {-# SPECIALIZE diffusion :: DiffSolver -> Delta -> Rate -> Field Float -> IO (Field Float) #-} {-# SPECIALIZE diffusion :: DiffSolver -> Delta -> Rate -> Field (Float, Float) -> IO (Field (Float, Float)) #-}