From 0d9ac482ace0c21e119a9e788a45005df5de2085 Mon Sep 17 00:00:00 2001 From: "KOKO\\Mimi" Date: Sun, 16 Aug 2026 01:54:41 +0900 Subject: [PATCH] docs: define C++ modular refactoring design --- docs/CODINGSTYLE.md | 256 +++++++++++++ ...ect-oriented-modular-refactoring-design.md | 355 ++++++++++++++++++ 2 files changed, 611 insertions(+) create mode 100644 docs/CODINGSTYLE.md create mode 100644 docs/superpowers/specs/2026-08-16-cpp-object-oriented-modular-refactoring-design.md diff --git a/docs/CODINGSTYLE.md b/docs/CODINGSTYLE.md new file mode 100644 index 0000000..8812ed3 --- /dev/null +++ b/docs/CODINGSTYLE.md @@ -0,0 +1,256 @@ +# FESA C++ Coding Style + +## 목적 + +이 문서는 FESA production 및 test C++의 코드 스타일, 객체 설계, 문서화와 검증 규칙을 +정의하는 project-local source of truth다. 새 C++를 작성하거나 기존 C++를 리팩터링하는 +사람과 Implementation Agent는 작업 전에 이 문서를 읽어야 한다. + +[Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html)를 baseline으로 +사용한다. 이 문서, `AGENTS.md`, 승인된 feature contract와 architecture/ADR이 Google guide의 +일반 규칙보다 우선한다. + +## 적용 범위와 우선순위 + +규칙 충돌 시 다음 순서로 해석한다. + +1. 승인된 feature requirements, formulation, numerical-review, I/O와 reference contract +2. `AGENTS.md`, `docs/ARCHITECTURE.md`와 `docs/ADR.md` +3. 이 문서의 FESA-specific rule과 exception +4. Google C++ Style Guide +5. 기존 local style + +새 코드는 이 문서를 즉시 준수한다. 기존 코드는 승인된 refactoring plan의 module slice +단위로 전환한다. 요청 범위 밖의 file을 style-only 이유로 함께 수정하지 않는다. + +## Language와 Toolchain + +- Production language는 C++17 이상이며 MSVC x64를 지원해야 한다. +- 승인된 build 기준은 CMake, Visual Studio generator와 Debug configuration이다. +- C++ compiler extension에 의존하지 않는다. +- MKL, TBB, HDF5와 Win32 type은 public solver core header에 노출하지 않는다. +- Standard library와 RAII를 manual lifetime management보다 우선한다. +- Google guide가 현재 권장하는 C++20 language target은 FESA의 C++17 contract를 바꾸지 + 않는다. + +## File 이름과 Header + +- File 이름은 소문자 snake_case를 사용한다. +- Production 및 test source extension은 기존 FESA/CMake 관례인 `.cpp`를 유지한다. +- Header extension은 `.h`를 사용한다. 기존 `.hpp`는 승인된 migration slice에서 `.h`로 + 바꾼다. +- Header는 self-contained여야 하며 include consumer의 transitive include에 의존하지 + 않는다. +- Header는 `#pragma once` 대신 full repository path 기반 include guard를 사용한다. + +예: + +```cpp +#ifndef FESA_MATH_VECTOR3_H_ +#define FESA_MATH_VECTOR3_H_ + +namespace fesa { + +class Vector3 {}; + +} // namespace fesa + +#endif // FESA_MATH_VECTOR3_H_ +``` + +Include 순서는 다음과 같다. + +1. 대응하는 header +2. C system header +3. C++ standard library header +4. Third-party header +5. FESA project header + +각 non-empty group 사이에는 빈 줄을 두고 group 안에서는 알파벳순으로 정렬한다. 사용하는 +symbol의 declaration을 제공하는 header를 직접 include한다. + +## 이름 규칙 + +| 대상 | 규칙 | 예 | +| --- | --- | --- | +| class, struct, enum, alias | PascalCase | `ElementProperty`, `EntityIndex` | +| function, method, accessor | PascalCase | `ComputeStiffness()`, `NodeCount()` | +| local variable, parameter | snake_case | `element_index`, `source_order` | +| class data member | snake_case + trailing `_` | `youngs_modulus_` | +| struct data member | snake_case | `source_id` | +| compile-time/static constant | `kPascalCase` | `kNodeCount` | +| enumerator | `kPascalCase` | `FailureCategory::kModel` | +| namespace | snake_case | `fesa::hdf5_internal` | +| macro | UPPER_SNAKE_CASE | `FESA_MATH_VECTOR3_H_` | + +Google guide는 accessor의 snake_case를 허용하지만 FESA는 사용자 승인에 따라 production +및 test 호출부를 포함한 모든 function name에 PascalCase를 적용한다. Constructor, +destructor와 operator 이름은 C++ language 규칙을 따른다. + +이름은 물리 및 수치 의미를 드러내야 한다. `value`, `data`, `handler`, `manager`처럼 문맥이 +없는 generic name을 넓은 scope에서 사용하지 않는다. Source label, internal entity index와 +equation index를 이름에서 구분한다. + +## Formatting + +- `.clang-format`의 `BasedOnStyle: Google`을 사용한다. +- 들여쓰기는 space 2개이며 tab을 사용하지 않는다. +- 최대 line length는 80자다. Include, guard, URL과 분할할 수 없는 contract string은 Google + guide의 예외를 따른다. +- Opening brace는 declaration/control statement의 마지막 줄에 둔다. +- Namespace body는 들여쓰지 않고 closing namespace comment를 작성한다. +- 한 statement에 한 declaration만 둔다. +- Variable은 가능한 가장 좁은 scope에서 선언과 동시에 초기화한다. +- `const`와 `constexpr`를 의미가 허용하는 범위에서 사용한다. +- `override`, `final`, `explicit`, `noexcept`와 `[[nodiscard]]`는 실제 contract를 표현할 때 + 사용한다. + +Formatting-only 변경과 behavior/architecture 변경은 같은 commit에 섞지 않는다. + +## Class와 Interface 설계 + +- Class는 하나의 명확한 책임과 invariant를 가져야 한다. +- Polymorphic base는 public virtual destructor를 가져야 한다. +- Abstract interface에는 현재 concrete 구현이 공유하지 않는 future method를 추가하지 + 않는다. +- 단독 ownership은 `std::unique_ptr`로 표현한다. 실제 shared lifetime이 없는 + `std::shared_ptr`는 사용하지 않는다. +- Non-owning pointer/reference의 lifetime은 Doxygen contract에 기록한다. +- Downcast와 type switch를 주요 확장 mechanism으로 사용하지 않는다. +- State가 없는 함수를 묶기 위한 static-only class를 만들지 않는다. Internal namespace와 + focused module을 사용한다. +- Base class에 optional field와 no-op method를 누적하지 않는다. Material density, plastic + state와 anisotropic constitutive law처럼 독립적인 의미는 별도 capability 또는 구성 + 객체로 설계한다. +- Public header가 implementation/vendor dependency를 역으로 끌어오지 않도록 한다. + +Data-only record는 struct를 사용할 수 있다. Invariant, encapsulation, lifetime 또는 behavior가 +있으면 class를 사용한다. + +## FEM Module 책임 + +- `model`: immutable semantic definition과 stable source/internal identity +- `elements`: element numerical kernel, local contribution과 element recovery +- `properties`: element property identity와 concrete section data +- `materials`: constitutive capability와 concrete material behavior +- `fem`: DOF/equation numbering, scatter와 sparse pattern +- `assembly`: deterministic element/load contribution reduction +- `constraints`: constraint definition 적용과 equation policy +- `analysis`: procedure-specific lifecycle과 backend orchestration +- `results`: backend-neutral recovery record와 physical result identity +- `io`: Abaqus syntax/semantic mapping과 HDF5 schema implementation +- `math`: backend-neutral value/storage type와 private numerical adapter + +한 module의 class가 다른 module의 owner 책임을 가져가지 않는다. Element가 global CSR을 +직접 쓰거나 Node가 equation ID를 저장하거나 Material이 analysis state를 임의로 소유하면 +안 된다. + +## 중복과 공통화 + +같은 의미, units, coordinate, failure policy와 ownership을 가진 logic을 한 번만 구현한다. +현재 승인된 공통화 방향은 다음과 같다. + +- 3D coordinate/axis/director 연산은 `Vector3` value class +- source label/set/instance 해석은 `SourceTargetResolver` +- full/free/constrained invariant는 `DofManager` owner validation +- MKL size/copy helper는 private dense-BLAS adapter +- ASCII case-insensitive comparison과 label parsing은 focused core utility + +두 코드 block이 비슷해 보여도 formulation sign, result location, source identity 또는 +tolerance가 다르면 공통화하지 않는다. 단 한 번 사용하는 logic을 future flexibility만을 +위해 framework로 만들지 않는다. + +## Error와 Ownership + +- Expected failure는 `Status` 또는 `Result`로 반환한다. +- Public solver API를 통해 backend exception이 그대로 새지 않게 한다. +- Unknown type/property/material 조합은 structured diagnostic으로 fail-closed 처리한다. +- Invalid input을 silent default, clamp, average 또는 fallback으로 숨기지 않는다. +- Candidate를 완성하고 검증한 뒤 Domain state, AnalysisState 또는 final HDF5에 commit한다. +- Stable ordering과 failure atomicity는 optimization option이 아니라 correctness contract다. + +## Doxygen + +Doxygen coverage는 production code에만 요구한다. Test function과 test helper에는 Doxygen를 +요구하지 않는다. + +Public/protected class와 function declaration은 다음 내용을 필요한 만큼 기록한다. + +- `@brief`: 무엇을 하는지 동사형 한 문장 +- `@param`: 이름만으로 드러나지 않는 units, coordinates, ownership 또는 valid range +- `@return`: success value와 failure 의미 +- `@throws`: 실제로 경계를 넘어가는 exception +- `@pre`: caller가 보장해야 하는 invariant +- `@note`: deterministic order, lifetime 또는 backend constraint +- `@warning`: sign, physical/numerical distinction 또는 destructive side effect + +예: + +```cpp +/// @brief Computes the element stiffness in stable global DOF order. +/// @return A finite symmetric contribution or a structured model failure. +/// @note The returned matrix does not include nonphysical result terms. +virtual Result ComputeStiffness() const = 0; +``` + +Private/internal production function은 declaration 또는 definition에 목적을 기록한다. 수식, +sign, coordinate transform, lifetime, ordered reduction이나 failure preservation이 +비자명하면 그 이유를 설명한다. Header declaration의 사용법을 `.cpp` definition에서 그대로 +반복하지 않는다. + +Comment는 코드 한 줄을 한국어 또는 영어로 번역하는 방식으로 작성하지 않는다. Public API +Doxygen는 일관된 tool output을 위해 영어를 기본으로 한다. Diagnostic message와 existing +contract language는 현재 외부 계약을 유지한다. + +## Determinism과 수치 코드 + +- Element contribution은 stable source/internal index 순서로 생성한다. +- Parallel worker는 index-owned output만 수정한다. +- Floating-point reduction 순서는 명시적으로 고정한다. +- Refactoring 중 expression/reduction 순서를 편의상 바꾸지 않는다. +- Arbitrary `max(1, ...)`, zero clamp 또는 missing-row ignore를 추가하지 않는다. +- End action, section resultant, generalized result와 stress의 identity/sign을 구분한다. +- Reference mapping은 row order가 아니라 승인된 source identity와 component를 사용한다. + +수치식을 공통화할 때는 현재 formulation과 test가 정의한 operation order 및 tolerance를 +먼저 확인한다. + +## Test와 변경 관리 + +- Production C++ 변경은 관련 C++ test와 같은 patch에 있어야 한다. +- Behavior 또는 interface 변경은 `RED -> observed failure -> minimal GREEN -> VERIFY`를 +따른다. +- Refactoring test는 base interface 사용, ownership/lifetime, invalid combination, + deterministic order와 current numerical result preservation을 검증한다. +- Focused test 뒤에 full MSVC x64 Debug build와 CTest를 실행한다. +- B33/MITC4 output 경계를 건드린 변경은 승인된 reference comparison을 다시 실행한다. +- Reference artifact, input path와 tolerance를 리팩터링에 맞춰 수정하지 않는다. +- Commit은 review 가능한 module slice로 제한하고 Conventional Commits를 사용한다. + +## Tooling + +Repository가 제공하는 설정을 우선한다. + +```powershell +clang-format --dry-run --Werror +clang-tidy -- -std=c++17 +doxygen Doxyfile +``` + +실제 build/test command는 `.harness/config.json`이 있으면 그 설정을 우선하고, 없으면 +`AGENTS.md`와 Harness의 MSVC/CMake/CTest entry point를 따른다. 필요한 tool이 설치되지 않아 +검증을 실행할 수 없으면 성공으로 간주하지 않고 environment limitation을 보고한다. + +Generated Doxygen HTML과 tool cache/build output은 source control에 넣지 않는다. + +## Implementation Agent Checklist + +Implementation Agent는 C++ Step을 시작하기 전에 다음을 확인한다. + +- 이 문서와 feature implementation plan을 읽었다. +- 변경할 base/concrete/module owner가 승인 설계와 일치한다. +- 관련 test file과 RED condition이 Step에 명시되어 있다. +- Public API naming과 production Doxygen가 이 문서에 맞는다. +- Vendor dependency와 ownership direction이 역전되지 않는다. +- Stable identity, numerical order, HDF5와 reference contract가 보존된다. +- Formatting, Doxygen, focused/full MSVC/CTest acceptance command가 계획되어 있다. diff --git a/docs/superpowers/specs/2026-08-16-cpp-object-oriented-modular-refactoring-design.md b/docs/superpowers/specs/2026-08-16-cpp-object-oriented-modular-refactoring-design.md new file mode 100644 index 0000000..272c3b5 --- /dev/null +++ b/docs/superpowers/specs/2026-08-16-cpp-object-oriented-modular-refactoring-design.md @@ -0,0 +1,355 @@ +# FESA C++ Object-Oriented Modular Refactoring Design + +## 상태 + +- 설계 대화 승인: 2026-08-16 +- 서면 spec 리뷰: 이 문서에 대한 사용자 검토 필요 +- 구현 상태: not-started + +## 목적 + +현재 B33 Euler beam, MITC4 shell과 linear static solver의 수치 및 외부 동작을 +유지하면서 C++ production code를 객체 책임 중심으로 재구성한다. 이번 리팩터링은 +Google C++ Style Guide 기반의 일관된 코드 스타일, 중복 제거, production Doxygen 문서화, +명시적인 추상 경계와 응집된 모듈을 제공해야 한다. + +효율성은 runtime 성능 향상이 아니라 다음 유지보수 특성을 의미한다. + +- 새 element, element property, material, analysis, load 또는 boundary condition을 추가할 + 때 기존 concrete 구현을 수정하는 범위를 줄인다. +- 하나의 의미를 여러 translation unit에서 다시 구현하지 않는다. +- parser semantic data, numerical kernel, assembly, recovery와 output 책임을 구분한다. +- 수치식과 I/O 계약을 사람이 직접 대조할 수 있는 단순한 dependency direction을 유지한다. + +## 범위 + +### 포함 + +- production 및 test C++ 전체의 Google-style naming과 formatting 전환 +- production header의 `.hpp`에서 `.h`로 전환과 header guard 적용 +- production 함수와 class의 Doxygen 문서화 +- `ElementDefinition`, `Element`, `ElementProperty`, `Material`, `Analysis`, `Load`, + `BoundaryCondition` 추상 경계 +- B33, MITC4, isotropic linear elasticity, beam/shell property, linear static analysis, + concentrated nodal load와 prescribed displacement의 concrete 구현 연결 +- `Vector3`, source-target resolution, DOF invariant validation과 dense-BLAS adapter의 + 중복 제거 +- `domain_mapper.cpp`, `hdf5_results_writer.cpp`, `result_recovery.cpp`의 책임별 분할 +- style, Doxygen, MSVC/CTest와 reference comparison 검증 +- `docs/CODINGSTYLE.md` 유지관리 문서와 Implementation Agent 필수 참조 연결 + +### 제외 + +- MITC3, solid hexa/tetra 또는 다른 element 구현 +- density, plasticity, anisotropic material 동작 구현 +- dynamic, eigenvalue, response spectrum 또는 random vibration analysis 구현 +- distributed load, body force 또는 MPC 구현 +- 승인된 formulation, sign, units, coordinate, HDF5 schema, reference artifact 또는 + tolerance 변경 +- runtime 성능 최적화 또는 parallel reduction policy 변경 +- general plugin registry, global static registration 또는 shared ownership framework + +## 근거와 제약 + +현재 production code는 semantic record와 numerical kernel을 이미 구분하지만 Domain은 +element, material, property, load와 boundary를 concrete vector로 각각 소유한다. +`SparseAssembler`, `DofManager`와 `ResultRecovery`는 B33/MITC4 concrete storage를 직접 +알아야 한다. B33과 MITC4라는 두 실제 element가 있으므로 element abstraction은 현재 +구현으로 검증할 수 있다. + +반면 아직 구현되지 않은 plastic integration, dynamic state, MPC enforcement의 메서드를 +base class에 미리 추가할 근거는 없다. 추상 class는 현재 concrete 구현이 실제로 공유하는 +계약만 제공하고 future capability는 해당 기능의 requirements/formulation/ADR이 승인될 때 +추가한다. + +다음 기존 계약은 리팩터링보다 우선한다. + +- Domain은 semantic definition을 단독 소유하고 parsing 이후 불변으로 취급한다. +- AnalysisModel은 Domain을 복사하지 않는 non-owning stable-index view다. +- DofManager는 DOF와 equation numbering 및 sparse pattern을 단독 소유한다. +- assembly worker는 global CSR storage를 직접 수정하지 않는다. +- stiffness partition과 factorization은 load assembly보다 먼저 수행한다. +- reaction과 free-equilibrium evidence는 full residual `K*d-F`에서 구한다. +- result recovery와 final HDF5는 candidate validation 후 commit한다. +- B33 및 MITC4 reference identity와 tolerance는 변경하지 않는다. + +## 추상 계층과 소유권 + +```text +Domain +├─ ElementDefinition* +│ ├─ EulerBeam3DDefinition +│ └─ Mitc4ShellDefinition +├─ ElementProperty* +│ ├─ GeneralBeamSection +│ └─ ShellSection +├─ Material* +│ └─ IsotropicLinearElasticMaterial +└─ StepDefinition + ├─ Load* + │ └─ ConcentratedNodalLoad + └─ BoundaryCondition* + └─ PrescribedDisplacementBoundaryCondition + +Analysis +└─ LinearStaticAnalysis + +Element +├─ EulerBeam3D +└─ Mitc4Shell +``` + +Domain은 각 base type을 `std::unique_ptr`로 단독 소유한다. Public access는 const이며 +collection의 vector position은 기존 stable `EntityIndex` 의미를 유지한다. AnalysisModel과 +후속 solver object는 raw ownership을 획득하지 않고 Domain 수명 안에서 index 또는 const +reference만 사용한다. Copy를 지원하기 위한 speculative `Clone()`과 `std::shared_ptr`는 +추가하지 않는다. + +`ElementDefinition`과 `Element`는 서로 다른 책임이다. + +- `ElementDefinition`은 source identity, source element type, node connectivity와 + property/material identity를 제공하는 semantic model이다. +- `Element`는 active DOF layout, stiffness contribution, transformation과 result recovery를 + 제공하는 numerical kernel이다. +- `ElementFactory`는 definition, property와 material compatibility를 검증한 뒤 concrete + kernel을 만든다. +- 잘못된 조합은 `dynamic_cast` 실패나 undefined behavior로 넘기지 않고 기존 + `Status`/`Result` diagnostic으로 fail-closed 처리한다. + +Element result는 모든 element에 의미 없는 field를 추가한 비대한 base record가 아니다. +공통 step/frame/source identity를 가진 backend-neutral result bundle이 beam 및 shell row를 +각자의 명확한 record로 보관한다. ResultRecovery와 ResultsWriter는 stable row identity를 +보존하며 서로 다른 result location을 평균하거나 합치지 않는다. + +## Material과 Element Property + +`Material` base는 identity, source location과 수명 계약만 제공한다. 현재 concrete type은 +물리 의미를 드러내도록 `IsotropicLinearElasticMaterial`로 명명한다. 현재 element factory가 +필요로 하는 isotropic elastic capability만 노출한다. + +다음 future concern은 이번 interface에 빈 메서드나 optional field로 미리 넣지 않는다. + +- density와 inertia contribution +- anisotropic elastic constitutive data +- plastic history state와 return mapping +- temperature 또는 rate dependency + +이 concern은 각 기능이 승인될 때 별도의 capability 또는 구성 객체로 추가한다. 같은 +원칙으로 `ElementProperty`는 identity를 제공하고 `GeneralBeamSection`과 `ShellSection`은 +각자 필요한 기하 property를 소유한다. Solid property를 예상해 비어 있는 thickness/area +accessor를 base에 추가하지 않는다. + +## Analysis 계층 + +현재 `Analysis` base의 8개 protected hook은 linear-static lifecycle에 특화되어 있다. +이를 모든 future procedure에 강제하지 않는다. + +```cpp +class Analysis { + public: + virtual ~Analysis() = default; + virtual Status Run(const AnalysisRequest& request) = 0; +}; +``` + +현재 승인 순서는 `LinearStaticAnalysis::Run()`의 private 단계로 유지한다. + +```text +initialize +-> build analysis model +-> build DOF map and sparse pattern +-> assemble and partition stiffness +-> factorize Kff +-> assemble loads and effective RHS +-> substitute and reconstruct +-> recover and write results +``` + +Dynamic, eigenvalue와 stochastic procedure는 추가될 때 별도 state, equation, solver와 output +lifecycle을 정의한다. 기존 linear-static hook 사이에 condition이나 unused future state를 +추가하지 않는다. 이 책임 변경은 구현 전에 ADR-007을 대체하거나 개정하는 ADR로 기록한다. + +## Load와 Boundary Condition + +`Load` concrete object는 자신의 semantic target과 magnitude를 소유하고 ordered full-DOF +contribution을 생성한다. `LoadAssembler`는 active source order로 contribution을 모아 기존 +fixed accumulation order로 global vector에 반영한다. Polymorphic load가 global vector를 +직접 병렬 갱신하지 않는다. + +현재 concrete load는 `ConcentratedNodalLoad`다. Future distributed load와 body force는 +element-local contribution을 생성할 수 있지만 stable global reduction은 계속 assembler가 +소유한다. + +`BoundaryCondition`은 enforcement algorithm을 직접 수행하지 않고 constraint definition을 +생성한다. 현재 concrete type은 nonzero 값을 포함하는 +`PrescribedDisplacementBoundaryCondition`이다. `EssentialConstraintPolicy`가 기존 stable +elimination과 full/reduced reconstruction을 수행한다. + +Future MPC는 별도 constraint equation과 enforcement policy를 요구한다. Prescribed +displacement, MPC, penalty와 Lagrange multiplier를 하나의 bool/enum branch가 누적된 class로 +합치지 않는다. + +## 공통 수학과 중복 제거 + +### Vector3 + +좌표, local axis, shell director와 cross-product는 고정 크기 `Vector3` 값 class를 사용한다. +동적 크기와 MKL-backed storage를 소유하는 기존 `Vector`와 역할을 섞지 않는다. + +`Vector3`는 현재 반복되는 다음 연산을 한 번만 정의한다. + +- component access +- addition, subtraction과 scalar multiplication +- `Dot()` +- `Cross()` +- `Norm()` +- `Normalized()` +- `IsFinite()` + +Normalization failure policy는 호출 위치에서 기존 scale-aware diagnostic을 유지한다. +`Vector3`가 임의 tolerance, zero clamp 또는 solver diagnostic을 소유하지 않는다. + +### 다른 공통 책임 + +- `SourceTargetResolver`: source label, instance와 set target을 stable identity로 해석한다. +- `DofManager::ValidateInvariants()`: full/free/constrained ordering과 equation mapping을 owner가 + 한 번 검증한다. +- private dense-BLAS adapter: Matrix와 Vector의 MKL integer conversion 및 copy operation을 + 공유한다. Vendor type은 public header에 노출하지 않는다. +- ASCII utility: case-insensitive name comparison과 positive source-label parsing을 공유한다. + +중복 제거는 같은 의미와 failure policy가 반복될 때만 적용한다. 이름만 비슷하지만 units, +identity 또는 diagnostic owner가 다른 계산을 하나로 합치지 않는다. State가 없는 helper를 +static-only class로 포장하지 않고 internal namespace/module을 사용한다. + +## 모듈 구조 + +```text +include/fesa/ +├─ analysis/ +│ ├─ analysis.h +│ └─ linear_static_analysis.h +├─ elements/ +│ ├─ element.h +│ ├─ element_definition.h +│ ├─ element_factory.h +│ ├─ euler_beam_3d.h +│ └─ mitc4_shell.h +├─ properties/ +│ ├─ element_property.h +│ ├─ general_beam_section.h +│ └─ shell_section.h +├─ materials/ +│ ├─ material.h +│ └─ isotropic_linear_elastic_material.h +├─ loads/ +│ ├─ load.h +│ └─ concentrated_nodal_load.h +├─ constraints/ +│ ├─ boundary_condition.h +│ ├─ prescribed_displacement.h +│ └─ essential_constraint_policy.h +├─ math/ +│ ├─ vector.h +│ ├─ vector3.h +│ ├─ matrix.h +│ └─ sparse_matrix.h +└─ model/ + ├─ domain.h + ├─ analysis_model.h + └─ source_target_resolver.h +``` + +`model_types.hpp`의 unrelated record는 각 owner module로 이동한다. Top-level orchestration +file은 다음과 같이 분리한다. + +- Abaqus mapping: topology, material/property, step/load/BC와 final Domain assembly +- HDF5 output: RAII/primitives, model dataset, result dataset, self-check와 atomic finalization +- Result recovery: global equilibrium, beam recovery, shell recovery와 atomic state commit + +Public header와 implementation dependency direction을 역전하지 않는다. MKL, TBB, HDF5와 +Win32 type은 기존 adapter/private implementation 경계 안에 남는다. + +## 코드 스타일과 문서화 + +`docs/CODINGSTYLE.md`를 FESA C++ style의 project-local source of truth로 사용한다. Google +C++ Style Guide가 baseline이고 FESA 계약이 우선한다. + +주요 결정은 다음과 같다. + +- C++17/MSVC 호환을 유지한다. Google guide의 현재 C++20 language target은 적용하지 않는다. +- 함수와 accessor를 포함한 production API는 PascalCase로 전면 전환한다. +- type은 PascalCase, 변수는 snake_case, constant/enumerator는 `kPascalCase`, class member는 + trailing underscore를 사용한다. +- Header는 `.h`와 full-path Google header guard를 사용한다. +- Source는 기존 FESA/CMake 관례인 `.cpp`를 유지하는 project exception으로 둔다. +- Formatting은 `BasedOnStyle: Google`, 2-space indentation과 80-column limit를 사용한다. +- Production public/protected declaration에는 Doxygen contract를 기록한다. +- Production internal function은 definition에 목적과 비자명한 수치/순서 의미를 기록한다. +- Test code에는 Doxygen coverage를 요구하지 않는다. + +Repository는 `.clang-format`, selected C++17-compatible `.clang-tidy`, `Doxyfile`과 optional +CMake docs target을 제공한다. Generated HTML은 source control에 넣지 않는다. + +Implementation Agent의 profile은 구현 전에 `docs/CODINGSTYLE.md`를 mandatory global input으로 +읽도록 변경한다. Agent workflow contract test는 해당 profile이 문서를 직접 참조하는지 +검증한다. + +## 오류 처리 + +- 모든 polymorphic base는 public virtual destructor를 갖는다. +- Factory는 null object를 성공 결과로 반환하지 않는다. +- Element/property/material incompatibility는 structured model diagnostic으로 거부한다. +- Public solver 경계는 기존 `Status`/`Result`를 사용한다. +- Backend exception은 현재 failure category와 atomicity contract를 유지해 번역한다. +- Unknown future kind를 silent fallback이나 default concrete type으로 바꾸지 않는다. +- Failed candidate는 Domain, AnalysisState 또는 final HDF5를 부분 변경하지 않는다. + +## 단계적 마이그레이션 + +1. 기존 unit/integration/reference 및 HDF5 contract baseline을 기록하고 architecture ADR을 + 갱신한다. +2. `.clang-format`, header rename/guard와 PascalCase를 module slice별 mechanical change로 + 적용한다. +3. `Vector3`, ASCII utility, SourceTargetResolver, DOF invariant validation과 private BLAS + adapter를 도입한다. +4. Domain semantic hierarchy와 current concrete material/property/load/boundary type을 + 연결한다. +5. Element runtime hierarchy와 factory를 DofManager, SparseAssembler와 ResultRecovery에 + 연결한다. +6. Ordered load contribution과 essential constraint policy를 연결한다. +7. Minimal Analysis base와 LinearStaticAnalysis-owned lifecycle로 전환한다. +8. Mapper, HDF5 writer와 recovery를 책임별로 분할하고 Doxygen/style coverage를 완료한다. + +Mechanical formatting, API rename와 semantic restructuring을 같은 review unit에 섞지 않는다. +각 slice는 buildable하고 독립 검증 가능해야 한다. + +## TDD와 검증 + +각 production change는 관련 C++ test와 같은 Step에서 `RED -> GREEN -> VERIFY`를 수행한다. + +- abstract base와 concrete polymorphic use를 검증하는 compile-time/unit test +- factory success와 incompatible property/material rejection test +- base interface를 통한 B33/MITC4 stiffness 및 recovery test +- stable element, load와 boundary source-order test +- Domain ownership, AnalysisModel lifetime와 stable identity test +- Vector3 arithmetic, finite and normalization-boundary test +- 기존 parser/I/O, HDF5 schema와 atomicity test +- B33 및 MITC4 integration/reference comparison +- repeated execution의 sparse structure, result row와 diagnostic order test +- Doxygen warning, formatting과 selected lint check +- full MSVC x64 Debug `/W4 /WX` build와 CTest + +수치 산술 순서를 의도적으로 변경하지 않은 slice는 가능한 한 exact equality를 요구한다. +Feature-approved reference tolerance는 최종 external comparison에만 그대로 적용한다. + +## 완료 기준 + +- 승인된 abstraction과 current concrete implementation이 base interface를 통해 연결된다. +- DofManager, assembler와 recovery에 B33/MITC4 type branch 또는 duplicate geometry helper가 + 남지 않는다. +- Production 및 test C++가 `docs/CODINGSTYLE.md`의 naming/formatting 규칙을 만족한다. +- Production API와 non-obvious internal function에 요구된 Doxygen가 존재한다. +- Implementation Agent profile이 `docs/CODINGSTYLE.md`를 mandatory input으로 참조한다. +- 전체 MSVC x64 Debug build/CTest와 B33/MITC4 reference comparison이 통과한다. +- HDF5 schema, stable identity, diagnostic, tolerance와 reference artifact에 변경이 없다.