dsmc-0.1.0.0: src/DSMC/Surface.hs
{-# LANGUAGE BangPatterns #-}
{-|
Gas-surface interaction models.
-}
module DSMC.Surface
( Reflector
, Surface(..)
, makeReflector
)
where
import Control.Monad.ST
import System.Random.MWC
import System.Random.MWC.Distributions (normal)
import DSMC.Util.Constants
import DSMC.Util.Vector
-- | A function which takes PRNG state, molecular velocity, surface
-- normal and samples post-collisional wrt to impregnable wall
-- boundary condition.
type Reflector s = GenST s -> Vec3 -> Vec3 -> ST s Vec3
-- | Surface models.
data Surface = CLL { bodyTemperature :: !Double
-- ^ Absolute temperature of surface.
, alpha :: !Double
-- ^ Kinetic energy accomodation for normal
-- velocity component.
, sigma :: !Double
-- ^ Accomodation for tangential momentum.
} |
-- ^ Cercignani-Lampis-Lord model.
Diffuse { bodyTemperature :: !Double
-- ^ Absolute temperature of surface.
, mass :: !Double
-- ^ Mass of reflected molecules (usually equal
-- to that in incident flow).
} |
-- ^ Diffuse reflection.
Mirror
-- ^ Surface with specular reflection.
-- | Produce reflector depending on surface type.
makeReflector :: Surface -> Reflector s
makeReflector (CLL t alphanor sigmatan) =
let
f = sqrt (2 * t * unigas)
alphatan = sigmatan * (2 - sigmatan)
cll :: Reflector s
cll !g !n !vel =
let
!e1 = normalize $ n >< vel
!e2 = normalize $ n >< e1
!ui = -(vel .* n)
!vi = vel .* e2
!urm = ui * sqrt (1 - alphanor) / f
!vrm = vi * (1 - sigmatan)
in do
!angle <- uniformR (0.0, pi * 2) g
!angle' <- uniformR (0.0, pi * 2) g
!v2 <- uniform g
!v2' <- uniform g
let !r = sqrt (- (alphatan * log v2))
!vr = r * (cos angle) * f + vrm
!wr = r * (sin angle) * f
!r' = sqrt (- (alphanor * log v2'))
!ur = sqrt (urm * urm + 2 * r' * urm * (cos angle') + r' * r') * f
return $! ((e1 .^ wr) <+> (e2 .^ vr) <+> (n .^ ur))
{-# INLINE cll #-}
in
cll
makeReflector Mirror = \_ !v !n -> return $! v <-> (n .^ (v .* n) .^ 2)
makeReflector (Diffuse t m) =
let
s = sqrt $ boltzmann * t / m
beta = 1 / (s * (sqrt 2))
diffuse :: Reflector s
diffuse g n vel =
let
e1 = normalize $ n >< vel
e2 = normalize $ n >< e1
in do
w <- normal 0 s g
v <- normal 0 s g
u' <- uniform g
let u = (sqrt (- (log u'))) / beta
return $ (e1 .^ v) <+> (e2 .^ w) <+> (n .^ u)
{-# INLINE diffuse #-}
in
diffuse