module Drasil.SglPendulum.Unitals where

import Language.Drasil
import Language.Drasil.ShortHands
import Language.Drasil.Chunk.Concept.NamedCombinators
import qualified Language.Drasil.NounPhrase.Combinators as NP
import Data.Drasil.Constraints (gtZeroConstr)
import Data.Drasil.Quantities.PhysicalProperties as QPP (len, mass)
import Data.Drasil.SI_Units (metre, degree, radian)
import qualified Data.Drasil.Quantities.Physics as QP (position, ixPos, xPos, force, velocity,
  angularVelocity, angularAccel, gravitationalAccel, tension, acceleration, yAccel,
  xAccel, yVel, xVel, iyPos, yPos, time, torque, momentOfInertia, angularDisplacement,
  angularFrequency, frequency, period)
import Data.Drasil.Concepts.Physics (pendulum)
import Data.Drasil.Concepts.Math as CM (angle, iAngle)
import Data.Drasil.Quantities.Math as QM (unitVect, unitVectj, pi_)
import Drasil.DblPendulum.Concepts (rod)
import Drasil.DblPendulum.Unitals (lRod)


symbols:: [QuantityDict]
symbols :: [QuantityDict]
symbols = (UnitalChunk -> QuantityDict) -> [UnitalChunk] -> [QuantityDict]
forall a b. (a -> b) -> [a] -> [b]
map UnitalChunk -> QuantityDict
forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw [UnitalChunk]
unitalChunks [QuantityDict] -> [QuantityDict] -> [QuantityDict]
forall a. [a] -> [a] -> [a]
++ (DefinedQuantityDict -> QuantityDict)
-> [DefinedQuantityDict] -> [QuantityDict]
forall a b. (a -> b) -> [a] -> [b]
map DefinedQuantityDict -> QuantityDict
forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw [DefinedQuantityDict]
unitless

inputs :: [QuantityDict]
inputs :: [QuantityDict]
inputs = (UnitalChunk -> QuantityDict) -> [UnitalChunk] -> [QuantityDict]
forall a b. (a -> b) -> [a] -> [b]
map UnitalChunk -> QuantityDict
forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw [UnitalChunk
lenRod, UnitalChunk
QPP.mass, UnitalChunk
QP.angularAccel, UnitalChunk
pendDisplacementAngle, UnitalChunk
initialPendAngle] 

outputs :: [QuantityDict]
outputs :: [QuantityDict]
outputs = (UnitalChunk -> QuantityDict) -> [UnitalChunk] -> [QuantityDict]
forall a b. (a -> b) -> [a] -> [b]
map UnitalChunk -> QuantityDict
forall q. (Quantity q, MayHaveUnit q) => q -> QuantityDict
qw [UnitalChunk
pendDisplacementAngle]

units :: [UnitalChunk]
units :: [UnitalChunk]
units = (UnitalChunk -> UnitalChunk) -> [UnitalChunk] -> [UnitalChunk]
forall a b. (a -> b) -> [a] -> [b]
map UnitalChunk -> UnitalChunk
forall c. (Unitary c, Concept c, MayHaveUnit c) => c -> UnitalChunk
ucw [UnitalChunk]
unitalChunks

unitalChunks :: [UnitalChunk]
unitalChunks :: [UnitalChunk]
unitalChunks = [UnitalChunk
lenRod, UnitalChunk
QPP.mass, UnitalChunk
QP.force, UnitalChunk
QP.ixPos, UnitalChunk
QP.xPos, UnitalChunk
QP.yPos,
   UnitalChunk
QP.angularVelocity, UnitalChunk
QP.angularAccel, UnitalChunk
QP.gravitationalAccel, UnitalChunk
QP.tension, UnitalChunk
QP.acceleration,
   UnitalChunk
QP.yAccel, UnitalChunk
QP.xAccel, UnitalChunk
QP.yVel, UnitalChunk
QP.xVel, UnitalChunk
QP.iyPos, UnitalChunk
QP.time, UnitalChunk
QP.velocity, UnitalChunk
QP.position, UnitalChunk
QP.torque,
   UnitalChunk
QP.momentOfInertia, UnitalChunk
QP.angularDisplacement, UnitalChunk
QP.angularVelocity, UnitalChunk
initialPendAngle,
   UnitalChunk
QP.angularFrequency, UnitalChunk
QP.frequency, UnitalChunk
QP.period, UnitalChunk
lenRod, UnitalChunk
pendDisplacementAngle, UnitalChunk
initialPendAngle]

lenRod, pendDisplacementAngle, initialPendAngle :: UnitalChunk

lenRod :: UnitalChunk
lenRod = String -> NP -> Sentence -> Symbol -> UnitDefn -> UnitalChunk
forall u.
IsUnit u =>
String -> NP -> Sentence -> Symbol -> u -> UnitalChunk
makeUCWDS "l_rod" (String -> NP
cn "length of the rod")
        (NP -> Sentence
forall n. NounPhrase n => n -> Sentence
phraseNP (UnitalChunk
len UnitalChunk -> NamedChunk -> NP
forall c d. (NamedIdea c, NamedIdea d) => c -> d -> NP
`the_ofThe` NamedChunk
rod))
        (Symbol -> Symbol -> Symbol
sub Symbol
cL Symbol
lRod) UnitDefn
metre

pendDisplacementAngle :: UnitalChunk
pendDisplacementAngle = String -> NP -> Sentence -> Symbol -> UnitDefn -> UnitalChunk
forall u.
IsUnit u =>
String -> NP -> Sentence -> Symbol -> u -> UnitalChunk
makeUCWDS "pendDisplacementAngle" (String -> NP
cn "displacement angle of the pendulum")
        (NP -> Sentence
forall n. NounPhrase n => n -> Sentence
phraseNP (ConceptChunk
angle ConceptChunk -> ConceptChunk -> NP
forall c d. (NamedIdea c, NamedIdea d) => c -> d -> NP
`the_ofThe` ConceptChunk
pendulum))
        (Symbol -> Symbol -> Symbol
sub Symbol
lTheta Symbol
lP) UnitDefn
degree

initialPendAngle :: UnitalChunk
initialPendAngle = String -> NP -> Sentence -> Symbol -> UnitDefn -> UnitalChunk
forall u.
IsUnit u =>
String -> NP -> Sentence -> Symbol -> u -> UnitalChunk
makeUCWDS "initialPendAngle" (String -> NP
cn "initial pendulum angle")
        (NP -> Sentence
forall n. NounPhrase n => n -> Sentence
phraseNP (NP -> NP
NP.the (ConceptChunk
CM.iAngle ConceptChunk -> ConceptChunk -> NP
forall c d. (NamedIdea c, NamedIdea d) => c -> d -> NP
`of_` ConceptChunk
pendulum)))
        (Symbol -> Symbol -> Symbol
sub Symbol
lTheta Symbol
lI) UnitDefn
radian

unitless :: [DefinedQuantityDict]
unitless :: [DefinedQuantityDict]
unitless = [DefinedQuantityDict
QM.unitVect, DefinedQuantityDict
QM.unitVectj, DefinedQuantityDict
QM.pi_]

-----------------------
-- CONSTRAINT CHUNKS --
-----------------------
lenRodCons, pendDisplacementAngleOutCons, angAccelOutCons, initialPendAngleCons :: ConstrConcept

inConstraints :: [UncertQ]
inConstraints :: [UncertQ]
inConstraints = (ConstrConcept -> UncertQ) -> [ConstrConcept] -> [UncertQ]
forall a b. (a -> b) -> [a] -> [b]
map (ConstrConcept -> Uncertainty -> UncertQ
forall c.
(Quantity c, Constrained c, Concept c, HasReasVal c,
 MayHaveUnit c) =>
c -> Uncertainty -> UncertQ
`uq` Uncertainty
defaultUncrt) [ConstrConcept
lenRodCons, ConstrConcept
initialPendAngleCons]

outConstraints :: [UncertQ]
outConstraints :: [UncertQ]
outConstraints = (ConstrConcept -> UncertQ) -> [ConstrConcept] -> [UncertQ]
forall a b. (a -> b) -> [a] -> [b]
map (ConstrConcept -> Uncertainty -> UncertQ
forall c.
(Quantity c, Constrained c, Concept c, HasReasVal c,
 MayHaveUnit c) =>
c -> Uncertainty -> UncertQ
`uq` Uncertainty
defaultUncrt) [ConstrConcept
angAccelOutCons, ConstrConcept
pendDisplacementAngleOutCons]

lenRodCons :: ConstrConcept
lenRodCons     = UnitalChunk -> [ConstraintE] -> Expr -> ConstrConcept
forall c.
(Concept c, MayHaveUnit c, Quantity c) =>
c -> [ConstraintE] -> Expr -> ConstrConcept
constrained' UnitalChunk
lenRod        [ConstraintE
gtZeroConstr] (Double -> Expr
forall r. LiteralC r => Double -> r
dbl 44.2)
initialPendAngleCons :: ConstrConcept
initialPendAngleCons  = UnitalChunk -> [ConstraintE] -> Expr -> ConstrConcept
forall c.
(Concept c, MayHaveUnit c, Quantity c) =>
c -> [ConstraintE] -> Expr -> ConstrConcept
constrained' UnitalChunk
initialPendAngle    [ConstraintE
gtZeroConstr] (Double -> Expr
forall r. LiteralC r => Double -> r
dbl 2.1)
pendDisplacementAngleOutCons :: ConstrConcept
pendDisplacementAngleOutCons  = UnitalChunk -> [ConstraintE] -> Expr -> ConstrConcept
forall c.
(Concept c, MayHaveUnit c, Quantity c) =>
c -> [ConstraintE] -> Expr -> ConstrConcept
constrained' UnitalChunk
pendDisplacementAngle    [ConstraintE
gtZeroConstr] (Double -> Expr
forall r. LiteralC r => Double -> r
dbl 2.1)
angAccelOutCons :: ConstrConcept
angAccelOutCons    = UnitalChunk -> [ConstraintE] -> Expr -> ConstrConcept
forall c.
(Concept c, MayHaveUnit c, Quantity c) =>
c -> [ConstraintE] -> Expr -> ConstrConcept
constrained' UnitalChunk
QP.angularAccel    [ConstraintE
gtZeroConstr] (Integer -> Expr
forall r. LiteralC r => Integer -> r
exactDbl 0)