feat: add thermal semantic domain model
This commit is contained in:
@@ -23,6 +23,12 @@ class AnalysisModel {
|
||||
/// @brief Returns the sole active static step.
|
||||
const StepDefinition& Step() const noexcept;
|
||||
|
||||
/// @brief Reports whether this view selects the uncoupled thermal step.
|
||||
bool IsThermal() const noexcept;
|
||||
|
||||
/// @brief Returns the selected thermal step, or null for structural views.
|
||||
const ThermalStepDefinition* ThermalStep() const noexcept;
|
||||
|
||||
/// @brief Returns active element-definition indices in stable Domain order.
|
||||
const std::vector<EntityIndex>& ActiveElements() const noexcept;
|
||||
|
||||
@@ -44,6 +50,12 @@ class AnalysisModel {
|
||||
/// @brief Returns concentrated-load indices in source order.
|
||||
const std::vector<EntityIndex>& ActiveLoads() const noexcept;
|
||||
|
||||
/// @brief Returns connected DS4 element indices in stable Domain order.
|
||||
const std::vector<EntityIndex>& ActiveThermalElements() const noexcept;
|
||||
|
||||
/// @brief Returns connected thermal node indices in stable Domain order.
|
||||
const std::vector<EntityIndex>& ActiveThermalNodes() const noexcept;
|
||||
|
||||
/// @brief Returns active surface pressure records without copying Domain data.
|
||||
const std::vector<SurfacePressureLoadDefinition>& ActiveSurfacePressureLoads()
|
||||
const noexcept;
|
||||
@@ -60,6 +72,9 @@ class AnalysisModel {
|
||||
std::vector<EntityIndex> active_sections_;
|
||||
std::vector<EntityIndex> active_boundary_conditions_;
|
||||
std::vector<EntityIndex> active_loads_;
|
||||
std::vector<EntityIndex> active_thermal_elements_;
|
||||
std::vector<EntityIndex> active_thermal_nodes_;
|
||||
bool is_thermal_{false};
|
||||
};
|
||||
|
||||
} // namespace fesa
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
#ifndef FESA_ELEMENTS_DS4_THERMAL_H_
|
||||
#define FESA_ELEMENTS_DS4_THERMAL_H_
|
||||
|
||||
#include <array>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/elements/element_definition.h"
|
||||
|
||||
namespace fesa {
|
||||
|
||||
/// @brief Defines one four-node uncoupled transient thermal DS4 element.
|
||||
/// @note This semantic definition contains no geometry kernel or equation
|
||||
/// state.
|
||||
class Ds4ThermalDefinition final : public ElementDefinition {
|
||||
public:
|
||||
Ds4ThermalDefinition(SourceEntityId source_id,
|
||||
std::array<EntityIndex, 4> node_indices,
|
||||
EntityIndex section_index, SourceLocation location);
|
||||
|
||||
ElementDefinitionKind Kind() const noexcept override;
|
||||
const SourceEntityId& SourceId() const noexcept override;
|
||||
std::string_view SourceElementType() const noexcept override;
|
||||
const std::vector<EntityIndex>& NodeIndices() const noexcept override;
|
||||
EntityIndex MaterialIndex() const noexcept override;
|
||||
EntityIndex PropertyIndex() const noexcept override;
|
||||
|
||||
/// @brief Returns the stable thermal-section collection position.
|
||||
EntityIndex ThermalSectionIndex() const noexcept;
|
||||
/// @brief Returns the source location defining this element.
|
||||
const SourceLocation& Location() const noexcept;
|
||||
|
||||
private:
|
||||
friend class Domain;
|
||||
|
||||
void BindMaterialIndex(EntityIndex material_index) noexcept;
|
||||
|
||||
SourceEntityId source_id_;
|
||||
std::array<EntityIndex, 4> node_indices_;
|
||||
std::vector<EntityIndex> node_indices_view_;
|
||||
EntityIndex section_index_;
|
||||
EntityIndex material_index_{0U};
|
||||
SourceLocation location_;
|
||||
};
|
||||
|
||||
inline Ds4ThermalDefinition::Ds4ThermalDefinition(
|
||||
SourceEntityId source_id, std::array<EntityIndex, 4> node_indices,
|
||||
EntityIndex section_index, SourceLocation location)
|
||||
: source_id_{std::move(source_id)},
|
||||
node_indices_{node_indices},
|
||||
node_indices_view_{node_indices.begin(), node_indices.end()},
|
||||
section_index_{section_index},
|
||||
location_{std::move(location)} {}
|
||||
|
||||
inline ElementDefinitionKind Ds4ThermalDefinition::Kind() const noexcept {
|
||||
return ElementDefinitionKind::kDs4Thermal;
|
||||
}
|
||||
|
||||
inline const SourceEntityId& Ds4ThermalDefinition::SourceId() const noexcept {
|
||||
return source_id_;
|
||||
}
|
||||
|
||||
inline std::string_view Ds4ThermalDefinition::SourceElementType() const noexcept {
|
||||
return "DS4";
|
||||
}
|
||||
|
||||
inline const std::vector<EntityIndex>& Ds4ThermalDefinition::NodeIndices()
|
||||
const noexcept {
|
||||
return node_indices_view_;
|
||||
}
|
||||
|
||||
inline EntityIndex Ds4ThermalDefinition::MaterialIndex() const noexcept {
|
||||
return material_index_;
|
||||
}
|
||||
|
||||
inline EntityIndex Ds4ThermalDefinition::PropertyIndex() const noexcept {
|
||||
return section_index_;
|
||||
}
|
||||
|
||||
inline EntityIndex Ds4ThermalDefinition::ThermalSectionIndex() const noexcept {
|
||||
return section_index_;
|
||||
}
|
||||
|
||||
inline const SourceLocation& Ds4ThermalDefinition::Location() const noexcept {
|
||||
return location_;
|
||||
}
|
||||
|
||||
inline void Ds4ThermalDefinition::BindMaterialIndex(
|
||||
EntityIndex material_index) noexcept {
|
||||
material_index_ = material_index;
|
||||
}
|
||||
|
||||
} // namespace fesa
|
||||
|
||||
#endif // FESA_ELEMENTS_DS4_THERMAL_H_
|
||||
@@ -9,7 +9,7 @@
|
||||
namespace fesa {
|
||||
|
||||
/// @brief Identifies the supported semantic element-definition kinds.
|
||||
enum class ElementDefinitionKind { kEulerBeam3D, kMitc4Shell };
|
||||
enum class ElementDefinitionKind { kEulerBeam3D, kMitc4Shell, kDs4Thermal };
|
||||
|
||||
/// @brief Provides immutable source identity and topology for one element.
|
||||
/// @note Numerical stiffness, recovery, and equation ids are intentionally
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
#ifndef FESA_MATERIALS_ISOTROPIC_THERMAL_MATERIAL_H_
|
||||
#define FESA_MATERIALS_ISOTROPIC_THERMAL_MATERIAL_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "fesa/core/status.h"
|
||||
#include "fesa/materials/material.h"
|
||||
|
||||
namespace fesa {
|
||||
|
||||
/// @brief Stores homogeneous isotropic heat-conduction material properties.
|
||||
class IsotropicThermalMaterial final : public Material {
|
||||
public:
|
||||
/// @brief Creates a material with finite positive conductivity, density, and
|
||||
/// specific heat.
|
||||
static Result<IsotropicThermalMaterial> Create(
|
||||
SourceEntityId source_id, std::string name, double conductivity,
|
||||
double density, double specific_heat, SourceLocation location);
|
||||
|
||||
MaterialKind Kind() const noexcept override;
|
||||
const SourceEntityId& SourceId() const noexcept override;
|
||||
const SourceLocation& Location() const noexcept override;
|
||||
|
||||
/// @brief Returns the source material name.
|
||||
const std::string& Name() const noexcept;
|
||||
/// @brief Returns conductivity in the active consistent unit system.
|
||||
double Conductivity() const noexcept;
|
||||
/// @brief Returns mass density in the active consistent unit system.
|
||||
double Density() const noexcept;
|
||||
/// @brief Returns specific heat in the active consistent unit system.
|
||||
double SpecificHeat() const noexcept;
|
||||
|
||||
private:
|
||||
IsotropicThermalMaterial(SourceEntityId source_id, std::string name,
|
||||
double conductivity, double density,
|
||||
double specific_heat, SourceLocation location);
|
||||
|
||||
SourceEntityId source_id_;
|
||||
std::string name_;
|
||||
double conductivity_;
|
||||
double density_;
|
||||
double specific_heat_;
|
||||
SourceLocation location_;
|
||||
};
|
||||
|
||||
} // namespace fesa
|
||||
|
||||
#endif // FESA_MATERIALS_ISOTROPIC_THERMAL_MATERIAL_H_
|
||||
@@ -6,7 +6,7 @@
|
||||
namespace fesa {
|
||||
|
||||
/// @brief Identifies the supported concrete material semantics.
|
||||
enum class MaterialKind { kIsotropicLinearElastic };
|
||||
enum class MaterialKind { kIsotropicLinearElastic, kIsotropicThermal };
|
||||
|
||||
/// @brief Provides stable identity for a Domain-owned material definition.
|
||||
class Material {
|
||||
|
||||
@@ -183,6 +183,30 @@ class Domain {
|
||||
const DomainCollectionView<LinearElasticMaterial>& LinearElasticMaterials()
|
||||
const noexcept;
|
||||
|
||||
/// @brief Returns thermal materials in stable thermal declaration order.
|
||||
const DomainCollectionView<IsotropicThermalMaterial>& ThermalMaterials()
|
||||
const noexcept;
|
||||
|
||||
/// @brief Returns DS4 definitions in stable thermal declaration order.
|
||||
const DomainCollectionView<Ds4ThermalDefinition>& ThermalElements()
|
||||
const noexcept;
|
||||
|
||||
/// @brief Returns centered thermal shell assignments in declaration order.
|
||||
const std::vector<ThermalShellSectionDefinition>& ThermalSections()
|
||||
const noexcept;
|
||||
|
||||
/// @brief Returns resolved initial temperatures in source order.
|
||||
const std::vector<ThermalInitialConditionDefinition>&
|
||||
ThermalInitialConditions() const noexcept;
|
||||
|
||||
/// @brief Returns model-level thermal boundary definitions in source order.
|
||||
const std::vector<ThermalBoundaryConditionDefinition>&
|
||||
ThermalModelBoundaries() const noexcept;
|
||||
|
||||
/// @brief Returns the sole thermal step, or null when the model is
|
||||
/// structural.
|
||||
const ThermalStepDefinition* ThermalStep() const noexcept;
|
||||
|
||||
/// @brief Returns all properties in stable Domain index order.
|
||||
const DomainCollectionView<ElementProperty>& Properties() const noexcept;
|
||||
|
||||
@@ -243,6 +267,8 @@ class Domain {
|
||||
DomainCollectionView<ShellSection> shell_sections_view_;
|
||||
DomainCollectionView<Material> materials_view_;
|
||||
DomainCollectionView<LinearElasticMaterial> linear_materials_view_;
|
||||
DomainCollectionView<IsotropicThermalMaterial> thermal_materials_view_;
|
||||
DomainCollectionView<Ds4ThermalDefinition> thermal_elements_view_;
|
||||
DomainCollectionView<StepDefinition> steps_view_;
|
||||
};
|
||||
|
||||
|
||||
@@ -12,9 +12,11 @@
|
||||
|
||||
#include "fesa/core/diagnostic.h"
|
||||
#include "fesa/core/source_identity.h"
|
||||
#include "fesa/elements/ds4_thermal.h"
|
||||
#include "fesa/elements/euler_beam_3d.h"
|
||||
#include "fesa/elements/mitc4_shell.h"
|
||||
#include "fesa/materials/isotropic_linear_elastic_material.h"
|
||||
#include "fesa/materials/isotropic_thermal_material.h"
|
||||
#include "fesa/properties/general_beam_section.h"
|
||||
#include "fesa/properties/shell_section.h"
|
||||
|
||||
@@ -226,6 +228,89 @@ struct DynamicStepDefinition {
|
||||
std::vector<NodalLoad> loads;
|
||||
};
|
||||
|
||||
/// @brief Stores homogeneous isotropic thermal material source data.
|
||||
struct ThermalMaterialDefinition {
|
||||
SourceEntityId source_id;
|
||||
std::string name;
|
||||
double conductivity;
|
||||
double density;
|
||||
double specific_heat;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
/// @brief Stores one centered homogeneous thermal shell assignment.
|
||||
struct ThermalShellSectionDefinition {
|
||||
SourceEntityId source_id;
|
||||
std::string name;
|
||||
double thickness;
|
||||
EntityIndex material_index;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
/// @brief Stores one DS4 definition before Domain ownership.
|
||||
struct Ds4ThermalElementDefinition {
|
||||
SourceEntityId source_id;
|
||||
std::array<EntityIndex, 4> node_indices;
|
||||
EntityIndex section_index;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
/// @brief Stores one resolved initial temperature target at five stations.
|
||||
struct ThermalInitialConditionDefinition {
|
||||
ThermalInitialConditionDefinition(EntityIndex target_node, double value,
|
||||
SourceLocation source_location)
|
||||
: node_index{target_node},
|
||||
station_values{{value, value, value, value, value}},
|
||||
location{std::move(source_location)} {}
|
||||
|
||||
EntityIndex node_index;
|
||||
std::array<double, 5> station_values;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
/// @brief Stores one prescribed thermal source DOF value.
|
||||
struct ThermalBoundaryConditionDefinition {
|
||||
EntityIndex node_index;
|
||||
int dof;
|
||||
double value;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
/// @brief Stores one signed inward CFlux source contribution.
|
||||
struct ThermalFluxLoadDefinition {
|
||||
EntityIndex node_index;
|
||||
int dof;
|
||||
double power;
|
||||
SourceLocation location;
|
||||
std::size_t source_order{0U};
|
||||
};
|
||||
|
||||
/// @brief Stores uncoupled transient heat-step controls without a time grid.
|
||||
struct ThermalStepDefinition {
|
||||
std::string name;
|
||||
double nominal_increment;
|
||||
double time_period;
|
||||
std::uint32_t maximum_increments{100U};
|
||||
bool nlgeom{false};
|
||||
std::vector<ThermalBoundaryConditionDefinition> boundaries;
|
||||
std::vector<ThermalFluxLoadDefinition> loads;
|
||||
SourceLocation location;
|
||||
|
||||
/// @brief Returns thermal boundaries in stable source order.
|
||||
const std::vector<ThermalBoundaryConditionDefinition>& Boundaries() const
|
||||
noexcept {
|
||||
return boundaries;
|
||||
}
|
||||
|
||||
/// @brief Returns additive thermal fluxes in stable source order.
|
||||
const std::vector<ThermalFluxLoadDefinition>& Loads() const noexcept {
|
||||
return loads;
|
||||
}
|
||||
|
||||
static constexpr std::array<double, 5> kStationZeta{
|
||||
{-1.0, -0.5, 0.0, 0.5, 1.0}};
|
||||
};
|
||||
|
||||
/// @brief Stores a stable resolved node-set membership list.
|
||||
struct NodeSet {
|
||||
std::string name;
|
||||
@@ -278,8 +363,11 @@ struct ModelDefinition {
|
||||
std::vector<EulerBeam3DDefinition> elements;
|
||||
std::vector<Mitc4ShellDefinition> shell_elements;
|
||||
std::vector<LinearElasticMaterial> materials;
|
||||
std::vector<ThermalMaterialDefinition> thermal_materials;
|
||||
std::vector<GeneralBeamSection> sections;
|
||||
std::vector<ShellSection> shell_sections;
|
||||
std::vector<ThermalShellSectionDefinition> thermal_sections;
|
||||
std::vector<Ds4ThermalElementDefinition> thermal_elements;
|
||||
std::vector<ShellNodeInitialFrame> shell_node_initial_frames;
|
||||
std::vector<NodeSet> node_sets;
|
||||
std::vector<ElementSet> element_sets;
|
||||
@@ -290,6 +378,9 @@ struct ModelDefinition {
|
||||
std::vector<MaterialDensityDefinition> densities;
|
||||
std::optional<FrequencyStepDefinition> frequency_step;
|
||||
std::optional<DynamicStepDefinition> dynamic_step;
|
||||
std::vector<ThermalInitialConditionDefinition> thermal_initial_conditions;
|
||||
std::vector<ThermalBoundaryConditionDefinition> thermal_model_boundaries;
|
||||
std::optional<ThermalStepDefinition> thermal_step;
|
||||
std::vector<Diagnostic> warnings;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user