I'm attempting to calculate symbolic expressions for the (Newton's method) Jacobian of a Galerkin finite element method using Mathematica. It would seem that this is a perfect application for symbolic differentiation tools but I can't get it working (probably due to my lack of Mathematica knowledge).
Mathematical statement of the problem
Let $v(\mathbf{x})$ and $\psi_k(\mathbf{x})$ ($k=1,\ldots,N$) be simple(ish) polynomial functions of space. Let $\mathbf{m}(\mathbf{x}) = [m_1(\mathbf{x}),m_2(\mathbf{x}),m_3(\mathbf{x})] $ be a vector field.
Let $$ \mathbf{m}(\mathbf{x}) = \sum_{k=1}^N \psi_k(\mathbf{x}) \mathbf{m}_k, $$ and $$ r(\mathbf{x}) = \int_V (\mathbf{m} \times \nabla^2 \mathbf{m}) v(\mathbf{x}) dV. $$
(I have used $\nabla^2$ as the vector Laplacian $ \nabla^2 \mathbf{m} = [ \nabla^2 m_1, \nabla^2 m_2, \nabla^2 m_3]. $)
Calculate $\frac{\partial r}{\partial m_{i,k}}$ for all $i$ (directions of $\mathbf{m}$), and all $k \in {1,\ldots,N}$ (index for the $\psi$ functions).
My code
I'm sure this can be written much more elegantly but as I said before I'm not too great with Mathematica. Anyway it should be good enough to give you the idea.
psi[x_, y_, z_] := {a[x, y, z], b[x, y, z]};
(* Really we just need to declare that this is a vector somehow...*)
m[x_, y_, z_] := {m1x*psi[x, y, z][[1]] + m2x*psi[x, y, z][[2]],
m1y*psi[x, y, z][[1]] + m2y*psi[x, y, z][[2]],
m1z*psi[x, y, z][[1]] + m2z*psi[x, y, z][[2]]}
VectorLaplacian[f[x,y,z]_] := {
D[f[x,y,z][[1]], {x, 2}] + D[f[x,y,z][[1]], {y, 2}] + D[f[x,y,z][[1]], {z, 2}],
D[f[x,y,z][[2]], {x, 2}] + D[f[x,y,z][[2]], {y, 2}] + D[f[x,y,z][[2]], {z, 2}],
D[f[x,y,z][[3]], {x, 2}] + D[f[x,y,z][[3]], {y, 2}] + D[f[x,y,z][[3]], {z, 2}]
}
r[x_, y_, z_] := (Cross[m[x, y, z], VectorLaplacian[m[x, y, z]]])*v[x,y,z]
(* I've left out the integration for now to keep things simpler *)
J[x_, y_, z_] := {
{D[r[x,y,z][[1]], m1x], D[r[x,y,z][[2]], m1x], D[r[x,y,z][[3]], m1x]},
{D[r[x,y,z][[1]], m1y], D[r[x,y,z][[2]], m1y], D[r[x,y,z][[3]], m1y]},
{D[r[x,y,z][[1]], m1z], D[r[x,y,z][[2]], m1z], D[r[x,y,z][[3]], m1z]},
{D[r[x,y,z][[1]], m2x], D[r[x,y,z][[2]], m2x], D[r[x,y,z][[3]], m2x]},
{D[r[x,y,z][[1]], m2y], D[r[x,y,z][[2]], m2y], D[r[x,y,z][[3]], m2y]},
{D[r[x,y,z][[1]], m2z], D[r[x,y,z][[2]], m2z], D[r[x,y,z][[3]], m2z]}
}
J[1, 1, 1]
But all I get is:
{{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}}
VectorLaplacian
is not quite right. You may want to define a function and then test it to see if it works. e.g. evaluateVectorLaplacian[m[x, y, z]]
to see that it does what you want. $\endgroup$