107 lines
7.7 KiB
Markdown
107 lines
7.7 KiB
Markdown
# 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 the validated runtime model object graph created from parsed input, `AnalysisModel` owns the active step execution view, and `AnalysisState` owns mutable solution and iteration state.
|
|
|
|
**Reason**: This prevents parser DTOs, equation ids, displacement vectors, residuals, and future nonlinear/time states from leaking into the persistent domain model. 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.
|