Skip to content
Snippets Groups Projects
Commit e7341f9b authored by Brian Groenke's avatar Brian Groenke
Browse files

Add support for defining coupling order between processes

parent 573e01bc
No related branches found
No related tags found
1 merge request!90Preparatory changes for adding water processes
......@@ -8,7 +8,15 @@ Represents a single component (layer + processes) in the stratigraphy.
struct StratComponent{TLayer,TProcesses,name}
layer::TLayer
processes::TProcesses
StratComponent(name::Symbol, layer::TLayer, processes::TProcesses) where {TLayer<:Layer,TProcesses<:CoupledProcesses} = new{TLayer,TProcesses,name}(layer,processes)
function StratComponent(name::Symbol, layer::TLayer, processes::TProcesses; ignore_order=false) where {TLayer<:Layer,TProcesses<:CoupledProcesses}
# check coupling order
if !issorted(processes.processes) && !ignore_order
processes = CoupledProcesses(sort(processes.processes))
@warn "The ordering of the given coupled processes is inconsistent with the defined rules and has been automatically corrected: $(map(p -> typeof(p).name.wrapper, processes.processes)).
If this was on purpose, you can override the defined ordering and suppress this warning with `ignore_order=true` or define `isless` on your process types to explicitly declare the intended ordering."
end
new{TLayer,TProcesses,name}(layer,processes)
end
end
ConstructionBase.constructorof(::Type{StratComponent{TLayer,TProcesses,name}}) where {TLayer,TProcesses,name} = (layer,processes) -> StratComponent(name, layer, processes)
"""
......@@ -21,11 +29,11 @@ componentnameval(::StratComponent{L,P,name}) where {L,P,name} = Val{name}
Base.show(io::IO, node::StratComponent{L,P,name}) where {L,P,name} = print(io, "$name($L,$P)")
# Constructors for stratigraphy nodes
top(bcs::BoundaryProcess...) = StratComponent(:top, Top(), CoupledProcesses(bcs...))
bottom(bcs::BoundaryProcess...) = StratComponent(:bottom, Bottom(), CoupledProcesses(bcs...))
function subsurface(name::Symbol, sub::SubSurface, processes::SubSurfaceProcess...)
top(bcs::BoundaryProcess...; ignore_order=false) = StratComponent(:top, Top(), CoupledProcesses(bcs...); ignore_order)
bottom(bcs::BoundaryProcess...; ignore_order=false) = StratComponent(:bottom, Bottom(), CoupledProcesses(bcs...); ignore_order)
function subsurface(name::Symbol, sub::SubSurface, processes::SubSurfaceProcess...; ignore_order=false)
@assert name RESERVED_COMPONENT_NAMES "layer identifier $name is reserved"
return StratComponent(name, sub, CoupledProcesses(processes...))
return StratComponent(name, sub, CoupledProcesses(processes...); ignore_order)
end
"""
......
......@@ -27,6 +27,13 @@ Base.Broadcast.broadcastable(l::Layer) = Ref(l)
Abstract base type for all dynamical processes.
"""
abstract type Process end
"""
isless(::Process, ::Process)
Defines an ordering between processes, which can be useful for automatically enforcing
order constraints when coupling processes together.
"""
Base.isless(::Process, ::Process) = false
"""
SubSurfaceProcess <: Process
......@@ -51,9 +58,9 @@ of other processes.
"""
struct CoupledProcesses{TProcs} <: Process
processes::TProcs
CoupledProcesses(processes::Tuple{Vararg{Process}}) = new{typeof(processes)}(processes)
CoupledProcesses(processes::SubSurfaceProcess...) = new{typeof(processes)}(processes)
CoupledProcesses(processes::BoundaryProcess...) = new{typeof(processes)}(processes)
CoupledProcesses(processes::SubSurfaceProcess...) = CoupledProcesses(processes)
CoupledProcesses(processes::BoundaryProcess...) = CoupledProcesses(processes)
CoupledProcesses(processes::Tuple{Vararg{Process}}) new{typeof(processes)}(processes)
end
Base.iterate(cp::CoupledProcesses) = Base.iterate(cp.processes)
Base.iterate(cp::CoupledProcesses, state) = Base.iterate(cp.processes, state)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment