modify documents

This commit is contained in:
KOKO\Mimi
2026-09-05 15:14:21 +09:00
parent 31dac85192
commit 97e4d7a971
79 changed files with 4570 additions and 2787 deletions
+192
View File
@@ -0,0 +1,192 @@
# Structural FEM Solver C++ Coding Style
## 목적과 우선순위
이 문서는 production 및 test C++의 project-local 규칙이다. [Google C++ Style
Guide](https://google.github.io/styleguide/cppguide.html)를 일반 baseline으로 사용하되 다음
순서가 우선한다.
1. 승인된 feature requirements, formulation, numerical/verification와 I/O contract
2. `AGENTS.md`, `docs/ARCHITECTURE.md`, `docs/ADR.md`
3. 이 문서
4. Google C++ Style Guide
5. 수정 대상 module의 기존 local style
요청 범위 밖 파일을 style-only 이유로 수정하지 않는다. 새 코드는 즉시 준수하고 기존
코드는 승인된 변경 slice 안에서만 점진적으로 정리한다.
## Language와 toolchain
- 최소 language level은 C++17이다.
- Windows validation baseline은 MSVC x64다.
- Compiler extension과 운영체제 전용 type을 public API에 노출하지 않는다.
- Build generator, preset, configuration과 test command는 `.harness/config.json`을 우선한다.
- Standard library, RAII와 value semantics를 manual lifetime management보다 우선한다.
- Vendor linear algebra, sparse, persistence와 OS header는 private adapter 내부에 둔다.
## 파일과 header
- File 이름은 소문자 `snake_case`를 사용한다.
- Source는 `.cpp`, header는 `.h`를 사용한다. 이미 존재하는 다른 extension은 별도 migration
없이 이름만 바꾸지 않는다.
- Header는 self-contained이며 consumer의 transitive include에 의존하지 않는다.
- Full repository path 기반 include guard를 사용한다.
```cpp
#ifndef FEM_CORE_VECTOR3_H_
#define FEM_CORE_VECTOR3_H_
namespace fem {
class Vector3 {};
} // namespace fem
#endif // FEM_CORE_VECTOR3_H_
```
Include group은 대응 header, C system, C++ standard library, third party, project header
순서다. 각 group 사이에 빈 줄을 두고 직접 사용하는 declaration의 header를 include한다.
## 이름 규칙
| 대상 | 규칙 | 예 |
| --- | --- | --- |
| class, struct, enum, alias | `PascalCase` | `ElementProperty` |
| function, method, accessor | `PascalCase` | `ComputeResidual()` |
| local variable, parameter | `snake_case` | `element_id` |
| class data member | `snake_case_` | `youngs_modulus_` |
| struct data member | `snake_case` | `source_label` |
| constant | `kPascalCase` | `kNodeCount` |
| enumerator | `kPascalCase` | `FailureKind::kModel` |
| namespace | `snake_case` | `fem::numerics_internal` |
| macro | `UPPER_SNAKE_CASE` | `FEM_CORE_VECTOR3_H_` |
Root namespace는 실제 project bootstrap에서 한 번 선택한다. 위 `fem`은 예시이며 여러
feature가 서로 다른 root namespace를 만들지 않는다.
이름은 physical/numerical 의미를 드러내야 한다. 넓은 scope의 `data`, `value`, `manager`,
`handler`를 피하고 source label, entity ID, DOF ID와 equation ID를 이름에서 구분한다.
## Formatting
- `.clang-format`은 Google 기반, space 2개와 최대 100 columns를 기본으로 한다.
- Tab을 사용하지 않는다.
- Declaration/control statement와 같은 줄에 opening brace를 둔다.
- Namespace body는 들여쓰지 않고 closing namespace comment를 작성한다.
- 한 statement에 한 declaration만 둔다.
- Variable은 가능한 가장 좁은 scope에서 선언과 동시에 초기화한다.
- 의미가 허용하면 `const`, `constexpr`, `explicit`, `override`, `noexcept`와 `[[nodiscard]]`를
사용한다. 장식 목적으로 contract를 과장하지 않는다.
- Formatting-only 변경과 behavior 변경을 불필요하게 섞지 않는다.
## API와 ownership
- Public interface는 현재 필요한 최소 capability만 제공한다.
- Class는 하나의 명확한 responsibility와 invariant를 가진다.
- Invariant, encapsulation, lifetime 또는 behavior가 없으면 data-only `struct`를 사용할 수 있다.
- 단독 ownership은 `std::unique_ptr` 또는 value로 표현한다. 실제 shared lifetime이 없으면
`std::shared_ptr`를 사용하지 않는다.
- Non-owning pointer/reference/span의 lifetime과 nullability를 API contract에 기록한다.
- Polymorphic base에는 public virtual destructor가 있어야 한다.
- Downcast와 type switch를 주요 확장 mechanism으로 사용하지 않는다.
- 단일 사용을 위해 abstract factory, registry 또는 future option을 만들지 않는다.
- Public header는 implementation/vendor dependency 방향을 역전하지 않는다.
## FEM module 규칙
- `model`은 validated immutable semantic definition을 소유한다.
- `element`는 local residual/tangent와 recovery를 소유하며 global matrix를 직접 수정하지 않는다.
- `material`은 constitutive trial/commit/revert contract를 소유한다.
- `dof`는 active DOF와 equation numbering을 소유한다. Node가 equation ID를 영구 저장하지
않는다.
- `assembly`는 sparsity, scatter와 deterministic reduction을 소유한다.
- `constraints`는 equation policy를 소유한다.
- `analysis`는 procedure lifecycle, convergence와 state commit을 소유한다.
- `results`는 physical result identity를 소유하고 persistence layout을 알지 않는다.
- `io`와 `storage`는 external representation을 core contract에 mapping한다.
- `numerics`는 physical entity를 알지 않는 backend-neutral operation을 제공한다.
비슷해 보이는 수식을 공통화하기 전에 units, sign, coordinates, result location, state lifetime와
tolerance가 같은지 확인한다. 한 번만 사용하는 logic을 future flexibility를 위해 framework로
만들지 않는다.
## 수치 코드
- DOF/component/local-node ordering은 type, constant 또는 contract로 명시한다.
- Shape derivative, Jacobian, quadrature weight와 coordinate transform의 convention을 수식과
test에서 동일하게 유지한다.
- Residual과 tangent의 부호 및 linearization point를 주석/contract에 기록한다.
- Parallel worker는 owner가 정해진 output만 수정하고 floating-point reduction 순서를
의도적으로 결정한다.
- 임의 clamp, `max(1, ...)`, missing-row ignore와 silent fallback을 추가하지 않는다.
- `double` 값의 equality를 일반적인 engineering quantity에 직접 사용하지 않고
`docs/TOLERANCE.md`의 목적별 metric을 사용한다.
- 성능 변경 전 benchmark와 correctness baseline을 기록한다. Expression order를 바꾸는
optimization은 numerical regression을 다시 검증한다.
## Error와 failure atomicity
- 예상 가능한 실패는 project의 `Status`/`Result<T>` 계약으로 반환한다.
- Backend exception과 raw error code가 public solver boundary를 통과하지 않게 한다.
- Unsupported type/property/material/procedure 조합은 structured diagnostic으로 fail closed한다.
- Candidate model/state/result를 완성해 검증한 뒤 authoritative owner에 commit한다.
- Partial failure가 기존 committed state 또는 정상 result artifact를 덮어쓰지 않게 한다.
- Assertion은 사용자 입력 오류가 아니라 내부 invariant 위반에 사용한다.
## Documentation
Public/protected production declaration은 필요한 경우 다음을 영어 Doxygen로 기록한다.
- purpose와 physical/numerical meaning
- units, coordinates, ordering과 valid range
- ownership, lifetime, precondition과 failure
- deterministic behavior 또는 backend limitation
- sign, trial/committed state와 destructive side effect 주의
```cpp
/// @brief Computes an element contribution in the declared local DOF order.
/// @return A finite residual and consistent tangent, or a structured failure.
/// @note This function does not modify the global system or committed state.
virtual Result<ElementContribution> Evaluate(
const ElementContext& context) const = 0;
```
코드가 말하는 내용을 번역하는 comment는 쓰지 않는다. 비자명한 formulation, operation order,
ownership 또는 선택 이유를 설명한다. Test helper에는 형식적인 Doxygen를 요구하지 않는다.
## Test와 변경 관리
- Production C++ 변경은 관련 test 변경과 같은 patch에 포함한다.
- `RED -> observed failure -> minimal GREEN -> focused VERIFY -> full VERIFY`를 따른다.
- Test는 정상값뿐 아니라 invalid combination, identity/order, state rollback, determinism과
error category를 검증한다.
- Numerical feature는 직접 kernel test와 독립 system/benchmark evidence를 모두 가진다.
- Reference artifact나 tolerance를 implementation 결과에 맞춰 수정하지 않는다.
- 새 warning, flaky test 또는 검증되지 않은 platform 성공 주장을 추가하지 않는다.
- Commit을 요청받으면 review 가능한 module slice와 Conventional Commits 형식을 사용한다.
## Tooling
Repository 설정과 존재하는 target에만 적용한다.
```powershell
clang-format --dry-run --Werror <changed-cpp-and-header-files>
clang-tidy <changed-cpp-files> -- -std=c++17
cmake --build .harness/build --config Debug
ctest --test-dir .harness/build -C Debug --output-on-failure
```
Tool, build metadata 또는 target이 없으면 검사를 성공으로 표시하지 말고 `미실행`과 이유를
보고한다. Generated documentation, build directory, cache와 runtime output은 source control에
넣지 않는다.
## Implementation checklist
- 승인된 feature contract와 직접 관련된 파일만 변경한다.
- Public dependency 방향과 owner가 architecture와 일치한다.
- 실패 test를 구현 전에 관찰했다.
- Units, coordinates, identity와 local/global ordering이 드러난다.
- Trial/committed state와 failure atomicity가 보존된다.
- Focused test와 가능한 full build/test를 실제로 실행했다.
- 미실행 검사, warning과 residual risk를 evidence에 기록했다.