Library
Automatically generated documentation based on the docstrings in the codebase.
Index
ArchetypeBuildingModel.AbstractNodeArchetypeBuildingModel.AbstractNodeNetworkArchetypeBuildingModel.AbstractProcessArchetypeBuildingModel.ArchetypeBuildingArchetypeBuildingModel.ArchetypeBuildingResultsArchetypeBuildingModel.BackboneInputArchetypeBuildingModel.BuildingDataTypeArchetypeBuildingModel.BuildingNodeDataArchetypeBuildingModel.BuildingNodeNetworkArchetypeBuildingModel.BuildingProcessDataArchetypeBuildingModel.EnvelopeDataArchetypeBuildingModel.GenericInputArchetypeBuildingModel.LoadsDataArchetypeBuildingModel.ScopeDataArchetypeBuildingModel.SpineOptInputArchetypeBuildingModel.StructureDataArchetypeBuildingModel.WeatherDataArchetypeBuildingModel._building_period_weightArchetypeBuildingModel._pyseries_to_timeseriesArchetypeBuildingModel.add_archetype_to_input!ArchetypeBuildingModel.add_results!ArchetypeBuildingModel.add_system_link_node_parameters!ArchetypeBuildingModel.aggregate_gfa_weightsArchetypeBuildingModel.archetype_building_processingArchetypeBuildingModel.calculate_base_floor_dimensionsArchetypeBuildingModel.calculate_convective_internal_heat_gainsArchetypeBuildingModel.calculate_convective_solar_gainsArchetypeBuildingModel.calculate_copArchetypeBuildingModel.calculate_effective_ground_temperatureArchetypeBuildingModel.calculate_envelope_radiative_sky_lossesArchetypeBuildingModel.calculate_envelope_solar_gainsArchetypeBuildingModel.calculate_exterior_wall_dimensionsArchetypeBuildingModel.calculate_gross_floor_area_weightsArchetypeBuildingModel.calculate_interior_air_and_furniture_thermal_massArchetypeBuildingModel.calculate_partition_wall_dimensionsArchetypeBuildingModel.calculate_radiative_internal_heat_gainsArchetypeBuildingModel.calculate_radiative_solar_gainsArchetypeBuildingModel.calculate_roof_dimensionsArchetypeBuildingModel.calculate_separating_floor_dimensionsArchetypeBuildingModel.calculate_structural_exterior_heat_transfer_coefficientArchetypeBuildingModel.calculate_structural_ground_heat_transfer_coefficientArchetypeBuildingModel.calculate_structural_interior_heat_transfer_coefficientArchetypeBuildingModel.calculate_structural_thermal_massArchetypeBuildingModel.calculate_total_dhw_demandArchetypeBuildingModel.calculate_total_envelope_radiative_sky_lossesArchetypeBuildingModel.calculate_total_envelope_solar_gainsArchetypeBuildingModel.calculate_total_internal_heat_loadsArchetypeBuildingModel.calculate_total_solar_gainsArchetypeBuildingModel.calculate_total_thermal_bridge_heat_transfer_coefficientArchetypeBuildingModel.calculate_ventilation_and_infiltration_heat_transfer_coefficientArchetypeBuildingModel.calculate_vertical_envelope_surface_areaArchetypeBuildingModel.calculate_window_dimensionsArchetypeBuildingModel.calculate_window_heat_transfer_coefficientArchetypeBuildingModel.collect_leaf_valuesArchetypeBuildingModel.create_abstract_node_networkArchetypeBuildingModel.create_building_node_networkArchetypeBuildingModel.create_building_weatherArchetypeBuildingModel.determine_temporal_structureArchetypeBuildingModel.form_and_invert_dynamics_matrixArchetypeBuildingModel.form_and_invert_hvac_matrixArchetypeBuildingModel.initialize_result_classes!ArchetypeBuildingModel.initialize_rhsArchetypeBuildingModel.initialize_temperaturesArchetypeBuildingModel.load_definitions_templateArchetypeBuildingModel.process_abstract_nodeArchetypeBuildingModel.process_abstract_systemArchetypeBuildingModel.process_building_envelopeArchetypeBuildingModel.process_building_loadsArchetypeBuildingModel.process_building_nodeArchetypeBuildingModel.process_building_stock_scopeArchetypeBuildingModel.process_building_systemArchetypeBuildingModel.process_structure_scopeArchetypeBuildingModel.process_ventilation_and_fenestration_scopeArchetypeBuildingModel.process_weatherArchetypeBuildingModel.run_input_data_testsArchetypeBuildingModel.run_object_class_testsArchetypeBuildingModel.run_parameter_testsArchetypeBuildingModel.run_structure_type_testsArchetypeBuildingModel.solve_archetype_building_hvac_demandArchetypeBuildingModel.solve_consumptionArchetypeBuildingModel.solve_heating_demandArchetypeBuildingModel.solve_heating_demand_loopArchetypeBuildingModel.timeseries_to_backbone_mapArchetypeBuildingModel.write_to_url
Public
This section lists all types and functions exported by the module.
Types
ArchetypeBuildingModel.ArchetypeBuilding — TypeArchetypeBuilding(
archetype::Object;
mod::Module = @__MODULE__,
realization::Symbol = :realization,
)Contains data representing a single archetype building.
The ArchetypeBuilding struct stores the information about the objects used in its construction, the aggregated statistical and structural properties, as well as the BuildingNodeData and BuildingProcessData. Furthermore, the relevant AbstractNode and AbstractProcess used to create the large-scale energy system model input are also stored for convenience. The contents of the ArchetypeBuilding are intended to be as human-readable as possible to allow for inspecting the contents individually for debugging purposes.
NOTE! The mod keyword changes from which Module data is accessed from by the constructor, @__MODULE__ by default.
This struct contains the following fields:
archetype::Object: Thebuilding_archetypeobject corresponding to thisArchetypeBuilding.scope::Object: The definedbuilding_scopefor this archetype.fabrics::Object: The definedbuilding_fabricsfor this archetype.systems::Object: The definedbuilding_systemsfor this archetype.loads::Object: The definedbuilding_loadsfor this archetype.weather::Object: The definedbuilding_weatherfor this archetype.scope_data::ScopeData: The processedbuilding_scopedata for this archetype.envelope_data::EnvelopeData: The processed envelope properties of this archetype.building_nodes::BuildingNodeNetwork: The temperature node network depicting this archetype.building_processes::Dict{Object,BuildingProcessData}: The processes in this archetype.loads_data::LoadsData: The loads defined for this archetype.weather_data::WeatherData: The processed weather data for this archetype.abstract_nodes::AbstractNodeNetwork: The processedAbstractNodes depicting this archetype.abstract_processes::Dict{Object,AbstractProcess}: The processedAbstractProcesses in this archetype.
The constructor performs the following steps:
- Fetch and create the corresponding
WeatherData. - Fetch and create the corresponding
ScopeData. - Form the
EnvelopeData. - Process the
LoadsData. - Process the temperature nodes using the
create_building_node_networkfunction. - Create the
BuildingProcessDatafor the HVAC system components. - Process the abstract temperature nodes using the
create_abstract_node_networkfunction based on theBuildingNodeNetwork. - Create the
AbstractProcesses corresponding to theBuildingProcessDatas. - Construct the final
ArchetypeBuilding.
ArchetypeBuildingModel.ArchetypeBuildingResults — TypeArchetypeBuildingResults(
archetype::ArchetypeBuilding;
free_dynamics::Bool = false,
initial_temperatures::Union{Nothing,Dict{Object,Float64}} = nothing,
mod::Module = @__MODULE__,
realization::Symbol = :realization,
) <: BuildingDataTypeStore the temperature and HVAC demand results for the archetype building.
The free_dynamics keyword can be used to force the calculations to ignore heating/cooling set points, while the initial_temperatures keyword can be used to fix the initial temperatures for the simulation. The realization keyword is used to select the true data from potentially stochastic input.
NOTE! The mod keyword changes from which Module data is accessed from by the constructor, @__MODULE__ by default.
This struct contains the following fields:
archetype::ArchetypeBuilding: TheArchetypeBuildingfor which the results were calculated.free_dynamics::Bool: Flag whether or not to ignore set point temperatures for free temperature dynamics.initial_temperatures::Dict{Object,Float64}: The initial temperatures used for the results.temperatures::Dict{Object,SpineDataType}: The resulting node temperatures in [K].hvac_demand::Dict{Object,SpineDataType}: The HVAC demand required to keep the temperature nodes within the permitted limits for each node.hvac_consumption::Dict{Object,SpineDataType}: The estimated energy consumption of the HVAC equipment required to fulfill the HVAC demand.
The constructor performs the following steps:
- Solve the initial temperatures, node temperatures, and HVAC demand using the
solve_heating_demandfunction. - Solve the HVAC consumption using the
solve_consumptionfunction. - Return the
ArchetypeBuildingResultsusing the calculated values.
ArchetypeBuildingModel.BackboneInput — TypeBackboneInput(url::{String,Dict})Link to the input data store for the Backbone energy system model.
Contains the following fields:
boundary::ObjectClass: Contains theupwardLimitanddownwardLimitsettings.effLevel::ObjectClass: All possible efficiency representation levels in Backbone.effSelector::ObjectClass: Contains thedirectOffefficiency representation used by the building model.grid::ObjectClass: Contains thebuildinggridfor buildingnodes.io::ObjectClass: Contains theinputandoutputindicators forunits.node::ObjectClass: Contains all thenodes in the building models, created based onAbstractNodes.unit::ObjectClass: Contains all theunits in the building models, created based onAbstractProcesses.unittype::ObjectClass: Contains aHVACtype for all buildingunits.effLevel__effSelector__unit::RelationshipClass: Attributes thedirectOffefficiency representation for allunits for all efficiency representation levels.grid__node::RelationshipClass: Connects allnodes into thebuildinggrid.grid__node__boundary::RelationshipClass: Contains theupwardLimitanddownwardLimitparameters for allnodes.grid__node__node::RelationshipClass: Contains thediffCoeffdiffusion parameters between thenodes.grid__node__unit__io::RelationshipClass: Defines how theunits interact with thenodes, and contains the necessary parameters.unit__unittype::RelationshipClass: Indicates allunits as of typeHVAC
ArchetypeBuildingModel.BuildingProcessData — TypeBuildingProcessData(
archetype::Object,
process::Object,
scope::ScopeData,
weather::WeatherData;
mod::Module = @__MODULE__,
) <: BuildingDataTypeAggregate building systems into processes for the lumped-capacitance thermal model.
The BuildingProcessData struct aims to remain as human-readable as possible, making it a high-level description of the properties of a process in the lumped-capacitance thermal model. Ultimately, BuildingProcessDatas are converted into AbstractProcesss for exporting into energy-system-model-specific input data formats.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
This struct contains the following fields:
building_process::Object: Thebuilding_processdefinition for thisBuildingProcessData.system_link_nodes::Vector{Object}: The energy system nodes used to connect the buildings to the energy system at large.coefficient_of_performance::SpineDataType: The coefficient of performance of the process.coefficient_of_performance_mode::Symbol: The mode of the process, either:heatingor:cooling.maximum_power_base_W::Dict{Tuple{Object,Object},SpineDataType}: User-defined base maximum power flows in [W] between this process and the nodes.maximum_power_gfa_scaled_W::Dict{Tuple{Object,Object},SpineDataType}: User-defined gross-floor-area-scaling maximum power flows in [W] between this process and the nodes.number_of_processes::Float64: The number of aggregated processes this one depicts for the large-scale energy system models.
The constructor calls the process_building_system function.
ArchetypeBuildingModel.EnvelopeData — TypeEnvelopeData(archetype::Object, data::ScopeData; mod::Module = @__MODULE__) <: BuildingDataTypeStore the calculated dimensions of the different parts of the building envelope.
EnvelopeData is generated based on the building_archetype parameters and the aggregated ScopeData.
NOTE! The mod keyword changes from which Module data is accessed from by the constructor, @__MODULE__ by default.
This struct contains the following fields:
base_floor::NamedTuple: Linear thermal bridge length [m] and surface area [m2] of the base floor.exterior_wall::NamedTuple: Linear thermal bridge length [m] and surface area [m2] of the load-bearing exterior walls.light_exterior_wall::NamedTuple: Linear thermal bridge length [m] and surface area [m2] of the light exterior walls.light_partition_wall::NamedTuple: Linear thermal bridge length [m] and one-sided surface area [m2] of the light partition walls.partition_wall::NamedTuple: Linear thermal bridge length [m] and one-sided surface area [m2] of the load-bearing partition walls.roof::NamedTuple: Linear thermal bridge length [m] and surface area [m2] of the roof.separating_floor::NamedTuple: Linear thermal bridge length [m] and one-sided surface area [m2] of the partition floors.window::NamedTuple: Linear thermal bridge length [m] and surface area [m2] of the windows.
The constructor calls the process_building_envelope function and checks that the results are sensible.
ArchetypeBuildingModel.GenericInput — TypeGenericInput(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. The url needs to be given to be consistent with BackboneInput and SpineOptInput, but isn't actually used for anything.
Contains the following fields:
building_archetype::ObjectClass: StoresArchetypeBuildinginformation and definitions.building_scope::ObjectClass: StoresScopeDatainformation and definitions.building_weather::ObjectClass: StoresWeatherDatainformation and definitions.building_archetype__building_scope::RelationshipClass: LinksArchetypeBuildingto its correspondingScopeData.building_archetype__building_weather::RelationshipClass: LinksArchetypeBuildingto its correspondingWeatherData.
ArchetypeBuildingModel.LoadsData — TypeLoadsData(
archetype::Object,
scope::ScopeData,
envelope::EnvelopeData,
weather::WeatherData;
mod::Module = @__MODULE__,
) <: BuildingDataTypeStore the domestic hot water demand and internal/solar heat gains data.
The domestic hot water demand and internal gains are calculated based on the provided base and GFA-scaling parameters, while the solar gains are calculated based on the building_weather object.
NOTE! The mod keyword changes from which Module data is accessed from by the constructor, @__MODULE__ by default.
This struct contains the following fields:
domestic_hot_water_demand_W::SpineDataType: Domestic hot water demand data in [W] for the building.internal_heat_gains_W::SpineDataType: Total internal heat gains data in [W] for the building.solar_heat_gains_W::SpineDataType: Total solar heat gain through windows data in [W] for the building.envelope_solar_gains_W::Dict{Object,SpineDataType}: Solar heat gains through each structure type [W].envelope_radiative_sky_losses_W::Dict{Object,SpineDataType}: Estimated radiative heat losses to the sky from the building envelope [W].
The constructor calls the process_building_loads function and checks that the results are sensible.
ArchetypeBuildingModel.ScopeData — TypeScopeData(scope::Object; mod::Module = @__MODULE__) <: BuildingDataTypeAggregate and store data defined by a building_scope object.
Essentially, stores information about the aggregated properties of the desired portion of the building stock, as defined by the building_scope object in the archetype building definition database.
NOTE! The mod keyword changes from which Module data is accessed from by the constructor, @__MODULE__ by default.
This struct contains the following fields:
building_scope::Object: Thebuilding_scopeused to define thisScopeData.number_of_buildings::Float64: Number of buildings included in thisscope.average_gross_floor_area_m2_per_building::Float64: Average GFA per building in [m2] of the buildings included in thisscope.HRU_efficiency::Float64: Average ventilation heat-recovery unit efficiency of the buildings included in thisscope.infiltration_rate_1_h::Float64: Average infiltration rate in [1/h] of the buildings included in thisscope.total_normal_solar_energy_transmittance::Float64: Average total normal solar energy transmittance of the windows included in thisscope.ventilation_rate_1_h::Float64: Average ventilation rate in [1/h] of the buildings included in thisscope.window_U_value_W_m2K::Float64: Average window U-value in [W/m2K] of the buildings included in thisscope.structure_data::Dict{Object,StructureData}:StructureDatadictionary for the average structural parameters of the buildings included in thisscope.location_id_gfa_weights::Dict{Object,Float64}: Gross-floor area weights for thelocation_ids included in thisscope, used for automatic weather data processing.shapefile_path::String: Path to a shapefile describing the geography of thisscope, used for the automatic weather data aggregation.raster_weight_path::Union{String,Nothing}: Optional path to a raster weight map for tweaking the automatic weather data aggregation.
The constructor essentially performs the following steps:
- Process building stock statistics using the
process_building_stock_scopefunction. - Process ventilation and fenestration statistics using the
process_ventilation_and_fenestration_scopefunction. - Process structure statistics using the
process_structure_scopefunction. - Check that the values make sense.
- Create the
ScopeData.
ArchetypeBuildingModel.SpineOptInput — TypeSpineOptInput(url::Union{String,Dict})Link to the input data store for the SpineOpt energy system model.
Contains the following fields:
node::ObjectClass: Contains all thenodes in the building models, created based onAbstractNodes.unit::ObjectClass: Contains all theunits in the building models, created based onAbstractProcesses.node__node::RelationshipClass: Defines the heat transfer coefficients between thenodes.unit__from_node::RelationshipClass: Definesunitinput flow properties.unit__to_node::RelationshipClass: Definesunitoutput flow properties.unit__node__node::RelationshipClass: Definesunitconversion properties.
ArchetypeBuildingModel.WeatherData — TypeWeatherData(
weather::Object;
mod::Module = @__MODULE__,
realization::Symbol = :realization,
) <: BuildingDataTypeProcess and store the weather data for further calculations.
NOTE! The mod keyword changes from which Module data is accessed from by the constructor, @__MODULE__ by default. The realization scenario is required for effective ground temperature calculations.
This struct contains the following fields:
building_weather::Object: Thebuilding_weatherobject used to construct thisWeatherData.ambient_temperature_K::SpineDataType: Ambient temperature data in [K].ground_temperature_K::SpineDataType: Effective ground temperature data in [K].diffuse_solar_irradiation_W_m2::SpineDataType: Diffuse solar irradiation data in [W/m2].direct_solar_irradiation_W_m2::Dict{Symbol,SpineDataType}: Direct solar irradiation data dictionary, containing irradiation for walls facing in different cardinal directions in [W/m2].
Essentially, the constructor calls the process_weather function, and checks that the resulting values are sensible.
Functions
ArchetypeBuildingModel.add_results! — Functionadd_results!(
results__building_archetype__building_node::RelationshipClass,
results__building_archetype__building_process::RelationshipClass,
results__system_link_node::ObjectClass,
results_dictionary::Dict{Object,ArchetypeBuildingResults};
mod::Module = @__MODULE__
)
Add results from `results_dictionary` into the result `RelationshipClass`es.
NOTE! The `mod` keyword changes from which Module data is accessed from,
`@__MODULE__` by default.ArchetypeBuildingModel.archetype_building_processing — Functionarchetype_building_processing(
weather_url::String,
save_layouts::Bool;
weather_data_dictionary::Union{Nothing,Dict{Object,WeatherData}} = nothing,
mod::Module = @__MODULE__,
realization::Symbol = :realization,
)Process the ScopeData, WeatherData, and ArchetypeBuilding objects.
Essentially, processes all the necessary information for ArchetypeBuilding creation, and returns the scope_data_dictionary, weather_data_dictionary, and archetype_dictionary for examining the processed data. Any automatically generated building_weather objects will be imported back into the database at weather_url. If save_layouts == true, diagnostic figures of the layouts are saved into figs/. The weather_data_dictionary keyword can be used to bypass weather data processing if a pre-existing dictionary is provided. The mod keyword changes from which Module data is accessed from, @__MODULE__ by default. The realization keyword is used to indicate the true data from potentially stochastic input.
This function performs the following steps:
- Construct the
ScopeDatafor each defined building_archetype__building_scope, and store in thescope_data_dictionary. - Try to construct the
WeatherDatafor each defined building_archetype__building_weather, and attempt automatic weather processing using ArchetypeBuildingWeather.py if no definition found. Results stored inweather_data_dictionary. - Use the
scope_data_dictionaryandweather_data_dictionaryto construct theArchetypeBuildingfor all defined archetypes, and store them inarchetype_dictionary. - Return
scope_data_dictionary,weather_data_dictionary, andarchetype_dictionary.
ArchetypeBuildingModel.create_abstract_node_network — Functioncreate_abstract_node_network(
building_node_network::BuildingNodeNetwork,
weather::WeatherData
)Process a BuildingNodeNetwork into an AbstractNodeNetwork.
The AbstractNodeNetwork is a useful step for creating model-agnostic input for multiple large-scale energy system models. weather is required to account for ambient temperatures.
ArchetypeBuildingModel.create_building_node_network — Functioncreate_building_node_network(
archetype::Object,
fabrics::Object,
systems::Object,
scope::ScopeData,
envelope::EnvelopeData,
loads::LoadsData;
mod::Module = @__MODULE__,
)Map all archetype building_nodes to their BuildingNodeDatas.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially, loops over the building_fabrics__building_node and building_systems__building_node relationships for the desired archetype, and collects all the building_nodes and BuildingNodeDatas into a BuildingNodeNetwork dictionary.
ArchetypeBuildingModel.create_building_weather — Functioncreate_building_weather(
archetype::Object,
scopedata::ScopeData;
ignore_year::Bool = false,
repeat::Bool = true,
save_layouts::Bool = true,
mod::Module = @__MODULE__,
)Try to create building_weather automatically using ArchetypeBuildingWeather.py.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially tries to automatically fetch weather data from ERA5 using the PYPSA/atlite python library, and aggregate it according to the GIS data indicated via the shapefile_path and raster_weight_path parameters for the building_stock objects. The desired weather period needs to be indicated using the building_archetype weather_start and weather_end parameters, and weighting is done based on the building_scope, the shapefile at shapefile_path, and the optional raster data at raster_weight_path.
The optional ignore_year and repeat keywords are used to control the corresponding flags of the created SpineInterface.TimeSeries. By default, the created TimeSeries are year-aware and repeating. The save_layouts keyword is used to control whether the layouts used for weighting the weather data are saved for diagnostics.
Returns a new building_weather object, as well as a dictionary containing its parameter values.
ArchetypeBuildingModel.initialize_result_classes! — Functioninitialize_result_classes!(mod::Module)Initialize RelationshipClasses and ObjectClasses for storing heating and HVAC demand results in mod.
Note that this function modifies mod directly!
ArchetypeBuildingModel.run_input_data_tests — Functionrun_input_data_tests(mod::Module = @__MODULE__)Runs input data tests for the Datastore loaded to module mod, @__MODULE__ by default.
Essentially performs the following steps:
ArchetypeBuildingModel.run_object_class_tests — Functionrun_object_class_tests(mod::Module = @__MODULE__; limit::Real = Inf)Run tests for archetype building model definition ObjectClasses for module mod. The limit keyword can be used to limit the number of tests run.
ArchetypeBuildingModel.run_parameter_tests — Functionrun_parameter_tests(mod::Module = @__MODULE__; limit::Real = Inf)Run tests for archetype building model definition Parameters for module mod. The limit keyword can be used to limit the number of tests run.
ArchetypeBuildingModel.run_structure_type_tests — Functionrun_structure_type_tests(mod::Module = @__MODULE__)Ensure that structure_type contains the correct objects.
ArchetypeBuildingModel.solve_archetype_building_hvac_demand — Functionsolve_archetype_building_hvac_demand(
archetype_dictionary::Dict{Object,ArchetypeBuilding};
free_dynamics::Bool = false,
initial_temperatures::Dict{Object,Dict{Object,Float64}} = Dict{
Object,
Dict{Object,Float64}
}(),
realization::Symbol = :realization,
)Solve the ArchetypeBuilding heating and cooling demand.
The free_dynamics keyword can be used to ignore node temperature limits, while the initial_temperatures keyword can be used to set desired initial temperatures for the nodes. The realization keyword is used to denote the true data from potentially stochastic input.
Essentially, performs the following steps:
- Create the
archetype_results_dictionaryby constructing theArchetypeBuildingResultsfor each entry in thearchetype_dictionary. - Create the
results__building_archetype__building_nodeRelationshipClassfor storing temperature results. - Create the
results__building_archetype__building_processRelationshipClassfor storing HVAC results. - Return the
archetype_results_dictionary, as well as the createdRelationshipClasses.
ArchetypeBuildingModel.write_to_url — Functionwrite_to_url(url::String, input::ModelInput; alternative::String="")Write model input data into the database at the url.
The alternative the parameter values are saved to depends on the given keyword
Internals
This section lists all the internal types and functions not exported by the module.
Types
ArchetypeBuildingModel.AbstractNode — TypeAbstractNode(
building_node_network::BuildingNodeNetwork,
node::Object,
weather::WeatherData,
) <: BuildingDataTypeContain parameters defining a node in a large-scale-energy-system-model-agnostic manner.
Essentially, a node is a point in a commodity network where commodity balance is observed. nodes can have a state, which represents accumulated commodities at the point. The state of a node can "bleed" either outside the model scope via the self_discharge_coefficient_kW_K, or into another nodes via the heat_transfer_coefficients_kW_K. The external_load_kW represents uncontrollable external influence affecting the node, e.g. commodity demand or gains.
This struct contains the following fields:
building_node::Object: Thebuilding_nodedefinition thisAbstractNodedepicts.thermal_mass_kWh_K::SpineDataType: The effective thermal mass of this node in [kWh/K].self_discharge_coefficient_kW_K::SpineDataType: The self-discharge coefficient in [kW/K] from this node.heat_transfer_coefficients_kW_K::Dict{Object,SpineDataType}: The heat transfer coefficients between this node and other nodes in [kW/K].external_load_kW::SpineDataType: Heat loads/gains on this node due to external influende, e.g. ambient conditions, inhabitants, solar irradiation, etc.minimum_temperature_K::SpineDataType: Minimum permitted temperature of the node in [K].maximum_temperature_K::SpineDataType: Maximum permitted temperature of the node in [K].
The constructor calls the process_abstract_node function.
ArchetypeBuildingModel.AbstractNodeNetwork — TypeAbstractNodeNetwork::Dict{Object,AbstractNode}Dict mapping AbstractNodes to their corresponding building_nodes.
ArchetypeBuildingModel.AbstractProcess — TypeAbstractProcess(process_data::BuildingProcessData; mod::Module = @__MODULE__) <: BuildingDataTypeContain parameters defining a process in a model-agnostic manner.
Essentially, a process is a commodity transfer/conversion from one node to another. For the purposes of the ArchetypeBuildingModel.jl, processes only have two attributes of interest: The ratio between total input and total output, and the maximum flows to and from the connected nodes.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
This struct contains the following fields:
building_process::Object: Thebuilding_processdefinition thisAbstractProcessdepicts.number_of_processes::Float64: The number of aggregated processes this one depicts for the large-scale energy system models.coefficient_of_performance::SpineDataType: The coefficient of performance of this process.maximum_flows::Dict{Tuple{Object,Object},SpineDataType}: The maximum flows to/from this process.
The constructor calls the process_abstract_system function.
ArchetypeBuildingModel.BuildingDataType — TypeBuildingDataTypeAbstract type for ArchetypeBuildingModel data structures.
ArchetypeBuildingModel.BuildingNodeData — TypeBuildingNodeData(
archetype::Object,
node::Object,
scope::ScopeData,
envelope::EnvelopeData,
loads::LoadsData;
mod::Module = @__MODULE__,
) <: BuildingDataTypeContains data about how the structures and systems are aggregated into nodes for the lumped-capacitance thermal model.
The BuildingNodeData struct aims to remain as human-readable as possible, making it a high-level description for what the lumped-capacitance node contains. Ultimately, BuildingNodeDatas are converted into AbstractNodes for exporting into energy-system-model-specific input data formats.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
This struct contains the following fields:
building_node::Object: Thebuilding_nodedefinition used for thisBuildingNodeData.thermal_mass_base_J_K::SpineDataType: Optional user-defined base effective thermal mass in [J/K] of the temperature node.thermal_mass_gfa_scaled_J_K::SpineDataType: Optional user-defined gross-floor-area-scaling effective thermal mass in [J/m2K] of the temperature node.thermal_mass_interior_air_and_furniture_J_K::Float64: The effective thermal mass contribution of the interior air and furniture on this temperature node.thermal_mass_structures_J_K::Float64: The effective thermal mass contribution of included structures on this temperature node.maximum_temperature_K::SpineDataType: The maximum permitted temperature of the node.minimum_temperature_K::SpineDataType: The minimum permitted temperature of the node.self_discharge_base_W_K::SpineDataType: Optional user-defined base self-discharge rate in [W/K] of the temperature node.self_discharge_gfa_scaled_W_K::SpineDataType: Optional user-defined gross-floor-area-scaling self-discharge rate in [W/m2K] of the temperature node.heat_transfer_coefficients_base_W_K::Dict{Object,SpineDataType}: Optional user-defined base heat transfer coefficients between this node and other temperature nodes.heat_transfer_coefficients_gfa_scaled_W_K::Dict{Object,SpineDataType}: Optional user-defined gross-floor-area-scaling heat transfer coefficients between this node and other temperature nodes.heat_transfer_coefficient_structures_interior_W_K::Float64: The contribution of included structures on the heat transfer coefficient between this node and the interior air node.heat_transfer_coefficient_structures_exterior_W_K::Float64: The contribution of included structures on the heat transfer coefficients between this node and the ambient temperature.heat_transfer_coefficient_structures_ground_W_K::Float64: The contribution of included structures on the heat transfer coefficient between this node and the effective ground temperature.heat_transfer_coefficient_windows_W_K::Float64: Contribution of windows to the heat transfer coefficient from this node to the ambient air.heat_transfer_coefficient_ventilation_and_infiltration_W_K::Float64: Contribution of infiltration and ventilation on the heat transfer coefficient between this node and the ambient air.heat_transfer_coefficient_thermal_bridges_W_K::Float64: Contribution of linear thermal bridges on the heat transfer coefficient between this node and the ambient air.domestic_hot_water_demand_W::SpineDataType: Domestic hot water demand in [W] on this node.internal_heat_gains_air_W::SpineDataType: Convective part of internal heat gains on this node in [W].internal_heat_gains_structures_W::SpineDataType: Radiative part of internal heat gains on this node in [W].solar_heat_gains_air_W::SpineDataType: Convective part of solar heat gains through windows on this node in [W].solar_heat_gains_structures_W::SpineDataType: Radiative part of solar heat gains through windows on this node in [W].solar_heat_gains_envelope_W::SpineDataType: Solar heat gains through the opaque building envelope [W].radiative_envelope_sky_losses_W::SpineDataType: Radiative heat losses to the sky from the exposed parts of the building envelope [W].interior_air_and_furniture_weight::Float64: The defined share of interior air and furniture assigned to this node.
The constructor calls the process_building_node function, and checks the values are sensible.
ArchetypeBuildingModel.BuildingNodeNetwork — TypeBuildingNodeNetwork::Dict{Object,BuildingNodeData}Dict mapping BuildingNodeData to their corresponding building_node Objects.
ArchetypeBuildingModel.StructureData — TypeStructureData <: BuildingDataTypeStore the important aggregated parameters for a structure type.
This type is used by the process_structure_scope function to store the gross-floor-area-averaged structural properties within the desired scope. Contains the following fields:
structure_type::Object: Type of the structure, e.g.base_floororroof.design_U_value_W_m2K::Float64: Design U-value of the structure in [W/m2K].effective_thermal_mass_J_m2K::Float64: Effective thermal mass of the structure in [J/m2K].external_U_value_to_ambient_air_W_m2K::Float64: U-value from the structure to ambient air in [W/m2K].external_U_value_to_ground_W_m2K::Float64: U-value from the structure to ground in [W/m2K].internal_U_value_to_structure_W_m2K::Float64: U-value from the structure to the interior air in [W/m2K].linear_thermal_bridges_W_mK::Float64: Linear thermal bridges in the structure in [W/mK].total_U_value_W_m2K::Float64: Total U-value through the structure.
Functions
ArchetypeBuildingModel._building_period_weight — Function_building_period_weight(building_period::Object, building_scope::Object; mod::Module = @__MODULE__)Calculate the weight of a building_period within a building_scope.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially, represents whether the building_period bp is contained within scope_period_start_year – scope_period_end_year in its entirety [1], only partially (0,1), or if at all [0].
\[w_\text{bp} = \text{max}\left( \text{min} \left( \frac{\text{end}_\text{scope} - \text{start}_\text{bp}}{\text{end}_\text{bp} - \text{start}_\text{bp}}, \frac{\text{end}_\text{bp} - \text{start}_\text{scope}}{\text{end}_\text{bp} - \text{start}_\text{bp}}, 1 \right), 0 \right)\]
ArchetypeBuildingModel._pyseries_to_timeseries — Function_pyseries_to_timeseries(
pyseries::PyCall.PyObject;
ignore_year::Bool = false,
repeat::Bool = true,
)Convert ArchetypeBuildingWeather.py output pandas.Series into a TimeSeries.
The optional keywords can be used to tweak how the TimeSeries is flagged. Default is a year-aware repeating timeseries.
ArchetypeBuildingModel.add_archetype_to_input! — Functionadd_archetype_to_input!(
backbone::BackboneInput,
result::ArchetypeBuildingResults;
mod::Module = @__MODULE__,
)Process and add the desired archetype building result into the backbone input.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
This is a very long and rather complicated function, which essentially translates the information contained in the result ArchetypeBuildingResults into the data structure in backbone BackboneInput, so that it is understood by the Backbone energy system model. The key steps taken by this function are summarized below:
- Map the ArchetypeBuildingModel
directionobjects to Backboneioobjects. - Create a
gridobject representing thearchetypebeing processed and map the grids. - Map the ArchetypeBuildingModel
building_nodeobjects to unique Backbonenodeobjects. - Identify the necessary system link nodes, and add them into the set of Backbone
nodeobjects with the desired names. - Include all building
nodes to the archetypegrid, and connect the system link nodes to their desiredgrids. - Map the ArchetypeBuildingModel
building_processobjects to unique Backboneunitobjects. - Determine Backbone
unitparameters based onAbstractProcessproperties. - Set the
directOffefficiency representation for allunits. - Determine Backbone
grid__nodeparameters based onAbstractNodeproperties. - Determine Backbone
grid__node__boundaryparameters based onAbstractNodemaximum and minimum permitted temperatures. - Determine Backbone
grid__node__nodeparameters based onAbstractNodeheat transfer coefficients. - Determine Backbone
grid__node__unit__ioparameters based onAbstractProcessmaximum flows. - Set the
HVACunittypefor everyunit.
add_archetype_to_input!(
spineopt::SpineOptInput,
result::ArchetypeBuildingResults;
mod::Module = @__MODULE__,
)Process and add the desired archetype building result into the spineopt input.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
This is a very long and rather complicated function, which essentially translates the information contained in the result ArchetypeBuildingResults into the data structure in spineopt SpineOptInput, so that it is understood by the SpineOpt energy system model. The key steps taken by this function are summarized below:
- Map the ArchetypeBuildingModel
building_nodeobjects to unique SpineOptnodeobjects. - Identify the necessary system link nodes, and add them into the set of SpineOpt
nodeobjects with the desired names. - Map the ArchetypeBuildingModel
building_processobjects to unique SpineOptunitobjects. - Determine SpineOpt
nodeparameters based on theAbstractNodeproperties. - Determine SpineOpt
node__nodeparameters based on theAbstractNodeheat transfer coefficients. - Determine SpineOpt
unit__from_nodeandunit__to_nodeparameters based on theAbstractProcessmaximum flow parameters. - Determine SpineOpt
unit__node__nodeparameters based on theAbstractProcessproperties.
add_archetype_to_input!(
generic::GenericInput,
result::ArchetypeBuildingResults
)Add ArchetypeBuildingResults to GenericInput.
Essentially goes over the fields of the contained ArchetypeBuilding and parses them into Map for Spine export.
ArchetypeBuildingModel.add_system_link_node_parameters! — Functionadd_system_link_node_parameters!(
backbone::BackboneInput,
results::Dict{Object,ArchetypeBuildingResults};
mod::Module = @__MODULE__,
)Add system link node parameters into BackboneInput.
ArchetypeBuildingModel.aggregate_gfa_weights — Functionaggregate_gfa_weights(gross_floor_area_weights::Dict{NTuple{5,Object},Float64})Aggregate gross_floor_area_weights for ventilation/infiltration and weather data processing.
Essentially, sums over the gross-floor area weights of unused dimensions to produce reduced sets of weights.
\[w_\text{bt,bp,lid} = \sum_\text{bp,hs} w_\text{bs,bt,bp,lid,hs} \\ w_\text{lid} = \sum_\text{bt,bp} w_\text{bt,bp,lid},\]
where w_bs,bt,bp,lid,hs are the full gross-floor area weights calculated using calculate_gross_floor_area_weights.
ArchetypeBuildingModel.calculate_base_floor_dimensions — Functioncalculate_base_floor_dimensions(
data::ScopeData,
storeys::Real,
frame_depth_m::Real
)Calculate the base floor dimensions, assuming a rectangular building.
Essentially, calculates the surface area of the base floor in [m2] A_bf, as well as the thermal bridge length [m] l_bf based on the known gross-floor area (GFA), the assumed number of storeys, and the assumed frame depth of the building. The thermal bridge length is simply assumed to correspond to the length of the perimeter of the base floor.
\[A_\text{bf} = \frac{A_\text{GFA}}{n_\text{storeys}}, \\ l_\text{bf} = 2 \left( \frac{A_\text{bf}}{d_\text{frame}} + d_\text{frame} \right),\]
where A_GFA is the gross-floor area of the building in [m2] based on the ScopeData, n_storeys is the assumed number_of_storeys, and d_frame is the assumed building_frame_depth_m.
ArchetypeBuildingModel.calculate_cop — Functioncalculate_cop(
weather::WeatherData,
COP_mode::Symbol,
process::Object;
mod::Module = @__MODULE__,
)Calculate the potentially time-varying coefficient of performance.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Uses the given COP_mode, sink_temperature_K, and source_temperature_K to calculate a potentially weather-dependent coefficient of performance. Based on the exergetic approach in EN 15316-4-2:2017 Annex D, where a known reference COP is extrapolated to unknown temperature ranges using the Carnot COP.
\[\text{COP}_{T_\text{in}, T_\text{out}} = \text{COP}_\text{base} \frac{T_\text{out}}{T_\text{out} - T_\text{in}}, \\ \text{where } \text{COP}_\text{base} = \frac{\text{COP}_\text{ref}}{\text{COP}_\text{carnot,ref}}\]
NOTE! Setting COP_mode to cooling simply flips the temperatures for the Carnot cop calculation!
If the source and sink temperatures are undefined, returns the defined base COP as the COP is assumed to be weather independent. See the archetype_definitions.json default values for sink_temperature_K and source_temperature_K for the different options how the COP can be made dependent on the weather.
ArchetypeBuildingModel.calculate_convective_internal_heat_gains — Functioncalculate_convective_internal_heat_gains(
archetype::Object
loads::LoadsData,
interior_weight::Real;
mod::Module = @__MODULE__,
)Calculate the convective internal heat gains on the node in [W].
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially, takes the given internal heat gain profile in loads and multiplies it with the share of interior air on this node as well as the assumed convective fraction of internal heat gains.
\[\Phi_\text{int,conv,n} = w_\text{int,n} f_\text{int,conv} \Phi_\text{int}\]
where w_int,n is the interior_air_and_furniture_weight of this node, f_int,conv is the assumed internal_heat_gain_convective_fraction, and Φ_int are the total internal heat gains of the building. See calculate_total_internal_heat_loads for how the total internal heat loads are calculated.
ArchetypeBuildingModel.calculate_convective_solar_gains — Functioncalculate_convective_solar_gains(
archetype::Object
loads::LoadsData,
interior_weight::Real;
mod::Module = @__MODULE__,
)Calculate the convective solar heat gains through windows on the node in [W].
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially, takes the given solar heat gain profile in loads and multiplies it with the share of interior air on this node as well as the assumed convective fraction of solar heat gains.
\[\Phi_\text{sol,conv,n} = w_\text{int,n} f_\text{sol,conv} \Phi_\text{sol}\]
where w_int,n is the interior_air_and_furniture_weight of this node, f_sol,conv is the assumed solar_heat_gain_convective_fraction, and Φ_sol are the total solar heat gains into the building. See calculate_total_solar_gains for how the total solar heat gains are calculated.
ArchetypeBuildingModel.calculate_effective_ground_temperature — Functioncalculate_effective_ground_temperature(
ambient_temp_K::SpineDataType;
coeff::Real = 1.7
realization::Symbol = :realization,
)Calculate the effective ground temperature based on the ambient temperature.
The method used in this function is based on Kissock et al., Simplified Model for Ground Heat Transfer from Slab-on-Grade buildings, ASHRAE Transactions 2013
\[\frac{a * T_\text{ambient annual average} + T_\text{ambient 3-month moving average}}{1 + a},\]
where the default coeff is a=1.7.
NOTE! The ambient temperature timeseries is assumed to repeat when calculating the annual and 3-month moving averages.
ArchetypeBuildingModel.calculate_envelope_solar_gains — Functioncalculate_envelope_solar_gains(
archetype::Object,
scope::ScopeData,
envelope::EnvelopeData,
weather::WeatherData;
mod::Module = @__MODULE__,
)Calculate the solar heat gains [W] per envelope structure_type.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Loosely based on EN ISO 52016-1:2017 Section 6.5.6.3.5, approximately accounts for the incident solar irradiation, while approximate radiative sky heat losses from the envelope are handled via calculate_envelope_radiative_sky_losses. Solar heat gains through windows are handled via calculate_total_solar_gains.
Essentially, the exterior of the surface is assumed to have negligible thermal mass, and the impact of the incident irradiation is applied to the structural node directly. The solar gains Φ_sol,st need to be calculated separately for each structure_type, as they are dependent on the exterior surface resistance:
\[\Phi_\text{sol,st} = R_\text{e,st} U_\text{ext,st} A_\text{st} a_\text{sol} \left( I_\text{diff} + F_\text{shading} \frac{\sum_{d \in D_\text{st}} I_\text{dir,d}}{\sum_{d \in D_\text{st}} 1} \right)\]
where R_e,st is the exterior_resistance_m2K_W of structure st, U_ext,st is the external_U_value_to_ambient_air_W_m2K of structure st, A_st is the surface area of the corresponding envelope structure (See EnvelopeData), a_sol is the assumed average_structural_solar_absorption_coefficient, I_diff is the diffuse_solar_irradiation_W_m2, F_shading is the assumed external_shading_coefficient, d represents either horizontal or cardinal directions, and I_dir,d is the direct_solar_irradiation_W_m2.
NOTE! The walls are assumed to be distributed equally towards all the cardinal directions.
ArchetypeBuildingModel.calculate_envelope_radiative_sky_losses — Functioncalculate_envelope_radiative_sky_losses(
archetype::Object,
scope::ScopeData,
envelope::EnvelopeData;
mod::Module = @__MODULE__,
)Calculate the envelope radiative sky losses [W] per structure_type.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Loosely based on EN ISO 52016-1:2017 Section 6.5.13.3, approximately accounts for the radiative sky heat losses of the building envelope. Solar heat gains through the building envelope are handled via calculate_envelope_solar_gains.
Essentially, the exterior of the surface is assumed to have negligible thermal mass, and the impact of radiative sky losses are applied to the structural node directly. The radiative sky heat losses Φ_sky,st are calculated for each structure as
\[\Phi_\text{sky,st} = R_\text{e,st} U_\text{ext,st} A_\text{st} F_\text{sky,st} h_\text{re} \Delta T_\text{sky}\]
where R_e,st is the exterior_resistance_m2K_W of structure st, U_ext,st is the external_U_value_to_ambient_air_W_m2K of structure st, A_st is the surface area of the corresponding envelope structure (See EnvelopeData), F_sky,st is the assumed sky view factor (hardcoded for now) for structure st, h_re is the assumed external_radiative_surface_heat_transfer_coefficient_W_m2K, and ΔT_sky is the assumed average_apparent_sky_temperature_difference_K.
ArchetypeBuildingModel.calculate_exterior_wall_dimensions — Functioncalculate_exterior_wall_dimensions(
vertical_envelope_area_m2::Real,
window::NamedTuple,
load_bearing_fraction::Real,
storeys::Real,
room_height_m::Real
)Calculate the dimensions of exterior walls, assuming a rectangular building.
The exterior wall surface area [m2] A_ewlb is calculated simply as the difference between vertical envelope area and the window surface area. The linear thermal bridge length [m] includes the corners of the exterior walls. The results are provided for load-bearing and light exterior walls separately, based on the assumed load-bearing fraction of the external walls.
\[A_\text{ewlb} = f_\text{lb} \left( A_\text{vertical envelope} - A_\text{w} \right), \\ l_\text{ewlb} = 4 f_\text{lb} \lceil n_\text{storeys} \rceil h_\text{room}\]
where f_lb is the assumed external_wall_load_bearing_fraction, A_vertical_envelope is the vertical envelope surface area of the building, A_w is the window surface area, n_storeys is the assumed number_of_storeys, and h_room is the assumed room_height_m. See calculate_vertical_envelope_surface_area and calculate_window_dimensions for how the vertical envelope and window areas are calculated.
The dimensions of light exterior walls are calculated similarly to the above, except that (1-f_lb) is used as the coefficient instead.
Returns the load-bearing exterior wall dimensions first, and the light exterior wall dimensions second.
ArchetypeBuildingModel.calculate_gross_floor_area_weights — Functioncalculate_gross_floor_area_weights(
scope::Object,
relevant_building_stock_statistics::Vector,
building_period_weights::Dict{Object,T} where T <: Real;
mod::Module = @__MODULE__,
)Calculate the gross-floor area weights for the relevant_building_stock_statistics.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially, returns a normalized weight for each relevant entry in the input data statistics, corresponding to how impactful it is when aggregating the properties for the given scope. The weights of the individual dimensions are assumed to be one, unless otherwise specified in The building_scope definition. Also returns the total number of buildings and the total weighted gross-floor area included in the building_scope.
\[w_\text{bs,bt,bp,lid,hs} = \frac{w_\text{bs} w_\text{bt} w_\text{bp} w_\text{lid} w_\text{hs} n_\text{bs,bt,bp,lid,hs} A_\text{gfa,bs,bt,bp,lid,hs}}{\sum_{bs,bt,bp,lid,hs} w_\text{bs,bt,bp,lid,hs}}\]
where w_bs is the building_stock_weight, w_bt is the building_type_weight, w_bp is the _building_period_weight, w_lid is the location_id_weight, w_hs is the heat_source_weight, n_bs,bt,bp,lid,hs is the number_of_buildings, and A_gfa is the average_gross_floor_area_m2_per_building.
ArchetypeBuildingModel.calculate_interior_air_and_furniture_thermal_mass — Functioncalculate_interior_air_and_furniture_thermal_mass(
archetype::Object,
scope::ScopeData,
interior_weight::Real;
mod::Module = @__MODULE__,
)Calculate the effective thermal mass of interior air and furniture on node in [J/K].
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially, the calculation is based on the gross-floor area [m2] of the archetype building, the assumed effective thermal capacity of interior air and furniture, and the assumed share of interior air and furniture weight on the node.
\[C_\text{int,n} = w_\text{int,n} c_\text{int,gfa} A_\text{gfa}\]
where w_int,n is the interior_air_and_furniture_weight on this building_node, c_int,gfa is the assumed effective_thermal_capacity_of_interior_air_and_furniture_J_m2K, and A_gfa is the gross-floor area of the building.
ArchetypeBuildingModel.calculate_total_thermal_bridge_heat_transfer_coefficient — Functioncalculate_total_thermal_bridge_heat_transfer_coefficient(
archetype::Object,
scope::ScopeData,
envelope::EnvelopeData,
interior_weight::Real;
mod::Module = @__MODULE__,
)Calculate total thermal bridge heat transfer coefficient.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Thermal bridges are assumed to bypass the temperature node within the structure, and act as direct heat transfer between the indoor air and ambient conditions.
\[H_{\Psi,n} = w_\text{int,n} \left( \Delta U_\text{w,tb} A_w + \sum_\text{st} \left[ l_\text{st} \Psi_\text{st} \right] \right)\]
where w_int,n is the interior_air_and_furniture_weight of this node, ΔU_w,tb is the window_area_thermal_bridge_surcharge_W_m2K, A_w is the window surface area based on calculate_window_dimensions, st is the structure_type, l_st is the length of the linear thermal bridge of structure st, and Ψ_st is the linear_thermal_bridges_W_mK.
ArchetypeBuildingModel.calculate_partition_wall_dimensions — Functioncalculate_partition_wall_dimensions(
vertical_envelope_area_m2::Real,
partition_wall_ratio::Real,
load_bearing_fraction::Real
)Calculate the partition wall dimensions, assuming a rectangular building.
The one-sided partition wall surface area [m2] is calculated based on the vertical envelope area of the building, and the assumed ratio between partition walls and vertical envelope. The linear thermal bridge length [m] is set to zero, as producing any actual estimation would require a lot more information about the layout of the building. The results are provided for load-bearing and light exterior walls separately, based on the assumed load-bearing faction.
\[A_\text{pwlb} = f_\text{lb} r_\text{pw} A_\text{vertical envelope}, \\ l_\text{pwlb} = 0\]
where f_lb is the assumed partition_wall_load_bearing_fraction, r_pw is the assumed partition_wall_length_ratio_to_external_walls_m_m, and A_vertical_envelope is the vertical envelope area of the building. See calculate_vertical_envelope_surface_area for how the vertical envelope area is calculated.
The dimensions of light partition walls are calculated similarly to the above, except that (1-f_lb) is used as the coefficient instead.
Returns the load-bearing partition wall dimensions first, and the light partition wall dimensions second.
ArchetypeBuildingModel.calculate_radiative_internal_heat_gains — Functioncalculate_radiative_internal_heat_gains(
archetype::Object,
node::Object,
envelope::EnvelopeData,
loads::LoadsData,
total_structure_area_m2::Real;
mod::Module = @__MODULE__,
)Calculate the radiative internal heat gains on the node in [W].
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially, takes the given internal heat gain profile in loads and multiplies it with the assumed radiative fraction of internal heat gains. The radiative heat gains are assumed to be distributed across the structures simply based on their relative surface areas. Note that currently, radiative internal heat gains are partially lost through windows!
\[\Phi_\text{int,rad,n} = (1 - f_\text{int,conv}) \frac{\sum_{\text{st} \in n} w_\text{n,st} A_\text{st}}{\sum_{\text{st}} A_\text{st}} \Phi_\text{int}\]
where f_int,conv is the assumed internal_heat_gain_convective_fraction, st is the structure_type and n is this building_node, w_n,st is the structure_type_weight of the structure st on this node, A_st is the surface area of structure st, and Φ_int are the total internal heat gains of the building. See calculate_total_internal_heat_loads for how the total internal heat loads are calculated.
ArchetypeBuildingModel.calculate_radiative_solar_gains — Functioncalculate_radiative_solar_gains(
archetype::Object,
node::Object,
envelope::EnvelopeData,
loads::LoadsData,
total_structure_area_m2::Real;
mod::Module = @__MODULE__,
)Calculate the radiative solar heat gains through windows on the node in [W].
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially, takes the given solar heat gain profile in loads and multiplies it with the assumed radiative fraction of solar heat gains. The radiative heat gains are assumed to be distributed across the structures simply based on their relative surface areas. Note that currently, radiative solar heat gains are partially lost through windows!
\[\Phi_\text{sol,rad,n} = (1 - f_\text{sol,conv}) \frac{\sum_{\text{st} \in n} w_\text{n,st} A_\text{st}}{\sum_{\text{st}} A_\text{st}} \Phi_\text{sol}\]
where f_sol,conv is the assumed solar_heat_gain_convective_fraction, st is the structure_type and n is this building_node, w_n,st is the structure_type_weight of the structure st on this node, A_st is the surface area of structure st, and Φ_sol are the total solar heat gains into the building. See calculate_total_solar_gains for how the total solar heat gains are calculated.
ArchetypeBuildingModel.calculate_roof_dimensions — Functioncalculate_roof_dimensions(
base_floor::NamedTuple,
storeys::Real,
frame_depth_m::Real
)Calculate the roof dimensions assuming a rectangular building.
Essentially, calculates the surface area of the roof in [m2] A_r, as well as the thermal bridge length [m] l_r based on the dimensions of the base floor. The thermal bridge length is simply assumed to correspond to the length of the perimeter of the roof, and in case of a partial top floor, the roof is divided into two separate surfaces, thus increasing the thermal bridge length.
\[A_\text{r} = A_\text{bf}, \\ l_\text{r} = \begin{cases} l_\text{bf}, \qquad n_\text{storey} \in \mathbb{N} \\ l_\text{bf} + 2 d_\text{frame}, \qquad n_\text{storey} \notin \mathbb{N} \end{cases}\]
where A_bf is the surface area of the base floor according to, l_bf is the thermal bridge (perimeter) length of the base floor, and d_frame is the assumed building_frame_depth_m. See calculate_base_floor_dimensions for how the base floor dimensions are calculated.
ArchetypeBuildingModel.calculate_separating_floor_dimensions — Functioncalculate_separating_floor_dimensions(
data::ScopeData,
base_floor::NamedTuple,
storeys::Real,
frame_depth_m::Real
)Calculate the separating floor dimensions assuming a rectangular building.
Essentially, calculates the one-sided surface area of the separating floors in [m2] A_sf, as well as the thermal bridge length [m] l_sf based on the known gross-floor area (GFA), the assumed number of storeys, and the dimensions of the base floor. The thermal bridge length is assumed to correspond to the length of the perimeter of the separating floors.
\[A_\text{sf} = A_\text{GFA} - A_\text{bf}, \\ l_\text{sf} = \begin{cases} \left( \lfloor n_\text{storeys} \rfloor - 1 \right) l_\text{bf}, \quad & n_\text{storeys} \in \mathbb{N} \\ \left( \lfloor n_\text{storeys} \rfloor - 1 \right) l_\text{bf} + 2 \left( \frac{A_\text{bf} (n_\text{storeys} - \lfloor n_\text{storeys} \rfloor)}{d_\text{frame}} + d_\text{frame} \right), \quad & n_\text{storeys} \notin \mathbb{N} \end{cases}\]
where A_GFA is the gross-floor area of the building, A_bf is the surface area of the base floor, n_storeys is the assumed number_of_storeys, l_bf is the linear thermal bridge (perimeter) length of the base floor, and d_frame is the assumed building_frame_depth_m. See calculate_base_floor_dimensions) for how the base floor dimensions are calculated.
ArchetypeBuildingModel.calculate_structural_exterior_heat_transfer_coefficient — Functioncalculate_structural_exterior_heat_transfer_coefficient(
node::Object,
scope::ScopeData,
envelope::EnvelopeData,
interior_weight::Real
)Calculate the total exterior heat transfer coefficient of the structures in node in [W/K].
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially, calculates the total heat transfer coefficient between the ambient air and the node containing the structures. Internal structures have no exterior heat transfer coefficient, as they are assumed to not be part of the building envelope. If an external structure is lumped together with the interior air node, it's internal heat transfer coefficient is attributed to its exterior heat transfer as well, but using this feature is not recommended!
\[H_\text{ext,n} = \sum_{\text{st} \in n} w_\text{n,st} \left( \frac{1}{U_\text{ext,st}} + \frac{w_{int,n}}{U_\text{int,st}} \right)^{-1} A_\text{st}\]
where st is the structure_type and n is the building_node, w_n,st is the structure_type_weight of the structure st on this node, U_ext,st is the external_U_value_to_ambient_air_W_m2K of structure st, w_int,n is the interior_air_and_furniture_weight of this node, U_int,st is the internal_U_value_to_structure_W_m2K of structure st, and A_st is the surface area of structure st.
ArchetypeBuildingModel.calculate_structural_ground_heat_transfer_coefficient — Functioncalculate_structural_ground_heat_transfer_coefficient(
archetype::Object,
node::Object,
scope::ScopeData,
envelope::EnvelopeData;
mod::Module = @__MODULE__,
)Calculate the total ground heat transfer coefficient of the structures in node in [W/K].
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially, calculates the total heat transfer coefficient between the ground and the node containing the structures according to the simplified method proposed by K.Kissock in: Simplified Model for Ground Heat Transfer from Slab-on-Grade Buildings, (c) 2013 ASHRAE
\[H_\text{grn,n} = \left( 1 + \frac{d_\text{frame}^2}{A_\text{bf}} \right) \sum_{\text{st} \in n} w_\text{n,st} U_\text{grn,st} A_\text{st}\]
where d_frame is the assumed building_frame_depth_m, A_bf is the area according to calculate_base_floor_dimensions, st is the structure_type and n is the building_node, w_n,st is the structure_type_weight of the structure st on this node, U_grn,st is the external_U_value_to_ground_W_m2K of structure st, and A_st is the surface area of structure st. Note that the correction factor C = (length + width) / length = 1 + d_frame^2 / A_bf in the above equation assumes that d_frame < A_bf / d_frame. If d_frame > A_bf / d_frame, the correction term becomes 1 + A_bf / d_frame^2 instead.
ArchetypeBuildingModel.calculate_structural_interior_heat_transfer_coefficient — Functioncalculate_structural_interior_heat_transfer_coefficient(
node::Object,
scope::ScopeData,
envelope::EnvelopeData,
interior_weight::Real;
mod::Module = @__MODULE__,
)Calculate the total interior heat transfer coefficient of the structures in node in [W/K].
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially, initializes the total heat transfer coefficient between the interior air node and the node containing the structures. For internal structures, the U-values for both the interior and exterior surface are used, effectively accounting for both sides of interior structures. If an external structure is lumped together with the interior air node, it's internal heat transfer coefficient is attributed to its exterior heat transfer instead, but using this feature is not recommended!
\[H_\text{int,n} = \begin{cases} (1 - w_\text{int,n}) \sum_{\text{st} \in n} w_\text{n,st} U_\text{int,st} A_\text{st} \qquad \text{st} \notin \text{internal structures} \\ (1 - w_\text{int,n}) \sum_{\text{st} \in n} w_\text{n,st} ( U_\text{int,st} + U_\text{ext,st} ) A_\text{st} \qquad \text{st} \notin \text{internal structures} \end{cases}\]
where w_int,n is the interior_air_and_furniture_weight on this building_node n, st is the structure_type, w_n,st is the structure_type_weight of the structure st on this node, U_int,st is the internal_U_value_to_structure_W_m2K of structure st, and A_st is the surface area of structure st. A structure st is considered internal if the is_internal flag is true.
ArchetypeBuildingModel.calculate_structural_thermal_mass — Functioncalculate_structural_thermal_mass(
node::Object,
scope::ScopeData,
envelope::EnvelopeData;
mod::Module = @__MODULE__,
)Calculate the effective thermal mass of the structures on node in [J/K].
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially, sums the total effective thermal mass of the structures attributed to this node, accounting for their assigned weights.
\[C_\text{n,str} = \sum_{\text{st} \in n} w_\text{n,st} c_\text{st} A_\text{st}\]
where st is the structure_type and n is the building_node, w_n,st is the structure_type_weight of the structure st on this node, c_stis the effective_thermal_mass_J_m2K of the structure, and A_st is the surface area of the structure.
ArchetypeBuildingModel.calculate_total_dhw_demand — Functioncalculate_total_dhw_demand(loads::Object, scope::ScopeData; mod::Module = @__MODULE__)Calculate the total domestic hot water (DHW) demand.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially, simply adds the fixed base DHW demand and the gross-floor-area-scaling DHW demand together for the given loads and scope.
\[\Phi_\text{DHW} = \Phi_\text{DHW,base} + \phi_\text{DHW,gfa} A_\text{gfa}\]
where Φ_DHW,base is the assumed domestic_hot_water_demand_base_W, Φ_DHW,gfa is the assumed domestic_hot_water_demand_gfa_scaling_W_m2, and A_gfa is the gross-floor area of the building.
ArchetypeBuildingModel.calculate_total_envelope_solar_gains — Functioncalculate_total_envelope_solar_gains(
node::Object,
loads::LoadsData;
mod::Module = @__MODULE__,
)Calculate the total solar heat gain [W] through the opaque envelope on this node.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
\[\Phi_\text{env,n} = \sum_{st \in n} w_\text{n,st} \Phi_\text{sol,st},\]
w_n,st is the structure_type_weight of the structure st on this node n, and Φ_sol,st are the heat gains through envelope structures using calculate_envelope_solar_gains.
ArchetypeBuildingModel.calculate_total_envelope_radiative_sky_losses — Functioncalculate_total_envelope_radiative_sky_losses(
node::Object,
loads::LoadsData;
mod::Module = @__MODULE__,
)Calculate the total radiative envelope sky heat losses [W] for this node.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
\[\Phi_\text{sky,n} = \sum_{st \in n} w_\text{n,st} \Phi_\text{sky,st},\]
w_n,st is the structure_type_weight of the structure st on this node n, and Φ_sky,st are the envelope radiative sky heat losses using calculate_envelope_radiative_sky_losses.
ArchetypeBuildingModel.calculate_total_internal_heat_loads — Functioncalculate_total_internal_heat_loads(
loads::Object,
scope::ScopeData;
mod::Module = @__MODULE__
)Calculate the total internal heat gains.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially, simply adds the fixed base internal gains and the gross-floor-area-scaling DHW demand together for the given loads and scope.
\[\Phi_\text{int} = \Phi_\text{int,base} + \phi_\text{int,gfa} A_\text{gfa}\]
where Φ_int,base is the assumed internal_heat_loads_base_W, Φ_int,gfa is the assumed internal_heat_loads_gfa_scaling_W_m2, and A_gfa is the gross-floor area of the building.
ArchetypeBuildingModel.calculate_total_solar_gains — Functioncalculate_total_solar_gains(
archetype::Object,
scope::ScopeData,
envelope::EnvelopeData,
weather::WeatherData;
mod::Module = @__MODULE__,
)Calculate the total solar heat gains through the windows.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Loosely based on EN ISO 52016-1:2017 6.5.13.2, accounting for the solar heat gains through the windows of the building. Solar heat gains through the envelope are handled via calculate_envelope_solar_gains.
The varying angle of incidence of the irradiation on the windows is accounted for using a very simple average non-perpendicularity factor. The frame-area fraction of the windows is accounted for in the solar energy transmittance, and window area distribution is handled using the shares towards cardinal directions.
\[\Phi_\text{sol} = f_\text{np} g_\text{gl} A_\text{w} \left( I_\text{diff} + F_\text{shading} \sum_{d \in \text{N,E,S,W}} w_d I_\text{dir,d} \right)\]
where f_np is the assumed window_non_perpendicularity_correction_factor, g_gl is the total_normal_solar_energy_transmittance of the glazing, A_w is the area of the windows, I_diff is the diffuse_solar_irradiation_W_m2, F_shading is the assumed external_shading_coefficient, d represents the cardinal directions, w_d is the window_area_distribution_towards_cardinal_directions, and I_dir,d is the direct_solar_irradiation_W_m2.
ArchetypeBuildingModel.calculate_ventilation_and_infiltration_heat_transfer_coefficient — Functioncalculate_ventilation_and_infiltration_heat_transfer_coefficient(
archetype::Object,
scope::ScopeData,
interior_weight::Real;
mod::Module = @__MODULE__,
)Calculate ventilation and infiltration heat transfer coefficient.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Ventilation and infiltration are assumed to transfer heat directly between the interior and ambient air. Loosely based on EN ISO 52016-1:2017 6.5.10.1.
\[H_\text{ven,n} = w_\text{int,n} A_\text{gfa} h_\text{room} \rho_\text{air} \frac{ (1 - \eta_\text{hru}) r_\text{ven} + r_\text{inf}}{3600}\]
where w_int,n is the interior_air_and_furniture_weight of this node, A_gfa is the gross-floor area of the building, h_room is the assumed room_height_m, ρ_air is the assumed volumetric_heat_capacity_of_interior_air_J_m3K, η_hru is the HRU_efficiency (heat recovery unit), r_ven is the ventilation_rate_1_h, and r_inf is the infiltration_rate_1_h. The division by 3600 accounts for the unit conversion from J to Wh.
ArchetypeBuildingModel.calculate_vertical_envelope_surface_area — Functioncalculate_vertical_envelope_surface_area(
base_floor::NamedTuple,
separating_floor::NamedTuple,
room_height_m::Real,
)Calculate the vertical envelope surface area [m2] assuming a rectangular building.
An auxiliary function used for window and exterior wall calculations.
\[A_\text{vertical envelope} = h_\text{room} \left( l_\text{bf} + l_\text{sf} \right)\]
where h_room is the assumed room_height_m, l_bf is the linear thermal bridge (perimeter) length of the base floor, and l_sf is the linear thermal bridge (perimeter) length of any separating floors. See calculate_base_floor_dimensions and calculate_separating_floor_dimensions for how the dimensions of the base and separating floors are calculated.
ArchetypeBuildingModel.calculate_window_dimensions — Functioncalculate_window_dimensions(
vertical_envelope_area_m2::Real,
window_to_wall_ratio::Real
)Calculate the window dimensions assuming a rectangular building.
Calculates the window surface area [m2] A_w simply using the assumed window-to-wall ratio. The linear thermal bridge lenght l_w is set to zero, as it's not really applicable without significantly better information about the number and size of the individual windows.
\[A_\text{w} = w A_\text{vertical envelope}, \\ l_\text{w} = 0\]
where w is the assumed window_area_to_external_wall_ratio_m2_m2, and A_vertical_envelope is the total vertical envelope area of the building. See calculate_vertical_envelope_surface_area for how the vertical envelope area is calculated.
ArchetypeBuildingModel.calculate_window_heat_transfer_coefficient — Functioncalculate_window_heat_transfer_coefficient(
scope::ScopeData,
envelope::EnvelopeData,
interior_weight::Real
)Calculate the total heat transfer coefficient for windows.
Windows are assumed to transfer heat directly between the indoor air and the ambient air.
\[H_\text{w,n} = w_\text{int,n} U_\text{w} A_\text{w}\]
where w_int,n is the interior_air_and_furniture_weight of this node, U_w is the window_U_value_W_m2K, and A_w is the surface area of the windows.
ArchetypeBuildingModel.collect_leaf_values — Functioncollect_leaf_values(x::T) where T ∈ {SpineDataType,AbstractArray,AbstractDict}Returns an Array of the leaf values contained in any SpineDataType.
ArchetypeBuildingModel.determine_temporal_structure — Functiondetermine_temporal_structure(
archetype::ArchetypeBuilding;
realization::Symbol = :realization,
)Check that external_load_kW timeseries are consistent in the AbstractNodeNetwork, and determine the time series indices and the delta_t.
Note that the time series need to have a constant delta_t. The realization keyword is necessary to indicate the true data from potentially stochastic input.
ArchetypeBuildingModel.form_and_invert_dynamics_matrix — Functionform_and_invert_dynamics_matrix(
archetype::ArchetypeBuilding,
t::DateTime,
delta_t::Int64,
)Forms and inverts the implicit Euler discretized dynamics matrix for the AbstractNodeNetwork.
The implicit Euler discretized dynamics matrix A is formed as follows:
\[\boldsymbol{A}_{n,m} = \begin{cases} \frac{C_m}{\Delta t} + \rho_m + \sum_{n' \in N} H_{n,m}, \qquad n = m, \\ - H_{n,m}, \qquad n \neq m, \end{cases}, \quad \text{where } n, m \in N\]
where A_n,m is the element of the dynamic matrix A on row n and column m, C_m is the thermal mass of node m, Δt is the length of the discretized time step, ρ_m is the self-discharge coefficient of node m, N is the set of nodes included in the lumped-capacitance thermal model, and H_{m,n} is the heat transfer coefficient between nodes n and m.
ArchetypeBuildingModel.form_and_invert_hvac_matrix — Functionform_and_invert_hvac_matrix(
dynamics_matrix::Matrix{Float64},
temp_check::BitVector
)Forms and inverts the matrix for solving HVAC demand in different situations.
Essentially, this function performs the
\[\left( \boldsymbol{A} - \sum_{m \in M}[\boldsymbol{A}_{m} + \boldsymbol{I}_{m}] \right)^{-1}\]
transformation of the dynamics matrix A, where the otherwise violated temperature variables m ∈ M are fixed and replaced with a variable for the required heating/cooling demand. See the solve_heating_demand function for the overall formulation.
ArchetypeBuildingModel.initialize_temperatures — Functioninitialize_temperatures(
archetype::ArchetypeBuilding,
indices::Vector{DateTime},
delta_t::Int64,
external_load_vector::Vector{Vector{Float64}},
thermal_mass_vector::Vector{Float64},
free_dynamics::Bool,
initial_temperatures::Union{Nothing,Dict{Object,Float64}},
)Initialize the temperature and temperature limit vectors for the heating/cooling demand calculations.
Initial temperatures are solved by repeatedly solving the first 24 hours until the end-result no longer changes. The initialization is abandoned if no stable initial temperatures are found within a thousand 24-hour solves. In this case, the minimum permitted temperatures are used as the initial temperatures for each node, unless otherwise specified via initial_temperatures. Internally, uses the solve_heating_demand_loop function.
See the solve_heating_demand function for the overall logic and formulation of the heating demand calculations.
ArchetypeBuildingModel.initialize_rhs — Functioninitialize_rhs(
archetype::ArchetypeBuilding,
indices::Vector{Dates.DateTime},
delta_t::Int64;
realization::Symbol = :realization,
)Initialize the right-hand side of the linear equation system, meaning the impact of the external_load_kW and previous temperatures.
The realization keyword is used to indicate the true data from potentially stochastic input.
See the solve_heating_demand function for the overall formulation. This function returns the right-hand side components separately
\[\hat{\Phi} = \hat{\Phi'} + \frac{C}{\Delta t} \hat{T}_{t-\Delta t},\]
where Φ' is the component of external loads, and the rest is the component of the impact of previous temperatures. The components are useful for the solve_heating_demand_loop function.
ArchetypeBuildingModel.load_definitions_template — Functionload_definitions_template()Read the archetype_definitions.json into Dict`.
ArchetypeBuildingModel.process_abstract_node — Functionprocess_abstract_node(
building_node_network::BuildingNodeNetwork,
node::Object,
weather::WeatherData
)Calculate the properties of an AbstractNode corresponding to the node in the building_node_network.
Combines all the individual parameters in BuildingNodeDatas in BuildingNodeNetwork into the bare minimum parameters required for modelling lumped-capacitance thermal nodes in our energy system modelling frameworks.
Essentially, this function performs the following steps:
- Sum all the thermal mass components together and convert into [Wh/K].
- Sum all the self-discharge and ambient heat transfer components together.
- Collect heat transfer coefficients between the interior air node and this one.
- Update heat transfer coefficients based on user-defined coefficients.
- Sum together the internal heat gains, solar gains, radiative sky heat losses, DHW demand, as well as the impact of ambient temperatures.
- Return the components required for constructing an
AbstractNode.
NOTE! The ambient temperatures are accounted for via a combination of self_discharge_coefficient_kW_K and external_load_kW, instead of heat_transfer_coefficients_kW_K on any ambient temperature nodes, as illustrated by the equations below. Typically, the heat balance equation in simplified lumped-capacitance thermal models is cast as
\[C_n \frac{dT_n(t)}{dt} = H_{amb,n} \left( T_{amb}(t) - T_{n}(t) \right) + \sum_{m \in \mathbb{N}} \left[ H_{n,m} \left( T_{m}(t) - T_{n}(t) \right) \right] + \Sigma P_{n}(t) + \Sigma \Phi_{n}(t),\]
where C_n is the effective thermal mass of node n, T_{n}(t) is the temperature of node n on time step t, T_{amb}(t) is the ambient temperature, H_{amb,n} is the conductance between ambient temperature and the node temperature, N is the set of temperature nodes connected to node n, H_{n,m} is the conductance between nodes n and m, ∑P_{n}(t) is the total impact of HVAC equipment, and ∑Φ_{n}(t) is the total effect of internal and solar heat gains. However, large-scale energy system models rarely support ambient temperature T_{amb}(t) as input data directly, requiring the above equation to be cast as
\[C_n \frac{dT_n(t)}{dt} = - H_{amb,n} T_{n}(t) + \sum_{m \in N} \left[ H_{n,m} \left( T_{m}(t) - T_{n}(t) \right) \right] + \Sigma P_{n}(t) + \left( H_{amb,n} T_{amb}(t) + \Sigma \Phi_{n}(t) \right).\]
Now the - H_{amb,n} T_{n}(t) term can be interpreted as self-discharge losses, while the H_{amb,n} T_{amb}(t) term can be bundled together with other external influences on the node, both supported by typical large-scale energy system models. Unfortunately, this has the side-effect of making the energy-system-model-level input data quite unintuitive, but avoids the need to implement ambient-temperature-dependent interactions in complicated energy system modelling frameworks.
NOTE! All heat transfer coefficients are assumed to be symmetrical! NOTE! All AbstractNodes are given 1e-9 Wh/K thermal mass to avoid singularities when solving the temperature dynamics and heat demand later on.
ArchetypeBuildingModel.process_abstract_system — Functionprocess_abstract_system(process::BuildingProcessData; mod::Module = @__MODULE__)Process a BuildingProcessData into an AbstractProcess.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially, combines the properties of a BuildingProcessData into the bare minimum parameters required to describe a "process" in our large-scale energy system modelling frameworks. Performs the following steps:
- COP mode indicated using COP sign, positive for heating and negative for cooling.
- Scale COP to account for boundary between buildings and system link nodes. W -> MW conversion and accounting for the total number of processes.
- Factor COP mode into the
maximum_flowsdictionary. - Return the components for
AbstractProcess.
ArchetypeBuildingModel.process_building_envelope — Functionprocess_building_envelope(archetype::Object, data::ScopeData; mod::Module = @__MODULE__)Calculate the dimensions of the archetype building envelope based on the assumptions and aggregated building stock data.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially, the archetype buildings are assumed to be rectangular in shape, with their external dimensions primarily governed by the number_of_storeys, building_frame_depth_m, and room_height_m parameters. The average_gross_floor_area_m2_per_building is divided into the desired number of floors, and the perimeter walls are calculated by assuming building_frame_depth_m as the length of two parallel walls, and determining the length of the two perpendicular walls based on the floor area. In case of non-integer number_of_storeys, only the topmost floor is assumed to deviate in shape from the rest, and the size of the partial floor is reduced by decreasing the length of the wall that isn't fixed to building_frame_depth_m.
Note that for interior structures like separating floors and partition walls, the surface_area_m2 only includes the surface area of one side of the structure! Accounting for coupling of both surfaces to the interior air is handled through the external_U_value_to_ambient_air_W_m2K and internal_U_value_to_structure_W_m2K parameters.
The building envelope calculations proceed as follows:
- Base floor dimensions using
calculate_base_floor_dimensions. - Roof dimensions using
calculate_roof_dimensions. - Separating floor dimensions using
calculate_separating_floor_dimensions. - Total vertical envelope area using
calculate_vertical_envelope_surface_area. - Window dimensions using
calculate_window_dimensions. - Exterior wall dimensions using
calculate_exterior_wall_dimensions. - Partition wall dimensions using
calculate_partition_wall_dimensions.
ArchetypeBuildingModel.process_building_loads — Functionprocess_building_loads(
archetype::Object,
scope::ScopeData,
envelope::EnvelopeData,
weather::WeatherData;
mod::Module = @__MODULE__,
)Calculate the domestic hot water demand, internal and solar heat gains for the archetype building.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially, performs the following steps:
- Finds the
building_loadsobject corresponding to thebuilding_archetype. - Calculates total domestic hot water (DHW) demand using
calculate_total_dhw_demand. - Calculates total internal heat loads using
calculate_total_internal_heat_loads. - Calculates total solar gains through windows using
calculate_total_solar_gains. - Calculates solar gains through envelope structures using
calculate_envelope_solar_gains. - Calculates envelope radiative sky losses using
calculate_envelope_radiative_sky_losses. - Returns the calculated DHW demand, internal gains, solar gains for windows and the envelope, and envelope radiative sky losses.
ArchetypeBuildingModel.process_building_node — Functionprocess_building_node(
node::Object,
scope::ScopeData,
envelope::EnvelopeData,
loads::LoadsData;
mod::Module = @__MODULE__,
)Calculates the properties of a node using the provided scope, envelope, and loads data.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Aggregates the properties of the allocated structures according to their structure_type_weight parameters. The fenestration and ventilation properties are allocated according to interior_air_and_furniture_weight. Division of internal heat gains and solar heat gains between the interior air and the different structure types is based on the interior_air_and_furniture_weight, the relative surface areas of the different structure types and their structure_type_weights, as well as the internal_heat_gain_convective_fraction parameter for controlling the assumed convective vs radiative fractions of the internal gains. Solar gains through the windows are divided between the interior air and structures similar to internal heat gains, but use the solar_heat_gain_convective_fraction parameter for their convective vs radiative fraction instead. Solar heat gains through the opaque parts of the building envelope are applied entirely to the structures, as are envelope radiative sky heat losses.
Essentially, this function performs the following steps:
- Fetch user defined thermal mass, self-discharge, temperature set-point, and heat transfer coefficient parameters.
- Calculate the thermal mass on the
nodeusingcalculate_interior_air_and_furniture_thermal_massandcalculate_structural_thermal_mass. - Calculate the total heat transfer coefficient between the structures on this
nodeand the interior air usingcalculate_structural_interior_heat_transfer_coefficient. - Calculate the total heat transfer coefficient between the structures on this
nodeand the ambient air usingcalculate_structural_exterior_heat_transfer_coefficient. - Calculate the total heat transfer coefficient between the structures on this
nodeand the ground usingcalculate_structural_ground_heat_transfer_coefficient. - Calculate the total heat transfer coefficient through windows for this
nodeusingcalculate_window_heat_transfer_coefficient. - Calculate the total heat transfer coefficient of ventilation and infiltration on this
nodeusingcalculate_ventilation_and_infiltration_heat_transfer_coefficient. - Calculate the total heat transfer coefficient of thermal bridges for this
nodeusingcalculate_total_thermal_bridge_heat_transfer_coefficient. - Fetch domestic hot water demand from
loadsfor thisnode. - Calculate the convective internal heat gains on this
nodeusingcalculate_convective_internal_heat_gains. - Calculate the radiative internal heat gains on this
nodeusingcalculate_radiative_internal_heat_gains. - Calculate the convective solar heat gains through windows on this
nodeusingcalculate_convective_solar_gains. - Calculate the radiative solar heat gains through windows on this
nodeusingcalculate_radiative_solar_gains. - Calculate the total solar heat gains through the opaque building envelope on this
nodeusingcalculate_total_envelope_solar_gains. - Calculate the total radiative envelope sky heat losses on this
nodeusingcalculate_total_envelope_radiative_sky_losses. - Return all the pieces necessary for constructing the
BuildingNodeDatafor thisnode.
NOTE! Linear thermal bridges are assumed to bypass any potential structural lumped-capacitance nodes, and apply directly to the heat transfer coefficient between the interior air and the ambient air! NOTE! Currently, radiative internal and solar gains are lost through the windows in the building envelope.
ArchetypeBuildingModel.process_building_stock_scope — Functionprocess_building_stock_scope(scope::Object; mod::Module = @__MODULE__)Process the aggregated building_stock_statistic properties of a scope.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Returns the gross-floor area weighted total number_of_buildings and average_gross_floor_area_m2_per_building defined by the building_scope and its associated relationships. Furthermore, returns the gross-floor area weights for the building_type__building_period__location_id useful for weighting the structural and fenestration/ventilation data.
Essentially, performs the following steps:
- Filter out irrelevant building stock statistics and check there are any left.
- Calculate the gross-floor area weights using
calculate_gross_floor_area_weights. - Aggregate the gross-floor area weights using
aggregate_gfa_weights. - Return the necessary pieces to construct a
ScopeData.
ArchetypeBuildingModel.process_building_system — Functionprocess_building_system(
archetype::Object,
process::Object,
scope::ScopeData,
weather::WeatherData;
mod::Module = @__MODULE__,
)Calculates the properties required for creating a BuildingProcessData.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially performs the following steps:
- Fetch the
number_of_processes,system_link_nodes, andCOP_modefrom the definitions. - Calculate the coefficient of performance using the
calculate_copfunction. - Fetch the defined maximum power flows.
- Return the components for
BuildingProcessData.
ArchetypeBuildingModel.process_structure_scope — Functionprocess_structure_scope(
aggregated_gfa_weights::Dict{NTuple{3,Object},Float64};
mod::Module = @__MODULE__,
)Aggregate structure_statistics using gross-floor area weights.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially, this function calculates the aggregate properties of structures based on the aggregated gross floor area weights produced by the aggregate_gfa_weights function. Returns the gross-floor area weighted average structural properties as StructureData for different structure_types. These include the design U-values [W/m2K], effective thermal mass [J/m2K], linear thermal bridges [W/mK], and and U-values for heat transfer between the building interior and the structure, the structure and ambient air, the structure and ground, as well as the total U-value through the structure.
\[p_\text{avg} = \sum_{\text{bt,bp,lid}} w_\text{bt,bp,lid} p_\text{bt,bp,lid}\]
where p is any of the above listed properties to be aggregated.
ArchetypeBuildingModel.process_ventilation_and_fenestration_scope — Functionprocess_ventilation_and_fenestration_scope(
aggregated_gfa_weights::Dict{NTuple{3,Object},Float64};
mod::Module = @__MODULE__,
)Aggregate ventilation_and_fenestration_statistics using gross-floor area weights.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Essentially, this function calculates the aggregate properties of ventilation and fenestration based on the aggregated gross-floor area weights produced by the aggregate_gfa_weights function. Returns the gross-floor area weighted average HRU-efficiency, infiltration rate [1/h], ventilation rate [1/h], window U-values [W/m2K], and window total normal solar energy transmittance.
\[p_\text{avg} = \sum_{\text{bt,bp,lid}} w_\text{bt,bp,lid} p_\text{bt,bp,lid}\]
where p is any of the above listed properties to be aggregated.
ArchetypeBuildingModel.process_weather — Functionprocess_weather(
weather::Object;
mod::Module = @__MODULE__,
realization::Symbol = realization,
)Process weather data for the WeatherData constructor.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default. The realization scenario is required for processing of effective ground temperature.
Essentially, performs the following steps:
- Fetch the ambient temperature data for
weather. - Calculate the effective ground temperature using
calculate_effective_ground_temperature. - Fetch diffuse and direct solar irradiation data.
- Return the components for the
WeatherDataconstructor.
ArchetypeBuildingModel.solve_consumption — Functionsolve_consumption(
archetype::ArchetypeBuilding,
hvac_demand::Dict{Object,T} where {T<:SpineDataType};
mod::Module = @__MODULE__,
)Solve the consumption of abstract_process included in the archetype, based on the hvac_demand.
NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default.
Currently produces only extremely simple estimates, where each abstract_process is assumed to handle the demand on their output nodes in full, regardless of what the other abstract_processes are doing. Thus, the results cannot be used as is for systems with complimentary HVAC processess, and the merit-order assumptions are left up to the user.
Heating and cooling are handled separately, though.
ArchetypeBuildingModel.solve_heating_demand — Functionsolve_heating_demand(
archetype::ArchetypeBuilding;
realization::Symbol=:realization,
free_dynamics::Bool=false,
initial_temperatures::Nothing=nothing,
)Solve the heating/cooling demand of the archetype.
Note that this function calculates the "final energy demand" of the archetype building, and not the energy consumption of it's HVAC systems. See the solve_consumption function for that. Furthermore, the calculations are deterministic, with realization defining the true data from potentially stochastic input. Essentially, performs the following steps:
- Check external load data and
determine_temporal_structure. - Initialize external load an thermal mass vectors using
initialize_rhs. - Initialize temperature and temperature limit vectors using
initialize_temperatures. - Solve the heating demand using
solve_heating_demand_loop. - Rearrange the solution into
Dicts and return them.
Uses an extremely simple rule-based control to solve the heating/cooling demand of the archetype building. The controller intervenes whenever node temperatures would deviate from permitted limits, and provides the required energy input to maintain the system at the limit.
The building dynamics are discretized using implicit (backwards) Euler, mainly for consistency with our existing energy system modelling tools like Backbone or SpineOpt. In principle, I believe the system could be solved analytically similar to my Master's Thesis, if better accuracy would be desired: Energy Management in Households with Coupled Photovoltaics and Electric Vehicles, Topi Rasku, 2015, Aalto University School of Science.
The idea of solving heating demand calculations can be as follows, starting from the energy balance equation for node n
\[C_n \frac{dT_n(t)}{dt} = - \rho_n T_n(t) + \sum_{m \in N} \left[ H_{n,m} \left( T_m(t) - T_n(t) \right) \right] + \Phi_n(t),\]
where C_n is the heat capacity of node n, T_n(t) is the time-dependent temperature of node n at time t, ρ_n is the self-discharge from node n, N is the set of temperature nodes in the lumped-capacitance model of the building, H_n,m is the heat transfer coefficient between nodes n and m, and Φ_n(t) is the time-dependent total external heat load on node n. Using the implicit Euler discretization, the above can be cast into
\[\left( \frac{C_n}{\Delta t} + \rho_n + \sum_{m \in N} H_{n,m} \right) T_{n,t} - \sum_{m \in N} \left[ H_{n,m} T_{m,t} \right] = \Phi_{n,t} + \frac{C_n}{\Delta t} T_{n,t-\Delta t},\]
where Δt is the length of the discretized time step. Since we always know the temperatures on the previous time step t-Δt, the above can be expressed in matrix form and solved as
\[\boldsymbol{A} \hat{T} = \hat{\Phi}, \\ \hat{T} = \boldsymbol{A}^{-1} \hat{\Phi},\]
where A is the so-called dynamics matrix, T is the current temperature vector, and Φ is the right-hand side vector, containing the effect of external loads and previous temperatures.
The above is used to calculate the temperatures of the nodes on each subsequent time step. However, when any of the node temperatures would violate the defined minimum and maximum permitted temperatures, that temperature variable is instead fixed to the violated boundary, moved to the right-hand side, and replaced with a heating/cooling demand variable ϕ_m instead. This results in a slightly modified problem to be solved
\[\hat{\phi} = \left( \boldsymbol{A} - \sum_{m \in M}[\boldsymbol{A}_{m} + \boldsymbol{I}_{m}] \right)^{-1} \left( \hat{\Phi} - \sum_{m \in M}[\hat{A}_{m} T'_m] \right),\]
where ϕ is the modified temperature vector with the fixed temperature replaced with the heating/cooling demand variable, m ∈ M are the nodes that would violate their permitted bounds, and are therefore fixed at the boundary T'_m, A_m represents a selection of column m from the matrix A, and I_m represents column m from an identity matrix. Please note that there are both matrix and vector selections of A_m, where the matrix selection preserves the dimensions with filling zeroes, while the vector selection is essentially only the selected column in vector form.
ArchetypeBuildingModel.solve_heating_demand_loop — Functionsolve_heating_demand_loop(
archetype::ArchetypeBuilding,
indices::Vector{DateTime},
delta_t::Int64,
initial_temperatures::Vector{Float64},
min_temperatures::Vector{SpineDataType},
max_temperatures::Vector{SpineDataType},
external_load_vector::Vector{Vector{Float64}},
thermal_mass_vector::Vector{Float64},
free_dynamics::Bool,
)Solve the heating/cooling demand one timestep at a time over the given indices.
Essentially, performs the following steps:
- Initialize the temperature vector, HVAC demand vector, and a dictionary for the dynamic matrices for solving the problem.
- Loop over the given
indicesand do the following:- Invert the dynamics matrix using
form_and_invert_dynamics_matrix. - Solve new temperatures if HVAC not in use.
- Check if new temperatures would violate temperature limits.
- If necessary, solve the HVAC demand via
form_and_invert_hvac_matrixrequired to keep temperatures within set limits.
- Invert the dynamics matrix using
- Return the solved temperatures and HVAC demand for each node and index.
See the solve_heating_demand function for the overall formulation.
ArchetypeBuildingModel.timeseries_to_backbone_map — Functiontimeseries_to_backbone_map(ts::TimeSeries)Convert TimeSeries into Backbone input data Map corresponding to time-varying data.
timeseries_to_backbone_map(x::Real)Convert Real into Backbone input data Map.