packages feed

dsmc-tools (empty) → 0.1.0.0

raw patch · 10 files changed

+665/−0 lines, 10 filesdep +ConfigFiledep +basedep +bytestringsetup-changed

Dependencies added: ConfigFile, base, bytestring, cmdargs, dsmc, gloss, gloss-raster, hslogger, mtl, repa, strict, transformers, vector

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright (c) 2012, Dmitry Dzhus++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Dmitry Dzhus nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README view
@@ -0,0 +1,52 @@+This package provides CLI to dsmc library to perform rarefied gas flow+simulation. The tool is named `dsmc-runner`. Another tool,+`dsmc-caster` is used to render CSG bodies to check if the body+geometry is defined correctly.++Both programs can be run with `-?` flag to obtain usage informaiton+and help of command-line flags.++To run programs using multiple threads, specify `+RTS -N` flag.++Extra data files which are installed with this package can be found in+`share` directory used by Cabal.++* dsmc-runner++To perform a simulation, input parameters for DSMC must be defined in+«problem file», which uses INI-like format, see `example.prb` included+in the package.++To define the body (which is then referenced from the problem file),+`.geo` format is used, see `body.geo`, `smiley.geo` and `reentry2.geo`+for example.++The runner dumps macroscopic data in text format to the file specified+using `-m` option, which can be then analyzed using visualization+software like ParaView.++To sum up,++    $ dsmc-runner example.prb -m macro.txt +RTS -N++    2012-06-13 11:32:02 MSK: [DEBUG] Program started+    2012-06-13 11:32:02 MSK: [DEBUG] Using problem file: example.prb+    2012-06-13 11:32:02 MSK: [DEBUG] Macroscopic data output file: macro.txt+    2012-06-13 11:32:02 MSK: [DEBUG] Not writing ensemble data+    2012-06-13 11:32:02 MSK: [DEBUG] Using body definition file: ./reentry2.geo+    2012-06-13 11:32:02 MSK: [DEBUG] Starting simulation+    2012-06-13 11:32:04 MSK: [DEBUG] Not steady yet; particles count: 1662080+    2012-06-13 11:32:05 MSK: [DEBUG] Not steady yet; particles count: 1661946+    2012-06-13 11:32:06 MSK: [DEBUG] Not steady yet; particles count: 1662026+    …++* dsmc-caster+  +dsmc-caster is a program used to view bodies defined using `.geo`+format.++    $ dsmc-caster smiley.geo +RTS -N++Drag with left mouse button to rotate the object and mouse wheel to+zoom in/out. More command-line options are available, see usage help+with `-?` flag.
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ body.geo view
@@ -0,0 +1,8 @@+solid cap = sphere (0, 0, -0.8; 3.1);+solid body = cone (0, 0, -5; 5; 0, 0, 0; 3);+solid bottom = sphere (0, 0, 0; 5); ++solid upper = cap or body;+solid whole = upper and bottom;++tlo whole;
+ dsmc-tools.cabal view
@@ -0,0 +1,49 @@+name:                dsmc-tools+description:         CLI tools for dsmc library+version:             0.1.0.0+synopsis:            DSMC toolkit for rarefied gas dynamics+license:             BSD3+license-file:        LICENSE+author:              Dmitry Dzhus+maintainer:          dima@dzhus.org+category:            Physics++data-files:          README, example.prb, body.geo, smiley.geo, reentry2.geo++build-type:          Simple+cabal-version:       >=1.8+tested-with:         GHC == 7.4.1++source-repository head+  type: git+  location: https://github.com/dzhus/dsmc-tools/++executable dsmc-caster+  ghc-options: -Wall -O2 -funbox-strict-fields -Odph -rtsopts -threaded -fno-liberate-case -funfolding-use-threshold1000 -funfolding-keeness-factor1000 -fllvm -optlo-O3+  main-is: src/Caster.hs++  -- other-modules:++  build-depends:+    base         == 4.*,+    cmdargs      == 0.9.*,+    dsmc         == 0.1.*,+    gloss        == 1.7.*,+    gloss-raster == 1.7.*,+    strict       == 0.3.*++executable dsmc-runner+  ghc-options: -Wall -O2 -funbox-strict-fields -Odph -rtsopts -threaded -fno-liberate-case -funfolding-use-threshold1000 -funfolding-keeness-factor1000 -fllvm -optlo-O3+  main-is: src/Runner.hs++  build-depends:+    base           == 4.*,+    bytestring     == 0.9.*,+    cmdargs        == 0.9.*,+    ConfigFile     == 1.1.*,+    dsmc           == 0.1.*,+    hslogger       == 1.2.*,+    transformers   == 0.3.*,+    mtl            == 2.1.*,+    repa           == 3.2.*,+    vector         == 0.9.*
+ example.prb view
@@ -0,0 +1,52 @@+[Body]+# Path to body definition file+definition = ./reentry2.geo+volume_points = 1000++[Flow]+# Absolute temperature, in K+t = 300++# Concentration+n = 1e20++# Molecular mass+m = 29++# Flow velocity components, in m/s+velocity = (1000, 0, 0)++# How many real particles a single simulator particle represents+fn = 5e16++[Surface]+temperature = 300++[Macroscopic]+# Macroscopic grid sizes, in m+mx = 0.1+my = 0.1+mz = 0.1++[Domain]+# Domain dimensions by x, y, z in m+w = 12+l = 12+h = 6++[Simulation]+dt = 1e-5++# For how many steps in steady regime to collect macroscopic data+steady_steps = 500++# Consider the system steady when the ratio of total particle counts+# on two consecutive steps differs from unit for less than this number+steady_epsilon = 1e-6++# Interface domains extrusion+ex = 0.04++# Start with empty simulation domain if true, fill it with particles+# distributed according to flow parameters upon start otherwise+empty_start = false
+ reentry2.geo view
@@ -0,0 +1,5 @@+solid s = sphere (0, 0, 0; 2);+solid s2 = sphere (1, 0, 0; 2.8);+solid whole = s and s2;++tlo whole;
+ smiley.geo view
@@ -0,0 +1,14 @@+solid head = sphere (0, 0, 0; 10);+solid cut = plane (1, 0, 0; 1, 0, 0) and plane (-1, 0, 0; -1, 0, 0);+++solid eyeballs = sphere (0, -4.2, 3; 2) or sphere (0, 4.2, 3; 2);+solid eyecuts = not eyeballs;+++solid smile = cylinder (-2, 0, 0; 2, 0, 0; 5) and not cylinder (-3, 0, 2; 3, 0, 2; 5);++solid smilecut = head and cut and eyecuts;+solid whole = smilecut and not smile;++tlo whole;
+ src/Caster.hs view
@@ -0,0 +1,207 @@+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE BangPatterns #-}++{-|++Standalone raycasting runner for traceable objects.++|-}++import Prelude hiding (reverse)++import GHC.Float++import Graphics.Gloss.Data.Color+import Graphics.Gloss.Data.Display+import qualified Graphics.Gloss.Data.Point as G+import qualified Graphics.Gloss.Interface.Pure.Game as G+import Graphics.Gloss.Raster.Field hiding (Point)++import System.Console.CmdArgs.Implicit++import qualified Data.Strict.Maybe as S+import qualified Data.Strict.Tuple as S++import DSMC.Particles+import DSMC.Traceables+import DSMC.Traceables.Parser+import DSMC.Util.Vector+++data InteractionMode = None | Rotate | Pan+++-- | World state with observation point parameters and event helpers.+-- Roll is always 0.+data World = World { dist :: Double+                   -- ^ Distance to origin.+                   , pitch :: Double+                   , yaw :: Double+                   -- ^ Yaw of camera as if it was in origin.+                   , target :: Point+                   -- ^ Where camera looks at.+                   , holdPoint :: Maybe (Float, Float)+                   -- ^ Point where mouse button was held down.+                   , mode :: InteractionMode+                   }+++-- | Static command line options for caster.+data Options = Options+    { bodyDef :: FilePath+    , width :: Int+    , height :: Int+    , pixels :: Int+    , brightRGBA :: (Float, Float, Float, Float)+    -- ^ Color for bright surfaces parallel to view plane (RGBA)+    , darkRGBA :: (Float, Float, Float, Float)+    -- ^ Color for dark surfaces perpendicular to view plane (RGBA)+    }+    deriving (Data, Typeable)+++type Ray = Particle+++-- | Pixels in meter at unit distance.+scaleFactor :: Double+scaleFactor = 50.0+++-- | Initial world.+start :: World+start = World 5 0 0 origin Nothing None+++uncurry4 :: (a -> b -> c -> d -> e) -> (a, b, c, d) -> e+uncurry4 f (a, b, c, d) = f a b c d+++-- |  Scale deltas between hold and release coordinates by this number.+dragFactor :: Double+dragFactor = pi / 1800+++-- | Change distance by this amount per one mouse wheel step.+zoomFactor :: Double+zoomFactor = 0.01+++-- | Handle mouse drag to change pitch & yaw and mouse wheel to zoom.+handleEvents :: G.Event -> World -> World+handleEvents e w =+    case e of+      G.EventKey (G.MouseButton G.LeftButton) G.Down _ c ->+          w{holdPoint = Just c, mode = Rotate}+      G.EventKey (G.MouseButton G.RightButton) G.Down _ c ->+          w{holdPoint = Just c, mode = Pan}+      G.EventKey (G.MouseButton _) G.Up _ _ -> +          w{holdPoint = Nothing}+      G.EventKey (G.MouseButton G.WheelDown) _ _ _ -> +          w{dist = dist w + zoomFactor}+      G.EventKey (G.MouseButton G.WheelUp) _ _ _ -> +          w{dist = dist w - zoomFactor}+      G.EventKey (G.Char 'r') G.Down _ _ ->+          w{ target = origin+           , yaw = 0+           , pitch = 0}+      G.EventMotion p@(x, y) ->+          case (holdPoint w) of+            Nothing -> w+            Just (u, v) -> +                let+                    xdelta = (float2Double (x - u)) * dragFactor+                    ydelta = (float2Double (y - v)) * dragFactor+                in+                  case (mode w) of+                    Rotate -> w{ holdPoint = Just p+                               , yaw = (yaw w) - xdelta+                               , pitch = (pitch w) + ydelta+                               }+                    Pan -> +                        let+                            !(_, sX, sY) = buildCartesian (yaw w) (pitch w)+                        in +                          w{ holdPoint = Just p+                           , target = (target w) <+> (sX .^ xdelta) <-> (sY .^ ydelta)+                           }+                    _ -> w+      _ -> w+++casterField :: Int+            -- ^ Window width.+            -> Int+            -- ^ Window height.+            -> Int+            -- ^ Pixels per point.+            -> Body+            -- ^ Body to show.+            -> Color+            -- ^ Bright color.+            -> Color+            -- ^ Dark color.+            -> IO ()+casterField width height pixels body bright' dark' =+    let+        display = InWindow "dsmc-tools CSG raycaster" (width, height) (0, 0)+        makePixel :: World -> G.Point -> Color+        !wS = fromIntegral (width `div` 2)+        !hS = fromIntegral (height `div` 2)+        makePixel !w !(x, y) =+            let+                !d = dist w+                !wScale = -(wS * d / scaleFactor)+                !hScale = (hS * d / scaleFactor)+                !(n, sX, sY) = buildCartesian (yaw w) (pitch w)+                !p = n .^ (-d) <+> target w+                ray :: Ray+                !ray = ((p+                        <+> (sX .^ ((float2Double x) * wScale))+                        <+> (sY .^ ((float2Double y) * hScale))), n)++                !hp = trace body ray+            in+              case hp of+                (((S.:!:) (HitPoint _ (S.Just hn)) _):_) ->+                    mixColors factor (1 - factor) bright' dark'+                    where+                      factor = abs $ double2Float $ invert n .* hn+                _ -> white+        {-# INLINE makePixel #-}+    in+      playField display (pixels, pixels) 5 start makePixel+                    handleEvents+                    (flip const)+++-- | Read body def and program arguments, run the actual caster on+-- success.+main :: IO ()+main =+    let+        sample = Options+                 { bodyDef = def &= argPos 0 &= typ "BODY-FILE"+                 , width = 500 &= help "Window width"+                 , height = 500 &= help "Window height"+                 , pixels = 1+                   &= help ("Number of pixels to draw per point," +++                            "in each dimension")+                 , brightRGBA = (0.9, 0.9, 0.9, 1)+                   &= help ("Color for surface parallel to view plane," +++                            " with each component within [0..1]")+                   &= typ "R,G,B,A"+                 , darkRGBA = (0, 0, 0, 1)+                   &= help "Color for surface perpendicular to view plane"+                   &= typ "R,G,B,A"+                 }+                 &= program "dsmc-caster"+    in do+      Options{..} <- cmdArgs $ sample+      body <- parseBodyFile bodyDef+      case body of+        Right b -> casterField width height pixels b+                   (uncurry4 makeColor brightRGBA)+                   (uncurry4 makeColor darkRGBA)+        Left e -> error $ "Problem when reading body definition: " ++ e
+ src/Runner.hs view
@@ -0,0 +1,246 @@+{-# LANGUAGE BangPatterns #-}+{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE ScopedTypeVariables #-}++module Main++where++import Control.Monad.Error+import Control.Exception++import Data.ByteString.Char8 as B++import Data.ConfigFile++import Data.Functor++import Data.Vector.Unboxed as VU hiding ((++))++import System.Console.CmdArgs.Implicit++import System.IO++import System.Log+import System.Log.Logger+import System.Log.Formatter+import System.Log.Handler (setFormatter)+import System.Log.Handler.Simple++import DSMC+import DSMC.Domain+import DSMC.Macroscopic+import DSMC.Particles+import DSMC.Surface+import DSMC.Traceables.Parser+import DSMC.Util.Constants+import DSMC.Util.Vector++import Data.Array.Repa as R hiding ((++))++import GHC.Conc.Sync+++simSection :: String+simSection = "Simulation"+++flowSection :: String+flowSection = "Flow"+++domainSection :: String+domainSection = "Domain"+++macroSection :: String+macroSection = "Macroscopic"++bodySection :: String+bodySection = "Body"+++surfaceSection :: String+surfaceSection = "Surface"+++-- | Command-line options for the runner.+data Options = Options+    { probDef :: FilePath+    , macroFile :: Maybe FilePath+    , ensFile :: Maybe FilePath+    }+    deriving (Data, Typeable)++main :: IO ()+main =+  let+    sample = Options+             { probDef = def &= argPos 0 &= typ "PROBLEM-FILE"+             , macroFile = Nothing &= help "Macroscopic data output file"+             , ensFile = Nothing &= help "Ensemble data output file"+             }+             &= program "dsmc-runner"+  in do+    -- | Setup logging to stderr+    let lf = simpleLogFormatter "$time: [$prio] $msg"+    lh <- (flip setFormatter) lf <$> verboseStreamHandler stderr DEBUG+    updateGlobalLogger rootLoggerName (setLevel DEBUG . setHandlers [lh] )++    debugM rootLoggerName "Program started"++    Options{..} <- cmdArgs $ sample++    debugM rootLoggerName ("Using problem file: " ++ probDef)++    debugM rootLoggerName $+           maybe "Not writing macroscopic data"+           ("Macroscopic data output file: " ++) macroFile++    debugM rootLoggerName $+           maybe "Not writing ensemble data"+           ("Ensemble data output file: " ++) ensFile++    -- Use number of cores as split factor for parallelizing+    -- stochastic processes.+    nsplit <- getNumCapabilities++    (hr :: Either IOException Handle) <- try (openFile probDef ReadMode)+    case hr of+      Left e -> errorM rootLoggerName $ show e+      Right hdl -> do+        res <- runErrorT $ do+                 cp <- join $ liftIO $ readhandle emptyCP hdl+                 -- Must refactor this somehow (actually, write CmdArgs+                 -- for .ini files)+                 n <- get cp flowSection "n"+                 t <- get cp flowSection "t"+                 m <- get cp flowSection "m"+                 v <- get cp flowSection "velocity"+                 sw <- get cp flowSection "fn"+                 w <- get cp domainSection "w"+                 l <- get cp domainSection "l"+                 h <- get cp domainSection "h"+                 ex <- get cp simSection "ex"+                 dt <- get cp simSection "dt"+                 ssteps <- get cp simSection "steady_steps"+                 sepsilon <- get cp simSection "steady_epsilon"+                 emptys <- get cp simSection "empty_start"+                 vpts <- get cp bodySection "volume_points"+                 mx <- get cp macroSection "mx"+                 my <- get cp macroSection "my"+                 mz <- get cp macroSection "mz"+                 bodyDef <- get cp bodySection "definition"+                 -- Interface to diffuse model only+                 surfTemp <- get cp surfaceSection "temperature"+                 return $ (Flow n t (m * amu) v sw, ex, dt,+                           ssteps, sepsilon, emptys,+                           vpts,+                           mx, my, mz,+                           makeDomain origin w l h,+                           bodyDef,+                           surfTemp)+        case res of+          Left e -> errorM rootLoggerName $+                    "Problem when reading problem definition: " ++ show e+          Right (flow, ex, dt,+                 ssteps, sepsilon, emptys,+                 vpts,+                 mx, my, mz,+                 domain,+                 bodyDef,+                 surfTemp) -> do+                   -- Try to read body from definition file+                   debugM rootLoggerName $+                          "Using body definition file: " ++ bodyDef+                   body <- parseBodyFile bodyDef+                   case body of+                     Left e -> errorM rootLoggerName $+                               "Problem when reading body definition: " ++ e+                     Right b ->+                       do+                         debugM rootLoggerName $ "Starting simulation"+                         -- Run the simulation, obtaining+                         -- iteration count and final+                         -- distributions+                         !(iters, e, macro) <-+                           simulate domain b flow dt+                                    emptys ex sepsilon ssteps+                                    (Diffuse surfTemp $+                                     DSMC.Particles.mass flow)+                                    (mx, my, mz) vpts nsplit+                         debugM rootLoggerName "Simulation complete"+                         debugM rootLoggerName $+                                "Particle count when finished: " +++                                (show $ ensembleSize e)+                         debugM rootLoggerName $+                                "Total iterations done: " +++                                (show iters)+                         case macroFile of+                           Just fp -> do+                             debugM rootLoggerName $+                               "Writing macroscopic data to file file: " ++ fp+                             saveMacroscopic macro fp+                           Nothing -> return ()+                         case ensFile of+                           Just fp -> do+                             debugM rootLoggerName $+                               "Writing ensemble data to file: " ++ fp+                             saveEnsemble e fp+                           Nothing -> return ()+                         return ()+++fd :: Double -> ByteString+fd = pack . show+{-# INLINE fd #-}+++ws :: ByteString+ws = B.singleton ' '+++nl :: ByteString+nl = B.singleton '\n'+++-- | Save Repa array in text file, one element per line.+saveRepa :: (Unbox e) =>+         (e -> ByteString)+         -- ^ Formatter function.+         -> ByteString+         -- ^ Header line+         -> R.Array U sh e+         -> FilePath+         -> IO ()+saveRepa f header array path = do+    h <- openFile path WriteMode+    hPut h $ B.concat [header, nl]+    VU.forM_ (R.toUnboxed array) (hPut h . f)+++formatParticle :: Particle -> ByteString+formatParticle ((x, y, z), (u, v, w)) =+    B.concat [fd x, ws, fd y, ws, fd z, ws, fd u, ws, fd v, ws, fd w, nl]+{-# INLINE formatParticle #-}+++formatMacroParameters :: (Point, IntensiveMacroParameters) -> ByteString+formatMacroParameters ((x, y, z), (n, (u, v, w), p, t)) =+    if n == 0.0 then B.empty+    else B.concat [fd x, ws, fd y, ws, fd z, ws,+                   fd n, ws,+                   fd u, ws, fd v, ws, fd w, ws,+                   fd p, ws, fd t, nl]+{-# INLINE formatMacroParameters #-}+++saveMacroscopic :: MacroField -> FilePath -> IO ()+saveMacroscopic =+  saveRepa formatMacroParameters $+  B.pack "x y z number_density u_avg v_avg w_avg pressure trans_temp"+++saveEnsemble :: Ensemble -> FilePath -> IO ()+saveEnsemble = saveRepa formatParticle $ B.pack "x y z u v w"