feat(cpp-object-oriented-modular-refactoring): step 12 - material-property-hierarchy

This commit is contained in:
KOKO\Mimi
2026-08-16 08:48:18 +09:00
parent ec9c3e250a
commit 64a7071986
14 changed files with 746 additions and 31 deletions
+3
View File
@@ -8,6 +8,9 @@
namespace fesa {
/// @brief Identifies a semantic entity by its stable collection position.
using EntityIndex = std::uint32_t;
/// @brief Identifies the input location that produced an item or diagnostic.
struct SourceLocation {
std::filesystem::path file;
@@ -0,0 +1,68 @@
#ifndef FESA_MATERIALS_ISOTROPIC_LINEAR_ELASTIC_MATERIAL_H_
#define FESA_MATERIALS_ISOTROPIC_LINEAR_ELASTIC_MATERIAL_H_
#include <string>
#include "fesa/core/status.h"
#include "fesa/materials/material.h"
namespace fesa {
/// @brief Stores homogeneous isotropic linear-elastic material data.
/// @note Poisson ratios above 0.5 remain valid for the approved beam subset;
/// shell compatibility is checked by the shell kernel.
class IsotropicLinearElasticMaterial final : public Material {
public:
/// @brief Creates a material after validating the current elastic fields.
/// @param source_id Stable semantic identity supplied by the mapper.
/// @param name Source material name.
/// @param youngs_modulus Young's modulus in the active consistent unit
/// system.
/// @param poissons_ratio Dimensionless Poisson ratio.
/// @param location Source MATERIAL keyword location.
/// @return A material or a structured model failure.
static Result<IsotropicLinearElasticMaterial> Create(SourceEntityId source_id,
std::string name,
double youngs_modulus,
double poissons_ratio,
SourceLocation location);
/// @brief Constructs an already validated parser-owned material record.
/// @note This compatibility seam preserves existing semantic mapping until
/// Domain polymorphic ownership is migrated.
IsotropicLinearElasticMaterial(std::string name, double youngs_modulus,
double poissons_ratio,
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 Young's modulus in the active consistent unit system.
double YoungsModulus() const noexcept;
/// @brief Returns the dimensionless Poisson ratio.
double PoissonsRatio() const noexcept;
// Public storage preserves the current semantic-record API until Domain
// ownership migrates in the next approved Step.
std::string name;
double youngs_modulus;
double poisson_ratio;
SourceLocation location;
private:
/// @brief Constructs a candidate whose fields have already been checked.
IsotropicLinearElasticMaterial(SourceEntityId source_id, std::string name,
double youngs_modulus, double poissons_ratio,
SourceLocation location);
SourceEntityId source_id_;
};
} // namespace fesa
#endif // FESA_MATERIALS_ISOTROPIC_LINEAR_ELASTIC_MATERIAL_H_
+28
View File
@@ -0,0 +1,28 @@
#ifndef FESA_MATERIALS_MATERIAL_H_
#define FESA_MATERIALS_MATERIAL_H_
#include "fesa/core/source_identity.h"
namespace fesa {
/// @brief Identifies the supported concrete material semantics.
enum class MaterialKind { kIsotropicLinearElastic };
/// @brief Provides stable identity for a Domain-owned material definition.
class Material {
public:
virtual ~Material() = default;
/// @brief Returns the concrete material kind.
virtual MaterialKind Kind() const noexcept = 0;
/// @brief Returns the stable source identity preserved for diagnostics.
virtual const SourceEntityId& SourceId() const noexcept = 0;
/// @brief Returns the input location that defined the material.
virtual const SourceLocation& Location() const noexcept = 0;
};
} // namespace fesa
#endif // FESA_MATERIALS_MATERIAL_H_
+5 -31
View File
@@ -11,12 +11,12 @@
#include "fesa/core/diagnostic.h"
#include "fesa/core/source_identity.h"
#include "fesa/materials/isotropic_linear_elastic_material.h"
#include "fesa/properties/general_beam_section.h"
#include "fesa/properties/shell_section.h"
namespace fesa {
/// @brief Identifies a semantic entity by its stable collection position.
using EntityIndex = std::uint32_t;
/// @brief Stores one source node and its global coordinates.
struct Node {
SourceEntityId source_id;
@@ -24,26 +24,8 @@ struct Node {
SourceLocation location;
};
/// @brief Stores the supported homogeneous isotropic elastic properties.
struct LinearElasticMaterial {
std::string name;
double youngs_modulus;
double poisson_ratio;
SourceLocation location;
};
/// @brief Stores the supported general Euler beam section properties.
struct GeneralBeamSection {
std::string name;
double area;
double i11;
double i12;
double i22;
double torsional_constant;
std::array<double, 3> first_axis;
std::vector<std::array<double, 2>> section_points;
SourceLocation location;
};
/// @brief Keeps the current material spelling during the hierarchy migration.
using LinearElasticMaterial = IsotropicLinearElasticMaterial;
/// @brief Preserves the source shell element label independently of
/// formulation.
@@ -52,14 +34,6 @@ enum class ShellSourceElementType { kS4, kS4r };
/// @brief Names the single internal shell formulation selected by S4 and S4R.
inline constexpr std::string_view kMitc4InternalFormulation{"FESA-MITC4"};
/// @brief Stores a centered constant-thickness shell section assignment.
struct ShellSection {
std::string name;
double thickness;
EntityIndex material_index;
SourceLocation location;
};
/// @brief Defines one four-node shell with stable semantic references.
struct Mitc4ShellDefinition {
SourceEntityId source_id;
@@ -0,0 +1,28 @@
#ifndef FESA_PROPERTIES_ELEMENT_PROPERTY_H_
#define FESA_PROPERTIES_ELEMENT_PROPERTY_H_
#include "fesa/core/source_identity.h"
namespace fesa {
/// @brief Identifies the supported concrete element-property semantics.
enum class ElementPropertyKind { kGeneralBeamSection, kShellSection };
/// @brief Provides stable identity for a Domain-owned element property.
class ElementProperty {
public:
virtual ~ElementProperty() = default;
/// @brief Returns the concrete property kind.
virtual ElementPropertyKind Kind() const noexcept = 0;
/// @brief Returns the stable source identity preserved for diagnostics.
virtual const SourceEntityId& SourceId() const noexcept = 0;
/// @brief Returns the input location that defined the property.
virtual const SourceLocation& Location() const noexcept = 0;
};
} // namespace fesa
#endif // FESA_PROPERTIES_ELEMENT_PROPERTY_H_
@@ -0,0 +1,83 @@
#ifndef FESA_PROPERTIES_GENERAL_BEAM_SECTION_H_
#define FESA_PROPERTIES_GENERAL_BEAM_SECTION_H_
#include <array>
#include <string>
#include <vector>
#include "fesa/core/status.h"
#include "fesa/properties/element_property.h"
namespace fesa {
/// @brief Stores the approved general Euler-beam section properties.
class GeneralBeamSection final : public ElementProperty {
public:
/// @brief Creates a validated general beam section.
/// @param first_axis Abaqus first section axis in global coordinates.
/// @param section_points Optional section-point coordinates `(x1,x2)`.
/// @return A section or a structured model failure.
static Result<GeneralBeamSection> Create(
SourceEntityId source_id, std::string name, double area, double i11,
double i12, double i22, double torsional_constant,
std::array<double, 3> first_axis,
std::vector<std::array<double, 2>> section_points,
SourceLocation location);
/// @brief Constructs an already validated parser-owned section record.
/// @note This compatibility seam preserves current consumers until Domain
/// polymorphic ownership is migrated.
GeneralBeamSection(std::string name, double area, double i11, double i12,
double i22, double torsional_constant,
std::array<double, 3> first_axis,
std::vector<std::array<double, 2>> section_points,
SourceLocation location);
ElementPropertyKind Kind() const noexcept override;
const SourceEntityId& SourceId() const noexcept override;
const SourceLocation& Location() const noexcept override;
/// @brief Returns the source section name.
const std::string& Name() const noexcept;
/// @brief Returns cross-sectional area.
double Area() const noexcept;
/// @brief Returns the first principal section inertia input.
double I11() const noexcept;
/// @brief Returns the cross-bending inertia, which is exactly zero in V0.
double I12() const noexcept;
/// @brief Returns the second principal section inertia input.
double I22() const noexcept;
/// @brief Returns the Saint-Venant torsional constant.
double TorsionalConstant() const noexcept;
/// @brief Returns the Abaqus first section axis in global coordinates.
const std::array<double, 3>& FirstAxis() const noexcept;
/// @brief Returns optional section points in source order.
const std::vector<std::array<double, 2>>& SectionPoints() const noexcept;
// Public storage preserves the current semantic-record API until Domain
// ownership migrates in the next approved Step.
std::string name;
double area;
double i11;
double i12;
double i22;
double torsional_constant;
std::array<double, 3> first_axis;
std::vector<std::array<double, 2>> section_points;
SourceLocation location;
private:
/// @brief Constructs a candidate whose fields have already been checked.
GeneralBeamSection(SourceEntityId source_id, std::string name, double area,
double i11, double i12, double i22,
double torsional_constant,
std::array<double, 3> first_axis,
std::vector<std::array<double, 2>> section_points,
SourceLocation location);
SourceEntityId source_id_;
};
} // namespace fesa
#endif // FESA_PROPERTIES_GENERAL_BEAM_SECTION_H_
+57
View File
@@ -0,0 +1,57 @@
#ifndef FESA_PROPERTIES_SHELL_SECTION_H_
#define FESA_PROPERTIES_SHELL_SECTION_H_
#include <string>
#include "fesa/core/status.h"
#include "fesa/properties/element_property.h"
namespace fesa {
/// @brief Stores a centered constant-thickness shell section assignment.
class ShellSection final : public ElementProperty {
public:
/// @brief Creates a validated shell section.
/// @param thickness Positive thickness in the active consistent unit system.
/// @param material_index Stable Domain material collection position.
/// @return A section or a structured model failure.
static Result<ShellSection> Create(SourceEntityId source_id, std::string name,
double thickness,
EntityIndex material_index,
SourceLocation location);
/// @brief Constructs an already validated parser-owned shell record.
/// @note This compatibility seam preserves current consumers until Domain
/// polymorphic ownership is migrated.
ShellSection(std::string name, double thickness, EntityIndex material_index,
SourceLocation location);
ElementPropertyKind Kind() const noexcept override;
const SourceEntityId& SourceId() const noexcept override;
const SourceLocation& Location() const noexcept override;
/// @brief Returns the source shell-section name.
const std::string& Name() const noexcept;
/// @brief Returns centered shell thickness.
double Thickness() const noexcept;
/// @brief Returns the stable Domain material collection position.
EntityIndex MaterialIndex() const noexcept;
// Public storage preserves the current semantic-record API until Domain
// ownership migrates in the next approved Step.
std::string name;
double thickness;
EntityIndex material_index;
SourceLocation location;
private:
/// @brief Constructs a candidate whose fields have already been checked.
ShellSection(SourceEntityId source_id, std::string name, double thickness,
EntityIndex material_index, SourceLocation location);
SourceEntityId source_id_;
};
} // namespace fesa
#endif // FESA_PROPERTIES_SHELL_SECTION_H_