Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Roe cleanup #161

Open
wants to merge 5 commits into
base: compute-graph
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion DEC/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ Metatheory = "e9d8d322-4543-424a-9be4-0cc815abe26c"
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
StructEquality = "6ec83bb0-ed9f-11e9-3b4c-2b04cb4e219c"
TermInterface = "8ea1fca8-c5ef-4a55-8b96-4e9afe9c9a3c"

[compat]
CairoMakie = "0.12.5"
Expand All @@ -26,6 +28,5 @@ Decapodes = "0.5.5"
GeometryBasics = "0.4.11"
MLStyle = "0.4.17"
OrdinaryDiffEq = "6.86.0"
Random = "1.11.0"
Reexport = "1.2.2"
StructEquality = "2.1.0"
22 changes: 22 additions & 0 deletions DEC/docs/literate/egraphs.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# This lesson covers the internals of Metatheory.jl-style E-Graphs. Let's reuse the heat_equation model on a new roe.
roe = Roe(DEC.ThDEC.Sort);
function heat_equation(roe)
u = fresh!(roe, PrimalForm(0), :u)

∂ₜ(u) ≐ Δ(u)

([u], [])
end

# We apply the model to the roe and collect its state variables.
(state, _) = heat_equation(roe)

# Recall from the Introduction that an E-Graph is a bipartite graph of ENodes and EClasses. Let's look at the EClasses:
classes = roe.graph.classes
# The keys are Metatheory Id types which store an Id. The values are EClasses, which are implementations of equivalence classes. Nodes which share the same EClass are considered equivalent.



# The constants in Roe are a dictionary of hashes of functions and constants. Let's extract just the values again:
vals = collect(values(e.graph.constants))
# The `u` is ::RootVar{Form} and ∂ₜ, ★, d are all functions defined in ThDEC/signature.jl file.
74 changes: 74 additions & 0 deletions DEC/docs/literate/heatequation.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Load AlgebraicJulia dependencies
using DEC
import DEC.ThDEC: Δ # conflicts with CombinatorialSpaces

# load other dependencies
using ComponentArrays
using CombinatorialSpaces
using GeometryBasics
using OrdinaryDiffEq
Point2D = Point2{Float64}
Point3D = Point3{Float64}
using CairoMakie

## Here we define the 1D heat equation model with one state variable and no parameters. That is, given an e-graph "roe," we define `u` to be a primal 0-form. The root variable carries a reference to the e-graph which it resides in. We then assert that the time derivative of the state is just its Laplacian. We return the state variable.
function heat_equation(roe)
u = fresh!(roe, PrimalForm(0), :u)

∂ₜ(u) ≐ Δ(u)

([u], [])
end

# Since this is a model in the DEC, we need to initialize the primal and dual meshes.
rect = triangulated_grid(100, 100, 1, 1, Point3D);
d_rect = EmbeddedDeltaDualComplex2D{Bool, Float64, Point3D}(rect);
subdivide_duals!(d_rect, Circumcenter());

# Now that we have a dual mesh, we can associate operators in our theory with precomputed matrices from Decapodes.jl.
op_lookup = ThDEC.precompute_matrices(d_rect, DiagonalHodge())

# Now we produce a "vector field" function which, given a model and operators in a theory, returns a function to be passed to the ODESolver. In stages, this function
#
# 1) extracts the Root Variables (state or parameter term) and runs the extractor along the e-graph,
# 2) extracts the derivative terms from the model into an SSA
# 3) yields a function accepting derivative terms, state terms, and parameter terms, whose body is both the lines, and derivatives.
vf = vfield(heat_equation, op_lookup)

# Let's initialize the
U = first.(d_rect[:point]);

# TODO component arrays
constants_and_parameters = ()

# We will run this for 500 timesteps.
t0 = 500.0

@info("Precompiling Solver")
prob = ODEProblem(vf, U, (0, t0), constants_and_parameters);
soln = solve(prob, Tsit5());

## 1-D HEAT EQUATION WITH DIFFUSIVITY

function heat_equation_with_constants(roe)
u = fresh!(roe, PrimalForm(0), :u)
k = fresh!(roe, Scalar(), :k)
ℓ = fresh!(roe, Scalar(), :ℓ)

∂ₜ(u) ≐ k * Δ(u)

([u], [k])
end

# we can reuse the mesh and operator lookup
vf = vfield(heat_equation_with_constants, operator_lookup)

# we can reuse the initial condition U but are specifying diffusivity constants.
constants_and_parameters = ComponentArray(k=0.25,);
t0 = 500

@info("Precompiling solver")
prob = ODEProblem(vf, U, (0, t0), constants_and_parameters);
soln = solve(prob, Tsit5());


52 changes: 52 additions & 0 deletions DEC/docs/literate/tutorial.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# This tutorial is a slower-paced introduction into the design. Here, we will construct a simple exponential model.
using DEC
using Test
using Metatheory.EGraphs
using ComponentArrays
using GeometryBasics
using OrdinaryDiffEq
Point2D = Point2{Float64}
Point3D = Point3{Float64}

using CairoMakie

# We define our model of exponential growth. This model is a function which accepts a Roe and returns a tuple of State and Parameter variables. Let's break it down:
#
# 1. Function adds root variables (::RootVar) to the Roe. The root variables have no child nodes.
# 2. Our model makes claims about what terms equal one another. The "≐" operator is an infix of "equate!" which claims unites the ids of the left and right VecExprs.
# 3. The State and Parameter variables are returned. Each variable points to the same parent Roe.
#
#
# Each variable points to the same Roe.
function exp_growth(roe)
u = fresh!(roe, PrimalForm(0), :u)
k = fresh!(roe, Scalar(), :k)

∂ₜ(u) ≐ k * u

([u], [k])
end

# We now need to initialize the primal and dual meshes we'll need to compute with.
rect = triangulated_grid(100, 100, 1, 1, Point3D);
d_rect = EmbeddedDeltaDualComplex2D{Bool, Float64, Point3D}(rect);
subdivide_duals!(d_rect, Circumcenter());

# For the theory of the DEC, we will need to associate each operator to the precomputed matrix specific to our dual mesh.
operator_lookup = ThDEC.create_dynamic_model(d_rect, DiagonalHodge())

# We now need to convert our model to an ODEProblem. In our case, ``vfield`` produces
vf = vfield(exp_growth, operator_lookup)

U = first.(d_rect[:point]);

constants_and_parameters = ComponentArray(k=-0.5,)

t0 = 50.0

@info("Precompiling Solver")
prob = ODEProblem(vf, U, (0, t0), constants_and_parameters);
soln = solve(prob, Tsit5());

save_dynamics(soln, "decay.gif")

57 changes: 57 additions & 0 deletions DEC/docs/make.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
using Documenter
using Literate
using Distributed

using DEC

using CairoMakie

# Set Literate.jl config if not being compiled on recognized service.
# config = Dict{String,String}()
# if !(haskey(ENV, "GITHUB_ACTIONS") || haskey(ENV, "GITLAB_CI"))
# config["nbviewer_root_url"] = "https://nbviewer.jupyter.org/github/AlgebraicJulia/DEC.jl/blob/gh-pages/dev"
# config["repo_root_url"] = "https://github.com/AlgebraicJulia/Decapodes.jl/blob/main/docs"
# end

const literate_dir = joinpath(@__DIR__, "..", "examples")
const generated_dir = joinpath(@__DIR__, "src", "examples")

@info "Building literate files"
for (root, dirs, files) in walkdir(literate_dir)
out_dir = joinpath(generated_dir, relpath(root, literate_dir))
pmap(files) do file
f,l = splitext(file)
if l == ".jl" && !startswith(f, "_")
Literate.markdown(joinpath(root, file), out_dir;
config=config, documenter=true, credit=false)
Literate.notebook(joinpath(root, file), out_dir;
execute=true, documenter=true, credit=false)
end
end
end
@info "Completed literate"

pages = Any[]
push!(pages, "DEC.jl" => "index.md")
push!(pages, "Library Reference" => "api.md")

@info "Building Documenter.jl docs"
makedocs(
modules = [DEC],
format = Documenter.HTML(
assets = ["assets/analytics.js"],
),
remotes = nothing,
sitename = "DEC.jl",
doctest = false,
checkdocs = :none,
pages = pages)


@info "Deploying docs"
deploydocs(
target = "build",
repo = "github.com/AlgebraicJulia/DEC.jl.git",
branch = "gh-pages",
devbranch = "main"
)
Loading
Loading