module; #include export module mean_field:mapping.kelvin; export import :mapping.compactification; export import :mapping.types; export import :mapping.compactification.options; export namespace mean_field::mapping::compactification { class KelvinCompactification final : public ExteriorDomainMap { public: explicit KelvinCompactification(options::KelvinCompactificationOptions options); [[nodiscard]] bool IsAffineInDisplacement() const noexcept override { return true; } [[nodiscard]] MappingStatus Evaluate( const ExteriorMapInput &input, ExteriorMapResult &result ) const override; [[nodiscard]] MappingStatus EvaluateVariation( const ExteriorMapInput &input, const ExteriorMapResult &result, const ExteriorMapDirection &direction, ExteriorMapVariation &variation ) const override; [[nodiscard]] std::string_view GetName() const noexcept override; [[nodiscard]] double GetReferenceStellarRadius() const noexcept; [[nodiscard]] double GetReferenceInfinityRadius() const noexcept; [[nodiscard]] double GetCoordinateTolerance() const noexcept; // Factors in delta J = scale * grad(delta u) + delta u (grad scale)^T. // They depend only on the fixed compactification coordinate, so prepared // operators can compute them once instead of evaluating the full map. [[nodiscard]] MappingStatus EvaluateJacobianVariationFactors( double coordinate, const mfem::Vector &coordinateGradient, double &scale, mfem::Vector &scaleGradient ) const; private: struct RadialFactors { double coordinate; double computational_radius; double scale; double scale_derivative; }; [[nodiscard]] MappingStatus ComputeRadialFactors( double compactification_coordinate, RadialFactors &factors ) const; options::KelvinCompactificationOptions m_options; }; } // namespace mean_field::mapping::compactification