Operators & Apply API

This page shows how to construct assembled operators and apply them to fields.

Build Path

From moments:

using CartesianGeometry
using CartesianOperators
using CartesianGeometry: nan

grid = (0.0:0.25:1.0, 0.0:0.25:1.0)
levelset(x, y, _=0) = x + y - 1.0

moms = geometric_moments(levelset, grid, Float64, nan; method=:vofijul)
cap = assembled_capacity(moms; bc=0.0)

Assembled operators:

G, H, Winv, nnodes, D_m, D_p, S_m, S_p = build_GHW(cap)

Convenience wrappers:

ops_diff = DiffusionOps(cap)

For convection/advection:

nt = cap.ntotal
uω = (ones(nt), ones(nt))   # N-direction tuple
uγ = zeros(length(cap.nnodes) * nt)
ops_conv = ConvectionOps(cap, uω, uγ)

Gradient Apply

By definition:

\[q = W^{-1}(Gx^\omega + Hx^\gamma)\]

APIs:

  • gradient(op, xω, xγ) returns combined q
  • gradient(op, xω, xγ; split=true) returns (qω, qγ) where:
    • qω = Winv*(G*xω)
    • qγ = Winv*(H*xγ)
  • gradient!(...) in-place variants are available

Example:

nt = size(ops_diff.G, 2)
xω = rand(nt)
xγ = rand(nt)

q = gradient(ops_diff, xω, xγ)
qω, qγ = gradient(ops_diff, xω, xγ; split=true)

Divergence Apply

By definition:

\[\operatorname{div}(q^\omega, q^\gamma) = -(G^\top + H^\top)q^\omega + H^\top q^\gamma\]

APIs:

  • divergence(op, qω, qγ) returns combined divergence
  • divergence(op, qω, qγ; split=true) returns (d_faces, d_int) where:
    • d_faces = -(G' + H')*qω
    • d_int = H'*qγ
  • divergence!(...) in-place variants are available

Example:

nf = size(ops_diff.G, 1)
qω = rand(nf)
qγ = rand(nf)

d = divergence(ops_diff, qω, qγ)
d_faces, d_int = divergence(ops_diff, qω, qγ; split=true)

Curl Apply (2D)

In 2D, scalar curl uses the rotated-divergence identity:

\[\operatorname{curl}(q_x, q_y) = \operatorname{div}(q_y, -q_x).\]

APIs:

  • curl(op, qω, qγ) returns combined scalar curl on the node lattice
  • curl(op, qω, qγ; split=true) returns (c_faces, c_int) from rotated split divergence
  • curl(op, qω) is shorthand with qγ = 0
  • curl!(out, op, qω, qγ) in-place variant

Sign convention is counter-clockwise positive; negate the result if your application uses clockwise-positive vorticity.

Example:

nf = size(ops_diff.G, 1)
qω = rand(nf)
qγ = rand(nf)

c = curl(ops_diff, qω, qγ)
c_faces, c_int = curl(ops_diff, qω, qγ; split=true)

3D note:

  • exported curl currently throws an informative error in 3D.
  • exact cut-cell 3D curl is planned once dual-edge circulation geometry is introduced.

Advection Operators

advection_ops(cap, uω, uγ; scheme=Centered()|Upwind1(), periodic=...) returns:

  • C[d]: directional transport blocks
  • K[d]: interface-coupling diagonal blocks
  • H, V, nnodes

Use this when assembling convection/advection systems with explicit control over scheme (Centered vs Upwind1) and periodicity.

Boundary Utilities

Useful helpers for higher-level assembly:

  • periodic_flags(bc, N) infer directional periodicity from border conditions
  • side_info(side, N) decode side axis/sign metadata
  • each_boundary_cell(nnodes, side) iterate physical cells touching one box side
  • apply_box_bc_mono!(A, b, cap, ops, D, bc_border; t=..., layout=...) apply box BC contributions to system matrix and RHS