#include #include #include import mean_field; import test_helpers; namespace { struct DeformationCompilationContext final { }; constexpr mean_field::deformation::SurfaceDeformationDescriptor surfaceDescriptor{ .name = "TestRadialSurface", .spatialDimension = 3, .motionKind = mean_field::deformation::SurfaceMotionKind::Radial, .linearOnReferenceGeometry = true, .requiresStarShapedReferenceSurface = true, .hasExactDerivativeTranspose = true, .hasExactPullbackDerivative = true, .translationTreatment = mean_field::deformation::GeometricGaugeTreatment::ExcludedByParameterization, .orientationTreatment = mean_field::deformation::GeometricGaugeTreatment::ExcludedByParameterization }; constexpr mean_field::deformation::InteriorDeformationExtensionDescriptor interiorDescriptor{ .name = "TestRadialInteriorExtension", .spatialDimension = 3, .linearOnReferenceGeometry = true, .requiresRadialFoliation = true, .requiresAuxiliarySolve = false, .hasExactDerivativeTranspose = true, .hasExactPullbackDerivative = true, .centerBehavior = mean_field::deformation::InteriorCenterBehavior::FixedAtReferenceCenter }; constexpr mean_field::deformation::VacuumDeformationExtensionDescriptor vacuumDescriptor{ .name = "TestFixedInfinityExtension", .spatialDimension = 3, .linearOnReferenceGeometry = true, .requiresRadialFoliation = true, .requiresAuxiliarySolve = false, .hasExactDerivativeTranspose = true, .hasExactPullbackDerivative = true, .outerBoundaryBehavior = mean_field::deformation::VacuumOuterBoundaryBehavior::FixedAtReferenceInfinity }; template < bool HasBuild = true, bool HasJacobian = true, bool HasJacobianTranspose = true, bool HasPullbackDerivative = true> class PreparedSurfaceFixture final { public: [[nodiscard]] mean_field::deformation::SurfaceDeformationDescriptor descriptor() const noexcept { return surfaceDescriptor; } [[nodiscard]] int parameterCount() const noexcept { return 4; } [[nodiscard]] int surfaceDisplacementSize() const noexcept { return 12; } void buildSurfaceDisplacement( const mfem::Vector &, mfem::Vector & ) const requires HasBuild { } void applyJacobian( const mfem::Vector &, const mfem::Vector &, mfem::Vector & ) const requires HasJacobian { } void applyJacobianTranspose( const mfem::Vector &, const mfem::Vector &, mfem::Vector & ) const requires HasJacobianTranspose { } void applyPullbackDerivative( const mfem::Vector &, const mfem::Vector &, const mfem::Vector &, mfem::Vector & ) const requires HasPullbackDerivative { } }; template class SurfacePrescriptionFixture final { public: using PreparedType = Prepared; [[nodiscard]] mean_field::deformation::SurfaceDeformationDescriptor descriptor() const noexcept requires HasDescriptor { return surfaceDescriptor; } void validate() const requires HasValidation { } static constexpr bool hasCompilation = HasCompilation; }; template < typename Prepared, bool HasDescriptor, bool HasValidation, bool HasCompilation> requires HasCompilation Prepared compileSurfaceDeformationPrescription( const SurfacePrescriptionFixture< Prepared, HasDescriptor, HasValidation, HasCompilation> &, const DeformationCompilationContext & ) { return {}; } template < bool HasBuild = true, bool HasJacobian = true, bool HasJacobianTranspose = true, bool HasPullbackDerivative = true, bool HasScalarDofCount = true, bool HasSupportQuery = true> class PreparedInteriorExtensionFixture final { public: [[nodiscard]] mean_field::deformation::InteriorDeformationExtensionDescriptor descriptor() const noexcept { return interiorDescriptor; } [[nodiscard]] int surfaceDisplacementSize() const noexcept { return 12; } [[nodiscard]] int interiorDisplacementSize() const noexcept { return 24; } [[nodiscard]] int scalarTrueDofCount() const noexcept requires HasScalarDofCount { return 8; } [[nodiscard]] bool hasStellarSupport(const int) const requires HasSupportQuery { return true; } void buildInteriorDisplacement( const mfem::Vector &, mfem::Vector & ) const requires HasBuild { } void applyJacobian( const mfem::Vector &, const mfem::Vector &, mfem::Vector & ) const requires HasJacobian { } void applyJacobianTranspose( const mfem::Vector &, const mfem::Vector &, mfem::Vector & ) const requires HasJacobianTranspose { } void applyPullbackDerivative( const mfem::Vector &, const mfem::Vector &, const mfem::Vector &, mfem::Vector & ) const requires HasPullbackDerivative { } }; template class InteriorExtensionFixture final { public: using PreparedType = Prepared; [[nodiscard]] mean_field::deformation::InteriorDeformationExtensionDescriptor descriptor() const noexcept requires HasDescriptor { return interiorDescriptor; } void validate() const requires HasValidation { } static constexpr bool hasCompilation = HasCompilation; }; template < typename Prepared, bool HasDescriptor, bool HasValidation, bool HasCompilation> requires HasCompilation Prepared compileInteriorDeformationExtension( const InteriorExtensionFixture< Prepared, HasDescriptor, HasValidation, HasCompilation> &, const DeformationCompilationContext & ) { return {}; } template < bool HasBuild = true, bool HasJacobian = true, bool HasJacobianTranspose = true, bool HasPullbackDerivative = true, bool HasScalarDofCount = true, bool HasSupportQuery = true> class PreparedVacuumExtensionFixture final { public: [[nodiscard]] mean_field::deformation::VacuumDeformationExtensionDescriptor descriptor() const noexcept { return vacuumDescriptor; } [[nodiscard]] int surfaceDisplacementSize() const noexcept { return 12; } [[nodiscard]] int vacuumDisplacementSize() const noexcept { return 30; } [[nodiscard]] int scalarTrueDofCount() const noexcept requires HasScalarDofCount { return 10; } [[nodiscard]] bool hasVacuumSupport(const int) const requires HasSupportQuery { return true; } void buildVacuumDisplacement( const mfem::Vector &, mfem::Vector & ) const requires HasBuild { } void applyJacobian( const mfem::Vector &, const mfem::Vector &, mfem::Vector & ) const requires HasJacobian { } void applyJacobianTranspose( const mfem::Vector &, const mfem::Vector &, mfem::Vector & ) const requires HasJacobianTranspose { } void applyPullbackDerivative( const mfem::Vector &, const mfem::Vector &, const mfem::Vector &, mfem::Vector & ) const requires HasPullbackDerivative { } }; template class VacuumExtensionFixture final { public: using PreparedType = Prepared; [[nodiscard]] mean_field::deformation::VacuumDeformationExtensionDescriptor descriptor() const noexcept requires HasDescriptor { return vacuumDescriptor; } void validate() const requires HasValidation { } static constexpr bool hasCompilation = HasCompilation; }; template < typename Prepared, bool HasDescriptor, bool HasValidation, bool HasCompilation> requires HasCompilation Prepared compileVacuumDeformationExtension( const VacuumExtensionFixture< Prepared, HasDescriptor, HasValidation, HasCompilation> &, const DeformationCompilationContext & ) { return {}; } using CompletePreparedSurface = PreparedSurfaceFixture<>; using CompleteSurfacePrescription = SurfacePrescriptionFixture; using CompletePreparedInteriorExtension = PreparedInteriorExtensionFixture<>; using CompleteInteriorExtension = InteriorExtensionFixture; using CompletePreparedVacuumExtension = PreparedVacuumExtensionFixture<>; using CompleteVacuumExtension = VacuumExtensionFixture; constexpr mean_field::deformation::DomainDeformationDescriptor domainDescriptor{ .surfaceDeformation = surfaceDescriptor, .stellarInteriorExtension = interiorDescriptor, .vacuumExtension = vacuumDescriptor, .linearOnReferenceGeometry = true, .requiresAuxiliarySolve = false, .hasExactDerivativeTranspose = true, .hasExactPullbackDerivative = true }; template < bool HasBuild = true, bool HasJacobian = true, bool HasJacobianTranspose = true, bool HasPullbackDerivative = true> class PreparedDomainDeformationFixture final { public: [[nodiscard]] mean_field::deformation::DomainDeformationDescriptor descriptor() const noexcept { return domainDescriptor; } [[nodiscard]] int parameterCount() const noexcept { return 4; } [[nodiscard]] int surfaceDisplacementSize() const noexcept { return 12; } [[nodiscard]] int volumeDisplacementSize() const noexcept { return 24; } void buildVolumeDisplacement( const mfem::Vector &, mfem::Vector & ) const requires HasBuild { } void applyJacobian( const mfem::Vector &, const mfem::Vector &, mfem::Vector & ) const requires HasJacobian { } void applyJacobianTranspose( const mfem::Vector &, const mfem::Vector &, mfem::Vector & ) const requires HasJacobianTranspose { } void applyPullbackDerivative( const mfem::Vector &, const mfem::Vector &, const mfem::Vector &, mfem::Vector & ) const requires HasPullbackDerivative { } }; } // namespace TEST_CASE( "Surface Deformation Contracts Require Complete Forward And Pullback Operations", tags::surface_deformation_type_contract ) { STATIC_CHECK(mean_field::deformation::PreparedSurfaceDeformationPrescription); STATIC_CHECK(mean_field::deformation::SurfaceDeformationPrescription); STATIC_CHECK( mean_field::deformation::SurfaceDeformationCompilable< CompleteSurfacePrescription, DeformationCompilationContext> ); STATIC_CHECK_FALSE(mean_field::deformation::PreparedSurfaceDeformationPrescription>); STATIC_CHECK_FALSE( mean_field::deformation::PreparedSurfaceDeformationPrescription> ); STATIC_CHECK_FALSE( mean_field::deformation::PreparedSurfaceDeformationPrescription> ); STATIC_CHECK_FALSE( mean_field::deformation::PreparedSurfaceDeformationPrescription> ); STATIC_CHECK_FALSE( mean_field::deformation::SurfaceDeformationPrescription< SurfacePrescriptionFixture> ); STATIC_CHECK_FALSE( mean_field::deformation::SurfaceDeformationPrescription< SurfacePrescriptionFixture> ); STATIC_CHECK_FALSE( mean_field::deformation::SurfaceDeformationCompilable< SurfacePrescriptionFixture, DeformationCompilationContext> ); } TEST_CASE( "Interior Extension Contracts Require Complete Forward And Pullback Operations", tags::interior_deformation_extension_type_contract ) { STATIC_CHECK(mean_field::deformation::PreparedInteriorDeformationExtension); STATIC_CHECK(mean_field::deformation::InteriorDeformationExtension); STATIC_CHECK( mean_field::deformation::InteriorDeformationExtensionCompilable< CompleteInteriorExtension, DeformationCompilationContext> ); STATIC_CHECK_FALSE( mean_field::deformation::PreparedInteriorDeformationExtension> ); STATIC_CHECK_FALSE( mean_field::deformation::PreparedInteriorDeformationExtension> ); STATIC_CHECK_FALSE( mean_field::deformation::PreparedInteriorDeformationExtension< PreparedInteriorExtensionFixture> ); STATIC_CHECK_FALSE( mean_field::deformation::PreparedInteriorDeformationExtension< PreparedInteriorExtensionFixture> ); STATIC_CHECK_FALSE( mean_field::deformation::PreparedInteriorDeformationExtension< PreparedInteriorExtensionFixture> ); STATIC_CHECK_FALSE( mean_field::deformation::PreparedInteriorDeformationExtension< PreparedInteriorExtensionFixture> ); STATIC_CHECK_FALSE(mean_field::deformation::PreparedInteriorDeformationExtension); STATIC_CHECK_FALSE( mean_field::deformation::InteriorDeformationExtension< InteriorExtensionFixture> ); STATIC_CHECK_FALSE( mean_field::deformation::InteriorDeformationExtensionCompilable< InteriorExtensionFixture, DeformationCompilationContext> ); } TEST_CASE( "Vacuum Extension Contracts Require Complete Forward And Pullback Operations", tags::vacuum_deformation_extension_type_contract ) { STATIC_CHECK(mean_field::deformation::PreparedVacuumDeformationExtension); STATIC_CHECK(mean_field::deformation::VacuumDeformationExtension); STATIC_CHECK( mean_field::deformation::VacuumDeformationExtensionCompilable< CompleteVacuumExtension, DeformationCompilationContext> ); STATIC_CHECK_FALSE( mean_field::deformation::PreparedVacuumDeformationExtension> ); STATIC_CHECK_FALSE( mean_field::deformation::PreparedVacuumDeformationExtension> ); STATIC_CHECK_FALSE( mean_field::deformation::PreparedVacuumDeformationExtension> ); STATIC_CHECK_FALSE( mean_field::deformation::PreparedVacuumDeformationExtension< PreparedVacuumExtensionFixture> ); STATIC_CHECK_FALSE( mean_field::deformation::PreparedVacuumDeformationExtension< PreparedVacuumExtensionFixture> ); STATIC_CHECK_FALSE( mean_field::deformation::PreparedVacuumDeformationExtension< PreparedVacuumExtensionFixture> ); STATIC_CHECK_FALSE(mean_field::deformation::PreparedVacuumDeformationExtension); STATIC_CHECK_FALSE( mean_field::deformation::VacuumDeformationExtension< VacuumExtensionFixture> ); STATIC_CHECK_FALSE( mean_field::deformation::VacuumDeformationExtensionCompilable< VacuumExtensionFixture, DeformationCompilationContext> ); } TEST_CASE( "Prepared Domain Deformation Contracts Require Complete Lift And Pullback Operations", tags::domain_deformation_type_contract ) { STATIC_CHECK(mean_field::deformation::PreparedDomainDeformationOperator>); STATIC_CHECK_FALSE( mean_field::deformation::PreparedDomainDeformationOperator> ); STATIC_CHECK_FALSE( mean_field::deformation::PreparedDomainDeformationOperator> ); STATIC_CHECK_FALSE( mean_field::deformation::PreparedDomainDeformationOperator> ); STATIC_CHECK_FALSE( mean_field::deformation::PreparedDomainDeformationOperator< PreparedDomainDeformationFixture> ); } TEST_CASE( "Deformation Descriptors Report Geometry And Exact Linearization Capabilities", tags::deformation_type_contract ) { STATIC_CHECK(surfaceDescriptor.isValid()); STATIC_CHECK(surfaceDescriptor.supportsExactNewtonLinearization()); STATIC_CHECK(interiorDescriptor.isValid()); STATIC_CHECK(interiorDescriptor.supportsExactNewtonLinearization()); STATIC_CHECK(vacuumDescriptor.isValid()); STATIC_CHECK(vacuumDescriptor.supportsExactNewtonLinearization()); STATIC_CHECK(domainDescriptor.isValid()); STATIC_CHECK(domainDescriptor.supportsExactNewtonLinearization()); constexpr auto invalidInteriorDescriptor = [] { auto descriptor = interiorDescriptor; descriptor.centerBehavior = mean_field::deformation::InteriorCenterBehavior::Unspecified; return descriptor; }(); constexpr auto invalidVacuumDescriptor = [] { auto descriptor = vacuumDescriptor; descriptor.outerBoundaryBehavior = mean_field::deformation::VacuumOuterBoundaryBehavior::Unspecified; return descriptor; }(); STATIC_CHECK_FALSE(invalidInteriorDescriptor.isValid()); STATIC_CHECK_FALSE(invalidVacuumDescriptor.isValid()); CHECK(surfaceDescriptor.motionKind == mean_field::deformation::SurfaceMotionKind::Radial); CHECK(interiorDescriptor.centerBehavior == mean_field::deformation::InteriorCenterBehavior::FixedAtReferenceCenter); CHECK( vacuumDescriptor.outerBoundaryBehavior == mean_field::deformation::VacuumOuterBoundaryBehavior::FixedAtReferenceInfinity ); }