modify docu and reference
This commit is contained in:
@@ -0,0 +1,169 @@
|
||||
# Step 8: nonlinear-state-commit-rollback
|
||||
|
||||
## 읽어야 할 파일
|
||||
|
||||
- `AGENTS.md`
|
||||
- `docs/ARCHITECTURE.md`
|
||||
- `docs/ADR.md`
|
||||
- `docs/nonlinear-static-newton-raphson/requirements.md`
|
||||
- `docs/nonlinear-static-newton-raphson/formulation.md`
|
||||
- `docs/nonlinear-static-newton-raphson/io.md`
|
||||
- `include/fesa/analysis/analysis_state.h`
|
||||
- `src/fesa/analysis/analysis_state.cpp`
|
||||
- `include/fesa/core/source_identity.h`
|
||||
- `include/fesa/fem/dof_manager.h`
|
||||
- `include/fesa/model/domain.h`
|
||||
- `include/fesa/results/result_records.h`
|
||||
- Step 3 files: `include/fesa/elements/nonlinear_mitc4_shell.h`
|
||||
- Step 4 files: `include/fesa/elements/nonlinear_mitc4_shell.h`
|
||||
- Step 5 files: `include/fesa/analysis/nonlinear_static_control.h`
|
||||
- Step 6 files: `include/fesa/solvers/linear/tangent_solver.h`
|
||||
- Step 7 files: `include/fesa/analysis/newton_iteration_log.h`
|
||||
|
||||
## 이전 Step 전제
|
||||
|
||||
Steps 3-7 provide nonlinear element recovery, residual/tangent, controls, tangent solver, and Newton log record types.
|
||||
|
||||
## 소유 파일
|
||||
|
||||
- Create: `include/fesa/analysis/nonlinear_analysis_state.h`
|
||||
- Create: `src/fesa/analysis/nonlinear_analysis_state.cpp`
|
||||
- Create: `tests/unit/analysis/nonlinear_analysis_state_test.cpp`
|
||||
- Modify: `src/fesa/CMakeLists.txt`
|
||||
- Modify: `tests/CMakeLists.txt`
|
||||
|
||||
## 인터페이스
|
||||
|
||||
```cpp
|
||||
namespace fesa {
|
||||
|
||||
struct NonlinearNodeBaseline {
|
||||
EntityIndex node_index;
|
||||
SourceEntityId source_id;
|
||||
std::array<std::array<double, 3>, 3> triad;
|
||||
std::array<double, 3> director;
|
||||
};
|
||||
|
||||
struct NonlinearStateBaselineInput {
|
||||
std::vector<NonlinearNodeBaseline> node_baselines;
|
||||
};
|
||||
|
||||
struct NonlinearTrialState {
|
||||
std::uint32_t increment_index;
|
||||
double load_factor;
|
||||
bool is_factor_zero_baseline;
|
||||
std::vector<EntityIndex> nodal_internal_order;
|
||||
std::vector<SourceEntityId> nodal_source_ids;
|
||||
Vector generalized_coordinates;
|
||||
Vector displacement;
|
||||
Vector rotation_vector;
|
||||
std::vector<std::array<std::array<double, 3>, 3>> nodal_triad;
|
||||
std::vector<std::array<double, 3>> nodal_director;
|
||||
Vector internal_force;
|
||||
Vector external_force;
|
||||
Vector residual;
|
||||
Vector reaction;
|
||||
std::vector<ShellResultRow> shell_results;
|
||||
double physical_strain_energy;
|
||||
std::array<double, 6> global_equilibrium;
|
||||
};
|
||||
|
||||
struct AcceptedFrameState {
|
||||
std::uint32_t frame_index;
|
||||
std::uint32_t increment_index;
|
||||
double load_factor;
|
||||
std::uint32_t iteration_count;
|
||||
bool is_factor_one;
|
||||
std::vector<EntityIndex> nodal_internal_order;
|
||||
std::vector<SourceEntityId> nodal_source_ids;
|
||||
Vector generalized_coordinates;
|
||||
Vector displacement;
|
||||
Vector rotation_vector;
|
||||
std::vector<std::array<std::array<double, 3>, 3>> nodal_triad;
|
||||
std::vector<std::array<double, 3>> nodal_director;
|
||||
Vector internal_force;
|
||||
Vector external_force;
|
||||
Vector residual;
|
||||
Vector reaction;
|
||||
std::vector<ShellResultRow> shell_results;
|
||||
double physical_strain_energy;
|
||||
std::array<double, 6> global_equilibrium;
|
||||
};
|
||||
|
||||
class NonlinearAnalysisState {
|
||||
public:
|
||||
static Result<NonlinearAnalysisState> Create(
|
||||
const Domain& domain,
|
||||
const DofManager& dofs,
|
||||
const NonlinearStateBaselineInput& baseline);
|
||||
|
||||
Result<NonlinearTrialState> BeginTrialFromCommitted() const;
|
||||
Status CommitAcceptedFrame(const AcceptedFrameState& frame);
|
||||
void DiscardTrial() noexcept;
|
||||
const std::vector<AcceptedFrameState>& AcceptedFrames() const noexcept;
|
||||
const NonlinearTrialState& CommittedState() const noexcept;
|
||||
};
|
||||
|
||||
} // namespace fesa
|
||||
```
|
||||
|
||||
## RED
|
||||
|
||||
Add tests first.
|
||||
|
||||
- `NSNR-STATE-000`: `NonlinearAnalysisState::Create` requires exactly one `NonlinearNodeBaseline` per `Domain.Nodes()` entry in stable internal order; each entry has `node_index` equal to its vector offset and `source_id` equal to `Domain.Nodes()[node_index].source_id`.
|
||||
- `NSNR-STATE-001`: `NonlinearAnalysisState::Create` rejects missing, extra, duplicate, out-of-order, or instance-label mismatched node identities before any mutable state is produced.
|
||||
- `NSNR-STATE-002`: `NonlinearAnalysisState::Create` validates node/DOF/frame inventory, sizes all vectors, preserves `nodal_internal_order` and `nodal_source_ids`, and creates a committed factor-zero baseline with `increment_index=0`, `load_factor=0.0`, `is_factor_zero_baseline=true`, and no accepted frames.
|
||||
- `NSNR-STATE-003`: duplicate source labels across different instances remain distinct when `SourceEntityId::instance_name` differs.
|
||||
- `NSNR-STATE-004`: trial state starts from committed state and can be discarded without mutation.
|
||||
- `NSNR-STATE-005`: accepted frames are appended in stable accepted-factor order.
|
||||
- `NSNR-STATE-006`: frame index is zero-based accepted-frame order; the factor-zero committed baseline is metadata/state only and is never appended as an accepted frame.
|
||||
- `NSNR-STATE-007`: final frame at load factor `1.0` has `is_factor_one=true`.
|
||||
- `NSNR-STATE-008`: residual and reaction are stored from full residual `r = f_int - f_ext`.
|
||||
- `NSNR-STATE-009`: accepted frame owns generalized coordinates, displacement, rotation vector, per-node identity/order, per-node triad/director, internal/external/residual/reaction, stable `ShellResultRow` recovery, physical strain energy, and global equilibrium.
|
||||
- `NSNR-STATE-010`: all accepted-frame vectors match node/DOF counts and all `ShellResultRow` rows are stable element/midsurface order.
|
||||
- `NSNR-STATE-011`: commit validates finite values for every approved scalar and atomically rejects nonfinite frames with `invalid-accepted-state`.
|
||||
- `NSNR-STATE-012`: failed trial preserves prior committed state.
|
||||
- `NSNR-STATE-013`: no unapproved verification data is stored.
|
||||
- `NSNR-STATE-014`: committed and accepted nodal identity vectors are preserved for Step 9 HDF5 node datasets and Step 11 HDF5-to-reference source mapping; source label alone is never used as identity.
|
||||
|
||||
Run:
|
||||
|
||||
```powershell
|
||||
cmake --build .harness/build --config Debug
|
||||
ctest --test-dir .harness/build -C Debug -R "NonlinearAnalysisState|CommitRollback" --output-on-failure
|
||||
```
|
||||
|
||||
Expected: new tests fail. Unexpected pass stops.
|
||||
|
||||
## GREEN
|
||||
|
||||
Implement `NonlinearAnalysisState::Create` as the only construction seam for a valid nonlinear state. It uses `Domain`, `DofManager`, and `NonlinearStateBaselineInput` to require one baseline per Domain node in stable internal order, match both `EntityIndex` and full `SourceEntityId`, allocate zero generalized/displacement/rotation/internal/external/residual/reaction vectors, preserve nodal order/source identity for HDF5/reference mapping, install finite per-node triads/directors, and establish the committed factor-zero baseline without adding an accepted frame. Commit validates inventory, order, shape, identity, and finiteness before mutating committed state.
|
||||
|
||||
## VERIFY
|
||||
|
||||
```powershell
|
||||
cmake --fresh -S . -B .harness/build -G "Visual Studio 18 2026" -A x64 `
|
||||
"-DFESA_GTEST_SOURCE_DIR=$gtestSource" `
|
||||
"-DMKL_DIR=$mklDir" `
|
||||
"-DTBB_DIR=$tbbDir" `
|
||||
"-DHDF5_DIR=$hdf5Dir"
|
||||
cmake --build .harness/build --config Debug
|
||||
ctest --test-dir .harness/build -C Debug -R "NonlinearAnalysisState|CommitRollback" --output-on-failure
|
||||
ctest --test-dir .harness/build -C Debug --show-only=json-v1
|
||||
ctest --test-dir .harness/build -C Debug --output-on-failure
|
||||
```
|
||||
|
||||
Recheck `.harness/config.json` before default commands.
|
||||
|
||||
## 상태 기록
|
||||
|
||||
Update only Step 8 status and one-line payload. Executor owns timestamps, commits, retry, and advancement.
|
||||
|
||||
## 금지사항
|
||||
|
||||
- Do not put equation ids into Node or Element objects. 이유: `DofManager` owns equation numbering.
|
||||
- Do not identify baseline nodes by source label alone. 이유: labels are not unique across instances and cannot support stable HDF5/reference mapping.
|
||||
- Do not commit trial data before convergence gates pass. 이유: rollback/preservation contract depends on committed-state isolation.
|
||||
- Do not expand existing `AnalysisState` for future nonlinear features. 이유: this Step owns only approved NSNR state.
|
||||
- Do not store stress projections or verification data outside approved `ShellResultRow`, physical energy, and global equilibrium fields. 이유: schema v1 has a bounded accepted-state contract.
|
||||
Reference in New Issue
Block a user