diff --git a/.github/workflows/commit-ci.yml b/.github/workflows/commit-ci.yml index 9840173d9..ebcf4beed 100644 --- a/.github/workflows/commit-ci.yml +++ b/.github/workflows/commit-ci.yml @@ -11,6 +11,7 @@ on: - CITATION - AUTHORS - doc/** + - .readthedocs.yml defaults: run: diff --git a/.github/workflows/pr-ci.yml b/.github/workflows/pr-ci.yml index 9f59cbe4d..da9961784 100644 --- a/.github/workflows/pr-ci.yml +++ b/.github/workflows/pr-ci.yml @@ -11,6 +11,7 @@ on: - CITATION - AUTHORS - doc/** + - .readthedocs.yml defaults: run: diff --git a/.readthedocs.yml b/.readthedocs.yml index 909c2c81b..406b61077 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,5 +1,4 @@ version: 2 # required -formats: [pdf] conda: environment: requirements/docs.yml build: diff --git a/README.md b/README.md index 5f09c120c..61b3e03ad 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -[![Chat on Gitter](https://img.shields.io/gitter/room/calliope-project/calliope.svg?style=flat-square)](https://app.gitter.im/#/room/#calliope-project_calliope:gitter.im) +[![Chat on Gitter](https://img.shields.io/gitter/room/calliope-project/calliope.svg)](https://app.gitter.im/#/room/#calliope-project_calliope:gitter.im) [![Main branch build status](https://github.com/calliope-project/calliope/actions/workflows/commit-ci.yml/badge.svg?branch=main)](https://github.com/calliope-project/calliope/actions/workflows/commit-ci.yml) -[![Documentation build status](https://img.shields.io/readthedocs/calliope.svg?style=flat-square)](https://readthedocs.org/projects/calliope/builds/) +[![Documentation build status](https://img.shields.io/readthedocs/calliope.svg?version=latest)](https://readthedocs.org/projects/calliope/builds/) [![Test coverage](https://codecov.io/gh/calliope-project/calliope/graph/badge.svg?token=UM542yaYrh)](https://codecov.io/gh/calliope-project/calliope) -[![PyPI version](https://img.shields.io/pypi/v/calliope.svg?style=flat-square)](https://pypi.python.org/pypi/calliope) -[![Anaconda.org/conda-forge version](https://img.shields.io/conda/vn/conda-forge/calliope.svg?style=flat-square&label=conda)](https://anaconda.org/conda-forge/calliope) -[![JOSS DOI](https://img.shields.io/badge/JOSS-10.21105/joss.00825-green.svg?style=flat-square)](https://doi.org/10.21105/joss.00825) +[![PyPI version](https://img.shields.io/pypi/v/calliope.svg)](https://pypi.python.org/pypi/calliope) +[![Anaconda.org/conda-forge version](https://img.shields.io/conda/vn/conda-forge/calliope.svg?label=conda)](https://anaconda.org/conda-forge/calliope) +[![JOSS DOI](https://img.shields.io/badge/JOSS-10.21105/joss.00825-green.svg)](https://doi.org/10.21105/joss.00825) --- @@ -49,10 +49,7 @@ More fully-featured examples that have been used in peer-reviewed scientific pub ## Documentation -Documentation is available on Read the Docs: - -- [Read the documentation online (recommended)](https://calliope.readthedocs.io/en/stable/) -- [Download all documentation in a single PDF file](https://readthedocs.org/projects/calliope/downloads/pdf/stable/) +Documentation is available on [Read the Docs](https://calliope.readthedocs.io/en/stable/). ## Contributing diff --git a/doc/_static/custom_math/annual_energy_balance.yaml b/doc/_static/custom_math/annual_energy_balance.yaml index 6001dd0d8..e1641f87f 100644 --- a/doc/_static/custom_math/annual_energy_balance.yaml +++ b/doc/_static/custom_math/annual_energy_balance.yaml @@ -5,8 +5,12 @@ # annual_source_max # New top-level parameters: -# annual_flow_max (if grouping technologies and/or nodes) -# flow_max_group (if grouping technologies and/or nodes) +# annual_flow_max (if summing over technologies and/or nodes) +# flow_max_group (if summing over technologies and/or nodes) + +# helper functions used: +# inheritance (where) +# sum (expression) constraints: annual_energy_balance_per_tech_and_node: diff --git a/doc/_static/custom_math/chp_htp.yaml b/doc/_static/custom_math/chp_htp.yaml index 2e307d952..ef64b7a71 100644 --- a/doc/_static/custom_math/chp_htp.yaml +++ b/doc/_static/custom_math/chp_htp.yaml @@ -65,6 +65,9 @@ # power_to_heat_ratio # boiler_eff +# helper functions used: +# reduce_carrier_dim (expression) + constraints: # Extraction turbine constraints # ~~ diff --git a/doc/_static/custom_math/demand_share_per_timestep_decision.yaml b/doc/_static/custom_math/demand_share_per_timestep_decision.yaml index 26ea25304..57fee2a3a 100644 --- a/doc/_static/custom_math/demand_share_per_timestep_decision.yaml +++ b/doc/_static/custom_math/demand_share_per_timestep_decision.yaml @@ -8,8 +8,13 @@ # Specifying `relaxation` inside the constraint to a non-zero value allows the constraint some flexibility around a given value, making a model easier to solve. # New top-level parameters: -# relaxation (defined here directly) -# total share limit (defined here directly) +# relaxation (defined here directly). +# demand_share_limit. +# decide_demand_share <- Link supply technologies to the demand technology they are going to be a share of. + +# helper functions used: +# sum (expression) +# select_from_lookup_arrays (expression) variables: demand_share_per_timestep_decision: diff --git a/doc/_static/custom_math/fuel_dist.yaml b/doc/_static/custom_math/fuel_dist.yaml index 889f405ca..786e275ed 100644 --- a/doc/_static/custom_math/fuel_dist.yaml +++ b/doc/_static/custom_math/fuel_dist.yaml @@ -8,6 +8,11 @@ # fuel_export_max # fuel_distribution_max # fuel_distributor_costs +# allow_fuel_distribution <- lookup array with a value of `True` for each carrier where you want to track its distribution + +# helper functions used: +# any (where) +# sum (expression) variables: fuel_distributor: diff --git a/doc/_static/custom_math/max_time_varying.yaml b/doc/_static/custom_math/max_time_varying.yaml index 93d9b0b6a..f39650249 100644 --- a/doc/_static/custom_math/max_time_varying.yaml +++ b/doc/_static/custom_math/max_time_varying.yaml @@ -7,6 +7,9 @@ # flow_cap_max_relative_per_ts # storage_max_relative_per_ts +# helper functions used: +# reduce_carrier_dim (expression) + constraints: max_time_varying_flow_cap: description: Limit flow out in each hour according to a time varying fractional limit that is multiplied by the technology flow cap. This represents, for instance, the impact of outdoor temperature on the maximum output of a technology relative to its rated max output. diff --git a/doc/_static/custom_math/net_import_share.yaml b/doc/_static/custom_math/net_import_share.yaml new file mode 100644 index 000000000..8c103ee42 --- /dev/null +++ b/doc/_static/custom_math/net_import_share.yaml @@ -0,0 +1,53 @@ +# Force upper limit on carrier imports within nodes or across all nodes as a share of all carrier flows at a node/across nodes. +# Imports of transmission technologies are defined by `flow_out` (outflow from a transmission technology that originated in a remote node). +# We assume that transmission technologies `test_transmission_elec` and `test_transmission_heat` have been defined. + +# New top-level parameters: +# net_import_share + +# helper functions used: +# defined (where) +# sum (expression) +# get_transmission_techs (expression) + +constraints: + net_import_share_max: + description: Limit upper bound on electricity imports within nodes as a share of all electricity flows at each node. + foreach: [nodes, timesteps] + where: "defined(techs=test_transmission_elec, within=nodes, how=any)" + equations: + - expression: net_import_share * sum(flow_out[techs=$transmission_techs, carriers=electricity], over=techs) <= $total_energy_balance + sub_expressions: + total_energy_balance: + - expression: sum(flow_out[carriers=electricity], over=techs) - sum(flow_in[carriers=electricity], over=techs) + slices: + transmission_techs: + - expression: get_transmission_techs(test_transmission_elec) + + net_annual_import_share_max: + description: Limit upper bound on annual electricity imports within nodes as a share of all electricity flows at each node. + foreach: [nodes] + where: "defined(techs=test_transmission_elec, within=nodes, how=any)" + equations: + - expression: net_import_share * sum(flow_out[techs=$transmission_techs, carriers=electricity], over=[techs, timesteps]) <= $total_energy_balance + sub_expressions: + total_energy_balance: + - expression: sum(flow_out[carriers=electricity], over=[techs, timesteps]) - sum(flow_in[carriers=electricity], over=[techs, timesteps]) + slices: + transmission_techs: + - expression: get_transmission_techs(test_transmission_elec) + + net_annual_import_share_max_node_group: + description: Limit upper bound on annual heat imports across a subset of nodes in the model as a share of combined heat flows in those nodes. + equations: + - expression: net_import_share * sum(flow_out[techs=$transmission_techs, nodes=$node_group, carriers=$carrier], over=[nodes, techs, timesteps]) <= $total_energy_balance + sub_expressions: + total_energy_balance: + - expression: sum(flow_out[nodes=$node_group, carriers=$carrier], over=[nodes, techs, timesteps]) - sum(flow_in[nodes=$node_group, carriers=$carrier], over=[nodes, techs, timesteps]) + slices: + transmission_techs: + - expression: get_transmission_techs(test_transmission_heat) + node_group: # The subset of nodes in which to limit heat imports + - expression: "[a, c]" + carrier: # The carrier for which to limit imports + - expression: heat \ No newline at end of file diff --git a/doc/_static/custom_math/piecewise_linear_efficiency.yaml b/doc/_static/custom_math/piecewise_linear_efficiency.yaml index 1102ae210..3d2403100 100644 --- a/doc/_static/custom_math/piecewise_linear_efficiency.yaml +++ b/doc/_static/custom_math/piecewise_linear_efficiency.yaml @@ -6,6 +6,9 @@ # flow_eff_piecewise_slopes (defining the new parameter `pieces`) # flow_eff_piecewise_intercept (defining the new parameter `pieces`) +# helper functions used: +# reduce_carrier_dim (expression) + variables: available_flow_cap: description: Flow capacity that will be set to zero if the technology is not operating in a given timestep and will be set to the value of the decision variable `flow_cap` otherwise. diff --git a/doc/_static/custom_math/share_all_timesteps.yaml b/doc/_static/custom_math/share_all_timesteps.yaml index 007b7b815..a56e9c314 100644 --- a/doc/_static/custom_math/share_all_timesteps.yaml +++ b/doc/_static/custom_math/share_all_timesteps.yaml @@ -7,6 +7,10 @@ # demand_share_equals # supply_share_equals +# helper functions used: +# sum (expression) +# reduce_carrier_dim (expression) + constraints: demand_share_equals_per_tech: description: Set the total outflow of certain technologies which produce the `power` carrier to a share of total demand inflow. diff --git a/doc/_static/custom_math/share_per_timestep.yaml b/doc/_static/custom_math/share_per_timestep.yaml index 1b9cb5e6c..85766798a 100644 --- a/doc/_static/custom_math/share_per_timestep.yaml +++ b/doc/_static/custom_math/share_per_timestep.yaml @@ -7,6 +7,10 @@ # demand_share_per_timestep_equals # supply_share_per_timestep_equals +# helper functions used: +# sum (expression) +# reduce_carrier_dim (expression) + constraints: demand_share_per_timestep_equals_per_tech: description: Set the per-timestep outflow of certain technologies which produce the `power` carrier to a share of demand inflow. diff --git a/doc/_static/custom_math/uptime_downtime_limits.yaml b/doc/_static/custom_math/uptime_downtime_limits.yaml index d8b1b4933..a3f2f6189 100644 --- a/doc/_static/custom_math/uptime_downtime_limits.yaml +++ b/doc/_static/custom_math/uptime_downtime_limits.yaml @@ -12,6 +12,10 @@ # downtime_periods (from CSV as a timeseries) # uptime_limit +# helper functions used: +# sum (expression) +# reduce_carrier_dim (expression) + constraints: annual_capacity_factor_min: description: Limit the lower bound of annual technology operation as a fraction of annual operation at maximum capacity. diff --git a/doc/_static/notebooks/national_scale.ipynb b/doc/_static/notebooks/national_scale.ipynb index ea0d464f3..57297e42c 100644 --- a/doc/_static/notebooks/national_scale.ipynb +++ b/doc/_static/notebooks/national_scale.ipynb @@ -418,12 +418,12 @@ " * costs (costs) object 'monetary'\n", " * loc_carriers (loc_carriers) object 'region1::power' .....\n", " * loc_techs (loc_techs) object 'region1::free_transmi...\n", - " * loc_techs_area (loc_techs_area) object 'region1-3::csp' ...\n", + " * loc_techs_area (loc_techs_area) object 'region1_3::csp' ...\n", " ... ...\n", - " * loc_techs_store (loc_techs_store) object 'region1-3::csp'...\n", - " * loc_techs_supply_plus (loc_techs_supply_plus) object 'region1-3...\n", + " * loc_techs_store (loc_techs_store) object 'region1_3::csp'...\n", + " * loc_techs_supply_plus (loc_techs_supply_plus) object 'region1_3...\n", " * loc_techs_transmission (loc_techs_transmission) object 'region1:...\n", - " * locs (locs) object 'region2' ... 'region1-3'\n", + " * locs (locs) object 'region2' ... 'region1_3'\n", " * techs (techs) object 'ac_transmission' ... 'csp'\n", " * timesteps (timesteps) datetime64[ns] 2005-01-01 ......\n", "Data variables: (12/34)\n", @@ -436,7 +436,7 @@ " ... ...\n", " lookup_loc_carriers (loc_carriers) object 'region1::free_tran...\n", " lookup_loc_techs (loc_techs_non_conversion) object 'region...\n", - " lookup_loc_techs_area (locs) object '' ... 'region1-3::csp'\n", + " lookup_loc_techs_area (locs) object '' ... 'region1_3::csp'\n", " timestep_resolution (timesteps) float64 1.0 1.0 1.0 ... 1.0 1.0\n", " timestep_weights (timesteps) float64 1.0 1.0 1.0 ... 1.0 1.0\n", " max_demand_timesteps (carriers) datetime64[ns] 2005-01-05T16:0...\n", @@ -445,42 +445,42 @@ " applied_overrides: \n", " scenario: None\n", " defaults: carrier_ratios:\\ncharge_rate:\\nenergy_cap_per_storag...\n", - " allow_operate_mode: 1