feat(model): added model sub system

SERiF defines a so-called "model" subsystem. A model is a fully compile-time description of a problem. Note that this is a description not an evaluation tool. The basic idea is that since we have this robust description we can more easily serialize and be confident that others who load a model are getting the exact same thing. Further, this provides a convient place to do things like validate that all options are compatible, do some limited initial construction of the needed computational graph, allocate needed memory, etc... Some of the stuff that might initially seem to belong to a model will be in the discritization system though (e.g. FEM object lifetimes)
This commit is contained in:
2026-11-09 13:20:46 -05:00
parent c6d1686c5d
commit 48c6bac1cc
24 changed files with 1816 additions and 0 deletions

View File

@@ -0,0 +1,58 @@
#pragma once
#include <array>
#include "serif/dimensions/type_alias.hpp"
#include "serif/model/specification.hpp"
#include "serif/model/specifications/physical_names.hpp"
namespace serif::model
{
/** @brief Prescribe angular momentum while angular velocity remains an independent solved coordinate. */
class FixedAngularMomentum final
{
public:
struct Parameters
{
dimensions::AngularMomentumValue angular_momentum;
std::array<double, 3> axis{0.0, 0.0, 1.0};
std::array<double, 3> center{};
};
using ScalarDescription = ScalarConstraint<dimensions::AngularMomentum, dimensions::AngularVelocity, dimensions::AngularMomentum,
"fixed_angular_momentum.angular_velocity", "Omega", "fixed_angular_momentum.residual", "R_J">;
using TargetValue = ScalarDescription::TargetValue;
using ModelDefinition = SpecificationDefinition<FixedAngularMomentum, "FixedAngularMomentum", SpecificationRole::invariant, GeneratedStateKind::physical_coordinate,
ScalarDescription, Reads<state::Density, state::SurfaceShape, state::OwnGeneratedCoordinate>,
Changes<equation::SurfaceShapeBalance, equation::HydrostaticBalance>>;
/** @brief Require finite nonnegative angular momentum about the default z axis. */
explicit FixedAngularMomentum(TargetValue angular_momentum);
/** @brief Validate the physical target and normalize a finite nonzero rotation axis. */
explicit FixedAngularMomentum(Parameters parameters);
/** @brief Inspect the prescribed total angular momentum. */
[[nodiscard]] TargetValue target() const noexcept
{
return m_target;
}
/** @brief Read the normalized rotation axis. */
[[nodiscard]] const std::array<double, 3>& axis() const noexcept
{
return m_axis;
}
/** @brief Read the point through which the rotation axis passes. */
[[nodiscard]] const std::array<double, 3>& center() const noexcept
{
return m_center;
}
private:
TargetValue m_target;
std::array<double, 3> m_axis;
std::array<double, 3> m_center;
};
} // namespace serif::model

View File

@@ -0,0 +1,41 @@
#pragma once
#include "serif/dimensions/type_alias.hpp"
#include "serif/model/specification.hpp"
#include "serif/model/specifications/physical_names.hpp"
namespace serif::model
{
/** @brief Prescribe total stellar mass while the effective surface-potential level remains an independent solved coordinate. */
class FixedTotalMass final
{
public:
struct Parameters
{
dimensions::MassValue total_mass;
};
// Preserve the serialized coordinate identity while describing its present physical meaning.
using ScalarDescription = ScalarConstraint<dimensions::Mass, dimensions::GravitationalPotential, dimensions::Mass,
"fixed_total_mass.multiplier", "Us", "fixed_total_mass.residual", "R_M">;
using TargetValue = ScalarDescription::TargetValue;
// Us retains the mass-constraint multiplier role; changing its physical units must not reorder public prescriptions.
using ModelDefinition = SpecificationDefinition<FixedTotalMass, "FixedTotalMass", SpecificationRole::invariant, GeneratedStateKind::multiplier,
ScalarDescription, Reads<state::Density, state::SurfaceShape>, Changes<equation::SurfaceShapeBalance>>;
/** @brief Require a positive finite target mass. */
explicit FixedTotalMass(TargetValue mass);
/** @brief Construct from named physical parameters. */
explicit FixedTotalMass(Parameters parameters);
/** @brief Inspect the prescribed total mass. */
[[nodiscard]] TargetValue target() const noexcept
{
return m_target;
}
private:
TargetValue m_target;
};
} // namespace serif::model

View File

@@ -0,0 +1,36 @@
#pragma once
namespace serif::model
{
namespace state
{
struct Density
{
};
struct SurfaceShape
{
};
struct GravitationalPotential
{
};
struct OwnGeneratedCoordinate
{
};
} // namespace state
namespace equation
{
struct PoissonBalance
{
};
struct SurfaceShapeBalance
{
};
struct HydrostaticBalance
{
};
struct OwnConstraint
{
};
} // namespace equation
} // namespace serif::model