{-# LANGUAGE PostfixOperators #-}
module Drasil.PDController.IModel where

import Data.Drasil.Quantities.Physics (time)
import Drasil.PDController.Assumptions
import Drasil.PDController.Concepts
import Drasil.PDController.DataDefs
import Drasil.PDController.GenDefs
import Drasil.PDController.References
import Drasil.PDController.TModel
import Language.Drasil
import Theory.Drasil (InstanceModel, im, qwC, newDEModel')
import Utils.Drasil (weave)
import Language.Drasil.Chunk.Concept.NamedCombinators
import qualified Language.Drasil.Sentence.Combinators as S
import Drasil.PDController.Unitals

instanceModels :: [InstanceModel]
instanceModels :: [InstanceModel]
instanceModels = [InstanceModel
imPD]

----------------------------------------------

imPD :: InstanceModel
imPD :: InstanceModel
imPD
  = ModelKind Expr
-> Inputs
-> QuantityDict
-> OutputConstraints
-> [DecRef]
-> Maybe Derivation
-> String
-> [Sentence]
-> InstanceModel
im (forall e. DifferentialModel -> ModelKind e
newDEModel' DifferentialModel
imPDRC)
      [forall q.
(Quantity q, MayHaveUnit q) =>
q -> RealInterval Expr Expr -> Input
qwC QuantityDict
qdSetPointTD forall a b. (a -> b) -> a -> b
$ forall b a. (Inclusive, b) -> RealInterval a b
UpFrom (Inclusive
Exc, forall r. LiteralC r => Integer -> r
exactDbl Integer
0), forall q.
(Quantity q, MayHaveUnit q) =>
q -> RealInterval Expr Expr -> Input
qwC QuantityDict
qdPropGain forall a b. (a -> b) -> a -> b
$ forall b a. (Inclusive, b) -> RealInterval a b
UpFrom (Inclusive
Exc, forall r. LiteralC r => Integer -> r
exactDbl Integer
0),
       forall q.
(Quantity q, MayHaveUnit q) =>
q -> RealInterval Expr Expr -> Input
qwC QuantityDict
qdDerivGain forall a b. (a -> b) -> a -> b
$ forall b a. (Inclusive, b) -> RealInterval a b
UpFrom (Inclusive
Exc, forall r. LiteralC r => Integer -> r
exactDbl Integer
0)]
      (forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw QuantityDict
qdProcessVariableTD)
      [forall b a. (Inclusive, b) -> RealInterval a b
UpFrom (Inclusive
Exc, forall r. LiteralC r => Integer -> r
exactDbl Integer
0)]
      [forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> DecRef
dRef Citation
abbasi2015, forall r.
(HasUID r, HasRefAddress r, HasShortName r) =>
r -> DecRef
dRef Citation
johnson2008]
      (forall a. a -> Maybe a
Just Derivation
imDeriv)
      String
"pdEquationIM"
      []

imPDRC :: DifferentialModel
imPDRC :: DifferentialModel
imPDRC
  = UnitalChunk
-> ConstrConcept
-> LHS
-> Expr
-> String
-> NP
-> Sentence
-> DifferentialModel
makeASingleDE
      UnitalChunk
time
      ConstrConcept
opProcessVariable
      LHS
lhs
      Expr
rhs
      String
"imPDRC"
      (String -> NP
nounPhraseSP String
"Computation of the Process Variable as a function of time")
      Sentence
EmptyS
      where lhs :: LHS
lhs = [forall r. LiteralC r => Integer -> r
exactDbl Integer
1 forall r. ExprC r => r -> r -> r
`addRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdDerivGain Expr -> Integer -> Term
$* (ConstrConcept
opProcessVariable ConstrConcept -> Integer -> Integer
$^^ Integer
1)]
                  LHS -> Term -> LHS
$+ (forall r. LiteralC r => Integer -> r
exactDbl Integer
1 Expr -> Integer -> Term
$* (ConstrConcept
opProcessVariable ConstrConcept -> Integer -> Integer
$^^ Integer
2))
                  LHS -> Term -> LHS
$+ (forall r. LiteralC r => Integer -> r
exactDbl Integer
20 forall r. ExprC r => r -> r -> r
`addRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdPropGain Expr -> Integer -> Term
$* (ConstrConcept
opProcessVariable ConstrConcept -> Integer -> Integer
$^^ Integer
0))
            rhs :: Expr
rhs = forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdSetPointTD forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdPropGain
      -- Matrix form: 
      -- coeffs = [[exactDbl 1, exactDbl 1 `addRe` sy qdDerivGain, exactDbl 20 `addRe` sy qdPropGain]]
      -- unknowns = [2, 1, 0]
      -- constants = [sy qdSetPointTD `mulRe` sy qdPropGain]

imDeriv :: Derivation
imDeriv :: Derivation
imDeriv
  = Sentence -> [Sentence] -> Derivation
mkDerivName (forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
processVariable)
      (forall a. [[a]] -> [a]
weave [[Sentence]
imDerivStmts, forall a b. (a -> b) -> [a] -> [b]
map ModelExpr -> Sentence
eS [ModelExpr]
imDerivEqns])

imDerivStmts :: [Sentence]
imDerivStmts :: [Sentence]
imDerivStmts = [Sentence
derivStmt1, Sentence
derivStmt2, Sentence
derivStmt3, Sentence
derivStmt4]

imDerivEqns :: [ModelExpr]
imDerivEqns :: [ModelExpr]
imDerivEqns = [ModelExpr
derivEqn1, ModelExpr
derivEqn2, ModelExpr
derivEqn3, ModelExpr
derivEqn4]

derivStmt1 :: Sentence
derivStmt1 :: Sentence
derivStmt1
  = [Sentence] -> Sentence
foldlSent
      [forall n. NounPhrase n => n -> Sentence
atStartNP (forall t. NamedIdea t => t -> NP
the ConceptChunk
processVariable), forall t. Express t => t -> Sentence
eS' QuantityDict
qdProcessVariableFD, String -> Sentence
S String
"in a", forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
pidCL Sentence -> Sentence -> Sentence
+:+
         String -> Sentence
S String
"is the product of the", forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
processError, forall r. (Referable r, HasShortName r) => r -> Sentence
fromSource DataDefinition
ddErrSig Sentence -> Sentence -> Sentence
`sC`
         forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
controlVariable, forall r. (Referable r, HasShortName r) => r -> Sentence
fromSource DataDefinition
ddCtrlVar Sentence -> Sentence -> Sentence
`sC` Sentence
EmptyS
         Sentence -> Sentence -> Sentence
`S.andThe` forall n. NamedIdea n => n -> Sentence
phrase ConceptChunk
powerPlant, forall r. (Referable r, HasShortName r) => r -> Sentence
fromSource GenDefn
gdPowerPlant]

derivEqn1 :: ModelExpr
derivEqn1 :: ModelExpr
derivEqn1
  = forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdProcessVariableFD
      forall r. ExprC r => r -> r -> r
$= (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdSetPointFD forall r. ExprC r => r -> r -> r
$- forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdProcessVariableFD)
      forall r. ExprC r => r -> r -> r
`mulRe` (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdPropGain forall r. ExprC r => r -> r -> r
`addRe` (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdDerivGain forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdFreqDomain))
      forall r. ExprC r => r -> r -> r
`mulRe` forall r. (ExprC r, LiteralC r) => r -> r
recip_ (forall r. (ExprC r, LiteralC r) => r -> r
square (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdFreqDomain) forall r. ExprC r => r -> r -> r
`addRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdFreqDomain forall r. ExprC r => r -> r -> r
`addRe` forall r. LiteralC r => Integer -> r
exactDbl Integer
20)

derivStmt2 :: Sentence
derivStmt2 :: Sentence
derivStmt2 = (String -> Sentence
S String
"Substituting the values and rearranging the equation" !.)

derivEqn2 :: ModelExpr
derivEqn2 :: ModelExpr
derivEqn2
  = forall r. (ExprC r, LiteralC r) => r -> r
square (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdFreqDomain) forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdProcessVariableFD
      forall r. ExprC r => r -> r -> r
`addRe` ((forall r. LiteralC r => Integer -> r
exactDbl Integer
1 forall r. ExprC r => r -> r -> r
`addRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdDerivGain) forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdProcessVariableFD forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdFreqDomain)
      forall r. ExprC r => r -> r -> r
`addRe` ((forall r. LiteralC r => Integer -> r
exactDbl Integer
20 forall r. ExprC r => r -> r -> r
`addRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdPropGain) forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdProcessVariableFD)
      forall r. ExprC r => r -> r -> r
$- (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdSetPointFD forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdFreqDomain forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdDerivGain)
      forall r. ExprC r => r -> r -> r
$- (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdSetPointFD forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdPropGain) forall r. ExprC r => r -> r -> r
$= forall r. LiteralC r => Integer -> r
exactDbl Integer
0

derivStmt3 :: Sentence
derivStmt3 :: Sentence
derivStmt3
  = String -> Sentence
S String
"Computing the" Sentence -> Sentence -> Sentence
+:+ forall n. NamedIdea n => n -> Sentence
phrase QuantityDict
qdInvLaplaceTransform Sentence -> Sentence -> Sentence
+:+
     forall r. (Referable r, HasShortName r) => r -> Sentence
fromSource TheoryModel
tmInvLaplace Sentence -> Sentence -> Sentence
+:+. String -> Sentence
S String
"of the equation"

derivEqn3 :: ModelExpr
derivEqn3 :: ModelExpr
derivEqn3
  = forall r c. (ModelExprC r, HasUID c, HasSymbol c) => r -> c -> r
deriv (forall r c. (ModelExprC r, HasUID c, HasSymbol c) => r -> c -> r
deriv (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdProcessVariableTD) UnitalChunk
time) UnitalChunk
time forall r. ExprC r => r -> r -> r
`addRe`
      (((forall r. LiteralC r => Integer -> r
exactDbl Integer
1 forall r. ExprC r => r -> r -> r
`addRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdDerivGain) forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ModelExprC r, HasUID c, HasSymbol c) => r -> c -> r
deriv (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdProcessVariableTD) UnitalChunk
time)
      forall r. ExprC r => r -> r -> r
`addRe` ((forall r. LiteralC r => Integer -> r
exactDbl Integer
20 forall r. ExprC r => r -> r -> r
`addRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdPropGain) forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdProcessVariableTD))
      forall r. ExprC r => r -> r -> r
$- (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdDerivGain forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ModelExprC r, HasUID c, HasSymbol c) => r -> c -> r
deriv (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdSetPointTD) UnitalChunk
time)
      forall r. ExprC r => r -> r -> r
$- (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdSetPointTD forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdPropGain) forall r. ExprC r => r -> r -> r
$= forall r. LiteralC r => Integer -> r
exactDbl Integer
0

derivStmt4 :: Sentence
derivStmt4 :: Sentence
derivStmt4
  = [Sentence] -> Sentence
foldlSent_
      [forall n. NounPhrase n => n -> Sentence
atStartNP (forall t. NamedIdea t => t -> NP
the ConceptChunk
setPoint), forall t. Express t => t -> Sentence
eS' QuantityDict
qdSetPointTD, String -> Sentence
S String
"is a step function and a constant" Sentence -> Sentence -> Sentence
+:+.
         forall r. (Referable r, HasShortName r) => r -> Sentence
fromSource ConceptInstance
aSP,
       String -> Sentence
S String
"Therefore the",
         String -> Sentence
S String
"differential of the set point is zero. Hence the equation",
         String -> Sentence
S String
"reduces to"]

derivEqn4 :: ModelExpr
derivEqn4 :: ModelExpr
derivEqn4
  = forall r c. (ModelExprC r, HasUID c, HasSymbol c) => r -> c -> r
deriv (forall r c. (ModelExprC r, HasUID c, HasSymbol c) => r -> c -> r
deriv (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdProcessVariableTD) UnitalChunk
time) UnitalChunk
time forall r. ExprC r => r -> r -> r
`addRe`
      ((forall r. LiteralC r => Integer -> r
exactDbl Integer
1 forall r. ExprC r => r -> r -> r
`addRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdDerivGain) forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ModelExprC r, HasUID c, HasSymbol c) => r -> c -> r
deriv (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdProcessVariableTD) UnitalChunk
time)
      forall r. ExprC r => r -> r -> r
`addRe` ((forall r. LiteralC r => Integer -> r
exactDbl Integer
20 forall r. ExprC r => r -> r -> r
`addRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdPropGain) forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdProcessVariableTD)
      forall r. ExprC r => r -> r -> r
$- (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdSetPointTD forall r. ExprC r => r -> r -> r
`mulRe` forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy QuantityDict
qdPropGain) forall r. ExprC r => r -> r -> r
$= forall r. LiteralC r => Integer -> r
exactDbl Integer
0