MESSAGEix-Buildings

Caution

This documentation and the related code was migrated from message_data dev branch as of commit 8213e6c (2025-05-08) in PR #350. It does not reflect further changes made on the message_data main branch, other related branches, or in forks or other repositories.

MESSAGEix-Buildings refers to a set of models including a specific configuration of MESSAGEix-GLOBIOM.

Code is maintained in the iiasa/MESSAGE_Buildings repository.

Function

This section briefly describes how the contents of the MESSAGE_Buildings repo and message_data interact, as a guide to reading the code.

ACCESS and STURM

The MESSAGE_Buildings contains two models (collectively the “buildings models”):

  • ACCESS: includes cooking end-use in the residential sector.

  • STURM: includes some residential and other end-uses, as well as the construction and demolition of buildings.

“MESSAGEix-Buildings” is thus the combination of ACCESS, STURM, and MESSAGEix-GLOBIOM (i.e. an instance of MESSAGE).

Both of the buildings models require as input prices for energy commodities. In MESSAGEix-Buildings, this is obtained from an existing MESSAGEix-GLOBIOM scenario. They produce various outputs; the ones relevant to MESSAGEix-Buildings are described below.

Build and solve

There are two phases to ‘running’ MESSAGEix-Buildings. These are handled by buildings.build_and_solve().

  1. Build. This refers to building a MESSAGE scenario with structure capturing buildings technologies, commodities, etc., from a base scenario that lacks these features. During this process, data is also needed to parametrize these new technologies; this data is obtained as output from ACCESS and STURM.

    Thus, the order of operations is:

    1. Prices are retrieved from the base scenario.

    2. ACCESS is run, and its output stored temporarily in variables and/or files.

    3. STURM is run, and its output stored temporarily in variables and/or files.

    4. The base MESSAGE scenario is modified to add buildings structure and parameter data derived from (2) and (3).

    These steps are handled by buildings.pre_solve().

  2. Solve. Because prices are endogenous in MESSAGE, solving the MESSAGE scenario produced by (1.4) can result in prices that are different from the ones provided to ACCESS and STURM in steps (1.2) and (1.3).

    For this reason, MESSAGEix-Buildings is set up to use the iterative solve feature of ixmp.Scenario.solve(). buildings.pre_solve() precedes the solution of the MESSAGE LP; afterwards buildings.post_solve() computes a convergence criterion.

    If the activity levels (demand) have not converged, the iteration loop repeats, up until max_iterations.

    Note

    As of 2023-01-10, this is not in active use; the models are run in a once-through fashion with max_iterations set to 1. See also the NAVIGATE workflow, wherein a second iteration is run manually after a policy scenario is solved.

Report

Reporting for MESSAGEix-Buildings involves the following pieces:

  1. In the “Build” phase above, STURM is run produces its own reporting output files. These are different from temporary files used in step (1.4) above to set up the buildings details.

    ACCESS does not produce reporting output files.

  2. buildings.report contains (genno-based) reporting code (buildings.report.callback()), i.e. extending the built-in /reference/reporting features of message_data, message_ix, and ixmp.

    As with the other reporting, this is decomposed into multiple functions arranged in a graph of tasks. Inter alia, computing the key buildings all will:

    • Read the STURM output files and subset some contents, e.g. service levels.

    • Compute custom aggregates based on standard message_data reporting, e.g. for final energy.

    • Transform these into the IAMC structure, i.e. by collapsing multiple dimensions into “Variable” strings.

    • Store these as time series data on the scenario being reported.

    • Write the final and some intermediate data to files.

    These reporting features handle quantities including final energy, but not emissions.

  3. For certain quantities, notably emissions, the legacy reporting code must be used. (This is because, as of 2023-01-10, there is no genno-based reporting that provides adjustments necessary for certain representations in main MESSAGEix-GLOBIOM scenarios, e.g. blending in gas supply.)

    buildings.report.configure_legacy_reporting() sets certain entries in default_tables.TECHS; for instance, the entry “rc coal” contains a list of technology IDs for residential and commercial (hence rc or RC) buildings technologies which consume the commodity coal. By default (in the base global model), this is a list with a single entry, “coal_rc”. buildings.report.configure_legacy_reporting() replaces this with multiple entries for various technologies.

    The legacy reporting also performs aggregation over quantities, including final energy, emissions, and others, computed by itself or found as time series data on the scenario, e.g. that stored by (2). This functionality is not documented here in its entirety.

Usage

  1. Clone the main MESSAGE_Buildings repo, linked above.

    Either use a directory named buildings in the same directory containing message_data; or, note the path and set this in the ixmp configuration file:

    ixmp config set "message buildings dir" /path/to/cloned/message-buildings/repo
    
  2. Invoke the model using, for example:

    mix-models \
      --url="ixmp://ixmp-dev/model name/base scenario" \
      buildings build-solve \
      --dest="ixmp://ixmp-dev/new model name/target scenario"
    
  3. Run the reporting:

    mix-models \
      --url="ixmp://ixmp-dev/new model name/target scenario" \
      report -m model.buildings "buildings all"
    

Base and destination scenarios

The following correspond to MESSAGE-BUILDINGS.py, given with the comment “BM NPi (after “run_cdlinks_setup” for NPi). This has MACRO but here run MESSAGE only.”

mix-models \
  --url="ixmp://ixmp-dev/MESSAGEix-GLOBIOM 1.1-BM-R12-NGFS/NPi2020-con-prim-dir-ncr" \
  buildings build-solve \
  --dest="ixmp://ixmp-dev/MESSAGEix-GLOBIOM 1.1-BM-R12-NGFS/NPi2020-con-prim-dir-ncr-building"

If using clim_scen="2C", the following scenario is used as the reference scenario for prices:

mix-models \
  --url="ixmp://ixmp-dev/MESSAGEix-GLOBIOM 1.1-BM-R12-NGFS/NPi2020-con-prim-dir-ncr" \
  buildings build-solve \
  --climate-scen="ENGAGE_SSP2_v4.1.8/EN_NPi2020_1000f" \
  --dest="ixmp://ixmp-dev/MESSAGEix-GLOBIOM 1.1-BM-R12-NGFS/NPi2020-con-prim-dir-ncr-building"

The following is commented in MESSAGE-BUILDINGS.py with the comment “NOTE: this scenario has the updated GLOBIOM matrix.”

mix-models \
  --url="ixmp://ixmp-dev/MESSAGEix-GLOBIOM 1.1-M-R12-NGFS/baseline" \
  buildings build-solve \
  --dest="ixmp://ixmp-dev/MESSAGEix-GLOBIOM 1.1-BM-R12-NGFS/baseline"

The following correspond to MESSAGE-BUILDINGS-STURM.py:

mix-models \
  --url="ixmp://ixmp-dev/MESSAGEix-GLOBIOM 1.1-M-R12-NGFS/baseline" \
  buildings build-solve \
  --dest="ixmp://ixmp-dev/MESSAGEix-GLOBIOM 1.1-BM-R12-EFC/baseline"

and:

mix-models \
  --url="ixmp://ixmp-dev/MESSAGEix-GLOBIOM 1.1-M-R12-NGFS/baseline" \
  buildings build-solve \
  --climate-scen="MESSAGEix-GLOBIOM 1.1-M-R12-NGFS/EN_NPi2020_1000" \
  --dest="ixmp://ixmp-dev/MESSAGEix-GLOBIOM 1.1-BM-R12-EFC/baseline"

The following corresponds to reporting_EFC.py:

mix-models \
  --url="ixmp://ixmp-dev/MESSAGEix-GLOBIOM 1.1-BM-R12-EFC/baseline#24" \
  report -m model.buildings "buildings all"

Configuration

The class buildings.Config defines all the options to which the code responds, as well as default values. Values given in code or on the command line will override these.

class message_ix_models.model.buildings.Config(sturm_scenario: str, climate_scenario: str = 'BL', clone: bool = False, code_dir: ~pathlib.Path = <factory>, max_iterations: int = 0, with_materials: bool = True, _output_path: ~pathlib.Path | None = None, run_access: bool = False, solve: dict[str, ~typing.Any] = <factory>, solve_config: ~message_ix_models.model.workflow.Config = <factory>, ssp: str = 'SSP2', sturm_method: str = 'Rscript')[source]

Configuration options for buildings code.

The code responds to values set on an instance of this class.

Raises:

FileNotFoundError – if code_dir points to a non-existent directory.

climate_scenario: str = 'BL'

Climate scenario. Either BL or 2C.

clone: bool = False

True if the base scenario should be cloned.

code_dir: Path

Path to the MESSAGEix-Buildings code and data.

If not set explicitly, this is populated using _code_dir_factory().

max_iterations: int = 0

Maximum number of iterations of the ACCESS–STURM–MESSAGE loop. Set to 1 for once-through mode.

run_access: bool = False

Run the ACCESS model on every iteration.

solve: dict[str, Any]

Keyword arguments for message_ix.Scenario.solve(). Set model=”MESSAGE_MACRO” to solve scenarios using MESSAGE_MACRO.

solve_config: Config

Similar to solve, but using another config class

ssp: str = 'SSP2'

Todo

Document the meaning of this setting.

sturm_method: str = 'Rscript'

Method for running STURM. See sturm.run().

sturm_scenario: str

Name or ID of STURM scenario to run.

with_materials: bool = True

True if the MESSAGEix-Materials + MESSAGEix-Buildings combination is active

Code reference

buildings

MESSAGEix-Buildings and related models.