I would like to calculate

$$ \mathbf T = (\mathbf B \bullet \nabla) \mathbf B$$

Where nabla (the upside down triangle) is the grad operator $(\partial/\partial x,\partial/\partial y,\partial/\partial z)$ and the dot is the divergence operator. This is the magnetic tension force, for those who are interested.

I have a vector

$$ \mathbf B = (B_x, B_y, B_z ) $$

At the moment I break this down into single-dimensional operations, do that for each dimension, then create the $\mathbf T$ vector, but I wanted to know if I could do it using the vector operations that Mathematica offers.

The struggle is that I am doing an operation on an operator, then the latter operator carries out its operation. So, the divergence operation will give us a scaler:

$$ (\mathbf B \bullet \nabla) = (B_x * \partial/\partial x + B_y * \partial/\partial y + B_z * \partial/\partial z)$$

Then for instance in the x dimension:

$$T_x = (B_x * \partial/\partial x + B_y * \partial/\partial y + B_z * \partial/\partial z) B_x = B_x \frac{\partial B_x}{\partial x} + B_y \frac{\partial B_x}{\partial y} + B_z \frac{\partial B_x}{\partial z}$$

So the full vector would be:

$$\mathbf T = (B_x \frac{\partial B_x}{\partial x} + B_y \frac{\partial B_x}{\partial y} + B_z \frac{\partial B_x}{\partial z}, B_x \frac{\partial B_y}{\partial x} + B_y \frac{\partial B_y}{\partial y} + B_z \frac{\partial B_y}{\partial z} , B_x \frac{\partial B_z}{\partial x} + B_y \frac{\partial B_z}{\partial y} + B_z \frac{\partial B_z}{\partial z}) $$

Mathematica offers the following functions Grad[] and Div[]; however, I can't work out how to get them to work in the required fashion.

  • $\begingroup$ Can this help? Is it possible to do vector calculus in Mathematica? Can you show what you have tried so far with Grad and Div that did not work as intended? For instance, why is the result of Grad[{bx[x, y, z], by[x, y, z], bz[x, y, z]}, {x, y, z}] not suitable? $\endgroup$
    – MarcoB
    Commented Jun 8, 2016 at 18:38
  • 1
    $\begingroup$ My vector calculus is rusty, so this may be naive, but consider the following, simpler construct: b = {bx[x], by[y], bz[z]}; b.Grad[b, {x, y, z}], which returns {bx[x] bx'[x], by[y] by'[y], bz[z] bz'[z]}. The elements of this list seem to resemble the expressions you showed for the elements of $\mathbf T$. $\endgroup$
    – MarcoB
    Commented Jun 8, 2016 at 19:31
  • $\begingroup$ That does work, but would be the "wrong" order of operations and wouldn't work if the two Bs were different. I might be wrong, but I don't think you could change the order of the grad operator w.r.t the divergence. Let me have a look through some vector identities to see if I can prove it either way :) $\endgroup$
    – Tomi
    Commented Jun 8, 2016 at 19:38
  • 1
    $\begingroup$ Tomi, I see what you mean. It may be helpful, then, to show a more general form of the operation you want with different vectors, if you are interested in that, together with the expected result that you obtain via the single-dimensional calculation. That way we have a known correct result to compare our attempts to. $\endgroup$
    – MarcoB
    Commented Jun 8, 2016 at 19:46
  • 1
    $\begingroup$ Tomi, thanks for adding the expected results. Again from a naive perspective, consider: b.Transpose@Grad[b, {x, y, z}]. $\endgroup$
    – MarcoB
    Commented Jun 8, 2016 at 21:03

1 Answer 1


Here is a way to do the manipulation. First I define a convenient way to set up vector fields, then I do the dot product and gradient. The main thing is that the application to the vector argument on the right is done element-wise, so that the natural Mathematica operation is Map (/@).

To make the order of operations clearer, I also use two different vector fields:

vec[a_Symbol, r_: {x, y, z}] := 
 Through[Array[Subscript[SymbolName[a], Map[SymbolName, r][[#]]] &, 3] @@ r]

vec[a].Grad[#, {x, y, z}] & /@ vec[b]

$$\left\{\text{a}_{\text{x }}(x,y,z) \text{b}_{\text{x}}{}^{(1,0,0)}(x,y,z)+\text{a}_{\text{y}}(x,y,z) \text{b}_{\text{x}}{}^{(0,1,0)}(x,y,z)+\text{a}_{\text{z }}(x,y,z) \text{b}_{\text{x}}{}^{(0,0,1)}(x,y,z),\text{a}_{\text{x }}(x,y,z) \text{b}_{\text{y}}{}^{(1,0,0)}(x,y,z)+\text{a}_{\text{y }}(x,y,z) \text{b}_{\text{y}}{}^{(0,1,0)}(x,y,z)+\text{a}_{\text{z }}(x,y,z) \text{b}_{\text{y}}{}^{(0,0,1)}(x,y,z),\text{a}_{\text{x }}(x,y,z) \text{b}_{\text{z}}{}^{(1,0,0)}(x,y,z)+\text{a}_{\text{y }}(x,y,z) \text{b}_{\text{z}}{}^{(0,1,0)}(x,y,z)+\text{a}_{\text{z }}(x,y,z) \text{b}_{\text{z}}{}^{(0,0,1)}(x,y,z)\right\}$$

With the function vec, you can specify the set of independent variables as an optional argument. It returns an array in which each entry is labeled by the first argument and by one of the coordinate names in the second argument (whose default is {x,y,z}).

By using Map, we're able to preserve the order of operations exactly the way it was written in the question.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.