feat(FieldDofMap): Completed FieldDofMap migration

also removed legacy BarotropicPolytrope implementation
This commit is contained in:
2026-08-29 08:56:36 -04:00
parent 177ae8b38a
commit 36adfa1174
104 changed files with 26967 additions and 26916 deletions

View File

@@ -121,7 +121,7 @@ export namespace mean_field::eos {
std::pow(density, 1.0 / m_polytropic_index);
}
[[nodiscard]] double enthalpy_from_pressure(double pressure) const override {
[[nodiscard]] double enthalpy_from_pressure(const double pressure) const override {
validate_nonnegativity(pressure, "pressure");
const double np1 = m_polytropic_index + 1;
return np1 * std::pow(m_polytropic_constant, m_polytropic_index / np1) * std::pow(pressure, 1.0 / np1);
@@ -159,12 +159,8 @@ export namespace mean_field::eos {
);
}
}
public:
private:
double m_polytropic_index;
double m_polytropic_constant;
double m_enthalpy_scale;
};
} // namespace mean_field::eos
} // namespace mean_field::eos

View File

@@ -8,7 +8,6 @@ module;
export module mean_field:fem;
export import :physics.contexts;
export import :boundary.contexts;
export import :mapping.domain_mapper;
export import :utils.misc;
@@ -92,38 +91,9 @@ export namespace mean_field::fem {
// =====================================================================
// Domain mapping
//
// These are declared after displacement so that they are destroyed
// before the displacement grid function to which mapping may refer.
// DomainMapper is retained only for legacy integrators. New operators
// use DomainMapperStateless exclusively.
// =====================================================================
std::unique_ptr<mapping::DomainMapper> mapping;
std::unique_ptr<mapping::DomainMapperStateless> domainMapperStateless;
// =====================================================================
// Block layouts
//
// These arrays are retained only for legacy code. Canonical operator
// layouts are defined by the compile-time forms in :utils.blocks.
//
// Main system: [Displacement | Density]
// Gravity system: [Flux | Potential]
// =====================================================================
mfem::Array<int> blockTrueOffsets;
mfem::Array<int> gravityBlockTrueOffsets;
// =====================================================================
// Boundary conditions and domain masks
// =====================================================================
mfem::Array<int> essentialDisplacementTdofs;
mfem::Array<int> vacuumDensityTdofs;
mfem::Array<int> vacuumEnthalpyTdofs;
mfem::Array<int> vacuumDisplacementTdofs;
std::unique_ptr<mapping::DomainMapper> domainMapperStateless;
// =====================================================================
// Global diagnostics
@@ -133,10 +103,9 @@ export namespace mean_field::fem {
mfem::DenseMatrix Q;
// =====================================================================
// Physics and boundary contexts
// Boundary context
// =====================================================================
physics::GravityContext gravityContext;
boundary::BoundaryContext boundaryContext;
std::unique_ptr<quadrature::RuleFactory> quadratureFactory;
@@ -160,13 +129,11 @@ export namespace mean_field::fem {
compactificationFec != nullptr && compactificationFes != nullptr &&
compactificationCoordinate != nullptr &&
mapping != nullptr && domainMapperStateless != nullptr && quadratureFactory != nullptr &&
blockTrueOffsets.Size() == 3 && gravityBlockTrueOffsets.Size() == 3;
domainMapperStateless != nullptr && quadratureFactory != nullptr;
}
[[nodiscard]] bool has_mapping() const {
return mapping != nullptr;
return domainMapperStateless != nullptr && displacement != nullptr && compactificationCoordinate != nullptr;
}
};

View File

@@ -5,6 +5,7 @@ module;
#include <cstddef>
#include <memory>
#include <stdexcept>
#include <utility>
#include <mfem.hpp>
@@ -887,6 +888,110 @@ export namespace mean_field::field {
mfem::Array<int> m_trueToReduced;
};
/*
* Canonical adapter between an MFEM GridFunction and a reduced field
* vector.
*
* FieldDofMap deliberately contains only indexing information. This
* adapter binds that indexing to the exact finite-element space whose true
* DOFs the map describes. Consequently, a grid function from another
* finite-element space is rejected even when it happens to have the same
* vector size.
*
* The finite-element space must outlive the adapter.
*/
class FieldDofGridFunctionAdapter {
public:
FieldDofGridFunctionAdapter(
FieldDofMap dofMap,
const mfem::FiniteElementSpace &finiteElementSpace
)
: m_dofMap(std::move(dofMap)),
m_finiteElementSpace(&finiteElementSpace) {
if (m_dofMap.full_size() != finiteElementSpace.GetTrueVSize()) {
throw std::invalid_argument(
"FieldDofGridFunctionAdapter map and finite-element "
"space have incompatible true-DOF sizes."
);
}
}
[[nodiscard]]
const FieldDofMap &dof_map() const noexcept {
return m_dofMap;
}
[[nodiscard]]
const mfem::FiniteElementSpace &finite_element_space() const noexcept {
return *m_finiteElementSpace;
}
/*
* Gather the grid function's true DOFs into reduced field ordering.
* The output vector is not resized so MFEM vector views remain valid.
*/
void gather(
const mfem::GridFunction &gridFunction,
mfem::Vector &reduced
) const {
validate_grid_function(gridFunction);
mfem::Vector full;
gridFunction.GetTrueDofs(full);
m_dofMap.gather(full, reduced);
}
[[nodiscard]]
mfem::Vector gather(const mfem::GridFunction &gridFunction) const {
mfem::Vector reduced(m_dofMap.reduced_size());
gather(gridFunction, reduced);
return reduced;
}
/*
* Scatter with projection semantics. Unsupported true DOFs are zeroed
* before the complete true vector is distributed to the grid function.
*/
void scatter(
const mfem::Vector &reduced,
mfem::GridFunction &gridFunction
) const {
validate_grid_function(gridFunction);
const mfem::Vector full = m_dofMap.scatter(reduced);
gridFunction.SetFromTrueDofs(full);
}
/*
* Scatter while preserving the grid function's existing unsupported
* true DOFs.
*/
void scatter_into(
const mfem::Vector &reduced,
mfem::GridFunction &gridFunction
) const {
validate_grid_function(gridFunction);
mfem::Vector full;
gridFunction.GetTrueDofs(full);
m_dofMap.scatter_into(reduced, full);
gridFunction.SetFromTrueDofs(full);
}
private:
void validate_grid_function(const mfem::GridFunction &gridFunction) const {
if (gridFunction.FESpace() != m_finiteElementSpace) {
throw std::invalid_argument(
"FieldDofGridFunctionAdapter received a grid function "
"from a different finite-element space."
);
}
}
FieldDofMap m_dofMap;
const mfem::FiniteElementSpace *m_finiteElementSpace;
};
/*
* Construct the canonical solver map for a registered spatial field.
*
@@ -903,4 +1008,16 @@ export namespace mean_field::field {
return FieldDofMap(support);
}
template <
MfemDomainField FieldT,
utils::domain::IsSchema SchemaT>
[[nodiscard]]
FieldDofGridFunctionAdapter
make_field_dof_grid_function_adapter(const mfem::ParFiniteElementSpace &finiteElementSpace) {
return FieldDofGridFunctionAdapter(
make_field_dof_map<FieldT, SchemaT>(finiteElementSpace),
finiteElementSpace
);
}
} // namespace mean_field::field

View File

@@ -6,7 +6,11 @@ import :mapping.domain_mapper;
export namespace mean_field::integrators {
class AdvectionIntegrator : public mfem::BlockNonlinearFormIntegrator {
public:
explicit AdvectionIntegrator(const mapping::DomainMapper &map);
AdvectionIntegrator(
const mapping::DomainMapper &mapper,
const mfem::GridFunction &displacement,
const mfem::GridFunction &compactification_coordinate
);
void AssembleElementVector(
const mfem::Array<const mfem::FiniteElement *> &el,
@@ -23,6 +27,6 @@ export namespace mean_field::integrators {
) override;
private:
const mapping::DomainMapper &m_map;
mapping::GridFunctionMappingEvaluator m_mapping;
};
} // namespace mean_field::integrators
} // namespace mean_field::integrators

View File

@@ -7,7 +7,9 @@ export namespace mean_field::integrators {
class CentrifugalForceIntegrator : public mfem::BlockNonlinearFormIntegrator {
public:
CentrifugalForceIntegrator(
const mapping::DomainMapper &map,
const mapping::DomainMapper &mapper,
const mfem::GridFunction &displacement,
const mfem::GridFunction &compactification_coordinate,
const mfem::Vector &omega
);
@@ -29,9 +31,9 @@ export namespace mean_field::integrators {
) override;
private:
const mapping::DomainMapper &m_map;
mapping::GridFunctionMappingEvaluator m_mapping;
mfem::Vector m_omega;
const mfem::IntegrationRule *m_ir = nullptr;
};
} // namespace mean_field::integrators
} // namespace mean_field::integrators

View File

@@ -7,7 +7,9 @@ export namespace mean_field::integrators {
class CoriolisIntegrator : public mfem::BlockNonlinearFormIntegrator {
public:
CoriolisIntegrator(
const mapping::DomainMapper &map,
const mapping::DomainMapper &mapper,
const mfem::GridFunction &displacement,
const mfem::GridFunction &compactification_coordinate,
const mfem::Vector &omega
);
@@ -26,9 +28,9 @@ export namespace mean_field::integrators {
) override;
private:
const mapping::DomainMapper &m_map;
mapping::GridFunctionMappingEvaluator m_mapping;
mfem::Vector m_omega;
mfem::DenseMatrix m_omega_mat;
};
} // namespace mean_field::integrators
} // namespace mean_field::integrators

View File

@@ -10,7 +10,9 @@ export namespace mean_field::integrators {
class GravityMomentumIntegrator : public mfem::BlockNonlinearFormIntegrator {
public:
explicit GravityMomentumIntegrator(
const mapping::DomainMapper &map,
const mapping::DomainMapper &mapper,
const mfem::GridFunction &displacement,
const mfem::GridFunction &compactification_coordinate,
GravityForceJacobianMode jacobian_mode = GravityForceJacobianMode::field_coupled
);
@@ -33,8 +35,8 @@ export namespace mean_field::integrators {
) override;
private:
const mapping::DomainMapper &m_map;
mapping::GridFunctionMappingEvaluator m_mapping;
GravityForceJacobianMode m_jacobian_mode;
const mfem::IntegrationRule *m_integration_rule{nullptr};
};
} // namespace mean_field::integrators
} // namespace mean_field::integrators

View File

@@ -6,7 +6,11 @@ import :mapping.domain_mapper;
export namespace mean_field::integrators {
class ContinuityVolumeIntegrator : public mfem::BlockNonlinearFormIntegrator {
public:
explicit ContinuityVolumeIntegrator(const mapping::DomainMapper &map);
ContinuityVolumeIntegrator(
const mapping::DomainMapper &mapper,
const mfem::GridFunction &displacement,
const mfem::GridFunction &compactification_coordinate
);
void AssembleElementVector(
const mfem::Array<const mfem::FiniteElement *> &el,
@@ -23,12 +27,16 @@ export namespace mean_field::integrators {
) override;
private:
const mapping::DomainMapper &m_map;
mapping::GridFunctionMappingEvaluator m_mapping;
};
class ContinuityFaceIntegrator : public mfem::BlockNonlinearFormIntegrator {
public:
explicit ContinuityFaceIntegrator(const mapping::DomainMapper &map);
ContinuityFaceIntegrator(
const mapping::DomainMapper &mapper,
const mfem::GridFunction &displacement,
const mfem::GridFunction &compactification_coordinate
);
void AssembleFaceVector(
const mfem::Array<const mfem::FiniteElement *> &el1,
@@ -58,7 +66,7 @@ export namespace mean_field::integrators {
);
private:
const mapping::DomainMapper &m_map;
mapping::GridFunctionMappingEvaluator m_mapping;
};
} // namespace mean_field::integrators

View File

@@ -10,7 +10,9 @@ export namespace mean_field::integrators {
template <utils::is_xad EOS_T> class PressureGradientIntegrator : public mfem::BlockNonlinearFormIntegrator {
public:
PressureGradientIntegrator(
const mapping::DomainMapper &map,
const mapping::DomainMapper &mapper,
const mfem::GridFunction &displacement,
const mfem::GridFunction &compactification_coordinate,
utils::EOS_P<EOS_T> eos
);
@@ -28,16 +30,18 @@ export namespace mean_field::integrators {
) override;
private:
const mapping::DomainMapper &m_map;
mapping::GridFunctionMappingEvaluator m_mapping;
utils::EOS_P<EOS_T> m_eos;
};
template <utils::is_xad EOS_T>
PressureGradientIntegrator<EOS_T>::PressureGradientIntegrator(
const mapping::DomainMapper &map,
const mapping::DomainMapper &mapper,
const mfem::GridFunction &displacement,
const mfem::GridFunction &compactification_coordinate,
utils::EOS_P<EOS_T> eos
)
: m_map(map),
: m_mapping(mapper, displacement, compactification_coordinate),
m_eos(std::move(eos)) {
}
@@ -48,6 +52,8 @@ export namespace mean_field::integrators {
const mfem::Array<const mfem::Vector *> &elfun,
const mfem::Array<mfem::Vector *> &elvec
) {
m_mapping.InvalidateCache();
if (utils::is_vacuum(Tr, elvec)) {
return;
}
@@ -78,7 +84,7 @@ export namespace mean_field::integrators {
const mfem::IntegrationPoint &ip = ir->IntPoint(q);
Tr.SetIntPoint(&ip);
auto [J_inv, detJ, weight] = m_map.GetQuadratureContext(Tr, ip);
auto [J_inv, detJ, weight] = m_mapping.GetQuadratureContext(Tr, ip);
fe_v->CalcDShape(ip, dshape_v_ref);
mfem::Mult(dshape_v_ref, J_inv, dshape_v_phys);
@@ -111,6 +117,8 @@ export namespace mean_field::integrators {
const mfem::Array<const mfem::Vector *> &elfun,
const mfem::Array2D<mfem::DenseMatrix *> &elmats
) {
m_mapping.InvalidateCache();
const mfem::FiniteElement *fe_v = el[0];
const mfem::FiniteElement *fe_rho = el[1];
@@ -141,7 +149,7 @@ export namespace mean_field::integrators {
const mfem::IntegrationPoint &ip = ir->IntPoint(q);
Tr.SetIntPoint(&ip);
auto [J_inv, detJ, weight] = m_map.GetQuadratureContext(Tr, ip);
auto [J_inv, detJ, weight] = m_mapping.GetQuadratureContext(Tr, ip);
fe_v->CalcDShape(ip, dshape_v_ref);
mfem::Mult(dshape_v_ref, J_inv, dshape_v_phys);

View File

@@ -7,7 +7,9 @@ export namespace mean_field::integrators {
class ViscosityIntegrator : public mfem::BlockNonlinearFormIntegrator {
public:
ViscosityIntegrator(
const mapping::DomainMapper &map,
const mapping::DomainMapper &mapper,
const mfem::GridFunction &displacement,
const mfem::GridFunction &compactification_coordinate,
double mu,
int quad_boost
);
@@ -29,7 +31,7 @@ export namespace mean_field::integrators {
) override;
private:
const mapping::DomainMapper &m_map;
mapping::GridFunctionMappingEvaluator m_mapping;
double m_mu;
int m_quad_boost;
};

View File

@@ -9,7 +9,9 @@ export namespace mean_field::mapping {
class MappedScalarCoefficient : public mfem::Coefficient {
public:
MappedScalarCoefficient(
const DomainMapper &map,
const DomainMapper &mapper,
const mfem::GridFunction &displacement,
const mfem::GridFunction &compactification_coordinate,
Coefficient &coeff,
COORDINATE_SPACE coord_space = COORDINATE_SPACE::PHYSICAL
);
@@ -27,7 +29,7 @@ export namespace mean_field::mapping {
);
private:
const DomainMapper &m_map;
GridFunctionMappingEvaluator m_mapping;
Coefficient &m_coeff;
COORDINATE_SPACE m_coord_space;
};
@@ -35,13 +37,17 @@ export namespace mean_field::mapping {
class MappedDiffusionCoefficient : public mfem::MatrixCoefficient {
public:
MappedDiffusionCoefficient(
const DomainMapper &map,
const DomainMapper &mapper,
const mfem::GridFunction &displacement,
const mfem::GridFunction &compactification_coordinate,
mfem::Coefficient &sigma,
int dim
);
MappedDiffusionCoefficient(
const DomainMapper &map,
const DomainMapper &mapper,
const mfem::GridFunction &displacement,
const mfem::GridFunction &compactification_coordinate,
MatrixCoefficient &sigma
);
@@ -52,7 +58,7 @@ export namespace mean_field::mapping {
) override;
private:
const DomainMapper &m_map;
GridFunctionMappingEvaluator m_mapping;
mfem::Coefficient *m_scalar;
MatrixCoefficient *m_tensor;
};
@@ -60,7 +66,9 @@ export namespace mean_field::mapping {
class MappedVectorCoefficient : public mfem::VectorCoefficient {
public:
MappedVectorCoefficient(
const DomainMapper &map,
const DomainMapper &mapper,
const mfem::GridFunction &displacement,
const mfem::GridFunction &compactification_coordinate,
VectorCoefficient &coeff
);
@@ -71,7 +79,7 @@ export namespace mean_field::mapping {
) override;
private:
const DomainMapper &m_map;
GridFunctionMappingEvaluator m_mapping;
VectorCoefficient &m_coeff;
};
@@ -80,7 +88,9 @@ export namespace mean_field::mapping {
using Func = std::function<double(const mfem::Vector &x)>;
PhysicalPositionFunctionCoefficient(
const DomainMapper &map,
const DomainMapper &mapper,
const mfem::GridFunction &displacement,
const mfem::GridFunction &compactification_coordinate,
Func f
);
@@ -91,13 +101,15 @@ export namespace mean_field::mapping {
private:
Func m_f;
const DomainMapper &m_map;
GridFunctionMappingEvaluator m_mapping;
};
class MappedHDivMassCoefficient final : public mfem::MatrixCoefficient {
public:
MappedHDivMassCoefficient(
const DomainMapper &map,
const DomainMapper &mapper,
const mfem::GridFunction &displacement,
const mfem::GridFunction &compactification_coordinate,
const int dim
);
@@ -108,6 +120,6 @@ export namespace mean_field::mapping {
) override;
private:
const DomainMapper &m_map;
GridFunctionMappingEvaluator m_mapping;
};
} // namespace mean_field::mapping

View File

@@ -8,347 +8,259 @@ import :mapping.compactification;
import :utils.user;
export namespace mean_field::mapping {
enum class FaceElementSide : uint8_t { element_1, element_2 };
class ElementDisplacementData {
public:
ElementDisplacementData(
const mfem::FiniteElement &element,
const mfem::Vector &displacement_dofs,
mfem::Ordering::Type ordering = mfem::Ordering::byNODES
);
[[nodiscard]] const mfem::FiniteElement &GetElement() const noexcept;
[[nodiscard]] const mfem::DenseMatrix &GetDofMatrix() const noexcept;
[[nodiscard]] int GetDimension() const noexcept;
[[nodiscard]] int GetDofCount() const noexcept;
[[nodiscard]] mfem::Ordering::Type GetOrdering() const noexcept;
private:
const mfem::FiniteElement *m_element;
mfem::DenseMatrix m_dof_matrix;
int m_dimension;
mfem::Ordering::Type m_ordering;
};
struct CompactificationPointData {
double coordinate{0.0};
mfem::Vector coordinate_gradient;
};
[[nodiscard]] ElementDisplacementData ElementDisplacementDataFromElementVDofs(
const mfem::FiniteElement &element,
const mfem::Vector &displacement_dofs
);
class ElementCompactificationData {
public:
ElementCompactificationData(
const mfem::FiniteElement &element,
const mfem::Vector &dofs
);
[[nodiscard]] const mfem::FiniteElement &GetElement() const noexcept;
[[nodiscard]] const mfem::Vector &GetDofs() const noexcept;
[[nodiscard]] int GetDofCount() const noexcept;
private:
const mfem::FiniteElement *m_element;
mfem::Vector m_dofs;
};
struct ElementMappingData {
const ElementDisplacementData &displacement;
const ElementCompactificationData &compactification;
};
class DomainMapperStateless {
public:
class Workspace {
public:
explicit Workspace(int dimension = 3);
void SetDimension(int dimension);
[[nodiscard]] int GetDimension() const noexcept;
private:
friend class DomainMapperStateless;
int m_dimension;
mfem::Vector m_shape;
mfem::DenseMatrix m_mesh_dshape;
mfem::Vector m_field_value;
mfem::DenseMatrix m_field_jacobian;
mfem::Vector m_compactification_shape;
mfem::DenseMatrix m_compactification_dshape;
CompactificationPointData m_compactification_point;
mfem::Vector m_reference_normal;
mfem::Vector m_mapped_normal;
mfem::DenseMatrix m_full_element_jacobian;
mfem::Vector m_vector_temp;
mfem::DenseMatrix m_matrix_temp_1;
mfem::DenseMatrix m_matrix_temp_2;
compactification::ExteriorMapResult m_exterior_result;
compactification::ExteriorMapVariation m_exterior_variation;
};
public:
DomainMapperStateless(
utils::DomainMapperStatelessOptions options,
std::unique_ptr<const compactification::ExteriorDomainMap> exterior_map
);
DomainMapperStateless(const DomainMapperStateless &) = delete;
DomainMapperStateless &operator=(const DomainMapperStateless &) = delete;
DomainMapperStateless(DomainMapperStateless &&) = default;
DomainMapperStateless &operator=(DomainMapperStateless &&) = default;
[[nodiscard]] MappingStatus EvaluatePoint(
const ElementMappingData &element_data,
mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point,
Workspace &workspace,
MappingPointContext &context
) const;
[[nodiscard]] MappingStatus EvaluateVolume(
const ElementMappingData &element_data,
mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point,
Workspace &workspace,
VolumeMappingContext &context
) const;
[[nodiscard]] MappingStatus EvaluateFace(
const ElementMappingData &element_data,
mfem::FaceElementTransformations &transformation,
FaceElementSide side,
const mfem::IntegrationPoint &integration_point,
Workspace &workspace,
FaceMappingContext &context
) const;
[[nodiscard]] MappingStatus EvaluatePointVariation(
const ElementMappingData &element_data,
const ElementDisplacementData &direction,
mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point,
const MappingPointContext &base_context,
Workspace &workspace,
MappingPointVariation &variation
) const;
[[nodiscard]] MappingStatus EvaluateVolumeVariation(
const ElementMappingData &element_data,
const ElementDisplacementData &direction,
mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point,
const VolumeMappingContext &base_context,
Workspace &workspace,
VolumeMappingVariation &variation
) const;
[[nodiscard]] MappingStatus EvaluateFaceVariation(
const ElementMappingData &element_data,
const ElementDisplacementData &direction,
mfem::FaceElementTransformations &transformation,
FaceElementSide side,
const mfem::IntegrationPoint &integration_point,
const FaceMappingContext &base_context,
Workspace &workspace,
FaceMappingVariation &variation
) const;
[[nodiscard]] bool IsCompactifiedElement(const mfem::ElementTransformation &transformation) const noexcept;
[[nodiscard]] int GetDimension() const noexcept;
[[nodiscard]] int GetVacuumElementAttribute() const noexcept;
[[nodiscard]] const compactification::ExteriorDomainMap &GetExteriorMap() const noexcept;
private:
void ValidateElementData(const ElementMappingData &element_data) const;
void EvaluateField(
const ElementDisplacementData &field,
mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point,
Workspace &workspace,
mfem::Vector &value,
mfem::DenseMatrix &jacobian
) const;
[[nodiscard]] MappingStatus EvaluateCompactificationCoordinate(
const ElementCompactificationData &compactification,
mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point,
Workspace &workspace,
CompactificationPointData &point_data
) const;
[[nodiscard]] static mfem::ElementTransformation &SelectFaceElementTransformation(
mfem::FaceElementTransformations &transformation,
FaceElementSide side
);
[[nodiscard]] static const mfem::IntegrationPoint &SelectFaceElementIntegrationPoint(
mfem::FaceElementTransformations &transformation,
FaceElementSide side
);
utils::DomainMapperStatelessOptions m_options;
std::unique_ptr<const compactification::ExteriorDomainMap> m_exterior_map;
};
class DomainMapper {
public:
explicit DomainMapper(
const double r_star_ref,
const double r_inf_ref
);
explicit DomainMapper(
const mfem::GridFunction &d,
const double r_star_ref,
const double r_inf_ref
);
[[nodiscard]] bool is_vacuum(const mfem::ElementTransformation &T) const;
void SetDisplacement(const mfem::GridFunction &d);
[[nodiscard]] bool HasCompactification() const noexcept;
[[nodiscard]] bool HasDisplacementField() const noexcept;
[[nodiscard]] bool CalcIsIdentity() const;
void ResetDisplacement();
void ComputeJacobian(
mfem::ElementTransformation &T,
mfem::DenseMatrix &J
) const;
double ComputeDetJ(
mfem::ElementTransformation &T,
const mfem::IntegrationPoint &ip
) const;
void ComputeMappedDiffusionTensor(
mfem::ElementTransformation &T,
mfem::DenseMatrix &D
) const;
void ComputeInverseJacobian(
mfem::ElementTransformation &T,
mfem::DenseMatrix &JInv
) const;
VolumeQuadratureContext GetQuadratureContext(
mfem::ElementTransformation &T,
const mfem::IntegrationPoint &ip
) const;
FaceQuadratureContext GetFaceQuadratureContext(
mfem::FaceElementTransformations &T,
const mfem::IntegrationPoint &ip
) const;
void GetPhysicalPoint(
mfem::ElementTransformation &T,
const mfem::IntegrationPoint &ip,
mfem::Vector &x_phys
) const;
void GetVectorValue(
const int i,
const mfem::IntegrationPoint &ip,
mfem::Vector &val
) const;
void MapHDivFluxToPhysical(
mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point,
const mfem::Vector &reference_flux,
mfem::Vector &physical_flux
) const;
void MapPhysicalFluxToHDivReference(
mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point,
const mfem::Vector &physical_flux,
mfem::Vector &reference_flux
) const;
void MapReferenceGradientToPhysical(
mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point,
const mfem::Vector &reference_gradient,
mfem::Vector &physical_gradient
) const;
[[nodiscard]] const mfem::GridFunction *GetDisplacement() const;
[[nodiscard]] double GetPhysInfRadius() const;
[[nodiscard]] size_t GetCacheHits() const;
[[nodiscard]] size_t GetCacheMisses() const;
[[nodiscard]] double GetCacheHitRate() const;
void ResetCacheStats() const;
private:
void InitAllScratchSpaces() const;
void ApplyKelvinMapping(
const mfem::Vector &x_ref,
mfem::Vector &x_phys
) const;
void ComputeKelvinJacobian(
const mfem::Vector &x_ref,
const mfem::Vector &x_disp,
const mfem::DenseMatrix &J_D,
mfem::DenseMatrix &J
) const;
void InvalidateCache() const;
void UpdateElementCache(const mfem::ElementTransformation &T) const;
private:
const mfem::GridFunction *m_d;
std::unique_ptr<mfem::GridFunction> m_internal_d;
const int m_dim{3};
const int m_vacuum_attr{3};
const double m_r_star_ref{1.0};
const double m_r_inf_ref{2.0};
const double m_xi_clamp{0.9999};
mutable int m_cached_elem_id{-1};
mutable int m_cached_elem_type{mfem::ElementTransformation::ELEMENT};
mutable const mfem::FiniteElement *m_fe{nullptr};
mutable mfem::Vector m_elem_dofs;
mutable mfem::DenseMatrix m_dof_mat;
mutable mfem::DenseMatrix m_dshape;
mutable mfem::Vector m_shape;
mutable size_t m_cache_hits{0};
mutable size_t m_cache_misses{0};
mutable mfem::DenseMatrix m_J_D;
mutable mfem::DenseMatrix m_J_temp;
mutable mfem::DenseMatrix m_JInv_temp;
mutable mfem::Vector m_x_ref;
mutable mfem::Vector m_x_disp;
mutable mfem::Vector m_d_val;
bool m_displacement_is_identity{true};
};
enum class FaceElementSide : uint8_t { element_1, element_2 };
class ElementDisplacementData {
public:
ElementDisplacementData(
const mfem::FiniteElement &element, const mfem::Vector &displacement_dofs,
mfem::Ordering::Type ordering = mfem::Ordering::byNODES);
[[nodiscard]] const mfem::FiniteElement &GetElement() const noexcept;
[[nodiscard]] const mfem::DenseMatrix &GetDofMatrix() const noexcept;
[[nodiscard]] int GetDimension() const noexcept;
[[nodiscard]] int GetDofCount() const noexcept;
[[nodiscard]] mfem::Ordering::Type GetOrdering() const noexcept;
private:
const mfem::FiniteElement *m_element;
mfem::DenseMatrix m_dof_matrix;
int m_dimension;
mfem::Ordering::Type m_ordering;
};
struct CompactificationPointData {
double coordinate{0.0};
mfem::Vector coordinate_gradient;
};
[[nodiscard]] ElementDisplacementData
ElementDisplacementDataFromElementVDofs(const mfem::FiniteElement &element,
const mfem::Vector &displacement_dofs);
class ElementCompactificationData {
public:
ElementCompactificationData(const mfem::FiniteElement &element,
const mfem::Vector &dofs);
[[nodiscard]] const mfem::FiniteElement &GetElement() const noexcept;
[[nodiscard]] const mfem::Vector &GetDofs() const noexcept;
[[nodiscard]] int GetDofCount() const noexcept;
private:
const mfem::FiniteElement *m_element;
mfem::Vector m_dofs;
};
struct ElementMappingData {
const ElementDisplacementData &displacement;
const ElementCompactificationData &compactification;
};
class DomainMapper {
public:
class Workspace {
public:
explicit Workspace(int dimension = 3);
void SetDimension(int dimension);
[[nodiscard]] int GetDimension() const noexcept;
private:
friend class DomainMapper;
int m_dimension;
mfem::Vector m_shape;
mfem::DenseMatrix m_mesh_dshape;
mfem::Vector m_field_value;
mfem::DenseMatrix m_field_jacobian;
mfem::Vector m_compactification_shape;
mfem::DenseMatrix m_compactification_dshape;
CompactificationPointData m_compactification_point;
mfem::Vector m_reference_normal;
mfem::Vector m_mapped_normal;
mfem::DenseMatrix m_full_element_jacobian;
mfem::Vector m_vector_temp;
mfem::DenseMatrix m_matrix_temp_1;
mfem::DenseMatrix m_matrix_temp_2;
compactification::ExteriorMapResult m_exterior_result;
compactification::ExteriorMapVariation m_exterior_variation;
};
public:
DomainMapper(
utils::DomainMapperOptions options,
std::unique_ptr<const compactification::ExteriorDomainMap> exterior_map);
DomainMapper(const DomainMapper &) = delete;
DomainMapper &operator=(const DomainMapper &) = delete;
DomainMapper(DomainMapper &&) = default;
DomainMapper &operator=(DomainMapper &&) = default;
[[nodiscard]] MappingStatus
EvaluatePoint(const ElementMappingData &element_data,
mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point,
Workspace &workspace, MappingPointContext &context) const;
[[nodiscard]] MappingStatus
EvaluateVolume(const ElementMappingData &element_data,
mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point,
Workspace &workspace, VolumeMappingContext &context) const;
[[nodiscard]] MappingStatus
EvaluateFace(const ElementMappingData &element_data,
mfem::FaceElementTransformations &transformation,
FaceElementSide side,
const mfem::IntegrationPoint &integration_point,
Workspace &workspace, FaceMappingContext &context) const;
[[nodiscard]] MappingStatus
EvaluatePointVariation(const ElementMappingData &element_data,
const ElementDisplacementData &direction,
mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point,
const MappingPointContext &base_context,
Workspace &workspace,
MappingPointVariation &variation) const;
[[nodiscard]] MappingStatus
EvaluateVolumeVariation(const ElementMappingData &element_data,
const ElementDisplacementData &direction,
mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point,
const VolumeMappingContext &base_context,
Workspace &workspace,
VolumeMappingVariation &variation) const;
[[nodiscard]] MappingStatus EvaluateFaceVariation(
const ElementMappingData &element_data,
const ElementDisplacementData &direction,
mfem::FaceElementTransformations &transformation, FaceElementSide side,
const mfem::IntegrationPoint &integration_point,
const FaceMappingContext &base_context, Workspace &workspace,
FaceMappingVariation &variation) const;
[[nodiscard]] bool IsCompactifiedElement(
const mfem::ElementTransformation &transformation) const noexcept;
[[nodiscard]] int GetDimension() const noexcept;
[[nodiscard]] const compactification::ExteriorDomainMap &
GetExteriorMap() const noexcept;
private:
void ValidateElementData(const ElementMappingData &element_data) const;
void EvaluateField(const ElementDisplacementData &field,
mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point,
Workspace &workspace, mfem::Vector &value,
mfem::DenseMatrix &jacobian) const;
[[nodiscard]] MappingStatus EvaluateCompactificationCoordinate(
const ElementCompactificationData &compactification,
mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point, Workspace &workspace,
CompactificationPointData &point_data) const;
[[nodiscard]] static mfem::ElementTransformation &
SelectFaceElementTransformation(
mfem::FaceElementTransformations &transformation, FaceElementSide side);
[[nodiscard]] static const mfem::IntegrationPoint &
SelectFaceElementIntegrationPoint(
mfem::FaceElementTransformations &transformation, FaceElementSide side);
utils::DomainMapperOptions m_options;
std::unique_ptr<const compactification::ExteriorDomainMap> m_exterior_map;
};
class GridFunctionMappingEvaluator {
public:
/*
* The evaluator references the supplied grid functions and caches copies of
* their element-local DOFs. Call InvalidateCache() or Refresh() after either
* grid function's values are modified. Finite-element-space sequence changes
* are 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);
/*
* Discard all element-local field data. The next evaluation reloads its
* requested element lazily. This operation is idempotent.
*/
void InvalidateCache() noexcept;
/*
* Reload the currently cached element immediately. If no element has been
* evaluated yet, Refresh() is a validated no-op. If either finite-element
* space changed sequence, the old element ID is discarded and the next
* evaluation reloads lazily against the updated spaces.
*/
void Refresh();
[[nodiscard]] MappingStatus
EvaluatePoint(mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point,
MappingPointContext &context);
[[nodiscard]] MappingStatus
EvaluateVolume(mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point,
VolumeMappingContext &context);
[[nodiscard]] MappingStatus
EvaluateFace(mfem::FaceElementTransformations &transformation,
FaceElementSide side,
const mfem::IntegrationPoint &integration_point,
FaceMappingContext &context);
[[nodiscard]] VolumeQuadratureContext
GetQuadratureContext(mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point);
[[nodiscard]] FaceQuadratureContext
GetFaceQuadratureContext(
mfem::FaceElementTransformations &transformation,
const mfem::IntegrationPoint &integration_point,
FaceElementSide side = FaceElementSide::element_1);
void GetPhysicalPoint(mfem::ElementTransformation &transformation,
const mfem::IntegrationPoint &integration_point,
mfem::Vector &physical_position);
private:
void ValidateFieldBindings() const;
[[nodiscard]] bool InvalidateForChangedSpaces();
void LoadElement(int element_id);
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;
DomainMapper::Workspace 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};
};
} // namespace mean_field::mapping

View File

@@ -6,8 +6,6 @@ export import :utils.user;
export import :utils.domain;
export import :physics.gravity;
export import :physics.solid_body;
export import :physics.barotrope;
export import :physics.contexts;
export import :boundary.contexts;
export import :analysis.integral;
export import :mapping.domain_mapper;

View File

@@ -74,7 +74,7 @@ export namespace mean_field::operators::context::barotropic {
public:
BarotropicClosureLinearizationContext(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const field::FieldDofMap &densityMap,
const field::FieldDofMap &enthalpyMap,
const field::FieldDofMap &displacementMap
@@ -103,7 +103,7 @@ export namespace mean_field::operators::context::barotropic {
void VerifyPrepared() const;
const fem::FEM &m_f;
const mapping::DomainMapperStateless &m_domainMapper;
const mapping::DomainMapper &m_domainMapper;
int m_densitySize{0};
int m_enthalpySize{0};

View File

@@ -49,11 +49,12 @@ export namespace mean_field::operators::context::gravity_field {
bool reconstructed_operators{false};
bool rebuilt_mass_operator{false};
bool rebuilt_source_operator{false};
bool rebuilt_divergence_operator{false};
bool refreshed_variation_state{false};
[[nodiscard]] bool DidAnyWork() const noexcept {
return reconstructed_operators || rebuilt_mass_operator || rebuilt_source_operator ||
refreshed_variation_state;
rebuilt_divergence_operator || refreshed_variation_state;
}
};
@@ -61,7 +62,7 @@ export namespace mean_field::operators::context::gravity_field {
public:
GravityFieldGeometryContext(
const fem::FEM &f,
const mapping::DomainMapperStateless &domain_mapper
const mapping::DomainMapper &domain_mapper
);
GravityFieldGeometryContext(const GravityFieldGeometryContext &) = delete;
@@ -77,6 +78,8 @@ export namespace mean_field::operators::context::gravity_field {
[[nodiscard]] const PreparedMappedHDivMassOperator &GetMassOperator() const;
[[nodiscard]] const PreparedMappedGravitySourceOperator &GetSourceOperator() const;
[[nodiscard]] const mfem::Operator &GetDivergenceOperator() const;
[[nodiscard]] const mfem::Operator &GetTransposeDivergenceOperator() const;
[[nodiscard]] const mfem::Vector &GetDisplacementTrue() const;
[[nodiscard]] const field::FieldDofMap &GetDisplacementMap() const noexcept;
[[nodiscard]] DiscretizationRevision GetDiscretizationRevision() const noexcept;
@@ -85,10 +88,12 @@ export namespace mean_field::operators::context::gravity_field {
private:
const fem::FEM &m_fem;
const mapping::DomainMapperStateless &m_domain_mapper;
const mapping::DomainMapper &m_domain_mapper;
std::unique_ptr<PreparedMappedHDivMassOperator> m_mass_operator;
std::unique_ptr<PreparedMappedGravitySourceOperator> m_source_operator;
std::unique_ptr<mfem::ParMixedBilinearForm> m_divergence_operator;
std::unique_ptr<mfem::TransposeOperator> m_transpose_divergence_operator;
field::FieldDofMap m_displacement_map;
mfem::Vector m_displacement_true;
@@ -113,7 +118,7 @@ export namespace mean_field::operators::context::gravity_field {
public:
GravityFieldLinearizationContext(
const fem::FEM &f,
const mapping::DomainMapperStateless &domain_mapper
const mapping::DomainMapper &domain_mapper
);
GravityFieldLinearizationContext(const GravityFieldLinearizationContext &) = delete;

View File

@@ -96,7 +96,7 @@ export namespace mean_field::operators::context::hydrostatic {
public:
HydrostaticEquilibriumContext(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper
const mapping::DomainMapper &domainMapper
);
HydrostaticEquilibriumContext(const HydrostaticEquilibriumContext &) = delete;
@@ -138,7 +138,7 @@ export namespace mean_field::operators::context::hydrostatic {
void VerifyPrepared() const;
const fem::FEM &m_f;
const mapping::DomainMapperStateless &m_domainMapper;
const mapping::DomainMapper &m_domainMapper;
field::FieldDofMap m_enthalpyMap;
field::FieldDofMap m_gravityPotentialMap;

View File

@@ -81,7 +81,7 @@ export namespace mean_field::operators::context::pressure_force {
public:
PressureForceLinearizationContext(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const field::FieldDofMap &enthalpyMap,
const field::FieldDofMap &displacementMap
);

View File

@@ -78,7 +78,7 @@ export namespace mean_field::operators::context::rotational_displacement_force {
public:
RotationalDisplacementForceLinearizationContext(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper
const mapping::DomainMapper &domainMapper
);
RotationalDisplacementForceLinearizationContext(const RotationalDisplacementForceLinearizationContext &) =

View File

@@ -13,7 +13,7 @@ export namespace mean_field::operators {
public:
GravityFieldOperator(
fem::FEM &f,
const mapping::DomainMapperStateless &domain_mapper,
const mapping::DomainMapper &domain_mapper,
context::gravity_field::GravityFieldLinearizationContext &linearization_context,
const mfem::Array<int> &state_offsets,
GravityFieldJacobianOperator &jacobian
@@ -55,7 +55,7 @@ export namespace mean_field::operators {
private:
fem::FEM &m_fem;
const mapping::DomainMapperStateless &m_domain_mapper;
const mapping::DomainMapper &m_domain_mapper;
context::gravity_field::GravityFieldLinearizationContext &m_linearization_context;
mfem::Array<int> m_state_offsets;
mfem::Array<int> m_residual_offsets;
@@ -112,4 +112,39 @@ export namespace mean_field::operators {
context::gravity_field::GravityFieldGeometryContext &m_gravity_field_geometry_context;
mfem::Vector m_displacement;
};
class ReducedGravityFieldPreconditioner final : public mfem::Solver {
public:
ReducedGravityFieldPreconditioner(
const fem::FEM &f,
const context::gravity_field::GravityFieldGeometryContext &geometry_context
);
ReducedGravityFieldPreconditioner(const ReducedGravityFieldPreconditioner &) = delete;
ReducedGravityFieldPreconditioner &operator=(const ReducedGravityFieldPreconditioner &) = delete;
ReducedGravityFieldPreconditioner(ReducedGravityFieldPreconditioner &&) = delete;
ReducedGravityFieldPreconditioner &operator=(ReducedGravityFieldPreconditioner &&) = delete;
void SetOperator(const mfem::Operator &gravity_operator) override;
void Mult(
const mfem::Vector &right_hand_side,
mfem::Vector &action
) const override;
[[nodiscard]] const mfem::Array<int> &GetOffsets() const noexcept;
private:
field::FieldDofMap m_flux_map;
field::FieldDofMap m_potential_map;
mfem::Array<int> m_offsets;
mfem::Array<int> m_empty_tdofs;
std::unique_ptr<mfem::OperatorJacobiSmoother> m_mass_preconditioner;
std::unique_ptr<mfem::HypreParMatrix> m_schur;
std::unique_ptr<mfem::HypreBoomerAMG> m_potential_preconditioner;
mutable mfem::Vector m_potential_rhs_true;
mutable mfem::Vector m_potential_action_true;
};
} // namespace mean_field::operators

View File

@@ -11,7 +11,7 @@ export namespace mean_field::operators {
public:
GravityFieldJacobianOperator(
fem::FEM &f,
const mapping::DomainMapperStateless &domain_mapper,
const mapping::DomainMapper &domain_mapper,
const context::gravity_field::GravityFieldLinearizationContext &linearization_context,
const mfem::Array<int> &state_offsets,
const mfem::Array<int> &residual_offsets
@@ -27,7 +27,7 @@ export namespace mean_field::operators {
private:
fem::FEM &m_fem;
const mapping::DomainMapperStateless &m_domain_mapper;
const mapping::DomainMapper &m_domain_mapper;
const context::gravity_field::GravityFieldLinearizationContext &m_linearization_context;
mfem::Array<int> m_state_offsets;
mfem::Array<int> m_residual_offsets;

View File

@@ -22,7 +22,7 @@ export namespace mean_field::operators::kernels {
*/
void apply_barotropic_closure(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const eos::Polytrope &equationOfState,
const mfem::Vector &densityTrue,
const mfem::Vector &enthalpyTrue,
@@ -32,7 +32,7 @@ export namespace mean_field::operators::kernels {
void apply_barotropic_closure_density_action(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const eos::Polytrope &equationOfState,
const mfem::Vector &densityVariationTrue,
const mfem::Vector &displacementTrue,
@@ -41,7 +41,7 @@ export namespace mean_field::operators::kernels {
void apply_barotropic_closure_enthalpy_action(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const eos::Polytrope &equationOfState,
const mfem::Vector &baseEnthalpyTrue,
const mfem::Vector &enthalpyVariationTrue,
@@ -51,7 +51,7 @@ export namespace mean_field::operators::kernels {
void apply_barotropic_closure_displacement_action(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const eos::Polytrope &equationOfState,
const mfem::Vector &baseDensityTrue,
const mfem::Vector &baseEnthalpyTrue,

View File

@@ -10,7 +10,7 @@ export import :mapping.domain_mapper;
export namespace mean_field::operators::kernels {
void apply_gravity_displacement_force_residual(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const mfem::Vector &densityTrue,
const mfem::Vector &gravityGradientTrue,
const mfem::Vector &displacementTrue,
@@ -19,7 +19,7 @@ export namespace mean_field::operators::kernels {
void apply_gravity_displacement_force_density_action(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const mfem::Vector &densityVariationTrue,
const mfem::Vector &baseGravityGradientTrue,
const mfem::Vector &displacementTrue,
@@ -28,7 +28,7 @@ export namespace mean_field::operators::kernels {
void apply_gravity_displacement_force_gradient_action(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const mfem::Vector &baseDensityTrue,
const mfem::Vector &gravityGradientVariationTrue,
const mfem::Vector &displacementTrue,
@@ -37,7 +37,7 @@ export namespace mean_field::operators::kernels {
void apply_gravity_displacement_force_displacement_action(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const mfem::Vector &baseDensityTrue,
const mfem::Vector &baseGravityGradientTrue,
const mfem::Vector &displacementVariationTrue,
@@ -47,7 +47,7 @@ export namespace mean_field::operators::kernels {
void apply_gravity_displacement_force_complete_action(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const mfem::Vector &baseDensityTrue,
const mfem::Vector &densityVariationTrue,
const mfem::Vector &baseGravityGradientTrue,

View File

@@ -15,7 +15,7 @@ export namespace mean_field::operators::kernels {
void apply_mapped_hdiv_mass(
const fem::FEM &f,
const mapping::DomainMapperStateless &domain_mapper,
const mapping::DomainMapper &domain_mapper,
const mfem::Vector &gravity_gradient_true,
const mfem::Vector &displacement_true,
mfem::Vector &action
@@ -23,7 +23,7 @@ export namespace mean_field::operators::kernels {
void apply_mapped_source(
const fem::FEM &f,
const mapping::DomainMapperStateless &domain_mapper,
const mapping::DomainMapper &domain_mapper,
const mfem::Vector &density_true,
const mfem::Vector &displacement_true,
mfem::Vector &action
@@ -31,7 +31,7 @@ export namespace mean_field::operators::kernels {
void apply_mapped_hdiv_mass_variation(
const fem::FEM &f,
const mapping::DomainMapperStateless &domain_mapper,
const mapping::DomainMapper &domain_mapper,
const mfem::Vector &gravity_gradient_true,
const mfem::Vector &displacement_true,
const mfem::Vector &displacement_variation_true,
@@ -40,7 +40,7 @@ export namespace mean_field::operators::kernels {
void apply_mapped_source_variation(
const fem::FEM &f,
const mapping::DomainMapperStateless &domain_mapper,
const mapping::DomainMapper &domain_mapper,
const mfem::Vector &density_true,
const mfem::Vector &displacement_true,
const mfem::Vector &displacement_variation_true,

View File

@@ -11,7 +11,7 @@ export import :physics.rigid_rotation;
export namespace mean_field::operators::kernels {
void apply_hydrostatic_equilibrium(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const physics::RigidRotation &rotation,
const mfem::Vector &enthalpyTrue,
const mfem::Vector &potentialTrue,
@@ -22,7 +22,7 @@ export namespace mean_field::operators::kernels {
void apply_hydrostatic_equilibrium_enthalpy_action(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const mfem::Vector &enthalpyVariationTrue,
const mfem::Vector &displacementTrue,
mfem::Vector &action
@@ -30,7 +30,7 @@ export namespace mean_field::operators::kernels {
void apply_hydrostatic_equilibrium_potential_action(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const mfem::Vector &potentialVariationTrue,
const mfem::Vector &displacementTrue,
mfem::Vector &action
@@ -38,7 +38,7 @@ export namespace mean_field::operators::kernels {
void apply_hydrostatic_equilibrium_constant_action(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
double constantVariation,
const mfem::Vector &displacementTrue,
mfem::Vector &action
@@ -46,7 +46,7 @@ export namespace mean_field::operators::kernels {
void apply_hydrostatic_equilibrium_displacement_action(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const physics::RigidRotation &rotation,
const mfem::Vector &baseEnthalpyTrue,
const mfem::Vector &basePotentialTrue,
@@ -58,7 +58,7 @@ export namespace mean_field::operators::kernels {
void apply_hydrostatic_equilibrium_action(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const physics::RigidRotation &rotation,
const mfem::Vector &baseEnthalpyTrue,
const mfem::Vector &basePotentialTrue,

View File

@@ -11,7 +11,7 @@ export import :eos.polytrope;
export namespace mean_field::operators::kernels {
void apply_pressure_force_residual(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const eos::Polytrope &barotrope,
const mfem::Vector &enthalpyTrue,
const mfem::Vector &displacementTrue,
@@ -20,7 +20,7 @@ export namespace mean_field::operators::kernels {
void apply_pressure_force_enthalpy_action(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const eos::Polytrope &barotrope,
const mfem::Vector &baseEnthalpyTrue,
const mfem::Vector &enthalpyVariationTrue,
@@ -30,7 +30,7 @@ export namespace mean_field::operators::kernels {
void apply_pressure_force_displacement_action(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const eos::Polytrope &barotrope,
const mfem::Vector &baseEnthalpyTrue,
const mfem::Vector &displacementVariationTrue,

View File

@@ -25,7 +25,7 @@ export namespace mean_field::operators::kernels {
*/
void apply_rotational_displacement_force_residual(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const physics::RigidRotation &rotation,
const mfem::Vector &densityTrue,
const mfem::Vector &displacementTrue,
@@ -34,7 +34,7 @@ export namespace mean_field::operators::kernels {
void apply_rotational_displacement_force_density_action(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const physics::RigidRotation &rotation,
const mfem::Vector &densityVariationTrue,
const mfem::Vector &displacementTrue,
@@ -43,7 +43,7 @@ export namespace mean_field::operators::kernels {
void apply_rotational_displacement_force_displacement_action(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const physics::RigidRotation &rotation,
const mfem::Vector &baseDensityTrue,
const mfem::Vector &displacementVariationTrue,
@@ -53,7 +53,7 @@ export namespace mean_field::operators::kernels {
void apply_rotational_displacement_force_complete_action(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const physics::RigidRotation &rotation,
const mfem::Vector &baseDensityTrue,
const mfem::Vector &densityVariationTrue,

View File

@@ -26,7 +26,7 @@ export namespace mean_field::operators {
public:
PreparedBarotropicClosureOperator(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const eos::Polytrope &equationOfState
);
@@ -71,7 +71,7 @@ export namespace mean_field::operators {
PreparedBarotropicClosureOperator(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const eos::Polytrope &equationOfState,
ConstructionData constructionData
);
@@ -100,7 +100,7 @@ export namespace mean_field::operators {
};
const fem::FEM &m_fem;
const mapping::DomainMapperStateless &m_domainMapper;
const mapping::DomainMapper &m_domainMapper;
const eos::Polytrope &m_equationOfState;
field::FieldDofMap m_densityMap;

View File

@@ -85,7 +85,7 @@ export namespace mean_field::operators {
public:
PreparedDisplacementResidualOperator(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const eos::Polytrope &barotrope,
const context::gravity_field::GravityFieldLinearizationContext &gravityContext
);
@@ -158,7 +158,7 @@ export namespace mean_field::operators {
void VerifyPrepared() const;
const fem::FEM &m_fem;
const mapping::DomainMapperStateless &m_domainMapper;
const mapping::DomainMapper &m_domainMapper;
const context::gravity_field::GravityFieldLinearizationContext &m_gravityContext;
PreparedPressureForceOperator m_pressureOperator;

View File

@@ -37,7 +37,7 @@ export namespace mean_field::operators {
public:
PreparedGravityDisplacementForceOperator(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const context::gravity_field::GravityFieldLinearizationContext &gravityContext
);
@@ -107,7 +107,7 @@ export namespace mean_field::operators {
void VerifyPrepared() const;
const fem::FEM &m_fem;
const mapping::DomainMapperStateless &m_domainMapper;
const mapping::DomainMapper &m_domainMapper;
const context::gravity_field::GravityFieldLinearizationContext &m_gravityContext;
context::gravity_field::GravityFieldRevisions m_preparedRevisions;

View File

@@ -14,7 +14,7 @@ export namespace mean_field::operators {
public:
PreparedMappedGravitySourceOperator(
const fem::FEM &f,
const mapping::DomainMapperStateless &domain_mapper
const mapping::DomainMapper &domain_mapper
);
void Prepare(const mfem::Vector &displacement);
@@ -55,7 +55,7 @@ export namespace mean_field::operators {
};
const fem::FEM &m_fem;
const mapping::DomainMapperStateless &m_domain_mapper;
const mapping::DomainMapper &m_domain_mapper;
field::FieldDofMap m_density_map;
field::FieldDofMap m_potential_map;

View File

@@ -13,7 +13,7 @@ export namespace mean_field::operators {
public:
PreparedMappedHDivMassOperator(
const fem::FEM &f,
const mapping::DomainMapperStateless &domain_mapper
const mapping::DomainMapper &domain_mapper
);
void Prepare(const mfem::Vector &displacement);
@@ -21,6 +21,8 @@ export namespace mean_field::operators {
const mfem::Vector &gravity_gradient,
mfem::Vector &action
) const override;
void AssembleDiagonal(mfem::Vector &diagonal) const override;
void AssembleTrueDiagonal(mfem::Vector &diagonal) const;
[[nodiscard]] bool IsPrepared() const noexcept;
[[nodiscard]] std::uint64_t GetPreparationCount() const noexcept;
@@ -30,7 +32,7 @@ export namespace mean_field::operators {
private:
const fem::FEM &m_fem;
const mapping::DomainMapperStateless &m_domain_mapper;
const mapping::DomainMapper &m_domain_mapper;
field::FieldDofMap m_flux_map;
field::FieldDofMap m_displacement_map;
@@ -40,9 +42,11 @@ export namespace mean_field::operators {
std::unique_ptr<mfem::MatrixCoefficient> m_stellar_mass_coefficient;
std::unique_ptr<mfem::MatrixCoefficient> m_vacuum_mass_coefficient;
std::unique_ptr<mfem::ParBilinearForm> m_mass_form;
std::unique_ptr<mfem::ParBilinearForm> m_stellar_mass_form;
std::unique_ptr<mfem::ParBilinearForm> m_vacuum_mass_form;
mutable mfem::Vector m_flux_true;
mutable mfem::Vector m_action_true;
mutable mfem::Vector m_domain_action_true;
mfem::Vector m_displacement_true;
std::uint64_t m_preparation_count{0};
bool m_is_prepared{false};

View File

@@ -84,7 +84,7 @@ export namespace mean_field::operators {
public:
PreparedHydrostaticEquilibriumOperator(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper
const mapping::DomainMapper &domainMapper
);
PreparedHydrostaticEquilibriumOperator(const PreparedHydrostaticEquilibriumOperator &) = delete;
@@ -217,7 +217,7 @@ export namespace mean_field::operators {
void VerifyPrepared() const;
const fem::FEM &m_fem;
const mapping::DomainMapperStateless &m_domainMapper;
const mapping::DomainMapper &m_domainMapper;
context::hydrostatic::HydrostaticEquilibriumContext m_context;

View File

@@ -68,7 +68,7 @@ export namespace mean_field::operators {
public:
PreparedMassNormalizationOperator(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const context::gravity_field::GravityFieldLinearizationContext &gravityContext
);
@@ -148,7 +148,7 @@ export namespace mean_field::operators {
[[nodiscard]] double GlobalSum(double localValue) const;
const fem::FEM &m_fem;
const mapping::DomainMapperStateless &m_domainMapper;
const mapping::DomainMapper &m_domainMapper;
const context::gravity_field::GravityFieldLinearizationContext &m_gravityContext;
std::vector<ElementPAData> m_elements;

View File

@@ -75,7 +75,7 @@ export namespace mean_field::operators {
public:
PreparedPressureForceOperator(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const eos::Polytrope &equationOfState
);
@@ -155,7 +155,7 @@ export namespace mean_field::operators {
PreparedPressureForceOperator(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const eos::Polytrope &equationOfState,
ConstructionData constructionData
);
@@ -217,7 +217,7 @@ export namespace mean_field::operators {
const fem::FEM &m_fem;
const mapping::DomainMapperStateless &m_domainMapper;
const mapping::DomainMapper &m_domainMapper;
const eos::Polytrope &m_equationOfState;

View File

@@ -42,7 +42,7 @@ export namespace mean_field::operators {
public:
PreparedRotationalDisplacementForceOperator(
const fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper
const mapping::DomainMapper &domainMapper
);
PreparedRotationalDisplacementForceOperator(const PreparedRotationalDisplacementForceOperator &) = delete;
@@ -105,7 +105,7 @@ export namespace mean_field::operators {
void VerifyPrepared() const;
const fem::FEM &m_fem;
const mapping::DomainMapperStateless &m_domainMapper;
const mapping::DomainMapper &m_domainMapper;
context::rotational_displacement_force::RotationalDisplacementForceLinearizationContext m_context;

View File

@@ -76,14 +76,14 @@ export namespace mean_field::operators {
public:
PreparedStellarEquilibriumOperator(
fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const eos::Polytrope &equationOfState,
double targetMass
);
PreparedStellarEquilibriumOperator(
fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const eos::Polytrope &equationOfState,
const models::StellarModel &stellarModel
);
@@ -130,7 +130,7 @@ export namespace mean_field::operators {
PreparedStellarEquilibriumOperator(
fem::FEM &f,
const mapping::DomainMapperStateless &domainMapper,
const mapping::DomainMapper &domainMapper,
const eos::Polytrope &equationOfState,
double targetMass,
ConstructionData constructionData

View File

@@ -1,162 +0,0 @@
module;
#include <cmath>
#include <format>
#include <stdexcept>
export module mean_field:physics.barotrope;
export namespace mean_field::physics {
class PolytropicBarotrope final {
public:
PolytropicBarotrope(
const double polytropic_index,
const double polytropic_constant
)
: m_polytropic_index(polytropic_index),
m_polytropic_constant(polytropic_constant),
m_enthalpy_scale((polytropic_index + 1.0) * polytropic_constant) {
if (!std::isfinite(polytropic_index) || polytropic_index < 1.0) {
throw std::invalid_argument(
std::format(
"The differentiable polytropic closure requires a "
"finite polytropic index greater than or equal to one. "
"Instead a value of {} has been provided",
polytropic_index
)
);
}
if (!std::isfinite(polytropic_constant) || polytropic_constant <= 0.0) {
throw std::invalid_argument(
std::format(
"The polytropic constant must be finite and positive. "
"Instead a value of {} has been provided",
polytropic_constant
)
);
}
};
[[nodiscard]] double polytropic_index() const noexcept {
return m_polytropic_index;
}
[[nodiscard]] double polytropic_constant() const noexcept {
return m_polytropic_constant;
}
[[nodiscard]] double enthalpy_scale() const noexcept {
return m_enthalpy_scale;
}
[[nodiscard]] double pressure_from_density(const double density) const {
validate_nonnegativity(density, "density");
if (density == 0.0) {
return 0.0;
}
return m_polytropic_constant * std::pow(density, 1.0 + 1.0 / m_polytropic_index);
}
[[nodiscard]] double enthalpy_from_density(const double density) const {
validate_nonnegativity(density, "density");
if (density == 0.0) {
return 0.0;
}
return m_enthalpy_scale * std::pow(density, 1.0 / m_polytropic_index);
}
[[nodiscard]] double density_from_enthalpy(const double enthalpy) const {
validate_finite(enthalpy, "enthalpy");
if (enthalpy <= 0.0) {
return 0.0;
}
return std::pow(enthalpy / m_enthalpy_scale, m_polytropic_index);
}
[[nodiscard]] double pressure_from_enthalpy(const double enthalpy) const {
validate_finite(enthalpy, "enthalpy");
if (enthalpy <= 0.0) {
return 0.0;
}
return density_from_enthalpy(enthalpy) * enthalpy / (m_polytropic_index + 1.0);
}
[[nodiscard]] double density_derivative_from_enthalpy(const double enthalpy) const {
validate_finite(enthalpy, "enthalpy");
if (enthalpy < 0.0) {
return 0.0;
}
if (enthalpy == 0.0) {
return m_polytropic_index == 1.0 ? 1.0 / m_enthalpy_scale : 0.0;
}
return m_polytropic_index / m_enthalpy_scale *
std::pow(enthalpy / m_enthalpy_scale, m_polytropic_index - 1.0);
}
[[nodiscard]] double pressure_derivative_from_enthalpy(const double enthalpy) const {
validate_finite(enthalpy, "enthalpy");
if (enthalpy <= 0.0) {
return 0.0;
}
return density_from_enthalpy(enthalpy);
}
[[nodiscard]] double pressure_derivative_from_density(const double density) const {
validate_nonnegativity(density, "density");
if (density == 0.0) {
return 0.0;
}
return m_polytropic_constant * (1.0 + 1.0 / m_polytropic_index) *
std::pow(density, 1.0 / m_polytropic_index);
}
private:
static void validate_finite(
const double value,
const char *quantity
) {
if (!std::isfinite(value)) {
throw std::domain_error(
std::format(
"The {} must be finite. Instead a value of {} has been "
"provided",
quantity, value
)
);
}
}
static void validate_nonnegativity(
const double value,
const char *quantity
) {
validate_finite(value, quantity);
if (value < 0.0) {
throw std::domain_error(
std::format(
"The {} must be non-negative. Instead a value of {} "
"has been "
"provided",
quantity, value
)
);
}
}
double m_polytropic_index;
double m_polytropic_constant;
double m_enthalpy_scale;
};
} // namespace mean_field::physics

View File

@@ -1,29 +0,0 @@
module;
#include <memory>
#include <mfem.hpp>
export module mean_field:physics.contexts;
export import :mapping.coefficients;
export namespace mean_field::physics {
struct GravityContext {
std::unique_ptr<mfem::ParBilinearForm> m_form;
std::unique_ptr<mfem::ParMixedBilinearForm> b_form;
std::unique_ptr<mfem::BlockOperator> block_A;
std::unique_ptr<mfem::Solver> prec_M;
std::unique_ptr<mfem::HypreBoomerAMG> prec_Phi;
std::unique_ptr<mfem::BlockDiagonalPreconditioner> block_prec;
std::unique_ptr<mfem::MINRESSolver> minres;
mfem::Array<int> stellar_mask;
std::unique_ptr<mfem::TransposeOperator> BT;
std::unique_ptr<mfem::HypreParMatrix> Schur;
std::unique_ptr<mfem::MatrixCoefficient> mapped_hdiv_mass_coeff;
std::unique_ptr<mfem::Operator> source_form;
};
} // namespace mean_field::physics

View File

@@ -16,27 +16,13 @@ export namespace mean_field::physics {
}
};
GravitySolution grav_potential(
fem::FEM &f,
const utils::Args &args,
const mfem::GridFunction &rho,
bool phi_warm = false
);
GravitySolution grav_potential_new(
GravitySolution solve_gravity_field(
fem::FEM &f,
const utils::Args &args,
const mfem::GridFunction &rho,
const mfem::GridFunction &displacement
);
mfem::GridFunction get_potential(
fem::FEM &fem,
const utils::Args &args,
const mfem::GridFunction &rho,
bool warm = false
);
mfem::DenseMatrix compute_quadrupole_moment_tensor(
const fem::FEM &fem,
const mfem::GridFunction &rho,
@@ -49,5 +35,4 @@ export namespace mean_field::physics {
const mfem::Vector &phys_x
);
void update_stiffness_matrix(fem::FEM &fem);
} // namespace mean_field::physics

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,4 @@
module;
#include <expected>
#include <functional>
#include <string_view>
@@ -9,109 +8,85 @@ module;
#include <XAD/XAD.hpp>
export module mean_field:utils.misc;
import :boundary.contexts;
import :utils.domain;
export namespace mean_field::utils {
constexpr double APPROX_MAX_ACCEPTABLE_POTENTIAL_ERROR_SI_BURNING = 1e-4;
constexpr double APPROX_MAX_ACCEPTABLE_POTENTIAL_ERROR_SI_BURNING = 1e-4;
bool is_vacuum(
const mfem::ElementTransformation &Tr,
mfem::Array<mfem::Vector *> elvec
) {
if (Tr.Attribute == 3) {
const int size_elvec = elvec.Size();
for (int i = 0; i < size_elvec; i++) {
if (elvec[i]) {
*elvec[i] = 0.0;
}
}
return true;
}
return false;
bool is_vacuum(const mfem::ElementTransformation &Tr,
mfem::Array<mfem::Vector *> elvec) {
using Schema = domain::CoreEnvelopeVacuumDomainSchema;
if (Schema::template attribute_belongs_to<domain::Vacuum>(Tr.Attribute)) {
const int size_elvec = elvec.Size();
for (int i = 0; i < size_elvec; i++) {
if (elvec[i]) {
*elvec[i] = 0.0;
}
}
return true;
}
return false;
}
bool is_vacuum(
const mfem::ElementTransformation &Tr,
const mfem::Array2D<mfem::DenseMatrix *> &elmats
) {
if (Tr.Attribute == 3) {
const int cols = elmats.NumCols();
const int rows = elmats.NumRows();
for (int rowID = 0; rowID < rows; rowID++) {
for (int colID = 0; colID < cols; colID++) {
if (elmats(rowID, colID)) {
*elmats(rowID, colID) = 0.0;
}
}
}
return true;
bool is_vacuum(const mfem::ElementTransformation &Tr,
const mfem::Array2D<mfem::DenseMatrix *> &elmats) {
using Schema = domain::CoreEnvelopeVacuumDomainSchema;
if (Schema::template attribute_belongs_to<domain::Vacuum>(Tr.Attribute)) {
const int cols = elmats.NumCols();
const int rows = elmats.NumRows();
for (int rowID = 0; rowID < rows; rowID++) {
for (int colID = 0; colID < cols; colID++) {
if (elmats(rowID, colID)) {
*elmats(rowID, colID) = 0.0;
}
return false;
}
}
return true;
}
return false;
}
constexpr std::string_view ANSI_GREEN = "\033[32m";
constexpr std::string_view ANSI_RED = "\033[31m";
constexpr std::string_view ANSI_YELLOW = "\033[33m";
constexpr std::string_view ANSI_BLUE = "\033[34m";
constexpr std::string_view ANSI_MAGENTA = "\033[35m";
constexpr std::string_view ANSI_CYAN = "\033[36m";
constexpr std::string_view ANSI_RESET = "\033[0m";
constexpr std::string_view ANSI_BCYAN = "\033[1;36m";
constexpr std::string_view ANSI_GREEN = "\033[32m";
constexpr std::string_view ANSI_RED = "\033[31m";
constexpr std::string_view ANSI_YELLOW = "\033[33m";
constexpr std::string_view ANSI_BLUE = "\033[34m";
constexpr std::string_view ANSI_MAGENTA = "\033[35m";
constexpr std::string_view ANSI_CYAN = "\033[36m";
constexpr std::string_view ANSI_RESET = "\033[0m";
constexpr std::string_view ANSI_BCYAN = "\033[1;36m";
constexpr double G = 1.0;
constexpr double MASS = 1.0;
constexpr double RADIUS = 1.0;
constexpr double G = 1.0;
constexpr double MASS = 1.0;
constexpr double RADIUS = 1.0;
[[maybe_unused]] constexpr char HOST[10] = "localhost";
[[maybe_unused]] constexpr int PORT = 19916;
[[maybe_unused]] constexpr char HOST[10] = "localhost";
[[maybe_unused]] constexpr int PORT = 19916;
template <typename T>
concept is_xad = std::is_same_v<T, xad::AReal<long double>> || std::is_same_v<T, xad::AReal<double>> ||
std::is_same_v<T, xad::AReal<float>>;
template <typename T>
concept is_xad = std::is_same_v<T, xad::AReal<long double>> ||
std::is_same_v<T, xad::AReal<double>> ||
std::is_same_v<T, xad::AReal<float>>;
template <typename T>
concept is_real = std::is_floating_point_v<T> || is_xad<T>;
template <typename T>
concept is_real = std::is_floating_point_v<T> || is_xad<T>;
template <is_real T> using EOS_P = std::function<T(const T &rho, const T &temp)>;
template <is_real T>
using EOS_P = std::function<T(const T &rho, const T &temp)>;
enum class DOMAINS : uint8_t {
CORE = 1 << 0,
ENVELOPE = 1 << 1,
VACUUM = 1 << 2,
STELLAR = CORE | ENVELOPE,
ALL = CORE | ENVELOPE | VACUUM
};
enum class DOMAINS : uint8_t {
CORE = 1 << 0,
ENVELOPE = 1 << 1,
VACUUM = 1 << 2,
STELLAR = CORE | ENVELOPE,
ALL = CORE | ENVELOPE | VACUUM
};
DOMAINS operator|(
DOMAINS lhs,
DOMAINS rhs
);
DOMAINS operator|(DOMAINS lhs, DOMAINS rhs);
DOMAINS operator&(
DOMAINS lhs,
DOMAINS rhs
);
DOMAINS operator&(DOMAINS lhs, DOMAINS rhs);
void populate_element_mask(
const mfem::Mesh *mesh,
DOMAINS domain,
mfem::Array<int> &mask
);
void populate_domain_tdofs(
const mfem::ParFiniteElementSpace *fes,
const mfem::Array<int> &element_mask,
mfem::Array<int> &ess_tdof
);
std::expected<
boundary::Bounds,
boundary::BoundsError>
discover_bounds(
const mfem::Mesh *mesh,
int vacuum_attr
);
int get_mesh_order(const mfem::Mesh &mesh);
int get_mesh_order(const mfem::Mesh &mesh);
} // namespace mean_field::utils

View File

@@ -7,9 +7,9 @@ export import :mapping.compactification.options;
export namespace mean_field::utils {
struct potential {
double rtol;
double atol;
int max_iters;
double rtol{1.0e-12};
double atol{1.0e-12};
int max_iters{1000};
};
struct rot {
@@ -18,7 +18,7 @@ export namespace mean_field::utils {
double L;
};
struct DomainMapperStatelessOptions {
struct DomainMapperOptions {
int dimension{3};
int vacuum_element_attribute{3};
};
@@ -31,7 +31,7 @@ export namespace mean_field::utils {
double index{};
double mass{};
double c{};
DomainMapperStatelessOptions domain_mapper_options{};
DomainMapperOptions domain_mapper_options{};
mapping::compactification::options::KelvinCompactificationOptions kelvin_options{};
int max_iters{};
double tol{};