Model Construction

The model is constructed by calling the ModelHub.construct_model() method. This method clearly illustrates the structure of the model. There are sets of investment periods, nodes and carriers based on the topology.json. Then, a block is created for each investment period (all investment periods in the set), each network, each node, and for each technologies. The methods for the block creation are called by the aforementioned ModelHub.construct_model() method from the .\src\model_construction directory (with a separate module for each block type).

Then, these blocks are all linked through cost, emissions and energy / material balances by calling the ModelHub.construct_balances() method (again retrieved from the .\src\model_construction directory).

Finally, the model can be solved using ModelHub.solve().

Note: the three steps above are combined in the ModelHub.quick_solve() method to quickly construct and solve the model at once. All of the methods are documented here.

Energy Hub Class

class ModelHub

Class to construct and manipulate an energy system model.

When constructing an instance, it reads data to the instance and initializes all attributes of the ModelHub class:

  • self.data: Data container

  • self.model: Model container

  • self.solution: Solution container

  • self.solver: Solver container

  • self.last_solve_info: Information on last solution that is written to the summary( pareto point, time stage,…)

  • self.info_pareto: Current pareto point (if used)

  • self.info_solving_algorithms: Information on time aggregation algorithms

  • self.info_monte_carlo: Information on monte carlo runs

add_technology(investment_period: str, node: str, technologies: list)

Adds technologies retrospectively to the model.

After adding a technology to a node, all balances need to be re-constructed, To solve the model again run, construct_balances() and then solve().

Parameters:
  • investment_period (str) – name of investment period for which technology is added

  • node (str) – name of node for which technology is added

  • technologies (list) – list of technologies that should be added

Return None:

construct_balances()

Constructs the energy balance, emission balance and calculates costs

construct_model()

Constructs the model. The model structure is as follows:

Global sets

  • set_periods: set of investment periods

  • set_nodes: set of nodes

  • set_carriers: set of carriers modelled

Global variables

  • var_npv: net present value of all costs

  • var_emissions_net: net emissions over all investment periods

Rest of model The rest of the model is organized in nested, hierarchical pyomo modelling blocks:

Investment Period Block

Network Block

Node Block

Technology Block

quick_solve()

Quick-solves the model (constructs model and balances and solves model).

This method lumbs together the following functions for convenience: - construct_model() - construct_balances() - solve()

read_data(data_path: pathlib.Path | str, start_period: int = None, end_period: int = None)

Reads in data from the specified path. The data is specified as the DataHandle class. Specifying the start_period and end_period parameter allows to run a time horizon than as specified in the topology (e.g. for testing)

Parameters:
  • data_path (Path, str) – Path of folder structure to read data from

  • start_period (int) – starting period of the model

  • end_period (int) – end period of the model

scale_model()

Creates a scaled model using the scale factors specified in the json files for technologies and networks as well as the global scaling factors specified. See also the documentation on model scaling.

solve()

Defines objective and solves model

write_results()

Writes optimization results of a model run to folder

Model Structure

In order to define your hierarchical model, Pyomo Blocks are used. There are multiple (nested) blocks present:

  • b_period: a block holding all investment periods as specified in your topology.json file.

    • b_node: a block per investment period holding all nodes as specified in your topology.json file. The rule to construct this is held in adopt_net0.model_construction.construct_nodes.py:

      • b_tec: a block per node holding all technologies as specified in your technology.json file for that node. These are added to the respective nodes through the adopt_net0.model_construction.construct_technology.py module.

    • b_netw: a block per investment period holding all networks as specified in your network.json file. The rule to construct this is held in adopt_net0.model_construction.construct_networks.py:

Block Construction

The aforementioned blocks are constructed based on the rules in their respective modules. These are:

For investment periods, contained in the adopt_net0.model_construction.construct_investment_period.py module:

construct_investment_period_block(b_period, data: dict)

SETS - set_networks: Set of networks for investment period - set_t_full: full set_t - set_t_clustered: clustered set_t (can be equal to set_t_full)

VARIABLES

Cost Variables

  • var_cost_capex_tecs: Total Capex of technologies for respective investment period

  • var_cost_capex_netws: Total Capex of networks for respective investment period

  • var_cost_opex_tecs: Total Opex (fixed and variable) of technologies for respective investment period

  • var_cost_opex_netws: Total Opex (fixed and variable) of networks for respective investment period

  • var_cost_tecs: Total technology costs

  • var_cost_netws: Total network costs

  • var_cost_imports: Total import costs

  • var_cost_exports: Total export costs

  • var_cost_violation: Total violation cost

  • var_carbon_revenue: Total carbon revenues from negative emission technologies

  • var_carbon_cost: Total carbon cost from technologies, networks and imports/exports

  • var_cost_total: Total annualized cost for respective investment period

Emission Variables

  • var_emissions_pos: Positive emissions from technologies, networks and imports/exports

  • var_emissions_neg: Negative emissions from technologies and imports/exports

  • var_emissions_net: Net emissions in investment period

Parameters:
  • b_period – pyomo block with investment period

  • data (dict) – data containing model configuration

Returns:

pyomo block with investment period

For nodes, from the adopt_net0.model_construction.construct_nodes.py module:

construct_node_block(b_node, data: dict, set_t_full, set_t_clustered)

Adds all nodes with respective data to the model

This function initializes parameters and decision variables for all considered nodes.

Set declarations:

  • set_technologies: Set for all technologies at respective node

  • set_carriers: Set of carriers used at node (this is a subset of all carriers)

Parameter declarations:

  • para_demand: Demand for each time step and carrier

  • para_production_profile: Maximal generic production profile for each time step and carrier

  • para_import_price: Import Prices for each time step and carrier

  • para_export_price: Export Prices for each time step and carrier

  • para_import_limit: Import Limits for each time step and carrier

  • para_export_limit: Export Limits for each time step and carrier

  • para_import_emissionfactors: Emission factors of imports for each time step and carrier

  • para_export_emissionfactors: Emission factors of exports for each time step and carrier

  • para_carbon_subsidy: Carbon subsidy for negative emissions

  • para_carbon_tax: Carbon tax for positive emissions

Variable declarations:

  • var_import_flow: Import Flow for each time step and carrier

  • var_export_flow: Export Flow for each time step and carrier

  • var_netw_inflow: Network Inflow for each time step and carrier

  • var_netw_outflow: Network Outflow for each time step and carrier

  • var_netw_consumption: Network consumption (if present)

  • var_generic_production: Actual generic production

  • var_import_emissions_pos: Positive emissions from imports

  • var_import_emissions_neg: Negative emissions from imports

  • var_export_emissions_pos: Positive emissions from exports

  • var_export_emissions_neg: Negative emissions from exports

  • var_car_emissions_pos: Sum of positive emissions

  • var_car_emissions_neg: Sum of negative emissions

Constraint declarations

  • Generic production: Equal to the parameter if curtailment is not possible, otherwise less-or-equal

  • Calculate import emissions (positive and negative): emissions = import * emissions-factor

  • Calculate export emissions (positive and negative): emissions = export * emissions-factor

  • Calculate carrier emissions as a sum of positive/negative import and export emissions

Parameters:
  • b_node – pyomo block with node model

  • data (dict) – data containing model configuration

  • set_t_full – pyomo set containing full resolution timesteps

  • set_t_clustered – pyomo set containing clustered resolution timesteps

Returns:

pyomo block with node model

For technologies, contained in the adopt_net0.model_construction.construct_technology.py module.

construct_technology_block(b_tec, data: dict, set_t_full, set_t_clustered)

Construct technology block and performs disjunct relaxation if required

Parameters:
  • b_tec – pyomo block with technology model

  • data (dict) – data containing model configuration

  • set_t_full – pyomo set containing timesteps

  • set_t_clustered – pyomo set containing clustered timesteps

Returns:

pyomo block with technology model

For networks, contained in the adopt_net0.model_construction.construct_networks.py module.

construct_network_block(b_netw, data: dict, set_nodes, set_t_full, set_t_clustered)

Construct network block and performs disjunct relaxation if required

Parameters:
  • b_netw – pyomo block with network model

  • data (dict) – data containing model configuration

  • set_nodes – pyomo set containing all nodes

  • set_t_full – pyomo set containing timesteps

  • set_t_clustered – pyomo set containing clustered timesteps

Returns:

pyomo block with network model

Balance Construction

All model blocks and components are linked through “balances”. These are calculations of total emissions and costs, and carrier (i.e., energy and/or material) balances. All carriers must be in balance for each node and on the global level. Violation of balances is only possible if specifically allowed for in the configuration (see here).

The module .\adopt_net0\model_construction\construct_balances contains the rules to construct these balances. These functions are called after the nodes and networks have been initialized, i.e. after the blocks have been constructed.

construct_emission_balance(model, data)

Calculates the total postive and negative emissions as well as the net emissions

\[E_{pos, tot} = E_{pos, technologies} + E_{pos, carriers} + E_{pos, networks}\]
\[E_{neg, tot} = E_{neg, technologies} + E_{neg, carriers}\]
\[E_{net} = E_{pos, tot} - E_{neg, tot}\]
Parameters:
  • model – pyomo model

  • data – DataHandle

Returns:

pyomo model

construct_export_costs(b_period, data, period)

Calculates the total export costs for an investment period

\[C_{export} = \sum(p_{t, export} * F_{t, export})\]
Parameters:
  • b_period – pyomo block for period

  • data – DataHandle

  • period (str) – investment period to calculate export cost for

Returns:

pyomo constraint

construct_global_balance(model)

Calculates total npv and total emissions over all investment periods :param model: pyomo model :return: pyomo model

construct_global_energybalance(model, config)

Calculates the global energy balance for each carrier summed over all nodes

\[outputFromTechnologies - inputToTechnologies + \ imports - exports = demand - genericProductionProfile\]
Parameters:
  • model – pyomo model

  • config (dict) – dict containing model information

Returns:

pyomo model

construct_import_costs(b_period, data, period: str)

Calculates the total import costs for an investment period

\[C_{import} = \sum(p_{t, import} * F_{t, import})\]
Parameters:
  • b_period – pyomo block for period

  • data – DataHandle

  • period (str) – investment period to calculate import cost for

Returns:

pyomo constraint

construct_network_constraints(model, config: dict)

Construct the network constraints to calculate nodal in- and outflow

\[outflowToNetwork = \sum(outflow \]

orall arcs at node)

\[inflowFromNetwork = \sum(inflow \]

orall arcs at node)

param model:

pyomo model

param dict config:

dict containing model information

return:

pyomo model

construct_nodal_energybalance(model, config: dict)

Calculates the energy balance for each node and carrier

\[outputFromTechnologies - inputToTechnologies + \ inflowFromNetwork - outflowToNetwork + \ imports - exports = demand - genericProductionProfile\]
Parameters:
  • model – pyomo model

  • config (dict) – dict containing model information

Returns:

pyomo model

construct_system_cost(model, data)

Aggregates costs per investment period

  • Total capex of technologies

  • Total capex of networks

  • Total opex of technologies

  • Total opex of networks

  • Total cost of technologies (sum of opex and capex)

  • Total cost of networks (sum of opex and capex)

  • Total import costs

  • Total export costs

  • Total costs from violations of the energy balance

  • Carbon costs and revenues

  • Total cost per investment period as a sum of technology, network, import, export, violation and carbon costs

Parameters:
  • model – pyomo model

  • config (dict) – dict containing model information

Returns:

pyomo model

delete_all_balances(model)

Deletes all balances (required if they need to be reconstructed)

Parameters:

model – pyomo model

Returns:

pyomo model