Created
June 25, 2017 08:29
-
-
Save rinx/19150e14bea1af695dd180b10868c17c to your computer and use it in GitHub Desktop.
monte carlo 1d radiative transfer code written in haskell using random-mersenne package and infinite list of random numbers.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import System.Random.Mersenne | |
np = 1000000 | |
tau = 1.0 -- cloud optical thickness | |
sal = 0.5 -- surface albedo | |
omg = 1.0 -- single scattering albedo | |
zu = tau -- atmosphere upper boundary | |
zb = 0.0 -- atmosphere lower boundary | |
main :: IO () | |
main = do | |
seed0 <- getStdGen | |
(sumr, sumt) <- randoms seed0 >>= world | |
print $ [sumr / np, sumt / np] | |
world :: [Double] -> IO (Double, Double) | |
world rn = loop 0 0.0 0.0 rn | |
where | |
loop :: Double -> Double -> Double -> [Double] -> IO (Double, Double) | |
loop t sumr sumt rn' | |
| t == np = return (sumr, sumt) | |
| otherwise = do | |
((wr, wt), rn'') <- solver 1.0 zu (-1.0) 0.0 0.0 rn' | |
loop (t+1) (sumr + wr) (sumt + wt) rn'' | |
solver :: Double -> Double -> Double | |
-> Double -> Double | |
-> [Double] -> IO ((Double, Double), [Double]) | |
solver w z dir sumr sumt rn = do | |
(n:rn') <- return rn | |
path <- return $ -log(n) | |
nextphase (z + dir * path) rn' | |
where | |
nextphase zn rn'' | |
| zn <= zb = solver (w * sal) zb 1.0 sumr (sumt + w) rn'' | |
| zn > zu = return ((sumr + w, sumt), rn'') | |
| otherwise = do | |
(n2:rn''') <- return rn'' | |
dnew <- return $ if n2 <= 0.5 | |
then 1.0 * dir | |
else -1.0 * dir | |
solver (w * omg) zn dnew sumr sumt rn''' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
benchmark
for 1000000 photons