feat(newton): first newton solver implementation
This commit is contained in:
@@ -2,6 +2,10 @@ module;
|
||||
|
||||
#include <compare>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <limits>
|
||||
#include <optional>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
|
||||
#include <mfem.hpp>
|
||||
@@ -45,6 +49,52 @@ export namespace mean_field::operators {
|
||||
constexpr auto operator<=>(const PreparedAngularMomentumReport &) const = default;
|
||||
};
|
||||
|
||||
enum class AngularMomentumPreparationRejectionReason : std::uint8_t {
|
||||
inverted_geometry,
|
||||
non_finite_geometry,
|
||||
non_finite_angular_velocity,
|
||||
non_finite_density,
|
||||
negative_moment_of_inertia,
|
||||
non_finite_moment_of_inertia,
|
||||
non_finite_residual
|
||||
};
|
||||
|
||||
/*
|
||||
* A trial state can fail to define the angular-momentum invariant without
|
||||
* violating the operator's structural contract. Keep that distinction in
|
||||
* a fixed-size value so a line search can reject the candidate without
|
||||
* constructing or transporting an exception.
|
||||
*/
|
||||
struct AngularMomentumPreparationRejection final {
|
||||
AngularMomentumPreparationRejectionReason reason{AngularMomentumPreparationRejectionReason::inverted_geometry};
|
||||
mapping::MappingStatus mappingStatus{mapping::MappingStatus::valid};
|
||||
double momentOfInertia{std::numeric_limits<double>::quiet_NaN()};
|
||||
};
|
||||
|
||||
using AngularMomentumPreparationResult =
|
||||
std::expected<PreparedAngularMomentumReport, AngularMomentumPreparationRejection>;
|
||||
|
||||
[[noreturn]] inline void
|
||||
throwAngularMomentumPreparationRejection(const AngularMomentumPreparationRejection &rejection) {
|
||||
switch (rejection.reason) {
|
||||
case AngularMomentumPreparationRejectionReason::inverted_geometry:
|
||||
throw std::domain_error("The angular-momentum trial inverts mapped geometry.");
|
||||
case AngularMomentumPreparationRejectionReason::non_finite_geometry:
|
||||
throw std::domain_error("The angular-momentum trial produced non-finite mapped geometry.");
|
||||
case AngularMomentumPreparationRejectionReason::non_finite_angular_velocity:
|
||||
throw std::domain_error("The angular-momentum trial has a non-finite angular velocity.");
|
||||
case AngularMomentumPreparationRejectionReason::non_finite_density:
|
||||
throw std::domain_error("The angular-momentum trial produced a non-finite interpolated density.");
|
||||
case AngularMomentumPreparationRejectionReason::negative_moment_of_inertia:
|
||||
throw std::domain_error("The angular-momentum trial produced a negative moment of inertia.");
|
||||
case AngularMomentumPreparationRejectionReason::non_finite_moment_of_inertia:
|
||||
throw std::domain_error("The angular-momentum trial produced a non-finite moment of inertia.");
|
||||
case AngularMomentumPreparationRejectionReason::non_finite_residual:
|
||||
throw std::domain_error("The angular-momentum trial produced a non-finite residual.");
|
||||
}
|
||||
throw std::logic_error("An unknown angular-momentum trial rejection was reported.");
|
||||
}
|
||||
|
||||
struct AngularMomentumConstraintReport final {
|
||||
double targetAngularMomentum;
|
||||
double achievedAngularMomentum;
|
||||
@@ -97,6 +147,11 @@ export namespace mean_field::operators {
|
||||
const AngularMomentumDependencies &dependencies
|
||||
);
|
||||
|
||||
[[nodiscard]] AngularMomentumPreparationResult TryPrepare(
|
||||
double angularVelocity,
|
||||
const AngularMomentumDependencies &dependencies
|
||||
);
|
||||
|
||||
void BuildResidual(mfem::Vector &residual) const;
|
||||
|
||||
void ApplyDensityJacobianAction(
|
||||
@@ -156,9 +211,9 @@ export namespace mean_field::operators {
|
||||
};
|
||||
|
||||
void BuildStaticPlan();
|
||||
void RefreshGeometry(const mfem::Vector &displacement);
|
||||
void RefreshDensity(const mfem::Vector &density);
|
||||
void AssembleResidual();
|
||||
[[nodiscard]] std::optional<mapping::MappingStatus> RefreshGeometry(const mfem::Vector &displacement);
|
||||
[[nodiscard]] bool RefreshDensity(const mfem::Vector &density);
|
||||
[[nodiscard]] std::optional<AngularMomentumPreparationRejection> TryAssembleResidual();
|
||||
void VerifyPrepared() const;
|
||||
|
||||
[[nodiscard]] double EvaluateDensityMomentActionLocal(const mfem::Vector &densityVariation) const;
|
||||
|
||||
Reference in New Issue
Block a user