feat(newton): first newton solver implementation
This commit is contained in:
83
libmeanfield/interface/preconditioning/stellar_recipe.cppm
Normal file
83
libmeanfield/interface/preconditioning/stellar_recipe.cppm
Normal file
@@ -0,0 +1,83 @@
|
||||
module;
|
||||
|
||||
#include <concepts>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <mfem.hpp>
|
||||
|
||||
export module mean_field:preconditioning.stellar_recipe;
|
||||
|
||||
export import :preconditioning.equilibrium_coordinates;
|
||||
|
||||
export namespace mean_field::preconditioning {
|
||||
/*
|
||||
* A stellar-preconditioner prescription is an unbound, owning value. It
|
||||
* may therefore be created before a problem exists and safely moved into
|
||||
* the eventual user-owned solve context. A prepared inverse is deliberately a
|
||||
* separate, problem-bound object with a stable address.
|
||||
*/
|
||||
struct StellarPreconditionerPrescriptionTag { };
|
||||
|
||||
template <typename Candidate>
|
||||
concept StellarPreconditionerPrescription =
|
||||
std::derived_from<std::remove_cvref_t<Candidate>, StellarPreconditionerPrescriptionTag> &&
|
||||
std::move_constructible<std::remove_cvref_t<Candidate>>;
|
||||
|
||||
struct DefaultStellarPreconditioner final : StellarPreconditionerPrescriptionTag { };
|
||||
|
||||
/*
|
||||
* This overload is the user-facing, problem-independent factory. The
|
||||
* existing makePreconditioner(problem) overload remains the low-level
|
||||
* factory for the typed, unprepared block assembled below.
|
||||
*/
|
||||
[[nodiscard]] constexpr DefaultStellarPreconditioner makePreconditioner() noexcept {
|
||||
return {};
|
||||
}
|
||||
|
||||
template <typename Candidate, typename Problem>
|
||||
concept PreparedStellarInverseFor =
|
||||
equilibrium::DiscretizedStellarEquilibriumProblem<std::remove_cvref_t<Problem>> &&
|
||||
std::derived_from<std::remove_cvref_t<Candidate>, mfem::Solver> &&
|
||||
std::destructible<std::remove_cvref_t<Candidate>> &&
|
||||
requires(std::remove_cvref_t<Candidate> &prepared, const std::remove_cvref_t<Candidate> &constantPrepared) {
|
||||
{ constantPrepared.GetProblem() } -> std::same_as<const std::remove_cvref_t<Problem> &>;
|
||||
{ constantPrepared.IsCurrent() } -> std::same_as<bool>;
|
||||
prepared.Refresh();
|
||||
};
|
||||
|
||||
/*
|
||||
* Built-in preparation is intentionally policy-first. The same spelling
|
||||
* can be supplied beside a third-party prescription and found by ADL,
|
||||
* without adding that prescription to a central registry or switch.
|
||||
* Preparation requires an already-prepared problem because the current
|
||||
* physical inverse assembles state-dependent numerical data.
|
||||
*/
|
||||
template <DefaultStellarPreconditionerAvailableFor Problem>
|
||||
[[nodiscard]] auto prepareStellarPreconditioner(
|
||||
DefaultStellarPreconditioner,
|
||||
const Problem &problem
|
||||
) {
|
||||
return preconditioning::prepare(problem, preconditioning::makePreconditioner(problem));
|
||||
}
|
||||
|
||||
template <typename Prescription, typename Problem>
|
||||
concept StellarPreconditionerRuntimeAvailableFor =
|
||||
StellarPreconditionerPrescription<Prescription> &&
|
||||
equilibrium::DiscretizedStellarEquilibriumProblem<std::remove_cvref_t<Problem>> &&
|
||||
requires(std::remove_cvref_t<Prescription> prescription, const std::remove_cvref_t<Problem> &problem) {
|
||||
requires std::same_as<
|
||||
decltype(prepareStellarPreconditioner(std::move(prescription), problem)),
|
||||
std::remove_cvref_t<decltype(prepareStellarPreconditioner(std::move(prescription), problem))>>;
|
||||
{
|
||||
prepareStellarPreconditioner(std::move(prescription), problem)
|
||||
} -> PreparedStellarInverseFor<std::remove_cvref_t<Problem>>;
|
||||
};
|
||||
|
||||
template <StellarPreconditionerPrescription Prescription, typename Problem>
|
||||
requires StellarPreconditionerRuntimeAvailableFor<Prescription, Problem>
|
||||
using PreparedStellarInverseType = std::remove_cvref_t<decltype(prepareStellarPreconditioner(
|
||||
std::declval<std::remove_cvref_t<Prescription> &&>(),
|
||||
std::declval<const std::remove_cvref_t<Problem> &>()
|
||||
))>;
|
||||
} // namespace mean_field::preconditioning
|
||||
Reference in New Issue
Block a user