feat(newton): first newton solver implementation
This commit is contained in:
@@ -3,6 +3,7 @@ module;
|
||||
#include <concepts>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <expected>
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
@@ -28,12 +29,11 @@ export namespace mean_field::equilibrium {
|
||||
static constexpr bool complete = false;
|
||||
};
|
||||
|
||||
template <model::StellarModelType Model>
|
||||
struct StellarSurfaceCompilationAudit<Model, true> {
|
||||
template <model::StellarModelType Model> struct StellarSurfaceCompilationAudit<Model, true> {
|
||||
private:
|
||||
using ModelType = std::remove_cvref_t<Model>;
|
||||
using EquationOfState = typename ModelType::EquationOfStateType;
|
||||
using Form = operators::CompiledStellarEquilibriumForm<ModelType>;
|
||||
using ModelType = std::remove_cvref_t<Model>;
|
||||
using EquationOfState = typename ModelType::EquationOfStateType;
|
||||
using Form = operators::CompiledStellarEquilibriumForm<ModelType>;
|
||||
using AvailableEquations = material::StellarEquilibriumThermodynamicEquations;
|
||||
|
||||
static constexpr bool thermodynamicsCompilable =
|
||||
@@ -46,14 +46,12 @@ export namespace mean_field::equilibrium {
|
||||
} else {
|
||||
using ThermodynamicEquations =
|
||||
material::CompiledThermodynamicEquationsT<EquationOfState, Form, AvailableEquations>;
|
||||
using Formulation = typename ThermodynamicEquations::PressureSurfaceFormulation;
|
||||
using CompiledSurface =
|
||||
surface::CompiledPressureSurfaceConstraintT<Formulation, EquationOfState>;
|
||||
using Formulation = typename ThermodynamicEquations::PressureSurfaceFormulation;
|
||||
using CompiledSurface = surface::CompiledPressureSurfaceConstraintT<Formulation, EquationOfState>;
|
||||
return requires(const ModelType &model) {
|
||||
{
|
||||
surface::compilePressureSurfaceConstraint<Formulation>(
|
||||
model.surfaceCondition(),
|
||||
model.equationOfState()
|
||||
model.surfaceCondition(), model.equationOfState()
|
||||
)
|
||||
} -> std::same_as<CompiledSurface>;
|
||||
};
|
||||
@@ -77,8 +75,7 @@ export namespace mean_field::equilibrium {
|
||||
requires operators::StellarEquilibriumSystemCompilable<std::remove_cvref_t<Candidate>>;
|
||||
requires hasStellarEquilibriumSurfaceCompilation<std::remove_cvref_t<Candidate>>;
|
||||
requires operators::CompilableRootManifestFor<
|
||||
std::remove_cvref_t<Candidate>,
|
||||
operators::CompiledStellarEquilibriumForm<std::remove_cvref_t<Candidate>>>;
|
||||
std::remove_cvref_t<Candidate>, operators::CompiledStellarEquilibriumForm<std::remove_cvref_t<Candidate>>>;
|
||||
requires operators::hasStellarEquilibriumCoreRuntime<std::remove_cvref_t<Candidate>>;
|
||||
requires operators::hasCompleteStellarEquilibriumRuntime<std::remove_cvref_t<Candidate>>;
|
||||
requires operators::stellarEquilibriumRotationProviderCount<std::remove_cvref_t<Candidate>> <= 1;
|
||||
@@ -105,19 +102,16 @@ export namespace mean_field::equilibrium {
|
||||
operators::StellarEquilibriumPhysicalCoreType<std::remove_cvref_t<Model>>,
|
||||
typename std::remove_cvref_t<Model>::SpecificationTypes>> { };
|
||||
|
||||
struct StellarEquilibriumProblemFactory;
|
||||
} // namespace detail
|
||||
|
||||
template <
|
||||
StellarEquilibriumModel Model,
|
||||
StellarDiscretizationType Discretization = StellarDiscretization>
|
||||
template <StellarEquilibriumModel Model, StellarDiscretizationType Discretization = StellarDiscretization>
|
||||
requires detail::StellarEquilibriumModelDiscretizationStructureAudit<
|
||||
std::remove_cvref_t<Model>,
|
||||
std::remove_cvref_t<Discretization>>::value
|
||||
class StellarEquilibriumProblem final {
|
||||
public:
|
||||
using ModelType = std::remove_cvref_t<Model>;
|
||||
using DiscretizationType = std::remove_cvref_t<Discretization>;
|
||||
using ModelType = std::remove_cvref_t<Model>;
|
||||
using DiscretizationType = std::remove_cvref_t<Discretization>;
|
||||
using NormalizationPrescriptionType = typename DiscretizationType::NormalizationPrescriptionType;
|
||||
|
||||
static constexpr bool hasFixedCentralDensity =
|
||||
@@ -128,13 +122,15 @@ export namespace mean_field::equilibrium {
|
||||
operators::stellarEquilibriumRotationProviderCount<ModelType>;
|
||||
static constexpr bool symbolicallySquare = ModelType::symbolicallySquare;
|
||||
|
||||
using PreparedOperatorType = operators::PreparedVariadicStellarEquilibriumOperator<ModelType>;
|
||||
using PhysicalCoreType = typename PreparedOperatorType::PhysicalCoreType;
|
||||
using FormType = operators::CompiledStellarEquilibriumForm<ModelType>;
|
||||
using JacobianFormType = operators::CompiledStellarEquilibriumJacobianForm<ModelType>;
|
||||
using ManifestType = operators::EquilibriumSystemManifest<ModelType, FormType, JacobianFormType>;
|
||||
using EquationOfStateType = model::EquationOfStateType<ModelType>;
|
||||
using SurfaceConditionType = model::SurfaceConditionType<ModelType>;
|
||||
using PreparedOperatorType = operators::PreparedVariadicStellarEquilibriumOperator<ModelType>;
|
||||
using Report = typename PreparedOperatorType::Report;
|
||||
using PreparationResult = typename PreparedOperatorType::PreparationResult;
|
||||
using PhysicalCoreType = typename PreparedOperatorType::PhysicalCoreType;
|
||||
using FormType = operators::CompiledStellarEquilibriumForm<ModelType>;
|
||||
using JacobianFormType = operators::CompiledStellarEquilibriumJacobianForm<ModelType>;
|
||||
using ManifestType = operators::EquilibriumSystemManifest<ModelType, FormType, JacobianFormType>;
|
||||
using EquationOfStateType = model::EquationOfStateType<ModelType>;
|
||||
using SurfaceConditionType = model::SurfaceConditionType<ModelType>;
|
||||
using AvailableThermodynamicEquations = material::StellarEquilibriumThermodynamicEquations;
|
||||
using ThermodynamicEquationsType =
|
||||
material::CompiledThermodynamicEquationsT<EquationOfStateType, FormType, AvailableThermodynamicEquations>;
|
||||
@@ -147,17 +143,18 @@ export namespace mean_field::equilibrium {
|
||||
|
||||
StellarEquilibriumProblem(
|
||||
ModelType stellarModel,
|
||||
DiscretizationType discretization
|
||||
DiscretizationType discretization,
|
||||
fem::FEM &finiteElementModel
|
||||
)
|
||||
: m_stellarModel(std::make_shared<ModelType>(std::move(stellarModel))),
|
||||
m_discretization(std::move(discretization)),
|
||||
m_compiledSurfaceConstraint(CompileSurfaceConstraint(*m_stellarModel)),
|
||||
m_preparedOperator(
|
||||
m_discretization.finiteElementModel(),
|
||||
finiteElementModel,
|
||||
m_discretization.domainMapper(),
|
||||
m_stellarModel,
|
||||
operators::PressureSurfaceConstraintView{m_compiledSurfaceConstraint},
|
||||
CompileDefaultDomainDeformation(m_discretization.finiteElementModel())
|
||||
CompileDefaultDomainDeformation(finiteElementModel)
|
||||
) {
|
||||
VerifyProblem();
|
||||
}
|
||||
@@ -176,6 +173,12 @@ export namespace mean_field::equilibrium {
|
||||
return m_discretization;
|
||||
}
|
||||
|
||||
[[nodiscard]] MPI_Comm GetCommunicator() const & {
|
||||
return m_discretization.communicator();
|
||||
}
|
||||
|
||||
[[nodiscard]] MPI_Comm GetCommunicator() const && = delete;
|
||||
|
||||
[[nodiscard]] const NormalizationPrescriptionType &GetNormalizationPrescription() const noexcept {
|
||||
return m_discretization.normalizationPrescription();
|
||||
}
|
||||
@@ -236,21 +239,54 @@ export namespace mean_field::equilibrium {
|
||||
const mfem::Vector &state,
|
||||
const operators::StellarEquilibriumDependencies &dependencies,
|
||||
const physics::RigidRotation &rotation
|
||||
) requires(generatedRotationProviderCount == 0) {
|
||||
)
|
||||
requires(generatedRotationProviderCount == 0)
|
||||
{
|
||||
auto report = m_preparedOperator.Prepare(state, dependencies, rotation);
|
||||
++m_preparationGeneration;
|
||||
return report;
|
||||
}
|
||||
|
||||
[[nodiscard]] PreparationResult TryPrepare(
|
||||
const mfem::Vector &state,
|
||||
const operators::StellarEquilibriumDependencies &dependencies,
|
||||
const physics::RigidRotation &rotation
|
||||
)
|
||||
requires(generatedRotationProviderCount == 0)
|
||||
{
|
||||
auto result = m_preparedOperator.TryPrepare(state, dependencies, rotation);
|
||||
if (!result.has_value()) {
|
||||
return std::unexpected(result.error());
|
||||
}
|
||||
++m_preparationGeneration;
|
||||
return result;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto Prepare(
|
||||
const mfem::Vector &state,
|
||||
const operators::StellarEquilibriumDependencies &dependencies
|
||||
) requires(generatedRotationProviderCount == 1) {
|
||||
)
|
||||
requires(generatedRotationProviderCount == 1)
|
||||
{
|
||||
auto report = m_preparedOperator.Prepare(state, dependencies);
|
||||
++m_preparationGeneration;
|
||||
return report;
|
||||
}
|
||||
|
||||
[[nodiscard]] PreparationResult TryPrepare(
|
||||
const mfem::Vector &state,
|
||||
const operators::StellarEquilibriumDependencies &dependencies
|
||||
)
|
||||
requires(generatedRotationProviderCount == 1)
|
||||
{
|
||||
auto result = m_preparedOperator.TryPrepare(state, dependencies);
|
||||
if (!result.has_value()) {
|
||||
return std::unexpected(result.error());
|
||||
}
|
||||
++m_preparationGeneration;
|
||||
return result;
|
||||
}
|
||||
|
||||
void BuildResidual(mfem::Vector &residual) const {
|
||||
m_preparedOperator.BuildResidual(residual);
|
||||
}
|
||||
@@ -266,8 +302,7 @@ export namespace mean_field::equilibrium {
|
||||
[[nodiscard]] static CompiledSurfaceConstraintType CompileSurfaceConstraint(const ModelType &stellarModel) {
|
||||
return surface::compilePressureSurfaceConstraint<
|
||||
typename ThermodynamicEquationsType::PressureSurfaceFormulation>(
|
||||
stellarModel.surfaceCondition(),
|
||||
stellarModel.equationOfState()
|
||||
stellarModel.surfaceCondition(), stellarModel.equationOfState()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -318,28 +353,25 @@ export namespace mean_field::equilibrium {
|
||||
template <
|
||||
typename Model,
|
||||
typename Discretization,
|
||||
bool StructurallyCompatible =
|
||||
StellarEquilibriumModelDiscretizationStructureAudit<
|
||||
std::remove_cvref_t<Model>,
|
||||
std::remove_cvref_t<Discretization>>::value>
|
||||
bool StructurallyCompatible = StellarEquilibriumModelDiscretizationStructureAudit<
|
||||
std::remove_cvref_t<Model>,
|
||||
std::remove_cvref_t<Discretization>>::value>
|
||||
struct StellarEquilibriumModelDiscretizationOperationAudit : std::false_type { };
|
||||
|
||||
template <typename Model, typename Discretization>
|
||||
struct StellarEquilibriumModelDiscretizationOperationAudit<
|
||||
Model,
|
||||
Discretization,
|
||||
true> {
|
||||
struct StellarEquilibriumModelDiscretizationOperationAudit<Model, Discretization, true> {
|
||||
private:
|
||||
using ModelType = std::remove_cvref_t<Model>;
|
||||
using ModelType = std::remove_cvref_t<Model>;
|
||||
using DiscretizationType = std::remove_cvref_t<Discretization>;
|
||||
using Problem = StellarEquilibriumProblem<ModelType, DiscretizationType>;
|
||||
using Prescription = typename DiscretizationType::NormalizationPrescriptionType;
|
||||
using Problem = StellarEquilibriumProblem<ModelType, DiscretizationType>;
|
||||
using Prescription = typename DiscretizationType::NormalizationPrescriptionType;
|
||||
|
||||
public:
|
||||
static constexpr bool value = [] {
|
||||
if constexpr (
|
||||
std::same_as<Prescription, normalization::Unnormalized> ||
|
||||
normalization::PhysicalRieszDiagonalPrescription<Prescription>) {
|
||||
normalization::PhysicalRieszDiagonalPrescription<Prescription>
|
||||
) {
|
||||
return true;
|
||||
} else {
|
||||
return normalization::RuntimePreparedNormalizationOperation<Problem>;
|
||||
@@ -362,46 +394,99 @@ export namespace mean_field::equilibrium {
|
||||
std::remove_cvref_t<Model>,
|
||||
std::remove_cvref_t<Discretization>>::value;
|
||||
|
||||
namespace detail {
|
||||
/* The structurally formed problem type is needed to probe the ADL
|
||||
* operation without a recursive concept. Its constructor remains
|
||||
* private, and this factory is the single construction authority after
|
||||
* the complete public compatibility contract has succeeded. */
|
||||
struct StellarEquilibriumProblemFactory final {
|
||||
template <StellarEquilibriumModel Model, StellarDiscretizationType Discretization>
|
||||
requires StellarEquilibriumModelDiscretizationCompatible<Model, Discretization>
|
||||
[[nodiscard]] static auto Create(
|
||||
Model &&stellarModel,
|
||||
Discretization discretization
|
||||
) {
|
||||
using ModelType = std::remove_cvref_t<Model>;
|
||||
using DiscretizationType = std::remove_cvref_t<Discretization>;
|
||||
return StellarEquilibriumProblem<ModelType, DiscretizationType>{
|
||||
std::forward<Model>(stellarModel),
|
||||
std::move(discretization)
|
||||
};
|
||||
}
|
||||
};
|
||||
} // namespace detail
|
||||
} // namespace mean_field::equilibrium
|
||||
|
||||
template <StellarEquilibriumModel Model, StellarDiscretizationType Discretization>
|
||||
requires StellarEquilibriumModelDiscretizationCompatible<Model, Discretization>
|
||||
namespace mean_field::equilibrium::detail {
|
||||
/* The structurally formed problem type is needed to probe the ADL
|
||||
* operation without a recursive concept. Its constructor remains
|
||||
* private, and this factory is the single construction authority after
|
||||
* the complete public compatibility contract has succeeded. */
|
||||
struct StellarEquilibriumProblemFactory final {
|
||||
template <
|
||||
StellarEquilibriumModel Model,
|
||||
StellarDiscretizationType Discretization>
|
||||
requires StellarEquilibriumModelDiscretizationCompatible<
|
||||
Model,
|
||||
Discretization>
|
||||
[[nodiscard]] static auto Create(
|
||||
Model &&stellarModel,
|
||||
Discretization discretization
|
||||
) {
|
||||
using ModelType = std::remove_cvref_t<Model>;
|
||||
using DiscretizationType = std::remove_cvref_t<Discretization>;
|
||||
fem::FEM &finiteElementModel = discretization.MutableFiniteElementModelForAssembly();
|
||||
return StellarEquilibriumProblem<ModelType, DiscretizationType>{
|
||||
std::forward<Model>(stellarModel), std::move(discretization), finiteElementModel
|
||||
};
|
||||
}
|
||||
|
||||
template <
|
||||
StellarEquilibriumModel Model,
|
||||
StellarDiscretizationType Discretization>
|
||||
requires StellarEquilibriumModelDiscretizationCompatible<
|
||||
Model,
|
||||
Discretization>
|
||||
[[nodiscard]] static auto CreateOwned(
|
||||
Model &&stellarModel,
|
||||
Discretization discretization
|
||||
) {
|
||||
using ModelType = std::remove_cvref_t<Model>;
|
||||
using DiscretizationType = std::remove_cvref_t<Discretization>;
|
||||
using ProblemType = StellarEquilibriumProblem<ModelType, DiscretizationType>;
|
||||
fem::FEM &finiteElementModel = discretization.MutableFiniteElementModelForAssembly();
|
||||
return std::unique_ptr<ProblemType>{
|
||||
new ProblemType{std::forward<Model>(stellarModel), std::move(discretization), finiteElementModel}
|
||||
};
|
||||
}
|
||||
|
||||
template <DiscretizedStellarEquilibriumProblem Problem>
|
||||
[[nodiscard]] static fem::FEM &MutableFiniteElementModelForProjection(Problem &problem) {
|
||||
return problem.m_discretization.MutableFiniteElementModelForAssembly();
|
||||
}
|
||||
|
||||
template <DiscretizedStellarEquilibriumProblem Problem>
|
||||
[[nodiscard]] static const fem::FEM &FiniteElementModel(const Problem &problem) {
|
||||
return problem.m_discretization.RequireFiniteElementModel();
|
||||
}
|
||||
};
|
||||
} // namespace mean_field::equilibrium::detail
|
||||
|
||||
export namespace mean_field::equilibrium {
|
||||
template <
|
||||
StellarEquilibriumModel Model,
|
||||
StellarDiscretizationType Discretization>
|
||||
requires StellarEquilibriumModelDiscretizationCompatible<
|
||||
Model,
|
||||
Discretization>
|
||||
[[nodiscard]] auto discretize(
|
||||
Model &&stellarModel,
|
||||
Discretization discretization
|
||||
) {
|
||||
return detail::StellarEquilibriumProblemFactory::Create(
|
||||
std::forward<Model>(stellarModel),
|
||||
std::move(discretization)
|
||||
std::forward<Model>(stellarModel), std::move(discretization)
|
||||
);
|
||||
}
|
||||
|
||||
template <StellarEquilibriumModel Model>
|
||||
requires StellarEquilibriumModelDiscretizationCompatible<Model, StellarDiscretization>
|
||||
requires StellarEquilibriumModelDiscretizationCompatible<
|
||||
Model,
|
||||
StellarDiscretization>
|
||||
[[nodiscard]] auto discretize(
|
||||
Model &&stellarModel,
|
||||
fem::FEM &finiteElementModel
|
||||
fem::FEM &&finiteElementModel
|
||||
) {
|
||||
return discretize(std::forward<Model>(stellarModel), StellarDiscretization{finiteElementModel});
|
||||
return discretize(std::forward<Model>(stellarModel), StellarDiscretization{std::move(finiteElementModel)});
|
||||
}
|
||||
|
||||
template <StellarEquilibriumModel Model>
|
||||
requires StellarEquilibriumModelDiscretizationCompatible<
|
||||
Model,
|
||||
StellarDiscretization>
|
||||
StellarEquilibriumProblem<
|
||||
std::remove_cvref_t<Model>,
|
||||
StellarDiscretization>
|
||||
discretize(
|
||||
Model &&,
|
||||
fem::FEM &
|
||||
) = delete;
|
||||
} // namespace mean_field::equilibrium
|
||||
|
||||
Reference in New Issue
Block a user