Skip to content

Commit 6c29679

Browse files
committed
WIP: tests; endpoint script->funct; remove intermediate var
1 parent b9eb474 commit 6c29679

File tree

26 files changed

+1295
-1246
lines changed

26 files changed

+1295
-1246
lines changed
Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,43 @@
11
name = "CatColabInterop"
22
uuid = "9ecda8fb-39ab-46a2-a496-7285fa6368c1"
33
license = "MIT"
4-
version = "0.1.1"
54
authors = ["CatColab team"]
5+
version = "0.1.1"
66

77
[deps]
88
HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
9+
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
910
MLStyle = "d8e11817-5142-5d16-987a-aa16d5891078"
1011
Oxygen = "df9a0d86-3283-4920-82dc-4555fc0d1d8b"
1112
Reexport = "189a3867-3050-52da-a836-e630ba90ab69"
1213
StructTypes = "856f2bd8-1eba-4b0a-8007-ebc267875bd4"
14+
TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
1315

1416
[weakdeps]
1517
ACSets = "227ef7b5-1206-438b-ac65-934d6da304b8"
1618
Catlab = "134e5e36-593f-5add-ad60-77f754baafbe"
19+
CombinatorialSpaces = "b1c52339-7909-45ad-8b6a-6e388f7c67f2"
20+
ComponentArrays = "b0b7db55-cfe3-40fc-9ded-d10e2dbeff66"
21+
CoordRefSystems = "b46f11dc-f210-4604-bfba-323c1ec968cb"
22+
Decapodes = "679ab3ea-c928-4fe6-8d59-fd451142d391"
23+
DiagrammaticEquations = "6f00c28b-6bed-4403-80fa-30e0dc12f317"
24+
Distributions = "31c24e10-a181-5473-b8eb-7969acd0382f"
25+
GeometryBasics = "5c1252a2-5f33-56bf-86c9-59e7332b4326"
26+
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
27+
OrdinaryDiffEq = "1dea7af3-3e70-54e6-95c3-0bf5283fa5ed"
28+
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
1729

1830
[extensions]
1931
CatlabExt = ["Catlab", "ACSets"]
32+
DecapodesExt = ["DiagrammaticEquations", "Decapodes", "ACSets", "CombinatorialSpaces", "JSON3", "StaticArrays", "LinearAlgebra", "ComponentArrays", "Distributions", "CoordRefSystems", "GeometryBasics", "OrdinaryDiffEq"]
2033

2134
[compat]
22-
Catlab = "0.17.2"
35+
Catlab = "0.17.3"
2336
HTTP = "1.10.19"
37+
JSON3 = "1.14.3"
2438
MLStyle = "0.4.17"
2539
Oxygen = "1.7.5"
2640
Reexport = "1.2.2"
2741
StructTypes = "1.11.0"
42+
TOML = "1.0.3"
2843
julia = "1.11"

packages/algjulia-interop/ext/decapodes-service/DecapodesService.jl renamed to packages/algjulia-interop/ext/DecapodesExt/DecapodesExt.jl

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module DecapodesService
1+
module DecapodesExt
22

33
import Base: run
44

@@ -24,32 +24,42 @@ Point3D = Point3{Float64}
2424
# simulation
2525
using OrdinaryDiffEq
2626

27-
using ..CatColabInterop
28-
using ..CatColabInterop: AlgebraicJuliaIntegration, AbstractDiagram, AbstractAnalysis
29-
import ..CatColabInterop: Model, ObGenerator, MorGenerator, DiagramObGenerator, DiagramMorGenerator
27+
28+
using CatColabInterop, Oxygen, HTTP
29+
import CatColabInterop: Model, ModelDiagram, ObGenerator, MorGenerator, DiagramObGenerator, DiagramMorGenerator
30+
import CatColabInterop: endpoint
3031

3132
# necessary to export
3233
export infer_types!, evalsim, default_dec_generate, default_dec_matrix_generate, DiagonalHodge, ComponentArray
3334

34-
struct ThDecapode <: AlgebraicJuliaIntegration end
35-
export ThDecapode
35+
include("interop.jl")
3636

3737
# functions for geometry and initial conditions
3838
include("geometry.jl")
3939

40-
# responsible for constructing a valid model
41-
include("model.jl")
42-
4340
# helper functions for Navier-Stokes
4441
include("ns_helper.jl")
4542

4643
# constructing initial conditions
4744
include("initial_conditions.jl")
4845

49-
# parses a payload to a valid analysis
50-
include("parse.jl")
46+
# constructs a simulation from the payload
47+
include("simulation.jl")
5148

5249
# executes the analysis
5350
include("execute.jl")
5451

52+
"""
53+
"""
54+
function endpoint(::Val{:DecapodeSimulation})
55+
@post "/decapodes-simulation" function(req::HTTP.Request)
56+
payload = json(req, ModelDiagrma)
57+
simulation = DecapodesSimulation(payload)
58+
sim = evalsim(simulation.pode)
59+
f = sim(simulation.geometry.dualmesh, simulation.generate, DiagonalHodge())
60+
res = run(f, simulation, ComponentArray(k=0.5,))
61+
sim_to_json(res)
62+
end
63+
end
64+
5565
end

packages/algjulia-interop/ext/decapodes-service/execute.jl renamed to packages/algjulia-interop/ext/DecapodesExt/execute.jl

File renamed without changes.

packages/algjulia-interop/ext/decapodes-service/geometry.jl renamed to packages/algjulia-interop/ext/DecapodesExt/geometry.jl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,11 +83,16 @@ function Geometry(json_object::AbstractDict)
8383
Geometry(domain)
8484
end
8585

86-
function Geometry(payload::DiagramPayload{ThDecapode})
87-
domain = PREDEFINED_MESHES[Symbol(payload.data[:mesh])]
86+
function Geometry(analysis::Analysis)
87+
domain = PREDEFINED_MESHES[Symbol(analysis.analysis[:mesh])]
8888
Geometry(domain)
8989
end
9090

91+
# function Geometry(payload::DiagramPayload{ThDecapode})
92+
# domain = PREDEFINED_MESHES[Symbol(payload.data[:mesh])]
93+
# Geometry(domain)
94+
# end
95+
9196
# function Geometry(d::Domain, args...)
9297
# throw(ImplError("The mesh ($(d)) is"))
9398
# end

packages/algjulia-interop/ext/decapodes-service/initial_conditions.jl renamed to packages/algjulia-interop/ext/DecapodesExt/initial_conditions.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ end
8080

8181
function initial_conditions(ics::GaussianIC, geometry::Geometry)
8282
c_dist = MvNormal(ics.ξ)
83-
c = [pdf(c_dist, [p[1], p[2]]) for p geometry.dualmesh[:point]]
83+
c = [Distributions.pdf(c_dist, [p[1], p[2]]) for p geometry.dualmesh[:point]]
8484
return c
8585
end
8686

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
# TODO change to Analysis
2+
3+
@kwdef mutable struct DecapodeDiagram
4+
pode::SummationDecapode = SummationDecapode(parse_decapode(quote end))
5+
scalars::Dict{Symbol, String} = Dict{Symbol, String}()
6+
vars::Dict{String, Int} = Dict{String, Int}()
7+
nc::Dict{Int, String} = Dict{Int, String}()
8+
end
9+
10+
function Base.push!(diagram::DecapodeDiagram, analysis::Analysis, ob::DiagramObGenerator)
11+
model_elem = only(filter(x->x.id==ob.over.content, analysis.model.obGenerators))
12+
name = if isempty(ob.label)
13+
id = isempty(keys(diagram.nc)) ? 1 : maximum(keys(diagram.mc)) + 1
14+
push!(diagram.nc, id => "")
15+
Symbol("$id")
16+
else
17+
Symbol(join(string.(ob.label),"."))
18+
end
19+
id = add_part!(diagram.pode, :Var, name=name, type=nameof(model_elem))
20+
push!(diagram.vars, ob.id => id)
21+
diagram
22+
end
23+
24+
# TODO remove only when we have multiple source/targets
25+
function mor_dom(diagram::Diagram, mor::DiagramMorGenerator)
26+
filter(ob -> ob.id == mor.dom.content, diagram.obGenerators) |> only
27+
end
28+
29+
function mor_cod(diagram::Diagram, mor::DiagramMorGenerator)
30+
filter(ob -> ob.id == mor.dom.content, diagram.obGenerators) |> only
31+
end
32+
33+
function Base.nameof(model::Model, mor::DiagramMorGenerator)
34+
model_mor = filter(m -> m.id == mor.over.content, model.morGenerators) |> only
35+
join(model_mor.label, ".") # TODO
36+
end
37+
38+
function Base.push!(diagram::DecapodeDiagram, analysis::Analysis, mor::DiagramMorGenerator)
39+
dom = mor_dom(analysis.diagram, mor) # get ObGenerator
40+
cod = mor_cod(analysis.diagram, mor)
41+
dom_id = check_endpoint!(diagram, dom)
42+
cod_id = check_endpoint!(diagram, cod)
43+
# get the name of the Op1 and add it to the model
44+
op1 = nameof(analysis.model, mor)
45+
add_part!(diagram.pode, :Op1, src=dom_id, tgt=cod_id, op1=op1)
46+
if op1 == :∂ₜ
47+
add_part!(diagram.pode, :TVar, incl=cod_id)
48+
end
49+
if mor.morType.content isa JSON3.Object
50+
scalar = analysis.model.mor_generators[mor.over.content]
51+
push!(diagram.scalars, scalar.label => mor.over.content)
52+
end
53+
diagram
54+
end
55+
56+
function DecapodeDiagram(analysis::Analysis)
57+
diagram = DecapodeDiagram()
58+
for ob in analysis.diagram.obGenerators
59+
push!(diagram, analysis, ob)
60+
end
61+
for mor in analysis.diagram.morGenerators
62+
push!(diagram, analysis, mor)
63+
end
64+
return diagram
65+
end
66+
67+
function check_endpoint!(diagram::DecapodeDiagram, endpoint::DiagramObGenerator)
68+
if haskey(diagram.vars, endpoint.id)
69+
diagram.vars[endpoint.id]
70+
else
71+
if endpoint.id values(diagram.nc)
72+
id = isempty(keys(diagram.nc)) ? 1 : length(keys(diagram.nc)) + 1
73+
name = Symbol("$id")
74+
acset_id = add_part!(diagram.pode, :Var, name=name, type=:infer)
75+
push!(diagram.nc, acset_id => endpoint.label)
76+
acset_id
77+
else
78+
out = filter(x -> x[2] == endpoint, pairs(diagram.nc))
79+
first(keys(out))
80+
end
81+
end
82+
end
83+
84+
function uuid_to_symb(decapode::SummationDecapode, vars::Dict{String, Int})
85+
Dict([key => (subpart(decapode, vars[key], :name)) for key keys(vars)])
86+
end

packages/algjulia-interop/ext/decapodes-service/model.jl renamed to packages/algjulia-interop/ext/DecapodesExt/model.jl

File renamed without changes.

packages/algjulia-interop/ext/decapodes-service/ns_helper.jl renamed to packages/algjulia-interop/ext/DecapodesExt/ns_helper.jl

File renamed without changes.
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# =======================================================================
2+
3+
""" DecapodeSimulation
4+
5+
This analysis contains the data necessary to execute a simulation.
6+
"""
7+
struct DecapodeSimulation
8+
pode::SummationDecapode
9+
plotVariables::Dict{String, Bool}
10+
scalars::Dict{Symbol, Any} # closures
11+
geometry::Geometry
12+
init::ComponentArray
13+
generate::Any
14+
uuiddict::Dict{Symbol, String}
15+
duration::Int
16+
end
17+
export DecapodeSimulation
18+
19+
function DecapodeSimulation(path::String; kwargs...)
20+
payload = JSON3.read(path, Analysis)
21+
DecapodeSimulation(payload; kwargs...)
22+
end
23+
24+
# TODO we need to amend this so other parameters are provided
25+
function DecapodeSimulation(analysis::Analysis; hodge=GeometricHodge())
26+
wrapped = DecapodeDiagram(analysis)
27+
plotVars = @match analysis.analysis[:plotVariables] begin
28+
vars::AbstractArray => Dict{String, Bool}(key => key vars for key keys(wrapped.vars))
29+
vars => Dict{String, Bool}( "$key" => var for (key, var) in vars) # TODO
30+
end
31+
dot_rename!(wrapped.pode)
32+
uuid2symb = uuid_to_symb(wrapped.pode, wrapped.vars)
33+
geometry = Geometry(analysis)
34+
♭♯_m = ♭♯_mat(geometry.dualmesh)
35+
wedge_dp10 = dec_wedge_product_dp(Tuple{1,0}, geometry.dualmesh)
36+
dual_d1_m = dec_dual_derivative(1, geometry.dualmesh)
37+
star0_inv_m = dec_inv_hodge_star(0, geometry.dualmesh, hodge)
38+
Δ0 = Δ(0,geometry.dualmesh)
39+
#fΔ0 = factorize(Δ0);
40+
function sys_generate(s, my_symbol)
41+
op = @match my_symbol begin
42+
sym && if haskey(wrapped.scalars, sym) end => x -> begin
43+
k = scalars[wrapped.scalars[sym]]
44+
k * x
45+
end
46+
:♭♯ => x -> ♭♯_m * x
47+
:dpsw => x -> wedge_dp10(x, star0_inv_m*(dual_d1_m*x))
48+
:Δ⁻¹ => x -> begin
49+
y = Δ0 \ x
50+
y .- minimum(y)
51+
end
52+
_ => default_dec_matrix_generate(s, my_symbol, hodge)
53+
end
54+
return (args...) -> op(args...)
55+
end
56+
#
57+
@info analysis.analysis[:initialConditions]
58+
u0 = initial_conditions(analysis.analysis[:initialConditions], geometry, uuid2symb)
59+
60+
# reversing `uuid2symb` into `symbol => uuid.` we need this to reassociate the var to its UUID
61+
symb2uuid = Dict([v => k for (k,v) in pairs(uuid2symb)])
62+
63+
# TODO what is anons doing here?
64+
anons = Dict{Symbol, Any}()
65+
DecapodeSimulation(wrapped.pode, plotVars, wrapped.scalars, geometry, u0, sys_generate, symb2uuid, analysis.analysis[:duration])
66+
end
67+
68+
Base.show(io::IO, system::DecapodeSimulation) = println(io, system.pode)
69+
70+

0 commit comments

Comments
 (0)