길이가 같은 요소 n개로 나눈 1차원 막대의 정상 열전도를 1차 유한요소로 푼다. 요소 e의 열전도도 ke가 설계 변수다. 왼쪽 끝 절점의 온도는 0으로 고정하고, 나머지 절점 1,…,n의 온도 T∈Rn은
K(k)T=f
를 푼다. K는 요소 행렬 hke[1−1−11]를 절점 (e,e+1) 자리에 더해 만든 행렬에서 고정 절점 0의 행과 열을 뺀 n×n 행렬이다(h는 요소 길이). 목적함수는 절점 온도의 가중합 J=c⊤T다.
함수 adjoint_gradient(k, f, c, h)를 완성해 (J, grad)를 반환한다. grad[e]는 ∂J/∂ke다.
adjoint 방법은 다음과 같다.
- KT=f를 푼다.
- K⊤λ=c를 푼다(adjoint 해석).
- ∂ke∂J=−λ⊤∂ke∂KT. 고정 절점의 값을 0으로 붙인 T~=(0,T), λ~=(0,λ)를 쓰면 −h1(λ~e+1−λ~e)(T~e+1−T~e)이다.
테스트는 다음을 확인한다.
- 기울기가 유한차분과 맞는다(여러 c에 대해).
- c=f(열 compliance)이면 λ=T이므로 모든 성분이 0 이하다. 어느 요소의 전도도를 올려도 compliance가 줄어든다.
- 설계 변수가 200개여도 선형계 풀이(
np.linalg.solve) 호출이 3회 이하다. 유한차분은 201회가 필요하다.
힌트: K의 대각 원소는 (ke+ke+1)/h(마지막 절점은 kn/h), 위·아래 대각 원소는 −ke+1/h다(절점 번호 기준으로 맞춰 본다). np.linalg.solve를 두 번만 쓴다.