feat(newton): first newton solver implementation
This commit is contained in:
@@ -236,15 +236,13 @@ export namespace mean_field::preconditioning {
|
||||
* assembly. The current kernels remain polytropic, but selection no
|
||||
* longer embeds that closed-world type test in the descriptor concept.
|
||||
*/
|
||||
template <typename EquationOfState>
|
||||
struct MaterialSurfaceEquationOfStateBackend {
|
||||
template <typename EquationOfState> struct MaterialSurfaceEquationOfStateBackend {
|
||||
static constexpr bool registered = false;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct MaterialSurfaceEquationOfStateBackend<eos::Polytrope> {
|
||||
template <> struct MaterialSurfaceEquationOfStateBackend<eos::Polytrope> {
|
||||
static constexpr bool registered = true;
|
||||
using CoreType = operators::PreparedStellarEquilibriumOperator;
|
||||
using CoreType = operators::PreparedStellarEquilibriumOperator;
|
||||
};
|
||||
|
||||
template <typename EquationOfState>
|
||||
@@ -252,8 +250,7 @@ export namespace mean_field::preconditioning {
|
||||
{
|
||||
MaterialSurfaceEquationOfStateBackend<std::remove_cvref_t<EquationOfState>>::registered
|
||||
} -> std::convertible_to<bool>;
|
||||
requires MaterialSurfaceEquationOfStateBackend<
|
||||
std::remove_cvref_t<EquationOfState>>::registered;
|
||||
requires MaterialSurfaceEquationOfStateBackend<std::remove_cvref_t<EquationOfState>>::registered;
|
||||
typename MaterialSurfaceEquationOfStateBackend<std::remove_cvref_t<EquationOfState>>::CoreType;
|
||||
};
|
||||
|
||||
@@ -266,13 +263,11 @@ export namespace mean_field::preconditioning {
|
||||
* truthful while the current kernels still consume the legacy physical
|
||||
* core directly.
|
||||
*/
|
||||
template <typename EquationOfState, typename PhysicalCore>
|
||||
struct MaterialSurfaceExecutableRuntime {
|
||||
template <typename EquationOfState, typename PhysicalCore> struct MaterialSurfaceExecutableRuntime {
|
||||
static constexpr bool available = false;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct MaterialSurfaceExecutableRuntime<eos::Polytrope, operators::PreparedStellarEquilibriumOperator> {
|
||||
template <> struct MaterialSurfaceExecutableRuntime<eos::Polytrope, operators::PreparedStellarEquilibriumOperator> {
|
||||
static constexpr bool available = true;
|
||||
};
|
||||
|
||||
@@ -280,33 +275,28 @@ export namespace mean_field::preconditioning {
|
||||
concept ExecutableMaterialSurfaceRuntimeFor = requires {
|
||||
{
|
||||
MaterialSurfaceExecutableRuntime<
|
||||
std::remove_cvref_t<EquationOfState>,
|
||||
std::remove_cvref_t<PhysicalCore>>::available
|
||||
std::remove_cvref_t<EquationOfState>, std::remove_cvref_t<PhysicalCore>>::available
|
||||
} -> std::convertible_to<bool>;
|
||||
requires MaterialSurfaceExecutableRuntime<
|
||||
std::remove_cvref_t<EquationOfState>,
|
||||
std::remove_cvref_t<PhysicalCore>>::available;
|
||||
std::remove_cvref_t<EquationOfState>, std::remove_cvref_t<PhysicalCore>>::available;
|
||||
};
|
||||
|
||||
template <typename Descriptor>
|
||||
concept ImplementedMaterialSurfaceDescriptor =
|
||||
MaterialSurfaceDescriptor<Descriptor> &&
|
||||
ImplementedMaterialSurfaceEquationOfState<
|
||||
typename Descriptor::ThermodynamicEquations::EquationOfStateType>;
|
||||
ImplementedMaterialSurfaceEquationOfState<typename Descriptor::ThermodynamicEquations::EquationOfStateType>;
|
||||
|
||||
template <typename Descriptor, typename PhysicalCore>
|
||||
concept MaterialSurfaceRuntimeFor =
|
||||
ImplementedMaterialSurfaceDescriptor<Descriptor> && requires {
|
||||
concept MaterialSurfaceRuntimeFor = ImplementedMaterialSurfaceDescriptor<Descriptor> && requires {
|
||||
typename MaterialSurfaceEquationOfStateBackend<
|
||||
typename std::remove_cvref_t<Descriptor>::ThermodynamicEquations::EquationOfStateType>::CoreType;
|
||||
requires std::same_as<
|
||||
std::remove_cvref_t<PhysicalCore>,
|
||||
typename MaterialSurfaceEquationOfStateBackend<
|
||||
typename std::remove_cvref_t<Descriptor>::ThermodynamicEquations::EquationOfStateType>::CoreType;
|
||||
requires std::same_as<
|
||||
std::remove_cvref_t<PhysicalCore>,
|
||||
typename MaterialSurfaceEquationOfStateBackend<
|
||||
typename std::remove_cvref_t<Descriptor>::ThermodynamicEquations::EquationOfStateType>::CoreType>;
|
||||
requires ExecutableMaterialSurfaceRuntimeFor<
|
||||
typename std::remove_cvref_t<Descriptor>::ThermodynamicEquations::EquationOfStateType,
|
||||
PhysicalCore>;
|
||||
};
|
||||
typename std::remove_cvref_t<Descriptor>::ThermodynamicEquations::EquationOfStateType>::CoreType>;
|
||||
requires ExecutableMaterialSurfaceRuntimeFor<
|
||||
typename std::remove_cvref_t<Descriptor>::ThermodynamicEquations::EquationOfStateType, PhysicalCore>;
|
||||
};
|
||||
|
||||
template <typename Candidate>
|
||||
concept MaterialSurfacePreconditionerProblem =
|
||||
@@ -778,14 +768,14 @@ export namespace mean_field::preconditioning {
|
||||
fullEnthalpyDirection = enthalpyDirection;
|
||||
|
||||
m_operation->Mult(m_fullDirection, m_fullAction);
|
||||
const auto fullActionView = m_operation->GetRootManifest().residualView(m_fullAction);
|
||||
const auto fullActionView = m_operation->GetRootManifest().residualView(m_fullAction);
|
||||
const auto fullDensityAction = fullActionView.block(utils::blocks::density_field.mass_term);
|
||||
const auto fullSurfaceAction =
|
||||
fullActionView.block(utils::blocks::surface_deformation_field.shape_equilibrium_term);
|
||||
const auto fullEnthalpyAction = fullActionView.block(utils::blocks::enthalpy_field.specific_term);
|
||||
densityAction = fullDensityAction;
|
||||
surfaceAction = fullSurfaceAction;
|
||||
enthalpyAction = fullEnthalpyAction;
|
||||
densityAction = fullDensityAction;
|
||||
surfaceAction = fullSurfaceAction;
|
||||
enthalpyAction = fullEnthalpyAction;
|
||||
}
|
||||
|
||||
void ApplyEnthalpyToDensity(
|
||||
@@ -1121,6 +1111,79 @@ export namespace mean_field::preconditioning {
|
||||
std::uint64_t regularizedEntries{0};
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
[[nodiscard]] inline DiagonalPreparationQuality regularizeMaterialSurfaceDiagonal(
|
||||
mfem::Vector &diagonal,
|
||||
const MaterialSurfaceDiagonalOptions options,
|
||||
const MPI_Comm communicator
|
||||
) {
|
||||
const int localOptionsAreValid = std::isfinite(options.relativeFloor) && options.relativeFloor >= 0.0 &&
|
||||
std::isfinite(options.absoluteFloor) && options.absoluteFloor > 0.0
|
||||
? 1
|
||||
: 0;
|
||||
int globalOptionsAreValid = 0;
|
||||
if (MPI_Allreduce(&localOptionsAreValid, &globalOptionsAreValid, 1, MPI_INT, MPI_MIN, communicator) !=
|
||||
MPI_SUCCESS) {
|
||||
throw std::runtime_error("Material-surface regularization could not validate its options.");
|
||||
}
|
||||
if (globalOptionsAreValid == 0) {
|
||||
throw std::invalid_argument("Material-surface diagonal floors must be finite and nonnegative.");
|
||||
}
|
||||
|
||||
double localMaximum = 0.0;
|
||||
double localMinimum = std::numeric_limits<double>::infinity();
|
||||
int localEntriesAreFinite = 1;
|
||||
for (int index = 0; index < diagonal.Size(); ++index) {
|
||||
if (!std::isfinite(diagonal(index))) {
|
||||
localEntriesAreFinite = 0;
|
||||
continue;
|
||||
}
|
||||
const double magnitude = std::abs(diagonal(index));
|
||||
localMaximum = std::max(localMaximum, magnitude);
|
||||
localMinimum = std::min(localMinimum, magnitude);
|
||||
}
|
||||
|
||||
int globalEntriesAreFinite = 0;
|
||||
if (MPI_Allreduce(&localEntriesAreFinite, &globalEntriesAreFinite, 1, MPI_INT, MPI_MIN, communicator) !=
|
||||
MPI_SUCCESS) {
|
||||
throw std::runtime_error("Material-surface regularization could not validate its diagonal.");
|
||||
}
|
||||
if (globalEntriesAreFinite == 0) {
|
||||
throw std::invalid_argument("A material-surface diagonal contains a non-finite entry.");
|
||||
}
|
||||
|
||||
double globalMaximum = 0.0;
|
||||
double globalMinimum = 0.0;
|
||||
const int maximumStatus =
|
||||
MPI_Allreduce(&localMaximum, &globalMaximum, 1, MPI_DOUBLE, MPI_MAX, communicator);
|
||||
const int minimumStatus =
|
||||
MPI_Allreduce(&localMinimum, &globalMinimum, 1, MPI_DOUBLE, MPI_MIN, communicator);
|
||||
if (maximumStatus != MPI_SUCCESS || minimumStatus != MPI_SUCCESS) {
|
||||
throw std::runtime_error("Material-surface regularization could not reduce diagonal magnitudes.");
|
||||
}
|
||||
const double floor = std::max(options.absoluteFloor, options.relativeFloor * globalMaximum);
|
||||
std::uint64_t localRegularized = 0;
|
||||
for (int index = 0; index < diagonal.Size(); ++index) {
|
||||
if (std::abs(diagonal(index)) < floor) {
|
||||
diagonal(index) = std::copysign(floor, diagonal(index) == 0.0 ? 1.0 : diagonal(index));
|
||||
++localRegularized;
|
||||
}
|
||||
}
|
||||
|
||||
std::uint64_t globalRegularized = 0;
|
||||
if (MPI_Allreduce(&localRegularized, &globalRegularized, 1, MPI_UINT64_T, MPI_SUM, communicator) !=
|
||||
MPI_SUCCESS) {
|
||||
throw std::runtime_error("Material-surface regularization could not count regularized entries.");
|
||||
}
|
||||
return {
|
||||
.minimumAbsoluteEntryBeforeRegularization = globalMinimum,
|
||||
.maximumAbsoluteEntryBeforeRegularization = globalMaximum,
|
||||
.appliedFloor = floor,
|
||||
.regularizedEntries = globalRegularized
|
||||
};
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
struct SurfaceRieszCalibrationReport final {
|
||||
SurfaceRieszCalibrationTarget target{SurfaceRieszCalibrationTarget::none};
|
||||
int probeCount{0};
|
||||
@@ -1522,40 +1585,7 @@ export namespace mean_field::preconditioning {
|
||||
const MaterialSurfaceDiagonalOptions options,
|
||||
const MPI_Comm communicator
|
||||
) {
|
||||
if (!std::isfinite(options.relativeFloor) || options.relativeFloor < 0.0 ||
|
||||
!std::isfinite(options.absoluteFloor) || options.absoluteFloor <= 0.0) {
|
||||
throw std::invalid_argument("Material-surface diagonal floors must be finite and nonnegative.");
|
||||
}
|
||||
double localMaximum = 0.0;
|
||||
double localMinimum = std::numeric_limits<double>::infinity();
|
||||
for (int index = 0; index < diagonal.Size(); ++index) {
|
||||
if (!std::isfinite(diagonal(index))) {
|
||||
throw std::invalid_argument("A material-surface diagonal contains a non-finite entry.");
|
||||
}
|
||||
const double magnitude = std::abs(diagonal(index));
|
||||
localMaximum = std::max(localMaximum, magnitude);
|
||||
localMinimum = std::min(localMinimum, magnitude);
|
||||
}
|
||||
double globalMaximum = 0.0;
|
||||
double globalMinimum = 0.0;
|
||||
MPI_Allreduce(&localMaximum, &globalMaximum, 1, MPI_DOUBLE, MPI_MAX, communicator);
|
||||
MPI_Allreduce(&localMinimum, &globalMinimum, 1, MPI_DOUBLE, MPI_MIN, communicator);
|
||||
const double floor = std::max(options.absoluteFloor, options.relativeFloor * globalMaximum);
|
||||
std::uint64_t localRegularized = 0;
|
||||
for (int index = 0; index < diagonal.Size(); ++index) {
|
||||
if (std::abs(diagonal(index)) < floor) {
|
||||
diagonal(index) = std::copysign(floor, diagonal(index) == 0.0 ? 1.0 : diagonal(index));
|
||||
++localRegularized;
|
||||
}
|
||||
}
|
||||
std::uint64_t globalRegularized = 0;
|
||||
MPI_Allreduce(&localRegularized, &globalRegularized, 1, MPI_UINT64_T, MPI_SUM, communicator);
|
||||
return {
|
||||
.minimumAbsoluteEntryBeforeRegularization = globalMinimum,
|
||||
.maximumAbsoluteEntryBeforeRegularization = globalMaximum,
|
||||
.appliedFloor = floor,
|
||||
.regularizedEntries = globalRegularized
|
||||
};
|
||||
return detail::regularizeMaterialSurfaceDiagonal(diagonal, options, communicator);
|
||||
}
|
||||
|
||||
Block m_block;
|
||||
@@ -2051,40 +2081,7 @@ export namespace mean_field::preconditioning {
|
||||
const MaterialSurfaceDiagonalOptions options,
|
||||
const MPI_Comm communicator
|
||||
) {
|
||||
if (!std::isfinite(options.relativeFloor) || options.relativeFloor < 0.0 ||
|
||||
!std::isfinite(options.absoluteFloor) || options.absoluteFloor <= 0.0) {
|
||||
throw std::invalid_argument("Material-surface diagonal floors must be finite and nonnegative.");
|
||||
}
|
||||
double localMaximum = 0.0;
|
||||
double localMinimum = std::numeric_limits<double>::infinity();
|
||||
for (int index = 0; index < diagonal.Size(); ++index) {
|
||||
if (!std::isfinite(diagonal(index))) {
|
||||
throw std::invalid_argument("A material-surface diagonal contains a non-finite entry.");
|
||||
}
|
||||
const double magnitude = std::abs(diagonal(index));
|
||||
localMaximum = std::max(localMaximum, magnitude);
|
||||
localMinimum = std::min(localMinimum, magnitude);
|
||||
}
|
||||
double globalMaximum = 0.0;
|
||||
double globalMinimum = 0.0;
|
||||
MPI_Allreduce(&localMaximum, &globalMaximum, 1, MPI_DOUBLE, MPI_MAX, communicator);
|
||||
MPI_Allreduce(&localMinimum, &globalMinimum, 1, MPI_DOUBLE, MPI_MIN, communicator);
|
||||
const double floor = std::max(options.absoluteFloor, options.relativeFloor * globalMaximum);
|
||||
std::uint64_t localRegularized = 0;
|
||||
for (int index = 0; index < diagonal.Size(); ++index) {
|
||||
if (std::abs(diagonal(index)) < floor) {
|
||||
diagonal(index) = std::copysign(floor, diagonal(index) == 0.0 ? 1.0 : diagonal(index));
|
||||
++localRegularized;
|
||||
}
|
||||
}
|
||||
std::uint64_t globalRegularized = 0;
|
||||
MPI_Allreduce(&localRegularized, &globalRegularized, 1, MPI_UINT64_T, MPI_SUM, communicator);
|
||||
return {
|
||||
.minimumAbsoluteEntryBeforeRegularization = globalMinimum,
|
||||
.maximumAbsoluteEntryBeforeRegularization = globalMaximum,
|
||||
.appliedFloor = floor,
|
||||
.regularizedEntries = globalRegularized
|
||||
};
|
||||
return detail::regularizeMaterialSurfaceDiagonal(diagonal, options, communicator);
|
||||
}
|
||||
|
||||
Block m_block;
|
||||
@@ -2111,7 +2108,9 @@ export namespace mean_field::preconditioning {
|
||||
template <
|
||||
MaterialSurfaceDescriptor Descriptor,
|
||||
MaterialSurfaceFactorizationPolicy Policy>
|
||||
requires MaterialSurfaceRuntimeFor<Descriptor, operators::PreparedStellarEquilibriumOperator>
|
||||
requires MaterialSurfaceRuntimeFor<
|
||||
Descriptor,
|
||||
operators::PreparedStellarEquilibriumOperator>
|
||||
[[nodiscard]] auto prepare(
|
||||
const operators::PreparedStellarEquilibriumOperator &operation,
|
||||
MaterialSurfaceBlock<
|
||||
@@ -2127,12 +2126,17 @@ export namespace mean_field::preconditioning {
|
||||
equilibrium::StellarEquilibriumModel Model,
|
||||
equilibrium::StellarDiscretizationType Discretization,
|
||||
MaterialSurfaceFactorizationPolicy Policy>
|
||||
requires MaterialSurfacePreconditionerProblem<
|
||||
equilibrium::StellarEquilibriumProblem<Model, Discretization>>
|
||||
requires MaterialSurfacePreconditionerProblem<equilibrium::StellarEquilibriumProblem<
|
||||
Model,
|
||||
Discretization>>
|
||||
[[nodiscard]] auto prepare(
|
||||
const equilibrium::StellarEquilibriumProblem<Model, Discretization> &problem,
|
||||
const equilibrium::StellarEquilibriumProblem<
|
||||
Model,
|
||||
Discretization> &problem,
|
||||
MaterialSurfaceBlock<
|
||||
MaterialSurfaceDescriptorFor<equilibrium::StellarEquilibriumProblem<Model, Discretization>>,
|
||||
MaterialSurfaceDescriptorFor<equilibrium::StellarEquilibriumProblem<
|
||||
Model,
|
||||
Discretization>>,
|
||||
backend::Diagonal,
|
||||
backend::Diagonal,
|
||||
Policy> block
|
||||
@@ -2144,7 +2148,9 @@ export namespace mean_field::preconditioning {
|
||||
MaterialSurfaceDescriptor Descriptor,
|
||||
MaterialSurfaceFactorizationPolicy Policy,
|
||||
backend::ApplicationMode Mode>
|
||||
requires MaterialSurfaceRuntimeFor<Descriptor, operators::PreparedStellarEquilibriumOperator>
|
||||
requires MaterialSurfaceRuntimeFor<
|
||||
Descriptor,
|
||||
operators::PreparedStellarEquilibriumOperator>
|
||||
[[nodiscard]] auto prepare(
|
||||
const operators::PreparedStellarEquilibriumOperator &operation,
|
||||
MaterialSurfaceBlock<
|
||||
@@ -2162,12 +2168,17 @@ export namespace mean_field::preconditioning {
|
||||
equilibrium::StellarDiscretizationType Discretization,
|
||||
MaterialSurfaceFactorizationPolicy Policy,
|
||||
backend::ApplicationMode Mode>
|
||||
requires MaterialSurfacePreconditionerProblem<
|
||||
equilibrium::StellarEquilibriumProblem<Model, Discretization>>
|
||||
requires MaterialSurfacePreconditionerProblem<equilibrium::StellarEquilibriumProblem<
|
||||
Model,
|
||||
Discretization>>
|
||||
[[nodiscard]] auto prepare(
|
||||
const equilibrium::StellarEquilibriumProblem<Model, Discretization> &problem,
|
||||
const equilibrium::StellarEquilibriumProblem<
|
||||
Model,
|
||||
Discretization> &problem,
|
||||
MaterialSurfaceBlock<
|
||||
MaterialSurfaceDescriptorFor<equilibrium::StellarEquilibriumProblem<Model, Discretization>>,
|
||||
MaterialSurfaceDescriptorFor<equilibrium::StellarEquilibriumProblem<
|
||||
Model,
|
||||
Discretization>>,
|
||||
backend::Diagonal,
|
||||
backend::HypreBoomerAMG<Mode>,
|
||||
Policy,
|
||||
|
||||
Reference in New Issue
Block a user