-- | Defines a structure to contain scientifically-relevant information about
-- an ODE.
module Language.Drasil.Data.ODEInfo (
  ODEInfo(..), odeInfo, ODEOptions(..), odeOptions, ODEMethod(..)
) where

import Language.Drasil.Chunk.Code (CodeVarChunk)
import Language.Drasil.CodeExpr (CodeExpr)


-- This may be temporary, but need a structure to hold ODE info for now. 
-- Goal will be for this info to be populated by the instance model for the ODE and the Choices structure.
-- Probably doesn't belong here, but where?
-- | Structure to hold ODE information.
data ODEInfo = ODEInfo {
  -- | Independent variable.
  ODEInfo -> CodeVarChunk
indepVar :: CodeVarChunk,
  -- | Dependent variable.
  ODEInfo -> CodeVarChunk
depVar :: CodeVarChunk,
  -- | Other variables in the ODE.
  ODEInfo -> [CodeVarChunk]
otherVars :: [CodeVarChunk],
  ODEInfo -> CodeExpr
tInit :: CodeExpr,
  ODEInfo -> CodeExpr
tFinal :: CodeExpr,
  -- | Initial value of an ODE.
  ODEInfo -> CodeExpr
initVal :: CodeExpr,
  -- | ODE equations.
  ODEInfo -> [CodeExpr]
odeSyst :: [CodeExpr],
  -- | Various options related to the ODE, including solution method, step size, initial value of a second order ODE, etc.
  ODEInfo -> ODEOptions
odeOpts :: ODEOptions
}

-- | Basic 'ODEInfo' constructor.
odeInfo :: CodeVarChunk -> CodeVarChunk -> [CodeVarChunk] -> CodeExpr -> CodeExpr -> 
  CodeExpr -> [CodeExpr] -> ODEOptions -> ODEInfo
odeInfo :: CodeVarChunk
-> CodeVarChunk
-> [CodeVarChunk]
-> CodeExpr
-> CodeExpr
-> CodeExpr
-> [CodeExpr]
-> ODEOptions
-> ODEInfo
odeInfo = CodeVarChunk
-> CodeVarChunk
-> [CodeVarChunk]
-> CodeExpr
-> CodeExpr
-> CodeExpr
-> [CodeExpr]
-> ODEOptions
-> ODEInfo
ODEInfo

data ODEOptions = ODEOpts {
  -- | Solution method.
  ODEOptions -> ODEMethod
solveMethod :: ODEMethod,
  -- | Absolute tolerance.
  ODEOptions -> CodeExpr
absTol :: CodeExpr,
  -- | Relative tolerance.
  ODEOptions -> CodeExpr
relTol :: CodeExpr,
  -- | Step size.
  ODEOptions -> CodeExpr
stepSize :: CodeExpr,
  -- | Holds the initial value of a second order ODE.
  ODEOptions -> CodeExpr
initValFstOrd :: CodeExpr
}

-- | Basic 'ODEOptions' constructor
odeOptions :: ODEMethod -> CodeExpr -> CodeExpr -> CodeExpr -> CodeExpr -> ODEOptions
odeOptions :: ODEMethod
-> CodeExpr -> CodeExpr -> CodeExpr -> CodeExpr -> ODEOptions
odeOptions = ODEMethod
-> CodeExpr -> CodeExpr -> CodeExpr -> CodeExpr -> ODEOptions
ODEOpts

-- | Methods for solving ODEs. Includes Runge-Kutta 4-5, Backwards Differentiation Formula, or Adams' method.
data ODEMethod = RK45 | BDF | Adams