Library

Automatically generated documentation based on the docstrings in the codebase.

Index

Public

This section lists all types and functions exported by the module.

Types

ArchetypeBuildingModel.ArchetypeBuildingType
ArchetypeBuilding(
    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: The building_archetype object corresponding to this ArchetypeBuilding.
  • scope::Object: The defined building_scope for this archetype.
  • fabrics::Object: The defined building_fabrics for this archetype.
  • systems::Object: The defined building_systems for this archetype.
  • loads::Object: The defined building_loads for this archetype.
  • weather::Object: The defined building_weather for this archetype.
  • scope_data::ScopeData: The processed building_scope data 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 processed AbstractNodes depicting this archetype.
  • abstract_processes::Dict{Object,AbstractProcess}: The processed AbstractProcesses in this archetype.

The constructor performs the following steps:

  1. Fetch and create the corresponding WeatherData.
  2. Fetch and create the corresponding ScopeData.
  3. Form the EnvelopeData.
  4. Process the LoadsData.
  5. Process the temperature nodes using the create_building_node_network function.
  6. Create the BuildingProcessData for the HVAC system components.
  7. Process the abstract temperature nodes using the create_abstract_node_network function based on the BuildingNodeNetwork.
  8. Create the AbstractProcesses corresponding to the BuildingProcessDatas.
  9. Construct the final ArchetypeBuilding.
source
ArchetypeBuildingModel.ArchetypeBuildingResultsType
ArchetypeBuildingResults(
    archetype::ArchetypeBuilding;
    free_dynamics::Bool = false,
    initial_temperatures::Union{Nothing,Dict{Object,Float64}} = nothing,
    mod::Module = @__MODULE__,
    realization::Symbol = :realization,
) <: BuildingDataType

Store 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: The ArchetypeBuilding for 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:

  1. Solve the initial temperatures, node temperatures, and HVAC demand using the solve_heating_demand function.
  2. Solve the HVAC consumption using the solve_consumption function.
  3. Return the ArchetypeBuildingResults using the calculated values.
source
ArchetypeBuildingModel.BackboneInputType
BackboneInput(url::{String,Dict})

Link to the input data store for the Backbone energy system model.

Contains the following fields:

  • boundary::ObjectClass: Contains the upwardLimit and downwardLimit settings.
  • effLevel::ObjectClass: All possible efficiency representation levels in Backbone.
  • effSelector::ObjectClass: Contains the directOff efficiency representation used by the building model.
  • grid::ObjectClass: Contains the building grid for building nodes.
  • io::ObjectClass: Contains the input and output indicators for units.
  • node::ObjectClass: Contains all the nodes in the building models, created based on AbstractNodes.
  • unit::ObjectClass: Contains all the units in the building models, created based on AbstractProcesses.
  • unittype::ObjectClass: Contains a HVAC type for all building units.
  • effLevel__effSelector__unit::RelationshipClass: Attributes the directOff efficiency representation for all units for all efficiency representation levels.
  • grid__node::RelationshipClass: Connects all nodes into the building grid.
  • grid__node__boundary::RelationshipClass: Contains the upwardLimit and downwardLimit parameters for all nodes.
  • grid__node__node::RelationshipClass: Contains the diffCoeff diffusion parameters between the nodes.
  • grid__node__unit__io::RelationshipClass: Defines how the units interact with the nodes, and contains the necessary parameters.
  • unit__unittype::RelationshipClass: Indicates all units as of type HVAC
source
ArchetypeBuildingModel.BuildingProcessDataType
BuildingProcessData(
    archetype::Object,
    process::Object,
    scope::ScopeData,
    weather::WeatherData;
    mod::Module = @__MODULE__,
) <: BuildingDataType

Aggregate 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: The building_process definition for this BuildingProcessData.
  • 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 :heating or :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.

source
ArchetypeBuildingModel.EnvelopeDataType
EnvelopeData(archetype::Object, data::ScopeData; mod::Module = @__MODULE__) <: BuildingDataType

Store 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.

source
ArchetypeBuildingModel.GenericInputType
GenericInput(url::Union{String,Dict}; mod::Module=@__MODULE__)

Create and store the ArchetypeBuildingModel.jl structure for Spine Data Stores.

NOTE! The mod keyword changes from which Module data is accessed from, @__MODULE__ by default. 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: Stores ArchetypeBuilding information and definitions.
  • building_scope::ObjectClass: Stores ScopeData information and definitions.
  • building_weather::ObjectClass: Stores WeatherData information and definitions.
  • building_archetype__building_scope::RelationshipClass: Links ArchetypeBuilding to its corresponding ScopeData.
  • building_archetype__building_weather::RelationshipClass: Links ArchetypeBuilding to its corresponding WeatherData.
source
ArchetypeBuildingModel.LoadsDataType
LoadsData(
    archetype::Object,
    scope::ScopeData,
    envelope::EnvelopeData,
    weather::WeatherData;
    mod::Module = @__MODULE__,
) <: BuildingDataType

Store 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.

source
ArchetypeBuildingModel.ScopeDataType
ScopeData(scope::Object; mod::Module = @__MODULE__) <: BuildingDataType

Aggregate 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: The building_scope used to define this ScopeData.
  • number_of_buildings::Float64: Number of buildings included in this scope.
  • average_gross_floor_area_m2_per_building::Float64: Average GFA per building in [m2] of the buildings included in this scope.
  • HRU_efficiency::Float64: Average ventilation heat-recovery unit efficiency of the buildings included in this scope.
  • infiltration_rate_1_h::Float64: Average infiltration rate in [1/h] of the buildings included in this scope.
  • total_normal_solar_energy_transmittance::Float64: Average total normal solar energy transmittance of the windows included in this scope.
  • ventilation_rate_1_h::Float64: Average ventilation rate in [1/h] of the buildings included in this scope.
  • window_U_value_W_m2K::Float64: Average window U-value in [W/m2K] of the buildings included in this scope.
  • structure_data::Dict{Object,StructureData}: StructureData dictionary for the average structural parameters of the buildings included in this scope.
  • location_id_gfa_weights::Dict{Object,Float64}: Gross-floor area weights for the location_ids included in this scope, used for automatic weather data processing.
  • shapefile_path::String: Path to a shapefile describing the geography of this scope, 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:

  1. Process building stock statistics using the process_building_stock_scope function.
  2. Process ventilation and fenestration statistics using the process_ventilation_and_fenestration_scope function.
  3. Process structure statistics using the process_structure_scope function.
  4. Check that the values make sense.
  5. Create the ScopeData.
source
ArchetypeBuildingModel.SpineOptInputType
SpineOptInput(url::Union{String,Dict})

Link to the input data store for the SpineOpt energy system model.

Contains the following fields:

  • node::ObjectClass: Contains all the nodes in the building models, created based on AbstractNodes.
  • unit::ObjectClass: Contains all the units in the building models, created based on AbstractProcesses.
  • node__node::RelationshipClass: Defines the heat transfer coefficients between the nodes.
  • unit__from_node::RelationshipClass: Defines unit input flow properties.
  • unit__to_node::RelationshipClass: Defines unit output flow properties.
  • unit__node__node::RelationshipClass: Defines unit conversion properties.
source
ArchetypeBuildingModel.WeatherDataType
WeatherData(
    weather::Object;
    mod::Module = @__MODULE__,
    realization::Symbol = :realization,
) <: BuildingDataType

Process 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: The building_weather object used to construct this WeatherData.
  • 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.

source

Functions

ArchetypeBuildingModel.add_results!Function
add_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.
source
ArchetypeBuildingModel.archetype_building_processingFunction
archetype_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:

  1. Construct the ScopeData for each defined building_archetype__building_scope, and store in the scope_data_dictionary.
  2. Try to construct the WeatherData for each defined building_archetype__building_weather, and attempt automatic weather processing using ArchetypeBuildingWeather.py if no definition found. Results stored in weather_data_dictionary.
  3. Use the scope_data_dictionary and weather_data_dictionary to construct the ArchetypeBuilding for all defined archetypes, and store them in archetype_dictionary.
  4. Return scope_data_dictionary, weather_data_dictionary, and archetype_dictionary.
source
ArchetypeBuildingModel.create_abstract_node_networkFunction
create_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.

source
ArchetypeBuildingModel.create_building_node_networkFunction
create_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.

source
ArchetypeBuildingModel.create_building_weatherFunction
create_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.

source
ArchetypeBuildingModel.run_object_class_testsFunction
run_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.

source
ArchetypeBuildingModel.run_parameter_testsFunction
run_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.

source
ArchetypeBuildingModel.solve_archetype_building_hvac_demandFunction
solve_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:

  1. Create the archetype_results_dictionary by constructing the ArchetypeBuildingResults for each entry in the archetype_dictionary.
  2. Create the results__building_archetype__building_node RelationshipClass for storing temperature results.
  3. Create the results__building_archetype__building_process RelationshipClass for storing HVAC results.
  4. Return the archetype_results_dictionary, as well as the created RelationshipClasses.
source
ArchetypeBuildingModel.write_to_urlFunction
write_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

source

Internals

This section lists all the internal types and functions not exported by the module.

Types

ArchetypeBuildingModel.AbstractNodeType
AbstractNode(
    building_node_network::BuildingNodeNetwork,
    node::Object,
    weather::WeatherData,
) <: BuildingDataType

Contain 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: The building_node definition this AbstractNode depicts.
  • 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.

source
ArchetypeBuildingModel.AbstractProcessType
AbstractProcess(process_data::BuildingProcessData; mod::Module = @__MODULE__) <: BuildingDataType

Contain 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: The building_process definition this AbstractProcess depicts.
  • 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.

source
ArchetypeBuildingModel.BuildingNodeDataType
BuildingNodeData(
    archetype::Object,
    node::Object,
    scope::ScopeData,
    envelope::EnvelopeData,
    loads::LoadsData;
    mod::Module = @__MODULE__,
) <: BuildingDataType

Contains 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: The building_node definition used for this BuildingNodeData.
  • 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.

source
ArchetypeBuildingModel.StructureDataType
StructureData <: BuildingDataType

Store 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_floor or roof.
  • 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.
source

Functions

ArchetypeBuildingModel._building_period_weightFunction
_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_yearscope_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)\]

source
ArchetypeBuildingModel._pyseries_to_timeseriesFunction
_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.

source
ArchetypeBuildingModel.add_archetype_to_input!Function
add_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:

  1. Map the ArchetypeBuildingModel direction objects to Backbone io objects.
  2. Create a grid object representing the archetype being processed and map the grids.
  3. Map the ArchetypeBuildingModel building_node objects to unique Backbone node objects.
  4. Identify the necessary system link nodes, and add them into the set of Backbone node objects with the desired names.
  5. Include all building nodes to the archetype grid, and connect the system link nodes to their desired grids.
  6. Map the ArchetypeBuildingModel building_process objects to unique Backbone unit objects.
  7. Determine Backbone unit parameters based on AbstractProcess properties.
  8. Set the directOff efficiency representation for all units.
  9. Determine Backbone grid__node parameters based on AbstractNode properties.
  10. Determine Backbone grid__node__boundary parameters based on AbstractNode maximum and minimum permitted temperatures.
  11. Determine Backbone grid__node__node parameters based on AbstractNode heat transfer coefficients.
  12. Determine Backbone grid__node__unit__io parameters based on AbstractProcess maximum flows.
  13. Set the HVAC unittype for every unit.
source
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:

  1. Map the ArchetypeBuildingModel building_node objects to unique SpineOpt node objects.
  2. Identify the necessary system link nodes, and add them into the set of SpineOpt node objects with the desired names.
  3. Map the ArchetypeBuildingModel building_process objects to unique SpineOpt unit objects.
  4. Determine SpineOpt node parameters based on the AbstractNode properties.
  5. Determine SpineOpt node__node parameters based on the AbstractNode heat transfer coefficients.
  6. Determine SpineOpt unit__from_node and unit__to_node parameters based on the AbstractProcess maximum flow parameters.
  7. Determine SpineOpt unit__node__node parameters based on the AbstractProcess properties.
source
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.

source
ArchetypeBuildingModel.aggregate_gfa_weightsFunction
aggregate_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.

source
ArchetypeBuildingModel.calculate_base_floor_dimensionsFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_copFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_convective_internal_heat_gainsFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_convective_solar_gainsFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_effective_ground_temperatureFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_envelope_solar_gainsFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_envelope_radiative_sky_lossesFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_exterior_wall_dimensionsFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_gross_floor_area_weightsFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_interior_air_and_furniture_thermal_massFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_total_thermal_bridge_heat_transfer_coefficientFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_partition_wall_dimensionsFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_radiative_internal_heat_gainsFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_radiative_solar_gainsFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_roof_dimensionsFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_separating_floor_dimensionsFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_structural_exterior_heat_transfer_coefficientFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_structural_ground_heat_transfer_coefficientFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_structural_interior_heat_transfer_coefficientFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_structural_thermal_massFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_total_dhw_demandFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_total_envelope_solar_gainsFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_total_envelope_radiative_sky_lossesFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_total_internal_heat_loadsFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_total_solar_gainsFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_ventilation_and_infiltration_heat_transfer_coefficientFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_vertical_envelope_surface_areaFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_window_dimensionsFunction
calculate_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.

source
ArchetypeBuildingModel.calculate_window_heat_transfer_coefficientFunction
calculate_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.

source
ArchetypeBuildingModel.determine_temporal_structureFunction
determine_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.

source
ArchetypeBuildingModel.form_and_invert_dynamics_matrixFunction
form_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.

source
ArchetypeBuildingModel.form_and_invert_hvac_matrixFunction
form_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.

source
ArchetypeBuildingModel.initialize_temperaturesFunction
initialize_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.

source
ArchetypeBuildingModel.initialize_rhsFunction
initialize_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.

source
ArchetypeBuildingModel.process_abstract_nodeFunction
process_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:

  1. Sum all the thermal mass components together and convert into [Wh/K].
  2. Sum all the self-discharge and ambient heat transfer components together.
  3. Collect heat transfer coefficients between the interior air node and this one.
  4. Update heat transfer coefficients based on user-defined coefficients.
  5. Sum together the internal heat gains, solar gains, radiative sky heat losses, DHW demand, as well as the impact of ambient temperatures.
  6. 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.

source
ArchetypeBuildingModel.process_abstract_systemFunction
process_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:

  1. COP mode indicated using COP sign, positive for heating and negative for cooling.
  2. Scale COP to account for boundary between buildings and system link nodes. W -> MW conversion and accounting for the total number of processes.
  3. Factor COP mode into the maximum_flows dictionary.
  4. Return the components for AbstractProcess.
source
ArchetypeBuildingModel.process_building_envelopeFunction
process_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:

  1. Base floor dimensions using calculate_base_floor_dimensions.
  2. Roof dimensions using calculate_roof_dimensions.
  3. Separating floor dimensions using calculate_separating_floor_dimensions.
  4. Total vertical envelope area using calculate_vertical_envelope_surface_area.
  5. Window dimensions using calculate_window_dimensions.
  6. Exterior wall dimensions using calculate_exterior_wall_dimensions.
  7. Partition wall dimensions using calculate_partition_wall_dimensions.
source
ArchetypeBuildingModel.process_building_loadsFunction
process_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:

  1. Finds the building_loads object corresponding to the building_archetype.
  2. Calculates total domestic hot water (DHW) demand using calculate_total_dhw_demand.
  3. Calculates total internal heat loads using calculate_total_internal_heat_loads.
  4. Calculates total solar gains through windows using calculate_total_solar_gains.
  5. Calculates solar gains through envelope structures using calculate_envelope_solar_gains.
  6. Calculates envelope radiative sky losses using calculate_envelope_radiative_sky_losses.
  7. Returns the calculated DHW demand, internal gains, solar gains for windows and the envelope, and envelope radiative sky losses.
source
ArchetypeBuildingModel.process_building_nodeFunction
process_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:

  1. Fetch user defined thermal mass, self-discharge, temperature set-point, and heat transfer coefficient parameters.
  2. Calculate the thermal mass on the node using calculate_interior_air_and_furniture_thermal_mass and calculate_structural_thermal_mass.
  3. Calculate the total heat transfer coefficient between the structures on this node and the interior air using calculate_structural_interior_heat_transfer_coefficient.
  4. Calculate the total heat transfer coefficient between the structures on this node and the ambient air using calculate_structural_exterior_heat_transfer_coefficient.
  5. Calculate the total heat transfer coefficient between the structures on this node and the ground using calculate_structural_ground_heat_transfer_coefficient.
  6. Calculate the total heat transfer coefficient through windows for this node using calculate_window_heat_transfer_coefficient.
  7. Calculate the total heat transfer coefficient of ventilation and infiltration on this node using calculate_ventilation_and_infiltration_heat_transfer_coefficient.
  8. Calculate the total heat transfer coefficient of thermal bridges for this node using calculate_total_thermal_bridge_heat_transfer_coefficient.
  9. Fetch domestic hot water demand from loads for this node.
  10. Calculate the convective internal heat gains on this node using calculate_convective_internal_heat_gains.
  11. Calculate the radiative internal heat gains on this node using calculate_radiative_internal_heat_gains.
  12. Calculate the convective solar heat gains through windows on this node using calculate_convective_solar_gains.
  13. Calculate the radiative solar heat gains through windows on this node using calculate_radiative_solar_gains.
  14. Calculate the total solar heat gains through the opaque building envelope on this node using calculate_total_envelope_solar_gains.
  15. Calculate the total radiative envelope sky heat losses on this node using calculate_total_envelope_radiative_sky_losses.
  16. Return all the pieces necessary for constructing the BuildingNodeData for this node.

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.

source
ArchetypeBuildingModel.process_building_stock_scopeFunction
process_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:

  1. Filter out irrelevant building stock statistics and check there are any left.
  2. Calculate the gross-floor area weights using calculate_gross_floor_area_weights.
  3. Aggregate the gross-floor area weights using aggregate_gfa_weights.
  4. Return the necessary pieces to construct a ScopeData.
source
ArchetypeBuildingModel.process_building_systemFunction
process_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:

  1. Fetch the number_of_processes, system_link_nodes, and COP_mode from the definitions.
  2. Calculate the coefficient of performance using the calculate_cop function.
  3. Fetch the defined maximum power flows.
  4. Return the components for BuildingProcessData.
source
ArchetypeBuildingModel.process_structure_scopeFunction
process_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.

source
ArchetypeBuildingModel.process_ventilation_and_fenestration_scopeFunction
process_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.

source
ArchetypeBuildingModel.process_weatherFunction
process_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:

  1. Fetch the ambient temperature data for weather.
  2. Calculate the effective ground temperature using calculate_effective_ground_temperature.
  3. Fetch diffuse and direct solar irradiation data.
  4. Return the components for the WeatherData constructor.
source
ArchetypeBuildingModel.solve_consumptionFunction
solve_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.

source
ArchetypeBuildingModel.solve_heating_demandFunction
solve_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:

  1. Check external load data and determine_temporal_structure.
  2. Initialize external load an thermal mass vectors using initialize_rhs.
  3. Initialize temperature and temperature limit vectors using initialize_temperatures.
  4. Solve the heating demand using solve_heating_demand_loop.
  5. 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.

source
ArchetypeBuildingModel.solve_heating_demand_loopFunction
solve_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:

  1. Initialize the temperature vector, HVAC demand vector, and a dictionary for the dynamic matrices for solving the problem.
  2. Loop over the given indices and do the following:
    1. Invert the dynamics matrix using form_and_invert_dynamics_matrix.
    2. Solve new temperatures if HVAC not in use.
    3. Check if new temperatures would violate temperature limits.
    4. If necessary, solve the HVAC demand via form_and_invert_hvac_matrix required to keep temperatures within set limits.
  3. Return the solved temperatures and HVAC demand for each node and index.

See the solve_heating_demand function for the overall formulation.

source