Files
2026-08-15 03:14:34 +09:00

78 KiB

Linear Static 3D Euler Beam Implementation Plan

For agentic workers: REQUIRED SKILL: use fesa-cpp-msvc-tdd for every Step 7-24 task and execute each task as one RED -> GREEN -> VERIFY cycle. The Harness executor, not the worker, owns commits and timestamps.

Goal: Build the approved single-step Abaqus TYPE=B33 linear-static pipeline from .inp parsing through deterministic sparse solution, result recovery, atomic HDF5 output, CLI execution, and a reusable read-only B33 reference-comparison test.

Architecture: Domain owns the immutable semantic model; AnalysisModel, DofManager, and AnalysisState separate active views, equation ownership, and mutable solution state. Dense math, CSR storage, oneTBB, oneMKL PARDISO, and HDF5 remain behind focused adapter boundaries, while Analysis::run() fixes factorization-before-load orchestration.

Tech Stack: C++17, MSVC x64 Debug, CMake, CTest, GoogleTest, Intel oneMKL, Intel oneTBB, and HDF5.

Metadata

  • feature_id: linear-static-3d-euler-beam
  • source_requirement: docs/linear-static-3d-euler-beam/requirements.md
  • source_research: docs/linear-static-3d-euler-beam/research.md
  • source_formulation: docs/linear-static-3d-euler-beam/formulation.md
  • source_numerical_review: docs/linear-static-3d-euler-beam/numerical-review.md
  • source_io_definition: docs/linear-static-3d-euler-beam/io.md
  • source_reference_models: docs/linear-static-3d-euler-beam/reference-model.md
  • approved_design: docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md
  • phase_steps: phases/linear-static-3d-euler-beam/step7.md through step24.md
  • status: ready-for-implementation
  • owner_agent: implementation-planning-agent
  • date: 2026-08-09

Global Constraints

  • Implement only one *STEP, *STATIC and two-node TYPE=B33; reject B31, a second step, instance transforms, nested assembly, I12!=0, and *DLOAD.
  • Preserve the exact lifecycle: stiffness assembly and partition, Kff factorization, load assembly, effective RHS, substitution, reconstruction, recovery, HDF5 write.
  • Treat reference/cantilever beam/ as a read-only four-file legacy baseline. Do not create, rename, rewrite, repair, restore, round, or clamp its files.
  • Use C++17 and MSVC x64 Debug. Apply /W4 /WX only to FESA targets and add no new warnings.
  • Keep each owned file focused on its listed responsibility and add reviewer-facing comments for the approved formula/sign, deterministic ordering, backend lifetime, and atomic-finalization decisions implemented there.
  • Write and run the related GoogleTest first, observe the planned RED cause, implement the minimum production behavior, then run the targeted GREEN and full VERIFY in the same Step.
  • Keep MKL, oneTBB, HDF5, and Windows file-replacement types out of public headers.
  • Do not change requirements, formulation, numerical review, I/O contract, reference contract, or tolerance policy during implementation or correction.
  • Do not execute Abaqus, Nastran, or another reference solver.
  • Do not commit directly; scripts/execute.py owns commits and timestamps.

Readiness Check

input required status observed status decision
requirements approved approved; 44 consecutive must requirements proceed
research sufficient evidence with implementation gaps identified ready-for-formulation; PARDISO and deterministic reduction gaps explicitly handed off proceed with the resolutions below
formulation ready for independent numerical review ready-for-numerical-review; no unresolved mathematical input proceed
numerical review pass for implementation planning pass-for-implementation-planning; no confirmed defect proceed
I/O definition ready for implementation planning ready-for-implementation-planning; NR-O03 station normalization resolved proceed
reference models ready for implementation planning or planned analytical fixtures ready-for-implementation-planning; legacy bundle inventory-ready and analytical fixtures planned proceed
approved design and Step 7-24 approved and mutually implementable design approved; all 18 module steps present proceed with the precedence notes below

Readiness resolutions

  1. NR-O01-PARDISO-CONTRACT is closed for planning by Intel's official oneMKL C reference: real symmetric positive definite matrices use mtype=2; analysis, numerical factorization, solve, and release are phases 11, 22, 33, and -1; iparm[34]=1 selects zero-based CSR; a retained factorization can serve repeated right-hand sides; and zero/negative SPD pivots stop with error -4. Sources: Intel oneMKL PARDISO and PARDISO iparm parameters.
  2. NR-O02-DETERMINISTIC-REDUCTION is fixed as a project algorithm: produce one index-addressed local contribution buffer per stable active-element order; enumerate each 12x12 local matrix in row-major localOrder; stable-sort COO by (row,column,elementOrder,localOrder); sum duplicates in that order; emit the exact sorted-unique SparsePattern; and retain exact zero values for every structural pattern slot. Serial, TBB, and repeated runs must produce byte-identical CSR arrays.
  3. NR-O03-STATION-NORMALIZATION is already resolved by the I/O/reference contracts: only unloaded, consistently oriented, two-endpoint interior stations are eligible; compare endpoints before choosing the smaller stable element ID; never average.
  4. Approved upstream contracts take precedence over broader wording in Step 12. *STATIC has exactly one row of four finite positive fields, and material acceptance requires exactly E,nu, E>0, and derived G=E/(2*(1+nu))>0; do not add an unapproved nu<0.5 rejection.

No readiness item requires a user decision, an upstream edit, or a new reference artifact.

Implementation Scope

Included behavior

  • Single small-displacement, small-rotation, linear-elastic static analysis.
  • Straight prismatic two-node 3D Euler-Bernoulli beam mapped only from Abaqus TYPE=B33.
  • Global nodal order [UX,UY,UZ,URX,URY,URZ]; axial, two-plane bending, and Saint-Venant torsion.
  • Approved Abaqus keyword subset, identity instances, stable source/internal identity, warning no-op output allowlist, nodal *CLOAD, and zero/nonzero prescribed displacement.
  • Formulation-only constant local line-load equivalent nodal vector; no parser or CLI distributed load.
  • Contiguous Vector, row-major contiguous Matrix, deterministic 0-based CSR SparseMatrix, element-local oneTBB work, SPD PARDISO factorization/substitution, and residual reactions.
  • Mandatory HDF5 displacement, reaction, equilibrium end action, endpoint section resultant, two-Gauss generalized strain/resultant, axial S11, metadata, and diagnostics.
  • fesa.exe CLI and a test-only HDF5-to-legacy-CSV comparison executable/test that Step 26 reruns unchanged.

Non-goals

  • Abaqus full compatibility, B31/Timoshenko behavior, multiple steps, instance transforms, nested assembly, dependent/independent mesh semantics.
  • I12!=0, taper, offset, release, curved beams, warping, geometric/material nonlinearity, dynamics, contact, or thermal effects.
  • *DLOAD parsing, a Domain distributed-load object, transverse/torsional shear stress, nodal stress averaging, or Abaqus beam-stress comparison.
  • Automatic slenderness acceptance/rejection, arbitrary regularization of singular systems, expression templates, alternate sparse solvers, packaging, release approval, or reference generation.

Interface and Data-Flow Ledger

The signatures below are the cross-task contract. A task may add private helpers in its owned .cpp, but later tasks must consume these names, ownership rules, and types without substituting parallel APIs.

// core
struct SourceLocation { std::filesystem::path file; std::size_t line; };
struct SourceEntityId {
    std::string instanceName;
    std::int64_t sourceLabel;
    std::string sourceLabelText;
};
enum class Severity { warning, error };
enum class FailureCategory { input, model, solver, output };
struct Diagnostic {
    Severity severity;
    std::string code;
    SourceLocation location;
    std::string keyword;
    std::string entityIdentity;
    std::string message;
};
class Status {
public:
    static Status ok();
    static Status failure(std::vector<Diagnostic> diagnostics);
    static Status failure(FailureCategory category, std::vector<Diagnostic> diagnostics);
    bool isOk() const noexcept;
    std::optional<FailureCategory> failureCategory() const noexcept;
    const std::vector<Diagnostic>& diagnostics() const noexcept;
};
template<class T> class Result {
public:
    static Result success(T value);
    static Result failure(Status status);
    bool hasValue() const noexcept;
    T& value();
    const T& value() const;
    const Status& status() const noexcept;
};

// dense math
class Vector {
public:
    explicit Vector(std::size_t size, double value = 0.0);
    std::size_t size() const noexcept;
    double* data() noexcept;
    const double* data() const noexcept;
    double& operator[](std::size_t index);
    const double& operator[](std::size_t index) const;
    double dot(const Vector& rhs) const;
    double norm() const;
    void scale(double alpha);
    void axpy(double alpha, const Vector& x);
};
class Matrix {
public:
    Matrix(std::size_t rows, std::size_t columns, double value = 0.0);
    std::size_t rows() const noexcept;
    std::size_t columns() const noexcept;
    double& operator()(std::size_t row, std::size_t column);
    const double& operator()(std::size_t row, std::size_t column) const;
    Vector multiply(const Vector& rhs) const;
    Matrix multiply(const Matrix& rhs) const;
};

// immutable semantic model
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;
};
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;
};
struct ModelDefinition {
    std::filesystem::path sourcePath;
    std::string sourceContentIdentity;
    std::string heading;
    std::vector<Node> nodes;
    std::vector<EulerBeam3DDefinition> elements;
    std::vector<LinearElasticMaterial> materials;
    std::vector<GeneralBeamSection> sections;
    std::vector<NodeSet> nodeSets;
    std::vector<ElementSet> elementSets;
    std::vector<PartDefinition> parts;
    std::vector<InstanceDefinition> instances;
    std::vector<StaticStepDefinition> steps;
    std::vector<Diagnostic> warnings;
};
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<LinearElasticMaterial>& materials() const noexcept;
    const std::vector<GeneralBeamSection>& sections() 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;
};

// parser and active analysis view
struct KeywordParameter { std::string name; std::optional<std::string> value; };
struct DataLine { std::vector<std::string> fields; SourceLocation location; };
struct KeywordBlock {
    std::string canonicalName;
    std::string originalLine;
    std::vector<KeywordParameter> parameters;
    std::vector<DataLine> data;
    SourceLocation location;
};
struct ParsedInput {
    std::filesystem::path sourcePath;
    std::string sourceContentIdentity;
    std::vector<KeywordBlock> blocks;
};
class AbaqusInputReader {
public:
    Result<ParsedInput> read(const std::filesystem::path& inputPath) const;
};
class AbaqusDomainMapper {
public:
    Result<Domain> map(const ParsedInput& input) const;
};
class AnalysisModel {
public:
    static Result<AnalysisModel> create(const Domain& domain);
    const Domain& domain() const noexcept;
    const StaticStepDefinition& step() const noexcept;
    const std::vector<EntityIndex>& activeElements() const noexcept;
    const std::vector<EntityIndex>& activeMaterials() const noexcept;
    const std::vector<EntityIndex>& activeSections() const noexcept;
    const std::vector<EntityIndex>& activeBoundaryConditions() const noexcept;
    const std::vector<EntityIndex>& activeLoads() const noexcept;
};

// equation and state ownership
enum class DofComponent : std::uint8_t { ux, uy, uz, urx, ury, urz };
struct SparsePattern {
    std::vector<std::size_t> rowOffsets;
    std::vector<std::size_t> columnIndices;
};
class DofManager {
public:
    static Result<DofManager> create(const AnalysisModel& model);
    std::size_t fullDofCount() const noexcept;
    std::size_t freeDofCount() const noexcept;
    std::size_t constrainedDofCount() const noexcept;
    std::size_t fullDof(EntityIndex node, DofComponent component) const;
    std::optional<std::size_t> freeEquation(std::size_t fullDof) const;
    const std::array<std::size_t, 12>& elementScatter(EntityIndex element) const;
    const std::vector<std::size_t>& freeDofs() const noexcept;
    const std::vector<std::size_t>& constrainedDofs() const noexcept;
    const Vector& prescribedValues() const noexcept;
    const SparsePattern& sparsePattern() const noexcept;
};
struct StepFrameIdentity { std::string stepName; std::size_t frameIndex; };
struct EndpointResultRow {
    EntityIndex element; int endpoint; SourceEntityId node;
    std::array<double, 6> endAction;
    std::array<double, 4> sectionResultant;
};
struct GaussResultRow {
    EntityIndex element; int gaussPoint;
    std::array<double, 4> generalizedStrain;
    std::array<double, 4> generalizedResultant;
};
struct StressS11Row {
    EntityIndex element; int gaussPoint; std::size_t sectionPoint;
    double x1; double x2; double s11; std::string source;
};
class AnalysisState {
public:
    static AnalysisState create(const DofManager& dofs, StepFrameIdentity identity);
    Vector& displacement() noexcept; const Vector& displacement() const noexcept;
    Vector& externalForce() noexcept; const Vector& externalForce() const noexcept;
    Vector& internalForce() noexcept; const Vector& internalForce() const noexcept;
    Vector& residual() noexcept; const Vector& residual() const noexcept;
    Vector& reaction() noexcept; const Vector& reaction() const noexcept;
    const StepFrameIdentity& identity() const noexcept;
    std::vector<EndpointResultRow>& endpointResults() noexcept;
    const std::vector<EndpointResultRow>& endpointResults() const noexcept;
    std::vector<GaussResultRow>& gaussResults() noexcept;
    const std::vector<GaussResultRow>& gaussResults() const noexcept;
    std::vector<StressS11Row>& stressResults() noexcept;
    const std::vector<StressS11Row>& stressResults() const noexcept;
};

// element, parallelism, and sparse assembly
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;
};
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;
};
class ParallelFor {
public:
    virtual ~ParallelFor() = default;
    virtual void execute(std::size_t count,
                         const std::function<void(std::size_t)>& body) const = 0;
};
class SerialParallelFor final : public ParallelFor {
public:
    void execute(std::size_t count,
                 const std::function<void(std::size_t)>& body) const override;
};
class TbbParallelFor final : public ParallelFor {
public:
    void execute(std::size_t count,
                 const std::function<void(std::size_t)>& body) const override;
};
struct CooContribution {
    std::size_t row;
    std::size_t column;
    double value;
    std::size_t elementOrder;
    std::size_t localOrder;
};
class SparseMatrix {
public:
    static Result<SparseMatrix> fromCoo(std::size_t rows, std::size_t columns,
                                        std::vector<CooContribution> contributions,
                                        const SparsePattern& expectedPattern);
    std::size_t rows() const noexcept;
    std::size_t columns() const noexcept;
    const std::vector<std::size_t>& rowOffsets() const noexcept;
    const std::vector<std::size_t>& columnIndices() const noexcept;
    const std::vector<double>& values() const noexcept;
    Vector multiply(const Vector& rhs) const;
    Status validate() const;
};
class SparseAssembler {
public:
    static Result<SparseMatrix> assembleStiffness(const AnalysisModel& model,
                                                  const DofManager& dofs,
                                                  const ParallelFor& parallelFor);
};

// constraints, solver, load, recovery, and output
struct PartitionedStiffness {
    SparseMatrix kff;
    SparseMatrix kfc;
    SparseMatrix kcf;
    SparseMatrix kcc;
};
class EssentialConstraints {
public:
    static Result<PartitionedStiffness> partition(const SparseMatrix& full,
                                                   const DofManager& dofs);
    static Vector gatherFree(const Vector& full, const DofManager& dofs);
    static Vector gatherConstrained(const Vector& full, const DofManager& dofs);
    static Vector reconstructFull(const Vector& freeValues,
                                  const Vector& constrainedValues,
                                  const DofManager& dofs);
};
class LinearSolver {
public:
    virtual ~LinearSolver() = default;
    virtual Status factorize(const SparseMatrix& matrix) = 0;
    virtual Status solve(const Vector& rhs, Vector& solution) const = 0;
};
class MklPardisoSolver final : public LinearSolver {
public:
    MklPardisoSolver();
    ~MklPardisoSolver() override;
    Status factorize(const SparseMatrix& matrix) override;
    Status solve(const Vector& rhs, Vector& solution) const override;
private:
    class Impl;
    std::unique_ptr<Impl> impl_;
};
class LoadAssembler {
public:
    static Result<Vector> assembleFullNodalLoad(const AnalysisModel& model,
                                                const DofManager& dofs);
    static Result<Vector> effectiveFreeRhs(const Vector& fullLoad,
                                           const SparseMatrix& kfc,
                                           const Vector& prescribedValues,
                                           const DofManager& dofs);
};
struct NodeStationResultRow {
    SourceEntityId node;
    EntityIndex representativeElement;
    std::array<double, 4> sectionResultant;
};
class ResultRecovery {
public:
    static Status recover(const AnalysisModel& model,
                          const DofManager& dofs,
                          const SparseMatrix& fullStiffness,
                          AnalysisState& state);
    static Result<std::vector<NodeStationResultRow>> normalizeSectionResultantsToNodeStations(
        const AnalysisModel& model,
        const std::vector<EndpointResultRow>& endpointRows,
        const std::array<double, 4>& componentTolerances); // [N,T,My,Mz]
};
class ResultsWriter {
public:
    virtual ~ResultsWriter() = default;
    virtual Status write(const std::filesystem::path& outputPath,
                         const Domain& domain,
                         const AnalysisState& state,
                         const std::vector<Diagnostic>& diagnostics) = 0;
};
class Hdf5ResultsWriter final : public ResultsWriter {
public:
    Status write(const std::filesystem::path& outputPath,
                 const Domain& domain,
                 const AnalysisState& state,
                 const std::vector<Diagnostic>& diagnostics) override;
};

// orchestration
struct AnalysisRequest { std::filesystem::path inputPath; std::filesystem::path outputPath; };
class Analysis {
public:
    virtual ~Analysis() = default;
    Status run(const AnalysisRequest& request);
protected:
    virtual Status initialize(const AnalysisRequest& request) = 0;
    virtual Status buildAnalysisModel() = 0;
    virtual Status buildDofMapAndSparsePattern() = 0;
    virtual Status assembleAndPartitionStiffness() = 0;
    virtual Status factorize() = 0;
    virtual Status assembleLoadsAndEffectiveRhs() = 0;
    virtual Status substituteAndReconstruct() = 0;
    virtual Status recoverAndWriteResults() = 0;
};
class LinearStaticAnalysis final : public Analysis {
public:
    LinearStaticAnalysis(const ParallelFor& parallelFor,
                         LinearSolver& linearSolver,
                         ResultsWriter& resultsWriter);
protected:
    Status initialize(const AnalysisRequest& request) override;
    Status buildAnalysisModel() override;
    Status buildDofMapAndSparsePattern() override;
    Status assembleAndPartitionStiffness() override;
    Status factorize() override;
    Status assembleLoadsAndEffectiveRhs() override;
    Status substituteAndReconstruct() override;
    Status recoverAndWriteResults() override;
};
class FesaApplication {
public:
    int run(const std::vector<std::string>& arguments);
};

These records preserve raw names/source-label lexemes and stable declaration order but contain no equation IDs or analysis vectors. Step 12 rejects transforms before creating InstanceDefinition, so the record deliberately has no transform field.

Work Breakdown

Every task below is one Harness Step and one independent review gate. Each task begins by registering the named GoogleTests in tests/CMakeLists.txt, observes the stated RED, adds only its owned production files, reaches the targeted GREEN, appends evidence to the implementation report, and runs its full VERIFY.

TASK-07: cmake-test-foundation

Files and single responsibilities

action file responsibility
create CMakeLists.txt C++17 project root, dependency entry, testing enablement, subdirectories
create cmake/FesaDependencies.cmake validate FESA_GTEST_SOURCE_DIR; normalize oneMKL, oneTBB, HDF5 imported targets
create include/fesa/build_info.hpp declare std::string_view solverVersion() noexcept only
create src/fesa/build_info.cpp define stable solver version string
create src/fesa/CMakeLists.txt fesa_solver, warning isolation, and later production source registration
create tests/CMakeLists.txt GoogleTest targets/discovery, common feature label, test meta-target
create tests/unit/build_info_test.cpp compile/runtime contract for solver version
create docs/linear-static-3d-euler-beam/implementation-report.md cumulative Step 7-24 evidence ledger
  • Consumes: repository toolchain and approved dependency locations; no solver module.
  • Produces: normalized dependency aliases Fesa::MKL, Fesa::TBB, and Fesa::HDF5; fesa_solver; fesa_unit_tests; custom target fesa_tests; common CTest label linear-static-3d-euler-beam; and solverVersion().
  • Tests: T07-BUILD-001 = BuildInfo.VersionIsStableAndNonEmpty; T07-BUILD-002 = BuildInfo.PublicHeaderHasNoBackendDependency.
  • RED: configure the test target with build_info_test.cpp registered but before creating build_info.hpp/.cpp; the build must fail for the missing header or symbol.
  • GREEN: BuildInfo CTest passes and GoogleTest revision equals 04ee1b4f2aefdffb0135d7cf2a2c519fe50dabe4.
  • Targeted command:
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug -R BuildInfo --output-on-failure
  • Full VERIFY:
cmake -S . -B .harness/build -A x64 -DFESA_GTEST_SOURCE_DIR=C:/git/googletest "-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" "-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" "-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R BuildInfo --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure

TASK-08: core-diagnostics

Files: create include/fesa/core/source_identity.hpp (identity/location values), include/fesa/core/diagnostic.hpp (diagnostic fields/order declaration), include/fesa/core/status.hpp (Status, FailureCategory, Result<T>), src/fesa/core/diagnostic.cpp (stable ordering/formatting), src/fesa/core/status.cpp (status state); create tests/unit/core/source_identity_test.cpp, diagnostic_test.cpp, status_test.cpp; modify both CMake lists only for these sources/tests.

  • Consumes: solverVersion() and C++ standard library only.
  • Produces: the core signatures in the ledger; stable sort tuple (file,line,keyword,entityIdentity,code,discoveryOrder); backend-free success/failure transport.
  • Tests: T08-CORE-001 = CoreDiagnostics.SourceIdentityPreservesRawIdentity; T08-CORE-002 = CoreDiagnostics.DiagnosticsSortDeterministically; T08-CORE-003 = CoreDiagnostics.ResultEnforcesValueErrorExclusivity.
  • RED/GREEN: registered tests fail to compile for missing core headers, then pass value/error, copy/move, failed access, exact fields, category, and ordering cases.
  • Targeted command: cmake --build .harness/build --config Debug --target fesa_tests then ctest --test-dir .harness/build -C Debug -R CoreDiagnostics --output-on-failure.
  • Full VERIFY:
cmake -S . -B .harness/build -A x64 -DFESA_GTEST_SOURCE_DIR=C:/git/googletest "-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" "-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" "-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R CoreDiagnostics --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure

TASK-09: dense-math-adapters

Files: create include/fesa/math/vector.hpp and matrix.hpp for owning public types; create src/fesa/math/vector.cpp and matrix.cpp for MKL CBLAS calls; create tests/unit/math/vector_test.cpp and matrix_test.cpp; modify both CMake lists only for dense math.

  • Consumes: core exceptions/status conventions and normalized oneMKL target.
  • Produces: the exact Vector/Matrix ledger signatures with deep copy, safe move, checked access, dimension checks, and row-major GEMV/GEMM.
  • Tests: T09-DENSE-001 = DenseMath.VectorOwnsAndChecksContiguousStorage; T09-DENSE-002 = DenseMath.RowMajorMatrixMatchesKnownGemvGemm.
  • RED/GREEN: missing headers/symbols produce RED; GREEN covers zero size, copy/move, bounds, mismatch, nonsquare operations, and known BLAS values.
  • Targeted command: build fesa_tests, then ctest --test-dir .harness/build -C Debug -R DenseMath --output-on-failure.
  • Full VERIFY:
cmake -S . -B .harness/build -A x64 -DFESA_GTEST_SOURCE_DIR=C:/git/googletest "-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" "-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" "-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R DenseMath --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure

TASK-10: domain-model

Files: create include/fesa/model/model_types.hpp for semantic records and include/fesa/model/domain.hpp for immutable ownership/lookups; create src/fesa/model/domain.cpp for construction/finalization; create tests/unit/model/model_types_test.cpp and domain_test.cpp; modify CMake lists only for the model.

  • Consumes: SourceEntityId, Diagnostic, Result<T>.
  • Produces: EntityIndex, all model records, ModelDefinition, and immutable Domain; stable indices follow declaration/instance/entity order; nodes/elements have no equation IDs.
  • Tests: T10-DOM-001 = DomainModel.SourceAndInternalIdentityRemainDistinct; T10-DOM-002 = DomainModel.ImmutableOwnershipPreservesStableOrder; T10-DOM-003 = DomainModel.MultipleIdentityInstancesDoNotMerge.
  • RED/GREEN: missing model types produce compile RED; GREEN proves raw identity, stable lookup/index, deep ownership, const access, one step storage, and absence of equation state.
  • Targeted command: build fesa_tests, then ctest --test-dir .harness/build -C Debug -R DomainModel --output-on-failure.
  • Full VERIFY:
cmake -S . -B .harness/build -A x64 -DFESA_GTEST_SOURCE_DIR=C:/git/googletest "-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" "-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" "-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R DomainModel --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure

TASK-11: inp-syntax-parser

Files: create include/fesa/io/abaqus/input_syntax.hpp for syntax records, input_reader.hpp for the reader boundary, src/fesa/io/abaqus/input_reader.cpp for lexical/syntax parsing; create tests/unit/io/abaqus/input_syntax_test.cpp and input_reader_test.cpp; modify CMake lists only for syntax parsing.

  • Consumes: SourceLocation, Diagnostic, Result<T>.
  • Produces: KeywordParameter, DataLine, KeywordBlock, ParsedInput, and AbaqusInputReader::read; it records normalized source path plus a deterministic fnv1a64: prefix followed by exactly 16 lowercase hexadecimal digits computed from the exact input bytes, and makes no B33 or keyword-policy decisions.
  • Tests: T11-SYN-001 = InpSyntax.CanonicalizesKeywordAndParameterNamesOnly; T11-SYN-002 = InpSyntax.PreservesDataAndSourceLocations; T11-SYN-003 = InpSyntax.RejectsMalformedOrOrphanData; T11-SYN-004 = InpSyntax.ReadsLegacyCantileverWithoutMutation.
  • RED/GREEN: registered parser tests fail for missing reader; GREEN covers mixed case, comments, blanks/trailing fields, valueless parameters, unreadable files, malformed syntax, and legacy syntax.
  • Targeted command: build fesa_tests, then ctest --test-dir .harness/build -C Debug -R InpSyntax --output-on-failure.
  • Full VERIFY:
cmake -S . -B .harness/build -A x64 -DFESA_GTEST_SOURCE_DIR=C:/git/googletest "-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" "-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" "-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R InpSyntax --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure

TASK-12: inp-domain-mapping

Files: create include/fesa/io/abaqus/domain_mapper.hpp, src/fesa/io/abaqus/domain_mapper.cpp, and tests/unit/io/abaqus/domain_mapper_test.cpp; modify CMake lists only for semantic mapping.

  • Consumes: ParsedInput, ModelDefinition, and Domain::create.
  • Produces: AbaqusDomainMapper::map returning a complete immutable Domain or ordered diagnostics; maps only the approved keyword grammar, exact four-field *STATIC, B33, identity instances, exact section/material rules, warning no-ops, and stable expansions.
  • Tests: T12-MAP-001 = InpDomainMapping.MapsEverySupportedKeywordAndLegacyDeck; T12-MAP-002 = InpDomainMapping.ExpandsSetsAndMultipleIdentityInstancesDeterministically; T12-MAP-003 = InpDomainMapping.NoOpAllowlistWarnsWithoutSemanticEffect; T12-MAP-004 = InpDomainMapping.RejectsUnsupportedAndInvalidPortfolio; T12-MAP-005 = InpDomainMapping.RejectsDloadWithoutDistributedLoadObject.
  • RED/GREEN: positive and table-driven negative tests are registered before the mapper and fail RED; GREEN includes B31, second step, transform, nested assembly, coupled section, invalid geometry/property, duplicate, dangling, nonfinite, malformed arity, NLGEOM, unknown keyword, and *DLOAD diagnostics.
  • Targeted command: build fesa_tests, then ctest --test-dir .harness/build -C Debug -R InpDomainMapping --output-on-failure.
  • Full VERIFY:
cmake -S . -B .harness/build -A x64 -DFESA_GTEST_SOURCE_DIR=C:/git/googletest "-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" "-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" "-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R InpDomainMapping --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure

TASK-13: analysis-model

Files: create include/fesa/analysis/analysis_model.hpp, src/fesa/analysis/analysis_model.cpp, and tests/unit/analysis/analysis_model_test.cpp; modify CMake lists only for the active view.

  • Consumes: immutable Domain and its sole StaticStepDefinition.
  • Produces: AnalysisModel::create and the exact active-ID/reference accessors in the ledger; reachable material/section IDs are deduplicated in stable internal-index order.
  • Tests: T13-MODEL-001 = AnalysisModel.ClassifiesActiveEntitiesInStableOrder; T13-MODEL-002 = AnalysisModel.ReferencesWithoutCopyingOrMutatingDomain; T13-MODEL-003 = AnalysisModel.RejectsMissingOrMultipleStep.
  • RED/GREEN: missing class gives RED; GREEN proves address identity, stable deduplication, immutability, and cardinality diagnostics.
  • Targeted command: build fesa_tests, then ctest --test-dir .harness/build -C Debug -R AnalysisModel --output-on-failure.
  • Full VERIFY:
cmake -S . -B .harness/build -A x64 -DFESA_GTEST_SOURCE_DIR=C:/git/googletest "-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" "-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" "-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R AnalysisModel --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure

TASK-14: dof-manager

Files: create include/fesa/fem/dof_manager.hpp, src/fesa/fem/dof_manager.cpp, and tests/unit/fem/dof_manager_test.cpp; modify CMake lists only for DOF ownership.

  • Consumes: AnalysisModel, Vector, expanded boundary targets, active element connectivity.
  • Produces: exact DofManager, DofComponent, and SparsePattern ledger contracts; prescribedValues() is ordered exactly like constrainedDofs().
  • Tests: T14-DOF-001 = DofManager.NumbersSixDofsAndFreeEquationsStably; T14-DOF-002 = DofManager.ExpandsAndValidatesPrescribedValues; T14-DOF-003 = DofManager.BuildsTwelveDofScatterAndSortedUniquePattern; T14-DOF-004 = DofManager.ReconstructsFullReducedRoundTrip.
  • RED/GREEN: numbering/constraint/pattern tests fail before production; GREEN covers zero/nonzero prescriptions, equal overlap, conflicting overlap, element scatter, sorted-unique pattern, and no Node/Element equation ID.
  • Targeted command: build fesa_tests, then ctest --test-dir .harness/build -C Debug -R DofManager --output-on-failure.
  • Full VERIFY:
cmake -S . -B .harness/build -A x64 -DFESA_GTEST_SOURCE_DIR=C:/git/googletest "-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" "-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" "-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R DofManager --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure

TASK-15: analysis-state

Files: create include/fesa/results/result_records.hpp for row identities, include/fesa/analysis/analysis_state.hpp for state ownership, src/fesa/analysis/analysis_state.cpp for allocation/access; create tests/unit/results/result_records_test.cpp and tests/unit/analysis/analysis_state_test.cpp; modify CMake lists only for result records/state.

  • Consumes: DofManager, Vector, model identities.
  • Produces: StepFrameIdentity, endpoint/Gauss/stress records, and exact AnalysisState accessors; every full vector is independently owned, full-size, and zero-initialized.
  • Tests: T15-STATE-001 = AnalysisState.AllocatesOnlyV0FullVectors; T15-STATE-002 = AnalysisState.PreservesStepFrameAndStableRowOrder; T15-STATE-003 = AnalysisState.CopiesOrMovesWithoutAliasing.
  • RED/GREEN: missing records/state produce RED; GREEN proves allocation, ownership, identity/order, reaction full-space semantics, and absence of velocity, acceleration, temperature, and nonlinear state APIs.
  • Targeted command: build fesa_tests, then ctest --test-dir .harness/build -C Debug -R AnalysisState --output-on-failure.
  • Full VERIFY:
cmake -S . -B .harness/build -A x64 -DFESA_GTEST_SOURCE_DIR=C:/git/googletest "-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" "-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" "-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R AnalysisState --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure

TASK-16: euler-beam-element

Files: create include/fesa/elements/euler_beam_3d.hpp for ConstantLocalLineLoad, stress/recovery records, and kernel API; create src/fesa/elements/euler_beam_3d.cpp for geometry, Gauss stiffness, transform, load, and recovery; create tests/unit/elements/euler_beam_3d_test.cpp; modify CMake lists only for the element.

  • Consumes: Node, GeneralBeamSection, LinearElasticMaterial, Vector, Matrix, formulation signs and tolerances.
  • Produces: exact EulerBeam3D ledger contract and BeamRecovery; local order is [u1,v1,w1,rx1,ry1,rz1,u2,v2,w2,rx2,ry2,rz2]; dl=T*dg, Kg=T^T*Kl*T.
  • Tests: T16-BEAM-001 = EulerBeam3D.HermiteAndBMatrixMatchReviewedSigns; T16-BEAM-002 = EulerBeam3D.TwoPointGaussMatchesClosedStiffness; T16-BEAM-003 = EulerBeam3D.HasSixRigidModesRankSixAndPositiveDeformationEnergy; T16-BEAM-004 = EulerBeam3D.RotatedTransformPreservesWorkAndEnergy; T16-BEAM-005 = EulerBeam3D.ConstantLineLoadMatchesAllSignedComponents; T16-BEAM-006 = EulerBeam3D.AnalyticalAxialTorsionAndTwoPlaneBendingRecover; T16-BEAM-007 = EulerBeam3D.RejectsInvalidGeometryAndProperties; T16-BEAM-008 = EulerBeam3D.RecoversSectionPointAndDefaultCentroidS11; T16-BEAM-009 = EulerBeam3D.ReproducesConstantStrainTwistAndCurvaturePatches; T16-BEAM-010 = EulerBeam3D.OnePointNegativeControlHasRankFour.
  • RED/GREEN: all invariant/analytical tests are written before the kernel; GREEN enforces normalized 1e-12 matrices/transforms/end signs, 1e-10 rigid residual, relative 1e-9 analytical results, the length-scaled Q^-T*K*Q^-1 six/six singular-value split, exact axial/twist/two-curvature patches, production rank 6, test-only one-point rank 4, two production Gauss points, exact geometry thresholds, and no fallback axis.
  • Targeted command: build fesa_tests, then ctest --test-dir .harness/build -C Debug -R EulerBeam3D --output-on-failure.
  • Full VERIFY:
cmake -S . -B .harness/build -A x64 -DFESA_GTEST_SOURCE_DIR=C:/git/googletest "-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" "-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" "-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R EulerBeam3D --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure

TASK-17: parallel-for-tbb

Files: create include/fesa/assembly/parallel_for.hpp for backend-free interface/serial/TBB classes, src/fesa/assembly/parallel_for.cpp for implementations, and tests/unit/assembly/parallel_for_test.cpp; modify CMake lists only for the adapter.

  • Consumes: std::function and normalized oneTBB target; it does not consume sparse storage.
  • Produces: exact ParallelFor, SerialParallelFor, and TbbParallelFor contracts; each index executes exactly once and writes only its caller-owned indexed slot.
  • Tests: T17-PFOR-001 = ParallelFor.ZeroOneManyExecuteExactlyOnce; T17-PFOR-002 = ParallelFor.SerialAndTbbProduceStableIndexedOutput; T17-PFOR-003 = ParallelFor.PropagatesBodyExceptionByContract.
  • RED/GREEN: missing adapter gives RED; GREEN proves no-op zero count, exact-once semantics, stable output, and exception propagation without process-wide thread changes.
  • Targeted command: build fesa_tests, then ctest --test-dir .harness/build -C Debug -R ParallelFor --output-on-failure.
  • Full VERIFY:
cmake -S . -B .harness/build -A x64 -DFESA_GTEST_SOURCE_DIR=C:/git/googletest "-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" "-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" "-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R ParallelFor --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure

TASK-18: sparse-assembly

Files: create include/fesa/math/sparse_matrix.hpp and src/fesa/math/sparse_matrix.cpp for owning 0-based CSR; create include/fesa/assembly/sparse_assembler.hpp and src/fesa/assembly/sparse_assembler.cpp for element buffers and deterministic reduction; create tests/unit/math/sparse_matrix_test.cpp and tests/unit/assembly/sparse_assembler_test.cpp; modify CMake lists only for sparse math/assembly.

  • Consumes: AnalysisModel, DofManager, EulerBeam3D, ParallelFor, SparsePattern, Vector.
  • Produces: exact CooContribution, SparseMatrix, and SparseAssembler ledger contracts; expected structural zero slots are retained; SparseMatrix is unrelated by inheritance to Matrix.
  • Tests: T18-SPARSE-001 = SparseAssembly.ValidatesKnownCsrAndMultiply; T18-SPARSE-002 = SparseAssembly.ReducesDuplicatesInFixedTupleOrder; T18-SPARSE-003 = SparseAssembly.RejectsInvalidIndexPatternAndShape; T18-SPARSE-004 = SparseAssembly.SerialTbbAndRepeatedRunsAreByteIdentical; T18-SPARSE-005 = SparseAssembly.PreservesExpectedStructuralZeros.
  • RED/GREEN: CSR/determinism tests fail before implementation; GREEN produces sorted unique columns, valid offsets, fixed duplicate sums, empty rows when expected, symmetry, and byte-identical arrays across schedulers/runs.
  • Targeted command: build fesa_tests, then ctest --test-dir .harness/build -C Debug -R SparseAssembly --output-on-failure.
  • Full VERIFY:
cmake -S . -B .harness/build -A x64 -DFESA_GTEST_SOURCE_DIR=C:/git/googletest "-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" "-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" "-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R SparseAssembly --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure

TASK-19: essential-constraints

Files: create include/fesa/constraints/essential_constraints.hpp, src/fesa/constraints/essential_constraints.cpp, and tests/unit/constraints/essential_constraints_test.cpp; modify CMake lists only for partition/mapping.

  • Consumes: full SparseMatrix, DofManager order, full/reduced Vector values.
  • Produces: PartitionedStiffness {kff,kfc,kcf,kcc} and exact EssentialConstraints ledger functions without assembling loads or RHS.
  • Tests: T19-CONSTRAINT-001 = EssentialConstraints.ExtractsHandComputedBlocksInStableOrder; T19-CONSTRAINT-002 = EssentialConstraints.HandlesNoAllAndMixedConstraints; T19-CONSTRAINT-003 = EssentialConstraints.ReconstructsNonzeroPrescribedValues; T19-CONSTRAINT-004 = EssentialConstraints.RejectsDimensionOrOrderMismatch.
  • RED/GREEN: block/round-trip tests fail before production; GREEN preserves numeric/order/CSR invariants and never assumes dc=0.
  • Targeted command: build fesa_tests, then ctest --test-dir .harness/build -C Debug -R EssentialConstraints --output-on-failure.
  • Full VERIFY:
cmake -S . -B .harness/build -A x64 -DFESA_GTEST_SOURCE_DIR=C:/git/googletest "-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" "-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" "-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R EssentialConstraints --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure

TASK-20: mkl-pardiso-solver

Files: create include/fesa/solvers/linear/linear_solver.hpp for the backend boundary, include/fesa/solvers/linear/mkl_pardiso_solver.hpp for the PImpl class, src/fesa/solvers/linear/mkl_pardiso_solver.cpp for all MKL calls/workspace lifetime; create tests/unit/solvers/linear/linear_solver_test.cpp and mkl_pardiso_solver_test.cpp; modify CMake lists only for the solver.

  • Consumes: validated square SparseMatrix, Vector, Status, Diagnostic, official PARDISO contract.
  • Produces: exact LinearSolver and MklPardisoSolver signatures; factorize() validates the full public CSR, copies its upper triangle into private MKL CSR with every diagonal slot retained, then runs PARDISO phase 11 and 22 with mtype=2, iparm[34]=1, and matrix checking enabled; solve() runs phase 33; re-factorization and destruction release with phase -1 through RAII.
  • Tests: T20-PARDISO-001 = MklPardisoSolver.SolvesKnownSpdWithNormalizedResidual; T20-PARDISO-002 = MklPardisoSolver.ReusesOneFactorizationForRepeatedRhs; T20-PARDISO-003 = MklPardisoSolver.RefactorizesWithoutLeakingState; T20-PARDISO-004 = MklPardisoSolver.RejectsInvalidCsrStateAndDimensions; T20-PARDISO-005 = MklPardisoSolver.ClassifiesSingularIndefiniteAndNonfiniteFailures; T20-PARDISO-006 = MklPardisoSolver.ConditioningSweepPassesResolvedCasesAndFailsUnresolvedCasesExplicitly.
  • RED/GREEN: adapter tests fail before implementation; GREEN meets residual 1e-10, repeated RHS, solve-before-factorize, dimension, invalid CSR, zero/negative pivot, singular, and indefinite diagnostics without regularization. The documented valid-scale sweep requires residual 1e-10 and analytical error 1e-9 for resolved cases and a structured solver failure for numerically unresolved cases; it introduces no new conditioning threshold.
  • Targeted command: build fesa_tests, then ctest --test-dir .harness/build -C Debug -R MklPardisoSolver --output-on-failure.
  • Full VERIFY:
cmake -S . -B .harness/build -A x64 -DFESA_GTEST_SOURCE_DIR=C:/git/googletest "-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" "-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" "-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R MklPardisoSolver --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure

TASK-21: load-assembly

Files: create include/fesa/assembly/load_assembler.hpp, src/fesa/assembly/load_assembler.cpp, and tests/unit/assembly/load_assembler_test.cpp; modify CMake lists only for nodal load/RHS assembly.

  • Consumes: AnalysisModel, DofManager, SparseMatrix kfc, and prescribed dc.
  • Produces: exact LoadAssembler ledger functions; multiple loads sum in source order; effective RHS is exactly Ff-kfc*dc.
  • Tests: T21-LOAD-001 = LoadAssembly.AssemblesNodeSetAndSixComponentLoads; T21-LOAD-002 = LoadAssembly.AccumulatesSignedLoadsInSourceOrder; T21-LOAD-003 = LoadAssembly.FormsNonzeroPrescribedEffectiveRhs; T21-LOAD-004 = LoadAssembly.RejectsNonfiniteOrDimensionMismatch; T21-LOAD-005 = LoadAssembly.ZeroLoadsRemainZero.
  • RED/GREEN: registered load/RHS tests fail before implementation; GREEN handles constrained loads and nonzero dc without factorization calls or distributed-load objects.
  • Targeted command: build fesa_tests, then ctest --test-dir .harness/build -C Debug -R LoadAssembly --output-on-failure.
  • Full VERIFY:
cmake -S . -B .harness/build -A x64 -DFESA_GTEST_SOURCE_DIR=C:/git/googletest "-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" "-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" "-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R LoadAssembly --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure

TASK-22: result-recovery

Files: create include/fesa/results/result_recovery.hpp, src/fesa/results/result_recovery.cpp, and tests/unit/results/result_recovery_test.cpp; modify CMake lists only for recovery and station normalization.

  • Consumes: AnalysisModel, DofManager, full SparseMatrix, solved AnalysisState, and EulerBeam3D::recover.
  • Produces: exact ResultRecovery::recover; internalForce=K*d, residual=internalForce-externalForce, constrained reaction from residual, stable endpoint/Gauss/stress rows, and test-only reusable node-station projection semantics.
  • Tests: T22-RECOVERY-001 = ResultRecovery.ComputesResidualReactionForNonzeroPrescription; T22-RECOVERY-002 = ResultRecovery.EnforcesNormalizedFreeResidual; T22-RECOVERY-003 = ResultRecovery.KeepsEndActionSectionAndGaussResultsDistinct; T22-RECOVERY-004 = ResultRecovery.MatchesAxialTorsionAndTwoPlaneEndSigns; T22-RECOVERY-005 = ResultRecovery.OrdersStressPointsAndDefaultCentroid; T22-RECOVERY-006 = ResultRecovery.RequiresInteriorEndpointConsistencyWithoutAveraging.
  • RED/GREEN: reaction/sign/station tests fail before implementation; GREEN enforces free residual 1e-10, nonfinite failure, source/stable order, and smaller-element representative only after endpoint agreement.
  • Targeted command: build fesa_tests, then ctest --test-dir .harness/build -C Debug -R ResultRecovery --output-on-failure.
  • Full VERIFY:
cmake -S . -B .harness/build -A x64 -DFESA_GTEST_SOURCE_DIR=C:/git/googletest "-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" "-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" "-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R ResultRecovery --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure

TASK-23: hdf5-results-writer

Files: create include/fesa/results/results_writer.hpp for the backend-free interface, include/fesa/io/hdf5/hdf5_results_writer.hpp for the concrete class, src/fesa/io/hdf5/hdf5_results_writer.cpp for HDF5 RAII/schema/temp-final replacement; create tests/unit/results/results_writer_test.cpp and tests/unit/io/hdf5/hdf5_results_writer_test.cpp; modify CMake lists only for output.

  • Consumes: immutable Domain, solved AnalysisState, diagnostics, solverVersion().
  • Produces: exact ResultsWriter/Hdf5ResultsWriter signatures; schema v0 at literal Step-1/frame 0, including the required generalized_resultant sibling; same-directory temporary write, flush/close/self-check, then a private .cpp finalizer that uses ReplaceFileW for an existing final and MoveFileExW(..., MOVEFILE_WRITE_THROUGH) for a new final, preserving the previous final and removing the temporary file when replacement fails. Win32 types never enter either public header.
  • Tests: T23-HDF5-001 = Hdf5ResultsWriter.WritesExactSchemaShapesAttributesAndIdentity; T23-HDF5-002 = Hdf5ResultsWriter.WritesMandatoryOutputsDespiteOutputRequests; T23-HDF5-003 = Hdf5ResultsWriter.WritesWarningsAndDefaultCentroid; T23-HDF5-004 = Hdf5ResultsWriter.FailureLeavesNoPartialAndPreservesExistingFinal; T23-HDF5-005 = Hdf5ResultsWriter.SuccessfullyReplacesExistingFinal.
  • RED/GREEN: schema/atomicity tests fail before the writer; GREEN verifies every exact path/component/location, UTF-8 identity, unit label, finite values, RAII closure, temporary cleanup, and replacement behavior.
  • Targeted command: build fesa_tests, then ctest --test-dir .harness/build -C Debug -R Hdf5ResultsWriter --output-on-failure.
  • Full VERIFY:
cmake -S . -B .harness/build -A x64 -DFESA_GTEST_SOURCE_DIR=C:/git/googletest "-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" "-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" "-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R Hdf5ResultsWriter --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure

TASK-24: linear-static-cli

Files and single responsibilities

action file responsibility
create include/fesa/analysis/linear_static_analysis.hpp Template Method and injected linear-static API
create src/fesa/analysis/linear_static_analysis.cpp exact stage order and state handoff
create include/fesa/app/fesa_application.hpp argument/exit-code application boundary
create src/fesa/app/fesa_application.cpp CLI parsing, default adapters, diagnostic output
create src/fesa/app/main.cpp minimal process entry point only
create tests/integration/analysis/linear_static_analysis_test.cpp spy/fake lifecycle and real analytical integration
create tests/integration/app/fesa_application_test.cpp CLI paths, exit codes, output-request no-op
create tests/reference/reference_comparison.hpp test-only row/metric contract without HDF5 types
create tests/reference/reference_comparison.cpp read-only CSV/HDF5 projection, precheck, compare, deterministic JSON
create tests/reference/reference_comparison_test.cpp comparison-policy positive/negative tests
create tests/reference/b33_reference_comparison_test.cpp approved B33 end-to-end run and artifact generation
modify src/fesa/CMakeLists.txt add fesa executable with OUTPUT_NAME fesa
modify tests/CMakeLists.txt add integration/reference executables, labels, and fesa_tests dependencies
  • Consumes: every ledger interface from Tasks 08-23 and the exact four read-only files under reference/cantilever beam/.
  • Produces: exact Analysis, LinearStaticAnalysis, AnalysisRequest, and FesaApplication ledger contracts; production defaults are TbbParallelFor, MklPardisoSolver, and Hdf5ResultsWriter; generated evidence is .harness/build/reference/cantilever-beam-b33/results.h5 plus comparison.json.

The test-only reference_comparison.hpp contract is:

namespace fesa::test {
enum class ComparisonQuantity { displacement, reaction, sectionResultant };
struct CanonicalComparisonRow {
    std::string modelId;
    std::string stepName;
    std::size_t frameIndex;
    std::string instanceName;
    std::int64_t sourceNodeLabel;
    ComparisonQuantity quantity;
    std::string component;
    double value;
    std::string unitDimension;
    std::string coordinateSystem;
    std::string hdf5DatasetPath;
};
struct RowDecision {
    CanonicalComparisonRow fesa;
    CanonicalComparisonRow reference;
    double absoluteError;
    double tolerance;
    bool passed;
};
struct ComponentMetrics {
    ComparisonQuantity quantity;
    std::string component;
    double referenceScale;
    double maximumAbsoluteError;
    double maximumNormalizedError;
    double rmsError;
    double normError;
    std::size_t worstRow;
};
struct PhysicsEvidence {
    double freeResidualNorm;
    std::array<double, 3> appliedForce;
    std::array<double, 3> reactionForce;
    std::array<double, 3> appliedMomentAboutOrigin;
    std::array<double, 3> reactionMomentAboutOrigin;
    bool endpointConsistencyPassed;
};
struct ComparisonReport {
    std::vector<RowDecision> rows;
    std::vector<ComponentMetrics> metrics;
    PhysicsEvidence physicsEvidence;
    bool stressComparisonApplicable;
    std::string stressComparisonReason;
    bool passed;
};
class ReferenceComparison {
public:
    static Result<ComparisonReport> compare(
        const std::filesystem::path& resultsHdf5,
        const std::filesystem::path& legacyReferenceDirectory);
    static Status writeDeterministicJson(
        const ComparisonReport& report,
        const std::filesystem::path& outputJson);
};
} // namespace fesa::test

stressComparisonApplicable is always false for this approved bundle and is serialized with the reason that analytical/unit and HDF5 schema tests provide stress evidence. The comparator accepts only the literal legacy directory and exact filenames; it has no write operation for that directory.

All malformed-reference negative cases operate on copies created under .harness/build/reference/contract-fixtures/; no test opens a legacy reference path for writing.

  • Tests: T24-ORCH-001 = LinearStaticCli.FactorizesBeforeLoadAndSolvesWithoutRefactorization; T24-ORCH-002 = LinearStaticCli.RealPipelineHandlesAnalyticalAndNonzeroPrescription; T24-CLI-001 = LinearStaticCli.DefaultAndExplicitOutputProduceFesaHdf5; T24-CLI-002 = LinearStaticCli.ReturnsEveryExactExitCodeAndOrderedDiagnostic; T24-CLI-003 = LinearStaticCli.OutputRequestsDoNotFilterMandatoryResults; T24-REF-001 = ReferenceComparisonContract.PrecheckRejectsMissingSchemaDuplicateAndNonfiniteRows; T24-REF-002 = ReferenceComparisonContract.AppliesAbaqusOnlyComponentScaleWithoutClampOrDrop; T24-REF-003 = ReferenceComparisonContract.ReportsEveryRowAndAggregateMetricDeterministically; T24-REF-004 = ReferenceComparisonContract.NormalizesEligibleStationsWithoutAveraging; T24-B33-001 = B33ReferenceComparison.GeneratesAuthoritativeHdf5AndComparisonEvidence.
  • RED/GREEN: orchestration/CLI/reference tests are registered first and fail for missing APIs; GREEN fixes the exact event trace, all CLI forms/codes, artifact precheck, exact row sets, header/component/frame/station normalization, zero/near-zero/failure tolerance cases, and deterministic metrics/physics evidence.
  • Step 26 handoff: B33ReferenceComparison is a completed test-only executable/test at the end of this task. Step 26 runs it and reads comparison.json without modifying source, tests, CMake, tolerances, or reference artifacts. Stress is recorded as N/A for Abaqus comparison while HDF5 stress_s11 remains required.
  • Targeted command:
cmake --build .harness/build --config Debug --target fesa_tests
ctest --test-dir .harness/build -C Debug -R "LinearStaticCli|ReferenceComparisonContract|B33ReferenceComparison" --output-on-failure
  • Full VERIFY:
cmake -S . -B .harness/build -A x64 -DFESA_GTEST_SOURCE_DIR=C:/git/googletest "-DMKL_DIR=C:/Program Files (x86)/Intel/oneAPI/mkl/2026.1/lib/cmake/mkl" "-DTBB_DIR=C:/Program Files (x86)/Intel/oneAPI/tbb/2023.1/lib/cmake/tbb" "-DHDF5_DIR=C:/Program Files/HDF_Group/HDF5/2.1.1/cmake"
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug -R "LinearStaticCli|ReferenceComparisonContract|B33ReferenceComparison" --output-on-failure
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure
git diff --exit-code -- reference/

TDD Test Plan

test group test type required RED condition required GREEN condition task targeted regex
T07-BUILD-* foundation test target sees missing build-info API version API, discovery, warning isolation pass TASK-07 BuildInfo
T08-CORE-* unit core type/header or behavior absent identity, status/result, fields/order pass TASK-08 CoreDiagnostics
T09-DENSE-* unit/backend dense types absent storage, checking, BLAS values pass TASK-09 DenseMath
T10-DOM-* unit/model semantic ownership types absent immutable stable Domain passes TASK-10 DomainModel
T11-SYN-* parser syntax reader absent lexical/syntax/source-location cases pass TASK-11 InpSyntax
T12-MAP-* parser semantic mapper absent complete positive/negative inventory passes TASK-12 InpDomainMapping
T13-MODEL-* unit/analysis active view absent stable non-copy view passes TASK-13 AnalysisModel
T14-DOF-* unit/FEM numbering/maps absent DOF, constraint, scatter, pattern pass TASK-14 DofManager
T15-STATE-* unit/state records/state absent exact V0 ownership/allocation passes TASK-15 AnalysisState
T16-BEAM-* formulation/analytical kernel absent or reviewed invariant fails all NR-T01 through NR-T08 element criteria pass TASK-16 EulerBeam3D
T17-PFOR-* adapter parallel boundary absent serial/TBB semantic equivalence passes TASK-17 ParallelFor
T18-SPARSE-* unit/assembly CSR/reducer absent canonical byte-identical CSR passes TASK-18 SparseAssembly
T19-CONSTRAINT-* unit/constraints partition absent exact blocks and nonzero reconstruction pass TASK-19 EssentialConstraints
T20-PARDISO-* backend/solver solver absent SPD, repeated RHS, failure diagnostics pass TASK-20 MklPardisoSolver
T21-LOAD-* unit/assembly load/RHS assembler absent nodal load and Ff-Kfc*dc pass TASK-21 LoadAssembly
T22-RECOVERY-* unit/results recovery absent residual/end/Gauss/stress/station rules pass TASK-22 ResultRecovery
T23-HDF5-* I/O writer/schema absent exact schema and atomicity pass TASK-23 Hdf5ResultsWriter
T24-ORCH-*, T24-CLI-* integration lifecycle/app absent exact stage/CLI/HDF5 path passes TASK-24 LinearStaticCli
T24-REF-* reference-contract comparator absent fail-fast row policy/tolerance/report pass TASK-24 ReferenceComparisonContract
T24-B33-* end-to-end reference approved run/comparison absent HDF5 and deterministic JSON are generated, all rows pass TASK-24 B33ReferenceComparison

Every implementation report RED entry must show a nonzero exit and the expected missing API or failed behavior. A configure/environment failure is not acceptable RED evidence. Every GREEN entry must show the same targeted regex at exit 0 after the minimum implementation.

CMake and CTest Plan

  • Root project: C++17 required, extensions off, enable_testing(), dependencies loaded from cmake/FesaDependencies.cmake.
  • Production library: fesa_solver static library. Apply /W4 /WX only when MSVC; never propagate it to GoogleTest, oneMKL, oneTBB, or HDF5 targets.
  • Application: target may be internally named fesa_app, but OUTPUT_NAME fesa is mandatory so Debug emits fesa.exe.
  • Tests: fesa_unit_tests, fesa_integration_tests, and fesa_reference_tests are GoogleTest executables. Custom target fesa_tests depends on all currently defined test executables so every Step's prescribed build command remains stable.
  • Discovery: use gtest_discover_tests; every discovered test carries linear-static-3d-euler-beam plus one of unit, parser, io, integration, or reference as appropriate. The exact suite names in the TDD plan preserve targeted CTest regexes.
  • Reference working directory: repository root so legacy relative paths remain exact; generated files go only under .harness/build/reference/cantilever-beam-b33/.
  • Dependency configuration is explicit and local; do not fetch or vendor dependencies and do not hardcode C:/git/googletest as a CMake default.
  • Harness auto-detection is used because .harness/config.json is absent.

Baseline commands required by the project contract are:

cmake -S . -B .harness/build -A x64
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --show-only=json-v1
ctest --test-dir .harness/build -C Debug --output-on-failure

The executable phase commands add the approved local dependency cache variables exactly as shown in each task. At least one test must be present in CTest JSON at every completed implementation Step.

Public dependency scans are additional Step evidence:

$denseLeaks = rg -n "mkl\.h|MKL_INT|CBLAS_" include/fesa
if ($LASTEXITCODE -eq 0) { throw "MKL API leaked into public headers:`n$denseLeaks" }
$pardisoLeaks = rg -n "mkl\.h|MKL_INT|pardiso" include/fesa
if ($LASTEXITCODE -eq 0) { throw "PARDISO API leaked into public headers:`n$pardisoLeaks" }
$tbbLeaks = rg -n "oneapi/tbb|tbb/" include/fesa
if ($LASTEXITCODE -eq 0) { throw "oneTBB API leaked into public headers:`n$tbbLeaks" }
$hdf5Leaks = rg -n "H5[A-Z_a-z0-9]*|hid_t" include/fesa
if ($LASTEXITCODE -eq 0) { throw "HDF5 API leaked into public headers:`n$hdf5Leaks" }

Acceptance Traceability Matrix

requirement implementation task GoogleTest evidence reference/acceptance evidence
FESA-REQ-LS3DEB-001 TASK-12, TASK-13, TASK-24 T12-MAP-004, T13-MODEL-003, T24-CLI-002 single step runs; second step structured failure
FESA-REQ-LS3DEB-002 TASK-12, TASK-16, TASK-24 T12-MAP-004, T16-BEAM-006, T24-ORCH-002 only straight prismatic small-linear B33 reaches solve
FESA-REQ-LS3DEB-003 TASK-14, TASK-15, TASK-23 T14-DOF-001, T15-STATE-001, T23-HDF5-001 exact six-component nodal order
FESA-REQ-LS3DEB-004 TASK-16, TASK-22 T16-BEAM-006, T22-RECOVERY-004 four analytical modes at relative 1e-9
FESA-REQ-LS3DEB-005 TASK-12, TASK-24 T12-MAP-001, T24-B33-001 B33 semantic object and artifact input precheck
FESA-REQ-LS3DEB-006 TASK-12 T12-MAP-004 exact unsupported-element-formulation
FESA-REQ-LS3DEB-007 TASK-12, TASK-14, TASK-19, TASK-21 T12-MAP-001, T14-DOF-002, T19-CONSTRAINT-003, T21-LOAD-003 DOF 1..6 and nonzero dc residual 1e-10
FESA-REQ-LS3DEB-008 TASK-12, TASK-16 T12-MAP-005, T16-BEAM-005 normalized 1e-12 kernel; *DLOAD rejected
FESA-REQ-LS3DEB-009 TASK-12 T12-MAP-001 positive coverage for exact keyword inventory
FESA-REQ-LS3DEB-010 TASK-11, TASK-12 T11-SYN-001, T11-SYN-002, T12-MAP-001 case-insensitive names/comments and raw identity
FESA-REQ-LS3DEB-011 TASK-12, TASK-14, TASK-21 T12-MAP-001, T12-MAP-004, T14-DOF-002, T21-LOAD-001 exact row grammar and deterministic target expansion
FESA-REQ-LS3DEB-012 TASK-12, TASK-16 T12-MAP-001, T16-BEAM-004, T16-BEAM-007 exact section/axis map, transform 1e-12
FESA-REQ-LS3DEB-013 TASK-12, TASK-16 T12-MAP-004, T16-BEAM-007 exact E,nu, derived positive G, positive properties
FESA-REQ-LS3DEB-014 TASK-12, TASK-16 T12-MAP-004, T16-BEAM-007 both exact scale-aware thresholds
FESA-REQ-LS3DEB-015 TASK-10, TASK-12, TASK-23 T10-DOM-001, T12-MAP-002, T23-HDF5-001 source/internal identity round-trip
FESA-REQ-LS3DEB-016 TASK-10, TASK-12 T10-DOM-003, T12-MAP-002 same-part instances remain distinct
FESA-REQ-LS3DEB-017 TASK-12 T12-MAP-004 exact unsupported-instance-transform
FESA-REQ-LS3DEB-018 TASK-12 T12-MAP-004 nested/dependent semantics rejected
FESA-REQ-LS3DEB-019 TASK-12, TASK-23 T12-MAP-003, T23-HDF5-003 exact warning no-op allowlist retained in diagnostics
FESA-REQ-LS3DEB-020 TASK-12, TASK-23, TASK-24 T12-MAP-004, T23-HDF5-002, T24-CLI-003 unknown model keyword fails; mandatory output unchanged
FESA-REQ-LS3DEB-021 TASK-10, TASK-13 T10-DOM-002, T13-MODEL-002 immutable Domain, non-copy active view
FESA-REQ-LS3DEB-022 TASK-14 T14-DOF-001, T14-DOF-003, T14-DOF-004 sole equation/scatter/pattern ownership
FESA-REQ-LS3DEB-023 TASK-15, TASK-23 T15-STATE-001, T15-STATE-002, T23-HDF5-001 exact required state connected to output; excluded state absent
FESA-REQ-LS3DEB-024 TASK-17, TASK-18 T17-PFOR-002, T18-SPARSE-004 stable element-local work and deterministic CSR 1e-12
FESA-REQ-LS3DEB-025 TASK-09, TASK-17, TASK-18, TASK-20, TASK-23 T09-DENSE-001, T09-DENSE-002, T17-PFOR-002, T18-SPARSE-001, T20-PARDISO-001, T23-HDF5-001 storage contracts plus no-leak scans
FESA-REQ-LS3DEB-026 TASK-20, TASK-24 T20-PARDISO-002, T24-ORCH-001 exact factorize-before-load event trace
FESA-REQ-LS3DEB-027 TASK-19, TASK-21, TASK-22 T19-CONSTRAINT-003, T21-LOAD-003, T22-RECOVERY-001 exact RHS, full reconstruction, residual reaction
FESA-REQ-LS3DEB-028 TASK-23, TASK-24 T23-HDF5-004, T23-HDF5-005, T24-CLI-001 authoritative HDF5 and atomic failure/success
FESA-REQ-LS3DEB-029 TASK-23 T23-HDF5-001 every exact schema-v0 path; generalized-resultant sibling included
FESA-REQ-LS3DEB-030 TASK-07, TASK-10, TASK-23, TASK-24 T07-BUILD-001, T10-DOM-001, T23-HDF5-001, T24-B33-001 metadata, stable identity, ordinary label, external SI provenance
FESA-REQ-LS3DEB-031 TASK-15, TASK-16, TASK-22, TASK-23 T15-STATE-002, T16-BEAM-006, T22-RECOVERY-003, T23-HDF5-001 exact components/locations independent of requests
FESA-REQ-LS3DEB-032 TASK-16, TASK-22, TASK-23, TASK-24 T16-BEAM-008, T22-RECOVERY-005, T23-HDF5-003, T24-B33-001 axial S11; no shear; reference stress explicit N/A
FESA-REQ-LS3DEB-033 TASK-08, TASK-24 T08-CORE-002, T24-CLI-001, T24-CLI-002 exact CLI forms/codes/ordered diagnostic fields
FESA-REQ-LS3DEB-034 TASK-07 through TASK-24 every T07-* through T24-* group per-Step report RED/GREEN/VERIFY; discovery nonzero; /W4 /WX
FESA-REQ-LS3DEB-035 TASK-16, TASK-18, TASK-19, TASK-20, TASK-22 T16-BEAM-001 through 010, T18-SPARSE-004, T19-CONSTRAINT-003, T20-PARDISO-001, T20-PARDISO-006, T22-RECOVERY-002 exact 1e-12, 1e-10, 1e-9 criteria and NR-T01..T11 coverage
FESA-REQ-LS3DEB-036 TASK-24 T24-REF-002, T24-B33-001 Abaqus-only component scale and exact mixed formula
FESA-REQ-LS3DEB-037 TASK-24 T24-REF-002, T24-B33-001 exact SI floors and zero-scale case
FESA-REQ-LS3DEB-038 TASK-24 T24-REF-001, T24-REF-002 missing/extra/duplicate/nonfinite/schema/identity fail first; no clamp/drop
FESA-REQ-LS3DEB-039 TASK-24 T24-REF-003, T24-B33-001 every row plus max absolute/normalized/RMS/norm/worst metrics
FESA-REQ-LS3DEB-040 TASK-11, TASK-24 T11-SYN-004, T24-REF-001, T24-B33-001 exact four paths and git diff --exit-code -- reference/
FESA-REQ-LS3DEB-041 TASK-24 T24-REF-001, T24-B33-001 four files, B33, exact headers, unique finite rows before compare
FESA-REQ-LS3DEB-042 TASK-22, TASK-24 T22-RECOVERY-006, T24-REF-004, T24-B33-001 exact component mapping/station eligibility/no-average
FESA-REQ-LS3DEB-043 TASK-24 and Steps 25-28 gates T24-ORCH-001, T24-REF-003, T24-B33-001 Step 25 build pass precedes Step 26 rerun; JSON carries Step 27 physics evidence
FESA-REQ-LS3DEB-044 TASK-12, TASK-16, TASK-24 T12-MAP-005, T16-BEAM-005, T24-REF-001 no reference solver/artifact mutation and no out-of-scope support claim

Implementation Report Evidence Contract

docs/linear-static-3d-euler-beam/implementation-report.md is created in TASK-07 and appended in TASK-08 through TASK-24. It must use this fixed structure for every Step:

## Step 16 — euler-beam-element
- task_id: TASK-16
- status: completed
- changed_files: exact repository-relative list
- requirement_ids: exact linked requirement IDs
- test_ids: exact linked test IDs

| stage | exact command | exit_code | expected_or_observed_result | evidence_tail |
| --- | --- | ---: | --- | --- |
| RED | targeted build/test command | nonzero | missing API or named behavior failure | concise compiler/test tail |
| GREEN | targeted build/test command | 0 | named regex passes | passed test/count tail |
| VERIFY-configure | exact CMake configure | 0 | MSVC x64 Debug generated | generator/compiler tail |
| VERIFY-build | exact build command | 0 | no warning under FESA `/W4 /WX` | build tail |
| VERIFY-discovery | CTest JSON discovery | 0 | discovered count at least one | count/regex tail |
| VERIFY-full | full CTest command | 0 | zero failed tests | summary tail |

- contract_checks: public dependency scan, numerical tolerance, ordering, or artifact check used by this Step
- generated_evidence: exact build-relative artifact paths or N/A
- reference_diff: unchanged or N/A; TASK-24 records `git diff --exit-code -- reference/` exit 0
- handoff: exact types/files/tests available to the next Step

The actual report repeats this section with each real Step number/name; it must not copy the example values when they do not apply. RED is invalid if failure is caused by a missing dependency, bad generator, stale build cache, or unrelated regression. TASK-24 additionally records results.h5, comparison.json, matched-row counts, physics-evidence keys, and the unchanged reference diff. Build/Test Executor Step 25 independently records command, exit code, duration, output tail, and failure classification in its own report.

Correction and Failure Boundaries

  • Classify failures as configure | compile | link | test | reference-comparison | harness | environment | upstream-contract before editing.
  • Correction may change only the source/header/test/CMake files owned by the failing task and must rerun that task's targeted command before full VERIFY.
  • Do not correct a failure by changing a requirement, formula/sign, I/O grammar/schema, reference artifact, row identity, component mapping, tolerance coefficient/floor, or gate order.
  • Do not regularize a singular PARDISO system, reinterpret B31, ignore transforms, add a fallback beam axis, clamp reference values, drop rows, average endpoint mismatch, or synthesize absent stress/SF2/SF3 reference rows.
  • Repeated environment failure is handed to the user; repeated implementation-owned failure is handed to the Correction Agent; any upstream contradiction is handed through the Coordinator Agent without contract edits.

Downstream Handoff

Implementation Agent

  • Execute TASK-07 through TASK-24 in order; do not pre-create later modules.
  • Read this plan and the task's Step file completely, but use approved upstream contract precedence recorded in Readiness resolutions.
  • End every Step green with implementation-report evidence and its exact phase-index summary.

Build/Test Executor Agent

  • Re-run the explicit dependency configure, Debug build, feature-label/regex tests, JSON discovery, and full CTest without source changes.
  • Confirm MSVC, x64, Debug, nonzero tests, no warnings, and reference/ unchanged.

Correction Agent

  • Use the failure classification and the task/test trace in the implementation report.
  • Apply only a minimal implementation-owned repair; upstream contracts, reference artifacts, and tolerances are immutable.

Reference Verification Agent

  • After Step 25 passes, run the already-built B33ReferenceComparison CTest and inspect its existing deterministic comparison.json.
  • Write the Step 26 report without modifying source, tests, CMake, reference files, matching rules, or tolerances.

Physics Evaluation Agent

  • Consume comparison.json.physics_evidence only after Step 26 passes; independently review force/moment equilibrium, reaction sign, displacement direction, symmetry, endpoint consistency, and residual.

Open Issues

  • No issue blocks implementation. The only permitted later escalation is a newly observed environment failure or an actual contradiction between implemented behavior and an approved upstream contract.