#include #include #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(eos, surface_pressure); const double pressure_potential = serif::eos::evaluate(eos, dimensions::DensityValue{density}).value(); const double surface_pressure_potential = serif::eos::evaluate(eos, surface_density).value(); equations::EquationPoint mechanics; mechanics.position = {0.3, 0.4, 0.0}; mechanics.fields.get() = density; mechanics.fields.get() = angular_velocity; mechanics.fields.get() = surface_level; mechanics.fields.get() = 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 boundary; boundary.position = mechanics.position; boundary.fields.get() = surface_level + angular_velocity * angular_velocity * surface.rotation().centrifugal_potential(boundary.position); boundary.fields.get() = surface_level; boundary.fields.get() = 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()); std::println("Surface potential residual = {:.3e}; derivative with respect to surface level = {}", surface_balance.residual, surface_balance.field_derivatives.get()); // 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; }