I am trying to compute the gradient of a finite element stiffness matrix with respect to nodal coordinates, Young’s modulus E, and thickness t. I am new to automatic differentiation (AD) and have tried using DifferentiationInterface.jl
with ForwardDiff
and Enzyme
as backends.
I also attempted changing nodes_cord
from a matrix to a vector, but I still encountered issues. When I compute only the area A of the triangle, differentiation works. However, once I include the computation of the strain-displacement matrix B, AD fails.
In the future, I will need to compute the gradient of the global assembled stiffness matrix (i.e., after assembling element stiffness matrices into a larger system). Given that, I want to ensure my approach scales properly.
Any advice on how to correctly differentiate this function would be greatly appreciated!
Here is the function I am working with:
function compute_CST_stiffness(nodes_cord::Matrix{Float64}, E::Number, ν::Number, t::Number)
x1, y1 = nodes_cord[1,:]
x2, y2 = nodes_cord[2,:]
x3, y3 = nodes_cord[3,:]
# Compute area of the triangle
A = 0.5 * abs(x1*(y2 - y3) + x2*(y3 - y1) + x3*(y1 - y2))
# Shape function derivatives
β = [y2 - y3, y3 - y1, y1 - y2] / (2A)
γ = [x3 - x2, x1 - x3, x2 - x1] / (2A)
# Plane stress elasticity matrix
D = (E / (1 - ν^2)) * [1 ν 0; ν 1 0; 0 0 (1 - ν)/2]
# Strain-displacement matrix B
B = zeros(3, 6)
for i in 1:3
B[1, 2i-1] = β[i]
B[2, 2i] = γ[i]
B[3, 2i-1] = γ[i]
B[3, 2i] = β[i]
end
# Compute stiffness matrix
K = t * A * (B' * D * B)
return K
end
Has anyone encountered similar issues when differentiating matrix-valued functions?
Would a different approach make differentiation more reliable, especially when working toward computing the gradient of the global assembled stiffness matrix?
Thanks in advance!