Skip to content

Commit

Permalink
added spaces to the sorts of forms and vector fields
Browse files Browse the repository at this point in the history
  • Loading branch information
olynch committed Aug 16, 2024
1 parent c2d64b5 commit c11d4dd
Showing 1 changed file with 70 additions and 33 deletions.
103 changes: 70 additions & 33 deletions src/ThDEC.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,38 +7,64 @@ struct SortError <: Exception
message::String
end

@struct_hash_equal struct Space
name::Symbol
dim::Int
end

dim(s::Space) = s.dim
nameof(s::Space) = s.name

struct SpaceLookup
default::Space
named::Dict{Symbol,Space}
end

@data Sort begin
Scalar()
Form(dim::Int, isdual::Bool)
VField(isdual::Bool)
Form(dim::Int, isdual::Bool, space::Space)
VField(isdual::Bool, space::Space)
end
export Sort, Scalar, Form, VField

const SORT_LOOKUP = Dict(
:Form0 => Form(0, false),
:Form1 => Form(1, false),
:Form2 => Form(2, false),
:DualForm0 => Form(0, true),
:DualForm1 => Form(1, true),
:DualForm2 => Form(2, true),
:Constant => Scalar()
)
function fromexpr(lookup::SpaceLookup, e, ::Type{Sort})
(name, spacename) = @match e begin
name::Symbol => (name, nothing)
:(Form0{$})
end
space = @match spacename begin
::Nothing => lookup.default
name::Symbol => lookup.named[name]
end
@match name begin
:Form0 => Form(0, false, space),
:Form1 => Form(1, false, space),
:Form2 => Form(2, false, space),
:DualForm0 => Form(0, true, space),
:DualForm1 => Form(1, true, space),
:DualForm2 => Form(2, true, space),
:Constant => Scalar()
end
end

function Base.nameof(s::Scalar)
:Constant
end

function Base.nameof(f::Form)
dual = isdual(f) ? "Dual" : ""
Symbol("$(dual)Form$(dim(f))")
formname = Symbol("$(dual)Form$(dim(f))")
Expr(:curly, formname, dim(space(f)))
end

const VF = VField

dim::Form) = ω.dim
isdual::Form) = ω.isdual
space::Form) = ω.space

isdual(v::VField) = v.isdual
space(v::VField) = v.space

# convenience functions
PrimalForm(i::Int) = Form(i, false)
Expand All @@ -60,17 +86,23 @@ function Base.show(io::IO, ω::Form)
print(io, isdual(ω) ? "DualForm($(dim(ω)))" : "PrimalForm($(dim(ω)))")
end

# TODO: VField
@nospecialize
function +(s1::Sort, s2::Sort)
@match (s1, s2) begin
(Scalar(), Scalar()) => Scalar()
(Scalar(), Form(i, isdual)) ||
(Form(i, isdual), Scalar()) => Form(i, isdual)
(Form(i1, isdual1), Form(i2, isdual2)) =>
if (i1 == i2) && (isdual1 == isdual2)
(Scalar(), Form(i, isdual, space)) ||
(Form(i, isdual, space), Scalar()) => Form(i, isdual, space)
(Form(i1, isdual1, space2), Form(i2, isdual2, space2)) =>
if (i1 == i2) && (isdual1 == isdual2) && (space1 == space2)
Form(i1, isdual1)
else
throw(SortError("Cannot add two forms of different dimensions/dualities: $((i1,isdual1)) and $((i2,isdual2))"))
throw(SortError(
"""
Can not add two forms of different dimensions/dualities/spaces:
$((i1,isdual1,space1)) and $((i2,isdual2,space2))
""")
)
end
end
end
Expand All @@ -83,13 +115,15 @@ end
# Negation is always valid
-(s::Sort) = s

# TODO: VField
@nospecialize
function *(s1::Sort, s2::Sort)
@match (s1, s2) begin
(Scalar(), Scalar()) => Scalar()
(Scalar(), Form(i, isdual)) ||
(Form(i, isdual), Scalar()) => Form(i, isdual)
(Form(_, _), Form(_, _)) => throw(SortError("Cannot scalar multiply a form with a form. Maybe try `∧`??"))
(Scalar(), Form(i, isdual, space)) ||
(Form(i, isdual, space), Scalar()) => Form(i, isdual)
(Form(_, _, _), Form(_, _, _)) =>
throw(SortError("Cannot scalar multiply a form with a form. Maybe try `∧`??"))
end
end

Expand All @@ -99,17 +133,20 @@ function as_sub(n::Int)
join(map(d -> SUBSCRIPT_DIGIT_0 + d, digits(n)))
end

# TODO: VField
@nospecialize
function (s1::Sort, s2::Sort)
@match (s1, s2) begin
(Form(i, isdual), Scalar()) || (Scalar(), Form(i, isdual)) => Form(i, isdual)
(Form(i1, isdual), Form(i2, isdual)) =>
if i1 + i2 <= 2
Form(i1 + i2, isdual)
(Form(i, isdual, space), Scalar()) || (Scalar(), Form(i, isdual, space)) =>
Form(i, isdual, space)
(Form(i1, isdual, space), Form(i2, isdual, space)) => begin
if i1 + i2 <= dim(space)
Form(i1 + i2, isdual, space)
else
throw(SortError("Can only take a wedge product when the dimensions of the forms add to less than 2: tried to wedge product $i1 and $i2"))
end
_ => throw(SortError("Can only take a wedge product of two forms of the same duality"))
end
_ => throw(SortError("Can only take a wedge product of two forms of the same duality on the same space"))
end
end

Expand All @@ -124,11 +161,11 @@ end
function d(s::Sort)
@match s begin
Scalar() => throw(SortError("Cannot take exterior derivative of a scalar"))
Form(i, isdual) =>
if i <= 1
Form(i + 1, isdual)
Form(i, isdual, space) =>
if i < dim(space)
Form(i + 1, isdual, space)
else
throw(SortError("Cannot take exterior derivative of a n-form for n >= 1"))
throw(SortError("Cannot take exterior derivative of a k-form for k >= n, where n = $(dim(space)) is the dimension of its ambient space"))
end
end
end
Expand All @@ -141,13 +178,13 @@ end
function (s::Sort)
@match s begin
Scalar() => throw(SortError("Cannot take Hodge star of a scalar"))
Form(i, isdual) => Form(2 - i, !isdual)
Form(i, isdual, space) => Form(dim(space) - i, !isdual, space)
end
end

function Base.nameof(::typeof(★), s)
inv = isdual(s) ? "⁻¹" : ""
Symbol("$(as_sub(isdual(s) ? 2 - dim(s) : dim(s)))$(inv)")
Symbol("$(as_sub(isdual(s) ? dim(space(s)) - dim(s) : dim(s)))$(inv)")
end

@nospecialize
Expand Down Expand Up @@ -183,15 +220,15 @@ end

function ♭♯(s::Sort)
@match s begin
Form(i, isdual) => Form(i, !isdual)
Form(i, isdual, space) => Form(i, !isdual, space)
_ => throw(SortError("♭♯ is only defined on forms."))
end
end

# Δ = ★d⋆d, but we check signature here to throw a more helpful error
function Δ(s::Sort)
@match s begin
Form(0, isdual) => Form(0, isdual)
Form(0, isdual, space) => Form(0, isdual, space)
_ => throw(SortError("Δ is not defined for $s"))
end
end
Expand Down

0 comments on commit c11d4dd

Please sign in to comment.