module Drasil.DblPend.ODEs (dblPenODEOpts, dblPenODEInfo) where

import Language.Drasil (ExprC(..), LiteralC(int, exactDbl, dbl), square)
import Language.Drasil.Code (odeInfo, odeOptions, quantvar, ODEInfo,
  ODEMethod(RK45), ODEOptions)

import Data.Drasil.Quantities.Physics (time)

import Drasil.DblPend.Unitals(massObj_1, massObj_2, lenRod_1, lenRod_2, pendDisAngle)
import Prelude hiding (sin, cos)

dblPenODEOpts :: ODEOptions
dblPenODEOpts :: ODEOptions
dblPenODEOpts = ODEMethod -> CodeExpr -> CodeExpr -> CodeExpr -> ODEOptions
odeOptions ODEMethod
RK45 (forall r. LiteralC r => Double -> r
dbl Double
0.000001) (forall r. LiteralC r => Double -> r
dbl Double
0.000001) (forall r. LiteralC r => Double -> r
dbl Double
0.001) -- java ode require smaller than 0.001

dblPenODEInfo :: ODEInfo
dblPenODEInfo :: ODEInfo
dblPenODEInfo = CodeVarChunk
-> CodeVarChunk
-> [CodeVarChunk]
-> CodeExpr
-> CodeExpr
-> [CodeExpr]
-> [CodeExpr]
-> ODEOptions
-> ODEInfo
odeInfo
  (forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar UnitalChunk
time)
  (forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar ConstrConcept
pendDisAngle)
  [forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar UnitalChunk
massObj_1, forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar UnitalChunk
massObj_2, forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar UnitalChunk
lenRod_1, forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar UnitalChunk
lenRod_2]
  (forall r. LiteralC r => Integer -> r
exactDbl Integer
0)
  (forall r. LiteralC r => Integer -> r
exactDbl Integer
20) -- final time
  [forall r. LiteralC r => Double -> r
dbl Double
1.3463968515384828, forall r. LiteralC r => Integer -> r
exactDbl Integer
0, forall r. LiteralC r => Double -> r
dbl Double
2.356194490192345, forall r. LiteralC r => Integer -> r
exactDbl Integer
0] -- unit in radian [3*pi/7, 0, 3*pi/4, 0]
  [ CodeExpr
o1,
    forall r. ExprC r => r -> r
neg CodeExpr
g forall r. ExprC r => r -> r -> r
`mulRe`
      (CodeExpr
two forall r. ExprC r => r -> r -> r
`mulRe` CodeExpr
m1 forall r. ExprC r => r -> r -> r
`addRe` CodeExpr
m2) forall r. ExprC r => r -> r -> r
`mulRe` forall r. ExprC r => r -> r
sin CodeExpr
t1 forall r. ExprC r => r -> r -> r
$-
      (CodeExpr
m2 forall r. ExprC r => r -> r -> r
`mulRe` CodeExpr
g forall r. ExprC r => r -> r -> r
`mulRe` forall r. ExprC r => r -> r
sin (CodeExpr
t1 forall r. ExprC r => r -> r -> r
$- (CodeExpr
two forall r. ExprC r => r -> r -> r
`mulRe` CodeExpr
t2))) forall r. ExprC r => r -> r -> r
$-
      ((CodeExpr
two forall r. ExprC r => r -> r -> r
`mulRe` forall r. ExprC r => r -> r
sin (CodeExpr
t1 forall r. ExprC r => r -> r -> r
$- CodeExpr
t2 )) forall r. ExprC r => r -> r -> r
`mulRe` CodeExpr
m2 forall r. ExprC r => r -> r -> r
`mulRe`
      (forall r. (ExprC r, LiteralC r) => r -> r
square CodeExpr
o2 forall r. ExprC r => r -> r -> r
`mulRe` CodeExpr
l2 forall r. ExprC r => r -> r -> r
`addRe`
      (forall r. (ExprC r, LiteralC r) => r -> r
square CodeExpr
o1 forall r. ExprC r => r -> r -> r
`mulRe` CodeExpr
l1 forall r. ExprC r => r -> r -> r
`mulRe` forall r. ExprC r => r -> r
cos (CodeExpr
t1 forall r. ExprC r => r -> r -> r
$- CodeExpr
t2))))
      forall r. ExprC r => r -> r -> r
$/
      CodeExpr
l1 forall r. ExprC r => r -> r -> r
`mulRe`(CodeExpr
two forall r. ExprC r => r -> r -> r
`mulRe` CodeExpr
m1 forall r. ExprC r => r -> r -> r
`addRe` CodeExpr
m2 forall r. ExprC r => r -> r -> r
$-
      (CodeExpr
m2 forall r. ExprC r => r -> r -> r
`mulRe` forall r. ExprC r => r -> r
cos (CodeExpr
two forall r. ExprC r => r -> r -> r
`mulRe` CodeExpr
t1  forall r. ExprC r => r -> r -> r
$- (CodeExpr
two forall r. ExprC r => r -> r -> r
`mulRe` CodeExpr
t2)))),
    CodeExpr
o2,
    CodeExpr
two forall r. ExprC r => r -> r -> r
`mulRe` forall r. ExprC r => r -> r
sin (CodeExpr
t1 forall r. ExprC r => r -> r -> r
$- CodeExpr
t2) forall r. ExprC r => r -> r -> r
`mulRe`
      (forall r. (ExprC r, LiteralC r) => r -> r
square CodeExpr
o1 forall r. ExprC r => r -> r -> r
`mulRe` CodeExpr
l1 forall r. ExprC r => r -> r -> r
`mulRe` (CodeExpr
m1 forall r. ExprC r => r -> r -> r
`addRe` CodeExpr
m2 ) forall r. ExprC r => r -> r -> r
`addRe`
      (CodeExpr
g forall r. ExprC r => r -> r -> r
`mulRe` (CodeExpr
m1 forall r. ExprC r => r -> r -> r
`addRe` CodeExpr
m2 ) forall r. ExprC r => r -> r -> r
`mulRe` forall r. ExprC r => r -> r
cos CodeExpr
t1) forall r. ExprC r => r -> r -> r
`addRe`
      (forall r. (ExprC r, LiteralC r) => r -> r
square CodeExpr
o2 forall r. ExprC r => r -> r -> r
`mulRe` CodeExpr
l2 forall r. ExprC r => r -> r -> r
`mulRe` CodeExpr
m2 forall r. ExprC r => r -> r -> r
`mulRe` forall r. ExprC r => r -> r
cos (CodeExpr
t1 forall r. ExprC r => r -> r -> r
$- CodeExpr
t2 )))
      forall r. ExprC r => r -> r -> r
$/
      CodeExpr
l2 forall r. ExprC r => r -> r -> r
`mulRe`(CodeExpr
two forall r. ExprC r => r -> r -> r
`mulRe` CodeExpr
m1 forall r. ExprC r => r -> r -> r
`addRe` CodeExpr
m2 forall r. ExprC r => r -> r -> r
$-
      (CodeExpr
m2 forall r. ExprC r => r -> r -> r
`mulRe` forall r. ExprC r => r -> r
cos (CodeExpr
two forall r. ExprC r => r -> r -> r
`mulRe` CodeExpr
t1  forall r. ExprC r => r -> r -> r
$- (CodeExpr
two forall r. ExprC r => r -> r -> r
`mulRe` CodeExpr
t2))))
    ]
  ODEOptions
dblPenODEOpts
    where t1 :: CodeExpr
t1  = forall r. ExprC r => r -> r -> r
idx (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy ConstrConcept
pendDisAngle) (forall r. LiteralC r => Integer -> r
int Integer
0) -- t1 is theta 1
          o1 :: CodeExpr
o1  = forall r. ExprC r => r -> r -> r
idx (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy ConstrConcept
pendDisAngle) (forall r. LiteralC r => Integer -> r
int Integer
1) -- o1 is omega 1
          t2 :: CodeExpr
t2  = forall r. ExprC r => r -> r -> r
idx (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy ConstrConcept
pendDisAngle) (forall r. LiteralC r => Integer -> r
int Integer
2) -- t2 is theta 2
          o2 :: CodeExpr
o2  = forall r. ExprC r => r -> r -> r
idx (forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy ConstrConcept
pendDisAngle) (forall r. LiteralC r => Integer -> r
int Integer
3) -- o2 is omega 2
          g :: CodeExpr
g   = forall r. LiteralC r => Double -> r
dbl Double
9.8 -- should be sy gravitationalAccelConst but there is a bug
                        -- https://github.com/JacquesCarette/Drasil/issues/2998
          m1 :: CodeExpr
m1  = forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
massObj_1
          m2 :: CodeExpr
m2  = forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
massObj_2
          two :: CodeExpr
two = forall r. LiteralC r => Integer -> r
exactDbl Integer
2
          l1 :: CodeExpr
l1  = forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
lenRod_1
          l2 :: CodeExpr
l2  = forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
lenRod_2