-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcheck_conservation.py
146 lines (121 loc) · 4.32 KB
/
check_conservation.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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# -*- coding: utf-8 -*-
"""
ESTIMATION OF ERRORS
This program needs have the files "results_R.txt" and "results_V.txt" in
its folder.
To estimate the error of a simulation, run:
>>> ERROR()
If there is the possibility of two bodies colliding or getting very close, run:
>>> PLOT_ERROR()
to see if there is a significant change in the error of both energy and angular momentum.
"""
import numpy as np
import matplotlib.pyplot as plt
def ERROR():
"""
Determines the error using:
Error X (%) = 100*abs(Xfinal - Xinitial)/Xinitial
Returns error in %.
"""
m, r, v = get_data()
Etotal_i = E(m, r[0], v[0])
Etotal_f = E(m, r[-1], v[-1])
LT_i, Lx_i, Ly_i, Lz_i = L(m, r[0], v[0])
LT_f, Lx_f, Ly_f, Lz_f = L(m, r[-1], v[-1])
error_E = abs(Etotal_i-Etotal_f)/abs(Etotal_i)*100
error_LT = abs(LT_i-LT_f)/LT_i*100
error_L = np.array([abs(Lx_i-Lx_f)/Lx_i*100, abs(Ly_i-Ly_f)/Ly_i*100, abs(Lz_i-Lz_f)/Lz_i*100])
print("\nThe error of the final state compared to the initial one is:")
print("\nError X (%) = 100*abs(Xfinal - Xinitial)/Xinitial")
print("\nError E (%) = {0:0.15f}".format(error_E))
print("\nError L (%) = {0:0.15f}".format(error_LT))
return error_E, error_LT, error_L
def PLOT_ERROR():
"""
Plots the evolution of the error vs iteration.
Error X (%) = 100*abs(Xfinal - Xinitial)/Xinitial
"""
m, r, v = get_data()
Etotal = np.array([E(m, r[i], v[i]) for i in range(len(v))])
error_E = abs(Etotal - Etotal[0])/Etotal[0]*100
LT = []
Lx = []
Ly = []
Lz = []
for i in range(len(r)):
LTi, Lxi, Lyi, Lzi = L(m, r[i], v[i])
LT += [LTi]
LT = np.array(LT)
error_L = abs(LT - LT[0])/LT[0]*100
t = range(len(Etotal))
fig1 = plt.figure(1, figsize=[14,7])
ax11 = fig1.add_subplot(121)
ax11.plot(t, error_E, ".")
ax11.set_xlabel("iteration [#]")
ax11.set_ylabel("error in energy [%]")
ax12 = fig1.add_subplot(122)
ax12.plot(t, error_L, ".")
ax12.set_xlabel("iteration [#]")
ax12.set_ylabel("error in modulus of angular momentum [%]")
fig1.tight_layout()
return error_E, error_L
def E(m, r, v):
"""
Calculates total energy of a given system in a given instant.
All data has to be normalized.
E = T + V
v : vx, vy, vz X n bodies (vector of 3N scalars)
m : m X n bodies (vector of N scalars)
"""
Ec = sum([0.5*m[i]*(v[3*i ]**2 + v[3*i+1]**2 + v[3*i+2]**2) for i in range(len(m))])
Ep = 0
for i in np.arange(0, len(m) - 1):
for j in np.arange(i + 1, len(m)):
Ep += m[i]*m[j]/np.sqrt((r[3*i ] - r[3*j ])**2 + \
(r[3*i+1] - r[3*j+1])**2 + \
(r[3*i+2] - r[3*j+2])**2 )
ET = Ec - Ep
return ET
def L(m, r, v):
"""
Calculates total angular momentum of a given system in a given instant.
All data has to be normalized.
v : vx, vy, vz X n bodies (vector of 3N scalars)
r : rx, ry, rz X n bodies (vector of 3N scalars)
m : m X n bodies (vector of N scalars)
"""
Lx = sum([m[i]*(r[3*i+1]*v[3*i+2] - r[3*i+2]*v[3*i+1]) for i in range(len(m))])
Ly = sum([m[i]*(r[3*i+2]*v[3*i ] - r[3*i ]*v[3*i+2]) for i in range(len(m))])
Lz = sum([m[i]*(r[3*i ]*v[3*i+1] - r[3*i+1]*v[3*i ]) for i in range(len(m))])
LT = np.sqrt(Lx**2 + Ly**2 + Lz**2)
return LT, Lx, Ly, Lz
def get_data():
"""
Gets all data from "initial_data.csv", "results_R.txt" and "results_V.txt".
The output are 3 vectors: r, v, m
"""
#LOADS INITIAL DATA
RVM = np.loadtxt("initial_data.csv", unpack=True, delimiter=",")
m = np.array(RVM[-1])
RVM = np.transpose(RVM)
r0 = []
for i in range(len(m)):
r0 += RVM[i, 0:3].tolist()
r0 = np.array(r0)
v0 = []
for i in range(len(m)):
v0 += RVM[i, 3:6].tolist()
v0 = np.array(v0)
#LOADS R
f = open("results_R.txt", "r")
r = f.read()
f.close()
r = np.array([[float(j) for j in i.split(" ")] for i in r.split("\n")[:-1]])
r = np.array([r0.tolist()] + r.tolist())
#LOADS V
f = open("results_V.txt", "r")
v = f.read()
f.close()
v = np.array([[float(j) for j in i.split(" ")] for i in v.split("\n")[:-1]])
v = np.array([v0.tolist()] + v.tolist())
return m, r, v