-
Notifications
You must be signed in to change notification settings - Fork 4
Description
So far, we did not have a functionality for adding variables for Data types except through dispatching on the model type. That may lead to issues with respect to method ambiguities. Hence, a new method is sought after.
Introducing variables for Data types should follow the following three standards:
- they should be only introduced for the required nodes that require them,
- they should be indexed over the node and not the data, and
- they should not require changes to the core code.
Point 2 is the reason we cannot use the same approach as applied for Node types as we would in this case index over the data, and not the node.
A potential solution for this problem, still utilizing the core structure developed for Node types, is outlined below. It requires the introduction of a function variables_data(m, 𝒩, 𝒯, 𝒫, modeltype) to the function create_model given by:
function variables_data(m, 𝒩::Vector{<:Node}, 𝒯, 𝒫, modeltype::EnergyModel)
# Extract all Data types within all Nodes
𝒟 = reduce(vcat, [node_data(n) for n ∈ 𝒩])
if isempty(𝒟) return end
# Vector of the unique data types in 𝒟.
data_composite_types = unique(typeof.(𝒟))
# Get all `Data`-types in the type-hierarchy that the nodes 𝒟 represents.
data_types = collect_types(data_composite_types)
# Sort the `Data`-types such that a supertype will always come before its subtypes.
data_types = sort_types(data_types)
for data_type ∈ data_types
# All nodes of the given sub type.
𝒟ˢᵘᵇ = filter(data -> isa(data, data_type), 𝒟)
# Convert to a Vector of common-type instad of Any.
𝒟ˢᵘᵇ = convert(Vector{data_type}, 𝒟ˢᵘᵇ)
try
variables_data(m, 𝒟ˢᵘᵇ, 𝒩, 𝒯, 𝒫, modeltype)
catch e
# Parts of the exception message we are looking for.
pre1 = "An object of name"
pre2 = "is already attached to this model."
if isa(e, ErrorException)
if occursin(pre1, e.msg) && occursin(pre2, e.msg)
# 𝒟ˢᵘᵇ was already registered by a call to a supertype, so just continue.
continue
end
end
# If we make it to this point, this means some other error occured. This should
# not be ignored.
throw(e)
end
end
# Add the variables for the required nodes.
for n ∈ 𝒩, data ∈ node_data(n)
variables_data(m, data, n, 𝒯, 𝒫, modeltype)
end
endIn addition, we have to create two additional functions:
function variables_data(m, 𝒟ˢᵘᵇ::Vector{<:Data}, 𝒩::Vector{<:Node}, 𝒯, 𝒫, modeltype::EnergyModel)
end
function variables_data(m, data::Data, n::Node, 𝒯, 𝒫, modeltype::EnergyModel)
endThe first function is used to create empty variable containers through the application of SparseVariables, while the second would only inserts the variables for the nodes that have the corresponding data.
Another required change is to define the following function.
node_data(n::Availability) = Data[]This function may be in general dangerous as it requires that if one wants to define a new composite subtype of Availability, one has to define as well the function for this type. However, the throught process is that Availability nodes should not include the data field.
The code runs with these functions added, but I have not tested it for additional variable creation. The function for looping through the types is however working. I have not added SparseVariables either, as it is not yet registered.