feat(libmeanfield): variadic refactor
also added normaliztion operator
This commit is contained in:
@@ -24,6 +24,7 @@ export namespace mean_field::preconditioning {
|
||||
operators::StellarEquilibriumDependencyStamp geometry;
|
||||
const void *equationOfStateIdentity{nullptr};
|
||||
operators::StellarEquilibriumDependencies linearization;
|
||||
std::uint64_t preparedOperatorGeneration{0};
|
||||
|
||||
constexpr bool operator==(const StellarPreconditionerLifecycleSnapshot &) const = default;
|
||||
};
|
||||
@@ -61,7 +62,8 @@ export namespace mean_field::preconditioning {
|
||||
.discretization = prepared.discretization != current.discretization,
|
||||
.geometry = prepared.geometry != current.geometry,
|
||||
.equationOfState = prepared.equationOfStateIdentity != current.equationOfStateIdentity,
|
||||
.linearization = prepared.linearization != current.linearization
|
||||
.linearization = prepared.linearization != current.linearization ||
|
||||
prepared.preparedOperatorGeneration != current.preparedOperatorGeneration
|
||||
};
|
||||
}
|
||||
|
||||
@@ -95,9 +97,11 @@ export namespace mean_field::preconditioning {
|
||||
static constexpr bool registered = false;
|
||||
};
|
||||
|
||||
template <equilibrium::StellarEquilibriumModel Model>
|
||||
struct StellarEquilibriumProblemTraits<equilibrium::StellarEquilibriumProblem<Model>> {
|
||||
using Problem = equilibrium::StellarEquilibriumProblem<Model>;
|
||||
template <
|
||||
equilibrium::StellarEquilibriumModel Model,
|
||||
equilibrium::StellarDiscretizationType Discretization>
|
||||
struct StellarEquilibriumProblemTraits<equilibrium::StellarEquilibriumProblem<Model, Discretization>> {
|
||||
using Problem = equilibrium::StellarEquilibriumProblem<Model, Discretization>;
|
||||
using Form = typename Problem::FormType;
|
||||
using JacobianForm = typename Problem::JacobianFormType;
|
||||
using Manifest = typename Problem::ManifestType;
|
||||
@@ -130,8 +134,9 @@ export namespace mean_field::preconditioning {
|
||||
.discretization = dependencies.discretization,
|
||||
.geometry = problem.GetGeometryDependency(),
|
||||
.equationOfStateIdentity =
|
||||
std::addressof(problem.GetStellarModel().template specification<eos::Polytrope>()),
|
||||
.linearization = dependencies
|
||||
std::addressof(problem.GetStellarModel().equationOfState()),
|
||||
.linearization = dependencies,
|
||||
.preparedOperatorGeneration = problem.GetPreparationGeneration()
|
||||
};
|
||||
}
|
||||
};
|
||||
@@ -139,6 +144,243 @@ export namespace mean_field::preconditioning {
|
||||
template <typename Candidate>
|
||||
concept StellarPreconditionerProblem = StellarEquilibriumProblemTraits<std::remove_cvref_t<Candidate>>::registered;
|
||||
|
||||
namespace detail {
|
||||
template <typename Block>
|
||||
struct IsGeneratedStellarValueBlock : std::false_type { };
|
||||
|
||||
template <typename Generated>
|
||||
struct IsGeneratedStellarValueBlock<utils::blocks::generated_value_block<Generated>>
|
||||
: std::true_type { };
|
||||
|
||||
template <typename Block>
|
||||
struct IsGeneratedStellarResidualBlock : std::false_type { };
|
||||
|
||||
template <typename Generated>
|
||||
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;
|
||||
|
||||
/* Pure structure contributions owned by a trusted backend are exact
|
||||
* (core, specification, coupling) capabilities. Future cores and new
|
||||
* edges start with no privilege: changing a built-in declaration must
|
||||
* be accompanied by an explicit preconditioner decision. Generated-
|
||||
* border terms remain the responsibility of specification-border
|
||||
* machinery. */
|
||||
template <typename PhysicalCore, typename Specification>
|
||||
struct StellarStructureBackendHandledCouplings {
|
||||
using Type = utils::blocks::type_list<>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct StellarStructureBackendHandledCouplings<
|
||||
operators::PreparedStellarEquilibriumOperator,
|
||||
models::FixedTotalMass> {
|
||||
using Type = utils::blocks::type_list<
|
||||
operators::StellarEquilibriumJacobianCoupling<
|
||||
utils::blocks::enthalpy::specific::residual,
|
||||
utils::blocks::density::mass::value>,
|
||||
operators::StellarEquilibriumJacobianCoupling<
|
||||
utils::blocks::enthalpy::specific::residual,
|
||||
utils::blocks::surface_deformation::parameters::value>>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct StellarStructureBackendHandledCouplings<
|
||||
operators::PreparedStellarEquilibriumOperator,
|
||||
models::FixedAngularMomentum> {
|
||||
using Type = utils::blocks::type_list<
|
||||
operators::StellarEquilibriumJacobianCoupling<
|
||||
utils::blocks::surface_deformation::shape_equilibrium::residual,
|
||||
utils::blocks::density::mass::value>,
|
||||
operators::StellarEquilibriumJacobianCoupling<
|
||||
utils::blocks::surface_deformation::shape_equilibrium::residual,
|
||||
utils::blocks::surface_deformation::parameters::value>,
|
||||
operators::StellarEquilibriumJacobianCoupling<
|
||||
utils::blocks::enthalpy::specific::residual,
|
||||
utils::blocks::density::mass::value>,
|
||||
operators::StellarEquilibriumJacobianCoupling<
|
||||
utils::blocks::enthalpy::specific::residual,
|
||||
utils::blocks::surface_deformation::parameters::value>>;
|
||||
};
|
||||
|
||||
template <>
|
||||
struct StellarStructureBackendHandledCouplings<
|
||||
operators::PreparedStellarEquilibriumOperator,
|
||||
models::FixedCentralDensity> {
|
||||
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>
|
||||
struct EveryCouplingContributionHandled;
|
||||
|
||||
template <
|
||||
typename Coupling,
|
||||
model::StellarModelType Model,
|
||||
typename PhysicalCore,
|
||||
models::ModelSpecification... Specifications>
|
||||
struct EveryCouplingContributionHandled<
|
||||
Coupling,
|
||||
Model,
|
||||
PhysicalCore,
|
||||
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> &&
|
||||
utils::blocks::contains_type_v<
|
||||
Coupling,
|
||||
typename StellarStructureBackendHandledCouplings<
|
||||
PhysicalCore,
|
||||
Specification>::Type>) ||
|
||||
operators::stellarEquilibriumSpecificationCouplingIsStructuralZero<
|
||||
Specification,
|
||||
Model,
|
||||
Coupling>;
|
||||
|
||||
public:
|
||||
static constexpr bool value =
|
||||
(handled<Specifications> && ...);
|
||||
};
|
||||
|
||||
template <
|
||||
typename Remaining,
|
||||
typename Model,
|
||||
typename PhysicalCore,
|
||||
typename ModelSpecifications,
|
||||
typename Unsupported>
|
||||
struct CollectUnsupportedStellarStructureCouplings;
|
||||
|
||||
template <
|
||||
typename Model,
|
||||
typename PhysicalCore,
|
||||
typename ModelSpecifications,
|
||||
typename Unsupported>
|
||||
struct CollectUnsupportedStellarStructureCouplings<
|
||||
utils::blocks::type_list<>,
|
||||
Model,
|
||||
PhysicalCore,
|
||||
ModelSpecifications,
|
||||
Unsupported> {
|
||||
using Type = Unsupported;
|
||||
};
|
||||
|
||||
template <
|
||||
typename Head,
|
||||
typename... Tail,
|
||||
typename Model,
|
||||
typename PhysicalCore,
|
||||
typename ModelSpecifications,
|
||||
typename... Unsupported>
|
||||
struct CollectUnsupportedStellarStructureCouplings<
|
||||
utils::blocks::type_list<Head, Tail...>,
|
||||
Model,
|
||||
PhysicalCore,
|
||||
ModelSpecifications,
|
||||
utils::blocks::type_list<Unsupported...>> {
|
||||
private:
|
||||
static constexpr bool supported =
|
||||
!isPurePhysicalStellarCoupling<Head> ||
|
||||
EveryCouplingContributionHandled<
|
||||
Head,
|
||||
Model,
|
||||
PhysicalCore,
|
||||
ModelSpecifications>::value;
|
||||
using Next = std::conditional_t<
|
||||
supported,
|
||||
utils::blocks::type_list<Unsupported...>,
|
||||
utils::blocks::type_list<Unsupported..., Head>>;
|
||||
|
||||
public:
|
||||
using Type = typename CollectUnsupportedStellarStructureCouplings<
|
||||
utils::blocks::type_list<Tail...>,
|
||||
Model,
|
||||
PhysicalCore,
|
||||
ModelSpecifications,
|
||||
Next>::Type;
|
||||
};
|
||||
|
||||
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>>)
|
||||
struct DefaultStellarStructurePhysicalTopologyAudit<
|
||||
Model,
|
||||
std::void_t<
|
||||
typename operators::CompiledStellarEquilibriumSystem<
|
||||
std::remove_cvref_t<Model>>::ContributionJacobianCouplings,
|
||||
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>>;
|
||||
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;
|
||||
|
||||
static constexpr bool supported = UnsupportedCouplings::size == 0;
|
||||
};
|
||||
} // namespace detail
|
||||
|
||||
/* A generated-border edge is owned by specification-border machinery and
|
||||
* is deliberately ignored here. Every pure physical edge contributed by a
|
||||
* model must be owned by the selected numerical structure backend, or
|
||||
* every non-backend provider of that edge must prove StructuralZero. In
|
||||
* particular, merely overlapping an existing base-Jacobian edge is not
|
||||
* sufficient: a custom nonzero coefficient on that edge would otherwise
|
||||
* disappear silently from the default preconditioner. This audit is
|
||||
* detection-safe and therefore suitable for constraining factories. */
|
||||
template <typename Candidate>
|
||||
struct DefaultStellarStructurePhysicalTopologySupport
|
||||
: detail::DefaultStellarStructurePhysicalTopologyAudit<
|
||||
std::remove_cvref_t<Candidate>> { };
|
||||
|
||||
template <typename Candidate>
|
||||
inline constexpr bool defaultStellarStructurePhysicalTopologySupported =
|
||||
DefaultStellarStructurePhysicalTopologySupport<
|
||||
std::remove_cvref_t<Candidate>>::supported;
|
||||
|
||||
template <typename Candidate>
|
||||
concept DefaultStellarStructurePhysicalTopologySupportedFor =
|
||||
defaultStellarStructurePhysicalTopologySupported<Candidate>;
|
||||
|
||||
namespace backend {
|
||||
template <typename Component, typename Problem, typename Backend = typename Component::BackendType>
|
||||
class PreparedComponent;
|
||||
@@ -174,56 +416,17 @@ export namespace mean_field::preconditioning {
|
||||
} // namespace backend
|
||||
|
||||
namespace detail {
|
||||
using DensityIdentity =
|
||||
IdentityBlock<utils::blocks::density::mass::value, utils::blocks::density::mass::residual>;
|
||||
using SurfaceIdentity = IdentityBlock<
|
||||
utils::blocks::surface_deformation::parameters::value,
|
||||
utils::blocks::surface_deformation::shape_equilibrium::residual>;
|
||||
using GravityGradientIdentity =
|
||||
IdentityBlock<utils::blocks::gravity::gradient::value, utils::blocks::gravity::gradient::residual>;
|
||||
using GravityPotentialIdentity =
|
||||
IdentityBlock<utils::blocks::gravity::poisson::value, utils::blocks::gravity::poisson::residual>;
|
||||
using EnthalpyIdentity =
|
||||
IdentityBlock<utils::blocks::enthalpy::specific::value, utils::blocks::enthalpy::specific::residual>;
|
||||
using FixedMassIdentity = IdentityBlock<
|
||||
utils::blocks::fixed_total_mass::mass_normalization::value,
|
||||
utils::blocks::fixed_total_mass::mass_normalization::residual>;
|
||||
using FixedCentralDensityIdentity = IdentityBlock<
|
||||
utils::blocks::fixed_central_density::central_value::value,
|
||||
utils::blocks::fixed_central_density::central_value::residual>;
|
||||
|
||||
template <typename Form> struct IdentityPlanForForm;
|
||||
|
||||
template <> struct IdentityPlanForForm<utils::blocks::surface_deformed_stellar_equilibrium_form> {
|
||||
using Type = PreconditionerPlan<
|
||||
DensityIdentity,
|
||||
SurfaceIdentity,
|
||||
GravityGradientIdentity,
|
||||
GravityPotentialIdentity,
|
||||
EnthalpyIdentity,
|
||||
FixedMassIdentity>;
|
||||
template <typename... Values, typename... 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>...>;
|
||||
|
||||
[[nodiscard]] static constexpr Type Make() {
|
||||
return Type{DensityIdentity{}, SurfaceIdentity{}, GravityGradientIdentity{},
|
||||
GravityPotentialIdentity{}, EnthalpyIdentity{}, FixedMassIdentity{}};
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct IdentityPlanForForm<utils::blocks::central_density_bordered_stellar_equilibrium_form> {
|
||||
using Type = PreconditionerPlan<
|
||||
DensityIdentity,
|
||||
SurfaceIdentity,
|
||||
GravityGradientIdentity,
|
||||
GravityPotentialIdentity,
|
||||
EnthalpyIdentity,
|
||||
FixedMassIdentity,
|
||||
FixedCentralDensityIdentity>;
|
||||
|
||||
[[nodiscard]] static constexpr Type Make() {
|
||||
return Type{
|
||||
DensityIdentity{}, SurfaceIdentity{}, GravityGradientIdentity{}, GravityPotentialIdentity{},
|
||||
EnthalpyIdentity{}, FixedMassIdentity{}, FixedCentralDensityIdentity{}
|
||||
};
|
||||
return Type{IdentityBlock<Values, Residuals>{}...};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user