Files
FESADev/docs/ARCHITECTURE.md
T
2026-08-18 02:29:26 +09:00

31 KiB
Raw Blame History

아키텍처

목표

FESA의 아키텍처 목표는 Abaqus .inp subset을 내부 semantic model로 변환하고, 유한요소 equation system을 구성해 구조해석 결과를 HDF5로 저장하며, reference comparison과 physics sanity가 가능한 C++17/MSVC 솔버 구조를 제공하는 것이다.

FESA의 element formulation과 numerical path는 Abaqus와 독립적이다. Abaqus .inp는 승인된 입력 형식이고 Abaqus CSV는 기능별 blocking quantity의 외부 수치 reference다. Abaqus 내부 적분, stabilization, state 또는 recovery 동작은 FESA architecture contract가 아니다.

핵심 품질 속성:

  • FEM formulation traceability
  • explicit I/O contracts
  • sparse linear algebra backend isolation
  • deterministic verification
  • incremental feature addition
  • Harness 기반 TDD

현재 승인된 V0 end-to-end 기능은 linear-static-3d-euler-beam이다. 상세 계약의 source of truth는 docs/superpowers/specs/2026-08-08-linear-static-3d-euler-beam-design.md이며, 이 문서는 그 계약을 전체 solver architecture의 모듈과 데이터 흐름에 배치한다. 아래에 나타난 비선형, 동적, thermal 및 다른 element 계층은 장기 확장 경계이며 V0 지원 범위가 아니다.

현재 구현된 디렉토리 구조

include/fesa/               # backend-neutral public C++ API
src/
  fesa/
    analysis/             # Analysis lifecycle, V0 LinearStaticAnalysis
    app/                  # CLI application and main
    assembly/             # deterministic stiffness/load assembly, ParallelFor adapter
    constraints/          # essential-constraint elimination and reconstruction
    core/                 # source identity, status, diagnostics
    elements/             # current B33/MITC4 kernels and recovery
    fem/                  # DOF/equation numbering and sparse pattern
    io/
      abaqus/             # .inp syntax reader and semantic Domain mapper
      hdf5/               # private HDF5 writer and atomic finalization
    math/                 # owning Vector, row-major Matrix, 0-based CSR SparseMatrix
    model/                # concrete V0 semantic records and immutable Domain
    results/              # recovery records, full residual, ResultsWriter boundary
    solvers/
      linear/             # LinearSolver interface and MKL PARDISO adapter
tests/
  unit/                    # local contracts and failure paths
  integration/             # analysis orchestration and CLI contracts
  reference/               # HDF5-to-Abaqus projection and comparison
reference/
  <case-dir>/              # declared read-only Abaqus input/required CSV pair
.agents/
  skills/                 # Harness and review skills
.codex/
  hooks.json              # PreToolUse/Stop hook registration
  agents/                 # FESA workflow custom agents
  skills/                 # FESA solver workflow skills
docs/                     # Product, architecture, ADR, workflow artifacts
scripts/
  execute.py              # Phase step executor
  hooks/                   # PreToolUse/Stop hook implementations
  msvc_harness/            # MSVC project discovery and validation adapters
phases/                   # Optional generated phase plans

materials/, properties/, loads/와 checked ElementFactory는 승인된 C++ modular refactoring의 target boundary이며 후속 implementation Step에서 추가한다. 이 documentation-only Step 시점에는 현재 구현 디렉토리로 표시하지 않는다. Density, plasticity, anisotropy, nonlinear/dynamic analysis, MPC/penalty, history output과 production validation module은 계속 장기 확장 경계이며 별도 승인 기능이 필요하다.

Harness Execution Layer

Harness는 solver core와 분리된 세 계층의 개발 운영 인프라다.

  • 계획 계층: .agents/skills/harness가 사용자 승인 전 Step 초안을 만들고, 승인 후 phases/ 파일을 생성한다.
  • 실행 계층: scripts/execute.pyfeat-<phase-name> 브랜치에서 Step마다 독립 Codex 세션을 실행하고 상태와 커밋을 관리한다.
  • 검증 계층: .codex/hooks.jsonscripts/hooks/pre_tool_use.pyscripts/hooks/stop_validation.py를 연결한다. Stop 검증은 scripts/msvc_harness/를 통해 MSVC build와 test를 실행한다.

Runner는 git add -A를 사용하므로 clean worktree 또는 별도 Git worktree가 실행 전제다. 전체 동작 계약은 docs/HARNESS_WORKFLOW.md, 설치와 .harness/config.json 설정은 docs/HARNESS.md를 source of truth로 삼는다.

CMake target과 dependency graph

Root CMake project는 C++17, extension off, CMake 3.25 이상을 요구하고 cmake/FesaDependencies.cmake, src/fesa, tests를 차례로 구성한다.

MKL CONFIG package  ─> Fesa::MKL  ─┐
TBB CONFIG package  ─> Fesa::TBB  ─┼─> fesa_solver (STATIC) ─> fesa_cli
HDF5 CONFIG package ─> Fesa::HDF5 ─┘             │
                                                  ├─> fesa_unit_tests
approved local GoogleTest source ─> GTest targets ├─> fesa_integration_tests
                                                  └─> fesa_reference_tests
  • FESA_GTEST_SOURCE_DIR는 네트워크 fetch 대신 승인된 local GoogleTest source checkout을 가리키는 필수 cache path다.
  • MKL, TBB, HDF5는 CONFIG package로 탐지한다. Package search가 설치를 찾지 못하면 MKL_DIR, TBB_DIR, HDF5_DIR를 configure 때 지정한다.
  • Package별 imported target 이름은 Fesa::MKL, Fesa::TBB, Fesa::HDF5로 정규화한다. Product module은 vendor target 이름을 직접 선택하지 않는다.
  • HDF5 package가 shared와 static C target을 모두 제공하면 approved Windows environment에서는 shared target을 우선한다. Static archive의 숨은 compiler-runtime 요구가 link interface 밖으로 새는 것을 피하기 위한 결정이다.
  • fesa_solver는 외부 dependency를 PRIVATE으로 link하고 /W4 /WX를 사용한다. 따라서 public header는 MKL/TBB/HDF5/Win32 type을 포함하지 않아야 한다.
  • Test executable은 unit, integration, reference 경계를 분리하며 fesa_tests target은 세 executable을 build하는 aggregate target이다. Reference target에만 source/build root compile definition을 제공한다.

Windows runtime closure

Configure 성공은 executable이 GoogleTest discovery 또는 CLI 실행 시 필요한 DLL을 찾는다는 뜻이 아니다. fesa_cli와 세 test executable의 POST_BUILD 단계는 TBB, MKL thread/core/default dispatch, OpenMP, libmmd.dll, HDF5를 포함한 imported-target runtime DLL을 executable 옆에 복사한다. 새 dynamic backend를 도입할 때는 link 성공뿐 아니라 clean environment에서의 post-build discovery/실행까지 runtime closure로 다뤄야 한다. 개인 설치 absolute path를 CMake source에 기록하지 말고 config package와 imported target metadata를 확장한다.

모듈 경계

  • core는 외부 라이브러리에 의존하지 않는다.
  • io/abaqus는 syntax와 semantic mapping만 담당하고 해석 알고리즘을 알지 않는다.
  • model은 Abaqus keyword 문자열이 아니라 solver semantic model을 가지며 Domain과 non-owning AnalysisModel의 수명 경계를 소유한다.
  • materialsproperties는 Domain이 소유하는 semantic identity와 현재 승인된 isotropic elasticity 및 beam/shell property data만 제공한다.
  • elements는 Domain-owned ElementDefinition, runtime numerical Element, checked ElementFactory와 element-local stiffness/recovery contract를 제공한다.
  • femDofManager는 DOF, equation ordering, scatter와 sparse pattern을 소유한다.
  • assembly는 runtime element contribution과 ordered load contribution을 stable full-DOF space에 조립한다. Contribution producer는 global storage를 직접 갱신하지 않는다.
  • loads는 semantic target과 magnitude를 소유하고 ordered LoadContribution을 생성한다.
  • constraintsConstraintDefinition 생성과 V0 essential BC elimination 및 full/reduced vector 변환을 분리한다. MPC와 penalty는 현재 범위가 아니다.
  • solversLinearSolver 뒤에 MKL PARDISO 세부 구현을 감춘다. TBB는 assembly/ParallelFor, HDF5는 results/ResultsWriter 경계 뒤에 각각 격리된다.
  • analysis는 step/history data를 받아 procedure를 실행하고 solver backend와 result writer를 조율한다.
  • results는 full residual과 B33/MITC4 rows를 복구하고 backend-neutral writer contract를 제공한다. HDF5 schema 구현은 io/hdf5가 담당한다.
  • test helper는 production parser/solver 내부 상태를 우회하지 않는다.

승인된 리팩터링 dependency와 ownership

다음 graph는 C++ object-oriented modular refactoring의 구현 방향을 고정한다. owns는 단독 수명 소유권을, 나머지 화살표는 왼쪽 consumer가 오른쪽 contract를 사용한다는 뜻이다. 이 graph는 기존 B33/MITC4 물리 기능을 늘리지 않는다.

Domain owns ElementDefinition / ElementProperty / Material / StepDefinition
AnalysisModel is a non-owning stable-index view into Domain
ElementFactory creates runtime Element candidates from compatible definitions
DofManager -> ElementDofLayout
SparseAssembler -> ElementStiffnessContribution
ResultRecovery -> ElementResultBundle
LoadAssembler -> ordered LoadContribution
EssentialConstraintPolicy -> ConstraintDefinition
Analysis <- LinearStaticAnalysis

승인된 B33/MITC4 formulation, operation/reduction order, sign, units, coordinates와 row identity는 이 ownership 리팩터링보다 우선한다. HDF5 schema, reference artifact와 ADR-014/ADR-020 tolerance도 변경하지 않는다.

DomainElementDefinition, ElementProperty, MaterialStepDefinition base object를 std::unique_ptr로 단독 소유하고 const access를 제공한다. Collection position은 기존 stable EntityIndex 의미를 유지한다. AnalysisModel과 solver consumer는 ownership을 가져오지 않고 Domain 수명 안에서 stable index 또는 const reference만 사용한다. std::shared_ptr, speculative Clone()과 global registry는 이 계약에 포함되지 않는다.

ElementDefinition은 source identity, source element type, connectivity와 property/material identity를 보존하는 semantic object다. Runtime Element는 active ElementDofLayout, ElementStiffnessContributionElementResultBundle을 제공하는 numerical kernel이다. ElementFactory만 compatible definition/property/material 조합을 검사해 runtime candidate를 만들며 unknown 또는 incompatible 조합을 기존 Status/Result<T> diagnostic으로 fail-closed 처리한다. DofManager, SparseAssemblerResultRecovery는 B33/MITC4 concrete storage가 아니라 위 runtime contract를 소비한다. Linear-static candidate는 runtime Elementstd::vector<std::unique_ptr<Element>>로 소유하고, consumer에는 그 owner 수명 안에서만 유효한 non-owning ElementView를 제공한다.

Material base는 identity, source location과 수명 의미만 공유한다. 현재 concrete isotropic linear elasticity에 필요한 capability만 사용하며 density, anisotropy, plastic state, temperature 또는 rate dependency를 optional field나 no-op method로 미리 추가하지 않는다. ElementProperty도 beam/shell이 실제 사용하는 data만 각 concrete type에 둔다.

Load는 semantic target과 magnitude를 소유하고 source order가 보존된 LoadContribution을 생성한다. Global vector의 deterministic accumulation은 LoadAssembler만 수행한다. BoundaryConditionConstraintDefinition을 생성하고 EssentialConstraintPolicy가 prescribed displacement의 stable elimination과 reconstruction을 수행한다. Future distributed/body load와 MPC enforcement는 구현된 기능이 아니며 별도 승인 계약 없이 이 경계에 branch나 optional state를 추가하지 않는다.

책임이 큰 facade는 외부 계약을 유지한 채 private implementation만 다음 owner로 나눈다.

  • Abaqus Domain mapping: topology, material/property, step/load/boundary mapping과 final Domain assembly
  • Result recovery: global equilibrium, beam recovery, shell recovery와 atomic state commit
  • HDF5 writing: RAII/primitives, model datasets, result datasets, self-check와 atomic finalization

이 분할은 parser diagnostic, ResultsWriter boundary, HDF5 schema 또는 final-file atomicity를 변경하지 않는다.

V0 입력 경계

V0 parser는 keyword와 parameter를 case-insensitive하게 해석하되 source label의 원문을 보존한다. 지원하는 model/procedure keyword는 다음과 같다.

  • *HEADING
  • *PART, *END PART
  • *NODE
  • *ELEMENT, TYPE=B33
  • *NSET, *ELSET, including GENERATE
  • *MATERIAL, *ELASTIC
  • *BEAM GENERAL SECTION, SECTION=GENERAL
  • *SECTION POINTS
  • *ASSEMBLY, *END ASSEMBLY
  • *INSTANCE, *END INSTANCE
  • *BOUNDARY, *CLOAD
  • *STEP, *STATIC, *END STEP

Part 내부 label은 SourceEntityId { instance_name, source_label }로 보존하고 Domain은 별도 stable internal index를 부여한다. 같은 part의 여러 identity instance는 허용하지만 translation/rotation data와 nested assembly는 구조화된 unsupported diagnostic으로 거부한다. 입력 파일당 하나의 static step만 허용하고 두 번째 step은 오류다.

*PREPRINT, *RESTART, *TRANSVERSE SHEAR STIFFNESS, *OUTPUT, FIELD, *OUTPUT, HISTORY, *NODE OUTPUT, *ELEMENT OUTPUT, *CONTACT OUTPUT 및 그에 속한 미지원 output variable data는 warning 후 no-op 처리한다. 이 allowlist 밖의 미지원 model-affecting keyword는 오류다. FESA output은 Abaqus output request에 좌우되지 않는다.

V0 beam과 section 계약

EulerBeam3D는 2절점과 절점당 [UX, UY, UZ, URX, URY, URZ] 6 DOF를 사용하며 축, 두 방향 EulerBernoulli 굽힘과 Saint-Venant 비틀림을 제공한다. Beam tangent를 local x, Abaqus first section axis n1을 local y, t x n1을 local z로 둔다. *BEAM GENERAL SECTIONA, I11, I12, I22, JIy=I11, Iz=I22로 매핑하고 V0는 I12=0만 허용한다. E, G, A, Iy, Iz, J는 양수여야 하며 zero-length element와 tangent에 평행한 guide vector를 scale-aware tolerance로 거부한다.

요소 API는 stiffness, transformation, load와 recovery 책임을 분리한다.

Matrix localStiffness() const;
Matrix globalStiffness() const;
Vector localEquivalentLoad(const ConstantLocalLineLoad& load) const;
BeamRecovery recover(const Vector& globalElementDisplacement) const;

localEquivalentLoad는 formulation의 constant local line-load kernel을 unit test하기 위한 계약이다. V0 parser는 *DLOAD나 distributed-load Domain object를 생성하지 않으므로 CLI pipeline에서는 이 kernel을 호출하지 않는다. Stiffness와 recovery는 formulation의 2점 Gauss rule과 부호 규약을 따른다.

핵심 객체 모델

Domain
├── owns nodes, sets and source identity
├── owns unique_ptr<ElementDefinition / ElementProperty / Material>
├── owns StepDefinition with Load / BoundaryCondition definitions
└── owns source path/identity and mapping warnings

AnalysisModel
├── non-owning stable-index view into Domain
├── stable active element/BC/load definition indices
└── reachable material/property indices

ElementFactory
└── creates checked runtime Element candidates

Element
├── exposes ElementDofLayout
├── produces ElementStiffnessContribution
└── recovers ElementResultBundle

DofManager
├── owns node x [UX,UY,UZ,URX,URY,URZ] full-DOF numbering
├── owns stable free/constrained order and prescribed values
├── owns element scatter maps
└── owns full-space CSR structural pattern

AnalysisState
├── displacement U
├── external force Fext
├── internal force Fint
├── residual R and full-index reaction
├── StepFrameIdentity
└── endpoint, Gauss and S11 recovery rows

Analysis
└── LinearStaticAnalysis

Vector
Matrix
SparseMatrix

위 abstract boundary는 현재 B33/MITC4, isotropic linear elasticity, beam/shell property, concentrated nodal load, prescribed displacement와 linear static procedure를 연결하는 데 필요한 최소 계약이다. MITC3, solid, dynamic, frequency, heat-transfer와 plastic behavior는 구현된 기능이 아니며 승인된 사용 사례 전에 future-only method나 state를 base에 추가하지 않는다.

상태 관리

  • Domain은 입력 파일에서 만들어진 전체 모델 정의를 std::unique_ptr로 단독 소유한다. 파싱 이후에는 가능한 한 불변으로 취급하고 stable collection index를 바꾸지 않는다.
  • LinearStaticAnalysisDomain을 소유하고, 그 뒤에 AnalysisModel, DofManager, AnalysisState, stiffness/RHS를 순서대로 만든다. 재사용 시에는 역순으로 해제하여 이전 Domain을 가리키는 view를 남기지 않는다.
  • AnalysisModel은 현재 step에서 활성화되는 해석 객체들의 실행 view이다. Domain을 복사하지 않으므로 Domain이 반드시 더 오래 살아야 한다.
  • DofManager는 자유도와 방정식 번호를 전담한다. Node 또는 Element 내부에 equation id를 분산 저장하지 않는다.
  • AnalysisState는 V0 frame에 필요한 다섯 full-DOF vector와 recovery rows만 소유한다. Velocity, acceleration, temperature, iteration history, nonlinear element state는 해당 procedure가 승인될 때 별도 계약으로 추가한다.
  • Result recovery는 모든 candidate vector/row를 검증한 뒤 state에 반영한다. 실패한 recovery가 앞선 유효 state를 부분적으로 덮어쓰지 않아야 한다.

데이터 흐름

Abaqus input file
-> syntax parse and semantic mapping
-> immutable Domain 생성
-> 단일 step AnalysisModel view 생성
-> ElementFactory가 compatible definition에서 runtime Element candidate 생성
-> DofManager가 ElementDofLayout으로 DOF/scatter map/sparse pattern 생성
-> ElementStiffnessContribution의 deterministic COO-to-CSR 조립
-> ConstraintDefinition의 stable essential-constraint partition 생성
-> LinearSolver::factorize(Kff)
-> ordered LoadContribution의 full nodal load vector 조립
-> effective RHS = Ff - Kfc * dc
-> LinearSolver::solve(rhs, df) substitution
-> full displacement 복구
-> full residual/reaction = K*d - F 및 ElementResultBundle 복구
-> ResultsWriter로 results.h5 atomic finalization

강성행렬 factorization은 하중벡터 조립보다 먼저 수행한다. 반력은 element end action의 별도 합이 아니라 조립된 전체 residual에서 구한다. Constrained component는 physical reaction이고 free component는 equilibrium residual evidence로 full-index vector에 남긴다.

해석 실행 흐름

Analysis base는 procedure-specific protected hook을 정의하지 않고 최소 실행 계약인 Analysis::Run(const AnalysisRequest&)만 제공한다. 다음 여덟 단계의 순서와 fail-fast 경계는 LinearStaticAnalysis::Run()의 private lifecycle이며 다른 procedure에 강제되지 않는다.

순서 Private stage 주요 작업과 생성되는 소유 객체 순서/실패 불변식
1 Initialize(request) .inp syntax read, semantic map, owned immutable Domain, sorted warnings 이전 run의 dependent object를 역순으로 제거하고 parse/map 실패를 input category로 반환한다.
2 BuildAnalysisModel() non-owning AnalysisModel view Domain을 복사하지 않으며 Domain lifetime 안에서만 사용한다.
3 BuildDofMapAndSparsePattern() DofManager, zero-initialized AnalysisState Stable full/free/constrained numbering과 structural pattern을 한 소유자에게 둔다.
4 AssembleAndPartitionStiffness() full CSR K와 Kff/Kfc/Kcf/Kcc Element-local buffer를 deterministic하게 reduce하고 structural zero와 stable order를 보존한다.
5 Factorize() retained Kff factorization 모든 load assembly보다 먼저 호출한다. Valid fully constrained model의 0 x 0 Kff는 trivial success다.
6 AssembleLoadsAndEffectiveRhs() full F와 Ff-Kfc*dc Semantic load source order와 finite sum을 보존하며 solver를 호출하지 않는다.
7 SubstituteAndReconstruct() free solution과 full displacement Factorization을 재수행하지 않고 substitution한 뒤 prescribed value를 stable order로 복구한다.
8 RecoverAndWriteResults() full residual/reaction, B33/MITC4 rows, final HDF5 Recovery candidate를 원자적으로 commit하고 writer 성공 뒤에만 최종 output을 교체한다.

비선형 정적 및 동적 해석은 V0 범위가 아니며 별도 ADR과 formulation을 승인한 뒤 이 lifecycle과 state/equation 계약을 별도 procedure에 정의한다. LinearStaticAnalysis의 private stage 사이에 조용히 반복·증분·시간 적분 동작을 삽입하지 않는다.

설계 패턴

  • Strategy/Adapter Pattern: Analysis::Run(const AnalysisRequest&), LinearSolver, ParallelFor, ResultsWriter가 현재 승인된 public 실행/backend 경계다. Vendor API는 concrete adapter implementation 안에만 둔다.
  • Procedure-owned lifecycle: Analysis는 protected Template Method hook을 공유하지 않고 LinearStaticAnalysis가 승인된 여덟 단계 lifecycle을 private하게 소유한다.
  • Syntax/Semantic separation: AbaqusInputReader는 syntax record를 만들고 AbaqusDomainMapper가 승인된 keyword 의미를 concrete Domain record로 변환한다.
  • Runtime Polymorphism: backend와 승인된 analysis/element/material/property/load/boundary 경계에만 사용한다. Factory compatibility는 중앙에서 fail-closed로 검사하며 global registry 또는 future-only capability를 추가하지 않는다.
  • RAII: MKL handle, HDF5 file/dataset, temporary solver workspace의 수명과 오류 처리를 wrapper에 묶는다.

Sparse Matrix Policy

  • Assembly는 element마다 index-addressed contribution buffer를 만들고, join 뒤 COO tuple을 stable order로 정렬해 한 thread에서 순서대로 합산한 후 CSR로 finalize한다.
  • SparseMatrix는 0-based CSR 데이터를 소유하는 별도 타입이며 dense Matrix를 상속하지 않는다. MKL PARDISO backend는 adapter 경계에서 필요한 descriptor와 indexing을 변환한다.
  • CSR row offset, sorted-unique column, dimensions, finite values를 construction boundary에서 검증하며 structural zero를 삭제하지 않는다.
  • Parallel worker는 global sparse matrix나 shared reduction accumulator를 직접 갱신하지 않는다. Worker별 failure slot과 contribution만 쓰고, deterministic reduction은 join 뒤에 수행한다.
  • Matrix symmetry와 factorization/substitution failure는 solver adapter가 구조화된 solver diagnostic으로 번역한다. 승인되지 않은 regularization이나 fallback으로 singularity를 숨기지 않는다.

Dense Math Policy

  • Vector는 contiguous double 데이터와 크기를 소유하고 copy, dot, Euclidean norm, scale, axpy를 MKL CBLAS adapter로 수행한다.
  • Matrix는 row-major contiguous double 데이터와 dimensions를 소유하고 matrix-vector 및 matrix-matrix 연산에 CBLAS_ROW_MAJOR를 사용한다.
  • 두 타입은 copy/move semantics와 bounds-checked access를 제공한다.
  • MKL header와 MKL-specific type은 adapter implementation 밖으로 노출하지 않는다.

Parallel Policy

  • ParallelFor[0,count) index-addressed 독립 작업만 노출하며 SerialParallelForTbbParallelFor가 같은 observable contract를 가진다.
  • 첫 oneTBB 적용 지점은 element-local stiffness 계산이다. 각 callback은 자기 index의 output slot만 쓴다.
  • 전역 sparse write와 부동소수 reduction은 parallel callback 밖의 deterministic 단계로 제한한다.
  • MKL 내부 thread와 TBB element loop가 oversubscription을 만들지 않도록 thread count와 task arena 정책을 명시한다.

HDF5 Result Schema

/metadata
/model/nodes
/model/elements
/steps/<step-name>/frames/0/nodal/displacement
/steps/<step-name>/frames/0/nodal/reaction
/steps/<step-name>/frames/0/element/end_force_local
/steps/<step-name>/frames/0/element/section_resultant
/steps/<step-name>/frames/0/element/generalized_strain
/steps/<step-name>/frames/0/element/stress_s11
/diagnostics

Schema requirements:

  • schema version, units, coordinate system, solver version, source input identity를 metadata에 기록한다.
  • field output과 history output을 구분한다.
  • reference comparison을 위한 row identity는 node id, element id, integration point id, step/frame id를 포함한다.
  • FESA solver는 results.h5를 authoritative output으로 쓴다.
  • Abaqus reference results는 기능 문서가 선언한 기존 CSV 파일이다. Directory/file naming, README, metadata 또는 provenance는 architecture readiness 조건이 아니다.
  • Verification은 기능이 요구하는 source identity와 component를 결정적으로 대응시키고 승인 tolerance를 적용한다. Missing/extra/duplicate/nonfinite required row는 숫자 비교 전에 실패한다. 단일 step/final-frame 기능은 별도 CSV step/frame 열을 요구하지 않는다.
  • FESA HDF5에서 추출한 deterministic CSV view는 optional debugging/review artifact이며 공식 solver output 또는 reference artifact가 아니다.
  • Writer는 final과 같은 directory의 임시 HDF5에 전체 schema를 쓴 뒤 flush, checked close, read-only reopen/self-check를 수행한다. Existing final은 ReplaceFileW, 새 final은 MoveFileExW(..., MOVEFILE_WRITE_THROUGH)로 완료하며 실패 시 temporary artifact를 정리하고 불완전한 파일을 정상 results.h5로 노출하지 않는다.

V0 결과 복구와 reference normalization

  • Nodal displacement와 reaction은 global [UX, UY, UZ, URX, URY, URZ] 순서다.
  • Equilibrium end action은 local [FX,FY,FZ,MX,MY,MZ], endpoint section resultant는 [N,T,My,Mz], generalized strain/resultant는 두 Gauss point에 기록한다.
  • General beam section stress는 section point의 axial S11만 복구한다. Section point가 없으면 centroid (0,0)source=fesa-default로 기록한다.
  • 승인된 reference/cantilever beam/cantilever beam elemental forces.csv는 각 B33 element의 두 endpoint에 Element Label, Node LabelSF1/SM1/SM2/SM3을 제공한다. (instance, element label, endpoint node label, component) identity로 HDF5 [element,endpoint,N/T/My/Mz]에 직접 대응하고 SF1 -> N, SM1 -> My, SM2 -> Mz, SM3 -> T로 비교한다. External reference comparison은 node-station collapse나 평균을 사용하지 않는다.
  • Reference tolerance는 같은 model/case, step/frame, logical quantity, unit dimension, coordinate system과 blocking behavior의 component family에서 Abaqus-only scale S=max(abs(reference))를 구한다. abs(reference)<=0.01*S인 행은 absolute error <=0.01*S, 그 외 행은 relative error <=0.05로 판정하며 family scale-relative RMS RMS(error)/S<=0.01도 통과해야 한다. 독립 absolute-error gate는 사용하지 않고 zero-scale family는 FESA도 exact zero일 때만 통과한다. 전체 판정 과정과 report/change management contract는 docs/TOLERANCE.md를 따른다.
  • Beam stress는 HDF5 schema와 unit/analytical test로 검증하지만 Abaqus reference comparison은 N/A다.

CLI와 diagnostics

fesa.exe <model.inp> --output <results.h5>

--output을 생략하면 현재 작업 디렉터리의 results.h5를 사용한다. Exit code는 0=success, 2=usage, 3=input syntax/semantic mapping, 4=model validation, 5=factorization/substitution, 6=HDF5 output으로 고정한다. Diagnostic은 severity, code, file, line, keyword, entity_identity, message를 가지며 stderr에 deterministic한 순서로 출력한다.

기능 확장 플레이북

다음 표는 코드 위치만이 아니라 함께 바뀌어야 하는 계약 경계를 나타낸다. 한 열만 구현하고 다른 열을 생략하면 internal utility 또는 실험 kernel일 수는 있어도 제품 기능은 아니다.

기능 유형 시작 전에 고정할 것 주요 구현 경계 함께 검증할 것 피해야 할 shortcut
새 element/material DOF, interpolation, constitutive law, integration, local axes/sign, feature-approved validity boundary Domain record와 mapper, element kernel, DofManager scatter/pattern, SparseAssembler, ResultRecovery feature-required invariants/tests and blocking reference quantities 서로 다른 물리를 같다고 주장, source ID와 internal index 혼용, 검증 전 범용 hierarchy 추가
새 load/constraint Abaqus target grammar, application order, units, follower 여부, prescribed-value 의미 Syntax/mapper, Domain target, full-space LoadAssembler 또는 constraint partition, diagnostics set/direct target ambiguity, multi-instance identity, nonfinite sum, Ff-Kfc*dc, reaction Element load kernel 존재를 parser 지원으로 간주, penalty를 elimination에 몰래 혼합
새 analysis procedure governing equation, state variables, increment/time lifecycle, tangent/residual, convergence와 output frame 별도 Analysis implementation, procedure-specific state/equation owner, solver interface extension orchestration order, failure atomicity, restart/frame identity, numerical benchmark V0 hook 사이에 조건문으로 반복/시간 적분 삽입, 사용하지 않는 future state 선할당
새 numerical backend matrix/index contract, lifecycle, reusable state, failure taxonomy, thread/runtime policy 기존 LinearSolver 또는 ParallelFor interface의 concrete adapter, CMake normalized target empty/dimension/extreme-scale input, repeated call, failed-output preservation, clean runtime discovery Vendor type을 public header에 노출, silent fallback/regularization, absolute install path 고정
새 output/reference quantity 물리 정의, location, sign, units, coordinates, stable row identity, mandatory 여부, tolerance Result record/recovery, AnalysisState, ResultsWriter/HDF5 schema, comparator projection schema dtype/shape, ordering, nonfinite rejection, identity inventory, reference N/A 대체 evidence 서로 다른 result identity 혼합, station mismatch 평균, output request로 mandatory result 제거

모든 확장은 PRD의 제품 완료 정의와 요구조건→정식화→I/O→구현→reference→physics gate를 따른다. 기존 feature contract에 없는 범위를 편의상 “Abaqus compatible”이라고 넓히지 않는다.

MITC4 확장 경계

MITC4가 구현될 때 Abaqus S4S4R source type은 같은 FESA formulation을 선택한다. Source type은 metadata/diagnostic identity로 보존하지만 FESA integration 또는 hourglass 경로를 선택하지 않는다. 6-DOF embedding의 비물리 drilling coordinate에는 physical rotational stiffness block의 positive minimum diagonal에 1e-3을 곱한 고정 numerical stabilization만 둔다. Drilling calibration, artificial-energy policy와 별도 drilling result dataset은 이 기능 범위가 아니다.

Full-integration FESA-MITC4의 reference comparison은 reference/shell/ S4의 기존 input 및 displacement CSV만 사용한다. Global U1/U2/U3 translation family만 blocking이고 UR1/UR2/UR3 rotation family는 warning-only evidence다. 두 family 모두 ADR-022의 공통 family-scale row/RMS 정책을 사용한다. S4R은 같은 kernel을 선택하는 source mapping과 metadata를 unit/integration tests로 검증하며 reference/shellR/ artifact는 acceptance comparison에 포함하지 않는다.