feat(newton): first newton solver implementation
This commit is contained in:
@@ -3,10 +3,14 @@ module;
|
||||
#include <compare>
|
||||
#include <concepts>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <limits>
|
||||
#include <stdexcept>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <mfem.hpp>
|
||||
#include <mpi.h>
|
||||
|
||||
export module mean_field:operators.prepared_stellar_equilibrium;
|
||||
|
||||
@@ -72,6 +76,70 @@ export namespace mean_field::operators {
|
||||
}
|
||||
};
|
||||
|
||||
enum class StellarEquilibriumPreparationRejectionReason : std::uint8_t {
|
||||
inverted_geometry,
|
||||
non_finite_geometry,
|
||||
thermodynamic_domain,
|
||||
non_finite_thermodynamics,
|
||||
inadmissible_physics,
|
||||
non_finite_physics
|
||||
};
|
||||
|
||||
enum class StellarEquilibriumPreparationStage : std::uint8_t {
|
||||
unspecified,
|
||||
generated_geometry,
|
||||
gravity,
|
||||
barotropic_closure,
|
||||
hydrostatic_equilibrium,
|
||||
displacement_residual,
|
||||
pressure_force,
|
||||
gravity_displacement_force,
|
||||
rotational_displacement_force,
|
||||
displacement_composition,
|
||||
mass_normalization,
|
||||
model_specification
|
||||
};
|
||||
|
||||
/*
|
||||
* A candidate state that cannot define a physical mapped domain is an
|
||||
* expected line-search outcome, not an exceptional program failure. Keep
|
||||
* this payload fixed-size so every trial can report it without allocating.
|
||||
*/
|
||||
struct StellarEquilibriumPreparationRejection final {
|
||||
StellarEquilibriumPreparationRejectionReason reason{
|
||||
StellarEquilibriumPreparationRejectionReason::inverted_geometry
|
||||
};
|
||||
StellarEquilibriumPreparationStage stage{StellarEquilibriumPreparationStage::unspecified};
|
||||
double minimumJacobianDeterminant{std::numeric_limits<double>::quiet_NaN()};
|
||||
eos::EvaluationErrorCode thermodynamicErrorCode{eos::EvaluationErrorCode::nonfinite_result};
|
||||
};
|
||||
|
||||
template <typename Report>
|
||||
using StellarEquilibriumPreparationResult = std::expected<Report, StellarEquilibriumPreparationRejection>;
|
||||
|
||||
[[noreturn]] inline void
|
||||
throwStellarEquilibriumPreparationRejection(const StellarEquilibriumPreparationRejection &rejection) {
|
||||
switch (rejection.reason) {
|
||||
case StellarEquilibriumPreparationRejectionReason::non_finite_geometry:
|
||||
throw std::domain_error("The prepared domain deformation has non-finite mapped geometry.");
|
||||
case StellarEquilibriumPreparationRejectionReason::thermodynamic_domain:
|
||||
throw eos::EvaluationError(
|
||||
rejection.thermodynamicErrorCode, "The stellar state lies outside the equation-of-state domain."
|
||||
);
|
||||
case StellarEquilibriumPreparationRejectionReason::non_finite_thermodynamics:
|
||||
throw eos::EvaluationError(
|
||||
rejection.thermodynamicErrorCode, "The stellar state produced non-finite thermodynamic data."
|
||||
);
|
||||
case StellarEquilibriumPreparationRejectionReason::inadmissible_physics:
|
||||
throw std::domain_error("The stellar state is physically inadmissible.");
|
||||
case StellarEquilibriumPreparationRejectionReason::non_finite_physics:
|
||||
throw std::domain_error("The stellar state produced non-finite physical data.");
|
||||
case StellarEquilibriumPreparationRejectionReason::inverted_geometry:
|
||||
throw std::domain_error("The prepared domain deformation inverts at least one volume element.");
|
||||
}
|
||||
throw std::logic_error("Unknown stellar-equilibrium candidate-rejection reason.");
|
||||
}
|
||||
|
||||
struct PreparedStellarEquilibriumStatistics final {
|
||||
std::uint64_t residualAssemblies{0};
|
||||
std::uint64_t residualApplications{0};
|
||||
@@ -159,6 +227,12 @@ export namespace mean_field::operators {
|
||||
const physics::RigidRotation &rotation
|
||||
);
|
||||
|
||||
[[nodiscard]] StellarEquilibriumPreparationResult<PreparedStellarEquilibriumReport> TryPrepare(
|
||||
const mfem::Vector &state,
|
||||
const StellarEquilibriumDependencies &dependencies,
|
||||
const physics::RigidRotation &rotation
|
||||
);
|
||||
|
||||
void BuildResidual(mfem::Vector &residual) const;
|
||||
|
||||
void Mult(
|
||||
@@ -188,12 +262,9 @@ export namespace mean_field::operators {
|
||||
[[nodiscard]] const PreparedHydrostaticEquilibriumOperator &GetHydrostaticOperator() const noexcept;
|
||||
[[nodiscard]] const PreparedDisplacementResidualOperator &GetDisplacementOperator() const noexcept;
|
||||
[[nodiscard]] const PreparedMassNormalizationOperator &GetMassNormalizationOperator() const noexcept;
|
||||
[[nodiscard]] double ApplyDensityVolumeIntegralDensityAction(
|
||||
const mfem::Vector &densityDirection
|
||||
) const;
|
||||
[[nodiscard]] double ApplyDensityVolumeIntegralSurfaceShapeAction(
|
||||
const mfem::Vector &surfaceShapeDirection
|
||||
) const;
|
||||
[[nodiscard]] double ApplyDensityVolumeIntegralDensityAction(const mfem::Vector &densityDirection) const;
|
||||
[[nodiscard]] double
|
||||
ApplyDensityVolumeIntegralSurfaceShapeAction(const mfem::Vector &surfaceShapeDirection) const;
|
||||
[[nodiscard]] const PreparedPressureSurfaceConstraint &GetSurfaceConstraintOperator() const noexcept;
|
||||
[[nodiscard]] const deformation::PreparedDomainDeformationRuntime &GetDomainDeformation() const noexcept;
|
||||
[[nodiscard]] const mfem::Vector &GetSurfaceDeformationParameters() const;
|
||||
@@ -222,6 +293,7 @@ export namespace mean_field::operators {
|
||||
void VerifyPrepared() const;
|
||||
|
||||
StellarEquilibriumRootManifest m_rootManifest;
|
||||
MPI_Comm m_communicator{MPI_COMM_NULL};
|
||||
mfem::Array<int> m_gravityStateOffsets;
|
||||
|
||||
context::gravity_field::GravityFieldLinearizationContext m_gravityContext;
|
||||
|
||||
Reference in New Issue
Block a user