feat: add thermal dof mapping

This commit is contained in:
KOKO\Mimi
2026-09-29 18:59:04 +09:00
parent 878a71bd96
commit e71f3ad9ac
4 changed files with 313 additions and 0 deletions
+21
View File
@@ -9,12 +9,15 @@
#include "fesa/analysis/analysis_model.h"
#include "fesa/constraints/boundary_condition.h"
#include "fesa/elements/element.h"
#include "fesa/elements/thermal_element_layout.h"
#include "fesa/math/vector.h"
namespace fesa {
class DofManagerTestAccess;
enum class DofProfile { kStructural, kThermal };
/// @brief Stores the stable structural CSR pattern.
struct SparsePattern {
std::vector<std::size_t> row_offsets;
@@ -32,6 +35,9 @@ class DofManager {
/// the procedure-owned runtime element view supersedes it in Step 20.
static Result<DofManager> Create(const AnalysisModel& model);
/// @brief Builds the active DS4 five-station equation mapping.
static Result<DofManager> CreateThermal(const AnalysisModel& model);
/// @brief Builds mappings from runtime element layouts in supplied order.
/// @param analysis_model Non-owning active model view that outlives this
/// call.
@@ -46,6 +52,13 @@ class DofManager {
Status Build(const AnalysisModel& analysis_model, const ElementView& elements,
const BoundaryConditionView& boundaries);
/// @brief Builds thermal mappings from stable DS4 semantic layouts.
Status BuildThermal(const AnalysisModel& analysis_model,
const std::vector<ThermalElementDofLayout>& layouts);
/// @brief Reports which physical component profile owns this mapping.
DofProfile Profile() const noexcept;
/// @brief Returns the full node-by-component DOF count.
std::size_t FullDofCount() const noexcept;
/// @brief Returns the free-equation count.
@@ -54,12 +67,18 @@ class DofManager {
std::size_t ConstrainedDofCount() const noexcept;
/// @brief Maps a stable node index and component to a full DOF.
std::size_t FullDof(EntityIndex node, DofComponent component) const;
/// @brief Maps an active thermal Domain node and station to a full DOF.
std::size_t FullThermalDof(EntityIndex node,
ThermalDofComponent component) const;
/// @brief Returns the free equation for a full DOF when unconstrained.
std::optional<std::size_t> FreeEquation(std::size_t full_dof) const;
/// @brief Maps one declared runtime layout to stable full DOFs.
/// @return The declared node/component scatter or a layout failure.
Result<std::vector<std::size_t>> ElementScatter(
const ElementDofLayout& layout) const;
/// @brief Maps one DS4 layout to its node-major 20-entry scatter.
Result<std::vector<std::size_t>> ThermalElementScatter(
const ThermalElementDofLayout& layout) const;
/// @brief Returns a beam scatter in endpoint/component order.
/// @note This compatibility wrapper delegates to the generic stored layout.
std::array<std::size_t, 12> ElementScatter(EntityIndex element) const;
@@ -100,6 +119,8 @@ class DofManager {
std::vector<std::size_t> constrained_dofs_;
Vector prescribed_values_{0U};
SparsePattern sparse_pattern_;
DofProfile profile_{DofProfile::kStructural};
std::vector<std::optional<std::size_t>> thermal_node_rows_;
};
} // namespace fesa