7.6 KiB
Architecture Decision Records
ADR-001: Solver Development Workflow Is Stage-Gated
Decision: FESA solver features must follow this workflow: requirements, research, formulation, I/O contract, TDD reference models, implementation, reference comparison, tolerance decision, release.
Reason: Structural solver correctness depends on more than code execution. Requirements, mathematical formulation, input/output contracts, reference artifacts, numerical comparison, and release evidence must be traceable.
Tradeoff: Initial feature delivery is slower. The benefit is that implementation agents do not invent formulation, tolerance, or reference assumptions during coding.
ADR-002: C++17/MSVC/CMake/CTest Remain The Baseline
Decision: The project targets C++17 or newer, MSVC on Windows, CMake, and CTest. Default validation uses Visual Studio 17 2022, x64, Debug.
Reason: The project is a Windows/MSVC structural solver. CMake/CTest gives a consistent build and test entry point for both harness validation and feature development.
Tradeoff: Visual Studio solution-only workflows and non-MSVC toolchains are not the primary path. They can be introduced by explicit ADR when needed.
ADR-003: MITC4 Linear Static Shell Is The Initial Solver Feature
Decision: The first solver implementation target is mitc4-linear-static-shell: a 4-node MITC4 shell element for linear static structural analysis.
Reason: MITC4 is a meaningful shell element target with strong research and OpenSees reference structure. It exercises element formulation, assembly, solver, I/O, and reference verification without immediately requiring nonlinear or dynamic analysis.
Tradeoff: This is more complex than a truss/bar bootstrap. The project accepts the complexity because MITC4 is the requested initial element.
ADR-004: OpenSees-Inspired Architecture, Modern C++ Ownership
Decision: FESA follows OpenSees-like conceptual boundaries: Domain, Node, Element, Material/Section, Analysis, SystemOfEqn, and Recorder/ResultWriter. It does not clone OpenSees raw ownership style.
Reason: OpenSees provides a useful solver architecture vocabulary, while modern C++17 RAII gives safer ownership and testable module boundaries.
Tradeoff: FESA classes will not be drop-in compatible with OpenSees. Similarity is architectural, not API compatibility.
ADR-005: MKL PARDISO For Global Linear Solves
Decision: FESA uses Intel oneAPI MKL CSR matrices and PARDISO for the initial global linear static solve.
Reason: Shell models need sparse linear algebra beyond toy dense solvers. MKL is already aligned with the Windows/MSVC toolchain and provides production-grade direct sparse solving.
Tradeoff: oneAPI MKL becomes a required dependency for real solver builds. The CMake configuration must detect MKLROOT or a known oneAPI installation path.
ADR-006: TBB For Parallel Element Work
Decision: FESA uses Intel oneAPI TBB for parallel element stiffness, residual/result recovery, and other embarrassingly parallel solver phases.
Reason: Element-level computation is a natural parallelism boundary. TBB integrates with oneAPI and avoids designing a custom thread pool.
Tradeoff: Global assembly must be deterministic. FESA will use thread-local contribution buffers and deterministic merge rather than concurrent writes into global CSR arrays.
ADR-007: HDF5 For Solver And Reference Results
Decision: FESA writes solver results to HDF5 and compares against stored HDF5 reference artifacts.
Reason: Shell results contain structured mesh, step/frame, nodal, element, Gauss point, resultant, stress, metadata, and tolerance data. HDF5 is better suited than flat CSV for this result hierarchy.
Tradeoff: HDF5 becomes a required dependency. FESA will provide an internal RAII wrapper over the HDF5 C API, but the actual HDF5 C library must be supplied by HDF5_ROOT or HDF5_DIR. The current local Windows install is C:\Program Files\HDF_Group\HDF5\2.1.1; use HDF5_ROOT for that root or HDF5_DIR for C:\Program Files\HDF_Group\HDF5\2.1.1\cmake.
ADR-008: Single Tolerance Policy
Decision: Reference comparison uses a single tolerance value 1e-5. A compared scalar passes when absolute error or relative error is within 1e-5.
Reason: A single tolerance policy is simple, explicit, and matches the current project decision.
Tradeoff: Quantity-specific scaling is deferred. If future models show that one global tolerance is too strict or too loose for some quantities, a new ADR must revise this policy.
ADR-009: Agents Do Not Run Reference Solvers
Decision: Abaqus, Nastran, and other reference solvers are not run by agents. Agents only consume stored reference artifacts.
Reason: Reference solver execution requires licensing, environment control, provenance, and human approval. Stored artifacts make validation reproducible inside the harness.
Tradeoff: Implementation can be blocked until required reference artifacts are supplied.
ADR-010: Domain, AnalysisModel, And AnalysisState Are Separate
Decision: Domain owns parsed model definition, AnalysisModel owns the active step execution view, and AnalysisState owns mutable solution and iteration state.
Reason: This prevents equation ids, displacement vectors, residuals, and future nonlinear/time states from leaking into input model objects. It also keeps the static solver compatible with future nonlinear, dynamic, and thermal workflows.
Tradeoff: The initial implementation has more object boundaries than a single monolithic model container.
ADR-011: Factory/Registry Handles Input Object Creation
Decision: Abaqus keyword parsing and internal object creation are separated through factory/registry mechanisms.
Reason: Adding elements, materials, loads, boundary conditions, sets, or properties should not require rewriting parser control flow.
Tradeoff: The first parser implementation needs a small registry layer before many object types exist.
ADR-012: Boundary Conditions Use DOF Elimination
Decision: Essential boundary conditions are applied by constrained DOF elimination. Reactions are recovered from the full system as K_full * U_full - F_full.
Reason: This gives a clear reduced solve while preserving physically meaningful reaction recovery for reference comparison.
Tradeoff: The implementation must preserve enough full-system information for reaction recovery instead of only storing the reduced matrix.
ADR-013: Results Use Step/Frame/Field/History Model
Decision: HDF5 results are organized by step, frame, field output, and history output.
Reason: The same result model can support static, nonlinear, dynamic, heat-transfer, and thermal-stress analyses.
Tradeoff: The v0 linear static output is more structured than a flat single-step result file.
ADR-014: Double Precision And 64-Bit Numbering
Decision: Solver scalar calculations use double; ids, sparse indices, and equation numbering are designed around int64 boundaries.
Reason: Structural solver verification needs double precision, and large sparse systems should not be blocked by 32-bit numbering assumptions.
Tradeoff: Memory use may be higher than a 32-bit-only implementation.
ADR-015: Units Are User-Consistent, Not Enforced
Decision: FESA does not enforce a unit system. Inputs and reference artifacts must be unit-consistent and record units in metadata.
Reason: Abaqus-style workflows commonly rely on user-consistent units.
Tradeoff: The solver cannot automatically detect every unit mismatch. Reference metadata and validation reports must make unit assumptions visible.