zen-garden 1.7.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. zen_garden-1.7.5/LICENSE.txt +21 -0
  2. zen_garden-1.7.5/PKG-INFO +106 -0
  3. zen_garden-1.7.5/README.md +67 -0
  4. zen_garden-1.7.5/pyproject.toml +55 -0
  5. zen_garden-1.7.5/zen_garden/__init__.py +11 -0
  6. zen_garden-1.7.5/zen_garden/__main__.py +83 -0
  7. zen_garden-1.7.5/zen_garden/_internal.py +103 -0
  8. zen_garden-1.7.5/zen_garden/model/__init__.py +1 -0
  9. zen_garden-1.7.5/zen_garden/model/default_config.py +178 -0
  10. zen_garden-1.7.5/zen_garden/model/objects/__init__.py +2 -0
  11. zen_garden-1.7.5/zen_garden/model/objects/carrier/__init__.py +13 -0
  12. zen_garden-1.7.5/zen_garden/model/objects/carrier/carrier.py +486 -0
  13. zen_garden-1.7.5/zen_garden/model/objects/component.py +1331 -0
  14. zen_garden-1.7.5/zen_garden/model/objects/element.py +397 -0
  15. zen_garden-1.7.5/zen_garden/model/objects/energy_system.py +557 -0
  16. zen_garden-1.7.5/zen_garden/model/objects/technology/__init__.py +13 -0
  17. zen_garden-1.7.5/zen_garden/model/objects/technology/conversion_technology.py +572 -0
  18. zen_garden-1.7.5/zen_garden/model/objects/technology/retrofitting_technology.py +142 -0
  19. zen_garden-1.7.5/zen_garden/model/objects/technology/storage_technology.py +445 -0
  20. zen_garden-1.7.5/zen_garden/model/objects/technology/technology.py +1003 -0
  21. zen_garden-1.7.5/zen_garden/model/objects/technology/transport_technology.py +396 -0
  22. zen_garden-1.7.5/zen_garden/model/objects/time_steps.py +266 -0
  23. zen_garden-1.7.5/zen_garden/model/optimization_setup.py +709 -0
  24. zen_garden-1.7.5/zen_garden/postprocess/.gitkeep +1 -0
  25. zen_garden-1.7.5/zen_garden/postprocess/__init__.py +0 -0
  26. zen_garden-1.7.5/zen_garden/postprocess/comparisons.py +342 -0
  27. zen_garden-1.7.5/zen_garden/postprocess/postprocess.py +507 -0
  28. zen_garden-1.7.5/zen_garden/postprocess/results/__init__.py +3 -0
  29. zen_garden-1.7.5/zen_garden/postprocess/results/multi_hdf_loader.py +546 -0
  30. zen_garden-1.7.5/zen_garden/postprocess/results/results.py +681 -0
  31. zen_garden-1.7.5/zen_garden/postprocess/results/solution_loader.py +223 -0
  32. zen_garden-1.7.5/zen_garden/preprocess/__init__.py +0 -0
  33. zen_garden-1.7.5/zen_garden/preprocess/extract_input_data.py +847 -0
  34. zen_garden-1.7.5/zen_garden/preprocess/time_series_aggregation.py +425 -0
  35. zen_garden-1.7.5/zen_garden/preprocess/unit_handling.py +1026 -0
  36. zen_garden-1.7.5/zen_garden/utils.py +1474 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 Reliability and Risk Engineering, ETH Zurich
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,106 @@
1
+ Metadata-Version: 2.1
2
+ Name: zen_garden
3
+ Version: 1.7.5
4
+ Summary: ZEN-garden is an optimization model of energy systems and value chains.
5
+ Author-email: Jacob Mannhardt <jmannhardt@ethz.ch>, Alissa Ganter <aganter@ethz.ch>
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ Requires-Dist: xarray
9
+ Requires-Dist: cython
10
+ Requires-Dist: numpy<=1.26.4
11
+ Requires-Dist: pandas>=2.2
12
+ Requires-Dist: scipy
13
+ Requires-Dist: pint
14
+ Requires-Dist: tables
15
+ Requires-Dist: pydantic
16
+ Requires-Dist: tsam
17
+ Requires-Dist: h5py
18
+ Requires-Dist: filelock
19
+ Requires-Dist: ordered-set
20
+ Requires-Dist: pyogrio
21
+ Requires-Dist: psutil
22
+ Requires-Dist: linopy<=0.3.10
23
+ Requires-Dist: pytest ; extra == "dev"
24
+ Requires-Dist: coverage ; extra == "dev"
25
+ Requires-Dist: sphinx==7.3.7 ; extra == "docs"
26
+ Requires-Dist: myst-parser==3.0.1 ; extra == "docs"
27
+ Requires-Dist: sphinx-book-theme==1.1.3 ; extra == "docs"
28
+ Requires-Dist: pydata-sphinx-theme==0.15.4 ; extra == "docs"
29
+ Requires-Dist: sphinx-reredirects==0.1.4 ; extra == "docs"
30
+ Requires-Dist: nbsphinx==0.9.4 ; extra == "docs"
31
+ Requires-Dist: nbsphinx-link==1.3.0 ; extra == "docs"
32
+ Requires-Dist: gurobipy ; extra == "gurobipy"
33
+ Project-URL: Documentation, https://zen-garden.readthedocs.io/en/latest/
34
+ Project-URL: Homepage, https://github.com/ZEN-universe/ZEN-garden
35
+ Provides-Extra: dev
36
+ Provides-Extra: docs
37
+ Provides-Extra: gurobipy
38
+
39
+ # ZEN-garden
40
+
41
+ [![GitHub Release](https://img.shields.io/github/v/release/ZEN-universe/ZEN-garden)](https://github.com/ZEN-universe/ZEN-garden/releases)
42
+ [![GitHub Tag](https://img.shields.io/github/v/tag/ZEN-universe/ZEN-garden)](https://github.com/ZEN-universe/ZEN-garden/tags)
43
+ [![GitHub forks](https://img.shields.io/github/forks/ZEN-universe/ZEN-garden)](https://github.com/ZEN-universe/ZEN-garden/forks)
44
+
45
+ [![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/ZEN-universe/ZEN-garden/pytest_with_conda.yml)](https://github.com/ZEN-universe/ZEN-garden/actions)
46
+ [![Endpoint Badge](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/jacob-mannhardt/30d479a5b4c591a63b7b0f41abbce6a0/raw/zen_garden_coverage.json)](https://github.com/ZEN-universe/ZEN-garden/actions)
47
+
48
+ [![Read the Docs](https://img.shields.io/readthedocs/zen-garden?logo=readthedocs)](https://zen-garden.readthedocs.io/en/latest/index.html)
49
+
50
+
51
+ [//]: # (<table><tr><td valign="center"> )
52
+
53
+ [//]: # ( <img align="left" height="25px" src="https://github.com/RRE-ETH/ZEN-garden/actions/workflows/pytest_with_conda.yml/badge.svg?branch=development"> )
54
+
55
+ [//]: # ( <img align="left" height="25px" src="https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/jafluri/5d0d79e86182cd9ccd785d824b1f9ac7/raw/zen_coverage.json">)
56
+
57
+ [//]: # ( <b> &#40;Development Branch&#41; </b>)
58
+
59
+ [//]: # (</td></tr></table>)
60
+
61
+ [//]: # (<hr style="height: 5px; background-color: black;">)
62
+
63
+ <img src="https://github.com/ZEN-universe/ZEN-garden/assets/114185605/d6a9aca9-74b0-4a82-8295-43e6a78b8450" alt="drawing" width="200"/>
64
+
65
+ Welcome to the ZEN-garden! ZEN-garden is an optimization model of energy systems and value chains.
66
+ It is currently used to model the electricity system, hydrogen value chains, and carbon capture, storage and utilization (CCUS) value chains.
67
+ However, it is designed to be modular and flexible, and can be extended to model other types of energy systems, value chains or other network-based systems.
68
+
69
+ ZEN-garden is developed by the [Reliability and Risk Engineering Laboratory](https://www.rre.ethz.ch/) at ETH Zurich.
70
+ <hr style="height: 5px; background-color: black;">
71
+
72
+ ## Documentation
73
+ Please refer to the documentation of the ZEN-garden framework [on Read-the-Docs](https://zen-garden.readthedocs.io/en/latest/).
74
+ To get started with ZEN-garden, you can follow the instructions in the [installation guide](https://zen-garden.readthedocs.io/en/latest/files/installation.html).
75
+
76
+ In the file `documentation/how_to_ZEN-garden.md`, you can find additional information on how to use the framework.
77
+ The `documentation/dataset_creation_tutorial.md` file contains a tutorial on how to create a simple dataset for the framework.
78
+ Additionally, example datasets are available in the `dataset_examples` folder.
79
+
80
+ More in-depth manuals are available in the [discussions forum](https://github.com/ZEN-universe/ZEN-garden/discussions) of our repo.
81
+
82
+ ## News
83
+ Review recent modifications outlined in the [changelog](https://github.com/ZEN-universe/ZEN-garden/blob/main/CHANGELOG.md).
84
+
85
+ ## Citing ZEN-garden
86
+ If you use ZEN-garden for research please cite
87
+
88
+ Ganter Alissa, Gabrielli Paolo, Sansavini, Giovanni (2024).
89
+ Near-term infrastructure rollout and investment strategies for net-zero hydrogen supply chains
90
+ 2024. https://doi.org/10.1016/j.rser.2024.114314
91
+
92
+ and use the following BibTeX:
93
+ ```
94
+ @article{GANTER2024114314,
95
+ author = {Alissa Ganter and Paolo Gabrielli and Giovanni Sansavini}
96
+ title = {Near-term infrastructure rollout and investment strategies for net-zero hydrogen supply chains},
97
+ journal = {Renewable and Sustainable Energy Reviews},
98
+ volume = {194},
99
+ pages = {114314},
100
+ year = {2024},
101
+ issn = {1364-0321},
102
+ doi = {https://doi.org/10.1016/j.rser.2024.114314},
103
+ url = {https://www.sciencedirect.com/science/article/pii/S1364032124000376},
104
+ }
105
+ ```
106
+
@@ -0,0 +1,67 @@
1
+ # ZEN-garden
2
+
3
+ [![GitHub Release](https://img.shields.io/github/v/release/ZEN-universe/ZEN-garden)](https://github.com/ZEN-universe/ZEN-garden/releases)
4
+ [![GitHub Tag](https://img.shields.io/github/v/tag/ZEN-universe/ZEN-garden)](https://github.com/ZEN-universe/ZEN-garden/tags)
5
+ [![GitHub forks](https://img.shields.io/github/forks/ZEN-universe/ZEN-garden)](https://github.com/ZEN-universe/ZEN-garden/forks)
6
+
7
+ [![GitHub Actions Workflow Status](https://img.shields.io/github/actions/workflow/status/ZEN-universe/ZEN-garden/pytest_with_conda.yml)](https://github.com/ZEN-universe/ZEN-garden/actions)
8
+ [![Endpoint Badge](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/jacob-mannhardt/30d479a5b4c591a63b7b0f41abbce6a0/raw/zen_garden_coverage.json)](https://github.com/ZEN-universe/ZEN-garden/actions)
9
+
10
+ [![Read the Docs](https://img.shields.io/readthedocs/zen-garden?logo=readthedocs)](https://zen-garden.readthedocs.io/en/latest/index.html)
11
+
12
+
13
+ [//]: # (<table><tr><td valign="center"> )
14
+
15
+ [//]: # ( <img align="left" height="25px" src="https://github.com/RRE-ETH/ZEN-garden/actions/workflows/pytest_with_conda.yml/badge.svg?branch=development"> )
16
+
17
+ [//]: # ( <img align="left" height="25px" src="https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/jafluri/5d0d79e86182cd9ccd785d824b1f9ac7/raw/zen_coverage.json">)
18
+
19
+ [//]: # ( <b> &#40;Development Branch&#41; </b>)
20
+
21
+ [//]: # (</td></tr></table>)
22
+
23
+ [//]: # (<hr style="height: 5px; background-color: black;">)
24
+
25
+ <img src="https://github.com/ZEN-universe/ZEN-garden/assets/114185605/d6a9aca9-74b0-4a82-8295-43e6a78b8450" alt="drawing" width="200"/>
26
+
27
+ Welcome to the ZEN-garden! ZEN-garden is an optimization model of energy systems and value chains.
28
+ It is currently used to model the electricity system, hydrogen value chains, and carbon capture, storage and utilization (CCUS) value chains.
29
+ However, it is designed to be modular and flexible, and can be extended to model other types of energy systems, value chains or other network-based systems.
30
+
31
+ ZEN-garden is developed by the [Reliability and Risk Engineering Laboratory](https://www.rre.ethz.ch/) at ETH Zurich.
32
+ <hr style="height: 5px; background-color: black;">
33
+
34
+ ## Documentation
35
+ Please refer to the documentation of the ZEN-garden framework [on Read-the-Docs](https://zen-garden.readthedocs.io/en/latest/).
36
+ To get started with ZEN-garden, you can follow the instructions in the [installation guide](https://zen-garden.readthedocs.io/en/latest/files/installation.html).
37
+
38
+ In the file `documentation/how_to_ZEN-garden.md`, you can find additional information on how to use the framework.
39
+ The `documentation/dataset_creation_tutorial.md` file contains a tutorial on how to create a simple dataset for the framework.
40
+ Additionally, example datasets are available in the `dataset_examples` folder.
41
+
42
+ More in-depth manuals are available in the [discussions forum](https://github.com/ZEN-universe/ZEN-garden/discussions) of our repo.
43
+
44
+ ## News
45
+ Review recent modifications outlined in the [changelog](https://github.com/ZEN-universe/ZEN-garden/blob/main/CHANGELOG.md).
46
+
47
+ ## Citing ZEN-garden
48
+ If you use ZEN-garden for research please cite
49
+
50
+ Ganter Alissa, Gabrielli Paolo, Sansavini, Giovanni (2024).
51
+ Near-term infrastructure rollout and investment strategies for net-zero hydrogen supply chains
52
+ 2024. https://doi.org/10.1016/j.rser.2024.114314
53
+
54
+ and use the following BibTeX:
55
+ ```
56
+ @article{GANTER2024114314,
57
+ author = {Alissa Ganter and Paolo Gabrielli and Giovanni Sansavini}
58
+ title = {Near-term infrastructure rollout and investment strategies for net-zero hydrogen supply chains},
59
+ journal = {Renewable and Sustainable Energy Reviews},
60
+ volume = {194},
61
+ pages = {114314},
62
+ year = {2024},
63
+ issn = {1364-0321},
64
+ doi = {https://doi.org/10.1016/j.rser.2024.114314},
65
+ url = {https://www.sciencedirect.com/science/article/pii/S1364032124000376},
66
+ }
67
+ ```
@@ -0,0 +1,55 @@
1
+ [build-system]
2
+ requires = ["flit_core >=3.2,<4"]
3
+ build-backend = "flit_core.buildapi"
4
+
5
+ [project]
6
+ name = "zen_garden"
7
+ authors = [
8
+ {name = "Jacob Mannhardt", email = "jmannhardt@ethz.ch"},
9
+ {name = "Alissa Ganter", email = "aganter@ethz.ch"}
10
+ ]
11
+ version = "1.7.5"
12
+ requires-python= ">=3.10"
13
+ description="ZEN-garden is an optimization model of energy systems and value chains."
14
+ readme = "README.md"
15
+ license = { file = "LICENSE.txt" }
16
+
17
+ dependencies = [
18
+ "xarray",
19
+ "cython",
20
+ "numpy<=1.26.4",
21
+ "pandas>=2.2",
22
+ "scipy",
23
+ "pint",
24
+ "tables",
25
+ "pydantic",
26
+ "tsam",
27
+ "h5py",
28
+ "filelock",
29
+ "ordered-set",
30
+ "pyogrio",
31
+ "psutil",
32
+ "linopy<=0.3.10",
33
+ ]
34
+
35
+ [project.optional-dependencies]
36
+ docs = [
37
+ "sphinx==7.3.7",
38
+ "myst-parser==3.0.1",
39
+ "sphinx-book-theme==1.1.3",
40
+ "pydata-sphinx-theme==0.15.4",
41
+ "sphinx-reredirects==0.1.4",
42
+ "nbsphinx==0.9.4",
43
+ "nbsphinx-link==1.3.0",
44
+ ]
45
+
46
+ dev = [
47
+ "pytest",
48
+ "coverage",
49
+ ]
50
+
51
+ gurobipy = ["gurobipy"]
52
+
53
+ [project.urls]
54
+ Homepage = "https://github.com/ZEN-universe/ZEN-garden"
55
+ Documentation = "https://zen-garden.readthedocs.io/en/latest/"
@@ -0,0 +1,11 @@
1
+ from . import model
2
+ from . import postprocess
3
+ from . import preprocess
4
+ from .utils import get_inheritors
5
+
6
+ from .model.objects.element import Element
7
+ from .model.optimization_setup import OptimizationSetup
8
+
9
+ # set the element classes of the EnergySystem class
10
+ inheritors = get_inheritors(Element)
11
+ OptimizationSetup.dict_element_classes.update({klass.__name__: klass for klass in inheritors})
@@ -0,0 +1,83 @@
1
+ """
2
+ :Title: ZEN-GARDEN
3
+ :Created: September-2022
4
+ :Authors: Janis Fluri (janis.fluri@id.ethz.ch),
5
+ Alissa Ganter (aganter@ethz.ch),
6
+ Jacob Mannhardt (jmannhardt@ethz.ch)
7
+ :Organization: Laboratory of Reliability and Risk Engineering, ETH Zurich
8
+
9
+ Compilation of the optimization problem.
10
+ """
11
+ from ._internal import main
12
+ import importlib.util
13
+ import argparse
14
+ import sys
15
+ import os
16
+ import zen_garden.model.default_config as default_config
17
+ import json
18
+ from zen_garden.utils import copy_dataset_example
19
+
20
+ def run_module(args=None):
21
+ """
22
+ Runs the main function of ZEN-Garden
23
+
24
+ :param args: Arguments to parse
25
+ """
26
+ if args is None:
27
+ args = sys.argv[1:]
28
+
29
+ # parse the args
30
+ description = "Run ZEN garden with a given config file. Per default, the config file will be read out from the " \
31
+ "current working directory. You can specify a config file with the --config argument. However, " \
32
+ "note that the output directory will always be the current working directory, independent of the " \
33
+ "dataset specified in the config file."
34
+ parser = argparse.ArgumentParser(description=description, add_help=True, usage="usage: python -m zen_garden [-h] [--config CONFIG] [--dataset DATASET] [--job_index JOB_INDEX] [--job_index_var JOB_INDEX_VAR] [--example EXAMPLE]")
35
+ # TODO make json config default
36
+ parser.add_argument("--config", required=False, type=str, default="./config.py", help="The config file used to run the pipeline, "
37
+ "defaults to config.py in the current directory.")
38
+ parser.add_argument("--dataset", required=False, type=str, default=None, help="Path to the dataset used for the run. IMPORTANT: This will overwrite the "
39
+ "config.analysis['dataset'] attribute of the config file!")
40
+ parser.add_argument("--job_index", required=False, type=str, default=None, help="A comma separated list (no spaces) of indices of the scenarios to run, if None, all scenarios are run in sequence")
41
+ parser.add_argument("--job_index_var", required=False, type=str, default="SLURM_ARRAY_TASK_ID", help="Try to read out the job index from the environment variable specified here. "
42
+ "If both --job_index and --job_index_var are specified, --job_index will be used.")
43
+ parser.add_argument("--example", required=False, type=str, default=None, help="Run an example scenario. The argument should be the name of a dataset example in documentation/dataset_examples. This command will copy the dataset and the config to the current folder and run the example.")
44
+
45
+ args = parser.parse_args(args)
46
+
47
+ # copy example dataset and run example #TODO so far doesn't work because dataset_examples are not part of the package but outside
48
+ if args.example is not None:
49
+ example_path_cwd,config_path_cwd = copy_dataset_example(args.example)
50
+ args.dataset = example_path_cwd
51
+ args.config = config_path_cwd
52
+
53
+ if not os.path.exists(args.config):
54
+ args.config = args.config.replace(".py", ".json")
55
+
56
+ # change working directory to the directory of the config file
57
+ config_path, config_file = os.path.split(args.config)
58
+ os.chdir(config_path)
59
+ ### import the config
60
+ if config_file.endswith(".py"):
61
+ spec = importlib.util.spec_from_file_location("module", config_file)
62
+ module = importlib.util.module_from_spec(spec)
63
+ spec.loader.exec_module(module)
64
+ config = module.config
65
+ else:
66
+ with open(args.config, "r") as f:
67
+ config = default_config.Config(**json.load(f))
68
+
69
+ ### get the job index
70
+ job_index = args.job_index
71
+ if job_index is None:
72
+ if (job_index := os.environ.get(args.job_index_var)) is not None:
73
+ job_index = int(job_index)
74
+ else:
75
+ job_index = [int(i) for i in job_index.split(",")]
76
+
77
+ ### run
78
+ main(config=config, dataset_path=args.dataset, job_index=job_index)
79
+
80
+
81
+ if __name__ == "__main__":
82
+
83
+ run_module()
@@ -0,0 +1,103 @@
1
+ """
2
+ :Title: ZEN-GARDEN
3
+ :Created: October-2021
4
+ :Authors: Alissa Ganter (aganter@ethz.ch),
5
+ Jacob Mannhardt (jmannhardt@ethz.ch)
6
+ :Organization: Laboratory of Reliability and Risk Engineering, ETH Zurich
7
+
8
+ Compilation of the optimization problem.
9
+ """
10
+ import cProfile
11
+ import importlib.util
12
+ import logging
13
+ import os
14
+ from collections import defaultdict
15
+ import importlib
16
+
17
+ from .model.optimization_setup import OptimizationSetup
18
+ from .postprocess.postprocess import Postprocess
19
+ from .utils import setup_logger, InputDataChecks, StringUtils, ScenarioUtils, OptimizationError
20
+ from .preprocess.unit_handling import Scaling
21
+
22
+ # we setup the logger here
23
+ setup_logger()
24
+
25
+
26
+ def main(config, dataset_path=None, job_index=None):
27
+ """
28
+ This function runs ZEN garden,
29
+ it is executed in the __main__.py script
30
+
31
+ :param config: A config instance used for the run
32
+ :param dataset_path: If not None, used to overwrite the config.analysis["dataset"]
33
+ :param job_index: The index of the scenario to run or a list of indices, if None, all scenarios are run in sequence
34
+ """
35
+
36
+ # print the version
37
+ version = importlib.metadata.version("zen-garden")
38
+ logging.info(f"Running ZEN-garden version: {version}")
39
+
40
+ # prevent double printing
41
+ logging.propagate = False
42
+
43
+ # overwrite the path if necessary
44
+ if dataset_path is not None:
45
+ # logging.info(f"Overwriting dataset to: {dataset_path}")
46
+ config.analysis["dataset"] = dataset_path
47
+ logging.info(f"Optimizing for dataset {config.analysis['dataset']}")
48
+ # get the abs path to avoid working dir stuff
49
+ config.analysis["dataset"] = os.path.abspath(config.analysis['dataset'])
50
+ config.analysis["folder_output"] = os.path.abspath(config.analysis['folder_output'])
51
+
52
+ ### SYSTEM CONFIGURATION
53
+ input_data_checks = InputDataChecks(config=config, optimization_setup=None)
54
+ input_data_checks.check_dataset()
55
+ input_data_checks.read_system_file(config)
56
+ input_data_checks.check_technology_selections()
57
+ input_data_checks.check_year_definitions()
58
+ # overwrite default system and scenario dictionaries
59
+ scenarios,elements = ScenarioUtils.get_scenarios(config,job_index)
60
+ # get the name of the dataset
61
+ model_name, out_folder = StringUtils.setup_model_folder(config.analysis,config.system)
62
+ # clean sub-scenarios if necessary
63
+ ScenarioUtils.clean_scenario_folder(config,out_folder)
64
+ ### ITERATE THROUGH SCENARIOS
65
+ for scenario, scenario_dict in zip(scenarios, elements):
66
+ # FORMULATE THE OPTIMIZATION PROBLEM
67
+ # add the scenario_dict and read input data
68
+ optimization_setup = OptimizationSetup(config, scenario_dict=scenario_dict, input_data_checks=input_data_checks)
69
+ # get rolling horizon years
70
+ steps_horizon = optimization_setup.get_optimization_horizon()
71
+ # iterate through horizon steps
72
+ for step in steps_horizon:
73
+ StringUtils.print_optimization_progress(scenario,steps_horizon,step,system=config.system)
74
+ # overwrite time indices
75
+ optimization_setup.overwrite_time_indices(step)
76
+ # create optimization problem
77
+ optimization_setup.construct_optimization_problem()
78
+ #TODO scaling algorithm
79
+ if config.solver["use_scaling"]:
80
+ optimization_setup.scaling.run_scaling()
81
+ else:
82
+ optimization_setup.scaling.analyze_numerics()
83
+ # SOLVE THE OPTIMIZATION PROBLEM
84
+ optimization_setup.solve()
85
+ # break if infeasible
86
+ if not optimization_setup.optimality:
87
+ # write IIS
88
+ optimization_setup.write_IIS()
89
+ raise OptimizationError(optimization_setup.model.termination_condition)
90
+ if config.solver["use_scaling"]:
91
+ optimization_setup.scaling.re_scale()
92
+ # save new capacity additions and cumulative carbon emissions for next time step
93
+ optimization_setup.add_results_of_optimization_step(step)
94
+ # EVALUATE RESULTS
95
+ # create scenario name, subfolder and param_map for postprocessing
96
+ scenario_name, subfolder, param_map = StringUtils.generate_folder_path(
97
+ config = config,scenario = scenario,scenario_dict=scenario_dict,steps_horizon=steps_horizon,step=step
98
+ )
99
+ # write results
100
+ Postprocess(optimization_setup, scenarios=config.scenarios, subfolder=subfolder,
101
+ model_name=model_name, scenario_name=scenario_name, param_map=param_map)
102
+ logging.info("--- Optimization finished ---")
103
+ return optimization_setup
@@ -0,0 +1 @@
1
+ from .default_config import Config
@@ -0,0 +1,178 @@
1
+ """
2
+ :Title: ZEN-GARDEN
3
+ :Created: October-2021
4
+ :Authors: Alissa Ganter (aganter@ethz.ch)
5
+ :Organization: Laboratory of Reliability and Risk Engineering, ETH Zurich
6
+
7
+ Default configuration. Changes from the default values are specified in config.py (folders data/tests) and system.py (individual datasets)
8
+ """
9
+
10
+ from pydantic import BaseModel, ConfigDict
11
+ from typing import Any, Optional, Union
12
+
13
+
14
+ class Subscriptable(BaseModel, extra="allow"):
15
+ def __getitem__(self, __name: str) -> Any:
16
+ return getattr(self, __name)
17
+
18
+ def __setitem__(self, __name: str, __value: Any) -> None:
19
+ setattr(self, __name, __value)
20
+
21
+ def keys(self) -> Any:
22
+ return self.model_dump().keys()
23
+
24
+ def update(self, new_values: dict[Any, Any]) -> None:
25
+ for key, val in new_values.items():
26
+ if isinstance(val, dict):
27
+ getattr(self, key).update(val)
28
+ else:
29
+ setattr(self, key, val)
30
+
31
+ def items(self) -> Any:
32
+ return self.model_dump().items()
33
+
34
+ def values(self) -> Any:
35
+ return self.model_dump().values()
36
+
37
+ def __iter__(self) -> Any:
38
+ self.fix_keys = list(self.model_dump().keys())
39
+ self.i = 0
40
+ return self
41
+
42
+ def __next__(self) -> Any:
43
+ if self.i < len(self.fix_keys):
44
+ ans = self.fix_keys[self.i]
45
+ self.i += 1
46
+ return ans
47
+ else:
48
+ del self.i
49
+ del self.fix_keys
50
+ raise StopIteration
51
+
52
+
53
+ class Subsets(Subscriptable):
54
+ set_carriers: list[str] = []
55
+ set_technologies: dict[str, list[str]] | list[str] = {
56
+ "set_conversion_technologies": ["set_retrofitting_technologies"],
57
+ "set_transport_technologies": [],
58
+ "set_storage_technologies": [],
59
+ }
60
+
61
+
62
+ class HeaderDataInputs(Subscriptable):
63
+ set_nodes: str = "node"
64
+ set_edges: str = "edge"
65
+ set_location: str = "location"
66
+ set_time_steps: str = "time" # IMPORTANT: time must be unique
67
+ set_time_steps_operation: str = "time_operation"
68
+ set_time_steps_storage_level: str = "time_storage_level"
69
+ set_time_steps_yearly: str = "year" # IMPORTANT: year must be unique
70
+ set_time_steps_yearly_entire_horizon: str = "year_entire_horizon"
71
+ set_carriers: str = "carrier"
72
+ set_input_carriers: str = "carrier"
73
+ set_output_carriers: str = "carrier"
74
+ set_time_steps_storage: str = "time_storage_level"
75
+ set_dependent_carriers: str = "carrier"
76
+ set_elements: str = "element"
77
+ set_conversion_technologies: str = "technology"
78
+ set_transport_technologies: str = "technology"
79
+ set_transport_technologies_loss_exponential: str = "technology"
80
+ set_storage_technologies: str = "technology"
81
+ set_technologies: str = "technology"
82
+ set_technologies_existing: str = "technology_existing"
83
+ set_capacity_types: str = "capacity_type"
84
+
85
+ class System(Subscriptable):
86
+ model_config = ConfigDict(extra="allow")
87
+ set_carriers: list[str] = []
88
+ set_capacity_types: list[str] = ["power", "energy"]
89
+ set_conversion_technologies: list[str] = []
90
+ set_storage_technologies: list[str] = []
91
+ set_retrofitting_technologies: list[str] = []
92
+ storage_periodicity: bool = True
93
+ set_transport_technologies: list[str] = []
94
+ set_transport_technologies_loss_exponential: list[str] = []
95
+ double_capex_transport: bool = False
96
+ set_nodes: list[str] = []
97
+ exclude_parameters_from_TSA: bool = True
98
+ conduct_scenario_analysis: bool = False
99
+ run_default_scenario: bool = True
100
+ clean_sub_scenarios: bool = False
101
+ total_hours_per_year: int = 8760
102
+ knowledge_depreciation_rate: float = 0.1
103
+ enforce_selfish_behavior: bool = False
104
+ reference_year: int = 2023
105
+ unaggregated_time_steps_per_year: int = 8760
106
+ aggregated_time_steps_per_year: int = 10
107
+ conduct_time_series_aggregation: bool = True
108
+ optimized_years: int = 3
109
+ interval_between_years: int = 1
110
+ use_rolling_horizon: bool = False
111
+ years_in_rolling_horizon: int = 5
112
+ years_in_decision_horizon: int = 1
113
+ use_capacities_existing: bool = True
114
+
115
+ class SolverOptions(Subscriptable):
116
+ pass
117
+
118
+ class Solver(Subscriptable):
119
+ name: str = "highs"
120
+ solver_options: SolverOptions = SolverOptions()
121
+ check_unit_consistency: bool = True
122
+ solver_dir: str = ".//outputs//solver_files"
123
+ keep_files: bool = False
124
+ io_api: str = "lp"
125
+ add_duals: bool = False
126
+ recommend_base_units: bool = False
127
+ immutable_unit: list[str] = []
128
+ range_unit_exponents: dict[str, int] = {"min": -1, "max": 1, "step_width": 1}
129
+ rounding_decimal_points: int = 5
130
+ rounding_decimal_points_ts: int = 4
131
+ linear_regression_check: dict[str, float] = {
132
+ "eps_intercept": 0.1,
133
+ "epsRvalue": 1 - (1e-5),
134
+ }
135
+ rounding_decimal_points_units: int = 6
136
+ round_parameters: bool = True
137
+ rounding_decimal_points_capacity: int = 4
138
+ analyze_numerics: bool = True
139
+ use_scaling: bool = True
140
+ scaling_include_rhs: bool = False
141
+ scaling_algorithm: Union[list[str],str] = ["geom","geom","geom"]
142
+
143
+
144
+
145
+ class TimeSeriesAggregation(Subscriptable):
146
+ slv: Solver = Solver()
147
+ clusterMethod: str = "hierarchical"
148
+ solver: str = slv.name
149
+ hoursPerPeriod: int = 1
150
+ extremePeriodMethod: Optional[str] = "None"
151
+ rescaleClusterPeriods: bool = False
152
+ representationMethod: str = "meanRepresentation"
153
+ resolution: int = 1
154
+ segmentation: bool = False
155
+ noSegments: int = 12
156
+
157
+ class Analysis(Subscriptable):
158
+ dataset: str = ""
159
+ objective: str = "total_cost"
160
+ sense: str = "minimize"
161
+ transport_distance: str = "Euclidean"
162
+ subsets: Subsets = Subsets()
163
+ header_data_inputs: HeaderDataInputs = HeaderDataInputs()
164
+ time_series_aggregation: TimeSeriesAggregation = TimeSeriesAggregation()
165
+ folder_output: str = "./outputs/"
166
+ overwrite_output: bool = True
167
+ output_format: str = "h5"
168
+ write_results_yml: bool = False
169
+ max_output_size_mb: int = 500
170
+ folder_name_system_specification: str = "system_specification"
171
+ earliest_year_of_data: int = 1900
172
+
173
+ class Config(Subscriptable):
174
+ analysis: Analysis = Analysis()
175
+ solver: Solver = Solver()
176
+ system: System = System()
177
+
178
+ scenarios: dict[str, Any] = {"": {}}
@@ -0,0 +1,2 @@
1
+ from .carrier import *
2
+ from .technology import *
@@ -0,0 +1,13 @@
1
+ """==========
2
+ :Title: ZEN-GARDEN
3
+ :Created: March-2022
4
+ :Authors: Alissa Ganter (aganter@ethz.ch)
5
+ :Organization: Laboratory of Reliability and Risk Engineering, ETH Zurich
6
+
7
+ function that loads all classes and subclasses of carrier directory.
8
+ """
9
+ from pathlib import Path
10
+
11
+ # register the subclasses
12
+ modules = Path(__file__).parent.glob("*.py")
13
+ __all__ = [f.stem for f in modules if f.is_file()]