Add native spherical harmonic surface coordinates to coupled equilibrium
This commit is contained in:
@@ -6,10 +6,12 @@ module;
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <mfem/linalg/vector.hpp>
|
||||
#include <mpi.h>
|
||||
|
||||
export module mean_field:equilibrium.stellar_discretization;
|
||||
|
||||
export import :deformation.domain_deformation;
|
||||
export import :fem;
|
||||
export import :mapping.domain_mapper;
|
||||
export import :normalization.physical_riesz;
|
||||
@@ -26,14 +28,40 @@ export namespace mean_field::equilibrium {
|
||||
* references retained by prepared operators. The mapper is part of that
|
||||
* owned FEM and therefore has the same lifetime.
|
||||
*/
|
||||
template <normalization::NormalizationPrescription Normalization> class StellarDiscretizationFor final {
|
||||
template <
|
||||
normalization::NormalizationPrescription Normalization,
|
||||
deformation::SurfaceDeformationPrescription SurfaceDeformation = deformation::NodalRadialSurface,
|
||||
deformation::InteriorDeformationExtension InteriorDeformation = deformation::PowerLawRadialInteriorExtension,
|
||||
deformation::VacuumDeformationExtension VacuumDeformation = deformation::FixedInfinityRadialVacuumExtension>
|
||||
requires deformation::SurfaceDeformationCompilable<
|
||||
SurfaceDeformation,
|
||||
deformation::SurfaceDeformationCompilationContext> &&
|
||||
deformation::InteriorDeformationExtensionCompilable<
|
||||
InteriorDeformation,
|
||||
deformation::RadialDeformationExtensionCompilationContext> &&
|
||||
deformation::VacuumDeformationExtensionCompilable<
|
||||
VacuumDeformation,
|
||||
deformation::RadialDeformationExtensionCompilationContext>
|
||||
class StellarDiscretizationFor final {
|
||||
public:
|
||||
using NormalizationPrescriptionType = std::remove_cvref_t<Normalization>;
|
||||
using NormalizationPrescriptionType = std::remove_cvref_t<Normalization>;
|
||||
using SurfaceDeformationPrescriptionType = SurfaceDeformation;
|
||||
using InteriorDeformationExtensionType = InteriorDeformation;
|
||||
using VacuumDeformationExtensionType = VacuumDeformation;
|
||||
|
||||
explicit StellarDiscretizationFor(fem::FEM &&finiteElementModel)
|
||||
requires std::same_as<
|
||||
NormalizationPrescriptionType,
|
||||
normalization::Unnormalized>
|
||||
NormalizationPrescriptionType,
|
||||
normalization::Unnormalized> &&
|
||||
std::same_as<
|
||||
SurfaceDeformation,
|
||||
deformation::NodalRadialSurface> &&
|
||||
std::same_as<
|
||||
InteriorDeformation,
|
||||
deformation::PowerLawRadialInteriorExtension> &&
|
||||
std::same_as<
|
||||
VacuumDeformation,
|
||||
deformation::FixedInfinityRadialVacuumExtension>
|
||||
: StellarDiscretizationFor(
|
||||
std::move(finiteElementModel),
|
||||
normalization::Unnormalized{}
|
||||
@@ -49,9 +77,55 @@ export namespace mean_field::equilibrium {
|
||||
StellarDiscretizationFor(
|
||||
fem::FEM &&finiteElementModel,
|
||||
NormalizationPrescriptionType normalizationPrescription
|
||||
)
|
||||
requires std::same_as<
|
||||
SurfaceDeformation,
|
||||
deformation::NodalRadialSurface> &&
|
||||
std::same_as<
|
||||
InteriorDeformation,
|
||||
deformation::PowerLawRadialInteriorExtension> &&
|
||||
std::same_as<
|
||||
VacuumDeformation,
|
||||
deformation::FixedInfinityRadialVacuumExtension>
|
||||
: StellarDiscretizationFor(
|
||||
std::move(finiteElementModel),
|
||||
std::move(normalizationPrescription),
|
||||
MakeDefaultSurface(finiteElementModel),
|
||||
InteriorDeformation{},
|
||||
VacuumDeformation{}
|
||||
) {
|
||||
}
|
||||
|
||||
StellarDiscretizationFor(
|
||||
fem::FEM &&finiteElementModel,
|
||||
NormalizationPrescriptionType normalizationPrescription,
|
||||
SurfaceDeformation surfaceDeformation
|
||||
)
|
||||
requires std::default_initializable<InteriorDeformation> && std::default_initializable<VacuumDeformation>
|
||||
: StellarDiscretizationFor(
|
||||
std::move(finiteElementModel),
|
||||
std::move(normalizationPrescription),
|
||||
std::move(surfaceDeformation),
|
||||
InteriorDeformation{},
|
||||
VacuumDeformation{}
|
||||
) {
|
||||
}
|
||||
|
||||
StellarDiscretizationFor(
|
||||
fem::FEM &&finiteElementModel,
|
||||
NormalizationPrescriptionType normalizationPrescription,
|
||||
SurfaceDeformation surfaceDeformation,
|
||||
InteriorDeformation interiorDeformation,
|
||||
VacuumDeformation vacuumDeformation
|
||||
)
|
||||
: m_finiteElementModel(TakeOwnership(std::move(finiteElementModel))),
|
||||
m_normalizationPrescription(std::move(normalizationPrescription)) {
|
||||
m_normalizationPrescription(std::move(normalizationPrescription)),
|
||||
m_surfaceDeformation(std::move(surfaceDeformation)),
|
||||
m_interiorDeformation(std::move(interiorDeformation)),
|
||||
m_vacuumDeformation(std::move(vacuumDeformation)) {
|
||||
m_surfaceDeformation.validate();
|
||||
m_interiorDeformation.validate();
|
||||
m_vacuumDeformation.validate();
|
||||
}
|
||||
|
||||
StellarDiscretizationFor(
|
||||
@@ -90,6 +164,21 @@ export namespace mean_field::equilibrium {
|
||||
|
||||
[[nodiscard]] const NormalizationPrescriptionType &normalizationPrescription() const && = delete;
|
||||
|
||||
[[nodiscard]] const SurfaceDeformation &surfaceDeformationPrescription() const & noexcept {
|
||||
return m_surfaceDeformation;
|
||||
}
|
||||
[[nodiscard]] const SurfaceDeformation &surfaceDeformationPrescription() const && = delete;
|
||||
|
||||
[[nodiscard]] const InteriorDeformation &interiorDeformationExtension() const & noexcept {
|
||||
return m_interiorDeformation;
|
||||
}
|
||||
[[nodiscard]] const InteriorDeformation &interiorDeformationExtension() const && = delete;
|
||||
|
||||
[[nodiscard]] const VacuumDeformation &vacuumDeformationExtension() const & noexcept {
|
||||
return m_vacuumDeformation;
|
||||
}
|
||||
[[nodiscard]] const VacuumDeformation &vacuumDeformationExtension() const && = delete;
|
||||
|
||||
[[nodiscard]] bool isCurrent() const noexcept {
|
||||
return m_finiteElementModel != nullptr && m_finiteElementModel->okay();
|
||||
}
|
||||
@@ -108,6 +197,15 @@ export namespace mean_field::equilibrium {
|
||||
return *m_finiteElementModel;
|
||||
}
|
||||
|
||||
[[nodiscard]] static deformation::NodalRadialSurface MakeDefaultSurface(const fem::FEM &finiteElementModel) {
|
||||
if (!finiteElementModel.okay()) {
|
||||
throw std::invalid_argument("A default surface requires a complete finite-element model.");
|
||||
}
|
||||
mfem::Vector center(finiteElementModel.mesh->SpaceDimension());
|
||||
center = 0.0;
|
||||
return deformation::NodalRadialSurface{std::move(center)};
|
||||
}
|
||||
|
||||
[[nodiscard]] static std::unique_ptr<fem::FEM> TakeOwnership(fem::FEM &&finiteElementModel) {
|
||||
if (!finiteElementModel.okay()) {
|
||||
throw std::invalid_argument("A stellar discretization requires a complete finite-element model.");
|
||||
@@ -117,6 +215,9 @@ export namespace mean_field::equilibrium {
|
||||
|
||||
std::unique_ptr<fem::FEM> m_finiteElementModel;
|
||||
NormalizationPrescriptionType m_normalizationPrescription;
|
||||
SurfaceDeformation m_surfaceDeformation;
|
||||
InteriorDeformation m_interiorDeformation;
|
||||
VacuumDeformation m_vacuumDeformation;
|
||||
};
|
||||
|
||||
template <normalization::NormalizationPrescription Normalization>
|
||||
@@ -125,12 +226,43 @@ export namespace mean_field::equilibrium {
|
||||
Normalization
|
||||
) -> StellarDiscretizationFor<std::remove_cvref_t<Normalization>>;
|
||||
|
||||
template <
|
||||
typename Normalization,
|
||||
typename Surface>
|
||||
StellarDiscretizationFor(
|
||||
fem::FEM &&,
|
||||
Normalization,
|
||||
Surface
|
||||
)
|
||||
-> StellarDiscretizationFor<
|
||||
std::remove_cvref_t<Normalization>,
|
||||
std::remove_cvref_t<Surface>>;
|
||||
|
||||
template <
|
||||
typename Normalization,
|
||||
typename Surface,
|
||||
typename Interior,
|
||||
typename Vacuum>
|
||||
StellarDiscretizationFor(
|
||||
fem::FEM &&,
|
||||
Normalization,
|
||||
Surface,
|
||||
Interior,
|
||||
Vacuum
|
||||
)
|
||||
-> StellarDiscretizationFor<
|
||||
std::remove_cvref_t<Normalization>,
|
||||
std::remove_cvref_t<Surface>,
|
||||
std::remove_cvref_t<Interior>,
|
||||
std::remove_cvref_t<Vacuum>>;
|
||||
|
||||
using StellarDiscretization = StellarDiscretizationFor<normalization::Unnormalized>;
|
||||
|
||||
template <typename Candidate> struct IsStellarDiscretization : std::false_type { };
|
||||
|
||||
template <normalization::NormalizationPrescription Normalization>
|
||||
struct IsStellarDiscretization<StellarDiscretizationFor<Normalization>> : std::true_type { };
|
||||
template <typename Normalization, typename Surface, typename Interior, typename Vacuum>
|
||||
struct IsStellarDiscretization<StellarDiscretizationFor<Normalization, Surface, Interior, Vacuum>>
|
||||
: std::true_type { };
|
||||
|
||||
template <typename Candidate>
|
||||
concept StellarDiscretizationType = IsStellarDiscretization<std::remove_cvref_t<Candidate>>::value;
|
||||
@@ -145,6 +277,51 @@ export namespace mean_field::equilibrium {
|
||||
};
|
||||
}
|
||||
|
||||
// Geometry is a numerical prescription. Keeping it on the discretization
|
||||
// leaves the model's EOS, surface pressure and integral constraints intact.
|
||||
template <
|
||||
normalization::NormalizationPrescription Normalization,
|
||||
deformation::SurfaceDeformationPrescription Surface>
|
||||
requires deformation::SurfaceDeformationCompilable<
|
||||
Surface,
|
||||
deformation::SurfaceDeformationCompilationContext>
|
||||
[[nodiscard]] auto makeStellarDiscretization(
|
||||
fem::FEM &&finiteElementModel,
|
||||
Normalization normalizationPrescription,
|
||||
Surface surface
|
||||
) {
|
||||
return StellarDiscretizationFor<Normalization, Surface>{
|
||||
std::move(finiteElementModel), std::move(normalizationPrescription), std::move(surface)
|
||||
};
|
||||
}
|
||||
|
||||
template <
|
||||
normalization::NormalizationPrescription Normalization,
|
||||
deformation::SurfaceDeformationPrescription Surface,
|
||||
deformation::InteriorDeformationExtension Interior,
|
||||
deformation::VacuumDeformationExtension Vacuum>
|
||||
requires deformation::SurfaceDeformationCompilable<
|
||||
Surface,
|
||||
deformation::SurfaceDeformationCompilationContext> &&
|
||||
deformation::InteriorDeformationExtensionCompilable<
|
||||
Interior,
|
||||
deformation::RadialDeformationExtensionCompilationContext> &&
|
||||
deformation::VacuumDeformationExtensionCompilable<
|
||||
Vacuum,
|
||||
deformation::RadialDeformationExtensionCompilationContext>
|
||||
[[nodiscard]] auto makeStellarDiscretization(
|
||||
fem::FEM &&finiteElementModel,
|
||||
Normalization normalizationPrescription,
|
||||
Surface surface,
|
||||
Interior interior,
|
||||
Vacuum vacuum
|
||||
) {
|
||||
return StellarDiscretizationFor<Normalization, Surface, Interior, Vacuum>{
|
||||
std::move(finiteElementModel), std::move(normalizationPrescription), std::move(surface),
|
||||
std::move(interior), std::move(vacuum)
|
||||
};
|
||||
}
|
||||
|
||||
template <normalization::NormalizationPrescription Normalization>
|
||||
StellarDiscretizationFor<std::remove_cvref_t<Normalization>> makeStellarDiscretization(
|
||||
fem::FEM &,
|
||||
|
||||
Reference in New Issue
Block a user