Skip to content

Commit

Permalink
Added steadystates dictionary keyword to collate (#83)
Browse files Browse the repository at this point in the history
Co-authored-by: Luke Morris <[email protected]>
Co-authored-by: Luke Morris <[email protected]>
  • Loading branch information
3 people authored Oct 28, 2024
1 parent e36dbd0 commit d4553b8
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 10 deletions.
24 changes: 14 additions & 10 deletions src/collages.jl
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,15 @@ end
collate(c::Collage) = collate(c.src, c.tgt, c.uwd, c.symbols)

# TODO: This is assuming only "restriction"-type morphisms.
""" function collate(equations, boundaries, uwd, symbols)
""" function collate(equations, boundaries, uwd, symbols; restrictions::Vector{Symbol})
Create a collage of two Decapodes that simulates with boundary conditions.
```
Passing a list of symbols into `restrictions` specifies a list of boundary variables that will be restricted.
"""
function collate(equations, boundaries, uwd, symbols)
function collate(equations, boundaries, uwd, symbols;
restrictions::Dict{Symbol,Symbol}=Dict{Symbol,Symbol}())
f = SummationDecapode{Any, Any, Symbol}()
copy_parts!(f, equations, (:Var, :TVar, :Op1, :Op2, , :Summand))
for b in boxes(uwd)
Expand All @@ -28,9 +31,6 @@ function collate(equations, boundaries, uwd, symbols)
var = only(incident(f, en, :name))
en_type = equations[only(incident(equations, en, :name)), :type]
bn_type = boundaries[only(incident(boundaries, bn, :name)), :type]
if en_type != bn_type
error("Cannot use $(string(bn)) of type $(string(bn_type)) to bound $(string(en)) of type $(string(en_type)).")
end
# Add a new variable and transfer the children of the original variable to it.
b_var = add_part!(f, :Var, type=f[var, :type], name=Symbol("r$(b)_" * string(f[var, :name])))
transfer_children!(f, var, b_var)
Expand All @@ -47,14 +47,18 @@ function collate(equations, boundaries, uwd, symbols)
# Insert the "masking" operation.
gettype(xs, n) = xs[only(incident(xs, n, :name)), :type]
newtype = @match (gettype(equations, en), gettype(boundaries, bn)) begin
(:infer, _) => :infer
(_, :infer) => :infer
(:Form0, :Constant) => :Form0
(:infer, x) || (x, :infer) => x
(x, :Constant) || (:Constant, x) => x
(x, :Parameter) || (:Parameter, x) => x
(x, y) && if x == y end => x
(x, y) => error("Type mismatch between $x and $y")
_ => error("Cannot use $(string(bn)) of type $(string(bn_type)) to bound $(string(en)) of type $(string(en_type)).")
end
s_var = add_part!(f, :Var, type=newtype, name=bn)
add_part!(f, :Op2, proj1=var, proj2=s_var, res=b_var, op2=uwd[b, :name])

if bn keys(restrictions)
add_part!(f, :Op1, src=only(incident(equations, restrictions[bn], :name)), tgt=s_var, op1=Symbol("restrict_" * string(bn)))
end
end

f
Expand Down
74 changes: 74 additions & 0 deletions test/collages.jl
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,77 @@ TwiceCollage = DiagrammaticEquations.collate(
name = [:K, :J, :K̇, :r1_J, :Jb1, :r2_J, :Jb2]
end

# Test that `restrictions` adds the correct restriction edges
DiffusionCollage = DiagrammaticEquations.collate(
DiffusionDynamics,
DiffusionBoundaries,
DiffusionMorphism,
DiffusionSymbols;
restrictions=Dict(:Kb1 => :K))

@test DiffusionCollage == @acset SummationDecapode{Any, Any, Symbol} begin
Var = 8
TVar = 1
Op1 = 3
Op2 = 3
src = [1, 3, 5]
tgt = [7, 2, 4]
proj1 = [5, 1, 2]
proj2 = [4, 6, 8]
res = [3, 5, 7]
incl = [2]
op1 = Any[:∂ₜ, [:d, :, :d, :], :restrict_Kb1]
op2 = [:rb1_leftwall, :rb2_rightwall, :rb3]
type = [:Form0, :Form0, :Form0, :Form0, :Form0, :Form0, :Form0, :Form0]
name = [:K, :K̇, :r1_K, :Kb1, :r2_K, :Kb2, :r3_K̇, :Null]
end

# Parameters
# Test simple boundary masks.
ParamDiffusionDynamics = infer_types!(@decapode begin
K::Form0
A::Parameter
∂ₜ(K) == A*((d,,d,)(K))
end)
ParamDiffusionBoundaries = @decapode begin
(Kb1, Kb2, Null)::Form0
Ab::Parameter
end
ParamDiffusionMorphism = @relation () begin
rb1_leftwall(C, Cb1)
rb2_rightwall(C, Cb2)
rb3(Ċ, Zero)
r0(Param,BoundaryParam)
end
ParamDiffusionSymbols = Dict(
:C => :K,
:Ċ => :K̇,
:Param => :A,
:BoundaryParam => :Ab,
:Cb1 => :Kb1,
:Cb2 => :Kb2,
:Zero => :Null)
ParamDiffusionCollage = DiagrammaticEquations.collate(
ParamDiffusionDynamics,
ParamDiffusionBoundaries,
ParamDiffusionMorphism,
ParamDiffusionSymbols)
infer_types!(ParamDiffusionCollage)

@test ParamDiffusionCollage == @acset SummationDecapode{Any, Any, Symbol} begin
Var = 12
TVar = 1
Op1 = 2
Op2 = 5
src = [1, 5]
tgt = [9, 4]
proj1 = [11, 7, 1, 3, 2]
proj2 = [4, 6, 8, 10, 12]
res = [3, 5, 7, 9, 11]
incl = [3]
op1 = Any[:∂ₜ, [:d, :, :d, :]]
op2 = [:*, :rb1_leftwall, :rb2_rightwall, :rb3, :r0]
type = [:Form0, :Parameter, :Form0, :infer, :Form0, :Form0, :Form0, :Form0, :Form0, :Form0, :Parameter, :Parameter]
name = [:K, :A, :K̇, Symbol("•2"), :r1_K, :Kb1, :r2_K, :Kb2, :r3_K̇, :Null, :r4_A, :Ab]
end

0 comments on commit d4553b8

Please sign in to comment.