feat(mapper): finished porting over mapper
This commit is contained in:
34
src/include/serif/mapping/coefficients.hpp
Normal file
34
src/include/serif/mapping/coefficients.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include "mfem/fem/gridfunc.hpp"
|
||||
#include "mfem/fem/coefficient.hpp"
|
||||
#include "mfem/fem/eltrans.hpp"
|
||||
#include "mfem/fem/intrules.hpp"
|
||||
#include "mfem/linalg/vector.hpp"
|
||||
|
||||
#include "serif/mapping/domain_mapper.hpp"
|
||||
#include "serif/mapping/evaluator.hpp"
|
||||
|
||||
namespace serif::mapping {
|
||||
class PhysicalPositionFunctionCoefficient : public mfem::Coefficient {
|
||||
public:
|
||||
using Func = std::function<double(const mfem::Vector& x)>;
|
||||
|
||||
PhysicalPositionFunctionCoefficient(
|
||||
const DomainMapper& mapper,
|
||||
const mfem::GridFunction& displacement,
|
||||
const mfem::GridFunction& compactification_coordinate,
|
||||
Func func
|
||||
);
|
||||
|
||||
double Eval(
|
||||
mfem::ElementTransformation& transformation,
|
||||
const mfem::IntegrationPoint& ip
|
||||
) override;
|
||||
private:
|
||||
Func m_f;
|
||||
GridFunctionMappingEvaluator m_mapping;
|
||||
};
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
#include <memory>
|
||||
|
||||
#include "serif/mapping/status.hpp"
|
||||
#include "serif/mapping/compactification/input_result.hpp"
|
||||
@@ -12,21 +13,18 @@ namespace serif::mapping::compactification {
|
||||
public:
|
||||
virtual ~ExteriorDomainMap() = default;
|
||||
|
||||
[[nodiscard]] virtual bool is_affine_in_displacement() const noexcept;
|
||||
|
||||
[[nodiscard]] virtual bool is_affine_in_displacement() const noexcept = 0;
|
||||
[[nodiscard]] virtual MappingStatus evaluate(
|
||||
const ExteriorMapInput &input,
|
||||
ExteriorMapResult &result
|
||||
) const = 0;
|
||||
|
||||
[[nodiscard]] virtual MappingStatus evaluate_variation(
|
||||
const ExteriorMapInput &input,
|
||||
const ExteriorMapResult &result,
|
||||
const ExteriorMapDirection &direction,
|
||||
ExteriorMapVariation &variation
|
||||
) const = 0;
|
||||
|
||||
[[nodiscard]] virtual std::string_view get_name() const noexcept = 0;
|
||||
|
||||
[[nodiscard]] virtual std::unique_ptr<const ExteriorDomainMap> clone() const = 0;
|
||||
};
|
||||
}
|
||||
@@ -27,6 +27,7 @@ namespace serif::mapping::compactification {
|
||||
) const override;
|
||||
|
||||
[[nodiscard]] std::string_view get_name() const noexcept override;
|
||||
[[nodiscard]] std::unique_ptr<const ExteriorDomainMap> clone() const override;
|
||||
|
||||
[[nodiscard]] double get_reference_stellar_radius() const noexcept;
|
||||
[[nodiscard]] double get_reference_infinity_radius() const noexcept;
|
||||
|
||||
@@ -3,11 +3,15 @@
|
||||
#include "mfem/linalg/densemat.hpp"
|
||||
#include "mfem/linalg/vector.hpp"
|
||||
|
||||
// TODO: There is likely some major readability improvements that could be gained by naming these things
|
||||
// less confusing names
|
||||
|
||||
// TODO [Emily]: Put more comments in this file describing what the various terms are
|
||||
namespace serif::mapping {
|
||||
struct VolumeQuadratureContext {
|
||||
mfem::DenseMatrix J_inv;
|
||||
double detJ;
|
||||
double weight;
|
||||
mfem::DenseMatrix J_element_to_physical_inverse;
|
||||
double mapping_determinate;
|
||||
double physical_integration_weight;
|
||||
};
|
||||
|
||||
struct FaceQuadratureContext {
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "mfem/mesh/mesh.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <map>
|
||||
#include <tuple>
|
||||
|
||||
#include "serif/mapping/compactification/kelvin.hpp"
|
||||
@@ -73,7 +73,7 @@ namespace serif::mapping {
|
||||
[[nodiscard]] int get_dimension() const noexcept;
|
||||
public: // This is a workspace class, these members are kept public so we do not need indirection through getters to access them
|
||||
mfem::Vector m_shape;
|
||||
mfem::DenseMatrix m_reference_shape;
|
||||
mfem::DenseMatrix m_reference_dshape;
|
||||
mfem::DenseMatrix m_mesh_dshape;
|
||||
mfem::DenseMatrix m_reference_field_jacobian;
|
||||
mfem::Vector m_field_value;
|
||||
@@ -120,7 +120,7 @@ namespace serif::mapping {
|
||||
const mfem::Mesh* mesh{nullptr};
|
||||
long sequence{-1}; // We explicitly use the non explicltiy sized versions here since that what MFEM uses fort these members. Alternative we could use a int64_t and verify that on the compiled system that is the same as a long
|
||||
long nodesSequence{-1};
|
||||
std::unordered_map<std::tuple<int, double, double, double>, DMFixedMeshGeometry> points;
|
||||
std::map<std::tuple<int, double, double, double>, DMFixedMeshGeometry> points; // Currently this is an regular map since to use an unordered map we would need to add a std::hash specialization for tuple<int, double, double, double>. Some small future optimizations may be available if we implement a fast hashing algorithm for that type.
|
||||
uint64_t hits{0};
|
||||
uint64_t misses{0};
|
||||
};
|
||||
|
||||
@@ -19,11 +19,6 @@
|
||||
namespace serif::mapping {
|
||||
class DomainMapper {
|
||||
public:
|
||||
DomainMapper(
|
||||
utils::user_options::DomainMapperOptions options,
|
||||
std::unique_ptr<compactification::ExteriorDomainMap> exterior_map
|
||||
);
|
||||
|
||||
DomainMapper(const DomainMapper&) = delete;
|
||||
DomainMapper& operator=(const DomainMapper&) = delete;
|
||||
|
||||
@@ -31,6 +26,14 @@ namespace serif::mapping {
|
||||
DomainMapper(DomainMapper&&) = default;
|
||||
DomainMapper& operator=(DomainMapper&&) = default;
|
||||
|
||||
|
||||
DomainMapper(
|
||||
utils::user_options::DomainMapperOptions options,
|
||||
std::unique_ptr<const compactification::ExteriorDomainMap> exterior_map
|
||||
);
|
||||
|
||||
std::unique_ptr<DomainMapper> clone() const;
|
||||
|
||||
void set_geometry_cache_enabled(bool enabled) const;
|
||||
[[nodiscard]] bool is_geometry_cache_enabled() const noexcept;
|
||||
void clear_geometry_cache() const;
|
||||
@@ -57,7 +60,7 @@ namespace serif::mapping {
|
||||
|
||||
[[nodiscard]] MappingStatus evaluate_face(
|
||||
const ElementMappingData& element_data,
|
||||
mfem::ElementTransformation& transformation,
|
||||
mfem::FaceElementTransformations& transformation,
|
||||
FaceElementSide side,
|
||||
const mfem::IntegrationPoint& ip,
|
||||
DMWorkspace& workspace,
|
||||
@@ -72,7 +75,7 @@ namespace serif::mapping {
|
||||
const MappingPointContext& context,
|
||||
DMWorkspace& workspace,
|
||||
MappingPointVariation& variation
|
||||
);
|
||||
) const;
|
||||
|
||||
[[nodiscard]] MappingStatus evaluate_volume_variation(
|
||||
const ElementMappingData& element_data,
|
||||
@@ -82,18 +85,18 @@ namespace serif::mapping {
|
||||
const VolumeMappingContext& context,
|
||||
DMWorkspace& workspace,
|
||||
VolumeMappingVariation& variation
|
||||
);
|
||||
) const;
|
||||
|
||||
[[nodiscard]] MappingStatus evaluate_face_variation(
|
||||
const ElementMappingData& element_data,
|
||||
const ElementDisplacementData& direction,
|
||||
mfem::ElementTransformation& transformation,
|
||||
mfem::FaceElementTransformations &transformation,
|
||||
FaceElementSide side,
|
||||
const mfem::IntegrationPoint& ip,
|
||||
const FaceMappingContext& context,
|
||||
DMWorkspace& workspace,
|
||||
FaceMappingVariation& variation
|
||||
);
|
||||
) const;
|
||||
|
||||
[[nodiscard]] bool is_compactified_element(const mfem::ElementTransformation& transformation) const noexcept;
|
||||
[[nodiscard]] int get_dimension() const noexcept;
|
||||
@@ -113,7 +116,7 @@ namespace serif::mapping {
|
||||
const ElementMappingData& element_data
|
||||
) const;
|
||||
|
||||
void evaluate_field(
|
||||
void evaluate_displacement_field(
|
||||
const ElementDisplacementData& field,
|
||||
mfem::ElementTransformation& transformation,
|
||||
const mfem::IntegrationPoint& ip,
|
||||
@@ -146,12 +149,12 @@ namespace serif::mapping {
|
||||
// These are static since they do not use any class members or workspace. Really these could and
|
||||
// maybe should be free functions...
|
||||
[[nodiscard]] static mfem::ElementTransformation& select_face_element_transformation(
|
||||
mfem::FaceElementTransformations& transformations,
|
||||
const mfem::FaceElementTransformations& transformations,
|
||||
FaceElementSide side
|
||||
);
|
||||
|
||||
[[nodiscard]] static const mfem::IntegrationPoint& select_face_element_integration_point(
|
||||
mfem::FaceElementTransformations& transformations,
|
||||
const mfem::FaceElementTransformations& transformations,
|
||||
FaceElementSide side
|
||||
);
|
||||
|
||||
|
||||
93
src/include/serif/mapping/evaluator.hpp
Normal file
93
src/include/serif/mapping/evaluator.hpp
Normal file
@@ -0,0 +1,93 @@
|
||||
#pragma once
|
||||
#include <memory>
|
||||
|
||||
#include "mfem/fem/gridfunc.hpp"
|
||||
#include "mfem/fem/eltrans.hpp"
|
||||
#include "mfem/fem/intrules.hpp"
|
||||
#include "mfem/linalg/vector.hpp"
|
||||
#include "mfem/general/array.hpp"
|
||||
|
||||
#include "serif/mapping/domain_mapper.hpp"
|
||||
#include "serif/mapping/context.hpp"
|
||||
#include "serif/mapping/status.hpp"
|
||||
|
||||
namespace serif::mapping {
|
||||
// Note this is NOT thread safe.
|
||||
class GridFunctionMappingEvaluator {
|
||||
public:
|
||||
/*
|
||||
* The evaluator references the supplied grid functions and caches copies of
|
||||
* their element-local DOFs. You need to make sure you call InvalidateCache() or Refresh() after either
|
||||
* grid function's values are modified. Changes to the finite-element-space sequence
|
||||
* should be detected automatically.
|
||||
*
|
||||
* This object owns mutable workspace and cache state and *is not* thread-safe.
|
||||
*/
|
||||
GridFunctionMappingEvaluator(
|
||||
const DomainMapper& mapper,
|
||||
const mfem::GridFunction& displacement,
|
||||
const mfem::GridFunction& compactification_coordinate
|
||||
);
|
||||
|
||||
void invalidate_cache() noexcept;
|
||||
void refresh();
|
||||
|
||||
[[nodiscard]] MappingStatus evaluate_point(
|
||||
mfem::ElementTransformation &transformation,
|
||||
const mfem::IntegrationPoint &integration_point,
|
||||
MappingPointContext &context
|
||||
);
|
||||
|
||||
[[nodiscard]] MappingStatus evaluate_volume(
|
||||
mfem::ElementTransformation &transformation,
|
||||
const mfem::IntegrationPoint &integration_point,
|
||||
VolumeMappingContext &context
|
||||
);
|
||||
|
||||
[[nodiscard]] MappingStatus evaluate_face(
|
||||
mfem::FaceElementTransformations &transformation,
|
||||
FaceElementSide side,
|
||||
const mfem::IntegrationPoint &integration_point,
|
||||
FaceMappingContext &context
|
||||
);
|
||||
|
||||
[[nodiscard]] VolumeQuadratureContext get_quadrature_context(
|
||||
mfem::ElementTransformation &transformation,
|
||||
const mfem::IntegrationPoint &integration_point
|
||||
);
|
||||
|
||||
[[nodiscard]] FaceQuadratureContext get_face_quadrature_context(
|
||||
mfem::FaceElementTransformations &transformation,
|
||||
const mfem::IntegrationPoint &integration_point,
|
||||
FaceElementSide side = FaceElementSide::ELEMENT_1
|
||||
);
|
||||
|
||||
void get_physical_point(
|
||||
mfem::ElementTransformation &transformation,
|
||||
const mfem::IntegrationPoint &integration_point,
|
||||
mfem::Vector &physical_position
|
||||
);
|
||||
private:
|
||||
void validate_field_bindings() const;
|
||||
[[nodiscard]] bool invalidate_for_changed_spaces();
|
||||
void load_element(int element_id);
|
||||
|
||||
private:
|
||||
const DomainMapper &m_mapper;
|
||||
const mfem::GridFunction &m_displacement;
|
||||
const mfem::GridFunction &m_compactification_coordinate;
|
||||
const mfem::FiniteElementSpace *m_displacement_space;
|
||||
const mfem::FiniteElementSpace *m_compactification_space;
|
||||
long m_displacement_space_sequence;
|
||||
long m_compactification_space_sequence;
|
||||
DMWorkspace m_workspace;
|
||||
|
||||
mfem::Array<int> m_displacement_dofs;
|
||||
mfem::Array<int> m_compactification_dofs;
|
||||
mfem::Vector m_element_displacement;
|
||||
mfem::Vector m_element_compactification;
|
||||
std::unique_ptr<ElementDisplacementData> m_displacement_data;
|
||||
std::unique_ptr<ElementCompactificationData> m_compactification_data;
|
||||
int m_cached_element_id{-1};
|
||||
};
|
||||
}
|
||||
87
src/include/serif/mapping/transformations.hpp
Normal file
87
src/include/serif/mapping/transformations.hpp
Normal file
@@ -0,0 +1,87 @@
|
||||
#pragma once
|
||||
|
||||
#include "serif/mapping/variation.hpp"
|
||||
#include "serif/mapping/context.hpp"
|
||||
|
||||
namespace serif::mapping {
|
||||
void map_hdiv_flux_to_physical(
|
||||
const MappingPointContext& context,
|
||||
const mfem::Vector& reference_flux,
|
||||
mfem::Vector& physical_flux
|
||||
);
|
||||
|
||||
void map_physical_flux_to_hdiv_reference(
|
||||
const MappingPointContext& context,
|
||||
const mfem::Vector& physical_flux,
|
||||
mfem::Vector& reference_flux
|
||||
);
|
||||
|
||||
void map_reference_gradient_to_physical(
|
||||
const MappingPointContext& context,
|
||||
const mfem::Vector& reference_gradient,
|
||||
mfem::Vector& physical_gradient
|
||||
);
|
||||
|
||||
void map_physical_gradient_to_reference(
|
||||
const MappingPointContext& context,
|
||||
const mfem::Vector& physical_gradient,
|
||||
mfem::Vector& reference_gradient
|
||||
);
|
||||
|
||||
void map_reference_vector_gradient_to_physical(
|
||||
const MappingPointContext& context,
|
||||
const mfem::DenseMatrix& reference_vector_gradient,
|
||||
mfem::DenseMatrix& physical_vector_gradient
|
||||
);
|
||||
|
||||
void map_physical_vector_gradient_to_reference(
|
||||
const MappingPointContext& context,
|
||||
const mfem::DenseMatrix& physical_vector_gradient,
|
||||
mfem::DenseMatrix& reference_vector_gradient
|
||||
);
|
||||
|
||||
[[nodiscard]] double map_hdiv_divergence_to_physical(
|
||||
const MappingPointContext& context,
|
||||
double reference_divergence
|
||||
);
|
||||
|
||||
void compute_hdiv_mass_tensor(
|
||||
const MappingPointContext& context,
|
||||
mfem::DenseMatrix& mass_tensor
|
||||
);
|
||||
|
||||
void compute_scalar_diffusion_tensor(
|
||||
const MappingPointContext& context,
|
||||
mfem::DenseMatrix& diffusion_tensor
|
||||
);
|
||||
|
||||
void map_hcurl_field_to_physical(
|
||||
const MappingPointContext& context,
|
||||
const mfem::Vector& reference_field,
|
||||
mfem::Vector& physical_field
|
||||
);
|
||||
|
||||
void map_physical_field_to_hcurl_reference(
|
||||
const MappingPointContext& context,
|
||||
const mfem::Vector& physical_field,
|
||||
mfem::Vector& reference_field
|
||||
);
|
||||
|
||||
void map_hcurl_curl_to_physical(
|
||||
const MappingPointContext& context,
|
||||
const mfem::Vector &reference_curl,
|
||||
mfem::Vector &physical_curl
|
||||
);
|
||||
|
||||
void map_physical_curl_to_hcurl_reference(
|
||||
const MappingPointContext& context,
|
||||
const mfem::Vector& physical_curl,
|
||||
mfem::Vector& reference_curl
|
||||
);
|
||||
|
||||
void compute_hdiv_mass_tensor_variation(
|
||||
const MappingPointContext& context,
|
||||
const MappingPointVariation& variation,
|
||||
mfem::DenseMatrix& mass_tensor_variation
|
||||
);
|
||||
}
|
||||
28
src/include/serif/mapping/volume_cache.hpp
Normal file
28
src/include/serif/mapping/volume_cache.hpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#pragma once
|
||||
|
||||
#include "mfem/linalg/densemat.hpp"
|
||||
|
||||
#include "serif/mapping/context.hpp"
|
||||
#include <vector>
|
||||
|
||||
namespace serif::mapping {
|
||||
class VolumeMappingCache {
|
||||
public:
|
||||
void set_size(int point_count, int dimension);
|
||||
void store(int point, VolumeMappingContext& context);
|
||||
void load(int point, VolumeMappingContext& context) const;
|
||||
void load_inverse_jacobian(int point, mfem::DenseMatrix& inverse) const;
|
||||
[[nodiscard]] int get_point_count() const noexcept;
|
||||
[[nodiscard]] int get_dimension() const noexcept;
|
||||
|
||||
private:
|
||||
void validate_point(int point) const;
|
||||
[[nodiscard]] const double* get_point_data(int point) const;
|
||||
|
||||
std::vector<double> m_data;
|
||||
int m_point_count{0};
|
||||
int m_dimension{0};
|
||||
int m_point_stride{0};
|
||||
};
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user