Skip to content

Commit

Permalink
Merge branch 'main' into gh-pages
Browse files Browse the repository at this point in the history
  • Loading branch information
Tasqu committed Apr 12, 2024
2 parents baac4e5 + 7c2c938 commit de4d323
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 100 deletions.
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
name = "ArchetypeBuildingModel"
uuid = "83d8b715-256d-42a8-83e0-f336dff6771c"
authors = ["Topi Rasku <[email protected]>"]
version = "2.7.0"
version_note = "kW scaling"
version = "2.7.1"
version_note = "kW scaling and v0.8 backbone datastore interface fixes"

[deps]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
Expand Down
2 changes: 1 addition & 1 deletion documentation/src/defining_archetype_buildings.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ The [building\_process](@ref) objects are used to define energy transfer/transfo
processes in the [building\_systems](@ref), e.g. direct electric resistance heaters
or heat pumps. The important relationship classes for the definitions are:
- [building\_process\_\_direction\_\_building\_node](@ref): Defines how [building\_process](@ref)es interact with the [building\_node](@ref)s, and houses their maximum power flow parameters.
- [building\_systems\_\_building\_process](@ref): Defines [building\_process](@ref)s parts of this [building\_systems](@ref). Also houses the maximum power flow parameters for the process.
- [building\_systems\_\_building\_process](@ref): Defines [building\_process](@ref)s parts of this [building\_systems](@ref).

The [building\_process](@ref) object class also contains a few important parameters,
mostly due to the potential complexity of different heat pump systems.
Expand Down
2 changes: 1 addition & 1 deletion process_archetype_buildings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ else
@info "Processing and writing $(name) input data into `$(input_url)`..."
@time write_to_url(
String(input_url),
input(archetype_results_dictionary; mod=m);
input(input_url, archetype_results_dictionary; mod=m);
alternative=alternative
)
end
Expand Down
88 changes: 25 additions & 63 deletions src/create_backbone_input.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ Functions for creating Backbone input data from the archetype buildings.
=#

"""
BackboneInput
BackboneInput(url::{String,Dict})
Create and store the input data for the Backbone energy system model.
Link to the input data store for the Backbone energy system model.
Contains the following fields:
- `boundary::ObjectClass`: Contains the `upwardLimit` and `downwardLimit` settings.
Expand Down Expand Up @@ -40,72 +40,32 @@ struct BackboneInput <: ModelInput
grid__node__node::RelationshipClass
grid__node__unit__io::RelationshipClass
unit__unittype::RelationshipClass
function BackboneInput() # Initialize an input struct.
boundary = ObjectClass(
:boundary,
[
Object(:downwardLimit, :boundary),
Object(:upwardLimit, :boundary),
Object(:reference, :boundary),
],
)
effLevel =
ObjectClass(:effLevel, [Object(Symbol("level$(i)"), :effLevel) for i = 1:9])
effSelector = ObjectClass(:effSelector, [Object(:directOff, :effSelector)])
grid = ObjectClass(:grid, Array{ObjectLike,1}())
io = ObjectClass(:io, [Object(:input, :io), Object(:output, :io)])
node = ObjectClass(:node, Array{ObjectLike,1}())
unit = ObjectClass(:unit, Array{ObjectLike,1}())
unittype = ObjectClass(:unittype, [Object(:HVAC, :unittype)])
effLevel__effSelector__unit = RelationshipClass(
:effLevel__effSelector__unit,
[:effLevel, :effSelector, :unit],
Array{RelationshipLike,1}(),
)
grid__node =
RelationshipClass(:grid__node, [:grid, :node], Array{RelationshipLike,1}())
grid__node__boundary = RelationshipClass(
:grid__node__boundary,
[:grid, :node],
Array{RelationshipLike,1}(),
)
grid__node__node = RelationshipClass(
:grid__node__node,
[:grid, :node, :node],
Array{RelationshipLike,1}(),
)
grid__node__unit__io = RelationshipClass(
:grid__node__unit__io,
[:grid, :node, :unit, :io],
Array{RelationshipLike,1}(),
)
unit__unittype = RelationshipClass(
:unit__unittype,
[:unit, :unittype],
Array{RelationshipLike,1}(),
)
function BackboneInput(url::Union{String,Dict}) # Fetch and link the database structure from url.
m = Module() # Create a separate module to load Backbone data store structure into.
using_spinedb(url, m)
new(
boundary,
effLevel,
effSelector,
grid,
io,
node,
unit,
unittype,
effLevel__effSelector__unit,
grid__node,
grid__node__boundary,
grid__node__node,
grid__node__unit__io,
unit__unittype,
m.boundary,
m.effLevel,
m.effSelector,
m.grid,
m.io,
m.node,
m.unit,
m.unittype,
m.effLevel__effSelector__unit,
m.grid__node,
m.grid__node__boundary,
m.grid__node__node,
m.grid__node__unit__io,
m.unit__unittype,
)
end
end


"""
BackboneInput(
url::Union{String,Dict},
results::Dict{Object,ArchetypeBuildingResults};
mod::Module = @__MODULE__
)
Expand All @@ -116,15 +76,16 @@ NOTE! The `mod` keyword changes from which Module data is accessed from,
`@__MODULE__` by default.
Essentially, performs the following steps:
1. Initialize an empty [`BackboneInput`](@ref).
1. Link to [`BackboneInput`](@ref) at `url`.
2. Loop over the given `results`, and [`add_archetype_to_input!`](@ref) one by one.
3. Calculate and [`add_system_link_node_parameters!`](@ref).
"""
function BackboneInput(
url::Union{String,Dict},
results::Dict{Object,ArchetypeBuildingResults};
mod::Module=@__MODULE__
)
backbone = BackboneInput()
backbone = BackboneInput(url)
for result in values(results)
add_archetype_to_input!(backbone, result; mod=mod)
end
Expand Down Expand Up @@ -400,7 +361,7 @@ function add_archetype_to_input!(
(grid=g_map[n], node=n_map[n], unit=u_map[p], io=io_map[d]) => Dict(
:capacity => parameter_value(abs(val)),
:conversionCoeff => parameter_value(val / abs(val)),
:unitSize => parameter_value(abs(val)),
:unitSize => parameter_value(abs(val) / abs_p.number_of_processes),
) for (p, abs_p) in result.archetype.abstract_processes for
((d, n), val) in abs_p.maximum_flows
)
Expand All @@ -413,6 +374,7 @@ function add_archetype_to_input!(
)

# `unit__unittype` simply attaching `HVAC` to every unit.
add_object!(backbone.unittype, Object(:HVAC, :unittype)) # First we need to create the new unittype.
add_relationships!(
backbone.unit__unittype,
[(unit=u, unittype=backbone.unittype(:HVAC)) for u in values(u_map)],
Expand Down
12 changes: 8 additions & 4 deletions src/create_generic_input.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ mostly for debugging purposes.
=#

"""
GenericInput
GenericInput(url::Union{String,Dict}; mod::Module=@__MODULE__)
Create and store the ArchetypeBuildingModel.jl structure for Spine Data Stores.
NOTE! The `mod` keyword changes from which Module data is accessed from,
`@__MODULE__` by default.
`@__MODULE__` by default. The `url` needs to be given to be consistent with
[`BackboneInput`](@ref) and [`SpineOptInput`](@ref), but isn't actually used
for anything.
Contains the following fields:
- `building_archetype::ObjectClass`: Stores [`ArchetypeBuilding`](@ref) information and definitions.
Expand All @@ -26,7 +28,7 @@ struct GenericInput <: ModelInput
building_weather::ObjectClass
building_archetype__building_scope::RelationshipClass
building_archetype__building_weather::RelationshipClass
function GenericInput(; mod=@__MODULE__)
function GenericInput(url::Union{String,Dict}; mod::Module=@__MODULE__)
building_archetype = deepcopy(mod.building_archetype)
building_scope = deepcopy(mod.building_scope)
building_weather = deepcopy(mod.building_weather)
Expand All @@ -45,6 +47,7 @@ end

"""
GenericInput(
url::Union{String,Dict},
results::Dict{Object,ArchetypeBuildingResults};
mod::Module=@__MODULE__
)
Expand All @@ -59,10 +62,11 @@ Essentially, performs the following steps:
2. Loop over the given `archetypes`, and [`add_archetype_to_input!`](@ref) one by one.
"""
function GenericInput(
url::Union{String,Dict},
results::Dict{Object,ArchetypeBuildingResults};
mod::Module=@__MODULE__
)
generic = GenericInput(; mod=mod)
generic = GenericInput(url; mod=mod)
for result in values(results)
add_archetype_to_input!(generic, result)
end
Expand Down
34 changes: 16 additions & 18 deletions src/create_spineopt_input.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ Functions and structs for handling input data for SpineOpt based on the archetyp
=#

"""
SpineOptInput
SpineOptInput(url::Union{String,Dict})
Create and store the input data for the SpineOpt energy system model.
Link to the input data store for the SpineOpt energy system model.
Contains the following fields:
- `node::ObjectClass`: Contains all the `node`s in the building models, created based on [`AbstractNode`](@ref)s.
Expand All @@ -24,27 +24,24 @@ struct SpineOptInput <: ModelInput
unit__from_node::RelationshipClass
unit__to_node::RelationshipClass
unit__node__node::RelationshipClass
function SpineOptInput()
node = ObjectClass(:node, Array{ObjectLike,1}())
unit = ObjectClass(:unit, Array{ObjectLike,1}())
node__node =
RelationshipClass(:node__node, [:node, :node], Array{RelationshipLike,1}())
unit__from_node =
RelationshipClass(:unit__from_node, [:unit, :node], Array{RelationshipLike,1}())
unit__to_node =
RelationshipClass(:unit__to_node, [:unit, :node], Array{RelationshipLike,1}())
unit__node__node = RelationshipClass(
:unit__node__node,
[:unit, :node, :node],
Array{RelationshipLike,1}(),
function SpineOptInput(url::Union{String,Dict}) # Fetch and link the database structure from url.
m = Module() # Create a separate module to load SpineOpt data store structure into.
using_spinedb(url, m)
new(
m.node,
m.unit,
m.node__node,
m.unit__from_node,
m.unit__to_node,
m.unit__node__node
)
new(node, unit, node__node, unit__from_node, unit__to_node, unit__node__node)
end
end


"""
SpineOptInput(
url::Union{String,Dict},
results::Dict{Object,ArchetypeBuildingResults};
mod::Module = @__MODULE__,
)
Expand All @@ -55,14 +52,15 @@ NOTE! The `mod` keyword changes from which Module data is accessed from,
`@__MODULE__` by default.
Essentially, performs the following steps:
1. Initialize an empty [`SpineOptInput`](@ref).
1. Link to [`SpineOptInput`](@ref) at `url`.
2. Loop over the given `results`, and [`add_archetype_to_input!`](@ref) one by one.
"""
function SpineOptInput(
url::Union{String,Dict},
results::Dict{Object,ArchetypeBuildingResults};
mod::Module=@__MODULE__
)
spineopt = SpineOptInput()
spineopt = SpineOptInput(url)
for result in values(results)
add_archetype_to_input!(spineopt, result; mod=mod)
end
Expand Down
2 changes: 1 addition & 1 deletion src/process_abstract_system.jl
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ function process_abstract_system(process::BuildingProcessData; mod::Module=@__MO
) *
( # Scaling W -> kW -> MW
!in(node, process.system_link_nodes) ? 1e-3 :
process.number_of_processes * 1e-3
process.number_of_processes * 1e-6
) *
(
process.maximum_power_base_W[(dir, node)] +
Expand Down
1 change: 1 addition & 0 deletions test/Project.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
[deps]
ArchetypeBuildingModel = "83d8b715-256d-42a8-83e0-f336dff6771c"
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
31 changes: 21 additions & 10 deletions testscript.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,27 @@ Pkg.activate("test")
using Revise
using Test
using Plots
using JSON
using ArchetypeBuildingModel
m = Module()

# Open database
# Some config

# Backbone path, required for input data creation tests.
bb_path = "C:\\backbone"
bb_template_path = bb_path * "\\tools\\bb_data_template.json"

# SpineOpt path, required for input data creation tests.
so_path = "C:\\SpineOpt.jl"
so_template_path = so_path * "\\templates\\spineopt_template.json"

# Provide the url for a datastore containing the required raw input data and the archetype building definitions.
url = "sqlite:///C:\\_SPINEPROJECTS\\SpineOpt_PED_demo_fluid\\.spinetoolbox\\data_and_definitions.sqlite"

# Output url
#output_url = <ADD OUTPUT URL IF DESIRED>
output_url = "sqlite:///" # In-memory db for testing.

## Open database

@info "Opening database..."
@time using_spinedb(url, m)
Expand Down Expand Up @@ -225,24 +236,24 @@ results__system_link_node = initialize_result_classes!(m)


## Test creating and writing SpineOpt input

#=
@info "Creating `SpineOptInput`..."
@time spineopt = SpineOptInput(archetype_results; mod=m)
#write_to_url(output_url, spineopt)

@time spineopt = SpineOptInput(JSON.parsefile(so_template_path), archetype_results; mod=m)
@time write_to_url(output_url, spineopt)
=#

## Test creating and writing Backbone input

@info "Creating `BackboneInput`..."
@time backbone = BackboneInput(archetype_results; mod=m)
#write_to_url(output_url, backbone)
@time backbone = BackboneInput(JSON.parsefile(bb_template_path), archetype_results; mod=m)
@time write_to_url(output_url, backbone)


## Test creating generic input

@info "Creating `GenericInput`..."
@time generic = GenericInput(archetype_results; mod=m)
#@time write_to_url(output_url, generic)
@time generic = GenericInput(output_url, archetype_results; mod=m)
@time write_to_url(output_url, generic)


## Plot diagnostics.
Expand Down

0 comments on commit de4d323

Please sign in to comment.