--- id: wiki-2026-0508-finite-element-analysis title: Finite Element Analysis (FEA) category: 10_Wiki/Topics status: verified canonical_id: self aliases: [FEA, FEM, finite element method, structural analysis, ANSYS, Abaqus, mesh] duplicate_of: none source_trust_level: A confidence_score: 0.95 verification_status: applied tags: [engineering, fea, fem, simulation, structural, mesh, computational-mechanics] raw_sources: [] last_reinforced: 2026-05-10 github_commit: pending tech_stack: language: Python / FORTRAN / C++ framework: ANSYS / Abaqus / FEniCS / PyANSYS --- # Finite Element Analysis (FEA) ## 매 한 줄 > **"매 PDE 의 의 의 mesh 의 element 의 의 discretize 의 solve"**. 매 structural, thermal, fluid, EM. 매 famous: ANSYS, Abaqus, NASTRAN. 매 modern: 매 FEniCS (open), 매 ML-augmented (PINN, GNN), 매 cloud HPC. ## 매 핵심 ### 매 step 1. **Geometry / CAD**. 2. **Mesh** (1D, 2D, 3D element). 3. **Material** (E, ν, ρ, ...). 4. **Boundary condition + load**. 5. **Assemble** (K matrix). 6. **Solve** (linear / nonlinear). 7. **Post-process**. ### 매 element type - **1D**: bar, beam. - **2D**: triangle, quad (CST, LST). - **3D**: tet, hex, wedge. - **Shell**: 매 thin structure. ### 매 analysis type - **Static linear**. - **Modal** (eigenvalue). - **Dynamic** (transient). - **Nonlinear** (geom, material, contact). - **Thermal**. - **CFD** (Navier-Stokes). - **EM** (Maxwell). ### 매 modern AI - **PINN** (physics-informed NN). - **GNN-based** (faster surrogate). - **Differentiable FEM** (JAX-FEM). - **NeRF for material**. ### 매 응용 1. **Aerospace**: 매 wing. 2. **Automotive**: 매 crash. 3. **Civil**: 매 building. 4. **Biomedical**: 매 implant. 5. **Electronics**: 매 PCB thermal. 6. **Geomechanics**: 매 dam. ## 💻 패턴 ### FEniCS (open-source) ```python from dolfinx import fem, mesh, plot from mpi4py import MPI import ufl domain = mesh.create_rectangle(MPI.COMM_WORLD, [(0,0), (1,1)], (32,32)) V = fem.FunctionSpace(domain, ('Lagrange', 1)) # 매 BC def boundary(x): return np.isclose(x[0], 0) | np.isclose(x[0], 1) bc = fem.dirichletbc(0.0, fem.locate_dofs_geometrical(V, boundary), V) # 매 weak form (Poisson) u = ufl.TrialFunction(V); v = ufl.TestFunction(V) f = fem.Constant(domain, 1.0) a = ufl.dot(ufl.grad(u), ufl.grad(v)) * ufl.dx L = f * v * ufl.dx # 매 solve problem = fem.petsc.LinearProblem(a, L, bcs=[bc]) uh = problem.solve() ``` ### Stiffness matrix (1D bar) ```python import numpy as np def bar_stiffness(E, A, L): """매 1D bar element.""" k = E * A / L return np.array([[k, -k], [-k, k]]) def assemble(elements, n_nodes): K = np.zeros((n_nodes, n_nodes)) for (e, k_local) in elements: for i, gi in enumerate(e): for j, gj in enumerate(e): K[gi, gj] += k_local[i, j] return K ``` ### Mesh generation (gmsh) ```python import gmsh gmsh.initialize() gmsh.model.add('plate') gmsh.model.geo.addPoint(0, 0, 0, 0.1, 1) gmsh.model.geo.addPoint(1, 0, 0, 0.1, 2) gmsh.model.geo.addPoint(1, 1, 0, 0.1, 3) gmsh.model.geo.addPoint(0, 1, 0, 0.1, 4) gmsh.model.geo.addLine(1, 2, 1) # ... 4 lines gmsh.model.geo.addPlaneSurface([1]) gmsh.model.mesh.generate(2) gmsh.write('plate.msh') ``` ### PyANSYS (commercial integration) ```python from ansys.mapdl.core import launch_mapdl mapdl = launch_mapdl() mapdl.prep7() mapdl.et(1, 'BEAM188') mapdl.mp('EX', 1, 200e9) # 매 Steel mapdl.k(1, 0); mapdl.k(2, 1); mapdl.l(1, 2) mapdl.lesize('all', '', '', 10) mapdl.lmesh('all') mapdl.solve() mapdl.post1() ``` ### Modal analysis ```python from scipy.linalg import eigh def modal(K, M, n_modes=5): """매 K φ = ω² M φ.""" eigvals, eigvecs = eigh(K, M) freqs_hz = np.sqrt(eigvals[:n_modes]) / (2 * np.pi) return freqs_hz, eigvecs[:, :n_modes] ``` ### Nonlinear (Newton-Raphson) ```python def newton_raphson(K_fn, R_fn, u0, tol=1e-6, max_iter=50): u = u0.copy() for _ in range(max_iter): residual = R_fn(u) if np.linalg.norm(residual) < tol: return u K = K_fn(u) du = np.linalg.solve(K, -residual) u += du raise ConvergenceError() ``` ### PINN (physics-informed) ```python import torch class PINN(torch.nn.Module): def __init__(self): super().__init__() self.net = torch.nn.Sequential( torch.nn.Linear(2, 64), torch.nn.Tanh(), torch.nn.Linear(64, 64), torch.nn.Tanh(), torch.nn.Linear(64, 1), ) def forward(self, x): return self.net(x) def physics_loss(self, x): x.requires_grad = True u = self.forward(x) u_x = torch.autograd.grad(u.sum(), x, create_graph=True)[0] u_xx = torch.autograd.grad(u_x.sum(), x, create_graph=True)[0] # 매 e.g., Poisson: -u_xx = f return ((-u_xx + 1) ** 2).mean() ``` ### GNN-based surrogate (MeshGraphNet) ```python import torch_geometric.nn as gnn class MeshGraphNet(torch.nn.Module): def __init__(self, node_dim=3, edge_dim=3, hidden=128): super().__init__() self.encoder = gnn.MLP([node_dim, hidden, hidden]) self.processor = torch.nn.ModuleList([gnn.GCNConv(hidden, hidden) for _ in range(15)]) self.decoder = torch.nn.Linear(hidden, node_dim) def forward(self, x, edge_index): x = self.encoder(x) for layer in self.processor: x = torch.relu(layer(x, edge_index)) return self.decoder(x) ``` ### Convergence test ```python def mesh_convergence(solver_fn, mesh_sizes): """매 element size 의 의 의 result 의 stable?""" results = {} for h in mesh_sizes: results[h] = solver_fn(h) diffs = [abs(results[mesh_sizes[i]] - results[mesh_sizes[i+1]]) for i in range(len(mesh_sizes)-1)] return diffs ``` ### Post-processing (paraview) ```python import pyvista as pv mesh = pv.read('result.vtk') mesh.plot(scalars='displacement', cmap='viridis') ``` ### Material library ```python MATERIALS = { 'steel': {'E': 200e9, 'nu': 0.3, 'rho': 7850, 'sy': 250e6}, 'aluminum': {'E': 70e9, 'nu': 0.33, 'rho': 2700, 'sy': 95e6}, 'concrete': {'E': 30e9, 'nu': 0.2, 'rho': 2400, 'sy': 30e6}, } ``` ### JAX-FEM (differentiable) ```python import jax_fem mesh = jax_fem.gen_mesh.box_mesh(10, 10, 10, 1.0, 1.0, 1.0) problem = jax_fem.LinearElasticity(mesh, E=200e9, nu=0.3) sol = jax_fem.solver.solver(problem, ...) # 매 sensitivity / topology opt 의 가능 ``` ## 매 결정 기준 | 상황 | Tool | |---|---| | Open-source academic | FEniCS / JAX-FEM | | Industry structural | ANSYS / Abaqus | | Cheap PoC | PyANSYS / FreeCAD | | ML surrogate | PINN / MeshGraphNet | | Topology opt | JAX-FEM (diff) | | Mobile / real-time | Surrogate model | **기본값**: 매 commercial = ANSYS/Abaqus + 매 open-source = FEniCS + 매 ML augmentation = MeshGraphNet for surrogate. ## 🔗 Graph - 변형: [[FEM]] - 응용: [[ANSYS]] · [[Abaqus]] - Adjacent: [[PINN]] ## 🤖 LLM 활용 **언제**: 매 engineering simulation. 매 design optimization. **언제 X**: 매 simple analytical solution. ## ❌ 안티패턴 - **Skip mesh convergence**: 매 unreliable. - **Linear for nonlinear regime**: 매 wrong. - **Wrong element type**: 매 locking. - **No BC validation**: 매 garbage. - **Pure ML w/o physics**: 매 OOD fail. ## 🧪 검증 / 중복 - Verified (Zienkiewicz Finite Element Method, FEniCS docs). - 신뢰도 A. ## 🕓 Changelog | 날짜 | 변경 | |---|---| | 2026-04-26 | FEA auto | | 2026-05-08 | Phase 1 | | 2026-05-10 | Manual cleanup — FEM steps + 매 FEniCS / PyANSYS / PINN / GNN / convergence code |