Operators API
Low-level operator algebra and tensor/scalar utilities.
Tensor and Scalar Algebra
LinearAlgebra.:⋅ — Function⋅(A::TensorField, B::TensorField)Element-wise (Hadamard) product followed by summation of all components, yielding a scalar per tensor (i.e., Frobenius inner product).
Returns: ScalarField
⋅(A::Union{VectorField,TensorField}, D::Function)Right contraction with the differential operator. With D == ∇:
- If
AisVectorField: returnsdiv(A)(scalar field). - If
AisTensorField: returnsdiv(A)(vector field).
Returns: ScalarField or VectorField
Examples
# 3D (assumes `problem` and a "body" physical group are defined)
V = vectorField(problem, [field("body", fx=x->x, fy=y->y, fz=z->z)])
divV = V ⋅ ∇ # ScalarField⋅(D::Function, A::Union{VectorField,TensorField})Left contraction with the differential operator. With D == ∇:
- If
AisVectorField: returnsdiv(A). - If
AisTensorField: returnsdiv(A').
Returns: ScalarField or VectorField
Examples
# 3D (assumes `problem` and a "body" physical group are defined)
T = tensorField(problem, [field("body", fz=z->z)])
DV = ∇ ⋅ T # VectorField (divergence of tensor)LowLevelFEM.unitTensor — FunctionunitTensor(A::TensorField)Creates an identity tensor field (I) with the same element structure and time steps as A.
Returns: TensorField
LowLevelFEM.trace — Functiontrace(A::TensorField)Computes the trace of each 3×3 tensor block.
Returns: ScalarField
LowLevelFEM.mapScalarField — FunctionmapScalarField(f, A::ScalarField)Apply a function elementwise to a scalar field.
The function f is applied to each element-wise matrix of the scalar field. If the field is nodal, it is first converted to elementwise form.
This is a low-level helper used to implement elementwise scalar-field operations such as abs, +, -, log, sqrt, etc.
Returns
- A new
ScalarFieldcontaining the transformed values.
Differential Operators
LowLevelFEM.∇ — Function∇(r::Union{VectorField, ScalarField, TensorField}; nabla=:grad)Computes derivatives of r.
- If
ris aScalarFieldandnabla == :grad, returns the gradient (aVectorField). - If
ris aVectorFieldandnabla == :grad, returns the gradient (aTensorField). - If
ris aVectorFieldandnabla == :curl, returns the curl (aVectorField). - If
ris aVectorFieldandnabla == :div, returns the divergence (aScalarField). - If
ris aTensorFieldandnabla == :div, returns the divergence (aVectorField).
Returns: ScalarField, VectorField, or TensorField
Types:
r:ScalarField,VectorField, orTensorFieldnabla: Symbol
3D Examples (assumes problem is set as in the ∇ doc setup)
# One-time 3D setup (assumes examples/Fields/cube.geo exists with physical group "body")
using LowLevelFEM
gmsh.initialize()
gmsh.open("examples/Fields/cube.geo")
mat = material("body", E=210e3, ν=0.3, ρ=7.85e-9)
problem = Problem([mat], type=:Solid)
# 1) Gradient of a 3D scalar field: ∇f → VectorField
f(X,Y,Z) = X^2 + Y*Z
S = scalarField(problem, [field("body", f=f)])
G = ∇(S) # VectorField with 3 components
# 2) Curl of a 3D vector field: ∇ × v → VectorField
vx(X,Y,Z) = 0
vy(X,Y,Z) = X
vz(X,Y,Z) = 0
V = vectorField(problem, [field("body", fx=vx, fy=vy, fz=vz)])
C = ∇(V, nabla=:curl) # approx (0, 0, 1) everywhere
# 3) Divergence of a 3D vector field: ∇ ⋅ v → ScalarField
v1(X,Y,Z) = X
v2(X,Y,Z) = Y
v3(X,Y,Z) = Z
V2 = vectorField(problem, [field("body", fx=v1, fy=v2, fz=v3)])
D = ∇(V2, nabla=:div) # ≈ 3
# 4) Divergence of a 3D tensor field: ∇ · T → VectorField (if T is TensorField)
# For example, a diagonal tensor T with only Tzz = g(Z): div(T) = (0, 0, ∂g/∂Z)
g(Z) = 10 - Z
T = tensorField(problem, [field("body", fz=g)])
DV = ∇(T, nabla=:div) # VectorField
# Symmetric displacement gradient via operators
# A = (u ∘ ∇ + ∇ ∘ u) / 2
gmsh.finalize()LowLevelFEM.grad — Functiongrad(r::Union{ScalarField,VectorField})Solves the gradient of the scalar field or vector field r. An alternative way to solve grad is to use ∇ as a differencial operator.
Return: VectorField or TensorField
Types:
r: ScalarField or VectorField
3D Examples
# Assumes a 3D mesh with physical group "body".
# 1) Gradient of a 3D scalar field → VectorField
f(X,Y,Z) = X^2 + Y*Z
S = scalarField(problem, [field("body", f=f)])
G1 = grad(S)
G2 = ∇(S)
# 2) Gradient of a 3D vector field → TensorField
vx(X,Y,Z) = X
vy(X,Y,Z) = Y
vz(X,Y,Z) = Z
V = vectorField(problem, [field("body", fx=vx, fy=vy, fz=vz)])
T1 = grad(V)
T2 = V ∘ ∇LowLevelFEM.curl — Functioncurl(r::VectorField)Solves the rotation of the vector field r. An alternative way to solve curl is to use ∇ as a differencial operator.
Return: VectorField
Types:
r: VectorField
3D Example (assumes problem is set as in the ∇ doc setup)
# Assumes a 3D mesh with physical group "body".
vx(X, Y, Z) = 0
vy(X, Y, Z) = X
vz(X, Y, Z) = 0
v = vectorField(problem, [field("body", fx=vx, fy=vy, fz=vz)])
D1 = curl(v)
D2 = ∇ × vLowLevelFEM.rot — Functionrot(r::VectorField)Solves the rotation of the vector field r. In some countries "rot" denotes the English "curl". (See the curl function.)
Return: VectorField
Types:
r: VectorField