#include #include "../src/physics.h" #include "../src/simulation.h" #include "../src/config_loader.h" #include #include struct TransitionEvent { double time_seconds; double time_days; int old_parent; int new_parent; char old_name[64]; char new_name[64]; double x_position; double y_position; double z_position; }; TEST_CASE("Root body transition - Earth to Sun", "[root][transition]") { const double TIME_STEP = 60.0; const double DAYS_TO_SIMULATE = 500.0; const double SECONDS_PER_DAY = 86400.0; const double AU = 1.496e11; SimulationState* sim = create_simulation(10, 0, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/test_root_body_transitions.toml")); const int PROBE_INDEX = 3; const int SUN_INDEX = 0; std::vector transitions; int previous_parent = sim->bodies[PROBE_INDEX].parent_index; INFO("Initial parent: " << sim->bodies[PROBE_INDEX].name << " (parent_index: " << previous_parent << ")"); double max_time = DAYS_TO_SIMULATE * SECONDS_PER_DAY; while (sim->time < max_time) { update_simulation(sim); int current_parent = sim->bodies[PROBE_INDEX].parent_index; if (current_parent != previous_parent) { TransitionEvent event; event.time_seconds = sim->time; event.time_days = sim->time / SECONDS_PER_DAY; event.old_parent = previous_parent; event.new_parent = current_parent; if (previous_parent >= 0 && previous_parent < sim->body_count) { strcpy(event.old_name, sim->bodies[previous_parent].name); } else { strcpy(event.old_name, "Sun"); } if (current_parent >= 0 && current_parent < sim->body_count) { strcpy(event.new_name, sim->bodies[current_parent].name); } else { strcpy(event.new_name, "Sun"); } event.x_position = sim->bodies[PROBE_INDEX].global_position.x; event.y_position = sim->bodies[PROBE_INDEX].global_position.y; event.z_position = sim->bodies[PROBE_INDEX].global_position.z; transitions.push_back(event); previous_parent = current_parent; INFO("Transition at day " << event.time_days << ": " << event.old_name << " -> " << event.new_name); } } INFO("Total transitions: " << transitions.size()); REQUIRE(transitions.size() > 0); bool found_sun_transition = false; for (const auto& event : transitions) { if (event.new_parent == SUN_INDEX || event.old_parent == SUN_INDEX) { found_sun_transition = true; INFO("Sun transition at day " << event.time_days << ": " << event.old_name << " -> " << event.new_name << " at position (" << event.x_position/AU << ", " << event.y_position/AU << ", " << event.z_position/AU << ") AU"); } } REQUIRE(found_sun_transition); destroy_simulation(sim); } TEST_CASE("Root body round-trip - Earth -> Sun -> Mars -> Sun", "[root][round-trip]") { const double TIME_STEP = 60.0; const double DAYS_TO_SIMULATE = 1000.0; const double SECONDS_PER_DAY = 86400.0; SimulationState* sim = create_simulation(10, 0, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/test_root_body_transitions.toml")); const int PROBE_INDEX = 3; const int SUN_INDEX = 0; std::vector transitions; int previous_parent = sim->bodies[PROBE_INDEX].parent_index; INFO("Initial parent: " << sim->bodies[PROBE_INDEX].name << " (parent_index: " << previous_parent << ")"); double max_time = DAYS_TO_SIMULATE * SECONDS_PER_DAY; while (sim->time < max_time) { update_simulation(sim); int current_parent = sim->bodies[PROBE_INDEX].parent_index; if (current_parent != previous_parent) { TransitionEvent event; event.time_seconds = sim->time; event.time_days = sim->time / SECONDS_PER_DAY; event.old_parent = previous_parent; event.new_parent = current_parent; if (previous_parent >= 0 && previous_parent < sim->body_count) { strcpy(event.old_name, sim->bodies[previous_parent].name); } else { strcpy(event.old_name, "Sun"); } if (current_parent >= 0 && current_parent < sim->body_count) { strcpy(event.new_name, sim->bodies[current_parent].name); } else { strcpy(event.new_name, "Sun"); } event.x_position = sim->bodies[PROBE_INDEX].global_position.x; event.y_position = sim->bodies[PROBE_INDEX].global_position.y; event.z_position = sim->bodies[PROBE_INDEX].global_position.z; transitions.push_back(event); previous_parent = current_parent; INFO("Transition at day " << event.time_days << ": " << event.old_name << " -> " << event.new_name); } } INFO("Total transitions: " << transitions.size()); REQUIRE(transitions.size() > 0); int sun_transitions = 0; for (const auto& event : transitions) { if (event.new_parent == SUN_INDEX || event.old_parent == SUN_INDEX) { sun_transitions++; INFO("Sun transition #" << sun_transitions << " at day " << event.time_days << ": " << event.old_name << " -> " << event.new_name); } } REQUIRE(sun_transitions >= 1); INFO("Root body transitions validated: " << sun_transitions << " Sun transitions detected"); destroy_simulation(sim); }