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 (Double -> CodeExpr
forall r. LiteralC r => Double -> r
dbl Double
0.000001) (Double -> CodeExpr
forall r. LiteralC r => Double -> r
dbl Double
0.000001) (Double -> CodeExpr
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
  (UnitalChunk -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar UnitalChunk
time)
  (ConstrConcept -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar ConstrConcept
pendDisAngle)
  [UnitalChunk -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar UnitalChunk
massObj_1, UnitalChunk -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar UnitalChunk
massObj_2, UnitalChunk -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar UnitalChunk
lenRod_1, UnitalChunk -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar UnitalChunk
lenRod_2]
  (Integer -> CodeExpr
forall r. LiteralC r => Integer -> r
exactDbl Integer
0)
  (Integer -> CodeExpr
forall r. LiteralC r => Integer -> r
exactDbl Integer
20) -- final time
  [Double -> CodeExpr
forall r. LiteralC r => Double -> r
dbl Double
1.3463968515384828, Integer -> CodeExpr
forall r. LiteralC r => Integer -> r
exactDbl Integer
0, Double -> CodeExpr
forall r. LiteralC r => Double -> r
dbl Double
2.356194490192345, Integer -> CodeExpr
forall r. LiteralC r => Integer -> r
exactDbl Integer
0] -- unit in radian [3*pi/7, 0, 3*pi/4, 0]
  [ CodeExpr
o1,
    CodeExpr -> CodeExpr
forall r. ExprC r => r -> r
neg CodeExpr
g CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* 
      (CodeExpr
two CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr
m1 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$+ CodeExpr
m2) CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr -> CodeExpr
forall r. ExprC r => r -> r
sin CodeExpr
t1 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$-
      (CodeExpr
m2 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr
g CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr -> CodeExpr
forall r. ExprC r => r -> r
sin (CodeExpr
t1 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$- (CodeExpr
two CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr
t2))) CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$-
      ((CodeExpr
two CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr -> CodeExpr
forall r. ExprC r => r -> r
sin (CodeExpr
t1 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$- CodeExpr
t2 )) CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr
m2 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* 
      (CodeExpr -> CodeExpr
forall r. (ExprC r, LiteralC r) => r -> r
square CodeExpr
o2 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr
l2 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$+
      (CodeExpr -> CodeExpr
forall r. (ExprC r, LiteralC r) => r -> r
square CodeExpr
o1 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr
l1 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr -> CodeExpr
forall r. ExprC r => r -> r
cos (CodeExpr
t1 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$- CodeExpr
t2))))
      CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$/
      CodeExpr
l1 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* (CodeExpr
two CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr
m1 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$+ CodeExpr
m2 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$-
      (CodeExpr
m2 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr -> CodeExpr
forall r. ExprC r => r -> r
cos (CodeExpr
two CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr
t1  CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$- (CodeExpr
two CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr
t2)))),
    CodeExpr
o2,
    CodeExpr
two CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr -> CodeExpr
forall r. ExprC r => r -> r
sin (CodeExpr
t1 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$- CodeExpr
t2) CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* 
      (CodeExpr -> CodeExpr
forall r. (ExprC r, LiteralC r) => r -> r
square CodeExpr
o1 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr
l1 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* (CodeExpr
m1 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$+ CodeExpr
m2 ) CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$+
      (CodeExpr
g CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* (CodeExpr
m1 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$+ CodeExpr
m2 ) CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr -> CodeExpr
forall r. ExprC r => r -> r
cos CodeExpr
t1) CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$+
      (CodeExpr -> CodeExpr
forall r. (ExprC r, LiteralC r) => r -> r
square CodeExpr
o2 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr
l2 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr
m2 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr -> CodeExpr
forall r. ExprC r => r -> r
cos (CodeExpr
t1 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$- CodeExpr
t2 )))
      CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$/
      CodeExpr
l2 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* (CodeExpr
two CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr
m1 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$+ CodeExpr
m2 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$-
      (CodeExpr
m2 CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr -> CodeExpr
forall r. ExprC r => r -> r
cos (CodeExpr
two CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr
t1  CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$- (CodeExpr
two CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
$* CodeExpr
t2))))
    ]
  ODEOptions
dblPenODEOpts
    where t1 :: CodeExpr
t1  = CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
idx (ConstrConcept -> CodeExpr
forall c. (HasUID c, HasSymbol c) => c -> CodeExpr
forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy ConstrConcept
pendDisAngle) (Integer -> CodeExpr
forall r. LiteralC r => Integer -> r
int Integer
0) -- t1 is theta 1
          o1 :: CodeExpr
o1  = CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
idx (ConstrConcept -> CodeExpr
forall c. (HasUID c, HasSymbol c) => c -> CodeExpr
forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy ConstrConcept
pendDisAngle) (Integer -> CodeExpr
forall r. LiteralC r => Integer -> r
int Integer
1) -- o1 is omega 1
          t2 :: CodeExpr
t2  = CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
idx (ConstrConcept -> CodeExpr
forall c. (HasUID c, HasSymbol c) => c -> CodeExpr
forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy ConstrConcept
pendDisAngle) (Integer -> CodeExpr
forall r. LiteralC r => Integer -> r
int Integer
2) -- t2 is theta 2
          o2 :: CodeExpr
o2  = CodeExpr -> CodeExpr -> CodeExpr
forall r. ExprC r => r -> r -> r
idx (ConstrConcept -> CodeExpr
forall c. (HasUID c, HasSymbol c) => c -> CodeExpr
forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy ConstrConcept
pendDisAngle) (Integer -> CodeExpr
forall r. LiteralC r => Integer -> r
int Integer
3) -- o2 is omega 2
          g :: CodeExpr
g   = Double -> CodeExpr
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  = UnitalChunk -> CodeExpr
forall c. (HasUID c, HasSymbol c) => c -> CodeExpr
forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
massObj_1
          m2 :: CodeExpr
m2  = UnitalChunk -> CodeExpr
forall c. (HasUID c, HasSymbol c) => c -> CodeExpr
forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
massObj_2
          two :: CodeExpr
two = Integer -> CodeExpr
forall r. LiteralC r => Integer -> r
exactDbl Integer
2
          l1 :: CodeExpr
l1  = UnitalChunk -> CodeExpr
forall c. (HasUID c, HasSymbol c) => c -> CodeExpr
forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
lenRod_1
          l2 :: CodeExpr
l2  = UnitalChunk -> CodeExpr
forall c. (HasUID c, HasSymbol c) => c -> CodeExpr
forall r c. (ExprC r, HasUID c, HasSymbol c) => c -> r
sy UnitalChunk
lenRod_2