diff --git a/src/include/serif/mapping/compactification/compactification.hpp b/src/include/serif/mapping/compactification/compactification.hpp index 47db8128..d34851ec 100644 --- a/src/include/serif/mapping/compactification/compactification.hpp +++ b/src/include/serif/mapping/compactification/compactification.hpp @@ -1,5 +1,12 @@ #pragma once +/** + * @file compactification.hpp + * @author Emily M. Boudreaux + * + * @brief File containing the definition of the ExteriorDomainMap interface, which is used to define the mapping from reference coordinates to physical coordinates in the exterior domain. + */ + #include #include @@ -9,22 +16,67 @@ namespace serif::mapping::compactification { + + /** + * @class ExteriorDomainMap + * + * @brief Abstract interface for some mapping from reference coordinates to physical coordinates in the exterior domain. + * Currently the only concrete implementation of this is the kelvin compactification. + */ class ExteriorDomainMap { public: virtual ~ExteriorDomainMap() = default; + /** + * @brief Check if the mapping is affine in the displacement, that is if the mapping is linear in the displacement and does not depend on the displacement. + * + * @return True if the mapping is affine in the displacement, false otherwise. + */ [[nodiscard]] virtual bool is_affine_in_displacement() const noexcept = 0; + + /** + * @brief Evaluate the mapping at a given point in the reference domain. + * + * @param input The input to the mapping, which contains the reference coordinates and the displacement. + * @param result The result of the mapping, which contains the physical coordinates and the Jacobian of the mapping. + * + * @return The status of the mapping evaluation, which indicates if the evaluation was successful or if there was an error. + * + */ [[nodiscard]] virtual MappingStatus evaluate( const ExteriorMapInput &input, ExteriorMapResult &result ) const = 0; + + /** + * @brief Evaluate the variation of the mapping at a given point in the reference domain. + * + * @param input The input to the mapping, which contains the reference coordinates and the displacement. + * @param result The result of the mapping, which contains the physical coordinates and the Jacobian of the mapping. + * @param direction The direction of the variation, which is a vector in the reference domain. + * @param variation The variation of the mapping, which contains the variation of the physical coordinates and the variation of the Jacobian. + * + * @return The status of the mapping evaluation, which indicates if the evaluation was successful or if there was an error. + */ [[nodiscard]] virtual MappingStatus evaluate_variation( const ExteriorMapInput &input, const ExteriorMapResult &result, const ExteriorMapDirection &direction, ExteriorMapVariation &variation ) const = 0; + + /** + * @brief Return the name of the mapping, which is used for debugging and logging. + * + * @return The name of the mapping. + */ [[nodiscard]] virtual std::string_view get_name() const noexcept = 0; + + /** + * @brief Clone the mapping, which creates a new instance of the mapping with the same parameters. + * + * @return A unique pointer to the cloned mapping. + */ [[nodiscard]] virtual std::unique_ptr clone() const = 0; }; } \ No newline at end of file diff --git a/src/include/serif/mapping/compactification/input_result.hpp b/src/include/serif/mapping/compactification/input_result.hpp index 792e7fff..561c71a7 100644 --- a/src/include/serif/mapping/compactification/input_result.hpp +++ b/src/include/serif/mapping/compactification/input_result.hpp @@ -1,19 +1,36 @@ #pragma once +/** + * @file input_result.hpp + * @author Emily M. Boudreaux + * + * @brief File containing the input and result structures for the compactification mapping. + */ + #include "mfem/linalg/vector.hpp" #include "mfem/linalg/densemat.hpp" namespace serif::mapping::compactification { + /** + * @struct ExteriorMapInput + * + * @brief Structure representing the input to the exterior domain mapping. This includes the reference position, displaced position, displacement Jacobian, compactification coordinate gradient, and compactification coordinate. + */ struct ExteriorMapInput { - const mfem::Vector &reference_position; - const mfem::Vector &displaced_position; - const mfem::DenseMatrix &displacement_jacobian; - const mfem::Vector &compactification_coordinate_gradient; - double compactification_coordinate; + const mfem::Vector &reference_position; ///< Position in reference space to evaluate the mapping at. + const mfem::Vector &displaced_position; ///< Position in displaced space to evaluate the mapping at (note this is displaced but not yet compactified). + const mfem::DenseMatrix &displacement_jacobian; ///< Jacobian of the displacement mapping at the reference position. + const mfem::Vector &compactification_coordinate_gradient; ///< Gradient of the compactification coordinate at the reference position. + double compactification_coordinate; ///< The compactification coordinate at the reference position. This ranges from 0 to 1, where 0 is the inner surface and 1 is the outer surface of the reference domain. }; + /** + * @struct ExteriorMapResult + * + * @brief Structure representing the result of the exterior domain mapping. This includes the physical position and the Jacobian of the mapping. + */ struct ExteriorMapResult { - mfem::Vector physical_position; - mfem::DenseMatrix mapping_jacobian; + mfem::Vector physical_position; ///< Position in physical space after applying the mapping. + mfem::DenseMatrix mapping_jacobian; ///< Jacobian of the mapping at the reference position, which maps from reference coordinates to physical coordinates. }; } diff --git a/src/include/serif/mapping/compactification/kelvin.hpp b/src/include/serif/mapping/compactification/kelvin.hpp index fcb69932..40dd68e8 100644 --- a/src/include/serif/mapping/compactification/kelvin.hpp +++ b/src/include/serif/mapping/compactification/kelvin.hpp @@ -1,5 +1,12 @@ #pragma once +/** + * @file kelvin.hpp + * @author Emily M. Boudreaux + * + * @brief File containing the definition of the KelvinCompactification class, which is a concrete implementation of the ExteriorDomainMap interface for the Kelvin compactification. + */ + #include #include "mfem/linalg/vector.hpp" @@ -9,16 +16,94 @@ #include "serif/utils/user_options/mapping/compactification/kelvin.hpp" namespace serif::mapping::compactification { + + /** + * @class KelvinCompactification + * + * @brief Concrete implementation of the ExteriorDomainMap interface for the Kelvin compactification. + * + * Broadly, for some reference position \f$\mathbf{x_{r}}\f$ on some reference domain \f$\Omega_{r}\f$ the Kelvin compactification maps to a physical position \f$\mathbf{x_{p}}\f$ on some physical domain \f$\Omega_{p}\f$ through the mapping + * \f[ + * \mathbf{x_{p}} = \frac{\mathbf{x_{r}}}{1 - \frac{|\mathbf{x_{r}}|}{R_{\infty}}} + * \f] + * + * This results in the inner surface of the domain being mapped to the exterior surface of the physical domain while the outer + * surface of the exterior domain is mapped to infinity. There are some implications of this, namely that we + * loose accuracy in all things as we approach the outer surface of the domain. However, it is nice in so far + * as we can apply true boundary conditions at infinity. + */ class KelvinCompactification final : public ExteriorDomainMap { public: - explicit KelvinCompactification(const utils::user_options::KelvinCompactificationOptions& options); + /** + * @brief Construct a KelvinCompactification with the given options. + * + * @param options The options for the Kelvin compactification, which must be valid. + * + * @throws std::invalid_argument If the reference stellar radius is not finite or positive + * @throws std::invalid_argument If the reference infinity radius is not finite or positive + * @throws std::invalid_argument If the reference infinity radius is not greater than the reference stellar radius + * @throws std::invalid_argument If the coordinate tolerance is not finite or positive or is greater than or equal to one + */ + explicit KelvinCompactification( + const utils::user_options::KelvinCompactificationOptions& options + ); + /** + * @brief Check if the mapping is affine in the displacement. For the Kelvin compactification, this is always true + * + * @return false + */ [[nodiscard]] bool is_affine_in_displacement() const noexcept override; + + /** + * @brief Evaluate the mapping at a given point in the reference domain. + * + * @param[in] input The input point in the reference domain to evaluate the mapping at. + * @param[out] result The result of the mapping evaluation, which will be filled in by the method. + * + * @return A status indicating the success or failure of the mapping evaluation. Mapping may fail if + * - the size of the input reference position is less than or equal to zero + * - the input displaced position size does not match the input reference position size + * - the input compactification coordinate gradient size does not match the input reference position size + * - the displacement_jacobian height does not match the input reference position size + * - the displacement_jacobian width does not match the input reference position size + * - the input reference, displaced, compactification coordinate gradient or jacobian contains non-finite values + * - There is some issue computing the radial factors (this error will be passed through) + * + * The mapping jacobian comes from trivial application of the product rule + * recall: \f$r_i = scale * x_i\f$ where \f$r\f$ is the physical position and \f$x\f$ is the displaced position. + * then we can differentiate wrt. \f$X_j\f$ holding nothing fixed. Note the capital \f$X\f$ here, this is the mesh coordinate not the displaced position. + * Lets call this jacobian \f$F\f$ + * \f[ + * F = \frac{\partial r_i}{\partial X_{j}} + * \f] + * + * \f$F\f$ then tells us how the physical position changes as we move along mesh coordinates + * + * Lets then apply this to the function we have for the kelvin compactification + * \f[ + * F = scale * \frac{\partial x_i}{\partial X_j} + x_i * \frac{\partial scale}{\partial X_j} + * \f] + * + * In the implementation you can see the displacement jacobian (\f$\frac{\partial x_i}{\partial X_j}\f$) and the scale derivative (\f$\frac{\partial scale}{\partial X_j}\f$) being applied to compute the mapping jacobian. + */ [[nodiscard]] MappingStatus evaluate( const ExteriorMapInput& input, ExteriorMapResult& result ) const override; + + /** + * @brief Evaluate the variation of the mapping at a given point in the reference domain. + * + * @param[in] input The input point in the reference domain to evaluate the mapping at. + * @param[in] result The result of the mapping evaluation, which will be used in the variation computation. + * @param[in] direction The direction in which to evaluate the variation. + * @param[out] variation The result of the variation evaluation, which will be filled in by the method. + * + * @return A status indicating the success or failure of the variation evaluation. The reasons for a failure are effectively the same + * as the reasons for a failure in the evaluate method just extended to cover the additional inputs. + */ [[nodiscard]] MappingStatus evaluate_variation( const ExteriorMapInput& input, const ExteriorMapResult& result, @@ -26,13 +111,47 @@ namespace serif::mapping::compactification { ExteriorMapVariation& variation ) const override; + /** + * @brief Get the name of the mapping, which is "KelvinCompactification" for this class. + * @return The name of the mapping. + */ [[nodiscard]] std::string_view get_name() const noexcept override; + + /** + * @brief Clone the mapping, returning a unique pointer to a new instance of the mapping. + * @return A unique pointer to a new instance of the mapping. + */ [[nodiscard]] std::unique_ptr clone() const override; + /** + * @brief Get the reference stellar radius for the mapping, which is the radius of the inner surface of the reference domain. + * @return The reference stellar radius for the mapping. + */ [[nodiscard]] double get_reference_stellar_radius() const noexcept; + + /** + * @brief Get the reference infinity radius for the mapping, which is the radius of the outer surface of the reference domain. + * @return The reference infinity radius for the mapping. + */ [[nodiscard]] double get_reference_infinity_radius() const noexcept; + + /** + * @brief Get the coordinate tolerance for the mapping, which is the tolerance for the compactification coordinate. + * @return The coordinate tolerance for the mapping. + */ [[nodiscard]] double get_coordinate_tolerance() const noexcept; + /** + * @brief Evaluate the mapping jacobian variation factors at some given compactification coordinate. + * + * @param[in] compactification_coordinate The compactification coordinate at which to evaluate the mapping jacobian variation factors. (Note this runs from 0 to 1, where 0 is the inner surface and 1 is the outer surface of the reference domain) + * @param[in] coordinateGradient The gradient of the compactification coordinate with respect to the mesh coordinates, which must be finite and have size 3. + * + * @param[out] scale The scale factor for the mapping jacobian, which will be filled in by the method. + * @param[out] scaleGradient The gradient of the scale factor with respect to the mesh coordinates, which will be filled in by the method. + * + * @return The status of the mapping evaluation. + */ [[nodiscard]] MappingStatus evaluate_jacobian_variation_factors( double compactification_coordinate, const mfem::Vector &coordinateGradient, @@ -41,22 +160,37 @@ namespace serif::mapping::compactification { ) const; private: + /** + * @struct RadialFactors + * + * @brief A struct to hold the radial factors for the Kelvin compactification mapping. + */ struct RadialFactors { - double compactification_coordinate; - double computational_radius; - double scale; - double scale_derivative; + double compactification_coordinate; ///< The compactification coordinate, which runs from 0 to 1, where 0 is the inner surface and 1 is the outer surface of the reference domain. + double computational_radius; ///< The computational radius, which is the radius of the reference domain at the given compactification coordinate. + double scale; ///< The scale factor for the mapping jacobian. + double scale_derivative; ///< The derivative of the scale factor with respect to the compactification coordinate. }; private: + /** + * @brief Compute the radial factors for the Kelvin compactification mapping at a given compactification coordinate. + * + * @param[in] compactification_coordinate The compactification coordinate at which to compute the radial factors. (Note this runs from 0 to 1, where 0 is the inner surface and 1 is the outer surface of the reference domain) + * @param[out] radial_factors The radial factors, which will be filled in by the method. + * + * @return The status of the mapping evaluation. + * + * @note See the implementation file for more details on the actual algorithm used here. + */ [[nodiscard]] MappingStatus compute_radial_factors( double compactification_coordinate, RadialFactors &radial_factors ) const; private: - utils::user_options::KelvinCompactificationOptions m_options; - const std::string_view m_name = "KelvinCompactification"; + utils::user_options::KelvinCompactificationOptions m_options; ///< The options for the Kelvin compactification, which must be valid. + const std::string_view m_name = "KelvinCompactification"; ///< The name of the mapping, which is "KelvinCompactification" for this class. }; diff --git a/src/include/serif/mapping/compactification/variation.hpp b/src/include/serif/mapping/compactification/variation.hpp index 53e1f1ce..96196c28 100644 --- a/src/include/serif/mapping/compactification/variation.hpp +++ b/src/include/serif/mapping/compactification/variation.hpp @@ -1,16 +1,35 @@ #pragma once +/** + * @file variation.hpp + * @author Emily M. Boudreaux + * + * @brief File containing the structures for the variation of the compactification mapping. + */ + #include "mfem/linalg/vector.hpp" #include "mfem/linalg/densemat.hpp" namespace serif::mapping::compactification { + /** + * @struct ExteriorMapDirection + * + * @brief Structure representing the direction of the variation in the exterior domain mapping. + * This includes the variation of the displaced position and the variation of the displacement Jacobian. + */ struct ExteriorMapDirection { - const mfem::Vector &displaced_position_variation; - const mfem::DenseMatrix &displacement_jacobian_variation; + const mfem::Vector &displaced_position_variation; ///< Variation of the position in displaced space. + const mfem::DenseMatrix &displacement_jacobian_variation; ///< Variation of the Jacobian of the displacement mapping. }; + /** + * @struct ExteriorMapVariation + * + * @brief Structure representing the variation of the exterior domain mapping. + * This includes the variation of the physical position and the variation of the mapping Jacobian. + */ struct ExteriorMapVariation { - mfem::Vector physical_position_variation; - mfem::DenseMatrix mapping_jacobian_variation; + mfem::Vector physical_position_variation; ///< Variation of the position in physical space. + mfem::DenseMatrix mapping_jacobian_variation; ///< Variation of the Jacobian of the mapping. }; }