Files
MeanField_SERiF/tests/serialize/write_top_fixture.cpp
Emily Boudreaux cb20faeb3d test(tests): added test suite
The test suite is extensive. Note that LLMs were used to aid in the development of the test suite. All LLM generated code was manually reviewed.
2026-11-09 13:53:17 -05:00

58 lines
2.4 KiB
C++

#include <algorithm>
#include <cmath>
#include <filesystem>
#include <numbers>
#include <print>
#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<double> { return 1.0; },
.enthalpy = [](double radius, double, double) -> io::Result<double> {
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<double> { return 1.0 - 0.2 * mu * mu; };
source.enthalpy = [](double radius, double mu, double) -> io::Result<double> {
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;
}