vibe coding an orbital mechanics simulation to try out claude code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

130 lines
4.5 KiB

#include <catch2/catch_test_macros.hpp>
#include "../src/physics.h"
#include "../src/simulation.h"
#include "../src/config_loader.h"
#include <cmath>
#include <vector>
struct ParentChange {
double time_seconds;
double time_days;
int old_parent;
int new_parent;
double distance_to_mars_au;
double distance_to_sun_au;
};
TEST_CASE("SOI transition - Sun to Mars", "[soi][transition]") {
const double TIME_STEP = 60.0;
const double DAYS_TO_SIMULATE = 2000.0;
const double SECONDS_PER_DAY = 86400.0;
const double AU = 1.496e11;
INFO("Note: SOI transitions use simple model (no hysteresis)");
SimulationState* sim = create_simulation(10, 0, 0, TIME_STEP);
REQUIRE(load_system_config(sim, "tests/test_soi_transition.toml"));
const int SMALL_BODY_INDEX = 2;
const int MARS_INDEX = 1;
const int SUN_INDEX = 0;
std::vector<ParentChange> parent_changes;
int previous_parent = sim->bodies[SMALL_BODY_INDEX].parent_index;
INFO("Initial parent index: " << previous_parent);
INFO("Expected: Sun (0)");
REQUIRE(previous_parent == SUN_INDEX);
double max_time = DAYS_TO_SIMULATE * SECONDS_PER_DAY;
while (sim->time < max_time) {
update_simulation(sim);
int current_parent = sim->bodies[SMALL_BODY_INDEX].parent_index;
if (current_parent != previous_parent) {
ParentChange change;
change.time_seconds = sim->time;
change.time_days = sim->time / SECONDS_PER_DAY;
change.old_parent = previous_parent;
change.new_parent = current_parent;
change.distance_to_mars_au = vec3_distance(sim->bodies[SMALL_BODY_INDEX].global_position,
sim->bodies[MARS_INDEX].global_position) / AU;
change.distance_to_sun_au = vec3_magnitude(sim->bodies[SMALL_BODY_INDEX].global_position) / AU;
parent_changes.push_back(change);
previous_parent = current_parent;
}
}
INFO("Total parent changes: " << parent_changes.size());
REQUIRE(parent_changes.size() > 0);
bool found_mars_transition = false;
for (const auto& change : parent_changes) {
if (change.new_parent == MARS_INDEX || change.old_parent == MARS_INDEX) {
found_mars_transition = true;
if (change.new_parent == MARS_INDEX) {
INFO("Entered Mars SOI at day " << change.time_days
<< ", distance to Mars: " << change.distance_to_mars_au << " AU"
<< ", distance to Sun: " << change.distance_to_sun_au << " AU");
} else if (change.old_parent == MARS_INDEX) {
INFO("Exited Mars SOI at day " << change.time_days
<< ", distance to Mars: " << change.distance_to_mars_au << " AU"
<< ", distance to Sun: " << change.distance_to_sun_au << " AU");
}
}
}
REQUIRE(found_mars_transition);
bool found_mars_exit = false;
for (const auto& change : parent_changes) {
if (change.old_parent == MARS_INDEX && change.new_parent == SUN_INDEX) {
found_mars_exit = true;
INFO("Mars -> Sun exit at day " << change.time_days
<< ", distance to Mars: " << change.distance_to_mars_au << " AU"
<< ", distance to Sun: " << change.distance_to_sun_au << " AU");
break;
}
}
REQUIRE(found_mars_exit);
destroy_simulation(sim);
}
TEST_CASE("SOI transition - verify SOI radii", "[soi][radii]") {
const double TIME_STEP = 60.0;
const double AU = 1.496e11;
SimulationState* sim = create_simulation(10, 0, 0, TIME_STEP);
REQUIRE(load_system_config(sim, "tests/test_soi_transition.toml"));
const int MARS_INDEX = 1;
double mars_soi_meters = sim->bodies[MARS_INDEX].soi_radius;
double mars_soi_au = mars_soi_meters / AU;
INFO("Mars SOI radius: " << mars_soi_meters / 1e9 << " million km");
INFO("Mars SOI radius: " << mars_soi_au << " AU");
double expected_mars_soi = 2.244e11 * pow(6.39e23 / 1.989e30, 0.4);
double expected_mars_soi_au = expected_mars_soi / AU;
INFO("Expected Mars SOI: " << expected_mars_soi / 1e9 << " million km");
INFO("Expected Mars SOI: " << expected_mars_soi_au << " AU");
double soi_error = fabs(mars_soi_au - expected_mars_soi_au) / expected_mars_soi_au;
INFO("SOI calculation error: " << soi_error * 100.0 << "%");
REQUIRE(soi_error < 0.01);
REQUIRE(mars_soi_au > 0.003);
REQUIRE(mars_soi_au < 0.005);
destroy_simulation(sim);
}