TBit-0.4.2.0: TBit/Parameterization.hs
module TBit.Parameterization ( loadParams
, getScalar
, getVector
, getMesh
, crunch
, primitiveLattice
, recipPrimitiveLattice) where
import TBit.Types
import Prelude hiding (map, head)
import Control.Monad.State
import Control.Monad.Except
import qualified Data.Map as M
import Data.Complex
import Data.List.Stream (map, head)
import Data.Maybe
import Numeric.LinearAlgebra.HMatrix (toColumns, fromRows, col, linearSolve, Vector)
-- |Given a list of ('Prelude.String', a) pairs, return a mapping from the
-- string to the value. Such a map is suitable for setting the 'TBit.Types.scalarParams'
-- and 'TBit.Types.vectorParams' records of the 'TBit.Types.Parameters' type.
loadParams :: [(String, a)] -> M.Map String a
loadParams = foldl (flip (uncurry M.insert)) M.empty
-- |Given a 'Prelude.String', retrieve that value from the parameterization monad.
-- If no such scalar has been uploaded to the 'TBit.Types.Parameters' type, 'getScalar'
-- with throw an error in 'TBit.Types.Parameterized'\'s 'Control.Monad.Except.ExceptT' monad.
getScalar :: String -> Parameterized (Complex Double)
getScalar s = do p <- gets (M.lookup s . scalarParams)
if isJust p
then return $ fromJust p
else throwError
$ UnknownParameter s
realScalar :: String -> Parameterized Double
realScalar = liftM realPart . getScalar
complexScalar :: String -> Parameterized (Complex Double)
complexScalar = getScalar
-- |Given a 'Prelude.String', retrieve that value from the parameterization monad.
-- If no such scalar has been uploaded to the 'TBit.Types.Parameters' type, 'getScalar'
-- with throw an error in 'TBit.Types.Parameterized'\'s 'Control.Monad.Except.ExceptT' monad.
getVector :: String -> Parameterized (Vector (Complex Double))
getVector s = do p <- gets (M.lookup s . vectorParams)
if isJust p
then return $ fromJust p
else throwError
$ UnknownParameter s
-- |Return the spacing information for purposes of gridding the Brillouin zone.
getMesh :: Parameterized Meshing
getMesh = gets meshingData
-- |Compute a 'TBit.Types.Parameterized' quantity given a set of input parameters.
crunch :: Parameterized a -> Parameters -> Either TBError a
crunch pmz ps = fst $ runState (runExceptT pmz) ps
-- |Return a list of primitive lattice vectors.
primitiveLattice :: Parameterized Lattice
primitiveLattice = gets latticeData
-- |Return a list of reciprocal primitive lattice vectors. They correspond in order
-- to the return values of 'primitiveLattice', in the sense that:
--
-- > do as <- primitiveLattice
-- > bs <- primitiveLattice
-- > return $ zipWith `dot` as bs
--
-- will return the list
--
-- > replicate dim (2*pi)
--
-- up to numerical precision.
recipPrimitiveLattice :: Parameterized Lattice
recipPrimitiveLattice = do lat <- primitiveLattice
let l = length lat
let bs = [ linearSolve (fromRows lat)
(col $ mtx l n)
| n <- [1..l]]
if any isNothing bs
then throwError SingularLatticeError
else (return . map (head . toColumns) . catMaybes) bs
where mtx l n = [ 2.0 * pi * kd n j | j <- [1..l] ]
kd a b = if a == b then 1.0 else 0.0