@@ -135,7 +135,8 @@ model-specific methods that return a comparable value (for example `Dates.Period
135135model_rate (:: AbstractModel ) = nothing
136136model_rate (model:: MultiScaleModel ) = model_rate (model_ (model))
137137
138- Base. length (mapping:: ModelMapping ) = length (mapping. data)
138+ Base. length (mapping:: ModelMapping{MultiScale} ) = length (mapping. data)
139+ Base. length (:: ModelMapping{SingleScale} ) = 1
139140Base. iterate (mapping:: ModelMapping{MultiScale} , state... ) = iterate (mapping. data, state... )
140141# Base.iterate(mapping::ModelMapping{SingleScale}, state...) = iterate(mapping.data.models, state...)
141142Base. show (io:: IO , mapping:: ModelMapping ) = print (io, " ModelMapping with scales: " , join (keys (mapping), " , " ))
@@ -154,20 +155,40 @@ end
154155Base. keys (mapping:: ModelMapping ) = keys (mapping. data)
155156Base. values (mapping:: ModelMapping ) = values (mapping. data)
156157Base. pairs (mapping:: ModelMapping ) = pairs (mapping. data)
158+ Base. keys (:: ModelMapping{SingleScale} ) = (" Default" ,)
159+ Base. values (mapping:: ModelMapping{SingleScale} ) = ((values (mapping. data. models)... , status (mapping. data)),)
160+ Base. pairs (mapping:: ModelMapping{SingleScale} ) = (" Default" => (values (mapping. data. models)... , status (mapping. data)),)
157161Base. getindex (mapping:: ModelMapping , key:: String ) = mapping. data[key]
158162Base. getindex (mapping:: ModelMapping , key:: AbstractString ) = mapping. data[String (key)]
163+ function Base. getindex (mapping:: ModelMapping{SingleScale} , key:: String )
164+ key == " Default" || throw (KeyError (key))
165+ return (values (mapping. data. models)... , status (mapping. data))
166+ end
167+ Base. getindex (mapping:: ModelMapping{SingleScale} , key:: AbstractString ) = getindex (mapping, String (key))
168+ Base. getindex (mapping:: ModelMapping{SingleScale} , key:: Symbol ) = getindex (mapping. data, key)
169+ Base. getindex (mapping:: ModelMapping{SingleScale} , key:: Integer ) = getindex (mapping. data, key)
159170Base. haskey (mapping:: ModelMapping , key:: String ) = haskey (mapping. data, key)
160171Base. haskey (mapping:: ModelMapping , key:: AbstractString ) = haskey (mapping. data, String (key))
161172Base. eltype (:: Type{ModelMapping} ) = Pair{String,Tuple}
162- Base. copy (mapping:: ModelMapping ) = ModelMapping (copy (mapping. data); check= false )
173+ Base. copy (mapping:: ModelMapping{MultiScale} ) = ModelMapping (copy (mapping. data); check= false )
174+ Base. copy (mapping:: ModelMapping{SingleScale} ) = ModelMapping {SingleScale,ModelList} (copy (mapping. data))
175+ Base. copy (mapping:: ModelMapping{SingleScale} , status) = ModelMapping {SingleScale,ModelList} (copy (mapping. data, status))
163176Base. Dict (mapping:: ModelMapping ) = copy (mapping. data)
177+ Base.:(== )(left:: ModelMapping{SingleScale} , right:: ModelMapping{SingleScale} ) = left. data == right. data
178+
179+ function Base. getproperty (mapping:: ModelMapping{SingleScale} , name:: Symbol )
180+ name === :data && return getfield (mapping, :data )
181+ return getproperty (getfield (mapping, :data ), name)
182+ end
164183
165184function ModelMapping {MultiScale} (mapping:: T ; check:: Bool = true ) where {T<: AbstractDict }
166185 normalized = _normalize_multiscale_mapping (mapping)
167186 check && _check_multiscale_mapping! (normalized)
168187 ModelMapping {MultiScale,Dict{String,Tuple}} (normalized)
169188end
170189
190+ ModelMapping (mapping:: AbstractDict ; check:: Bool = true ) = ModelMapping {MultiScale} (mapping; check= check)
191+
171192ModelMapping (mapping:: ModelMapping ; check:: Bool = true ) = check ? ModelMapping (mapping. data; check= true ) : mapping
172193
173194"""
@@ -190,6 +211,12 @@ function ModelMapping(
190211 " No mapping or model was provided. Use `ModelMapping(\" Scale\" => models)` or pass models directly."
191212 )
192213
214+ # Backwards compatibility: allow dict-like construction for type promotion maps,
215+ # e.g. `ModelMapping(Float64 => Float32)`.
216+ if ! isempty (args) && all (arg -> arg isa Pair && ! (first (arg) isa Union{AbstractString,Symbol}), args)
217+ return Dict (args)
218+ end
219+
193220 if _all_scale_pairs (args)
194221 isempty (processes) || error (
195222 " Cannot mix scale-level pairs with process keyword arguments. " ,
@@ -200,7 +227,7 @@ function ModelMapping(
200227 " Provide statuses inside each scale mapping instead."
201228 )
202229 raw_mapping = Dict {String,Any} (String (first (pair)) => last (pair) for pair in args)
203- return ModelMapping {MultiScale,typeof(raw_mapping) } (raw_mapping; check= check)
230+ return ModelMapping {MultiScale} (raw_mapping; check= check)
204231 end
205232
206233 _contains_scale_like_pair (args) && error (
@@ -215,13 +242,20 @@ function ModelMapping(
215242end
216243
217244# Canonical API dispatches for model mappings.
218- dep (mapping:: ModelMapping ; verbose:: Bool = true ) = dep (mapping. data; verbose= verbose)
219- hard_dependencies (mapping:: ModelMapping ; verbose:: Bool = true ) = hard_dependencies (mapping. data; verbose= verbose)
245+ dep (mapping:: ModelMapping{SingleScale} ; verbose:: Bool = true ) = dep (mapping. data)
246+ dep (mapping:: ModelMapping{MultiScale} ; verbose:: Bool = true ) = dep (mapping. data; verbose= verbose)
247+ hard_dependencies (mapping:: ModelMapping{SingleScale} ; verbose:: Bool = true ) = hard_dependencies (mapping. data)
248+ hard_dependencies (mapping:: ModelMapping{MultiScale} ; verbose:: Bool = true ) = hard_dependencies (mapping. data; verbose= verbose)
220249inputs (mapping:: ModelMapping ) = inputs (mapping. data)
221250outputs (mapping:: ModelMapping ) = outputs (mapping. data)
222251variables (mapping:: ModelMapping ) = variables (mapping. data)
223252to_initialize (mapping:: ModelMapping , graph= nothing ) = to_initialize (mapping. data, graph)
224253reverse_mapping (mapping:: ModelMapping ; all= true ) = reverse_mapping (mapping. data; all= all)
254+ init_variables (mapping:: ModelMapping{SingleScale} ; verbose= true ) = init_variables (mapping. data; verbose= verbose)
255+ to_initialize (mapping:: ModelMapping{SingleScale} ) = to_initialize (mapping. data)
256+ to_initialize (mapping:: ModelMapping{SingleScale} , graph) = to_initialize (mapping)
257+ pre_allocate_outputs (mapping:: ModelMapping{SingleScale} , outs, nsteps; type_promotion= nothing , check= true ) =
258+ pre_allocate_outputs (mapping. data, outs, nsteps; type_promotion= type_promotion, check= check)
225259
226260function _all_scale_pairs (args)
227261 ! isempty (args) && all (arg -> arg isa Pair && first (arg) isa Union{AbstractString,Symbol}, args)
0 commit comments