#include #include "../src/physics.h" #include "../src/simulation.h" #include "../src/config_loader.h" #include "../src/test_utilities.h" #include TEST_CASE("Orbital period - Earth (RK4)", "[period][rk4]") { const double TIME_STEP = 60.0; const double EXPECTED_PERIOD_DAYS = 365.0; const double SECONDS_PER_DAY = 86400.0; const double MAX_SIMULATION_DAYS = 400.0; SimulationState* sim = create_simulation(10, 0, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/test_orbital_period.toml")); OrbitTracker* tracker = create_orbit_tracker(1); double max_time = MAX_SIMULATION_DAYS * SECONDS_PER_DAY; while (sim->time < max_time && !tracker->orbit_completed) { update_simulation(sim); update_orbit_tracker(tracker, &sim->bodies[1], &sim->bodies[0], sim->time); } REQUIRE(tracker->orbit_completed); double measured_period_days = tracker->time_at_completion / SECONDS_PER_DAY; double period_error_days = fabs(measured_period_days - EXPECTED_PERIOD_DAYS); INFO("Expected period: " << EXPECTED_PERIOD_DAYS << " days"); INFO("Measured period: " << measured_period_days << " days"); INFO("Error: " << period_error_days << " days"); REQUIRE(period_error_days < 5.0); destroy_orbit_tracker(tracker); destroy_simulation(sim); } TEST_CASE("Orbital period - Mars (RK4)", "[period][rk4]") { const double TIME_STEP = 60.0; const double EXPECTED_PERIOD_DAYS = 687.0; const double SECONDS_PER_DAY = 86400.0; const double MAX_SIMULATION_DAYS = 750.0; SimulationState* sim = create_simulation(10, 0, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/test_orbital_period.toml")); OrbitTracker* tracker = create_orbit_tracker(2); double max_time = MAX_SIMULATION_DAYS * SECONDS_PER_DAY; while (sim->time < max_time && !tracker->orbit_completed) { update_simulation(sim); update_orbit_tracker(tracker, &sim->bodies[2], &sim->bodies[0], sim->time); } REQUIRE(tracker->orbit_completed); double measured_period_days = tracker->time_at_completion / SECONDS_PER_DAY; double period_error_days = fabs(measured_period_days - EXPECTED_PERIOD_DAYS); INFO("Expected period: " << EXPECTED_PERIOD_DAYS << " days"); INFO("Measured period: " << measured_period_days << " days"); INFO("Error: " << period_error_days << " days"); REQUIRE(period_error_days < 25.0); destroy_orbit_tracker(tracker); destroy_simulation(sim); } TEST_CASE("Orbit direction - prograde for zero inclination", "[direction]") { const double TIME_STEP = 60.0; const double TEST_DURATION_DAYS = 1.0; const double SECONDS_PER_DAY = 86400.0; const int STEPS = (int)(TEST_DURATION_DAYS * SECONDS_PER_DAY / TIME_STEP); SimulationState* sim = create_simulation(2, 0, 0, TIME_STEP); REQUIRE(load_system_config(sim, "tests/test_energy.toml")); CelestialBody* sun = &sim->bodies[0]; CelestialBody* earth = &sim->bodies[1]; Vec3 initial_rel_pos = vec3_sub(earth->global_position, sun->global_position); double theta_start = atan2(initial_rel_pos.y, initial_rel_pos.x); for (int i = 0; i < STEPS; i++) { update_simulation(sim); } Vec3 final_rel_pos = vec3_sub(earth->global_position, sun->global_position); double theta_final = atan2(final_rel_pos.y, final_rel_pos.x); INFO("Initial angle: " << theta_start << " rad"); INFO("Final angle: " << theta_final << " rad"); REQUIRE(theta_final > theta_start); destroy_simulation(sim); }