-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathequations.py
92 lines (82 loc) · 3.36 KB
/
equations.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
from sympy import Symbol, Function, Number, diff
from modulus.eq.pdes import PDE
from typing import List, Dict
from scipy.constants import G
def generalPhase(mass: List[Number], dimensions: int = 2) -> Dict[str, List[Symbol]]:
N: int = len(mass)
q: List[Symbol] = [Symbol(f"q{i}") for i in range(dimensions * N)]
return {
"q": q,
"p": [Symbol(f"p{i}") for i in range(dimensions * N)],
}
def createMasses(masses: List[float]) -> List[Number]:
return [Number(m) for m in masses]
class FreeBodies(PDE):
def __init__(self, masses: List[float], dimensions: int = 2) -> None:
super().__init__()
assert dimensions <= 3, "Invalid dimension value (must be ≤ 3)"
t = Symbol("t")
mass: List[Number] = createMasses(masses)
input: Dict[str, List[Symbol]] = generalPhase(mass, dimensions)
q: List[Symbol] = input["q"]
p: List[Symbol] = input["p"]
kinetic_energy = sum([pi**2 / (2 * mi) for pi, mi in zip(p, mass)])
potential_energy = sum(
[
G * mi * mj / abs(qi - qj)
for i, qi in enumerate(q)
for j, qj in enumerate(q)
if i != j
]
)
H = kinetic_energy + potential_energy
self.equations = {}
for i, (qi, pi) in enumerate(zip(q, p)):
self.equations[f"q{i}_dot"] = diff(H, pi) - qi.diff(t)
self.equations[f"p{i}_dot"] = -diff(H, qi) - pi.diff(t)
class Euler(PDE):
def __init__(self, masses: List[float], dimensions: int = 2) -> None:
super().__init__()
assert dimensions <= 3, "Invalid dimension value (must be ≤ 3)"
t = Symbol("t")
mass: List[Number] = createMasses(masses)
input: Dict[str, List[Symbol]] = generalPhase(mass, dimensions)
q: List[Symbol] = input["q"]
p: List[Symbol] = input["p"]
kinetic_energy = sum([pi**2 / (2 * mi) for pi, mi in zip(p, mass)])
potential_energy = sum(
[
G * mi * mj / abs(qi - qj)
for i, qi in enumerate(q)
for j, qj in enumerate(q)
if i != j
]
)
H = kinetic_energy + potential_energy
self.equations = {}
for i, (qi, pi) in enumerate(zip(q, p)):
self.equations[f"q{i}_dot"] = diff(H, pi) - qi.diff(t)
self.equations[f"p{i}_dot"] = -diff(H, qi) - pi.diff(t)
class Lagrange(PDE):
def __init__(self, masses: List[float], dimensions: int = 2) -> None:
super().__init__()
assert dimensions <= 3, "Invalid dimension value (must be ≤ 3)"
t = Symbol("t")
mass: List[Number] = createMasses(masses)
input: Dict[str, List[Symbol]] = generalPhase(mass, dimensions)
q: List[Symbol] = input["q"]
p: List[Symbol] = input["p"]
kinetic_energy = sum([pi**2 / (2 * mi) for pi, mi in zip(p, mass)])
potential_energy = sum(
[
G * mi * mj / abs(qi - qj)
for i, qi in enumerate(q)
for j, qj in enumerate(q)
if i != j
]
)
H = kinetic_energy + potential_energy
self.equations = {}
for i, (qi, pi) in enumerate(zip(q, p)):
self.equations[f"q{i}_dot"] = diff(H, pi) - qi.diff(t)
self.equations[f"p{i}_dot"] = -diff(H, qi) - pi.diff(t)