#include #include #include #include #include #include "serif/utils/serialize/top.hpp" /** @brief Write analytic inputs for an optional test against TOP's actual Fortran reader. */ int main(int argc, char** argv) { namespace io = serif::utils::serialize; if (argc != 2) { std::println(stderr, "Usage: top_export_fixture OUTPUT_DIRECTORY"); return 2; } const std::filesystem::path directory{argv[1]}; std::filesystem::create_directories(directory); io::TopPolytropeSource source{ .polytropic_index = 1.0, .gravitational_constant = 1.0, .mass = 1.0, .angular_velocity = 0.0, .central_density = std::numbers::pi / 4.0, .central_enthalpy = 1.0, .surface_radius = [](double, double) -> io::Result { return 1.0; }, .enthalpy = [](double radius, double, double) -> io::Result { if (radius == 0.0) return 1.0; if (radius == 1.0) return 0.0; return std::sin(std::numbers::pi * radius) / (std::numbers::pi * radius); } }; const io::TopExportOptions options{.radial_points = 64, .maximum_degree = 8, .angular_points = 24, .azimuthal_points = 8}; const auto spherical = io::export_top(directory / "spherical", source, options); if (!spherical) { std::println(stderr, "{}: {}", spherical.error().path, spherical.error().message); return 1; } source.angular_velocity = 0.2; source.surface_radius = [](double mu, double) -> io::Result { return 1.0 - 0.2 * mu * mu; }; source.enthalpy = [](double radius, double mu, double) -> io::Result { const double surface = 1.0 - 0.2 * mu * mu; if (radius == 0.0) return 1.0; if (radius >= surface) return 0.0; double lo = 0.0, hi = 1.0; for (int i = 0; i < 60; ++i) { const double z = 0.5 * (lo + hi); const double a = 0.5 * (5.0 * z * z * z - 3.0 * std::pow(z, 5)); if (0.8 * z + a * (surface - 0.8) < radius) lo = z; else hi = z; } const double z = 0.5 * (lo + hi); const double p2 = 0.5 * (3.0 * mu * mu - 1.0); return (1.0 - z * z) * (1.0 + 0.1 * z * z * p2); }; const auto deformed = io::export_top(directory / "deformed", source, options); if (!deformed) { std::println(stderr, "{}: {}", deformed.error().path, deformed.error().message); return 1; } return 0; }