<commit_before>{-# OPTIONS_GHC -funbox-strict-fields #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Behave.Types (
    Catalog
  , Particle (..)
  , ParticleType (..)
  , SizeClass (..)
  , Life (..)
  , Fuel (..)
  , SpreadEnv (..)
  , Spread (..)
  , SpreadAtAzimuth (..)
  , Combustion (..)
  , noSpread
  , standardCatalog
  , indexCatalog
  , mkCatalog
  , _envWindSpeed
) where

import           Control.Lens (makeLensesFor)
import qualified Data.Vector.Unboxed as U
import qualified Data.Vector as V
import           Data.Vector.Unboxed.Deriving (derivingUnbox)
import           Data.Text (Text)
import           Behave.Units
import           Data.Hashable (Hashable(..))


-- | Type of 'Particle'
data ParticleType
  = ParticleDead  -- ^ Dead fuel particle
  | ParticleHerb  -- ^ Herbaceous live particle
  | ParticleWood  -- ^ Woody live particle
  deriving (Show, Eq, Enum)

derivingUnbox "ParticleType"
    [t| ParticleType -> Int |]
    [|fromEnum|]
    [|toEnum|]


-- | A fuel bed particle
data Particle
  = Particle {
      partType        :: !ParticleType
    , partLoad        :: !FuelLoad         -- ^ fuel loading
    , partSavr        :: !SaToVolRatio     -- ^ surface area to volume ratio
    , partDensity     :: !(Density Double) -- ^ particle density
    , partHeat        :: !HeatOfCombustion -- ^ heat of combustion
    , partSiTotal     :: !Fraction         -- ^ total silica content
    , partSiEffective :: !Fraction         -- ^ effective silica content
  } deriving (Eq, Show)

derivingUnbox "Particle"
    [t| Particle -> ( (ParticleType,FuelLoad,SaToVolRatio)
                    , (Density Double,HeatOfCombustion,Fraction,Fraction)) |]
    [| \(Particle a b c d e f g) -> ((a,b,c),(d,e,f,g)) |]
    [| \((a,b,c),(d,e,f,g)) -> Particle a b c d e f g|]

data Life = Dead | Alive deriving (Eq, Show, Enum)

data SizeClass = SC0 | SC1 | SC2 | SC3 | SC4 | SC5
  deriving (Eq, Show, Enum)


data Fuel
  = Fuel {
      fuelName      :: !Text                   -- ^ name
    , fuelDesc      :: !Text                   -- ^ description
    , fuelDepth     :: !(Length Double)        -- ^ total depth
    , fuelMext      :: !Moisture               -- ^ moisture of extinction
    , fuelAdjust    :: !(Dimensionless Double) -- ^ adjustment factor
    , fuelParticles :: !(U.Vector Particle)    -- ^ particle array
  } deriving (Eq, Show)

data Combustion
  = Combustion {
      combLifeAreaWtg     :: !(Life -> Double) -- ^ fuel area weighting factor
    , combLifeRxFactor    :: !(Life -> Double) -- ^ fuel rx factor
    , combFineDeadFactor  :: !Double -- ^ fine dead fuel ratio
    , combLiveExtFactor   :: !Double -- ^ live fuel moisture extinction factor
    , combFuelBedBulkDens :: !Double -- ^ fuel bed bulk density
    , combResidenceTime   :: !Double -- ^ residence time
    , combFluxRatio       :: !Double -- ^ propagating flux ratio
    , combSlopeK          :: !Double -- ^ slope parameter 'k'
    , combWindB           :: !Double -- ^ wind parameter 'b'
    , combWindE           :: !Double -- ^ wind parameter 'e'
    , combWindK           :: !Double -- ^ wind parameter 'k'
  }

data Spread
  = Spread {
      spreadRxInt         :: !ReactionIntensity -- ^ Reaction intensity
    , spreadSpeed0        :: !Speed             -- ^ no-wind, no-slope speed
    , spreadHpua          :: !HeatPerUnitArea   -- ^ heat per unit area
    , spreadPhiEffWind    :: !Ratio             -- ^ combined wind-slope factor
    , spreadSpeedMax      :: !Speed             -- ^ max spread speed
    , spreadAzimuthMax    :: !Azimuth           -- ^ direction of max spread
    , spreadEccentricity  :: !Ratio             -- ^ ellipse eccentricity
    , spreadByramsMax     :: !ByramsIntensity   -- ^ max fireline intensity
    , spreadFlameMax      :: !(Length Double)   -- ^ max flame length
  } deriving (Eq, Show)

instance Hashable Spread where
  hashWithSalt s (Spread a b c d e f g h i) =
    s `hashWithSalt` a
      `hashWithSalt` b
      `hashWithSalt` c
      `hashWithSalt` d
      `hashWithSalt` e
      `hashWithSalt` f
      `hashWithSalt` g
      `hashWithSalt` h
      `hashWithSalt` i
  {-# INLINE hashWithSalt #-}

noSpread :: Spread
noSpread = Spread _0 _0 _0 _0 _0 _0 _0 _0 _0

derivingUnbox "Spread"
    [t| Spread -> ( (ReactionIntensity,Speed,HeatPerUnitArea,Ratio,Speed)
                  , (Azimuth,Ratio,ByramsIntensity,Length Double)) |]
    [| \(Spread a b c d e f g h i) -> ((a,b,c,d,e),(f,g,h,i)) |]
    [| \((a,b,c,d,e),(f,g,h,i)) -> Spread a b c d e f g h i|]

data SpreadAtAzimuth
  = SpreadAtAzimuth {
      spreadSpeed  :: Speed           -- ^ no-wind, no-slope spread rate
    , spreadByrams :: ByramsIntensity -- ^ fireline intensity
    , spreadFlame  :: Length Double   -- ^ flame Length
  } deriving (Eq, Show)


data SpreadEnv
  = SpreadEnv {
      envD1hr        :: !Moisture -- ^ Moisture of 1hr lag dead particles
    , envD10hr       :: !Moisture -- ^ Moisture of 10hr lag dead particles
    , envD100hr      :: !Moisture -- ^ Moisture of 100hr lag dead particles
    , envHerb        :: !Moisture -- ^ Moisture of live herbaceous particles
    , envWood        :: !Moisture -- ^ Moisture of live woody particles
    , envWindSpeed   :: !Speed    -- ^ Wind speed
    , envWindAzimuth :: !Azimuth  -- ^ Wind azimuth (compass bearing)
    , envSlope       :: !Ratio    -- ^ Terrain slope (rise/reach ratio)
    , envAspect      :: !Azimuth  -- ^ Terrain aspect (downslope compass bearing)
  } deriving (Eq, Show)
makeLensesFor [
   ("envWindSpeed", "_envWindSpeed")
  ] ''SpreadEnv

instance Hashable SpreadEnv where
  hashWithSalt s (SpreadEnv a b c d e f g h i) =
    s `hashWithSalt` a
      `hashWithSalt` b
      `hashWithSalt` c
      `hashWithSalt` d
      `hashWithSalt` e
      `hashWithSalt` f
      `hashWithSalt` g
      `hashWithSalt` h
      `hashWithSalt` i
  {-# INLINE hashWithSalt #-}

derivingUnbox "SpreadEnv"
    [t| SpreadEnv -> ( (Moisture,Moisture,Moisture,Moisture,Moisture)
                     , (Speed,Azimuth,Ratio,Azimuth))|]
    [| \(SpreadEnv a b c d e f g h i) -> ((a,b,c,d,e),(f,g,h,i)) |]
    [| \((a,b,c,d,e),(f,g,h,i)) -> SpreadEnv a b c d e f g h i|]<commit_msg>noSpreadEnv<commit_after>{-# OPTIONS_GHC -funbox-strict-fields #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Behave.Types (
    Catalog
  , Particle (..)
  , ParticleType (..)
  , SizeClass (..)
  , Life (..)
  , Fuel (..)
  , SpreadEnv (..)
  , Spread (..)
  , SpreadAtAzimuth (..)
  , Combustion (..)
  , noSpread
  , noSpreadEnv
  , standardCatalog
  , indexCatalog
  , mkCatalog
  , _envWindSpeed
) where

import           Control.Lens (makeLensesFor)
import qualified Data.Vector.Unboxed as U
import qualified Data.Vector as V
import           Data.Vector.Unboxed.Deriving (derivingUnbox)
import           Data.Text (Text)
import           Behave.Units
import           Data.Hashable (Hashable(..))


-- | Type of 'Particle'
data ParticleType
  = ParticleDead  -- ^ Dead fuel particle
  | ParticleHerb  -- ^ Herbaceous live particle
  | ParticleWood  -- ^ Woody live particle
  deriving (Show, Eq, Enum)

derivingUnbox "ParticleType"
    [t| ParticleType -> Int |]
    [|fromEnum|]
    [|toEnum|]


-- | A fuel bed particle
data Particle
  = Particle {
      partType        :: !ParticleType
    , partLoad        :: !FuelLoad         -- ^ fuel loading
    , partSavr        :: !SaToVolRatio     -- ^ surface area to volume ratio
    , partDensity     :: !(Density Double) -- ^ particle density
    , partHeat        :: !HeatOfCombustion -- ^ heat of combustion
    , partSiTotal     :: !Fraction         -- ^ total silica content
    , partSiEffective :: !Fraction         -- ^ effective silica content
  } deriving (Eq, Show)

derivingUnbox "Particle"
    [t| Particle -> ( (ParticleType,FuelLoad,SaToVolRatio)
                    , (Density Double,HeatOfCombustion,Fraction,Fraction)) |]
    [| \(Particle a b c d e f g) -> ((a,b,c),(d,e,f,g)) |]
    [| \((a,b,c),(d,e,f,g)) -> Particle a b c d e f g|]

data Life = Dead | Alive deriving (Eq, Show, Enum)

data SizeClass = SC0 | SC1 | SC2 | SC3 | SC4 | SC5
  deriving (Eq, Show, Enum)


data Fuel
  = Fuel {
      fuelName      :: !Text                   -- ^ name
    , fuelDesc      :: !Text                   -- ^ description
    , fuelDepth     :: !(Length Double)        -- ^ total depth
    , fuelMext      :: !Moisture               -- ^ moisture of extinction
    , fuelAdjust    :: !(Dimensionless Double) -- ^ adjustment factor
    , fuelParticles :: !(U.Vector Particle)    -- ^ particle array
  } deriving (Eq, Show)

data Combustion
  = Combustion {
      combLifeAreaWtg     :: !(Life -> Double) -- ^ fuel area weighting factor
    , combLifeRxFactor    :: !(Life -> Double) -- ^ fuel rx factor
    , combFineDeadFactor  :: !Double -- ^ fine dead fuel ratio
    , combLiveExtFactor   :: !Double -- ^ live fuel moisture extinction factor
    , combFuelBedBulkDens :: !Double -- ^ fuel bed bulk density
    , combResidenceTime   :: !Double -- ^ residence time
    , combFluxRatio       :: !Double -- ^ propagating flux ratio
    , combSlopeK          :: !Double -- ^ slope parameter 'k'
    , combWindB           :: !Double -- ^ wind parameter 'b'
    , combWindE           :: !Double -- ^ wind parameter 'e'
    , combWindK           :: !Double -- ^ wind parameter 'k'
  }

data Spread
  = Spread {
      spreadRxInt         :: !ReactionIntensity -- ^ Reaction intensity
    , spreadSpeed0        :: !Speed             -- ^ no-wind, no-slope speed
    , spreadHpua          :: !HeatPerUnitArea   -- ^ heat per unit area
    , spreadPhiEffWind    :: !Ratio             -- ^ combined wind-slope factor
    , spreadSpeedMax      :: !Speed             -- ^ max spread speed
    , spreadAzimuthMax    :: !Azimuth           -- ^ direction of max spread
    , spreadEccentricity  :: !Ratio             -- ^ ellipse eccentricity
    , spreadByramsMax     :: !ByramsIntensity   -- ^ max fireline intensity
    , spreadFlameMax      :: !(Length Double)   -- ^ max flame length
  } deriving (Eq, Show)

instance Hashable Spread where
  hashWithSalt s (Spread a b c d e f g h i) =
    s `hashWithSalt` a
      `hashWithSalt` b
      `hashWithSalt` c
      `hashWithSalt` d
      `hashWithSalt` e
      `hashWithSalt` f
      `hashWithSalt` g
      `hashWithSalt` h
      `hashWithSalt` i
  {-# INLINE hashWithSalt #-}

noSpread :: Spread
noSpread = Spread _0 _0 _0 _0 _0 _0 _0 _0 _0

derivingUnbox "Spread"
    [t| Spread -> ( (ReactionIntensity,Speed,HeatPerUnitArea,Ratio,Speed)
                  , (Azimuth,Ratio,ByramsIntensity,Length Double)) |]
    [| \(Spread a b c d e f g h i) -> ((a,b,c,d,e),(f,g,h,i)) |]
    [| \((a,b,c,d,e),(f,g,h,i)) -> Spread a b c d e f g h i|]

data SpreadAtAzimuth
  = SpreadAtAzimuth {
      spreadSpeed  :: Speed           -- ^ no-wind, no-slope spread rate
    , spreadByrams :: ByramsIntensity -- ^ fireline intensity
    , spreadFlame  :: Length Double   -- ^ flame Length
  } deriving (Eq, Show)


data SpreadEnv
  = SpreadEnv {
      envD1hr        :: !Moisture -- ^ Moisture of 1hr lag dead particles
    , envD10hr       :: !Moisture -- ^ Moisture of 10hr lag dead particles
    , envD100hr      :: !Moisture -- ^ Moisture of 100hr lag dead particles
    , envHerb        :: !Moisture -- ^ Moisture of live herbaceous particles
    , envWood        :: !Moisture -- ^ Moisture of live woody particles
    , envWindSpeed   :: !Speed    -- ^ Wind speed
    , envWindAzimuth :: !Azimuth  -- ^ Wind azimuth (compass bearing)
    , envSlope       :: !Ratio    -- ^ Terrain slope (rise/reach ratio)
    , envAspect      :: !Azimuth  -- ^ Terrain aspect (downslope compass bearing)
  } deriving (Eq, Show)
makeLensesFor [
   ("envWindSpeed", "_envWindSpeed")
  ] ''SpreadEnv

noSpreadEnv :: SpreadEnv
noSpreadEnv = SpreadEnv _0 _0 _0 _0 _0 _0 _0 _0 _0

instance Hashable SpreadEnv where
  hashWithSalt s (SpreadEnv a b c d e f g h i) =
    s `hashWithSalt` a
      `hashWithSalt` b
      `hashWithSalt` c
      `hashWithSalt` d
      `hashWithSalt` e
      `hashWithSalt` f
      `hashWithSalt` g
      `hashWithSalt` h
      `hashWithSalt` i
  {-# INLINE hashWithSalt #-}

derivingUnbox "SpreadEnv"
    [t| SpreadEnv -> ( (Moisture,Moisture,Moisture,Moisture,Moisture)
                     , (Speed,Azimuth,Ratio,Azimuth))|]
    [| \(SpreadEnv a b c d e f g h i) -> ((a,b,c,d,e),(f,g,h,i)) |]
    [| \((a,b,c,d,e),(f,g,h,i)) -> SpreadEnv a b c d e f g h i|]
{'fraction_non_alphanumeric': 0.1278035728338711, 'fraction_numerical': 0.00511529078460691, 'mean_word_length': 2.242663944883899, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '191471', 'n_tokens_mistral': 4429, 'n_tokens_neox': 4190, 'n_words': 1123}