Files
MeanField_SERiF/tests/sandbox/equations_sandbox.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

49 lines
2.9 KiB
C++

#include <cmath>
#include <print>
#include "serif/eos/evaluation.hpp"
#include "serif/eos/models/polytropic.hpp"
#include "serif/equations/barotropic_density.hpp"
#include "serif/equations/surface_potential.hpp"
/** @brief Evaluate manufactured interior and surface samples and inspect their exact derivatives. */
int main() {
namespace equations = serif::equations;
namespace dimensions = serif::dimensions;
const serif::eos::models::Polytrope eos{1.0, 0.8};
const double density = 0.5, angular_velocity = 0.3, surface_level = 1.2;
const dimensions::PressureValue surface_pressure{0.0};
const equations::BarotropicDensityBalance density_balance{eos, surface_pressure};
const equations::SurfacePotentialBalance surface;
using Balance = decltype(density_balance);
// Density supplies the pressure potential through the EOS; it is not another solved field.
const auto surface_density = serif::eos::evaluate<dimensions::MassDensity>(eos, surface_pressure);
const double pressure_potential = serif::eos::evaluate<dimensions::BarotropicPressurePotential>(eos, dimensions::DensityValue{density}).value();
const double surface_pressure_potential = serif::eos::evaluate<dimensions::BarotropicPressurePotential>(eos, surface_density).value();
equations::EquationPoint<Balance::Operands> mechanics;
mechanics.position = {0.3, 0.4, 0.0};
mechanics.fields.get<Balance::Density>() = density;
mechanics.fields.get<Balance::AngularVelocity>() = angular_velocity;
mechanics.fields.get<Balance::SurfaceLevel>() = surface_level;
mechanics.fields.get<Balance::Potential>() = surface_level - pressure_potential + surface_pressure_potential +
angular_velocity * angular_velocity * density_balance.rotation().centrifugal_potential(mechanics.position);
const auto interior_balance = density_balance.evaluate(mechanics);
equations::EquationPoint<decltype(surface)::Operands> boundary;
boundary.position = mechanics.position;
boundary.fields.get<decltype(surface)::Potential>() = surface_level +
angular_velocity * angular_velocity * surface.rotation().centrifugal_potential(boundary.position);
boundary.fields.get<decltype(surface)::SurfaceLevel>() = surface_level;
boundary.fields.get<decltype(surface)::AngularVelocity>() = angular_velocity;
const auto surface_balance = surface.evaluate(boundary);
std::println("Density balance residual = {:.3e}; angular-velocity derivative = {}",
interior_balance.residual, interior_balance.field_derivatives.get<Balance::AngularVelocity>());
std::println("Surface potential residual = {:.3e}; derivative with respect to surface level = {}",
surface_balance.residual, surface_balance.field_derivatives.get<decltype(surface)::SurfaceLevel>());
// complete_sandbox assembles these same physical equations on its finite-element mesh.
return std::abs(interior_balance.residual) < 1.0e-12 && std::abs(surface_balance.residual) < 1.0e-12 ? 0 : 1;
}