feat: add eigen2 frequency pipeline and fail-closed validation

Implement MITC4 mass, constrained whitening, MKL FEAST, modal HDF5, and deterministic Value comparison. MSVC Debug builds; 394 of 395 tests pass. Original-model all-c residual and the documented S3 static contract conflict remain unresolved; this is an implementation checkpoint, not feature acceptance.
This commit is contained in:
KOKO\Mimi
2026-09-09 03:14:30 +09:00
parent e74ac247db
commit 22c9d4435c
39 changed files with 7240 additions and 541 deletions
+19 -2
View File
@@ -4,6 +4,7 @@
#include <cstddef>
#include <filesystem>
#include <memory>
#include <optional>
#include <string>
#include <vector>
@@ -47,7 +48,7 @@ class DomainCollectionView {
std::vector<const T*> entries_;
};
/// @brief Owns one immutable static-step semantic definition.
/// @brief Owns one immutable static or frequency-step semantic definition.
/// @note Loads retain source order and are owned polymorphically by unique
/// pointers.
class StepDefinition {
@@ -84,6 +85,12 @@ class StepDefinition {
/// @brief Reports whether this step uses the nonlinear static procedure.
bool IsNonlinearStatic() const noexcept;
/// @brief Reports whether this step defines the frequency procedure.
bool IsFrequency() const noexcept;
/// @brief Returns frequency source semantics when this is a frequency step.
const FrequencyStepDefinition* Frequency() const noexcept;
/// @brief Reports the source NLGEOM setting for this static step.
bool UsesNonlinearGeometry() const noexcept;
@@ -108,6 +115,9 @@ class StepDefinition {
/// @brief Converts one parsed static-step record to owned semantic objects.
explicit StepDefinition(StaticStepDefinition definition);
/// @brief Converts one parsed frequency-step record to owned semantics.
explicit StepDefinition(FrequencyStepDefinition definition);
std::string name_;
std::vector<std::unique_ptr<BoundaryCondition>> boundary_conditions_;
BoundaryConditionView boundary_conditions_view_;
@@ -124,6 +134,7 @@ class StepDefinition {
double minimum_increment_;
double maximum_increment_;
SourceLocation location_;
std::optional<FrequencyStepDefinition> frequency_;
};
/// @brief Owns the complete immutable semantic model definition.
@@ -184,9 +195,15 @@ class Domain {
/// @brief Returns assembly element surfaces in stable declaration order.
const std::vector<ElementSurfaceDefinition>& ElementSurfaces() const noexcept;
/// @brief Returns static steps in stable declaration order.
/// @brief Returns procedure steps in stable declaration order.
const DomainCollectionView<StepDefinition>& Steps() const noexcept;
/// @brief Returns resolved density records in stable material-index order.
const std::vector<MaterialDensityDefinition>& Densities() const noexcept;
/// @brief Returns the sole frequency source definition when present.
const FrequencyStepDefinition* Frequency() const noexcept;
/// @brief Returns sorted nonfatal mapping diagnostics.
const std::vector<Diagnostic>& Warnings() const noexcept;
+60 -34
View File
@@ -117,18 +117,15 @@ struct StaticStepDefinition {
std::vector<PrescribedDisplacementDefinition> step_boundaries,
std::vector<NodalLoad> step_loads,
std::vector<SurfacePressureLoadDefinition> step_surface_pressure_loads,
StaticProcedureKind step_procedure_kind,
bool step_nlgeom,
double step_initial_increment,
double step_time_period,
double step_minimum_increment,
double step_maximum_increment,
StaticProcedureKind step_procedure_kind, bool step_nlgeom,
double step_initial_increment, double step_time_period,
double step_minimum_increment, double step_maximum_increment,
SourceLocation step_location)
: name{std::move(step_name)},
boundaries{std::move(step_boundaries)},
loads{std::move(step_loads)},
surface_pressure_loads{std::move(step_surface_pressure_loads)},
procedure_kind{step_procedure_kind},
: name{std::move(step_name)},
boundaries{std::move(step_boundaries)},
loads{std::move(step_loads)},
surface_pressure_loads{std::move(step_surface_pressure_loads)},
procedure_kind{step_procedure_kind},
nlgeom{step_nlgeom},
initial_increment{step_initial_increment},
time_period{step_time_period},
@@ -141,35 +138,30 @@ struct StaticStepDefinition {
std::string step_name,
std::vector<PrescribedDisplacementDefinition> step_boundaries,
std::vector<NodalLoad> step_loads,
StaticProcedureKind step_procedure_kind,
bool step_nlgeom,
double step_initial_increment,
double step_time_period,
double step_minimum_increment,
double step_maximum_increment,
StaticProcedureKind step_procedure_kind, bool step_nlgeom,
double step_initial_increment, double step_time_period,
double step_minimum_increment, double step_maximum_increment,
SourceLocation step_location)
: StaticStepDefinition(
std::move(step_name), std::move(step_boundaries),
std::move(step_loads), {}, step_procedure_kind, step_nlgeom,
step_initial_increment, step_time_period, step_minimum_increment,
step_maximum_increment, std::move(step_location)) {}
: StaticStepDefinition(std::move(step_name), std::move(step_boundaries),
std::move(step_loads), {}, step_procedure_kind,
step_nlgeom, step_initial_increment,
step_time_period, step_minimum_increment,
step_maximum_increment, std::move(step_location)) {
}
/// @brief Creates a legacy linear static step definition.
StaticStepDefinition(
std::string step_name,
std::vector<PrescribedDisplacementDefinition> step_boundaries,
std::vector<NodalLoad> step_loads,
double step_initial_increment,
double step_time_period,
double step_minimum_increment,
double step_maximum_increment,
SourceLocation step_location)
: StaticStepDefinition(
std::move(step_name), std::move(step_boundaries),
std::move(step_loads),
StaticProcedureKind::kLinearSmallDisplacement, false,
step_initial_increment, step_time_period, step_minimum_increment,
step_maximum_increment, std::move(step_location)) {}
std::vector<NodalLoad> step_loads, double step_initial_increment,
double step_time_period, double step_minimum_increment,
double step_maximum_increment, SourceLocation step_location)
: StaticStepDefinition(std::move(step_name), std::move(step_boundaries),
std::move(step_loads),
StaticProcedureKind::kLinearSmallDisplacement,
false, step_initial_increment, step_time_period,
step_minimum_increment, step_maximum_increment,
std::move(step_location)) {}
std::string name;
std::vector<PrescribedDisplacementDefinition> boundaries;
@@ -184,6 +176,38 @@ struct StaticStepDefinition {
SourceLocation location;
};
/// @brief Identifies the accepted source eigensolver selection.
enum class FrequencyEigensolver { kLanczos };
/// @brief Identifies the accepted modal normalization selection.
enum class FrequencyNormalization { kMass };
/// @brief Stores one resolved constant material mass density.
struct MaterialDensityDefinition {
EntityIndex material_index;
double rho;
SourceLocation location;
};
/// @brief Stores the sole supported frequency-step source semantics.
struct FrequencyStepDefinition {
std::string source_step_name_raw;
std::string source_step_name_canonical;
SourceLocation step_location;
SourceLocation frequency_location;
SourceLocation data_location;
std::int64_t requested_mode_count;
bool nlgeom_explicit;
bool perturbation_explicit;
bool eigensolver_explicit;
bool sim_explicit;
bool acoustic_coupling_explicit;
bool normalization_explicit;
FrequencyEigensolver eigensolver;
FrequencyNormalization normalization;
std::vector<PrescribedDisplacementDefinition> boundaries;
};
/// @brief Stores a stable resolved node-set membership list.
struct NodeSet {
std::string name;
@@ -245,6 +269,8 @@ struct ModelDefinition {
std::vector<InstanceDefinition> instances;
std::vector<ElementSurfaceDefinition> element_surfaces;
std::vector<StaticStepDefinition> steps;
std::vector<MaterialDensityDefinition> densities;
std::optional<FrequencyStepDefinition> frequency_step;
std::vector<Diagnostic> warnings;
};