From 75395ac34c17057c20922078ad6fb3f2be51d711 Mon Sep 17 00:00:00 2001 From: Tom Bland Date: Fri, 29 Nov 2024 15:17:45 +0000 Subject: [PATCH 1/4] Change default solver to scipy --- docs/inputs/toml.rst | 6 +++--- .../add-agent/1-single-objective/settings.toml | 2 +- .../add-agent/2-multiple-objective/settings.toml | 2 +- .../add-correlation-demand/1-correlation/settings.toml | 2 +- .../add-new-technology/1-introduction/settings.toml | 2 +- .../add-new-technology/2-scenario/settings.toml | 2 +- docs/tutorial-code/add-region/1-new-region/settings.toml | 2 +- .../add-service-demand/1-exogenous-demand/settings.toml | 2 +- .../carbon-budget/1-carbon-budget/settings.toml | 2 +- .../1-min-constraint/settings.toml | 2 +- .../2-max-constraint/settings.toml | 2 +- .../modify-timing-data/1-modify-timeslices/settings.toml | 2 +- .../2-modify-time-framework/settings.toml | 2 +- docs/tutorial-code/new-decision-metric/settings.toml | 2 +- src/muse/agents/factories.py | 2 +- src/muse/data/example/default/settings.toml | 2 +- src/muse/data/example/default_retro/settings.toml | 2 +- src/muse/data/example/default_timeslice/settings.toml | 2 +- src/muse/sectors/subsector.py | 2 +- 19 files changed, 21 insertions(+), 21 deletions(-) diff --git a/docs/inputs/toml.rst b/docs/inputs/toml.rst index 058b64e20..c1909a419 100644 --- a/docs/inputs/toml.rst +++ b/docs/inputs/toml.rst @@ -442,12 +442,12 @@ Sectors contain a number of subsections: are registered via :py:func:`~muse.investments.register_investment`. At time of writing, three are available: + - "scipy" solver (default): Formulates investment as a true LP problem and solves it using + the `scipy solver`_. + - an "adhoc" solver: Simple in-house solver that ranks the technologies according to cost and service the demand incrementally. - - "scipy" solver: Formulates investment as a true LP problem and solves it using - the `scipy solver`_. - - "cvxopt" solver: Formulates investment as a true LP problem and solves it using the python package `cvxopt`_. `cvxopt`_ is *not* installed by default. Users can install it with ``pip install cvxopt`` or ``conda install cvxopt``. diff --git a/docs/tutorial-code/add-agent/1-single-objective/settings.toml b/docs/tutorial-code/add-agent/1-single-objective/settings.toml index 981977384..8c508b8cd 100644 --- a/docs/tutorial-code/add-agent/1-single-objective/settings.toml +++ b/docs/tutorial-code/add-agent/1-single-objective/settings.toml @@ -41,7 +41,7 @@ commodities_out = '{path}/technodata/residential/CommOut.csv' [sectors.residential.subsectors.all] agents = '{path}/technodata/Agents.csv' existing_capacity = '{path}/technodata/residential/ExistingCapacity.csv' -lpsolver = "scipy" # Optional, defaults to "adhoc" +lpsolver = "scipy" # Optional, defaults to "scipy" constraints = [ # Optional, defaults to the constraints below "max_production", diff --git a/docs/tutorial-code/add-agent/2-multiple-objective/settings.toml b/docs/tutorial-code/add-agent/2-multiple-objective/settings.toml index 981977384..8c508b8cd 100644 --- a/docs/tutorial-code/add-agent/2-multiple-objective/settings.toml +++ b/docs/tutorial-code/add-agent/2-multiple-objective/settings.toml @@ -41,7 +41,7 @@ commodities_out = '{path}/technodata/residential/CommOut.csv' [sectors.residential.subsectors.all] agents = '{path}/technodata/Agents.csv' existing_capacity = '{path}/technodata/residential/ExistingCapacity.csv' -lpsolver = "scipy" # Optional, defaults to "adhoc" +lpsolver = "scipy" # Optional, defaults to "scipy" constraints = [ # Optional, defaults to the constraints below "max_production", diff --git a/docs/tutorial-code/add-correlation-demand/1-correlation/settings.toml b/docs/tutorial-code/add-correlation-demand/1-correlation/settings.toml index 82d722630..ab825a656 100644 --- a/docs/tutorial-code/add-correlation-demand/1-correlation/settings.toml +++ b/docs/tutorial-code/add-correlation-demand/1-correlation/settings.toml @@ -41,7 +41,7 @@ commodities_out = '{path}/technodata/residential/CommOut.csv' [sectors.residential.subsectors.all] agents = '{path}/technodata/Agents.csv' existing_capacity = '{path}/technodata/residential/ExistingCapacity.csv' -lpsolver = "scipy" # Optional, defaults to "adhoc" +lpsolver = "scipy" # Optional, defaults to "scipy" constraints = [ # Optional, defaults to the constraints below "max_production", diff --git a/docs/tutorial-code/add-new-technology/1-introduction/settings.toml b/docs/tutorial-code/add-new-technology/1-introduction/settings.toml index b938346e1..25c2d0c85 100644 --- a/docs/tutorial-code/add-new-technology/1-introduction/settings.toml +++ b/docs/tutorial-code/add-new-technology/1-introduction/settings.toml @@ -41,7 +41,7 @@ commodities_out = '{path}/technodata/residential/CommOut.csv' [sectors.residential.subsectors.all] agents = '{path}/technodata/Agents.csv' existing_capacity = '{path}/technodata/residential/ExistingCapacity.csv' -lpsolver = "scipy" # Optional, defaults to "adhoc" +lpsolver = "scipy" # Optional, defaults to "scipy" constraints = [ # Optional, defaults to the constraints below "max_production", diff --git a/docs/tutorial-code/add-new-technology/2-scenario/settings.toml b/docs/tutorial-code/add-new-technology/2-scenario/settings.toml index b938346e1..25c2d0c85 100644 --- a/docs/tutorial-code/add-new-technology/2-scenario/settings.toml +++ b/docs/tutorial-code/add-new-technology/2-scenario/settings.toml @@ -41,7 +41,7 @@ commodities_out = '{path}/technodata/residential/CommOut.csv' [sectors.residential.subsectors.all] agents = '{path}/technodata/Agents.csv' existing_capacity = '{path}/technodata/residential/ExistingCapacity.csv' -lpsolver = "scipy" # Optional, defaults to "adhoc" +lpsolver = "scipy" # Optional, defaults to "scipy" constraints = [ # Optional, defaults to the constraints below "max_production", diff --git a/docs/tutorial-code/add-region/1-new-region/settings.toml b/docs/tutorial-code/add-region/1-new-region/settings.toml index d0e5557d2..6dfa11930 100644 --- a/docs/tutorial-code/add-region/1-new-region/settings.toml +++ b/docs/tutorial-code/add-region/1-new-region/settings.toml @@ -41,7 +41,7 @@ commodities_out = '{path}/technodata/residential/CommOut.csv' [sectors.residential.subsectors.all] agents = '{path}/technodata/Agents.csv' existing_capacity = '{path}/technodata/residential/ExistingCapacity.csv' -lpsolver = "scipy" # Optional, defaults to "adhoc" +lpsolver = "scipy" # Optional, defaults to "scipy" constraints = [ # Optional, defaults to the constraints below "max_production", diff --git a/docs/tutorial-code/add-service-demand/1-exogenous-demand/settings.toml b/docs/tutorial-code/add-service-demand/1-exogenous-demand/settings.toml index 981977384..8c508b8cd 100644 --- a/docs/tutorial-code/add-service-demand/1-exogenous-demand/settings.toml +++ b/docs/tutorial-code/add-service-demand/1-exogenous-demand/settings.toml @@ -41,7 +41,7 @@ commodities_out = '{path}/technodata/residential/CommOut.csv' [sectors.residential.subsectors.all] agents = '{path}/technodata/Agents.csv' existing_capacity = '{path}/technodata/residential/ExistingCapacity.csv' -lpsolver = "scipy" # Optional, defaults to "adhoc" +lpsolver = "scipy" # Optional, defaults to "scipy" constraints = [ # Optional, defaults to the constraints below "max_production", diff --git a/docs/tutorial-code/carbon-budget/1-carbon-budget/settings.toml b/docs/tutorial-code/carbon-budget/1-carbon-budget/settings.toml index 24815755c..ba5fac9c7 100644 --- a/docs/tutorial-code/carbon-budget/1-carbon-budget/settings.toml +++ b/docs/tutorial-code/carbon-budget/1-carbon-budget/settings.toml @@ -54,7 +54,7 @@ commodities_out = '{path}/technodata/residential/CommOut.csv' [sectors.residential.subsectors.all] agents = '{path}/technodata/Agents.csv' existing_capacity = '{path}/technodata/residential/ExistingCapacity.csv' -lpsolver = "scipy" # Optional, defaults to "adhoc" +lpsolver = "scipy" # Optional, defaults to "scipy" constraints = [ # Optional, defaults to the constraints below "max_production", diff --git a/docs/tutorial-code/min-max-timeslice-constraints/1-min-constraint/settings.toml b/docs/tutorial-code/min-max-timeslice-constraints/1-min-constraint/settings.toml index c566622c6..05130bfd0 100644 --- a/docs/tutorial-code/min-max-timeslice-constraints/1-min-constraint/settings.toml +++ b/docs/tutorial-code/min-max-timeslice-constraints/1-min-constraint/settings.toml @@ -41,7 +41,7 @@ commodities_out = '{path}/technodata/residential/CommOut.csv' [sectors.residential.subsectors.all] agents = '{path}/technodata/Agents.csv' existing_capacity = '{path}/technodata/residential/ExistingCapacity.csv' -lpsolver = "scipy" # Optional, defaults to "adhoc" +lpsolver = "scipy" # Optional, defaults to "scipy" constraints = [ # Optional, defaults to the constraints below "max_production", diff --git a/docs/tutorial-code/min-max-timeslice-constraints/2-max-constraint/settings.toml b/docs/tutorial-code/min-max-timeslice-constraints/2-max-constraint/settings.toml index c566622c6..05130bfd0 100644 --- a/docs/tutorial-code/min-max-timeslice-constraints/2-max-constraint/settings.toml +++ b/docs/tutorial-code/min-max-timeslice-constraints/2-max-constraint/settings.toml @@ -41,7 +41,7 @@ commodities_out = '{path}/technodata/residential/CommOut.csv' [sectors.residential.subsectors.all] agents = '{path}/technodata/Agents.csv' existing_capacity = '{path}/technodata/residential/ExistingCapacity.csv' -lpsolver = "scipy" # Optional, defaults to "adhoc" +lpsolver = "scipy" # Optional, defaults to "scipy" constraints = [ # Optional, defaults to the constraints below "max_production", diff --git a/docs/tutorial-code/modify-timing-data/1-modify-timeslices/settings.toml b/docs/tutorial-code/modify-timing-data/1-modify-timeslices/settings.toml index ebee78bfb..679f3c266 100644 --- a/docs/tutorial-code/modify-timing-data/1-modify-timeslices/settings.toml +++ b/docs/tutorial-code/modify-timing-data/1-modify-timeslices/settings.toml @@ -41,7 +41,7 @@ commodities_out = '{path}/technodata/residential/CommOut.csv' [sectors.residential.subsectors.all] agents = '{path}/technodata/Agents.csv' existing_capacity = '{path}/technodata/residential/ExistingCapacity.csv' -lpsolver = "scipy" # Optional, defaults to "adhoc" +lpsolver = "scipy" # Optional, defaults to "scipy" constraints = [ # Optional, defaults to the constraints below "max_production", diff --git a/docs/tutorial-code/modify-timing-data/2-modify-time-framework/settings.toml b/docs/tutorial-code/modify-timing-data/2-modify-time-framework/settings.toml index fc03a7ced..4a264e54d 100644 --- a/docs/tutorial-code/modify-timing-data/2-modify-time-framework/settings.toml +++ b/docs/tutorial-code/modify-timing-data/2-modify-time-framework/settings.toml @@ -41,7 +41,7 @@ commodities_out = '{path}/technodata/residential/CommOut.csv' [sectors.residential.subsectors.all] agents = '{path}/technodata/Agents.csv' existing_capacity = '{path}/technodata/residential/ExistingCapacity.csv' -lpsolver = "scipy" # Optional, defaults to "adhoc" +lpsolver = "scipy" # Optional, defaults to "scipy" constraints = [ # Optional, defaults to the constraints below "max_production", diff --git a/docs/tutorial-code/new-decision-metric/settings.toml b/docs/tutorial-code/new-decision-metric/settings.toml index 90694b9e0..12d7ad113 100644 --- a/docs/tutorial-code/new-decision-metric/settings.toml +++ b/docs/tutorial-code/new-decision-metric/settings.toml @@ -41,7 +41,7 @@ commodities_out = '{path}/technodata/residential/CommOut.csv' [sectors.residential.subsectors.all] agents = '{path}/technodata/Agents.csv' existing_capacity = '{path}/technodata/residential/ExistingCapacity.csv' -lpsolver = "scipy" # Optional, defaults to "adhoc" +lpsolver = "scipy" # Optional, defaults to "scipy" constraints = [ # Optional, defaults to the constraints below "max_production", diff --git a/src/muse/agents/factories.py b/src/muse/agents/factories.py index f912ecd1e..2630970dd 100644 --- a/src/muse/agents/factories.py +++ b/src/muse/agents/factories.py @@ -303,7 +303,7 @@ def _standardize_inputs( def _standardize_investing_inputs( search_rules: Optional[Union[str, Sequence[str]]] = None, - investment: Union[Callable, str, Mapping] = "adhoc", + investment: Union[Callable, str, Mapping] = "scipy", constraints: Optional[ Union[Callable, str, Mapping, Sequence[Union[str, Mapping]]] ] = None, diff --git a/src/muse/data/example/default/settings.toml b/src/muse/data/example/default/settings.toml index 981977384..8c508b8cd 100644 --- a/src/muse/data/example/default/settings.toml +++ b/src/muse/data/example/default/settings.toml @@ -41,7 +41,7 @@ commodities_out = '{path}/technodata/residential/CommOut.csv' [sectors.residential.subsectors.all] agents = '{path}/technodata/Agents.csv' existing_capacity = '{path}/technodata/residential/ExistingCapacity.csv' -lpsolver = "scipy" # Optional, defaults to "adhoc" +lpsolver = "scipy" # Optional, defaults to "scipy" constraints = [ # Optional, defaults to the constraints below "max_production", diff --git a/src/muse/data/example/default_retro/settings.toml b/src/muse/data/example/default_retro/settings.toml index 900a1469e..4c9cae789 100644 --- a/src/muse/data/example/default_retro/settings.toml +++ b/src/muse/data/example/default_retro/settings.toml @@ -41,7 +41,7 @@ commodities_out = '{path}/technodata/residential/CommOut.csv' [sectors.residential.subsectors.retro_and_new] agents = '{path}/technodata/Agents.csv' existing_capacity = '{path}/technodata/residential/ExistingCapacity.csv' -lpsolver = "scipy" # Optional, defaults to "adhoc" +lpsolver = "scipy" # Optional, defaults to "scipy" constraints = [ # Optional, defaults to the constraints below "max_production", diff --git a/src/muse/data/example/default_timeslice/settings.toml b/src/muse/data/example/default_timeslice/settings.toml index c566622c6..05130bfd0 100644 --- a/src/muse/data/example/default_timeslice/settings.toml +++ b/src/muse/data/example/default_timeslice/settings.toml @@ -41,7 +41,7 @@ commodities_out = '{path}/technodata/residential/CommOut.csv' [sectors.residential.subsectors.all] agents = '{path}/technodata/Agents.csv' existing_capacity = '{path}/technodata/residential/ExistingCapacity.csv' -lpsolver = "scipy" # Optional, defaults to "adhoc" +lpsolver = "scipy" # Optional, defaults to "scipy" constraints = [ # Optional, defaults to the constraints below "max_production", diff --git a/src/muse/sectors/subsector.py b/src/muse/sectors/subsector.py index 381a49b2f..b816a171a 100644 --- a/src/muse/sectors/subsector.py +++ b/src/muse/sectors/subsector.py @@ -147,7 +147,7 @@ def factory( year=current_year or int(technologies.year.min()), asset_threshold=getattr(settings, "asset_threshold", 1e-12), # only used by self-investing agents - investment=getattr(settings, "lpsolver", "adhoc"), + investment=getattr(settings, "lpsolver", "scipy"), forecast=getattr(settings, "forecast", 5), constraints=getattr(settings, "constraints", ()), timeslice_level=timeslice_level, From 4923636a77b205cb1757526532101a5045d8387e Mon Sep 17 00:00:00 2001 From: Tom Bland Date: Fri, 29 Nov 2024 15:33:21 +0000 Subject: [PATCH 2/4] Add warning if lpsolver is not specified --- src/muse/sectors/subsector.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/muse/sectors/subsector.py b/src/muse/sectors/subsector.py index b816a171a..dc75222c7 100644 --- a/src/muse/sectors/subsector.py +++ b/src/muse/sectors/subsector.py @@ -127,6 +127,8 @@ def factory( name: str = "subsector", timeslice_level: str | None = None, ) -> Subsector: + from logging import getLogger + from muse import constraints as cs from muse import demand_share as ds from muse import investments as iv @@ -139,6 +141,13 @@ def factory( msg = "Invalid parameter asset_threshhold. Did you mean asset_threshold?" raise ValueError(msg) + # Raise warning if lpsolver is not specified (PR #587) + if not hasattr(settings, "lpsolver"): + msg = ( + f"lpsolver not specified for subsector '{name}'. Defaulting to 'scipy'" + ) + getLogger(__name__).warning(msg) + agents = agents_factory( settings.agents, settings.existing_capacity, From 4ffc9502503335bc684843b86ded3793674a9f26 Mon Sep 17 00:00:00 2001 From: Tom Bland Date: Fri, 29 Nov 2024 15:50:35 +0000 Subject: [PATCH 3/4] Fix failing test --- tests/conftest.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/conftest.py b/tests/conftest.py index 95b9b6753..bef2e1442 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -362,6 +362,7 @@ def newcapa_agent(agent_args, technologies, stock) -> Agent: @fixture def retro_agent(agent_args, technologies, stock) -> Agent: + agent_args["investment"] = "adhoc" # fails with scipy solver, see # 587 return create_agent(agent_args, technologies, stock.capacity, "retrofit") From b9456f89b975bfee9e88be326ba25cf2967ccec8 Mon Sep 17 00:00:00 2001 From: Tom Bland Date: Tue, 3 Dec 2024 10:53:37 +0000 Subject: [PATCH 4/4] Clearer documentation about default solver --- docs/inputs/toml.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/inputs/toml.rst b/docs/inputs/toml.rst index c1909a419..66241f1e2 100644 --- a/docs/inputs/toml.rst +++ b/docs/inputs/toml.rst @@ -442,7 +442,7 @@ Sectors contain a number of subsections: are registered via :py:func:`~muse.investments.register_investment`. At time of writing, three are available: - - "scipy" solver (default): Formulates investment as a true LP problem and solves it using + - "scipy" solver (default from v1.3): Formulates investment as a true LP problem and solves it using the `scipy solver`_. - an "adhoc" solver: Simple in-house solver that ranks the technologies