Add AD support for complex-valued DOFs - #1325
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1325 +/- ##
==========================================
- Coverage 88.83% 88.83% -0.01%
==========================================
Files 228 228
Lines 30132 30177 +45
==========================================
+ Hits 26768 26807 +39
- Misses 3364 3370 +6
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
JordiManyer
left a comment
There was a problem hiding this comment.
Hi @zjwegert , thanks for the contribution. Very interesting, I didn't know you could do this. I added some comments on the reusability of the code. I think it would help to make the whole AD module more maintainable. Cheers!
Thanks @JordiManyer ! I'll take a look when I get a chance. |
|
Hey @JordiManyer, I've made the changes you requested and updated the NEWS. Cheers |
|
Hi @JordiManyer, this should be ready now. I'm happy to make changes in GridapDistributed once you're happy with this PR. Edit: I've also added |
JordiManyer
left a comment
There was a problem hiding this comment.
Hi @zjwegert I have a couple style comments, but otherwise I think the changes are good. I will merge after!
This PR adds basic autodiff support for problems with complex-valued DOFs. Currently, this is not supported natively because ForwardDiff does not fully support complex-valued functions.
The approach here is to split the computation into real and imaginary parts, and since we're assuming that the functional is differentiable, we can compute the derivative by only perturbing the real parts of the cell dofs. I thought the best approach would be to dispatch on
T=eltype(get_vector_type(V))and add new methodsautodiff_array_gradient(::Type{<:Complex},...)andautodiff_array_gradient(::Type{<:Complex},...)that split the computation as above.There are three cases that we consider:
ℂ→ℂ. The standard approach in AD systems is to compute the conjugate gradientf'(z)ᴴ = ∂ᵣu + i ∂ₛuso thatdF(z)(v) = <f'(z)ᴴ, v> = f'(z)v.ℂ → ℝ. Using CR-Calculus we have that the gradient is given by∇z(f) = 2∂f/∂z* = ∂ᵣu + i ∂ₛuand the directional derivative is given bydF(z)(v)=Re{∇z(f),v}.ℂ → ℂ: requires splitting into derivative inzand derivative inz*. This is not implemented yet. To do this one properly, we should probably implement a new kind of FEOperator calledNonholomorphicFEOperatorthat appropriately builds the Jacobian's inzandz*and implements a basic Newton method.Because (1) and (2) are in the same form, we reuse the code below for both cases.
@JordiManyer, If we're happy with this PR, I'll make the appropriate changes to GridapDistributed as well.