haskell-cnc-0.1.3: examples/nbody.hs
{-
- Intel Concurrent Collections for Haskell
- Copyright (c) 2010, Intel Corporation.
-
- This program is free software; you can redistribute it and/or modify it
- under the terms and conditions of the GNU Lesser General Public License,
- version 2.1, as published by the Free Software Foundation.
-
- This program is distributed in the hope it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
- more details.
-
- You should have received a copy of the GNU Lesser General Public License along with
- this program; if not, write to the Free Software Foundation, Inc.,
- 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
-
-}
{-# LANGUAGE ExistentialQuantification
, ScopedTypeVariables
, BangPatterns
, NamedFieldPuns
, RecordWildCards
, FlexibleInstances
, DeriveDataTypeable
#-}
-- Author: Chih-Ping Chen
-- This program uses CnC to calculate the accelerations of the bodies in a 3D system.
import System.Environment
import Data.Int
import Data.List
#include "haskell_cnc.h"
-- This step generates the bodies in the system.
genVectors vectors tag =
do put vectors tag (tag' * 1.0, tag' * 0.2, tag' * 30.0)
where tag' = fromIntegral tag
-- This step computes the accelerations of the bodies.
compute vectors accels n tag =
do vecList <- sequence (List.map (get vectors) [1..n])
vector <- get vectors tag
put accels tag (accel vector vecList)
where accel vector vecList = multTriple g $ sumTriples $ List.map (pairWiseAccel vector) vecList
pairWiseAccel (x,y,z) (x',y',z') = let dx = x'-x
dy = y'-y
dz = z'-z
eps = 0.005
distanceSq = dx^2 + dy^2 + dz^2 + eps
factor = 1/sqrt(distanceSq ^ 3)
in multTriple factor (dx,dy,dz)
sumTriples = foldr (\(x,y,z) (x',y',z') -> (x+x',y+y',z+z')) (0,0,0)
multTriple c (x,y,z) = (c*x,c*y,c*z)
g = 9.8
-- This describes the graph-- The same tag collection prescribes the two step collections.
run n = runGraph $
do tags <- newTagCol
vectors <- newItemCol
accels <- newItemCol
prescribe tags (genVectors vectors)
prescribe tags (compute vectors accels n)
initialize $
do sequence_ (List.map (putt tags) [1..n])
finalize $
do stepPutStr "Begin finalize action.\n"
vecList <- itemsToList vectors
accList <- itemsToList accels
return (vecList, accList)
main =
do args <- getArgs
let (vecList, accList) = case args of
[] -> run 3
[s] -> run (read s)
--putStrLn $ show vecList; putStrLn $ show accList;
-- Do a meaningless sum to generate a small output:
--putStrLn $ show (foldl (\sum (_,(x,y,z)) -> sum + x+y+z) 0 vecList)
--putStrLn $ show (foldl (\sum (_,(x,y,z)) -> sum + x+y+z) 0 accList)
putStrLn $ show (foldl (\sum (_,(x,y,z)) -> if x>0.1 then sum+1 else sum) 0 vecList)
putStrLn $ show (foldl (\sum (_,(x,y,z)) -> if x>0 then sum+1 else sum) 0 accList)