1+ # # Uses linear interpolation between the knot points. For a = b = 1/2 the integration follows the trapezoid rule.
2+ # # This results in the Symplectic Euler method or Stoermer-Verlet, depending on how exactly one sets it up.
3+ #  u(t) = a t + b = (xdk+1 - xdk)/Δt t + xdk
4+ #  du(t) = a = (xdk+1 - xdk)/Δt
5+ #  ωc(t) = 2 V L(qc)ᵀ du(t)
6+ #  L(xck,vck) -> Δt (a Ld(u(0),du(0)) + b Ld(u(h),u(h)), where a + b = 1
7+ #  L(qck,ωck) -> Δt (a Ld(u(0),2 V qdk† (qdk+1-qdk)/Δt) + b Ld(qdk+1,2 V qdk† (qdk+1-qdk)/Δt), where a + b = 1
8+ #  ωckw = sqrt((2/Δt)^2 - ωckᵀωck) - 2/Δt
9+ #  Fckᵀxck -> a Fdkᵀxdk + b Fdk+1ᵀxdk, where a + b = 1
10+ 
11+ METHODORDER =  1  #  This refers to the interpolating spline
12+ getGlobalOrder () =  (global  METHODORDER; return  METHODORDER)
13+ 
14+ #  Convenience functions
15+ @inline  getx3 (state:: State , Δt) =  state. xk[1 ] +  state. vsol[2 ]* Δt
16+ @inline  getq3 (state:: State , Δt) =  state. qk[1 ] *  ωbar (state. ωsol[2 ],Δt) *  Δt /  2 
17+ 
18+ @inline  posargsc (state:: State ) =  (state. xc, state. qc)
19+ @inline  fullargsc (state:: State ) =  (state. xc, state. vc, state. qc, state. ωc)
20+ @inline  posargsk (state:: State ; k= 1 ) =  (state. xk[k], state. qk[k])
21+ @inline  posargssol (state:: State ) =  (state. xsol[2 ], state. qsol[2 ])
22+ @inline  fullargssol (state:: State ) =  (state. xsol[2 ], state. vsol[2 ], state. qsol[2 ], state. ωsol[2 ])
23+ @inline  posargsnext (state:: State , Δt) =  (getx3 (state, Δt), getq3 (state, Δt))
24+ 
25+ 
26+ @inline  function  derivωbar (ω:: SVector{3} , Δt)
27+     msq =  - sqrt (4  /  Δt^ 2  -  dot (ω, ω))
28+     return  [ω'  /  msq; I]
29+ end 
30+ 
31+ @inline  function  ωbar (ω, Δt)
32+     return  UnitQuaternion (sqrt (4  /  Δt^ 2  -  dot (ω, ω)), ω, false )
33+ end 
34+ 
35+ @inline  function  setForce! (state:: State , F, τ)
36+     state. Fk[1 ] =  F
37+     state. τk[1 ] =  τ
38+     return 
39+ end 
40+ 
41+ 
42+ @inline  function  discretizestate! (body:: Body{T} , Δt) where  T
43+     state =  body. state
44+     xc =  state. xc
45+     qc =  state. qc
46+     vc =  state. vc
47+     ωc =  state. ωc
48+ 
49+     state. xk[1 ] =  xc +  vc* Δt
50+     state. qk[1 ] =  qc *  ωbar (ωc,Δt) *  Δt /  2 
51+ 
52+     state. Fk[1 ] =  szeros (T,3 )
53+     state. τk[1 ] =  szeros (T,3 )
54+ 
55+     return 
56+ end 
57+ 
58+ @inline  function  currentasknot! (body:: Body )
59+     state =  body. state
60+ 
61+     state. xk[1 ] =  state. xc
62+     state. qk[1 ] =  state. qc
63+ 
64+     return 
65+ end 
66+ 
67+ @inline  function  updatestate! (body:: Body{T} , Δt) where  T
68+     state =  body. state
69+ 
70+     state. xc =  state. xsol[2 ]
71+     state. qc =  state. qsol[2 ]
72+     state. vc =  state. vsol[2 ]
73+     state. ωc =  state. ωsol[2 ]
74+ 
75+     state. xk[1 ] =  state. xk[1 ] +  state. vsol[2 ]* Δt
76+     state. qk[1 ] =  state. qk[1 ] *  ωbar (state. ωsol[2 ],Δt) *  Δt /  2 
77+ 
78+     state. xsol[2 ] =  state. xk[1 ]
79+     state. qsol[2 ] =  state. qk[1 ]
80+ 
81+     state. Fk[1 ] =  szeros (T,3 )
82+     state. τk[1 ] =  szeros (T,3 )
83+     return 
84+ end 
85+ 
86+ @inline  function  setsolution! (body:: Body )
87+     state =  body. state
88+     state. xsol[2 ] =  state. xk[1 ]
89+     state. qsol[2 ] =  state. qk[1 ]
90+     state. vsol[1 ] =  state. vc
91+     state. vsol[2 ] =  state. vc
92+     state. ωsol[1 ] =  state. ωc
93+     state. ωsol[2 ] =  state. ωc
94+     return 
95+ end 
96+ 
97+ @inline  function  settempvars! (body:: Body{T} , x, v, F, q, ω, τ, d) where  T
98+     state =  body. state
99+     stateold =  deepcopy (state)
100+ 
101+     state. xc =  x
102+     state. qc =  q
103+     state. vc =  v
104+     state. ωc =  ω
105+     state. Fk[1 ] =  F
106+     state. τk[1 ] =  τ
107+     state. d =  d
108+ 
109+     return  stateold
110+ end 
0 commit comments