How to continue (vector calculus) abuse of notation in Julia?

Is there an idiomatic way to get the curl of a symbolic vector field using Symbolics.jl? I’m trying the following

using Symbolics, LinearAlgebra
@variables x y z
@variables A₁(x,y,z) A₂(x,y,z) A₃(x,y,z)
∇ = [Differential(x), Differential(y), Differential(z)]
A = [A₁, A₂, A₃]
∇ × A

But this errors with MethodError: no method matching -(::ComposedFunction{Differential, Num}, ::ComposedFunction{Differential, Num}) since × is understandably a multiplicative operator, so multiplying ∂/∂x to A_x gives Differential(x, 1) ∘ A_x(x, y, z) instead of applying the derivative operator like we’re used to in math. I can get around this by doing some type piracy, mainly, defining

Base.:(*)(D::Differential, x::Num) = D(x)

but I don’t know if there’s a more elegant way without hooking into Base or Symbolics internals.

The above example talks about curls, but really, I want to be able to treat the gradient operator as a “vector” and use it in the same way in math. That is, create a “vector” operator out of any set of Cartesian coordinates in Euclidean space, then apply it to vector fields. For example, I’m also trying the possibility of a primed frame, where:

@variables x′ y′ z′
@variables W₁(x′,y′,z′) W₂(x′,y′,z′) W₃(x′,y′,z′)
∇′ = [Differential(x′), Differential(y′), Differential(z′)]
W = [W₁, W₂, W₃]
∇′ ⋅ W # divergence of W in the primed frame
2 Likes