feat(newton): first newton solver implementation

This commit is contained in:
2026-09-08 06:36:39 -04:00
parent 76818f2f82
commit b3c04d507a
98 changed files with 20397 additions and 11040 deletions

View File

@@ -63,7 +63,7 @@ export namespace mean_field::preconditioning {
.geometry = prepared.geometry != current.geometry,
.equationOfState = prepared.equationOfStateIdentity != current.equationOfStateIdentity,
.linearization = prepared.linearization != current.linearization ||
prepared.preparedOperatorGeneration != current.preparedOperatorGeneration
prepared.preparedOperatorGeneration != current.preparedOperatorGeneration
};
}
@@ -97,9 +97,7 @@ export namespace mean_field::preconditioning {
static constexpr bool registered = false;
};
template <
equilibrium::StellarEquilibriumModel Model,
equilibrium::StellarDiscretizationType Discretization>
template <equilibrium::StellarEquilibriumModel Model, equilibrium::StellarDiscretizationType Discretization>
struct StellarEquilibriumProblemTraits<equilibrium::StellarEquilibriumProblem<Model, Discretization>> {
using Problem = equilibrium::StellarEquilibriumProblem<Model, Discretization>;
using Form = typename Problem::FormType;
@@ -131,10 +129,9 @@ export namespace mean_field::preconditioning {
[[nodiscard]] static StellarPreconditionerLifecycleSnapshot Snapshot(const Problem &problem) {
const operators::StellarEquilibriumDependencies &dependencies = problem.GetLinearizationDependencies();
return {
.discretization = dependencies.discretization,
.geometry = problem.GetGeometryDependency(),
.equationOfStateIdentity =
std::addressof(problem.GetStellarModel().equationOfState()),
.discretization = dependencies.discretization,
.geometry = problem.GetGeometryDependency(),
.equationOfStateIdentity = std::addressof(problem.GetStellarModel().equationOfState()),
.linearization = dependencies,
.preparedOperatorGeneration = problem.GetPreparationGeneration()
};
@@ -145,26 +142,20 @@ export namespace mean_field::preconditioning {
concept StellarPreconditionerProblem = StellarEquilibriumProblemTraits<std::remove_cvref_t<Candidate>>::registered;
namespace detail {
template <typename Block>
struct IsGeneratedStellarValueBlock : std::false_type { };
template <typename Block> struct IsGeneratedStellarValueBlock : std::false_type { };
template <typename Generated>
struct IsGeneratedStellarValueBlock<utils::blocks::generated_value_block<Generated>>
: std::true_type { };
struct IsGeneratedStellarValueBlock<utils::blocks::generated_value_block<Generated>> : std::true_type { };
template <typename Block>
struct IsGeneratedStellarResidualBlock : std::false_type { };
template <typename Block> struct IsGeneratedStellarResidualBlock : std::false_type { };
template <typename Generated>
struct IsGeneratedStellarResidualBlock<utils::blocks::generated_residual_block<Generated>>
: std::true_type { };
struct IsGeneratedStellarResidualBlock<utils::blocks::generated_residual_block<Generated>> : std::true_type { };
template <typename Coupling>
inline constexpr bool isPurePhysicalStellarCoupling =
!IsGeneratedStellarValueBlock<
std::remove_cvref_t<typename Coupling::Value>>::value &&
!IsGeneratedStellarResidualBlock<
std::remove_cvref_t<typename Coupling::Residual>>::value;
!IsGeneratedStellarValueBlock<std::remove_cvref_t<typename Coupling::Value>>::value &&
!IsGeneratedStellarResidualBlock<std::remove_cvref_t<typename Coupling::Residual>>::value;
/* Pure structure contributions owned by a trusted backend are exact
* (core, specification, coupling) capabilities. Future cores and new
@@ -172,8 +163,7 @@ export namespace mean_field::preconditioning {
* be accompanied by an explicit preconditioner decision. Generated-
* border terms remain the responsibility of specification-border
* machinery. */
template <typename PhysicalCore, typename Specification>
struct StellarStructureBackendHandledCouplings {
template <typename PhysicalCore, typename Specification> struct StellarStructureBackendHandledCouplings {
using Type = utils::blocks::type_list<>;
};
@@ -213,17 +203,12 @@ export namespace mean_field::preconditioning {
struct StellarStructureBackendHandledCouplings<
operators::PreparedStellarEquilibriumOperator,
models::FixedCentralDensity> {
using Type = utils::blocks::type_list<
operators::StellarEquilibriumJacobianCoupling<
utils::blocks::enthalpy::specific::residual,
utils::blocks::enthalpy::specific::value>>;
using Type = utils::blocks::type_list<operators::StellarEquilibriumJacobianCoupling<
utils::blocks::enthalpy::specific::residual,
utils::blocks::enthalpy::specific::value>>;
};
template <
typename Coupling,
typename Model,
typename PhysicalCore,
typename ModelSpecifications>
template <typename Coupling, typename Model, typename PhysicalCore, typename ModelSpecifications>
struct EveryCouplingContributionHandled;
template <
@@ -235,30 +220,22 @@ export namespace mean_field::preconditioning {
Coupling,
Model,
PhysicalCore,
models::detail::SpecificationSetStorage<Specifications...>> final {
models::detail::SpecificationSetStorage<Specifications...>>
final {
private:
template <typename Specification>
static constexpr bool handled =
!utils::blocks::contains_type_v<
Coupling,
typename operators::StellarEquilibriumSpecificationCompilation<
Specification>::JacobianCouplings> ||
(operators::stellarEquilibriumBackendRuntimeAuthorized<
Specification,
Model> &&
typename operators::StellarEquilibriumSpecificationCompilation<Specification>::JacobianCouplings> ||
(operators::stellarEquilibriumBackendRuntimeAuthorized<Specification, Model> &&
utils::blocks::contains_type_v<
Coupling,
typename StellarStructureBackendHandledCouplings<
PhysicalCore,
Specification>::Type>) ||
operators::stellarEquilibriumSpecificationCouplingIsStructuralZero<
Specification,
Model,
Coupling>;
typename StellarStructureBackendHandledCouplings<PhysicalCore, Specification>::Type>) ||
operators::stellarEquilibriumSpecificationCouplingIsStructuralZero<Specification, Model, Coupling>;
public:
static constexpr bool value =
(handled<Specifications> && ...);
static constexpr bool value = (handled<Specifications> && ...);
};
template <
@@ -269,11 +246,7 @@ export namespace mean_field::preconditioning {
typename Unsupported>
struct CollectUnsupportedStellarStructureCouplings;
template <
typename Model,
typename PhysicalCore,
typename ModelSpecifications,
typename Unsupported>
template <typename Model, typename PhysicalCore, typename ModelSpecifications, typename Unsupported>
struct CollectUnsupportedStellarStructureCouplings<
utils::blocks::type_list<>,
Model,
@@ -299,11 +272,7 @@ export namespace mean_field::preconditioning {
private:
static constexpr bool supported =
!isPurePhysicalStellarCoupling<Head> ||
EveryCouplingContributionHandled<
Head,
Model,
PhysicalCore,
ModelSpecifications>::value;
EveryCouplingContributionHandled<Head, Model, PhysicalCore, ModelSpecifications>::value;
using Next = std::conditional_t<
supported,
utils::blocks::type_list<Unsupported...>,
@@ -318,42 +287,36 @@ export namespace mean_field::preconditioning {
Next>::Type;
};
template <typename Candidate, typename = void>
struct DefaultStellarStructurePhysicalTopologyAudit {
using ContributionCouplings = utils::blocks::type_list<>;
using UnsupportedCouplings = utils::blocks::type_list<>;
template <typename Candidate, typename = void> struct DefaultStellarStructurePhysicalTopologyAudit {
using ContributionCouplings = utils::blocks::type_list<>;
using UnsupportedCouplings = utils::blocks::type_list<>;
static constexpr bool supported = false;
};
template <model::StellarModelType Model>
requires(
operators::StellarEquilibriumSystemCompilable<
std::remove_cvref_t<Model>> &&
operators::hasStellarEquilibriumCoreRuntime<
std::remove_cvref_t<Model>>)
operators::StellarEquilibriumSystemCompilable<std::remove_cvref_t<Model>> &&
operators::hasStellarEquilibriumCoreRuntime<std::remove_cvref_t<Model>>
)
struct DefaultStellarStructurePhysicalTopologyAudit<
Model,
std::void_t<
typename operators::CompiledStellarEquilibriumSystem<
std::remove_cvref_t<Model>>::ContributionJacobianCouplings,
operators::StellarEquilibriumPhysicalCoreType<
std::remove_cvref_t<Model>>>> {
operators::StellarEquilibriumPhysicalCoreType<std::remove_cvref_t<Model>>>> {
private:
using Compilation = operators::CompiledStellarEquilibriumSystem<
std::remove_cvref_t<Model>>;
using PhysicalCore = operators::StellarEquilibriumPhysicalCoreType<
std::remove_cvref_t<Model>>;
using Compilation = operators::CompiledStellarEquilibriumSystem<std::remove_cvref_t<Model>>;
using PhysicalCore = operators::StellarEquilibriumPhysicalCoreType<std::remove_cvref_t<Model>>;
public:
using ContributionCouplings =
typename Compilation::ContributionJacobianCouplings;
using UnsupportedCouplings =
typename CollectUnsupportedStellarStructureCouplings<
ContributionCouplings,
std::remove_cvref_t<Model>,
PhysicalCore,
typename std::remove_cvref_t<Model>::SpecificationTypes,
utils::blocks::type_list<>>::Type;
using ContributionCouplings = typename Compilation::ContributionJacobianCouplings;
using UnsupportedCouplings = typename CollectUnsupportedStellarStructureCouplings<
ContributionCouplings,
std::remove_cvref_t<Model>,
PhysicalCore,
typename std::remove_cvref_t<Model>::SpecificationTypes,
utils::blocks::type_list<>>::Type;
static constexpr bool supported = UnsupportedCouplings::size == 0;
};
@@ -369,13 +332,11 @@ export namespace mean_field::preconditioning {
* detection-safe and therefore suitable for constraining factories. */
template <typename Candidate>
struct DefaultStellarStructurePhysicalTopologySupport
: detail::DefaultStellarStructurePhysicalTopologyAudit<
std::remove_cvref_t<Candidate>> { };
: detail::DefaultStellarStructurePhysicalTopologyAudit<std::remove_cvref_t<Candidate>> { };
template <typename Candidate>
inline constexpr bool defaultStellarStructurePhysicalTopologySupported =
DefaultStellarStructurePhysicalTopologySupport<
std::remove_cvref_t<Candidate>>::supported;
DefaultStellarStructurePhysicalTopologySupport<std::remove_cvref_t<Candidate>>::supported;
template <typename Candidate>
concept DefaultStellarStructurePhysicalTopologySupportedFor =
@@ -419,9 +380,8 @@ export namespace mean_field::preconditioning {
template <typename Form> struct IdentityPlanForForm;
template <typename... Values, typename... Residuals>
struct IdentityPlanForForm<utils::blocks::block_form<
utils::blocks::type_list<Values...>,
utils::blocks::type_list<Residuals...>>> {
struct IdentityPlanForForm<
utils::blocks::block_form<utils::blocks::type_list<Values...>, utils::blocks::type_list<Residuals...>>> {
static_assert(sizeof...(Values) == sizeof...(Residuals));
using Type = PreconditionerPlan<IdentityBlock<Values, Residuals>...>;