docs(mapping/compactification): added compactification documentation

This commit is contained in:
2026-10-12 11:16:57 -04:00
parent eb521f3f01
commit 546dc42d3e
4 changed files with 240 additions and 18 deletions

View File

@@ -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 <string_view>
#include <memory>
@@ -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<const ExteriorDomainMap> clone() const = 0;
};
}

View File

@@ -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.
};
}

View File

@@ -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 <string_view>
#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<const ExteriorDomainMap> 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.
};

View File

@@ -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.
};
}