Skip to main content

Curl

SPH curl of a vector field. Kernel: coreOperations/wp_curl.py (computeSPHCurlTensor_Kernel); JVP coreOperations/wp_curlJVP.py.

Equation​

(∇×f)i  =  ∑j∈N(i)curlProduct(coeffij, ∇Wij),(\nabla\times\mathbf{f})_i \;=\; \sum_{j \in \mathcal{N}(i)} \mathrm{curlProduct}(\mathrm{coeff}_{ij},\, \nabla W_{ij}),

with coeffij\mathrm{coeff}_{ij} from the same Gradient coefficient table (Naive / Symmetric / Difference / Summation, apparent volume VjV_j, grad-h rescaling) and the same CRK-then-renormalized kernel gradient GijG_{ij}. curlProduct (math/wp_cross.py) applies the per-dimension curl operator to the coefficient:

  • 2D — scalar output, the zz-component of the 3D curl: \left(G_{ij,x}\,\mathrm{coeff}_{ij,y} - G_{ij,y}\,\mathrm{coeff}_{ij,x}\right),$$
  • 3D — vector output, the standard right-hand-rule cross product (c×∇Wij)(\mathbf{c}\times\nabla W_{ij}) per field block. (An earlier implementation negated the 3D result; the negation was confirmed to be a bug and removed — see math/wp_cross.py's own note and warpier_core.md),
  • 1D — the curl is identically zero; the output is a scalar.

Output shape: 2D: [N, 1] (a vector field collapses to the scalar zz-component); 3D: inputShape (a vector field stays a vector); 1D: [N].

Public API​

warpOperation(
queryParticles, operationProperties, domain,
queryValues=f, referenceValues=f, # required, vector fields
queryVolumes=None, referenceVolumes=None,
crkState=None, gradHState=None, renormalizationState=None,
adjacency=None,
)

with operation == WarpOperation.Curl.

OptionDefaultEffect
gradientModeNaivecoefficient scheme (same table as Gradient)
supportMode / operationMode / corrections / calibration—as in Gradient

There is no consistentDivergence or dot-mode analogue for Curl.

JVP / HVP​

Value JVP — relaunch-on-tangents identity, as usual (tests/operations/test_forward_mode_value_jvp.py).

Geometry JVP — 2D only. The product rule expanded through the 2D cross:

d(∇×f)i=∑j[Gx dcoeffy−Gy dcoeffx+dGx coeffy−dGy coeffx]+∑j(Gx (dfiAij+dfjBij)y−Gy (dfiAij+dfjBij)x)⏟value-tangent term, fused,d(\nabla\times\mathbf{f})_i = \sum_j \Big[ G_x\, d\mathrm{coeff}_y - G_y\, d\mathrm{coeff}_x + dG_x\, \mathrm{coeff}_y - dG_y\, \mathrm{coeff}_x \Big] + \underbrace{\sum_j \left(G_x\, (df_i A_{ij} + df_j B_{ij})_y - G_y\, (df_i A_{ij} + df_j B_{ij})_x\right)}_{\text{value-tangent term, fused}},

with the same A/BA/B weights and G/dGG/dG chain as Gradient. warpOperationJVP rejects domain.dim != 2 for Curl (1D and 3D are both undecided by the underlying derivation spike); the same CRK/renorm-tangent, grad-h-unsupported, and query-mass-rejected rules as Gradient apply. The kernel produces a scalar per query particle internally; the torch-level entry point unsqueezes to [nQuery, 1].

Gated by tests/operations/test_forward_mode_geometry_jvp_curl.py.

No HVP exists for Curl.

Tests​

  • tests/operations/test_operations_core.py — shape/finiteness.
  • tests/operations/test_forward_mode_value_jvp.py — value-JVP identity.
  • tests/operations/test_forward_mode_geometry_jvp_curl.py — 2D geometry JVP vs reverse-mode Jacobian, including CRK/renorm correction tangents.
  • tests/operations/test_grid_modes.py — adjacency vs grid traversal parity.

See also​

Gradient · Divergence · Laplacian