feat(cpp-object-oriented-modular-refactoring): step 4 - model-element-google-style
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "fesa/model/domain.hpp"
|
||||
#include "fesa/model/domain.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
#include "fesa/fem/dof_manager.hpp"
|
||||
#include "fesa/math/sparse_matrix.h"
|
||||
#include "fesa/math/vector.h"
|
||||
#include "fesa/model/domain.hpp"
|
||||
#include "fesa/model/domain.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
#ifndef FESA_ELEMENTS_EULER_BEAM_3D_H_
|
||||
#define FESA_ELEMENTS_EULER_BEAM_3D_H_
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/core/status.h"
|
||||
#include "fesa/math/matrix.h"
|
||||
#include "fesa/math/vector.h"
|
||||
#include "fesa/model/model_types.h"
|
||||
|
||||
namespace fesa {
|
||||
|
||||
/// @brief Stores constant line-load components in the beam local frame.
|
||||
struct ConstantLocalLineLoad {
|
||||
double px;
|
||||
double py;
|
||||
double pz;
|
||||
double mx;
|
||||
};
|
||||
|
||||
/// @brief Stores one axial stress at a Gauss and section-point identity.
|
||||
struct BeamStressPoint {
|
||||
int gauss_point;
|
||||
std::size_t section_point;
|
||||
double x1;
|
||||
double x2;
|
||||
double s11;
|
||||
std::string source;
|
||||
};
|
||||
|
||||
/// @brief Stores distinct beam end-action, section, Gauss, and stress results.
|
||||
struct BeamRecovery {
|
||||
std::array<std::array<double, 6>, 2> equilibrium_end_actions;
|
||||
std::array<std::array<double, 4>, 2> endpoint_section_resultants;
|
||||
std::array<std::array<double, 4>, 2> gauss_generalized_strains;
|
||||
std::array<std::array<double, 4>, 2> gauss_generalized_resultants;
|
||||
std::vector<BeamStressPoint> stress_points;
|
||||
};
|
||||
|
||||
/// @brief Implements the approved two-node prismatic B33 Euler beam kernel.
|
||||
/// @note Equation numbering and semantic element identity remain external.
|
||||
class EulerBeam3D {
|
||||
public:
|
||||
/// @brief Creates a validated beam kernel and right-handed local frame.
|
||||
/// @param first_node First source node in the element connectivity.
|
||||
/// @param second_node Second source node in the element connectivity.
|
||||
/// @param section Supported general beam section and local first axis.
|
||||
/// @param material Supported isotropic elastic material.
|
||||
/// @return A validated beam or a structured model failure.
|
||||
static Result<EulerBeam3D> Create(const Node& first_node,
|
||||
const Node& second_node,
|
||||
const GeneralBeamSection& section,
|
||||
const LinearElasticMaterial& material);
|
||||
|
||||
/// @brief Computes the 12-by-12 stiffness in local DOF order.
|
||||
/// @note Uses the approved two-point Gauss operation order.
|
||||
Matrix LocalStiffness() const;
|
||||
|
||||
/// @brief Computes the stiffness in stable global element DOF order.
|
||||
Matrix GlobalStiffness() const;
|
||||
|
||||
/// @brief Computes the formulation-only constant local line-load vector.
|
||||
/// @warning This kernel does not expose distributed loads through parser
|
||||
/// input.
|
||||
Vector LocalEquivalentLoad(const ConstantLocalLineLoad& load) const;
|
||||
|
||||
/// @brief Recovers signed physical quantities at their distinct locations.
|
||||
/// @param global_element_displacement Twelve global element DOF values.
|
||||
/// @return Beam recovery rows in deterministic location order.
|
||||
BeamRecovery Recover(const Vector& global_element_displacement) const;
|
||||
|
||||
private:
|
||||
/// @brief Stores already validated geometry, material, and section state.
|
||||
EulerBeam3D(double length, double youngs_modulus, double shear_modulus,
|
||||
double area, double iy, double iz, double torsional_constant,
|
||||
std::array<double, 9> rotation,
|
||||
std::vector<std::array<double, 2>> section_points);
|
||||
|
||||
double length_;
|
||||
double youngs_modulus_;
|
||||
double shear_modulus_;
|
||||
double area_;
|
||||
double iy_;
|
||||
double iz_;
|
||||
double torsional_constant_;
|
||||
std::array<double, 9> rotation_;
|
||||
std::vector<std::array<double, 2>> section_points_;
|
||||
};
|
||||
|
||||
} // namespace fesa
|
||||
|
||||
#endif // FESA_ELEMENTS_EULER_BEAM_3D_H_
|
||||
@@ -1,74 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "fesa/core/status.h"
|
||||
#include "fesa/math/matrix.h"
|
||||
#include "fesa/math/vector.h"
|
||||
#include "fesa/model/model_types.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace fesa {
|
||||
|
||||
struct ConstantLocalLineLoad {
|
||||
double px;
|
||||
double py;
|
||||
double pz;
|
||||
double mx;
|
||||
};
|
||||
|
||||
struct BeamStressPoint {
|
||||
int gaussPoint;
|
||||
std::size_t sectionPoint;
|
||||
double x1;
|
||||
double x2;
|
||||
double s11;
|
||||
std::string source;
|
||||
};
|
||||
|
||||
struct BeamRecovery {
|
||||
std::array<std::array<double, 6>, 2> equilibriumEndActions;
|
||||
std::array<std::array<double, 4>, 2> endpointSectionResultants;
|
||||
std::array<std::array<double, 4>, 2> gaussGeneralizedStrains;
|
||||
std::array<std::array<double, 4>, 2> gaussGeneralizedResultants;
|
||||
std::vector<BeamStressPoint> stressPoints;
|
||||
};
|
||||
|
||||
// Implements the approved two-node straight prismatic B33 Euler-Bernoulli
|
||||
// kernel. Equation numbering and element identity remain outside this type.
|
||||
class EulerBeam3D {
|
||||
public:
|
||||
static Result<EulerBeam3D> create(const Node& firstNode,
|
||||
const Node& secondNode,
|
||||
const GeneralBeamSection& section,
|
||||
const LinearElasticMaterial& material);
|
||||
Matrix localStiffness() const;
|
||||
Matrix globalStiffness() const;
|
||||
Vector localEquivalentLoad(const ConstantLocalLineLoad& load) const;
|
||||
BeamRecovery recover(const Vector& globalElementDisplacement) const;
|
||||
|
||||
private:
|
||||
EulerBeam3D(double length,
|
||||
double youngsModulus,
|
||||
double shearModulus,
|
||||
double area,
|
||||
double iy,
|
||||
double iz,
|
||||
double torsionalConstant,
|
||||
std::array<double, 9> rotation,
|
||||
std::vector<std::array<double, 2>> sectionPoints);
|
||||
|
||||
double length_;
|
||||
double youngsModulus_;
|
||||
double shearModulus_;
|
||||
double area_;
|
||||
double iy_;
|
||||
double iz_;
|
||||
double torsionalConstant_;
|
||||
std::array<double, 9> rotation_;
|
||||
std::vector<std::array<double, 2>> sectionPoints_;
|
||||
};
|
||||
|
||||
} // namespace fesa
|
||||
@@ -0,0 +1,179 @@
|
||||
#ifndef FESA_ELEMENTS_MITC4_SHELL_H_
|
||||
#define FESA_ELEMENTS_MITC4_SHELL_H_
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
#include "fesa/core/status.h"
|
||||
#include "fesa/math/matrix.h"
|
||||
#include "fesa/math/vector.h"
|
||||
#include "fesa/model/model_types.h"
|
||||
|
||||
namespace fesa {
|
||||
|
||||
/// @brief Stores bilinear shape values and natural-coordinate derivatives.
|
||||
struct Mitc4ShapeFunctions {
|
||||
std::array<double, 4> values;
|
||||
std::array<double, 4> xi_derivatives;
|
||||
std::array<double, 4> eta_derivatives;
|
||||
};
|
||||
|
||||
/// @brief Stores a right-handed local shell frame at one location.
|
||||
struct Mitc4LocalFrame {
|
||||
std::array<double, 3> e1;
|
||||
std::array<double, 3> e2;
|
||||
std::array<double, 3> e3;
|
||||
};
|
||||
|
||||
/// @brief Stores canonical MITC4 covariant shear interpolation weights.
|
||||
struct Mitc4TyingWeights {
|
||||
std::array<double, 2> xi_zeta;
|
||||
std::array<double, 2> eta_zeta;
|
||||
};
|
||||
|
||||
/// @brief Stores one fixed 2-by-2-by-2 integration point and weight.
|
||||
struct Mitc4QuadraturePoint {
|
||||
std::array<double, 3> natural_coordinates;
|
||||
double weight;
|
||||
};
|
||||
|
||||
/// @brief Separates physical, drilling, and stabilized stiffness matrices.
|
||||
struct Mitc4Stiffness {
|
||||
Matrix physical_local20;
|
||||
Matrix physical_global24;
|
||||
Matrix drilling_global24;
|
||||
Matrix stabilized_global24;
|
||||
double drilling_stiffness;
|
||||
};
|
||||
|
||||
/// @brief Stores physical shell recovery at one midsurface Gauss location.
|
||||
struct Mitc4PhysicalRecoveryPoint {
|
||||
std::array<double, 2> natural_coordinates;
|
||||
Mitc4LocalFrame local_frame;
|
||||
std::array<double, 8> generalized_strain;
|
||||
std::array<double, 8> section_resultant;
|
||||
std::array<std::array<double, 3>, 3> in_plane_stress;
|
||||
};
|
||||
|
||||
/// @brief Stores physical-only recovery rows and strain energy.
|
||||
struct Mitc4PhysicalRecovery {
|
||||
std::array<Mitc4PhysicalRecoveryPoint, 4> points;
|
||||
double strain_energy;
|
||||
};
|
||||
|
||||
/// @brief Implements the approved small-rotation FESA-MITC4 shell kernel.
|
||||
/// @note Physical and numerical drilling contributions remain separate.
|
||||
class Mitc4Shell {
|
||||
public:
|
||||
/// @brief Creates a validated shell kernel from four non-owning node
|
||||
/// pointers.
|
||||
/// @param nodes Node pointers valid for the duration of this call.
|
||||
/// @param initial_directors Validated unit initial directors in node order.
|
||||
/// @param section Centered constant-thickness shell section.
|
||||
/// @param material Supported isotropic elastic material.
|
||||
/// @return A validated shell or a structured model failure.
|
||||
static Result<Mitc4Shell> Create(
|
||||
std::array<const Node*, 4> nodes,
|
||||
std::array<std::array<double, 3>, 4> initial_directors,
|
||||
const ShellSection& section, const LinearElasticMaterial& material);
|
||||
|
||||
/// @brief Evaluates bilinear shape functions and derivatives.
|
||||
static Mitc4ShapeFunctions ShapeFunctions(double xi, double eta) noexcept;
|
||||
|
||||
/// @brief Evaluates the canonical edge-midpoint tying weights.
|
||||
static Mitc4TyingWeights TyingWeights(double xi, double eta) noexcept;
|
||||
|
||||
/// @brief Returns the fixed 2-by-2-by-2 quadrature inventory.
|
||||
static const std::array<Mitc4QuadraturePoint, 8>& VolumeQuadrature() noexcept;
|
||||
|
||||
/// @brief Evaluates the right-handed local frame at a midsurface location.
|
||||
[[nodiscard]] Mitc4LocalFrame LocalFrame(double xi, double eta) const;
|
||||
|
||||
/// @brief Returns the physical 24-to-20 transformation.
|
||||
[[nodiscard]] Matrix PhysicalTransformation20() const;
|
||||
|
||||
/// @brief Returns the numerical drilling 24-to-4 transformation.
|
||||
[[nodiscard]] Matrix DrillingTransformation4() const;
|
||||
|
||||
/// @brief Evaluates the direct five-component physical strain operator.
|
||||
[[nodiscard]] Matrix DirectStrainDisplacement20(double xi, double eta,
|
||||
double zeta) const;
|
||||
|
||||
/// @brief Evaluates all four canonical covariant tying shear samples.
|
||||
[[nodiscard]] Matrix CovariantTyingShearSamples20() const;
|
||||
|
||||
/// @brief Evaluates the MITC-projected five-component strain operator.
|
||||
[[nodiscard]] Matrix StrainDisplacement20(double xi, double eta,
|
||||
double zeta) const;
|
||||
|
||||
/// @brief Returns the isotropic in-plane plane-stress matrix.
|
||||
[[nodiscard]] Matrix PlaneStressConstitutive() const;
|
||||
|
||||
/// @brief Returns the five-component plane-stress and shear matrix.
|
||||
[[nodiscard]] Matrix MaterialConstitutive5() const;
|
||||
|
||||
/// @brief Returns the centered membrane section matrix.
|
||||
[[nodiscard]] Matrix MembraneSectionMatrix() const;
|
||||
|
||||
/// @brief Returns the centered bending section matrix.
|
||||
[[nodiscard]] Matrix BendingSectionMatrix() const;
|
||||
|
||||
/// @brief Returns the corrected transverse-shear section matrix.
|
||||
[[nodiscard]] Matrix TransverseShearSectionMatrix() const;
|
||||
|
||||
/// @brief Computes physical, drilling, and stabilized stiffness matrices.
|
||||
/// @return Finite stiffness matrices or a structured model failure.
|
||||
[[nodiscard]] Result<Mitc4Stiffness> Stiffness() const;
|
||||
|
||||
/// @brief Recovers physical shell quantities without drilling results.
|
||||
/// @param global_element_displacement24 Global element DOFs in node order.
|
||||
/// @return Physical recovery rows or a structured model failure.
|
||||
[[nodiscard]] Result<Mitc4PhysicalRecovery> RecoverPhysical(
|
||||
const Vector& global_element_displacement24) const;
|
||||
|
||||
private:
|
||||
using Vector3 = std::array<double, 3>;
|
||||
|
||||
/// @brief Stores covariant, reciprocal, frame, and Jacobian data at one
|
||||
/// point.
|
||||
struct GeometryData {
|
||||
std::array<Vector3, 3> covariant;
|
||||
std::array<Vector3, 3> reciprocal;
|
||||
Mitc4LocalFrame frame;
|
||||
double jacobian;
|
||||
};
|
||||
|
||||
/// @brief Stores validated shell geometry and constitutive state.
|
||||
Mitc4Shell(std::array<Vector3, 4> coordinates,
|
||||
std::array<Vector3, 4> directors, std::array<Vector3, 4> tangent_a,
|
||||
std::array<Vector3, 4> tangent_b, Vector3 normal_candidate,
|
||||
double thickness, double youngs_modulus, double poisson_ratio,
|
||||
SourceLocation source_location, std::string identity);
|
||||
|
||||
/// @brief Evaluates a finite positive Jacobian and right-handed frame.
|
||||
bool EvaluateGeometry(double xi, double eta, double zeta,
|
||||
GeometryData& result) const noexcept;
|
||||
|
||||
/// @brief Evaluates displacement-basis derivatives in covariant directions.
|
||||
std::array<std::array<Vector3, 3>, 20> BasisDerivatives(
|
||||
double xi, double eta, double zeta) const noexcept;
|
||||
|
||||
/// @brief Builds direct or tied strain without changing projection order.
|
||||
Matrix StrainDisplacement(double xi, double eta, double zeta,
|
||||
const Matrix* tying_samples) const;
|
||||
|
||||
std::array<Vector3, 4> coordinates_;
|
||||
std::array<Vector3, 4> directors_;
|
||||
std::array<Vector3, 4> tangent_a_;
|
||||
std::array<Vector3, 4> tangent_b_;
|
||||
Vector3 normal_candidate_;
|
||||
double thickness_;
|
||||
double youngs_modulus_;
|
||||
double poisson_ratio_;
|
||||
SourceLocation source_location_;
|
||||
std::string identity_;
|
||||
};
|
||||
|
||||
} // namespace fesa
|
||||
|
||||
#endif // FESA_ELEMENTS_MITC4_SHELL_H_
|
||||
@@ -1,142 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "fesa/core/status.h"
|
||||
#include "fesa/math/matrix.h"
|
||||
#include "fesa/math/vector.h"
|
||||
#include "fesa/model/model_types.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
|
||||
namespace fesa {
|
||||
|
||||
struct Mitc4ShapeFunctions {
|
||||
std::array<double, 4> values;
|
||||
std::array<double, 4> xiDerivatives;
|
||||
std::array<double, 4> etaDerivatives;
|
||||
};
|
||||
|
||||
struct Mitc4LocalFrame {
|
||||
std::array<double, 3> e1;
|
||||
std::array<double, 3> e2;
|
||||
std::array<double, 3> e3;
|
||||
};
|
||||
|
||||
struct Mitc4TyingWeights {
|
||||
std::array<double, 2> xiZeta;
|
||||
std::array<double, 2> etaZeta;
|
||||
};
|
||||
|
||||
struct Mitc4QuadraturePoint {
|
||||
std::array<double, 3> naturalCoordinates;
|
||||
double weight;
|
||||
};
|
||||
|
||||
struct Mitc4Stiffness {
|
||||
Matrix physicalLocal20;
|
||||
Matrix physicalGlobal24;
|
||||
Matrix drillingGlobal24;
|
||||
Matrix stabilizedGlobal24;
|
||||
double drillingStiffness;
|
||||
};
|
||||
|
||||
struct Mitc4PhysicalRecoveryPoint {
|
||||
std::array<double, 2> naturalCoordinates;
|
||||
Mitc4LocalFrame localFrame;
|
||||
std::array<double, 8> generalizedStrain;
|
||||
std::array<double, 8> sectionResultant;
|
||||
std::array<std::array<double, 3>, 3> inPlaneStress;
|
||||
};
|
||||
|
||||
struct Mitc4PhysicalRecovery {
|
||||
std::array<Mitc4PhysicalRecoveryPoint, 4> points;
|
||||
double strainEnergy;
|
||||
};
|
||||
|
||||
// Concrete small-rotation MITC4 kinematics, constitutive, stiffness, and
|
||||
// physical-only recovery kernel. Global equation/result ownership remains outside.
|
||||
class Mitc4Shell {
|
||||
public:
|
||||
static Result<Mitc4Shell> create(
|
||||
std::array<const Node*, 4> nodes,
|
||||
std::array<std::array<double, 3>, 4> initialDirectors,
|
||||
const ShellSection& section,
|
||||
const LinearElasticMaterial& material);
|
||||
|
||||
static Mitc4ShapeFunctions shapeFunctions(double xi, double eta) noexcept;
|
||||
static Mitc4TyingWeights tyingWeights(double xi, double eta) noexcept;
|
||||
static const std::array<Mitc4QuadraturePoint, 8>&
|
||||
volumeQuadrature() noexcept;
|
||||
|
||||
[[nodiscard]] Mitc4LocalFrame localFrame(double xi, double eta) const;
|
||||
[[nodiscard]] Matrix physicalTransformation20() const;
|
||||
[[nodiscard]] Matrix drillingTransformation4() const;
|
||||
[[nodiscard]] Matrix directStrainDisplacement20(
|
||||
double xi,
|
||||
double eta,
|
||||
double zeta) const;
|
||||
[[nodiscard]] Matrix covariantTyingShearSamples20() const;
|
||||
[[nodiscard]] Matrix strainDisplacement20(
|
||||
double xi,
|
||||
double eta,
|
||||
double zeta) const;
|
||||
|
||||
[[nodiscard]] Matrix planeStressConstitutive() const;
|
||||
[[nodiscard]] Matrix materialConstitutive5() const;
|
||||
[[nodiscard]] Matrix membraneSectionMatrix() const;
|
||||
[[nodiscard]] Matrix bendingSectionMatrix() const;
|
||||
[[nodiscard]] Matrix transverseShearSectionMatrix() const;
|
||||
[[nodiscard]] Result<Mitc4Stiffness> stiffness() const;
|
||||
[[nodiscard]] Result<Mitc4PhysicalRecovery> recoverPhysical(
|
||||
const Vector& globalElementDisplacement24) const;
|
||||
|
||||
private:
|
||||
using Vector3 = std::array<double, 3>;
|
||||
|
||||
struct GeometryData {
|
||||
std::array<Vector3, 3> covariant;
|
||||
std::array<Vector3, 3> reciprocal;
|
||||
Mitc4LocalFrame frame;
|
||||
double jacobian;
|
||||
};
|
||||
|
||||
Mitc4Shell(
|
||||
std::array<Vector3, 4> coordinates,
|
||||
std::array<Vector3, 4> directors,
|
||||
std::array<Vector3, 4> tangentA,
|
||||
std::array<Vector3, 4> tangentB,
|
||||
Vector3 normalCandidate,
|
||||
double thickness,
|
||||
double youngsModulus,
|
||||
double poissonRatio,
|
||||
SourceLocation sourceLocation,
|
||||
std::string identity);
|
||||
|
||||
bool evaluateGeometry(
|
||||
double xi,
|
||||
double eta,
|
||||
double zeta,
|
||||
GeometryData& result) const noexcept;
|
||||
std::array<std::array<Vector3, 3>, 20> basisDerivatives(
|
||||
double xi,
|
||||
double eta,
|
||||
double zeta) const noexcept;
|
||||
Matrix strainDisplacement(
|
||||
double xi,
|
||||
double eta,
|
||||
double zeta,
|
||||
const Matrix* tyingSamples) const;
|
||||
|
||||
std::array<Vector3, 4> coordinates_;
|
||||
std::array<Vector3, 4> directors_;
|
||||
std::array<Vector3, 4> tangentA_;
|
||||
std::array<Vector3, 4> tangentB_;
|
||||
Vector3 normalCandidate_;
|
||||
double thickness_;
|
||||
double youngsModulus_;
|
||||
double poissonRatio_;
|
||||
SourceLocation sourceLocation_;
|
||||
std::string identity_;
|
||||
};
|
||||
|
||||
} // namespace fesa
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
#include "fesa/core/status.h"
|
||||
#include "fesa/io/abaqus/input_syntax.hpp"
|
||||
#include "fesa/model/domain.hpp"
|
||||
#include "fesa/model/domain.h"
|
||||
|
||||
namespace fesa {
|
||||
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
#ifndef FESA_MODEL_DOMAIN_H_
|
||||
#define FESA_MODEL_DOMAIN_H_
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/core/status.h"
|
||||
#include "fesa/model/model_types.h"
|
||||
|
||||
namespace fesa {
|
||||
|
||||
/// @brief Owns the complete immutable semantic model definition.
|
||||
/// @note Collection positions remain stable internal indices after
|
||||
/// construction.
|
||||
class Domain {
|
||||
public:
|
||||
/// @brief Creates a Domain that owns a copy or moved model definition.
|
||||
/// @param definition Complete parsed semantic records in declaration order.
|
||||
/// @return A successful owning Domain.
|
||||
static Result<Domain> Create(ModelDefinition definition);
|
||||
|
||||
/// @brief Returns nodes in stable declaration order.
|
||||
const std::vector<Node>& Nodes() const noexcept;
|
||||
|
||||
/// @brief Returns Euler beam definitions in stable declaration order.
|
||||
const std::vector<EulerBeam3DDefinition>& Elements() const noexcept;
|
||||
|
||||
/// @brief Returns MITC4 shell definitions in stable declaration order.
|
||||
const std::vector<Mitc4ShellDefinition>& ShellElements() const noexcept;
|
||||
|
||||
/// @brief Returns materials in stable declaration order.
|
||||
const std::vector<LinearElasticMaterial>& Materials() const noexcept;
|
||||
|
||||
/// @brief Returns beam sections in stable declaration order.
|
||||
const std::vector<GeneralBeamSection>& Sections() const noexcept;
|
||||
|
||||
/// @brief Returns shell sections in stable declaration order.
|
||||
const std::vector<ShellSection>& ShellSections() const noexcept;
|
||||
|
||||
/// @brief Returns preprocessed shell-node frames in stable node order.
|
||||
const std::vector<ShellNodeInitialFrame>& ShellNodeInitialFrames()
|
||||
const noexcept;
|
||||
|
||||
/// @brief Returns node sets in stable declaration order.
|
||||
const std::vector<NodeSet>& NodeSets() const noexcept;
|
||||
|
||||
/// @brief Returns element sets in stable declaration order.
|
||||
const std::vector<ElementSet>& ElementSets() const noexcept;
|
||||
|
||||
/// @brief Returns static steps in stable declaration order.
|
||||
const std::vector<StaticStepDefinition>& Steps() const noexcept;
|
||||
|
||||
/// @brief Returns sorted nonfatal mapping diagnostics.
|
||||
const std::vector<Diagnostic>& Warnings() const noexcept;
|
||||
|
||||
/// @brief Returns the source input path associated with this model.
|
||||
const std::filesystem::path& SourcePath() const noexcept;
|
||||
|
||||
/// @brief Returns the deterministic source-content identity.
|
||||
const std::string& SourceContentIdentity() const noexcept;
|
||||
|
||||
private:
|
||||
/// @brief Takes ownership of an already constructed model definition.
|
||||
explicit Domain(ModelDefinition definition);
|
||||
|
||||
ModelDefinition definition_;
|
||||
};
|
||||
|
||||
} // namespace fesa
|
||||
|
||||
#endif // FESA_MODEL_DOMAIN_H_
|
||||
@@ -1,38 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "fesa/core/status.h"
|
||||
#include "fesa/model/model_types.hpp"
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace fesa {
|
||||
|
||||
// Owns the complete semantic definition. Public access remains const so a
|
||||
// vector position can serve as a stable internal index after construction.
|
||||
class Domain {
|
||||
public:
|
||||
static Result<Domain> create(ModelDefinition definition);
|
||||
|
||||
const std::vector<Node>& nodes() const noexcept;
|
||||
const std::vector<EulerBeam3DDefinition>& elements() const noexcept;
|
||||
const std::vector<Mitc4ShellDefinition>& shellElements() const noexcept;
|
||||
const std::vector<LinearElasticMaterial>& materials() const noexcept;
|
||||
const std::vector<GeneralBeamSection>& sections() const noexcept;
|
||||
const std::vector<ShellSection>& shellSections() const noexcept;
|
||||
const std::vector<ShellNodeInitialFrame>& shellNodeInitialFrames() const noexcept;
|
||||
const std::vector<NodeSet>& nodeSets() const noexcept;
|
||||
const std::vector<ElementSet>& elementSets() const noexcept;
|
||||
const std::vector<StaticStepDefinition>& steps() const noexcept;
|
||||
const std::vector<Diagnostic>& warnings() const noexcept;
|
||||
const std::filesystem::path& sourcePath() const noexcept;
|
||||
const std::string& sourceContentIdentity() const noexcept;
|
||||
|
||||
private:
|
||||
explicit Domain(ModelDefinition definition);
|
||||
|
||||
ModelDefinition definition_;
|
||||
};
|
||||
|
||||
} // namespace fesa
|
||||
@@ -0,0 +1,185 @@
|
||||
#ifndef FESA_MODEL_MODEL_TYPES_H_
|
||||
#define FESA_MODEL_MODEL_TYPES_H_
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/core/diagnostic.h"
|
||||
#include "fesa/core/source_identity.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;
|
||||
std::array<double, 3> coordinates;
|
||||
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 Preserves the source shell element label independently of
|
||||
/// formulation.
|
||||
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;
|
||||
ShellSourceElementType source_type;
|
||||
std::array<EntityIndex, 4> node_indices;
|
||||
EntityIndex material_index;
|
||||
EntityIndex section_index;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
/// @brief Stores the deterministic initial director and tangent frame at a
|
||||
/// node.
|
||||
struct ShellNodeInitialFrame {
|
||||
EntityIndex node_index;
|
||||
std::array<double, 3> director;
|
||||
std::array<double, 3> tangent_a;
|
||||
std::array<double, 3> tangent_b;
|
||||
};
|
||||
|
||||
/// @brief Defines one two-node Euler beam with stable semantic references.
|
||||
struct EulerBeam3DDefinition {
|
||||
SourceEntityId source_id;
|
||||
std::array<EntityIndex, 2> node_indices;
|
||||
EntityIndex material_index;
|
||||
EntityIndex section_index;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
/// @brief Stores one prescribed nodal degree-of-freedom range.
|
||||
struct BoundaryCondition {
|
||||
std::string target;
|
||||
int first_dof;
|
||||
int last_dof;
|
||||
double value;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
/// @brief Stores one concentrated nodal load component.
|
||||
struct NodalLoad {
|
||||
std::string target;
|
||||
int dof;
|
||||
double magnitude;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
/// @brief Stores the approved single linear-static step definition.
|
||||
struct StaticStepDefinition {
|
||||
std::string name;
|
||||
std::vector<BoundaryCondition> boundaries;
|
||||
std::vector<NodalLoad> loads;
|
||||
double initial_increment;
|
||||
double time_period;
|
||||
double minimum_increment;
|
||||
double maximum_increment;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
/// @brief Stores a stable resolved node-set membership list.
|
||||
struct NodeSet {
|
||||
std::string name;
|
||||
std::optional<std::string> instance_name;
|
||||
std::vector<EntityIndex> node_indices;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
/// @brief Stores a stable resolved element-set membership list.
|
||||
struct ElementSet {
|
||||
std::string name;
|
||||
std::optional<std::string> instance_name;
|
||||
std::vector<EntityIndex> element_indices;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
/// @brief Preserves source identities declared inside one part.
|
||||
struct PartDefinition {
|
||||
std::string name;
|
||||
std::vector<std::int64_t> node_source_labels;
|
||||
std::vector<std::int64_t> element_source_labels;
|
||||
std::vector<std::string> node_set_names;
|
||||
std::vector<std::string> element_set_names;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
/// @brief Maps one source label to a stable internal entity index.
|
||||
struct SourceIndexMapping {
|
||||
std::int64_t source_label;
|
||||
EntityIndex internal_index;
|
||||
};
|
||||
|
||||
/// @brief Preserves one identity instance and its deterministic source
|
||||
/// mappings.
|
||||
struct InstanceDefinition {
|
||||
std::string name;
|
||||
std::string part_name;
|
||||
std::vector<SourceIndexMapping> node_mappings;
|
||||
std::vector<SourceIndexMapping> element_mappings;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
/// @brief Owns every parsed semantic record before immutable Domain
|
||||
/// construction.
|
||||
struct ModelDefinition {
|
||||
std::filesystem::path source_path;
|
||||
std::string source_content_identity;
|
||||
std::string heading;
|
||||
std::vector<Node> nodes;
|
||||
std::vector<EulerBeam3DDefinition> elements;
|
||||
std::vector<Mitc4ShellDefinition> shell_elements;
|
||||
std::vector<LinearElasticMaterial> materials;
|
||||
std::vector<GeneralBeamSection> sections;
|
||||
std::vector<ShellSection> shell_sections;
|
||||
std::vector<ShellNodeInitialFrame> shell_node_initial_frames;
|
||||
std::vector<NodeSet> node_sets;
|
||||
std::vector<ElementSet> element_sets;
|
||||
std::vector<PartDefinition> parts;
|
||||
std::vector<InstanceDefinition> instances;
|
||||
std::vector<StaticStepDefinition> steps;
|
||||
std::vector<Diagnostic> warnings;
|
||||
};
|
||||
|
||||
} // namespace fesa
|
||||
|
||||
#endif // FESA_MODEL_MODEL_TYPES_H_
|
||||
@@ -1,165 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "fesa/core/diagnostic.h"
|
||||
#include "fesa/core/source_identity.h"
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
namespace fesa {
|
||||
|
||||
// Stable internal identities are vector positions assigned in declaration order.
|
||||
using EntityIndex = std::uint32_t;
|
||||
|
||||
struct Node {
|
||||
SourceEntityId sourceId;
|
||||
std::array<double, 3> coordinates;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
struct LinearElasticMaterial {
|
||||
std::string name;
|
||||
double youngsModulus;
|
||||
double poissonRatio;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
struct GeneralBeamSection {
|
||||
std::string name;
|
||||
double area;
|
||||
double i11;
|
||||
double i12;
|
||||
double i22;
|
||||
double torsionalConstant;
|
||||
std::array<double, 3> firstAxis;
|
||||
std::vector<std::array<double, 2>> sectionPoints;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
enum class ShellSourceElementType {
|
||||
s4,
|
||||
s4r
|
||||
};
|
||||
|
||||
inline constexpr std::string_view kMitc4InternalFormulation{"FESA-MITC4"};
|
||||
|
||||
struct ShellSection {
|
||||
std::string name;
|
||||
double thickness;
|
||||
EntityIndex materialIndex;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
struct Mitc4ShellDefinition {
|
||||
SourceEntityId sourceId;
|
||||
ShellSourceElementType sourceType;
|
||||
std::array<EntityIndex, 4> nodeIndices;
|
||||
EntityIndex materialIndex;
|
||||
EntityIndex sectionIndex;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
struct ShellNodeInitialFrame {
|
||||
EntityIndex nodeIndex;
|
||||
std::array<double, 3> director;
|
||||
std::array<double, 3> tangentA;
|
||||
std::array<double, 3> tangentB;
|
||||
};
|
||||
|
||||
struct EulerBeam3DDefinition {
|
||||
SourceEntityId sourceId;
|
||||
std::array<EntityIndex, 2> nodeIndices;
|
||||
EntityIndex materialIndex;
|
||||
EntityIndex sectionIndex;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
struct BoundaryCondition {
|
||||
std::string target;
|
||||
int firstDof;
|
||||
int lastDof;
|
||||
double value;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
struct NodalLoad {
|
||||
std::string target;
|
||||
int dof;
|
||||
double magnitude;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
struct StaticStepDefinition {
|
||||
std::string name;
|
||||
std::vector<BoundaryCondition> boundaries;
|
||||
std::vector<NodalLoad> loads;
|
||||
double initialIncrement;
|
||||
double timePeriod;
|
||||
double minimumIncrement;
|
||||
double maximumIncrement;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
struct NodeSet {
|
||||
std::string name;
|
||||
std::optional<std::string> instanceName;
|
||||
std::vector<EntityIndex> nodeIndices;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
struct ElementSet {
|
||||
std::string name;
|
||||
std::optional<std::string> instanceName;
|
||||
std::vector<EntityIndex> elementIndices;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
struct PartDefinition {
|
||||
std::string name;
|
||||
std::vector<std::int64_t> nodeSourceLabels;
|
||||
std::vector<std::int64_t> elementSourceLabels;
|
||||
std::vector<std::string> nodeSetNames;
|
||||
std::vector<std::string> elementSetNames;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
struct SourceIndexMapping {
|
||||
std::int64_t sourceLabel;
|
||||
EntityIndex internalIndex;
|
||||
};
|
||||
|
||||
struct InstanceDefinition {
|
||||
std::string name;
|
||||
std::string partName;
|
||||
std::vector<SourceIndexMapping> nodeMappings;
|
||||
std::vector<SourceIndexMapping> elementMappings;
|
||||
SourceLocation location;
|
||||
};
|
||||
|
||||
// This construction-boundary value owns every parsed semantic record before
|
||||
// it is finalized into an immutable Domain.
|
||||
struct ModelDefinition {
|
||||
std::filesystem::path sourcePath;
|
||||
std::string sourceContentIdentity;
|
||||
std::string heading;
|
||||
std::vector<Node> nodes;
|
||||
std::vector<EulerBeam3DDefinition> elements;
|
||||
std::vector<Mitc4ShellDefinition> shellElements;
|
||||
std::vector<LinearElasticMaterial> materials;
|
||||
std::vector<GeneralBeamSection> sections;
|
||||
std::vector<ShellSection> shellSections;
|
||||
std::vector<ShellNodeInitialFrame> shellNodeInitialFrames;
|
||||
std::vector<NodeSet> nodeSets;
|
||||
std::vector<ElementSet> elementSets;
|
||||
std::vector<PartDefinition> parts;
|
||||
std::vector<InstanceDefinition> instances;
|
||||
std::vector<StaticStepDefinition> steps;
|
||||
std::vector<Diagnostic> warnings;
|
||||
};
|
||||
|
||||
} // namespace fesa
|
||||
@@ -0,0 +1,53 @@
|
||||
#ifndef FESA_MODEL_SHELL_GEOMETRY_H_
|
||||
#define FESA_MODEL_SHELL_GEOMETRY_H_
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
#include "fesa/core/status.h"
|
||||
#include "fesa/model/model_types.h"
|
||||
|
||||
namespace fesa {
|
||||
|
||||
/// @brief Classifies a mandatory shell-geometry validation location.
|
||||
enum class ShellGeometryPointKind { kCenter, kStiffness, kTying, kRecovery };
|
||||
|
||||
/// @brief Identifies one deterministic shell-geometry validation point.
|
||||
struct ShellGeometryValidationPoint {
|
||||
ShellGeometryPointKind kind;
|
||||
std::size_t location_index;
|
||||
std::array<double, 3> natural_coordinates;
|
||||
};
|
||||
|
||||
/// @brief Stores deterministic preprocessing data for one shell element.
|
||||
struct ShellElementGeometryData {
|
||||
EntityIndex element_index;
|
||||
std::array<double, 3> normal_candidate;
|
||||
double surface_area_weight;
|
||||
};
|
||||
|
||||
/// @brief Owns preprocessed shell node frames and element geometry data.
|
||||
struct ShellGeometry {
|
||||
std::vector<ShellNodeInitialFrame> nodal_frames;
|
||||
std::vector<ShellElementGeometryData> element_data;
|
||||
};
|
||||
|
||||
/// @brief Returns the complete fixed validation-point inventory.
|
||||
/// @note Ordering is center, stiffness, tying, then recovery identity.
|
||||
const std::array<ShellGeometryValidationPoint, 17>&
|
||||
ShellGeometryValidationPoints() noexcept;
|
||||
|
||||
/// @brief Builds deterministic nodal frames and validates shell geometry.
|
||||
/// @param nodes Source nodes indexed by stable EntityIndex.
|
||||
/// @param elements Shell definitions in stable source order.
|
||||
/// @param sections Shell sections used for thickness validation.
|
||||
/// @return Validated geometry or a structured model failure.
|
||||
Result<ShellGeometry> PreprocessShellGeometry(
|
||||
const std::vector<Node>& nodes,
|
||||
const std::vector<Mitc4ShellDefinition>& elements,
|
||||
const std::vector<ShellSection>& sections);
|
||||
|
||||
} // namespace fesa
|
||||
|
||||
#endif // FESA_MODEL_SHELL_GEOMETRY_H_
|
||||
@@ -1,44 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "fesa/core/status.h"
|
||||
#include "fesa/model/model_types.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
#include <vector>
|
||||
|
||||
namespace fesa {
|
||||
|
||||
enum class ShellGeometryPointKind {
|
||||
center,
|
||||
stiffness,
|
||||
tying,
|
||||
recovery
|
||||
};
|
||||
|
||||
struct ShellGeometryValidationPoint {
|
||||
ShellGeometryPointKind kind;
|
||||
std::size_t locationIndex;
|
||||
std::array<double, 3> naturalCoordinates;
|
||||
};
|
||||
|
||||
struct ShellElementGeometryData {
|
||||
EntityIndex elementIndex;
|
||||
std::array<double, 3> normalCandidate;
|
||||
double surfaceAreaWeight;
|
||||
};
|
||||
|
||||
struct ShellGeometry {
|
||||
std::vector<ShellNodeInitialFrame> nodalFrames;
|
||||
std::vector<ShellElementGeometryData> elementData;
|
||||
};
|
||||
|
||||
const std::array<ShellGeometryValidationPoint, 17>&
|
||||
shellGeometryValidationPoints() noexcept;
|
||||
|
||||
Result<ShellGeometry> preprocessShellGeometry(
|
||||
const std::vector<Node>& nodes,
|
||||
const std::vector<Mitc4ShellDefinition>& elements,
|
||||
const std::vector<ShellSection>& sections);
|
||||
|
||||
} // namespace fesa
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "fesa/model/model_types.hpp"
|
||||
#include "fesa/model/model_types.h"
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
#include "fesa/analysis/analysis_state.hpp"
|
||||
#include "fesa/core/diagnostic.h"
|
||||
#include "fesa/core/status.h"
|
||||
#include "fesa/model/domain.hpp"
|
||||
#include "fesa/model/domain.h"
|
||||
|
||||
#include <filesystem>
|
||||
#include <vector>
|
||||
|
||||
Reference in New Issue
Block a user