modify documents

This commit is contained in:
NINI
2026-04-21 01:12:24 +09:00
parent 2d9d6a70ae
commit 74ba552672
4 changed files with 306 additions and 77 deletions

View File

@@ -8,12 +8,21 @@
- git 주소 : https://teagit.mimi1011.synology.me/baram2584/FESADev.git
## 아키텍처 규칙
- CRITICAL: {절대 지켜야 할 규칙 1 (예: 모든 API 로직은 app/api/ 라우트 핸들러에서만 처리)}
- CRITICAL: {절대 지켜야 할 규칙 2 (예: 클라이언트 컴포넌트에서 직접 외부 API를 호출하지 말 것)}
- {일반 규칙 (예: 컴포넌트는 components/ 폴더에, 타입은 types/ 폴더에 분리)}
- CRITICAL: 레퍼런스가 되는 예제들과 결과 비교를 통해 솔버의 품질을 항상 유지
- CRITICAL: `docs/ARCHITECTURE.md``docs/ADR.md`의 결정 사항을 우선 준수할 것. 구조 변경이 필요하면 먼저 ADR을 추가/수정할 것
- 요소, 재료, 하중, 경계조건, 해석 알고리즘은 런타임 다형성 기반으로 확장할 것
- `Domain`은 입력 모델 정의를 보존하고 가능한 한 불변으로 취급할 것
- 현재 step에서 활성화되는 객체는 `AnalysisModel`로 분리하고, 해석 중 변하는 물리량과 반복 상태는 `AnalysisState`에 저장할 것
- 자유도 정의, constrained/free dof mapping, equation numbering, sparse pattern 생성은 `DofManager`가 전담할 것. Node/Element 내부에 equation id를 분산 저장하지 말 것
- 해석 알고리즘은 Strategy + Template Method 구조를 따를 것. 선형 정적, 비선형 정적, 동적, 열전달 해석은 공통 실행 흐름을 공유하되 세부 반복/적분 알고리즘은 분리할 것
- Abaqus input keyword와 내부 객체 생성은 Factory + Registry 구조로 분리할 것. Phase 1 입력 범위는 `*Node`, `*Element`, `*Nset`, `*Elset`, `*Material`, `*Elastic`, `*Shell Section`, `*Boundary`, `*Cload`, `*Step`
- MKL, TBB, HDF5 API는 solver core에 직접 노출하지 말고 adapter/wrapper 계층 뒤에서 사용할 것
- 결과는 step/frame/field/history 모델로 관리할 것
- 대규모 모델을 목표로 sparse matrix, assembly, solver 계층은 성능 확장이 가능하게 설계할 것
- MITC4 요소 구현은 Phase 1에서 정확도와 테스트 가능성을 우선하며, reference 검증 전 과도한 최적화를 하지 말 것
## Harness Workflow
- 먼저 `docs/PRD.md`, `docs/ARCHITECTURE.md`, `docs/ADR.md`, `docs/UI_GUIDE.md`를 읽고 기획/설계 의도를 파악할 것
- 먼저 `docs/PRD.md`, `docs/ARCHITECTURE.md`, `docs/ADR.md`를 읽고 기획/설계 의도를 파악할 것
- 단계별 실행 계획이 필요하면 repo skill `harness-workflow`를 사용해 `phases/` 아래 파일을 설계할 것
- 변경사항 리뷰가 필요하면 repo skill `harness-review` 또는 Codex의 `/review`를 사용할 것
- `phases/{phase}/index.json`은 phase 진행 상태의 단일 진실 공급원으로 취급할 것

View File

@@ -5,17 +5,63 @@
---
### ADR-001: {결정 사항 (예: Next.js App Router 선택)}
**결정**: {뭘 선택했는지}
**이유**: {왜 선택했는지}
**트레이드오프**: {뭘 포기했는지}
### ADR-001: Runtime Polymorphism 기반 Solver Core
**결정**: 요소, 재료, 하중, 경계조건, 해석 알고리즘은 base interface와 runtime polymorphism 기반으로 확장한다.
### ADR-002: {결정 사항}
**결정**: {뭘 선택했는지}
**이유**: {왜 선택했는지}
**트레이드오프**: {뭘 포기했는지}
**이유**: FESA는 MITC4 Shell 요소에서 시작하지만 RBE2/RBE3, 압력하중, 비선형 정적해석, 동적해석, 열전달, 1D/3D 요소로 확장될 예정이다. 초기에는 정확도와 테스트 가능성이 가장 중요하므로, 각 물리 객체를 독립적으로 테스트하고 교체할 수 있는 구조가 필요하다.
### ADR-003: {결정 사항}
**결정**: {뭘 선택했는지}
**이유**: {왜 선택했는지}
**트레이드오프**: {뭘 포기했는지}
**트레이드오프**: virtual dispatch 비용과 객체 분산에 따른 캐시 효율 저하가 발생할 수 있다. 대규모 모델 성능이 필요한 영역은 `Assembler`, element kernel, sparse solver 계층에서 batch 처리 또는 타입별 최적화를 추가한다.
---
### ADR-002: Immutable Domain + Mutable AnalysisState
**결정**: 입력 모델 정의는 `Domain`에 보존하고 가능한 한 불변으로 취급한다. 해석 중 변하는 displacement, velocity, acceleration, temperature, force, residual, iteration 정보는 `AnalysisState`에 분리한다.
**이유**: 선형 정적해석, 기하비선형 정적해석, 동적해석, 열전달 및 thermal-stress coupling은 서로 다른 상태 변수를 필요로 한다. 모델 정의와 해석 상태를 분리하면 restart, 결과 저장, reference 비교, 테스트가 쉬워진다.
**트레이드오프**: `Domain`, `AnalysisModel`, `AnalysisState` 사이의 참조/id 관리가 필요하다. 단순한 단일 해석 코드보다 초기 구조가 복잡하지만, 다중 step 및 비선형/동적 확장성을 얻는다.
---
### ADR-003: Step/Frame/Field/History 결과 모델
**결정**: 해석 결과는 `ResultStep`, `ResultFrame`, `FieldOutput`, `HistoryOutput` 구조로 저장한다.
**이유**: 정적해석, 비선형 increment, 동적 time frame, history output을 같은 결과 모델로 다루기 위해 Abaqus와 유사한 step/frame/history 개념이 필요하다. HDF5 저장 구조와 reference 결과 비교도 이 구조를 기준으로 설계한다.
**트레이드오프**: Phase 1 선형 정적해석만 놓고 보면 결과 구조가 다소 무겁다. 그러나 Phase 2 이후의 비선형 반복, Phase 3 동해석, reaction/history 검증을 위해 초기에 최소 구조를 잡는 편이 낫다.
---
### ADR-004: Strategy + Template Method 기반 Analysis 실행
**결정**: 해석 알고리즘은 `Analysis` strategy로 분리하고, 공통 실행 흐름은 template method로 관리한다.
**이유**: 선형 정적해석, Newton-Raphson 비선형 정적해석, HHT 동적해석, 열전달 해석은 조립, 경계조건 적용, solver 호출, 상태 갱신, 결과 저장이라는 공통 흐름을 공유한다. 공통 흐름을 유지하면서 해석별 반복 구조만 바꾸는 방식이 중복을 줄인다.
**트레이드오프**: 공통 template이 지나치게 커지면 해석별 특수성이 숨겨질 수 있다. 따라서 `Analysis`는 전체 흐름을 조율하고, assembly, solver, convergence, time integration은 별도 strategy로 분리한다.
---
### ADR-005: Factory + Registry 기반 Abaqus Input 객체 생성
**결정**: Abaqus input keyword와 내부 객체 생성을 factory/registry 계층으로 분리한다. Phase 1 입력 범위에는 `*Node`, `*Element`, `*Nset`, `*Elset`, `*Material`, `*Elastic`, `*Shell Section`, `*Boundary`, `*Cload`, `*Step`을 포함한다.
**이유**: Abaqus input format 호환성을 유지하면서 요소/재료/하중/경계조건 타입을 계속 추가해야 한다. parser 본체가 모든 타입을 직접 생성하면 확장할수록 변경 비용과 회귀 위험이 커진다.
**트레이드오프**: registry 초기화와 타입 매핑 코드가 추가된다. 대신 새 keyword나 element type을 추가할 때 parser core의 변경을 최소화할 수 있다.
---
### ADR-006: External Library Adapter Boundary
**결정**: MKL, TBB, HDF5는 solver core에 직접 노출하지 않고 adapter/wrapper 계층 뒤에서 사용한다.
**이유**: FESA의 핵심 도메인 모델과 해석 알고리즘이 특정 외부 라이브러리 API에 강하게 결합되면 테스트와 교체가 어려워진다. `SparseMatrix`, `Vector`, `LinearSolver`, `ParallelFor`, `ResultsWriter` 같은 경계를 통해 외부 의존성을 제한한다.
**트레이드오프**: wrapper 계층 구현 비용이 추가된다. 성능이 민감한 부분에서는 adapter가 불필요한 복사를 만들지 않도록 API를 신중히 설계해야 한다.
---
### ADR-007: DofManager가 자유도와 방정식 번호를 전담
**결정**: node와 element 내부에 equation id를 분산 저장하지 않고, `DofManager`가 자유도 정의, constrained/free dof mapping, equation numbering, sparse pattern 생성을 전담한다.
**이유**: 대규모 모델, 경계조건, RBE2/RBE3, 비선형 재조립, thermal-stress coupling에서는 자유도 관리가 solver 품질과 성능에 직접 영향을 준다. 자유도 관리를 별도 객체로 분리하면 경계조건 적용과 행렬 조립이 명확해진다.
**트레이드오프**: element 계산 시 node id에서 equation id로 변환하는 조회 비용이 생긴다. 이 비용은 assembly precompute 또는 element connectivity cache로 줄인다.

View File

@@ -1,78 +1,246 @@
# 아키텍처
## 목표
FESA는 MITC4 Shell 요소 기반 구조해석에서 시작해 비선형 정적해석, 비선형 동적해석, 열전달 및 thermal-stress coupling, 1D/3D 요소까지 확장하는 유한요소 솔버이다.
초기 구현은 정확도와 테스트 가능성을 우선한다. 단, 대규모 모델을 목표로 하므로 자유도 관리, 희소 행렬 조립, 선형 솔버, 병렬 실행 계층은 초기부터 성능 확장이 가능하도록 분리한다.
## 설계 원칙
- Domain 객체는 입력 모델의 의미를 보존하고 가능한 한 불변에 가깝게 유지한다.
- 해석 중 변하는 물리량과 반복 상태는 AnalysisState에 명시적으로 분리한다.
- 요소, 재료, 하중, 경계조건, 해석 알고리즘은 런타임 다형성 기반으로 확장한다.
- MITC4 구현은 Phase 1에서 정확도와 테스트 가능성을 우선하며, assembly와 solver 계층은 대규모 모델 최적화가 가능하도록 경계를 둔다.
- 결과는 step/frame/field/history 개념으로 저장하여 정적, 비선형, 동적, 열전달 해석을 같은 결과 모델로 다룬다.
- 외부 라이브러리(MKL, TBB, HDF5)는 adapter 계층 뒤에 둔다.
- Abaqus input 호환성은 파서와 factory/registry 계층에서 관리한다. Phase 1의 입력 범위에는 `*Node`, `*Element`, `*Nset`, `*Elset`, `*Material`, `*Elastic`, `*Shell Section`, `*Boundary`, `*Cload`, `*Step`을 포함한다.
## 디렉토리 구조
```
src/
├── Analysis/ # Analysis 관련 class
├── Property/ # 요소 재료 및 속성 관련 class
├── Element/ # 절점, 요소 관련 class
├── Boundary/ # 경계조건 관련 class
├── Load/ # 하중 관련 class
── Util/ # 수학 라이브러리 등 솔버 utility 관련 class
├── Analysis/ # Static, nonlinear static, dynamic, heat transfer analysis
├── Assembly/ # 전역 행렬/벡터 조립, sparse pattern 생성
├── Boundary/ # Fix, RBE2, RBE3 등 경계조건
├── Core/ # Domain, AnalysisModel, AnalysisState, DofManager
├── Element/ # Node, Element, MITC4 등 요소 구현
── IO/ # Abaqus input parser, HDF5 results writer
├── Load/ # NodalLoad, PressureLoad, BodyForce 등 하중
├── Math/ # Vector, Matrix, SparseMatrix, MKL adapter
├── Material/ # LinearElastic 등 재료 모델
├── Property/ # ShellProperty, 1D/2D/3D property
├── Results/ # Step, Frame, FieldOutput, HistoryOutput
└── Util/ # 공통 유틸리티, 로깅, 검증 보조 함수
```
## 클래스 구조
## 핵심 클래스 구조
```
Domain
├── Node
├── Element
├── Material
├── Property
├── NodeSet
├── ElementSet
├── BoundaryCondition
├── Load
└── StepDefinition
AnalysisModel
├── active elements
├── active loads
├── active boundary conditions
├── active properties/materials
└── equation system view
AnalysisState
├── displacement U
├── velocity V
├── acceleration A
├── temperature T
├── external force Fext
├── internal force Fint
├── residual R
├── current time / increment / iteration
└── element state / integration point state
DofManager
├── node dof definitions
├── constrained/free dof mapping
├── equation numbering
└── sparse matrix pattern ownership
Analysis
├── LinearStaticAnalysis
├── NonlinearStaticAnalysis
├── DynamicAnalysis
├── FrequencyAnalysis
└── HeatTransferAnalysis
Element
├── 1DElement
│ ├── Truss
│ └── Beam
├── 2DElement
│ ├── MITC3
│ └── MITC4
└── 3DElement
├── Hexahedral
├── Tetrahedral
├── Wedge
└── Pyramid
BoundaryCondition
├── Fix
├── RBE2
└── RBE3
Load
├── NodalLoad
├── PressureLoad
└── BodyForce
Results
├── ResultStep
├── ResultFrame
├── FieldOutput
└── HistoryOutput
InputParser
ResultsWriter
Assembler
LinearSolver
Vector
Matrix
SparseMatrix
```
Domain # 전체 해석 객체들을 저장하고 관리하는 class
## 디자인 패턴
AnalysisModel # 현재 해석 step에서 active 되는 해석 객체들을 저장하는 class
### Strategy Pattern
해석 알고리즘과 수치 알고리즘을 교체 가능하게 구성한다.
AnalysisObject
├── Analysis # Analysis 관련 class
├── StaticAnalysis
├── DynamicAnalysis
├── FrequencyAnalysis
├── ...
├── Property # 요소 재료 및 속성 관련 class
├── 1DProperty
├── 2DProperty
├── 3DProperty
├── ...
├── Element # 절점, 요소 관련 class
├── 1DElement
├── Truss
├── Beam
├── ...
├── 2DElement
├── MITC3
├── MITC4
├── ...
├── 3DElement
├── Hexahedral
├── Tetrahedral
├── Wedge
├── Pyramid
├── ...
├── ...
├── BoundaryCondition # 경계조건 관련 class
├── Fix
├── RBE2
├── RBE3
├── ...
├── Load # 하중 관련 class
├── NodalLoad
├── PressureLoad
├── BodyFroce
├── ...
InputParser # input 파일 파싱 class
ResultsWriter # 해석 결과 저장 class
MKLWrapper # MKL Wrapper
Vector # Vector
Matrix # Matrix
적용 대상:
- `Analysis`: `LinearStaticAnalysis`, `NonlinearStaticAnalysis`, `DynamicAnalysis`, `HeatTransferAnalysis`
- `LinearSolver`: `MKLPardisoSolver`, 향후 iterative solver
- `TimeIntegrator`: `HHTIntegrator`, 향후 Newmark 등
- `ConvergenceCriteria`: residual norm, displacement norm, energy norm
### Template Method Pattern
해석 실행의 큰 흐름은 `Analysis::run()`에서 고정하고, 세부 단계는 해석 종류별로 재정의한다.
기본 흐름:
```
initialize
buildAnalysisModel
buildDofMap
buildSparsePattern
assemble
applyBoundaryConditions
solve
updateState
writeResults
```
## 패턴
당신과 상의 후 수치해석 솔버에 최적화된 디자인 패턴을 선택하겠습니다.
비선형 정적해석은 위 흐름을 Newton-Raphson 반복 루프 안에서 사용하고, 동적해석은 time step/frame 루프 안에서 사용한다.
### Factory + Registry Pattern
Abaqus input keyword와 내부 객체 생성을 분리한다.
예:
- `*Element, type=S4` -> `MITC4ElementFactory`
- `*Material`, `*Elastic` -> `LinearElasticMaterialFactory`
- `*Boundary` -> `FixBoundaryFactory`
- `*Cload` -> `NodalLoadFactory`
- `*Nset`, `*Elset` -> set registry
요소, 재료, 하중, 경계조건 타입 추가 시 parser 본체의 변경을 최소화한다.
### Adapter Pattern
MKL, TBB, HDF5 API는 solver core에 직접 노출하지 않는다.
적용 대상:
- `SparseMatrix`, `Vector`, `Matrix`
- `LinearSolver`
- `ParallelFor`
- `ResultsWriter`
외부 라이브러리 교체 또는 테스트 double 사용이 가능하도록 adapter 계층에서 의존성을 제한한다.
### Runtime Polymorphism
요소, 재료, 하중, 경계조건은 base interface를 통해 다룬다. Phase 1에서는 명확성과 테스트 가능성을 우선하고, 대규모 모델 성능 최적화가 필요할 경우 assembly 내부에서 타입별 batch 처리 또는 kernel 분리를 추가한다.
## 상태 관리
### Domain
`Domain`은 입력 파일에서 만들어진 전체 모델 정의를 소유한다. 파싱 이후에는 가능한 한 불변으로 취급한다.
포함 대상:
- nodes, elements
- materials, properties
- node sets, element sets
- loads, boundary conditions
- analysis step definitions
### AnalysisModel
`AnalysisModel`은 현재 step에서 활성화되는 해석 객체들의 실행 view이다. `Domain`을 복사하지 않고 참조 또는 id 기반 view로 구성한다.
포함 대상:
- active elements
- active loads
- active boundary conditions
- active property/material references
- current equation system view
### DofManager
`DofManager`는 자유도와 방정식 번호를 전담한다. Node 또는 Element 내부에 equation id를 분산 저장하지 않는다.
책임:
- node별 활성 자유도 정의
- constrained/free dof mapping
- equation numbering
- sparse matrix pattern 생성에 필요한 connectivity 제공
- 경계조건 적용 전후의 dof view 관리
### AnalysisState
`AnalysisState`는 해석 중 변하는 물리량과 반복 상태를 소유한다.
포함 대상:
- displacement, velocity, acceleration
- temperature
- external force, internal force, residual
- current time, increment, Newton iteration
- element state, integration point state
Phase 1에서는 displacement 중심으로 최소 구현하되, 기하비선형과 thermal-stress coupling을 위해 element/internal state 확장 지점을 유지한다.
### Results State
결과는 `ResultStep` -> `ResultFrame` -> `FieldOutput`/`HistoryOutput` 구조로 관리한다.
- `ResultStep`: 해석 step 단위 결과
- `ResultFrame`: 정적해석의 load increment 또는 동적해석의 time frame
- `FieldOutput`: node/element field 결과
- `HistoryOutput`: 특정 node, element, set, reaction, energy 등의 이력 결과
## 데이터 흐름
```
해석 입력 파일 -> 파일 파싱 후 AnalysisModel 생성 -> 해석 step 루프 진입 -> 현재 해석 step 진행 -> 해석 결과 파일에 쓰기 -> 다음 해석 step 진입 -> 반복 -> 해석 종료
Abaqus input file
-> InputParser
-> Domain 생성
-> StepDefinition 루프
-> AnalysisModel 생성
-> DofManager로 자유도/방정식 번호 생성
-> sparse pattern 생성
-> Analysis 실행
-> Assembler로 전역 행렬/벡터 조립
-> BoundaryCondition 적용
-> LinearSolver 또는 nonlinear/time integration loop
-> AnalysisState 갱신
-> ResultsWriter로 step/frame/history 저장
-> 다음 step 진행
```
## 상태 관리
당신과 상의 후 수치해석 솔버에 최적화된 상태 관리 방식을 선택하겠습니다.
## 성능 확장 방향
- 행렬 조립은 element 단위 병렬화를 고려해 설계한다.
- 전역 행렬은 대규모 모델을 위해 sparse matrix를 기본으로 한다.
- MKL 기반 direct solver를 우선 지원하되, solver interface는 iterative solver를 추가할 수 있게 둔다.
- TBB 병렬화는 요소 stiffness 계산, element force 계산, assembly precompute 등 독립 작업부터 적용한다.
- 정확도 검증이 끝나기 전에는 MITC4 element formulation을 과도하게 최적화하지 않는다.

View File

@@ -1,4 +1,4 @@
# PRD: {프로젝트명}
# PRD: FESA
## 목표
MITC4 Shell 요소를 사용해 구조 해석을 하는 유한요소 솔버를 개발
@@ -10,6 +10,8 @@ MITC4 Shell 요소를 사용해 구조 해석을 하는 유한요소 솔버를
1. MITC4 Shell 요소를 사용한 구조해석
2. Parallel 연산을 통한 계산 성능 향상
3. Abaqus Input format 사용을 통해 다른 상용 소프트웨어와 호환성 높음
4. step/frame/history 기반 해석 결과 관리
5. reference 모델 결과 비교를 통한 정확도 검증
## 개발 계획
1. Phase 1
@@ -17,12 +19,15 @@ MITC4 Shell 요소를 사용해 구조 해석을 하는 유한요소 솔버를
- 선형 탄성 재료
- 절점하중
- 고정 경계조건
- Abaqus input subset: *Node, *Element, *Nset, *Elset, *Material, *Elastic, *Shell Section, *Boundary, *Cload, *Step
- 선형 정적 해석
- step/frame 기반 결과 저장의 최소 구조
- reference 모델 결과 비교 테스트
2. Phase 2
- 압력하중
- RBE2, RBE3 경계조건
- Newton-Raphson 비선형 알고리즘
- 비선형 정적해석
- 기하비선형 중심의 비선형 정적해석
3. Phase 3
- HHT 시간 적분 알고리즘
- time dependent 하중
@@ -31,6 +36,7 @@ MITC4 Shell 요소를 사용해 구조 해석을 하는 유한요소 솔버를
- Heat transfer 해석
- 절점 온도에 대한 열전도 요소 행렬 계산
- 온도 하중 계산
- thermal-stress coupling 확장
5. Phase 5
- 1D, 3D 요소 구현
- 기타 하중, 경계조건 구현
- 기타 하중, 경계조건 구현