1
0
Fork 0
mirror of https://github.com/Findus23/rebound-collisions.git synced 2024-09-19 15:53:48 +02:00
rebound-collisions/final_results.py

176 lines
6.3 KiB
Python
Raw Normal View History

2021-12-20 16:27:14 +01:00
import glob
2021-05-03 15:59:58 +02:00
from typing import List
import pandas as pd
from rebound import SimulationArchive, Simulation
2021-12-20 16:27:14 +01:00
from scipy.constants import mega
2021-05-03 15:59:58 +02:00
2021-12-20 16:27:14 +01:00
from extradata import ExtraData, CollisionMeta
2021-05-03 15:59:58 +02:00
from utils import filename_from_argv, is_potentially_habitable, Particle, earth_mass, earth_water_mass
# pd.set_option('display.max_columns', None)
pd.options.display.max_columns = None
pd.options.display.width = 0
2021-12-20 16:27:14 +01:00
minmax=True
def chunks(lst, lst2):
"""Yield successive n-sized chunks from lst."""
for i in range(0, len(lst), 2):
yield lst[i:i + 2] + lst2[i:i + 2]
def print_row(mean, std, name: str):
strings = [name]
for value, pm in zip(list(mean), list(std)):
strings.append(f"{value:.1f}\\pm {pm:.1f}")
print(" & ".join(strings) + r" \\")
2021-05-03 15:59:58 +02:00
def get_masses(ed: ExtraData, planets: List[Particle]):
total = 0
water = 0
for p in planets:
data = ed.pd(p)
2021-12-20 16:27:14 +01:00
# print(data.water_mass)
2021-05-03 15:59:58 +02:00
total += data.total_mass / earth_mass
water += data.water_mass / earth_water_mass
return total, water
2021-12-20 16:27:14 +01:00
methods = {
"rbf": "data/final_rbf_*.bin",
"nn": "data/final_nn_*.bin",
"lz": "data/final_lz_*.bin",
"pm": "data/final_pm_*.bin",
}
columns = ["num_planets", "num_planets_pot", "M_planets", "M_planets_pot", "M_water", "M_water_pot", "escaped_mass",
"escaped_water_mass", "sun_mass", "sun_water_mass", "gas_giant_mass", "gas_giant_water_mass",
"collision_mass", "collision_water_mass","last_collision_time"]
maintable = []
for name, filepath in methods.items():
table = []
rows = []
for file in sorted(glob.glob(filepath)):
fn = filename_from_argv(file)
# print(fn)
ed = ExtraData.load(fn)
if ed.meta.current_time < ed.meta.tmax:
print("not yet finished")
2021-05-03 15:59:58 +02:00
continue
2021-12-20 16:27:14 +01:00
sa = SimulationArchive(str(fn.with_suffix(".bin")))
last_sim: Simulation = sa[-1]
planets = []
for particle in last_sim.particles:
if ed.pd(particle).type in ["sun", "gas giant"]:
continue
if ed.pd(particle).type == "planetesimal":
continue
# print(particle.r * astronomical_unit / earth_radius)
planets.append(particle)
pothab_planets = [p for p in planets if is_potentially_habitable(p)]
num_planets = len(planets)
num_planets_pot = len(pothab_planets)
M_planets, M_water = get_masses(ed, planets)
M_planets_pot, M_water_pot = get_masses(ed, pothab_planets)
# mass of particles thrown into Sun/escaped
escaped_mass = 0
escaped_water_mass = 0
sun_mass = 0
sun_water_mass = 0
for particle in ed.pdata.values():
if particle.escaped:
if particle.type in ["sun", "gas giant"]:
print(fn, particle, "escaped", particle.type)
continue
escaped_mass += particle.total_mass / earth_mass
escaped_water_mass += particle.water_mass / earth_water_mass
elif particle.collided_with_sun:
sun_mass += particle.total_mass / earth_mass
sun_water_mass += particle.water_mass / earth_water_mass
# count mass lost to gas giants
gas_giant_mass = 0
gas_giant_water_mass = 0
for col_id, collision in ed.tree.get_tree().items():
gas_parent = None
other_parent = None
gas_parent_counter = 0
for parent in collision["parents"]:
if ed.pdata[parent].type == "gas giant":
gas_parent_counter += 1
gas_parent = parent
else:
other_parent = parent
if gas_parent_counter > 1:
print(f"it seems like {gas_parent_counter} gas giants collided with each other")
continue
if gas_parent:
previous_body = ed.pdata[other_parent]
gas_giant_mass += previous_body.total_mass / earth_mass
gas_giant_water_mass += previous_body.water_mass / earth_water_mass
# count mass lost in collisions
collision_mass = 0
collision_water_mass = 0
for col_id, collision in ed.tree.get_tree().items():
parent_mass = 0
parent_water_mass = 0
for parent in collision["parents"]:
parent_body = ed.pdata[parent]
parent_mass += parent_body.total_mass / earth_mass
parent_water_mass += parent_body.water_mass / earth_water_mass
child = ed.pdata[col_id]
diff = parent_mass - child.total_mass / earth_mass
diff_water = parent_water_mass - child.water_mass / earth_water_mass
collision_mass += diff
collision_water_mass += diff_water
if collision_water_mass < 1e-10:
collision_water_mass = 0
if collision_mass < 1e-10:
collision_mass = 0
# last collision time
last_collision_time = 0
for col_id, collision in ed.tree.get_tree().items():
meta: CollisionMeta = collision["meta"]
if meta.time > last_collision_time:
last_collision_time = meta.time
last_collision_time /= mega
values = [num_planets, num_planets_pot, M_planets, M_planets_pot, M_water, M_water_pot, escaped_mass,
escaped_water_mass, sun_mass, sun_water_mass, gas_giant_mass, gas_giant_water_mass,
collision_mass, collision_water_mass, last_collision_time]
# print(values)
table.append(values)
rows.append(str(fn))
pd.set_option('display.float_format', lambda x: '%.1f' % x)
df = pd.DataFrame(table, index=rows, columns=columns)
# print(df)
# print("\n-----\n")
# print_row(df.mean(), df.std(), name)
if minmax:
maintable.append(list(zip(df.min(), df.max())))
else:
maintable.append(list(zip(df.mean(), df.std())))
transposed = list(map(list, zip(*maintable)))
for row, name in zip(transposed, columns):
strings = [name.replace("_", "\\_")]
for value, pm in row:
if minmax:
strings.append(f"{value:.1f} -- {pm:.1f}")
2021-05-03 15:59:58 +02:00
else:
2021-12-20 16:27:14 +01:00
strings.append(f"{value:.1f}\\pm {pm:.1f}")
2021-05-03 15:59:58 +02:00
print(" & ".join(strings) + r" \\")