# Adjoint method in gridap

**URL:** <https://discourse.julialang.org/t/adjoint-method-in-gridap/100529>\
**Category:** New to Julia\
**Tags:** question, gridap\
**Created:** [June 18, 2023, 6:59pm UTC](https://discourse.julialang.org/t/adjoint-method-in-gridap/100529 "2023-06-18T18:59:37Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![mary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mary/32/53139_2.png) [@mary](https://discourse.julialang.org/u/mary)\
**Post date:** [June 18, 2023, 6:59pm UTC](https://discourse.julialang.org/t/adjoint-method-in-gridap/100529/1 "2023-06-18T18:59:37Z")

</div>

Hi, I am trying to understand this code of gridap tutorial 18 but i couldnt is there anyone who can explain how below equation is written in julia as below?  
dg/dpt=−2ℜ[w^†(dA/dpt u)]

```julia
function Dgfdpf(pf_vec; β, η, phys_params, fem_params)
    pfh = FEFunction(fem_params.Pf, pf_vec)
    pth = (pf -> Threshold(pf; β, η)) ∘ pfh
    A_mat = MatrixA(pth; phys_params, fem_params)
    b_vec = assemble_vector(v->(∫(v)fem_params.dΓ_s), fem_params.V)
    u_vec = A_mat \ b_vec
    O_mat = MatrixOf(fem_params)

    uh = FEFunction(fem_params.U, u_vec)
    w_vec = A_mat' \ (O_mat * u_vec)
    wconjh = FEFunction(fem_params.U, conj(w_vec))

    l_temp(dp) = ∫(real(-2 * DAdpf(uh, wconjh, pfh; phys_params, β, η)) * dp)fem_params.dΩ_d
    dgfdpf = assemble_vector(l_temp, fem_params.Pf)
    return dgfdpf
end

```

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [June 18, 2023, 8:10pm UTC](https://discourse.julialang.org/t/adjoint-method-in-gridap/100529/2 "2023-06-18T20:10:47Z")

</div>

> [@mary](#):
>
> ```julia
> l_temp(dp) = ∫(real(-2 * DAdpf(uh, wconjh, pfh; phys_params, β, η)) * dp)fem_params.dΩ_d
> dgfdpf = assemble_vector(l_temp, fem_params.Pf)
> 
> ```

`−2ℜ[w^†(dA/dpt u)]` is a linear form in `u` (here = the FEM basis functions), so it uses the above two lines via `assemble_vector`.

---

<div class="post-metadata">

**Author:** ![mary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mary/32/53139_2.png) [@mary](https://discourse.julialang.org/u/mary)\
**Post date:** [June 18, 2023, 8:17pm UTC](https://discourse.julialang.org/t/adjoint-method-in-gridap/100529/3 "2023-06-18T20:17:00Z")

</div>

why it isnt multiplied by w^T? it is just using uh and wconjh as inputs of dA. considering dAdp as below.

```julia
DAdpf(u, v, pfh; phys_params, β, η) = ((p -> Dξdpf(p, phys_params.n_air, phys_params.n_metal, β, η)) ∘ pfh) * (∇(v) ⊙ ∇(u))

```

as you can see there is ∇(v) ⊙ ∇(u) in dA, so what if there is (ε(v) ⊙ (σfun∘(ε(u))) in dA?  
thank you

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [June 18, 2023, 8:24pm UTC](https://discourse.julialang.org/t/adjoint-method-in-gridap/100529/4 "2023-06-18T20:24:05Z")

</div>

> [@mary](#):
>
> why it isnt multiplied by w^T?

That’s what the `wconjh` argument does. If A is the FEM matrix of a bilinear form a(u,v), then \vec{u}^T A \vec{v} = a(u,v) = \int \text{something}(u,v) d\Omega, where u(x) = \sum\_k u\_k p\_k(x) is the function formed from the FEM basis functions p\_k(x) \in P with coefficients \vec{u}, and similarly for v(x) and \vec{v}.

Now, for the adjoint method, it’s the same sort of thing but with the derivative of A with respect to the parameters. The \vec{w}^\dagger turns into a function \overline{w(x)} in the integrand, which is represented here by `wconjh`.

---

<div class="post-metadata">

**Author:** ![mary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mary/32/53139_2.png) [@mary](https://discourse.julialang.org/u/mary)\
**Post date:** [June 18, 2023, 8:36pm UTC](https://discourse.julialang.org/t/adjoint-method-in-gridap/100529/5 "2023-06-18T20:36:38Z")

</div>

so as you have mentioned that a(u,v) is the integration of something and in my case is

```julia
A_Disp(u,v,pth) = ((p->Em(p))∘pth) * (ε(v) ⊙ (σfun∘(ε(u))))
    a_Disp(u,v) =∫(A_Disp(u,v,pth))fem_params.dΩ

```

l\_temp would be as tutorial as below (without 2 as i think it is due to problem)

```julia
    l_temp(dp) = ∫(-(DAdpf(uh, wconjh, pfh; β, η)) * dp)fem_params.dΩ

```

knowing that

```julia
DAdpf(u, v, pfh; β, η) = ((p->DEdpf(p, β, η)) ∘ pfh) * (ε(v) ⊙ (σfun∘(ε(u))))

```

---

<div class="post-metadata">

**Author:** ![mary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mary/32/53139_2.png) [@mary](https://discourse.julialang.org/u/mary)\
**Post date:** [June 26, 2023, 7:28pm UTC](https://discourse.julialang.org/t/adjoint-method-in-gridap/100529/6 "2023-06-26T19:28:04Z")

</div>

in this case it is assumed that b is independent from p so its derivation is zero. if i have a traction on boundary how can i assemble vector for derivation. DAdp is defined on domain while DbDp for traction and without body force defined on boundary?

```julia
dg/dp=- w^t(dA/dp * u - db/dp)

```

b(v)=(v ⋅ n ⋅ (σfun∘(ε(v)))

```julia
thanks
```

---

<div class="post-metadata">

**Author:** ![mary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mary/32/53139_2.png) [@mary](https://discourse.julialang.org/u/mary)\
**Post date:** [July 19, 2023, 6:00pm UTC](https://discourse.julialang.org/t/adjoint-method-in-gridap/100529/7 "2023-07-19T18:00:38Z")

</div>

@stevengj is there any documents or papers to help me in this wat? as you say if `u^TAv=a(u,v)` however it seems that dor dA, the conjugate of w is going through dA function. Am i right? Also I want to know that if i have real numbers, just w goes through dA?  
thank you

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [July 19, 2023, 6:02pm UTC](https://discourse.julialang.org/t/adjoint-method-in-gridap/100529/8 "2023-07-19T18:02:34Z")

</div>

> [@mary](#):
>
> however it seems that dor dA, the conjugate of w is going through dA function. Am i right? Also I want to know that if i have real numbers, just w goes through dA?

For complex numbers where your weak forms and/or objective functions involve complex conjugatiohn, you apply the adjoint method using CR calculus; there are some tutorials on CR calculus online.

---

<div class="post-metadata">

**Author:** ![mary](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mary/32/53139_2.png) [@mary](https://discourse.julialang.org/u/mary)\
**Post date:** [July 19, 2023, 6:04pm UTC](https://discourse.julialang.org/t/adjoint-method-in-gridap/100529/9 "2023-07-19T18:04:53Z")

</div>

@stevengj what if i dont have complex numbers?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [July 19, 2023, 6:23pm UTC](https://discourse.julialang.org/t/adjoint-method-in-gridap/100529/10 "2023-07-19T18:23:28Z")

</div>

For real numbers, the you can remove the conjugation (it does nothing anyway).
