Repository: calliope-project/calliope (language: python)

Issue:
Update top level config
Fixes issue #452 

Possible TODO: allow init kwargs to be passed to the built-in example models on their initialisation (e.g., `calliope.examples.national_scale(override_dict={"config.init.subset_time": ...})` -> `calliope.examples.national_scale(subset_time=...)`)

TODO: add top-level parameter tests.

Summary of changes in this pull request:

* `run` and `model` config split into `init`/`build`/`solve` config keys with a flat dict layout in each.
*  parameters moved out of config into a top-level parameters key with a syntax discussed in #452 and in a number of discussions.

Reviewer checklist:

- [ ] Test(s) added to cover contribution
- [ ] Documentation updated
- [ ] Changelog updated
- [ ] Coverage maintained or improved
Separate top-level config and parameters 
## Problem description

`run` and `model` configs mix up configuration and parameters. We want to be able to pipe these parameters to the Calliope model dataset and then onto the backend. We handle that at the moment with hardcoding which are parameters in the core code, which isn't ideal. An idea on how to change these YAML structures:

```yaml
config:
  init:
    name: null
    calliope_version: null
    random_seed: null
    subset_time: null
    time: {}
    timeseries_data_path: null 
    timeseries_data: null 
    timeseries_dateformat: "%Y-%m-%d %H:%M:%S"
  build:
    custom_math: []
    backend: pyomo
    cyclic_storage: true
    ensure_feasibility: false
    mode: plan
  solve: 
    operate_window: null
    operate_horizon: null
    operate_use_cap_results: false
    spores_number: 3
    spores_score_cost_class: spores_score
    spores_slack_cost_group: null
    spores_save_per_spore: false
    spores_save_per_spore_path: null
    spores_skip_cost_op: false
    save_logs: null
    solver_io: null
    solver_options: null
    solver: cbc
    zero_threshold: 1e-10

parameters:
  reserve_margin: {electricity: 0.1}
  bigM: 1e9
  objective_cost_class: {"costs": {"monetary": 1, "emissions": 0.1}}
  my_param: {("costs", "carriers"): {("monetary", "electricity"): 1, ("monetary", "heat"): 0.1}}
  spores_slack: 0.1
  spores_objective_cost_class: {"costs": {spores_score: 1, monetary: 0} }
```

Other things:
- `file_allowed` is deprecated.
- All config items could become arguments in the relevant methods (`init` in `calliope.Model`)/(`build` in `calliope.Model.build`)/(`solve` in `calliope.Model.solve`).
- ^ config items then have to be flattened so they can be used by args.
- parameters can be dimensionless or have dimensions in a dict form (for non-tech/node/tech+node dims). This is very simplified and wouldn't work well for large parameters. That's ok because we would solve it in the long (hopefully medium) term with #92. 
- Users can then add their own top-level parameters to 'parameters' for use in their custom constraints.

## Calliope version

v0.7.0-dev

Separate top-level config and parameters 
## Problem description

`run` and `model` configs mix up configuration and parameters. We want to be able to pipe these parameters to the Calliope model dataset and then onto the backend. We handle that at the moment with hardcoding which are parameters in the core code, which isn't ideal. An idea on how to change these YAML structures:

```yaml
config:
  init:
    name: null
    calliope_version: null
    random_seed: null
    subset_time: null
    time: {}
    timeseries_data_path: null 
    timeseries_data: null 
    timeseries_dateformat: "%Y-%m-%d %H:%M:%S"
  build:
    custom_math: []
    backend: pyomo
    cyclic_storage: true
    ensure_feasibility: false
    mode: plan
  solve: 
    operate_window: null
    operate_horizon: null
    operate_use_cap_results: false
    spores_number: 3
    spores_score_cost_class: spores_score
    spores_slack_cost_group: null
    spores_save_per_spore: false
    spores_save_per_spore_path: null
    spores_skip_cost_op: false
    save_logs: null
    solver_io: null
    solver_options: null
    solver: cbc
    zero_threshold: 1e-10

parameters:
  reserve_margin: {electricity: 0.1}
  bigM: 1e9
  objective_cost_class: {"costs": {"monetary": 1, "emissions": 0.1}}
  my_param: {("costs", "carriers"): {("monetary", "electricity"): 1, ("monetary", "heat"): 0.1}}
  spores_slack: 0.1
  spores_objective_cost_class: {"costs": {spores_score: 1, monetary: 0} }
```

Other things:
- `file_allowed` is deprecated.
- All config items could become arguments in the relevant methods (`init` in `calliope.Model`)/(`build` in `calliope.Model.build`)/(`solve` in `calliope.Model.solve`).
- ^ config items then have to be flattened so they can be used by args.
- parameters can be dimensionless or have dimensions in a dict form (for non-tech/node/tech+node dims). This is very simplified and wouldn't work well for large parameters. That's ok because we would solve it in the long (hopefully medium) term with #92. 
- Users can then add their own top-level parameters to 'parameters' for use in their custom constraints.

## Calliope version

v0.7.0-dev



Discussion / hints:

Fix patch:
diff --git a/doc/_static/math.rst b/doc/_static/math.rst
index 3da29fe68..5b38efe04 100644
--- a/doc/_static/math.rst
+++ b/doc/_static/math.rst
@@ -5,7 +5,7 @@ Objective
 minmax_cost_optimisation
 ^^^^^^^^^^^^^^^^^^^^^^^^
 
-Minimise the total cost of installing and operation all technologies in the system. If multiple cost classes are present (e.g., monetary and co2 emissions), the weighted sum of total costs is minimised. Cost class weights can be defined in `run.objective_options.cost_class`.
+Minimise the total cost of installing and operation all technologies in the system. If multiple cost classes are present (e.g., monetary and co2 emissions), the weighted sum of total costs is minimised. Cost class weights can be defined in the top-level parameter `objective_cost_class`.
 
 .. container:: scrolling-wrapper
 
@@ -15,20 +15,26 @@ Minimise the total cost of installing and operation all technologies in the syst
         \end{array}
         \begin{cases}
             \sum\limits_{\text{cost} \in \text{costs}} (\sum\limits_{\substack{\text{node} \in \text{nodes} \\ \text{tech} \in \text{techs}}} (\textbf{cost}_\text{node,tech,cost}) \times \textit{objective_cost_class}_\text{cost}) + \sum\limits_{\text{timestep} \in \text{timesteps}} (\sum\limits_{\substack{\text{carrier} \in \text{carriers} \\ \text{node} \in \text{nodes}}} (\textbf{unmet_demand}_\text{node,carrier,timestep} - \textbf{unused_supply}_\text{node,carrier,timestep}) \times \textit{timestep_weights}_\text{timestep}) \times \textit{bigM}&\quad
-            \text{if } (\text{run_config.ensure_feasibility}\mathord{=}\text{true})
+            \text{if } (\bigvee\limits_{\substack{\text{node} \in \text{nodes} \\ \text{tech} \in \text{techs} \\ \text{cost} \in \text{costs}}} (cost))\land{}(\text{config.ensure_feasibility}\mathord{=}\text{true})
             \\
             \sum\limits_{\text{cost} \in \text{costs}} (\sum\limits_{\substack{\text{node} \in \text{nodes} \\ \text{tech} \in \text{techs}}} (\textbf{cost}_\text{node,tech,cost}) \times \textit{objective_cost_class}_\text{cost})&\quad
-            \text{if } (\neg (\text{run_config.ensure_feasibility}\mathord{=}\text{true}))
+            \text{if } (\bigvee\limits_{\substack{\text{node} \in \text{nodes} \\ \text{tech} \in \text{techs} \\ \text{cost} \in \text{costs}}} (cost))\land{}(\neg (\text{config.ensure_feasibility}\mathord{=}\text{true}))
+            \\
+            \sum\limits_{\text{timestep} \in \text{timesteps}} (\sum\limits_{\substack{\text{carrier} \in \text{carriers} \\ \text{node} \in \text{nodes}}} (\textbf{unmet_demand}_\text{node,carrier,timestep} - \textbf{unused_supply}_\text{node,carrier,timestep}) \times \textit{timestep_weights}_\text{timestep}) \times \textit{bigM}&\quad
+            \text{if } (\neg (\bigvee\limits_{\substack{\text{node} \in \text{nodes} \\ \text{tech} \in \text{techs} \\ \text{cost} \in \text{costs}}} (cost)))\land{}(\text{config.ensure_feasibility}\mathord{=}\text{true})
+            \\
+            0&\quad
+            \text{if } (\neg (\bigvee\limits_{\substack{\text{node} \in \text{nodes} \\ \text{tech} \in \text{techs} \\ \text{cost} \in \text{costs}}} (cost)))\land{}(\neg (\text{config.ensure_feasibility}\mathord{=}\text{true}))
             \\
         \end{cases}
 
 Subject to
 ----------
 
-energy_capacity_per_storage_capacity_min
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+flow_capacity_per_storage_capacity_min
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Set the lower bound of a `storage`/`supply_plus` technology's energy capacity relative to its storage capacity.
+Set the lower bound of a `storage`/`supply_plus` technology's flow capacity relative to its storage capacity.
 
 .. container:: scrolling-wrapper
 
@@ -38,17 +44,17 @@ Set the lower bound of a `storage`/`supply_plus` technology's energy capacity re
             \text{ node }\negthickspace \in \negthickspace\text{ nodes, }
             \text{ tech }\negthickspace \in \negthickspace\text{ techs }
             \\
-            \text{if } (\exists (\textbf{storage_cap}_\text{node,tech}) \land \exists (\textit{energy_cap_per_storage_cap_min}_\text{node,tech}) \land \neg (\exists (\textit{energy_cap_per_storage_cap_equals}_\text{node,tech})))
+            \text{if } (\exists (\textbf{storage_cap}_\text{node,tech}) \land \exists (\textit{flow_cap_per_storage_cap_min}_\text{node,tech}))
         \end{array}
         \begin{cases}
-            \textbf{energy_cap}_\text{node,tech} \geq \textbf{storage_cap}_\text{node,tech} \times \textit{energy_cap_per_storage_cap_min}_\text{node,tech}&\quad
+            \textbf{flow_cap}_\text{node,tech} \geq \textbf{storage_cap}_\text{node,tech} \times \textit{flow_cap_per_storage_cap_min}_\text{node,tech}&\quad
             \\
         \end{cases}
 
-energy_capacity_per_storage_capacity_max
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+flow_capacity_per_storage_capacity_max
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Set the upper bound of a `storage`/`supply_plus` technology's energy capacity relative to its storage capacity.
+Set the upper bound of a `storage`/`supply_plus` technology's flow capacity relative to its storage capacity.
 
 .. container:: scrolling-wrapper
 
@@ -58,17 +64,17 @@ Set the upper bound of a `storage`/`supply_plus` technology's energy capacity re
             \text{ node }\negthickspace \in \negthickspace\text{ nodes, }
             \text{ tech }\negthickspace \in \negthickspace\text{ techs }
             \\
-            \text{if } (\exists (\textbf{storage_cap}_\text{node,tech}) \land \exists (\textit{energy_cap_per_storage_cap_max}_\text{node,tech}) \land \neg (\exists (\textit{energy_cap_per_storage_cap_equals}_\text{node,tech})))
+            \text{if } (\exists (\textbf{storage_cap}_\text{node,tech}) \land \exists (\textit{flow_cap_per_storage_cap_max}_\text{node,tech}))
         \end{array}
         \begin{cases}
-            \textbf{energy_cap}_\text{node,tech} \leq \textbf{storage_cap}_\text{node,tech} \times \textit{energy_cap_per_storage_cap_max}_\text{node,tech}&\quad
+            \textbf{flow_cap}_\text{node,tech} \leq \textbf{storage_cap}_\text{node,tech} \times \textit{flow_cap_per_storage_cap_max}_\text{node,tech}&\quad
             \\
         \end{cases}
 
-energy_capacity_per_storage_capacity_equals
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+source_capacity_equals_flow_capacity
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Set a fixed relationship between a `storage`/`supply_plus` technology's energy capacity and its storage capacity.
+Set a `supply_plus` technology's flow capacity to equal its source capacity.
 
 .. container:: scrolling-wrapper
 
@@ -78,17 +84,17 @@ Set a fixed relationship between a `storage`/`supply_plus` technology's energy c
             \text{ node }\negthickspace \in \negthickspace\text{ nodes, }
             \text{ tech }\negthickspace \in \negthickspace\text{ techs }
             \\
-            \text{if } (\exists (\textbf{storage_cap}_\text{node,tech}) \land \exists (\textit{energy_cap_per_storage_cap_equals}_\text{node,tech}))
+            \text{if } (\exists (\textbf{source_cap}_\text{node,tech}) \land \textit{source_cap_equals_flow_cap}_\text{node,tech}\mathord{=}\text{true})
         \end{array}
         \begin{cases}
-            \textbf{energy_cap}_\text{node,tech} = \textbf{storage_cap}_\text{node,tech} \times \textit{energy_cap_per_storage_cap_equals}_\text{node,tech}&\quad
+            \textbf{source_cap}_\text{node,tech} = \textbf{flow_cap}_\text{node,tech}&\quad
             \\
         \end{cases}
 
-resource_capacity_equals_energy_capacity
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+force_zero_area_use
+^^^^^^^^^^^^^^^^^^^
 
-Set a `supply_plus` technology's energy capacity to equal its resource capacity.
+Set a technology's area use to zero if its flow capacity upper bound is zero.
 
 .. container:: scrolling-wrapper
 
@@ -98,17 +104,17 @@ Set a `supply_plus` technology's energy capacity to equal its resource capacity.
             \text{ node }\negthickspace \in \negthickspace\text{ nodes, }
             \text{ tech }\negthickspace \in \negthickspace\text{ techs }
             \\
-            \text{if } (\exists (\textbf{resource_cap}_\text{node,tech}) \land \textit{resource_cap_equals_energy_cap}_\text{node,tech}\mathord{=}\text{true})
+            \text{if } (\exists (\textbf{area_use}_\text{node,tech}) \land \textit{flow_cap_max}_\text{node,tech}\mathord{=}\text{0})
         \end{array}
         \begin{cases}
-            \textbf{resource_cap}_\text{node,tech} = \textbf{energy_cap}_\text{node,tech}&\quad
+            \textbf{area_use}_\text{node,tech} = 0&\quad
             \\
         \end{cases}
 
-force_zero_resource_area
-^^^^^^^^^^^^^^^^^^^^^^^^
+area_use_per_flow_capacity
+^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Set a technology's resource area to zero if its energy capacity upper bound is zero.
+Set a fixed relationship between a technology's flow capacity and its area use.
 
 .. container:: scrolling-wrapper
 
@@ -118,56 +124,55 @@ Set a technology's resource area to zero if its energy capacity upper bound is z
             \text{ node }\negthickspace \in \negthickspace\text{ nodes, }
             \text{ tech }\negthickspace \in \negthickspace\text{ techs }
             \\
-            \text{if } (\exists (\textbf{resource_area}_\text{node,tech}) \land \textit{energy_cap_max}_\text{node,tech}\mathord{=}\text{0})
+            \text{if } (\exists (\textbf{area_use}_\text{node,tech}) \land \exists (\textit{area_use_per_flow_cap}_\text{node,tech}))
         \end{array}
         \begin{cases}
-            \textbf{resource_area}_\text{node,tech} = 0&\quad
+            \textbf{area_use}_\text{node,tech} = \textbf{flow_cap}_\text{node,tech} \times \textit{area_use_per_flow_cap}_\text{node,tech}&\quad
             \\
         \end{cases}
 
-resource_area_per_energy_capacity
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+area_use_capacity_per_loc
+^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Set a fixed relationship between a technology's energy capacity and its resource area.
+Set an upper bound on the total area that all technologies with a area_use can occupy at a given node.
 
 .. container:: scrolling-wrapper
 
     .. math::
         \begin{array}{r}
             \forall{}
-            \text{ node }\negthickspace \in \negthickspace\text{ nodes, }
-            \text{ tech }\negthickspace \in \negthickspace\text{ techs }
+            \text{ node }\negthickspace \in \negthickspace\text{ nodes }
             \\
-            \text{if } (\exists (\textbf{resource_area}_\text{node,tech}) \land \exists (\textit{resource_area_per_energy_cap}_\text{node,tech}))
+            \text{if } (\exists (\textbf{area_use}_\text{node,tech}) \land \exists (\textit{available_area}_\text{node}))
         \end{array}
         \begin{cases}
-            \textbf{resource_area}_\text{node,tech} = \textbf{energy_cap}_\text{node,tech} \times \textit{resource_area_per_energy_cap}_\text{node,tech}&\quad
+            \sum\limits_{\text{tech} \in \text{techs}} (\textbf{area_use}_\text{node,tech}) \leq \textit{available_area}_\text{node}&\quad
             \\
         \end{cases}
 
-resource_area_capacity_per_loc
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+flow_capacity_systemwide_max
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Set an upper bound on the total area that all technologies with a resource_area can occupy at a given node.
+Set an upper bound on flow capacity of a technology across all nodes in which the technology exists.
 
 .. container:: scrolling-wrapper
 
     .. math::
         \begin{array}{r}
             \forall{}
-            \text{ node }\negthickspace \in \negthickspace\text{ nodes }
+            \text{ tech }\negthickspace \in \negthickspace\text{ techs }
             \\
-            \text{if } (\exists (\textbf{resource_area}_\text{node,tech}) \land \exists (\textit{available_area}_\text{node}))
+            \text{if } (\exists (\textit{flow_cap_max_systemwide}_\text{tech}))
         \end{array}
         \begin{cases}
-            \sum\limits_{\text{tech} \in \text{techs}} (\textbf{resource_area}_\text{node,tech}) \leq \textit{available_area}_\text{node}&\quad
+            \sum\limits_{\text{node} \in \text{nodes}} (\textbf{flow_cap}_\text{node,tech}) \leq \textit{flow_cap_max_systemwide}_\text{tech}&\quad
             \\
         \end{cases}
 
-energy_capacity_systemwide
-^^^^^^^^^^^^^^^^^^^^^^^^^^
+flow_capacity_systemwide_min
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Set an upper bound on, or a fixed total of, energy capacity of a technology across all nodes in which the technology exists.
+Set a lower bound on flow capacity of a technology across all nodes in which the technology exists.
 
 .. container:: scrolling-wrapper
 
@@ -176,21 +181,17 @@ Set an upper bound on, or a fixed total of, energy capacity of a technology acro
             \forall{}
             \text{ tech }\negthickspace \in \negthickspace\text{ techs }
             \\
-            \text{if } (\exists (\textit{energy_cap_equals_systemwide}_\text{tech}) \lor \exists (\textit{energy_cap_max_systemwide}_\text{tech}))
+            \text{if } (\exists (\textit{flow_cap_min_systemwide}_\text{tech}))
         \end{array}
         \begin{cases}
-            \sum\limits_{\text{node} \in \text{nodes}} (\textbf{energy_cap}_\text{node,tech}) = \textit{energy_cap_equals_systemwide}_\text{tech}&\quad
-            \text{if } (\exists (\textit{energy_cap_equals_systemwide}_\text{tech}))
-            \\
-            \sum\limits_{\text{node} \in \text{nodes}} (\textbf{energy_cap}_\text{node,tech}) \leq \textit{energy_cap_max_systemwide}_\text{tech}&\quad
-            \text{if } (\neg (\exists (\textit{energy_cap_equals_systemwide}_\text{tech})))
+            \sum\limits_{\text{node} \in \text{nodes}} (\textbf{flow_cap}_\text{node,tech}) \geq \textit{flow_cap_min_systemwide}_\text{tech}&\quad
             \\
         \end{cases}
 
 balance_conversion_plus_primary
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Fix the relationship between total carrier production and total carrier consumption of `conversion_plus` technologies for `in` (consumption) and `out` (production) carrier flows.
+Fix the relationship between total outflow and total inflow of `conversion_plus` technologies for `in` (consumption) and `out` (production) carrier flows.
 
 .. container:: scrolling-wrapper
 
@@ -201,17 +202,17 @@ Fix the relationship between total carrier production and total carrier consumpt
             \text{ tech }\negthickspace \in \negthickspace\text{ techs, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\text{tech_group=conversion_plus} \land \textit{carrier_ratios}_\text{node,tech,carrier_tier,carrier,timestep}\mathord{>}\text{0})
+            \text{if } (\text{tech_group=conversion_plus} \land \textit{carrier_ratios}_\text{node,tech,carrier_tier,carrier}\mathord{>}\text{0})
         \end{array}
         \begin{cases}
-            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=out,carrier,timestep} }) = -1 \times \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\textbf{carrier_con}_\text{node,tech,carrier,timestep} \times \textit{carrier_ratios}_\text{node,tech,carrier_tier=in,carrier,timestep}) \times \textit{energy_eff}_\text{node,tech,timestep}&\quad
+            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=out,carrier} }) = \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{carrier_ratios}_\text{node,tech,carrier_tier=in,carrier}) \times \textit{flow_eff}_\text{node,tech}&\quad
             \\
         \end{cases}
 
-carrier_production_max_conversion_plus
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+flow_out_max_conversion_plus
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Set the upper bound in each timestep of a `conversion_plus` technology's total carrier production on its `out` carrier flows.
+Set the upper bound in each timestep of a `conversion_plus` technology's total outflow on its `out` carrier flows.
 
 .. container:: scrolling-wrapper
 
@@ -225,14 +226,14 @@ Set the upper bound in each timestep of a `conversion_plus` technology's total c
             \text{if } (\text{tech_group=conversion_plus} \land \neg (\textit{cap_method}_\text{node,tech}\mathord{=}\text{integer}))
         \end{array}
         \begin{cases}
-            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) \leq \textit{timestep_resolution}_\text{timestep} \times \textbf{energy_cap}_\text{node,tech}&\quad
+            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) \leq \textit{timestep_resolution}_\text{timestep} \times \textbf{flow_cap}_\text{node,tech}&\quad
             \\
         \end{cases}
 
-carrier_production_min_conversion_plus
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+flow_out_min_conversion_plus
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Set the lower bound in each timestep of a `conversion_plus` technology's total carrier production on its `out` carrier flows.
+Set the lower bound in each timestep of a `conversion_plus` technology's total outflow on its `out` carrier flows.
 
 .. container:: scrolling-wrapper
 
@@ -243,10 +244,10 @@ Set the lower bound in each timestep of a `conversion_plus` technology's total c
             \text{ tech }\negthickspace \in \negthickspace\text{ techs, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\exists (\textit{energy_cap_min_use}_\text{node,tech}) \land \text{tech_group=conversion_plus} \land \neg (\textit{cap_method}_\text{node,tech}\mathord{=}\text{integer}))
+            \text{if } (\exists (\textit{flow_out_min_relative}_\text{node,tech}) \land \text{tech_group=conversion_plus} \land \neg (\textit{cap_method}_\text{node,tech}\mathord{=}\text{integer}))
         \end{array}
         \begin{cases}
-            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) \geq \textit{timestep_resolution}_\text{timestep} \times \textbf{energy_cap}_\text{node,tech} \times \textit{energy_cap_min_use}_\text{node,tech}&\quad
+            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) \geq \textit{timestep_resolution}_\text{timestep} \times \textbf{flow_cap}_\text{node,tech} \times \textit{flow_out_min_relative}_\text{node,tech}&\quad
             \\
         \end{cases}
 
@@ -265,37 +266,37 @@ Fix the relationship between a `conversion_plus` technology's total `in_2`/`in_3
             \text{ carrier_tier }\negthickspace \in \negthickspace\text{ carrier_tiers, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\text{tech_group=conversion_plus} \land \text{carrier_tier} \in \text{[in_2,out_2,in_3,out_3]} \land \textit{carrier_ratios}_\text{node,tech,carrier_tier,carrier,timestep}\mathord{>}\text{0})
+            \text{if } (\text{tech_group=conversion_plus} \land \text{carrier_tier} \in \text{[in_2,out_2,in_3,out_3]} \land \textit{carrier_ratios}_\text{node,tech,carrier_tier,carrier}\mathord{>}\text{0})
         \end{array}
         \begin{cases}
-            \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\frac{ \textbf{carrier_con}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=in,carrier,timestep} }) = \sum\limits_{\text{carrier} \in \text{carrier_tier(in_2)}} (\frac{ \textbf{carrier_con}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=in_2,carrier,timestep} })&\quad
-            \text{if } (\text{carrier_tier} \in \text{[in_2]})\land{}(\text{carrier_tier} \in \text{[in_2,in_3]})
+            \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\frac{ \textbf{flow_in}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=in,carrier} }) = \sum\limits_{\text{carrier} \in \text{carrier_tier(in_2)}} (\frac{ \textbf{flow_in}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=in_2,carrier} })&\quad
+            \text{if } (\text{carrier_tier} \in \text{[in_2,in_3]})\land{}(\text{carrier_tier} \in \text{[in_2]})
             \\
-            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=out,carrier,timestep} }) = \sum\limits_{\text{carrier} \in \text{carrier_tier(in_2)}} (\frac{ \textbf{carrier_con}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=in_2,carrier,timestep} })&\quad
-            \text{if } (\text{carrier_tier} \in \text{[in_2]})\land{}(\text{carrier_tier} \in \text{[out_2,out_3]})
+            \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\frac{ \textbf{flow_in}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=in,carrier} }) = \sum\limits_{\text{carrier} \in \text{carrier_tier(in_3)}} (\frac{ \textbf{flow_in}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=in_3,carrier} })&\quad
+            \text{if } (\text{carrier_tier} \in \text{[in_2,in_3]})\land{}(\text{carrier_tier} \in \text{[in_3]})
             \\
-            \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\frac{ \textbf{carrier_con}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=in,carrier,timestep} }) = \sum\limits_{\text{carrier} \in \text{carrier_tier(in_3)}} (\frac{ \textbf{carrier_con}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=in_3,carrier,timestep} })&\quad
-            \text{if } (\text{carrier_tier} \in \text{[in_3]})\land{}(\text{carrier_tier} \in \text{[in_2,in_3]})
+            \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\frac{ \textbf{flow_in}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=in,carrier} }) = \sum\limits_{\text{carrier} \in \text{carrier_tier(out_2)}} (\frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=out_2,carrier} })&\quad
+            \text{if } (\text{carrier_tier} \in \text{[in_2,in_3]})\land{}(\text{carrier_tier} \in \text{[out_2]})
             \\
-            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=out,carrier,timestep} }) = \sum\limits_{\text{carrier} \in \text{carrier_tier(in_3)}} (\frac{ \textbf{carrier_con}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=in_3,carrier,timestep} })&\quad
-            \text{if } (\text{carrier_tier} \in \text{[in_3]})\land{}(\text{carrier_tier} \in \text{[out_2,out_3]})
+            \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\frac{ \textbf{flow_in}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=in,carrier} }) = \sum\limits_{\text{carrier} \in \text{carrier_tier(out_3)}} (\frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=out_3,carrier} })&\quad
+            \text{if } (\text{carrier_tier} \in \text{[in_2,in_3]})\land{}(\text{carrier_tier} \in \text{[out_3]})
             \\
-            \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\frac{ \textbf{carrier_con}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=in,carrier,timestep} }) = \sum\limits_{\text{carrier} \in \text{carrier_tier(out_2)}} (\frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=out_2,carrier,timestep} })&\quad
-            \text{if } (\text{carrier_tier} \in \text{[out_2]})\land{}(\text{carrier_tier} \in \text{[in_2,in_3]})
+            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=out,carrier} }) = \sum\limits_{\text{carrier} \in \text{carrier_tier(in_2)}} (\frac{ \textbf{flow_in}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=in_2,carrier} })&\quad
+            \text{if } (\text{carrier_tier} \in \text{[out_2,out_3]})\land{}(\text{carrier_tier} \in \text{[in_2]})
             \\
-            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=out,carrier,timestep} }) = \sum\limits_{\text{carrier} \in \text{carrier_tier(out_2)}} (\frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=out_2,carrier,timestep} })&\quad
-            \text{if } (\text{carrier_tier} \in \text{[out_2]})\land{}(\text{carrier_tier} \in \text{[out_2,out_3]})
+            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=out,carrier} }) = \sum\limits_{\text{carrier} \in \text{carrier_tier(in_3)}} (\frac{ \textbf{flow_in}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=in_3,carrier} })&\quad
+            \text{if } (\text{carrier_tier} \in \text{[out_2,out_3]})\land{}(\text{carrier_tier} \in \text{[in_3]})
             \\
-            \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\frac{ \textbf{carrier_con}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=in,carrier,timestep} }) = \sum\limits_{\text{carrier} \in \text{carrier_tier(out_3)}} (\frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=out_3,carrier,timestep} })&\quad
-            \text{if } (\text{carrier_tier} \in \text{[out_3]})\land{}(\text{carrier_tier} \in \text{[in_2,in_3]})
+            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=out,carrier} }) = \sum\limits_{\text{carrier} \in \text{carrier_tier(out_2)}} (\frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=out_2,carrier} })&\quad
+            \text{if } (\text{carrier_tier} \in \text{[out_2,out_3]})\land{}(\text{carrier_tier} \in \text{[out_2]})
             \\
-            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=out,carrier,timestep} }) = \sum\limits_{\text{carrier} \in \text{carrier_tier(out_3)}} (\frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=out_3,carrier,timestep} })&\quad
-            \text{if } (\text{carrier_tier} \in \text{[out_3]})\land{}(\text{carrier_tier} \in \text{[out_2,out_3]})
+            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=out,carrier} }) = \sum\limits_{\text{carrier} \in \text{carrier_tier(out_3)}} (\frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{carrier_ratios}_\text{node,tech,carrier_tier=out_3,carrier} })&\quad
+            \text{if } (\text{carrier_tier} \in \text{[out_2,out_3]})\land{}(\text{carrier_tier} \in \text{[out_3]})
             \\
         \end{cases}
 
-conversion_plus_prod_con_to_zero
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+conversion_plus_flow_to_zero
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 Set a `conversion_plus` technology's carrier flow to zero if its `carrier_ratio` is zero.
 
@@ -309,13 +310,13 @@ Set a `conversion_plus` technology's carrier flow to zero if its `carrier_ratio`
             \text{ carrier }\negthickspace \in \negthickspace\text{ carriers, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\textit{carrier_ratios}_\text{node,tech,carrier_tier,carrier,timestep}\mathord{=}\text{0} \land \text{tech_group=conversion_plus})
+            \text{if } (\textit{carrier_ratios}_\text{node,tech,carrier_tier,carrier}\mathord{=}\text{0} \land \text{tech_group=conversion_plus})
         \end{array}
         \begin{cases}
-            \textbf{carrier_con}_\text{node,tech,carrier,timestep} = 0&\quad
+            \textbf{flow_in}_\text{node,tech,carrier,timestep} = 0&\quad
             \text{if } (\text{carrier_tier} \in \text{[in,in_2,in_3]})
             \\
-            \textbf{carrier_prod}_\text{node,tech,carrier,timestep} = 0&\quad
+            \textbf{flow_out}_\text{node,tech,carrier,timestep} = 0&\quad
             \text{if } (\text{carrier_tier} \in \text{[out,out_2,out_3]})
             \\
         \end{cases}
@@ -323,7 +324,7 @@ Set a `conversion_plus` technology's carrier flow to zero if its `carrier_ratio`
 balance_conversion
 ^^^^^^^^^^^^^^^^^^
 
-Fix the relationship between a `conversion` technology's carrier production and consumption.
+Fix the relationship between a `conversion` technology's outflow and consumption.
 
 .. container:: scrolling-wrapper
 
@@ -337,14 +338,14 @@ Fix the relationship between a `conversion` technology's carrier production and
             \text{if } (\text{tech_group=conversion})
         \end{array}
         \begin{cases}
-            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) = -1 \times \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\textbf{carrier_con}_\text{node,tech,carrier,timestep}) \times \textit{energy_eff}_\text{node,tech,timestep}&\quad
+            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) = \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\textbf{flow_in}_\text{node,tech,carrier,timestep}) \times \textit{flow_eff}_\text{node,tech}&\quad
             \\
         \end{cases}
 
-carrier_production_max
-^^^^^^^^^^^^^^^^^^^^^^
+flow_out_max
+^^^^^^^^^^^^
 
-Set the upper bound of a non-`conversion_plus` technology's carrier production.
+Set the upper bound of a non-`conversion_plus` technology's outflow.
 
 .. container:: scrolling-wrapper
 
@@ -356,17 +357,17 @@ Set the upper bound of a non-`conversion_plus` technology's carrier production.
             \text{ carrier }\negthickspace \in \negthickspace\text{ carriers, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \neg (\text{tech_group=conversion_plus}) \land \neg (\textit{cap_method}_\text{node,tech}\mathord{=}\text{integer}) \land \textit{allowed_carrier_prod}_\text{node,tech}\mathord{=}\text{true} \land \text{carrier_tier} \in \text{[out]})
+            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \neg (\text{tech_group=conversion_plus}) \land \neg (\textit{cap_method}_\text{node,tech}\mathord{=}\text{integer}) \land \textit{allowed_flow_out}_\text{node,tech}\mathord{=}\text{true} \land \text{carrier_tier} \in \text{[out]})
         \end{array}
         \begin{cases}
-            \textbf{carrier_prod}_\text{node,tech,carrier,timestep} \leq \textbf{energy_cap}_\text{node,tech} \times \textit{timestep_resolution}_\text{timestep} \times \textit{parasitic_eff}_\text{node,tech,timestep}&\quad
+            \textbf{flow_out}_\text{node,tech,carrier,timestep} \leq \textbf{flow_cap}_\text{node,tech} \times \textit{timestep_resolution}_\text{timestep} \times \textit{parasitic_eff}_\text{node,tech}&\quad
             \\
         \end{cases}
 
-carrier_production_min
-^^^^^^^^^^^^^^^^^^^^^^
+flow_out_min
+^^^^^^^^^^^^
 
-Set the lower bound of a non-`conversion_plus` technology's carrier production.
+Set the lower bound of a non-`conversion_plus` technology's outflow.
 
 .. container:: scrolling-wrapper
 
@@ -378,17 +379,17 @@ Set the lower bound of a non-`conversion_plus` technology's carrier production.
             \text{ carrier }\negthickspace \in \negthickspace\text{ carriers, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \exists (\textit{energy_cap_min_use}_\text{node,tech}) \land \neg (\text{tech_group=conversion_plus}) \land \neg (\textit{cap_method}_\text{node,tech}\mathord{=}\text{integer}) \land \textit{allowed_carrier_prod}_\text{node,tech}\mathord{=}\text{true} \land \text{carrier_tier} \in \text{[out]})
+            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \exists (\textit{flow_out_min_relative}_\text{node,tech}) \land \neg (\text{tech_group=conversion_plus}) \land \neg (\textit{cap_method}_\text{node,tech}\mathord{=}\text{integer}) \land \textit{allowed_flow_out}_\text{node,tech}\mathord{=}\text{true} \land \text{carrier_tier} \in \text{[out]})
         \end{array}
         \begin{cases}
-            \textbf{carrier_prod}_\text{node,tech,carrier,timestep} \geq \textbf{energy_cap}_\text{node,tech} \times \textit{timestep_resolution}_\text{timestep} \times \textit{energy_cap_min_use}_\text{node,tech}&\quad
+            \textbf{flow_out}_\text{node,tech,carrier,timestep} \geq \textbf{flow_cap}_\text{node,tech} \times \textit{timestep_resolution}_\text{timestep} \times \textit{flow_out_min_relative}_\text{node,tech}&\quad
             \\
         \end{cases}
 
-carrier_consumption_max
-^^^^^^^^^^^^^^^^^^^^^^^
+flow_in_max
+^^^^^^^^^^^
 
-Set the upper bound of a non-`conversion_plus` technology's carrier consumption.
+Set the upper bound of a non-`conversion_plus` technology's inflow.
 
 .. container:: scrolling-wrapper
 
@@ -400,17 +401,17 @@ Set the upper bound of a non-`conversion_plus` technology's carrier consumption.
             \text{ carrier }\negthickspace \in \negthickspace\text{ carriers, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land (\text{tech_group=transmission} \lor \text{tech_group=demand} \lor \text{tech_group=storage}) \land (\neg (\textit{cap_method}_\text{node,tech}\mathord{=}\text{integer}) \lor \text{tech_group=demand}) \land \textit{allowed_carrier_con}_\text{node,tech}\mathord{=}\text{true} \land \text{carrier_tier} \in \text{[in]})
+            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land (\text{tech_group=transmission} \lor \text{tech_group=demand} \lor \text{tech_group=storage}) \land (\neg (\textit{cap_method}_\text{node,tech}\mathord{=}\text{integer}) \lor \text{tech_group=demand}) \land \textit{allowed_flow_in}_\text{node,tech}\mathord{=}\text{true} \land \text{carrier_tier} \in \text{[in]})
         \end{array}
         \begin{cases}
-            \textbf{carrier_con}_\text{node,tech,carrier,timestep} \geq -1 \times \textbf{energy_cap}_\text{node,tech} \times \textit{timestep_resolution}_\text{timestep}&\quad
+            \textbf{flow_in}_\text{node,tech,carrier,timestep} \leq \textbf{flow_cap}_\text{node,tech} \times \textit{timestep_resolution}_\text{timestep}&\quad
             \\
         \end{cases}
 
-resource_max
-^^^^^^^^^^^^
+source_use_max
+^^^^^^^^^^^^^^
 
-Set the upper bound of a `supply_plus` technology's resource consumption.
+Set the upper bound of a `supply_plus` technology's source consumption.
 
 .. container:: scrolling-wrapper
 
@@ -424,14 +425,14 @@ Set the upper bound of a `supply_plus` technology's resource consumption.
             \text{if } (\text{tech_group=supply_plus})
         \end{array}
         \begin{cases}
-            \textbf{resource_con}_\text{node,tech,timestep} \leq \textit{timestep_resolution}_\text{timestep} \times \textbf{resource_cap}_\text{node,tech}&\quad
+            \textbf{source_use}_\text{node,tech,timestep} \leq \textit{timestep_resolution}_\text{timestep} \times \textbf{source_cap}_\text{node,tech}&\quad
             \\
         \end{cases}
 
 storage_max
 ^^^^^^^^^^^
 
-Set the upper bound of the amount of energy a `storage`/`supply_plus` technology can store.
+Set the upper bound of the amount of carrier a `storage`/`supply_plus` technology can store.
 
 .. container:: scrolling-wrapper
 
@@ -452,7 +453,7 @@ Set the upper bound of the amount of energy a `storage`/`supply_plus` technology
 storage_discharge_depth_limit
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Set the lower bound of the stored energy a `storage`/`supply_plus` technology must keep in reserve at all times.
+Set the lower bound of the stored carrier a `storage`/`supply_plus` technology must keep in reserve at all times.
 
 .. container:: scrolling-wrapper
 
@@ -473,7 +474,7 @@ Set the lower bound of the stored energy a `storage`/`supply_plus` technology mu
 system_balance
 ^^^^^^^^^^^^^^
 
-Set the global energy balance of the optimisation problem by fixing the total production of a given energy carrier to equal the total consumption of that carrier at every node in every timestep.
+Set the global carrier balance of the optimisation problem by fixing the total production of a given carrier to equal the total consumption of that carrier at every node in every timestep.
 
 .. container:: scrolling-wrapper
 
@@ -486,24 +487,24 @@ Set the global energy balance of the optimisation problem by fixing the total pr
             \\
         \end{array}
         \begin{cases}
-            \sum\limits_{\text{tech} \in \text{techs}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \sum\limits_{\text{tech} \in \text{techs}} (\textbf{carrier_con}_\text{node,tech,carrier,timestep}) - \sum\limits_{\text{tech} \in \text{techs}} (\textbf{carrier_export}_\text{node,tech,carrier,timestep}) + \textbf{unmet_demand}_\text{node,carrier,timestep} + \textbf{unused_supply}_\text{node,carrier,timestep} = 0&\quad
-            \text{if } (\text{run_config.ensure_feasibility}\mathord{=}\text{true})\land{}(\bigvee\limits_{\text{tech} \in \text{techs}} (export_carrier))
+            \sum\limits_{\text{tech} \in \text{techs}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) - \sum\limits_{\text{tech} \in \text{techs}} (\textbf{flow_in}_\text{node,tech,carrier,timestep}) - \sum\limits_{\text{tech} \in \text{techs}} (\textbf{flow_export}_\text{node,tech,carrier,timestep}) + \textbf{unmet_demand}_\text{node,carrier,timestep} + \textbf{unused_supply}_\text{node,carrier,timestep} = 0&\quad
+            \text{if } (\text{config.ensure_feasibility}\mathord{=}\text{true})\land{}(\bigvee\limits_{\text{tech} \in \text{techs}} (export_carrier))
             \\
-            \sum\limits_{\text{tech} \in \text{techs}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \sum\limits_{\text{tech} \in \text{techs}} (\textbf{carrier_con}_\text{node,tech,carrier,timestep}) + \textbf{unmet_demand}_\text{node,carrier,timestep} + \textbf{unused_supply}_\text{node,carrier,timestep} = 0&\quad
-            \text{if } (\text{run_config.ensure_feasibility}\mathord{=}\text{true})\land{}(\neg (\bigvee\limits_{\text{tech} \in \text{techs}} (export_carrier)))
+            \sum\limits_{\text{tech} \in \text{techs}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) - \sum\limits_{\text{tech} \in \text{techs}} (\textbf{flow_in}_\text{node,tech,carrier,timestep}) + \textbf{unmet_demand}_\text{node,carrier,timestep} + \textbf{unused_supply}_\text{node,carrier,timestep} = 0&\quad
+            \text{if } (\text{config.ensure_feasibility}\mathord{=}\text{true})\land{}(\neg (\bigvee\limits_{\text{tech} \in \text{techs}} (export_carrier)))
             \\
-            \sum\limits_{\text{tech} \in \text{techs}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \sum\limits_{\text{tech} \in \text{techs}} (\textbf{carrier_con}_\text{node,tech,carrier,timestep}) - \sum\limits_{\text{tech} \in \text{techs}} (\textbf{carrier_export}_\text{node,tech,carrier,timestep}) = 0&\quad
-            \text{if } (\neg (\text{run_config.ensure_feasibility}\mathord{=}\text{true}))\land{}(\bigvee\limits_{\text{tech} \in \text{techs}} (export_carrier))
+            \sum\limits_{\text{tech} \in \text{techs}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) - \sum\limits_{\text{tech} \in \text{techs}} (\textbf{flow_in}_\text{node,tech,carrier,timestep}) - \sum\limits_{\text{tech} \in \text{techs}} (\textbf{flow_export}_\text{node,tech,carrier,timestep}) = 0&\quad
+            \text{if } (\neg (\text{config.ensure_feasibility}\mathord{=}\text{true}))\land{}(\bigvee\limits_{\text{tech} \in \text{techs}} (export_carrier))
             \\
-            \sum\limits_{\text{tech} \in \text{techs}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \sum\limits_{\text{tech} \in \text{techs}} (\textbf{carrier_con}_\text{node,tech,carrier,timestep}) = 0&\quad
-            \text{if } (\neg (\text{run_config.ensure_feasibility}\mathord{=}\text{true}))\land{}(\neg (\bigvee\limits_{\text{tech} \in \text{techs}} (export_carrier)))
+            \sum\limits_{\text{tech} \in \text{techs}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) - \sum\limits_{\text{tech} \in \text{techs}} (\textbf{flow_in}_\text{node,tech,carrier,timestep}) = 0&\quad
+            \text{if } (\neg (\text{config.ensure_feasibility}\mathord{=}\text{true}))\land{}(\neg (\bigvee\limits_{\text{tech} \in \text{techs}} (export_carrier)))
             \\
         \end{cases}
 
 balance_supply
 ^^^^^^^^^^^^^^
 
-Set the upper bound on, or a fixed total of, a `supply` technology's ability to produce energy based on the quantity of  available resource.
+Set the upper bound on, or a fixed total of, a `supply` technology's ability to produce a carrier based on the quantity of  available source.
 
 .. container:: scrolling-wrapper
 
@@ -515,36 +516,36 @@ Set the upper bound on, or a fixed total of, a `supply` technology's ability to
             \text{ carrier }\negthickspace \in \negthickspace\text{ carriers, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\exists (\textit{resource}_\text{node,tech,timestep}) \land \text{tech_group=supply})
+            \text{if } ((\exists (\textit{source_equals}_\text{node,tech}) \lor \exists (\textit{source_max}_\text{node,tech})) \land \text{tech_group=supply})
         \end{array}
         \begin{cases}
-            \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{energy_eff}_\text{node,tech,timestep} } = \textit{resource}_\text{node,tech,timestep} \times \textit{resource_scale}_\text{node,tech} \times \textbf{resource_area}_\text{node,tech}&\quad
-            \text{if } (\textit{force_resource}_\text{node,tech}\mathord{=}\text{true} \land \textit{energy_eff}_\text{node,tech,timestep}\mathord{>}\text{0})\land{}(\textit{resource_unit}_\text{node,tech}\mathord{=}\text{energy_per_area})
+            \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{flow_eff}_\text{node,tech} } = \textit{source_equals}_\text{node,tech} \times \textbf{area_use}_\text{node,tech}&\quad
+            \text{if } (\exists (\textit{source_equals}_\text{node,tech}) \land \textit{flow_eff}_\text{node,tech}\mathord{>}\text{0})\land{}(\textit{source_unit}_\text{node,tech}\mathord{=}\text{per_area})
             \\
-            \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{energy_eff}_\text{node,tech,timestep} } = \textit{resource}_\text{node,tech,timestep} \times \textit{resource_scale}_\text{node,tech} \times \textbf{energy_cap}_\text{node,tech}&\quad
-            \text{if } (\textit{force_resource}_\text{node,tech}\mathord{=}\text{true} \land \textit{energy_eff}_\text{node,tech,timestep}\mathord{>}\text{0})\land{}(\textit{resource_unit}_\text{node,tech}\mathord{=}\text{energy_per_cap})
+            \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{flow_eff}_\text{node,tech} } = \textit{source_equals}_\text{node,tech} \times \textbf{flow_cap}_\text{node,tech}&\quad
+            \text{if } (\exists (\textit{source_equals}_\text{node,tech}) \land \textit{flow_eff}_\text{node,tech}\mathord{>}\text{0})\land{}(\textit{source_unit}_\text{node,tech}\mathord{=}\text{per_cap})
             \\
-            \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{energy_eff}_\text{node,tech,timestep} } = \textit{resource}_\text{node,tech,timestep} \times \textit{resource_scale}_\text{node,tech}&\quad
-            \text{if } (\textit{force_resource}_\text{node,tech}\mathord{=}\text{true} \land \textit{energy_eff}_\text{node,tech,timestep}\mathord{>}\text{0})\land{}(\textit{resource_unit}_\text{node,tech}\mathord{=}\text{energy})
+            \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{flow_eff}_\text{node,tech} } = \textit{source_equals}_\text{node,tech} \times 1&\quad
+            \text{if } (\exists (\textit{source_equals}_\text{node,tech}) \land \textit{flow_eff}_\text{node,tech}\mathord{>}\text{0})\land{}(\textit{source_unit}_\text{node,tech}\mathord{=}\text{absolute})
             \\
-            \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{energy_eff}_\text{node,tech,timestep} } \leq \textit{resource}_\text{node,tech,timestep} \times \textit{resource_scale}_\text{node,tech} \times \textbf{resource_area}_\text{node,tech}&\quad
-            \text{if } (\neg (\textit{force_resource}_\text{node,tech}\mathord{=}\text{true}) \land \textit{energy_eff}_\text{node,tech,timestep}\mathord{>}\text{0})\land{}(\textit{resource_unit}_\text{node,tech}\mathord{=}\text{energy_per_area})
+            \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{flow_eff}_\text{node,tech} } \leq \textit{source_max}_\text{node,tech} \times \textbf{area_use}_\text{node,tech}&\quad
+            \text{if } (\neg (\exists (\textit{source_equals}_\text{node,tech})) \land \exists (\textit{sink_max}) \land \textit{flow_eff}_\text{node,tech}\mathord{>}\text{0})\land{}(\textit{source_unit}_\text{node,tech}\mathord{=}\text{per_area})
             \\
-            \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{energy_eff}_\text{node,tech,timestep} } \leq \textit{resource}_\text{node,tech,timestep} \times \textit{resource_scale}_\text{node,tech} \times \textbf{energy_cap}_\text{node,tech}&\quad
-            \text{if } (\neg (\textit{force_resource}_\text{node,tech}\mathord{=}\text{true}) \land \textit{energy_eff}_\text{node,tech,timestep}\mathord{>}\text{0})\land{}(\textit{resource_unit}_\text{node,tech}\mathord{=}\text{energy_per_cap})
+            \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{flow_eff}_\text{node,tech} } \leq \textit{source_max}_\text{node,tech} \times \textbf{flow_cap}_\text{node,tech}&\quad
+            \text{if } (\neg (\exists (\textit{source_equals}_\text{node,tech})) \land \exists (\textit{sink_max}) \land \textit{flow_eff}_\text{node,tech}\mathord{>}\text{0})\land{}(\textit{source_unit}_\text{node,tech}\mathord{=}\text{per_cap})
             \\
-            \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{energy_eff}_\text{node,tech,timestep} } \leq \textit{resource}_\text{node,tech,timestep} \times \textit{resource_scale}_\text{node,tech}&\quad
-            \text{if } (\neg (\textit{force_resource}_\text{node,tech}\mathord{=}\text{true}) \land \textit{energy_eff}_\text{node,tech,timestep}\mathord{>}\text{0})\land{}(\textit{resource_unit}_\text{node,tech}\mathord{=}\text{energy})
+            \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{flow_eff}_\text{node,tech} } \leq \textit{source_max}_\text{node,tech} \times 1&\quad
+            \text{if } (\neg (\exists (\textit{source_equals}_\text{node,tech})) \land \exists (\textit{sink_max}) \land \textit{flow_eff}_\text{node,tech}\mathord{>}\text{0})\land{}(\textit{source_unit}_\text{node,tech}\mathord{=}\text{absolute})
             \\
-            \textbf{carrier_prod}_\text{node,tech,carrier,timestep} = 0&\quad
-            \text{if } (\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0})
+            \textbf{flow_out}_\text{node,tech,carrier,timestep} = 0&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0})
             \\
         \end{cases}
 
 balance_supply_min_use
 ^^^^^^^^^^^^^^^^^^^^^^
 
-Set the lower bound on, or a fixed amount of, the energy a `supply` technology must consume in each timestep.
+Set the lower bound on the quantity of its source a `supply` technology must use in each timestep.
 
 .. container:: scrolling-wrapper
 
@@ -556,10 +557,17 @@ Set the lower bound on, or a fixed amount of, the energy a `supply` technology m
             \text{ carrier }\negthickspace \in \negthickspace\text{ carriers, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\exists (\textit{resource}_\text{node,tech,timestep}) \land \text{tech_group=supply} \land \exists (\textit{resource_min_use}_\text{node,tech}) \land \textit{energy_eff}_\text{node,tech,timestep}\mathord{>}\text{0} \land \neg (\textit{force_resource}_\text{node,tech}\mathord{=}\text{true}))
+            \text{if } (\exists (\textit{source_min}_\text{node,tech}) \land \neg (\exists (\textit{source_equals}_\text{node,tech})) \land \text{tech_group=supply} \land \textit{flow_eff}_\text{node,tech}\mathord{>}\text{0})
         \end{array}
         \begin{cases}
-            \textit{resource_min_use}_\text{node,tech} \leq \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{energy_eff}_\text{node,tech,timestep} }&\quad
+            \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{flow_eff}_\text{node,tech} } \geq \textit{source_min}_\text{node,tech} \times \textbf{area_use}_\text{node,tech}&\quad
+            \text{if } (\textit{source_unit}_\text{node,tech}\mathord{=}\text{per_area})
+            \\
+            \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{flow_eff}_\text{node,tech} } \geq \textit{source_min}_\text{node,tech} \times \textbf{flow_cap}_\text{node,tech}&\quad
+            \text{if } (\textit{source_unit}_\text{node,tech}\mathord{=}\text{per_cap})
+            \\
+            \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{flow_eff}_\text{node,tech} } \geq \textit{source_min}_\text{node,tech} \times 1&\quad
+            \text{if } (\textit{source_unit}_\text{node,tech}\mathord{=}\text{absolute})
             \\
         \end{cases}
 
@@ -580,30 +588,59 @@ balance_demand
             \text{if } (\text{tech_group=demand})
         \end{array}
         \begin{cases}
-            \textbf{carrier_con}_\text{node,tech,carrier,timestep} \times \textit{energy_eff}_\text{node,tech,timestep} = \textit{resource}_\text{node,tech,timestep} \times \textit{resource_scale}_\text{node,tech} \times \textbf{resource_area}_\text{node,tech}&\quad
-            \text{if } (\textit{force_resource}_\text{node,tech}\mathord{=}\text{true})\land{}(\textit{resource_unit}_\text{node,tech}\mathord{=}\text{energy_per_area})
+            \textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech} = \textit{sink_equals}_\text{node,tech,timestep} \times \textbf{area_use}_\text{node,tech}&\quad
+            \text{if } (\exists (\textit{sink_equals}_\text{node,tech,timestep}))\land{}(\textit{sink_unit}_\text{node,tech}\mathord{=}\text{per_area})
+            \\
+            \textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech} = \textit{sink_equals}_\text{node,tech,timestep} \times \textbf{flow_cap}_\text{node,tech}&\quad
+            \text{if } (\exists (\textit{sink_equals}_\text{node,tech,timestep}))\land{}(\textit{sink_unit}_\text{node,tech}\mathord{=}\text{per_cap})
+            \\
+            \textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech} = \textit{sink_equals}_\text{node,tech,timestep} \times 1&\quad
+            \text{if } (\exists (\textit{sink_equals}_\text{node,tech,timestep}))\land{}(\textit{sink_unit}_\text{node,tech}\mathord{=}\text{absolute})
             \\
-            \textbf{carrier_con}_\text{node,tech,carrier,timestep} \times \textit{energy_eff}_\text{node,tech,timestep} = \textit{resource}_\text{node,tech,timestep} \times \textit{resource_scale}_\text{node,tech} \times \textbf{energy_cap}_\text{node,tech}&\quad
-            \text{if } (\textit{force_resource}_\text{node,tech}\mathord{=}\text{true})\land{}(\textit{resource_unit}_\text{node,tech}\mathord{=}\text{energy_per_cap})
+            \textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech} \leq \textit{sink_max} \times \textbf{area_use}_\text{node,tech}&\quad
+            \text{if } (\neg (\exists (\textit{sink_equals}_\text{node,tech,timestep})) \land \exists (\textit{sink_max}))\land{}(\textit{sink_unit}_\text{node,tech}\mathord{=}\text{per_area})
             \\
-            \textbf{carrier_con}_\text{node,tech,carrier,timestep} \times \textit{energy_eff}_\text{node,tech,timestep} = \textit{resource}_\text{node,tech,timestep} \times \textit{resource_scale}_\text{node,tech}&\quad
-            \text{if } (\textit{force_resource}_\text{node,tech}\mathord{=}\text{true})\land{}(\textit{resource_unit}_\text{node,tech}\mathord{=}\text{energy})
+            \textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech} \leq \textit{sink_max} \times \textbf{flow_cap}_\text{node,tech}&\quad
+            \text{if } (\neg (\exists (\textit{sink_equals}_\text{node,tech,timestep})) \land \exists (\textit{sink_max}))\land{}(\textit{sink_unit}_\text{node,tech}\mathord{=}\text{per_cap})
+            \\
+            \textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech} \leq \textit{sink_max} \times 1&\quad
+            \text{if } (\neg (\exists (\textit{sink_equals}_\text{node,tech,timestep})) \land \exists (\textit{sink_max}))\land{}(\textit{sink_unit}_\text{node,tech}\mathord{=}\text{absolute})
+            \\
+        \end{cases}
+
+balance_demand_min_use
+^^^^^^^^^^^^^^^^^^^^^^
+
+Set the lower bound on the quantity of flow a `demand` technology must dump to its sink in each timestep.
+
+.. container:: scrolling-wrapper
+
+    .. math::
+        \begin{array}{r}
+            \forall{}
+            \text{ node }\negthickspace \in \negthickspace\text{ nodes, }
+            \text{ tech }\negthickspace \in \negthickspace\text{ techs, }
+            \text{ carrier }\negthickspace \in \negthickspace\text{ carriers, }
+            \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \textbf{carrier_con}_\text{node,tech,carrier,timestep} \times \textit{energy_eff}_\text{node,tech,timestep} \geq \textit{resource}_\text{node,tech,timestep} \times \textit{resource_scale}_\text{node,tech} \times \textbf{resource_area}_\text{node,tech}&\quad
-            \text{if } (\neg (\textit{force_resource}_\text{node,tech}\mathord{=}\text{true}))\land{}(\textit{resource_unit}_\text{node,tech}\mathord{=}\text{energy_per_area})
+            \text{if } (\exists (\textit{sink_min}) \land \neg (\exists (\textit{source_equals}_\text{node,tech})) \land \text{tech_group=supply} \land \textit{flow_eff}_\text{node,tech}\mathord{>}\text{0})
+        \end{array}
+        \begin{cases}
+            \textit{sink_min} \times \textbf{area_use}_\text{node,tech} \leq \textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech}&\quad
+            \text{if } (\textit{sink_unit}_\text{node,tech}\mathord{=}\text{per_area})
             \\
-            \textbf{carrier_con}_\text{node,tech,carrier,timestep} \times \textit{energy_eff}_\text{node,tech,timestep} \geq \textit{resource}_\text{node,tech,timestep} \times \textit{resource_scale}_\text{node,tech} \times \textbf{energy_cap}_\text{node,tech}&\quad
-            \text{if } (\neg (\textit{force_resource}_\text{node,tech}\mathord{=}\text{true}))\land{}(\textit{resource_unit}_\text{node,tech}\mathord{=}\text{energy_per_cap})
+            \textit{sink_min} \times \textbf{flow_cap}_\text{node,tech} \leq \textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech}&\quad
+            \text{if } (\textit{sink_unit}_\text{node,tech}\mathord{=}\text{per_cap})
             \\
-            \textbf{carrier_con}_\text{node,tech,carrier,timestep} \times \textit{energy_eff}_\text{node,tech,timestep} \geq \textit{resource}_\text{node,tech,timestep} \times \textit{resource_scale}_\text{node,tech}&\quad
-            \text{if } (\neg (\textit{force_resource}_\text{node,tech}\mathord{=}\text{true}))\land{}(\textit{resource_unit}_\text{node,tech}\mathord{=}\text{energy})
+            \textit{sink_min} \times 1 \leq \textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech}&\quad
+            \text{if } (\textit{sink_unit}_\text{node,tech}\mathord{=}\text{absolute})
             \\
         \end{cases}
 
 balance_supply_plus_no_storage
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Set the upper bound on, or a fixed total of, a `supply_plus` (without storage) technology's ability to produce energy based on only the quantity of consumed resource.
+Set the upper bound on, or a fixed total of, a `supply_plus` (without storage) technology's ability to produce flow based on only the quantity of consumed resource.
 
 .. container:: scrolling-wrapper
 
@@ -618,18 +655,18 @@ Set the upper bound on, or a fixed total of, a `supply_plus` (without storage) t
             \text{if } (\text{tech_group=supply_plus} \land \neg (\textit{include_storage}_\text{node,tech}\mathord{=}\text{true}))
         \end{array}
         \begin{cases}
-            \textbf{resource_con}_\text{node,tech,timestep} \times \textit{resource_eff}_\text{node,tech,timestep} = 0&\quad
-            \text{if } (\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech,timestep}\mathord{=}\text{0})
+            \textbf{source_use}_\text{node,tech,timestep} \times \textit{source_eff}_\text{node,tech} = 0&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech}\mathord{=}\text{0})
             \\
-            \textbf{resource_con}_\text{node,tech,timestep} \times \textit{resource_eff}_\text{node,tech,timestep} = \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ (\textit{energy_eff}_\text{node,tech,timestep} \times \textit{parasitic_eff}_\text{node,tech,timestep}) }&\quad
-            \text{if } (\neg (\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech,timestep}\mathord{=}\text{0}))
+            \textbf{source_use}_\text{node,tech,timestep} \times \textit{source_eff}_\text{node,tech} = \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ (\textit{flow_eff}_\text{node,tech} \times \textit{parasitic_eff}_\text{node,tech}) }&\quad
+            \text{if } (\neg (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech}\mathord{=}\text{0}))
             \\
         \end{cases}
 
 balance_supply_plus_with_storage
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Set the upper bound on, or a fixed total of, a `supply_plus` (with storage) technology's ability to produce energy based on the quantity of consumed resource and available stored energy.
+Set the upper bound on, or a fixed total of, a `supply_plus` (with storage) technology's ability to produce flow based on the quantity of consumed resource and available stored carrier.
 
 .. container:: scrolling-wrapper
 
@@ -644,30 +681,30 @@ Set the upper bound on, or a fixed total of, a `supply_plus` (with storage) tech
             \text{if } (\exists (\textbf{storage}_\text{node,tech,timestep}) \land \text{tech_group=supply_plus})
         \end{array}
         \begin{cases}
-            \textbf{storage}_\text{node,tech,timestep} = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech} + (\textbf{resource_con}_\text{node,tech,timestep} \times \textit{resource_eff}_\text{node,tech,timestep})&\quad
-            \text{if } (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true}))\land{}(\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech,timestep}\mathord{=}\text{0})
+            \textbf{storage}_\text{node,tech,timestep} = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech} + (\textbf{source_use}_\text{node,tech,timestep} \times \textit{source_eff}_\text{node,tech})&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech}\mathord{=}\text{0})\land{}(\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true}))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech} + (\textbf{resource_con}_\text{node,tech,timestep} \times \textit{resource_eff}_\text{node,tech,timestep}) - \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ (\textit{energy_eff}_\text{node,tech,timestep} \times \textit{parasitic_eff}_\text{node,tech,timestep}) }&\quad
-            \text{if } (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true}))\land{}(\neg (\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech,timestep}\mathord{=}\text{0}))
+            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech})^{\textit{timestep_resolution}_\text{timestep-1}}) \times \textbf{storage}_\text{node,tech,timestep-1} + (\textbf{source_use}_\text{node,tech,timestep} \times \textit{source_eff}_\text{node,tech})&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech}\mathord{=}\text{0})\land{}(((\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \text{config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]})) \land \neg (\textit{lookup_cluster_first_timestep}\mathord{=}\text{true}))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech,timestep})^{\textit{timestep_resolution}_\text{timestep-1}}) \times \textbf{storage}_\text{node,tech,timestep-1} + (\textbf{resource_con}_\text{node,tech,timestep} \times \textit{resource_eff}_\text{node,tech,timestep})&\quad
-            \text{if } (((\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \text{run_config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]})) \land \neg (\textit{lookup_cluster_first_timestep}\mathord{=}\text{true}))\land{}(\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech,timestep}\mathord{=}\text{0})
+            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech})^{\textit{timestep_resolution}_\text{timestep=lookup_cluster_last_timestep[timestep]}}) \times \textbf{storage}_\text{node,tech,timestep=lookup_cluster_last_timestep[timestep]} + (\textbf{source_use}_\text{node,tech,timestep} \times \textit{source_eff}_\text{node,tech})&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech}\mathord{=}\text{0})\land{}(\textit{lookup_cluster_first_timestep}\mathord{=}\text{true} \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true})))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech,timestep})^{\textit{timestep_resolution}_\text{timestep-1}}) \times \textbf{storage}_\text{node,tech,timestep-1} + (\textbf{resource_con}_\text{node,tech,timestep} \times \textit{resource_eff}_\text{node,tech,timestep}) - \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ (\textit{energy_eff}_\text{node,tech,timestep} \times \textit{parasitic_eff}_\text{node,tech,timestep}) }&\quad
-            \text{if } (((\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \text{run_config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]})) \land \neg (\textit{lookup_cluster_first_timestep}\mathord{=}\text{true}))\land{}(\neg (\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech,timestep}\mathord{=}\text{0}))
+            \textbf{storage}_\text{node,tech,timestep} = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech} + (\textbf{source_use}_\text{node,tech,timestep} \times \textit{source_eff}_\text{node,tech}) - \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ (\textit{flow_eff}_\text{node,tech} \times \textit{parasitic_eff}_\text{node,tech}) }&\quad
+            \text{if } (\neg (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech}\mathord{=}\text{0}))\land{}(\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true}))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech,timestep})^{\textit{timestep_resolution}_\text{timestep=lookup_cluster_last_timestep[timestep]}}) \times \textbf{storage}_\text{node,tech,timestep=lookup_cluster_last_timestep[timestep]} + (\textbf{resource_con}_\text{node,tech,timestep} \times \textit{resource_eff}_\text{node,tech,timestep})&\quad
-            \text{if } (\textit{lookup_cluster_first_timestep}\mathord{=}\text{true} \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true})))\land{}(\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech,timestep}\mathord{=}\text{0})
+            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech})^{\textit{timestep_resolution}_\text{timestep-1}}) \times \textbf{storage}_\text{node,tech,timestep-1} + (\textbf{source_use}_\text{node,tech,timestep} \times \textit{source_eff}_\text{node,tech}) - \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ (\textit{flow_eff}_\text{node,tech} \times \textit{parasitic_eff}_\text{node,tech}) }&\quad
+            \text{if } (\neg (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech}\mathord{=}\text{0}))\land{}(((\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \text{config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]})) \land \neg (\textit{lookup_cluster_first_timestep}\mathord{=}\text{true}))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech,timestep})^{\textit{timestep_resolution}_\text{timestep=lookup_cluster_last_timestep[timestep]}}) \times \textbf{storage}_\text{node,tech,timestep=lookup_cluster_last_timestep[timestep]} + (\textbf{resource_con}_\text{node,tech,timestep} \times \textit{resource_eff}_\text{node,tech,timestep}) - \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ (\textit{energy_eff}_\text{node,tech,timestep} \times \textit{parasitic_eff}_\text{node,tech,timestep}) }&\quad
-            \text{if } (\textit{lookup_cluster_first_timestep}\mathord{=}\text{true} \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true})))\land{}(\neg (\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech,timestep}\mathord{=}\text{0}))
+            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech})^{\textit{timestep_resolution}_\text{timestep=lookup_cluster_last_timestep[timestep]}}) \times \textbf{storage}_\text{node,tech,timestep=lookup_cluster_last_timestep[timestep]} + (\textbf{source_use}_\text{node,tech,timestep} \times \textit{source_eff}_\text{node,tech}) - \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ (\textit{flow_eff}_\text{node,tech} \times \textit{parasitic_eff}_\text{node,tech}) }&\quad
+            \text{if } (\neg (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech}\mathord{=}\text{0}))\land{}(\textit{lookup_cluster_first_timestep}\mathord{=}\text{true} \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true})))
             \\
         \end{cases}
 
-resource_availability_supply_plus
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+source_availability_supply_plus
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Set the upper bound on, or a fixed total of, a `supply_plus` technology's ability to consume its available energy resource.
+Set the upper bound on, or a fixed total of, a `supply_plus` technology's ability to consume its available resource.
 
 .. container:: scrolling-wrapper
 
@@ -678,33 +715,33 @@ Set the upper bound on, or a fixed total of, a `supply_plus` technology's abilit
             \text{ tech }\negthickspace \in \negthickspace\text{ techs, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\exists (\textbf{resource_con}_\text{node,tech,timestep}) \land \exists (\textit{resource}_\text{node,tech,timestep}))
+            \text{if } (\exists (\textbf{source_use}_\text{node,tech,timestep}) \land (\exists (\textit{source_equals}_\text{node,tech}) \lor \exists (\textit{source_max}_\text{node,tech})))
         \end{array}
         \begin{cases}
-            \textbf{resource_con}_\text{node,tech,timestep} = \textit{resource}_\text{node,tech,timestep} \times \textit{resource_scale}_\text{node,tech} \times \textbf{resource_area}_\text{node,tech}&\quad
-            \text{if } (\textit{force_resource}_\text{node,tech}\mathord{=}\text{true})\land{}(\textit{resource_unit}_\text{node,tech}\mathord{=}\text{energy_per_area})
+            \textbf{source_use}_\text{node,tech,timestep} = \textit{source_equals}_\text{node,tech} \times \textbf{area_use}_\text{node,tech}&\quad
+            \text{if } (\exists (\textit{source_equals}_\text{node,tech}))\land{}(\textit{source_unit}_\text{node,tech}\mathord{=}\text{per_area})
             \\
-            \textbf{resource_con}_\text{node,tech,timestep} = \textit{resource}_\text{node,tech,timestep} \times \textit{resource_scale}_\text{node,tech} \times \textbf{energy_cap}_\text{node,tech}&\quad
-            \text{if } (\textit{force_resource}_\text{node,tech}\mathord{=}\text{true})\land{}(\textit{resource_unit}_\text{node,tech}\mathord{=}\text{energy_per_cap})
+            \textbf{source_use}_\text{node,tech,timestep} = \textit{source_equals}_\text{node,tech} \times \textbf{flow_cap}_\text{node,tech}&\quad
+            \text{if } (\exists (\textit{source_equals}_\text{node,tech}))\land{}(\textit{source_unit}_\text{node,tech}\mathord{=}\text{per_cap})
             \\
-            \textbf{resource_con}_\text{node,tech,timestep} = \textit{resource}_\text{node,tech,timestep} \times \textit{resource_scale}_\text{node,tech}&\quad
-            \text{if } (\textit{force_resource}_\text{node,tech}\mathord{=}\text{true})\land{}(\textit{resource_unit}_\text{node,tech}\mathord{=}\text{energy})
+            \textbf{source_use}_\text{node,tech,timestep} = \textit{source_equals}_\text{node,tech} \times 1&\quad
+            \text{if } (\exists (\textit{source_equals}_\text{node,tech}))\land{}(\textit{source_unit}_\text{node,tech}\mathord{=}\text{absolute})
             \\
-            \textbf{resource_con}_\text{node,tech,timestep} \leq \textit{resource}_\text{node,tech,timestep} \times \textit{resource_scale}_\text{node,tech} \times \textbf{resource_area}_\text{node,tech}&\quad
-            \text{if } (\neg (\textit{force_resource}_\text{node,tech}\mathord{=}\text{true}))\land{}(\textit{resource_unit}_\text{node,tech}\mathord{=}\text{energy_per_area})
+            \textbf{source_use}_\text{node,tech,timestep} \leq \textit{source_max}_\text{node,tech} \times \textbf{area_use}_\text{node,tech}&\quad
+            \text{if } (\neg (\exists (\textit{source_equals}_\text{node,tech})) \land \exists (\textit{source_max}_\text{node,tech}))\land{}(\textit{source_unit}_\text{node,tech}\mathord{=}\text{per_area})
             \\
-            \textbf{resource_con}_\text{node,tech,timestep} \leq \textit{resource}_\text{node,tech,timestep} \times \textit{resource_scale}_\text{node,tech} \times \textbf{energy_cap}_\text{node,tech}&\quad
-            \text{if } (\neg (\textit{force_resource}_\text{node,tech}\mathord{=}\text{true}))\land{}(\textit{resource_unit}_\text{node,tech}\mathord{=}\text{energy_per_cap})
+            \textbf{source_use}_\text{node,tech,timestep} \leq \textit{source_max}_\text{node,tech} \times \textbf{flow_cap}_\text{node,tech}&\quad
+            \text{if } (\neg (\exists (\textit{source_equals}_\text{node,tech})) \land \exists (\textit{source_max}_\text{node,tech}))\land{}(\textit{source_unit}_\text{node,tech}\mathord{=}\text{per_cap})
             \\
-            \textbf{resource_con}_\text{node,tech,timestep} \leq \textit{resource}_\text{node,tech,timestep} \times \textit{resource_scale}_\text{node,tech}&\quad
-            \text{if } (\neg (\textit{force_resource}_\text{node,tech}\mathord{=}\text{true}))\land{}(\textit{resource_unit}_\text{node,tech}\mathord{=}\text{energy})
+            \textbf{source_use}_\text{node,tech,timestep} \leq \textit{source_max}_\text{node,tech} \times 1&\quad
+            \text{if } (\neg (\exists (\textit{source_equals}_\text{node,tech})) \land \exists (\textit{source_max}_\text{node,tech}))\land{}(\textit{source_unit}_\text{node,tech}\mathord{=}\text{absolute})
             \\
         \end{cases}
 
 balance_storage
 ^^^^^^^^^^^^^^^
 
-Fix the quantity of energy stored in a `storage` technology at the end of each timestep based on the net flow of energy charged and discharged and the quantity of energy stored at the start of the timestep.
+Fix the quantity of carrier stored in a `storage` technology at the end of each timestep based on the net flow of carrier charged and discharged and the quantity of carrier stored at the start of the timestep.
 
 .. container:: scrolling-wrapper
 
@@ -719,30 +756,30 @@ Fix the quantity of energy stored in a `storage` technology at the end of each t
             \text{if } (\text{tech_group=storage})
         \end{array}
         \begin{cases}
-            \textbf{storage}_\text{node,tech,timestep} = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech} - \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{energy_eff}_\text{node,tech,timestep} } - (\textbf{carrier_con}_\text{node,tech,carrier,timestep} \times \textit{energy_eff}_\text{node,tech,timestep})&\quad
-            \text{if } (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true}))\land{}(\textit{energy_eff}_\text{node,tech,timestep}\mathord{>}\text{0})
+            \textbf{storage}_\text{node,tech,timestep} = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech} - \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{flow_eff}_\text{node,tech} } + (\textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech})&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{>}\text{0})\land{}(\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true}))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech} - (\textbf{carrier_con}_\text{node,tech,carrier,timestep} \times \textit{energy_eff}_\text{node,tech,timestep})&\quad
-            \text{if } (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true}))\land{}(\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0})
+            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech})^{\textit{timestep_resolution}_\text{timestep-1}}) \times \textbf{storage}_\text{node,tech,timestep-1} - \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{flow_eff}_\text{node,tech} } + (\textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech})&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{>}\text{0})\land{}(((\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \text{config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]})) \land \neg (\textit{lookup_cluster_first_timestep}\mathord{=}\text{true}))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech,timestep})^{\textit{timestep_resolution}_\text{timestep-1}}) \times \textbf{storage}_\text{node,tech,timestep-1} - \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{energy_eff}_\text{node,tech,timestep} } - (\textbf{carrier_con}_\text{node,tech,carrier,timestep} \times \textit{energy_eff}_\text{node,tech,timestep})&\quad
-            \text{if } (((\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \text{run_config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]})) \land \neg (\textit{lookup_cluster_first_timestep}\mathord{=}\text{true}))\land{}(\textit{energy_eff}_\text{node,tech,timestep}\mathord{>}\text{0})
+            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech})^{\textit{timestep_resolution}_\text{timestep=lookup_cluster_last_timestep[timestep]}}) \times \textbf{storage}_\text{node,tech,timestep=lookup_cluster_last_timestep[timestep]} - \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{flow_eff}_\text{node,tech} } + (\textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech})&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{>}\text{0})\land{}(\textit{lookup_cluster_first_timestep}\mathord{=}\text{true} \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true})))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech,timestep})^{\textit{timestep_resolution}_\text{timestep-1}}) \times \textbf{storage}_\text{node,tech,timestep-1} - (\textbf{carrier_con}_\text{node,tech,carrier,timestep} \times \textit{energy_eff}_\text{node,tech,timestep})&\quad
-            \text{if } (((\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \text{run_config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]})) \land \neg (\textit{lookup_cluster_first_timestep}\mathord{=}\text{true}))\land{}(\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0})
+            \textbf{storage}_\text{node,tech,timestep} = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech} + (\textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech})&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0})\land{}(\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true}))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech,timestep})^{\textit{timestep_resolution}_\text{timestep=lookup_cluster_last_timestep[timestep]}}) \times \textbf{storage}_\text{node,tech,timestep=lookup_cluster_last_timestep[timestep]} - \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{energy_eff}_\text{node,tech,timestep} } - (\textbf{carrier_con}_\text{node,tech,carrier,timestep} \times \textit{energy_eff}_\text{node,tech,timestep})&\quad
-            \text{if } (\textit{lookup_cluster_first_timestep}\mathord{=}\text{true} \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true})))\land{}(\textit{energy_eff}_\text{node,tech,timestep}\mathord{>}\text{0})
+            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech})^{\textit{timestep_resolution}_\text{timestep-1}}) \times \textbf{storage}_\text{node,tech,timestep-1} + (\textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech})&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0})\land{}(((\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \text{config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]})) \land \neg (\textit{lookup_cluster_first_timestep}\mathord{=}\text{true}))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech,timestep})^{\textit{timestep_resolution}_\text{timestep=lookup_cluster_last_timestep[timestep]}}) \times \textbf{storage}_\text{node,tech,timestep=lookup_cluster_last_timestep[timestep]} - (\textbf{carrier_con}_\text{node,tech,carrier,timestep} \times \textit{energy_eff}_\text{node,tech,timestep})&\quad
-            \text{if } (\textit{lookup_cluster_first_timestep}\mathord{=}\text{true} \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true})))\land{}(\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0})
+            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech})^{\textit{timestep_resolution}_\text{timestep=lookup_cluster_last_timestep[timestep]}}) \times \textbf{storage}_\text{node,tech,timestep=lookup_cluster_last_timestep[timestep]} + (\textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech})&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0})\land{}(\textit{lookup_cluster_first_timestep}\mathord{=}\text{true} \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true})))
             \\
         \end{cases}
 
 set_storage_initial
 ^^^^^^^^^^^^^^^^^^^
 
-Fix the relationship between energy stored in a `storage` technology at the start and end of the whole model period.
+Fix the relationship between carrier stored in a `storage` technology at the start and end of the whole model period.
 
 .. container:: scrolling-wrapper
 
@@ -752,17 +789,17 @@ Fix the relationship between energy stored in a `storage` technology at the star
             \text{ node }\negthickspace \in \negthickspace\text{ nodes, }
             \text{ tech }\negthickspace \in \negthickspace\text{ techs }
             \\
-            \text{if } (\exists (\textbf{storage}_\text{node,tech,timestep}) \land \exists (\textit{storage_initial}_\text{node,tech}) \land \text{run_config.cyclic_storage}\mathord{=}\text{true})
+            \text{if } (\exists (\textbf{storage}_\text{node,tech,timestep}) \land \exists (\textit{storage_initial}_\text{node,tech}) \land \text{config.cyclic_storage}\mathord{=}\text{true})
         \end{array}
         \begin{cases}
-            \textbf{storage}_\text{node,tech,timestep=timesteps[-1]} \times ((1 - \textit{storage_loss}_\text{node,tech,timestep})^{\textit{timestep_resolution}_\text{timestep=timesteps[-1]}}) = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech}&\quad
+            \textbf{storage}_\text{node,tech,timestep=timesteps[-1]} \times ((1 - \textit{storage_loss}_\text{node,tech})^{\textit{timestep_resolution}_\text{timestep=timesteps[-1]}}) = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech}&\quad
             \\
         \end{cases}
 
 balance_transmission
 ^^^^^^^^^^^^^^^^^^^^
 
-Fix the relationship between between energy flowing into and out of a `transmission` link in each timestep.
+Fix the relationship between between carrier flowing into and out of a `transmission` link in each timestep.
 
 .. container:: scrolling-wrapper
 
@@ -774,17 +811,17 @@ Fix the relationship between between energy flowing into and out of a `transmiss
             \text{ carrier }\negthickspace \in \negthickspace\text{ carriers, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\text{tech_group=transmission} \land \textit{allowed_carrier_prod}_\text{node,tech}\mathord{=}\text{true})
+            \text{if } (\text{tech_group=transmission} \land \textit{allowed_flow_out}_\text{node,tech}\mathord{=}\text{true})
         \end{array}
         \begin{cases}
-            \textbf{carrier_prod}_\text{node,tech,carrier,timestep} = -1 \times \textbf{carrier_con}_\text{node=link_remote_nodes[node],tech=link_remote_techs[tech],carrier,timestep} \times \textit{energy_eff}_\text{node,tech,timestep}&\quad
+            \textbf{flow_out}_\text{node,tech,carrier,timestep} = \textbf{flow_in}_\text{node=link_remote_nodes[node],tech=link_remote_techs[tech],carrier,timestep} \times \textit{flow_eff}_\text{node,tech}&\quad
             \\
         \end{cases}
 
 symmetric_transmission
 ^^^^^^^^^^^^^^^^^^^^^^
 
-Fix the energy capacity of two `transmission` technologies representing the same link in the system.
+Fix the flow capacity of two `transmission` technologies representing the same link in the system.
 
 .. container:: scrolling-wrapper
 
@@ -797,14 +834,14 @@ Fix the energy capacity of two `transmission` technologies representing the same
             \text{if } (\text{tech_group=transmission})
         \end{array}
         \begin{cases}
-            \textbf{energy_cap}_\text{node,tech} = \textbf{energy_cap}_\text{node=link_remote_nodes[node],tech=link_remote_techs[tech]}&\quad
+            \textbf{flow_cap}_\text{node,tech} = \textbf{flow_cap}_\text{node=link_remote_nodes[node],tech=link_remote_techs[tech]}&\quad
             \\
         \end{cases}
 
 export_balance
 ^^^^^^^^^^^^^^
 
-Set the lower bound of a technology's carrier production to a technology's carrier export, for any technologies that can export energy out of the system.
+Set the lower bound of a technology's outflow to a technology's carrier export, for any technologies that can export carriers out of the system.
 
 .. container:: scrolling-wrapper
 
@@ -819,14 +856,14 @@ Set the lower bound of a technology's carrier production to a technology's carri
             \text{if } (\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \textit{export}_\text{node,tech}\mathord{=}\text{true})
         \end{array}
         \begin{cases}
-            \textbf{carrier_prod}_\text{node,tech,carrier,timestep} \geq \textbf{carrier_export}_\text{node,tech,carrier,timestep}&\quad
+            \textbf{flow_out}_\text{node,tech,carrier,timestep} \geq \textbf{flow_export}_\text{node,tech,carrier,timestep}&\quad
             \\
         \end{cases}
 
-carrier_export_max
-^^^^^^^^^^^^^^^^^^
+flow_export_max
+^^^^^^^^^^^^^^^
 
-Set the upper bound of a technology's carrier export, for any technologies that can export energy out of the system.
+Set the upper bound of a technology's carrier export, for any technologies that can export carriers out of the system.
 
 .. container:: scrolling-wrapper
 
@@ -838,13 +875,13 @@ Set the upper bound of a technology's carrier export, for any technologies that
             \text{ carrier }\negthickspace \in \negthickspace\text{ carriers, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\exists (\textbf{carrier_export}_\text{node,tech,carrier,timestep}) \land \exists (\textit{export_max}_\text{node,tech}))
+            \text{if } (\exists (\textbf{flow_export}_\text{node,tech,carrier,timestep}) \land \exists (\textit{export_max}_\text{node,tech}))
         \end{array}
         \begin{cases}
-            \textbf{carrier_export}_\text{node,tech,carrier,timestep} \leq \textit{export_max}_\text{node,tech} \times \textbf{operating_units}_\text{node,tech,timestep}&\quad
+            \textbf{flow_export}_\text{node,tech,carrier,timestep} \leq \textit{export_max}_\text{node,tech} \times \textbf{operating_units}_\text{node,tech,timestep}&\quad
             \text{if } (\textit{cap_method}_\text{node,tech}\mathord{=}\text{integer})
             \\
-            \textbf{carrier_export}_\text{node,tech,carrier,timestep} \leq \textit{export_max}_\text{node,tech}&\quad
+            \textbf{flow_export}_\text{node,tech,carrier,timestep} \leq \textit{export_max}_\text{node,tech}&\quad
             \text{if } (\neg (\textit{cap_method}_\text{node,tech}\mathord{=}\text{integer}))
             \\
         \end{cases}
@@ -870,10 +907,10 @@ Set the upper bound of the number of integer units of technology that can exist,
             \\
         \end{cases}
 
-carrier_production_max_milp
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
+flow_out_max_milp
+^^^^^^^^^^^^^^^^^
 
-Set the upper bound of a non-`conversion_plus` technology's ability to produce energy, for any technology using integer units to define its capacity.
+Set the upper bound of a non-`conversion_plus` technology's ability to produce carriers, for any technology using integer units to define its capacity.
 
 .. container:: scrolling-wrapper
 
@@ -885,17 +922,17 @@ Set the upper bound of a non-`conversion_plus` technology's ability to produce e
             \text{ carrier }\negthickspace \in \negthickspace\text{ carriers, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\exists (\textbf{operating_units}_\text{node,tech,timestep}) \land \exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \neg (\text{tech_group=conversion_plus}) \land \textit{allowed_carrier_prod}_\text{node,tech}\mathord{=}\text{true})
+            \text{if } (\exists (\textbf{operating_units}_\text{node,tech,timestep}) \land \exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \neg (\text{tech_group=conversion_plus}) \land \textit{allowed_flow_out}_\text{node,tech}\mathord{=}\text{true})
         \end{array}
         \begin{cases}
-            \textbf{carrier_prod}_\text{node,tech,carrier,timestep} \leq \textbf{operating_units}_\text{node,tech,timestep} \times \textit{timestep_resolution}_\text{timestep} \times \textit{energy_cap_per_unit}_\text{node,tech} \times \textit{parasitic_eff}_\text{node,tech,timestep}&\quad
+            \textbf{flow_out}_\text{node,tech,carrier,timestep} \leq \textbf{operating_units}_\text{node,tech,timestep} \times \textit{timestep_resolution}_\text{timestep} \times \textit{flow_cap_per_unit}_\text{node,tech} \times \textit{parasitic_eff}_\text{node,tech}&\quad
             \\
         \end{cases}
 
-carrier_production_max_conversion_plus_milp
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+flow_out_max_conversion_plus_milp
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Set the upper bound of a `conversion_plus` technology's ability to produce energy across all of its `out` energy carriers, if it uses integer units to define its capacity.
+Set the upper bound of a `conversion_plus` technology's ability to outflow across all of its `out` carriers, if it uses integer units to define its capacity.
 
 .. container:: scrolling-wrapper
 
@@ -906,17 +943,17 @@ Set the upper bound of a `conversion_plus` technology's ability to produce energ
             \text{ tech }\negthickspace \in \negthickspace\text{ techs, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\exists (\textbf{operating_units}_\text{node,tech,timestep}) \land \text{tech_group=conversion_plus} \land \textit{allowed_carrier_prod}_\text{node,tech}\mathord{=}\text{true})
+            \text{if } (\exists (\textbf{operating_units}_\text{node,tech,timestep}) \land \text{tech_group=conversion_plus} \land \textit{allowed_flow_out}_\text{node,tech}\mathord{=}\text{true})
         \end{array}
         \begin{cases}
-            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) \leq \textbf{operating_units}_\text{node,tech,timestep} \times \textit{timestep_resolution}_\text{timestep} \times \textit{energy_cap_per_unit}_\text{node,tech}&\quad
+            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) \leq \textbf{operating_units}_\text{node,tech,timestep} \times \textit{timestep_resolution}_\text{timestep} \times \textit{flow_cap_per_unit}_\text{node,tech}&\quad
             \\
         \end{cases}
 
-carrier_consumption_max_milp
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+flow_in_max_milp
+^^^^^^^^^^^^^^^^
 
-Set the upper bound of a non-`conversion_plus` technology's ability to consume energy, for any technology using integer units to define its capacity.
+Set the upper bound of a non-`conversion_plus` technology's ability to consume carriers, for any technology using integer units to define its capacity.
 
 .. container:: scrolling-wrapper
 
@@ -928,17 +965,17 @@ Set the upper bound of a non-`conversion_plus` technology's ability to consume e
             \text{ carrier }\negthickspace \in \negthickspace\text{ carriers, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\exists (\textbf{operating_units}_\text{node,tech,timestep}) \land \neg (\text{tech_group=conversion_plus}) \land \textit{allowed_carrier_con}_\text{node,tech}\mathord{=}\text{true})
+            \text{if } (\exists (\textbf{operating_units}_\text{node,tech,timestep}) \land \neg (\text{tech_group=conversion_plus}) \land \textit{allowed_flow_in}_\text{node,tech}\mathord{=}\text{true})
         \end{array}
         \begin{cases}
-            \textbf{carrier_con}_\text{node,tech,carrier,timestep} \geq -1 \times \textbf{operating_units}_\text{node,tech,timestep} \times \textit{timestep_resolution}_\text{timestep} \times \textit{energy_cap_per_unit}_\text{node,tech}&\quad
+            \textbf{flow_in}_\text{node,tech,carrier,timestep} \leq \textbf{operating_units}_\text{node,tech,timestep} \times \textit{timestep_resolution}_\text{timestep} \times \textit{flow_cap_per_unit}_\text{node,tech}&\quad
             \\
         \end{cases}
 
-carrier_production_min_milp
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
+flow_out_min_milp
+^^^^^^^^^^^^^^^^^
 
-Set the lower bound of a non-`conversion_plus` technology's ability to produce energy, for any technology using integer units to define its capacity.
+Set the lower bound of a non-`conversion_plus` technology's ability to produce carriers, for any technology using integer units to define its capacity.
 
 .. container:: scrolling-wrapper
 
@@ -950,17 +987,17 @@ Set the lower bound of a non-`conversion_plus` technology's ability to produce e
             \text{ carrier }\negthickspace \in \negthickspace\text{ carriers, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\exists (\textbf{operating_units}_\text{node,tech,timestep}) \land \exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \exists (\textit{energy_cap_min_use}_\text{node,tech}) \land \neg (\text{tech_group=conversion_plus}) \land \textit{allowed_carrier_prod}_\text{node,tech}\mathord{=}\text{true})
+            \text{if } (\exists (\textbf{operating_units}_\text{node,tech,timestep}) \land \exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \exists (\textit{flow_out_min_relative}_\text{node,tech}) \land \neg (\text{tech_group=conversion_plus}) \land \textit{allowed_flow_out}_\text{node,tech}\mathord{=}\text{true})
         \end{array}
         \begin{cases}
-            \textbf{carrier_prod}_\text{node,tech,carrier,timestep} \geq \textbf{operating_units}_\text{node,tech,timestep} \times \textit{timestep_resolution}_\text{timestep} \times \textit{energy_cap_per_unit}_\text{node,tech} \times \textit{energy_cap_min_use}_\text{node,tech}&\quad
+            \textbf{flow_out}_\text{node,tech,carrier,timestep} \geq \textbf{operating_units}_\text{node,tech,timestep} \times \textit{timestep_resolution}_\text{timestep} \times \textit{flow_cap_per_unit}_\text{node,tech} \times \textit{flow_out_min_relative}_\text{node,tech}&\quad
             \\
         \end{cases}
 
-carrier_production_min_conversion_plus_milp
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+flow_out_min_conversion_plus_milp
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Set the lower bound of a `conversion_plus` technology's ability to produce energy across all of its `out` energy carriers, if it uses integer units to define its capacity.
+Set the lower bound of a `conversion_plus` technology's ability to outflow across all of its `out` carriers, if it uses integer units to define its capacity.
 
 .. container:: scrolling-wrapper
 
@@ -971,10 +1008,10 @@ Set the lower bound of a `conversion_plus` technology's ability to produce energ
             \text{ tech }\negthickspace \in \negthickspace\text{ techs, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\exists (\textbf{operating_units}_\text{node,tech,timestep}) \land \exists (\textit{energy_cap_min_use}_\text{node,tech}) \land \text{tech_group=conversion_plus} \land \textit{allowed_carrier_prod}_\text{node,tech}\mathord{=}\text{true})
+            \text{if } (\exists (\textbf{operating_units}_\text{node,tech,timestep}) \land \exists (\textit{flow_out_min_relative}_\text{node,tech}) \land \text{tech_group=conversion_plus} \land \textit{allowed_flow_out}_\text{node,tech}\mathord{=}\text{true})
         \end{array}
         \begin{cases}
-            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) \geq \textbf{operating_units}_\text{node,tech,timestep} \times \textit{timestep_resolution}_\text{timestep} \times \textit{energy_cap_per_unit}_\text{node,tech} \times \textit{energy_cap_min_use}_\text{node,tech}&\quad
+            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) \geq \textbf{operating_units}_\text{node,tech,timestep} \times \textit{timestep_resolution}_\text{timestep} \times \textit{flow_cap_per_unit}_\text{node,tech} \times \textit{flow_out_min_relative}_\text{node,tech}&\quad
             \\
         \end{cases}
 
@@ -998,10 +1035,10 @@ Fix the storage capacity of any technology using integer units to define its cap
             \\
         \end{cases}
 
-energy_capacity_units_milp
-^^^^^^^^^^^^^^^^^^^^^^^^^^
+flow_capacity_units_milp
+^^^^^^^^^^^^^^^^^^^^^^^^
 
-Fix the energy capacity of any technology using integer units to define its capacity.
+Fix the flow capacity of any technology using integer units to define its capacity.
 
 .. container:: scrolling-wrapper
 
@@ -1011,17 +1048,17 @@ Fix the energy capacity of any technology using integer units to define its capa
             \text{ node }\negthickspace \in \negthickspace\text{ nodes, }
             \text{ tech }\negthickspace \in \negthickspace\text{ techs }
             \\
-            \text{if } (\exists (\textbf{operating_units}_\text{node,tech,timestep}) \land \exists (\textit{energy_cap_per_unit}_\text{node,tech}))
+            \text{if } (\exists (\textbf{operating_units}_\text{node,tech,timestep}) \land \exists (\textit{flow_cap_per_unit}_\text{node,tech}))
         \end{array}
         \begin{cases}
-            \textbf{energy_cap}_\text{node,tech} = \textbf{units}_\text{node,tech} \times \textit{energy_cap_per_unit}_\text{node,tech}&\quad
+            \textbf{flow_cap}_\text{node,tech} = \textbf{units}_\text{node,tech} \times \textit{flow_cap_per_unit}_\text{node,tech}&\quad
             \\
         \end{cases}
 
-energy_capacity_max_purchase_milp
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+flow_capacity_max_purchase_milp
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Set the upper bound on, or a fixed total of, a technology's energy capacity, for any technology with binary capacity purchasing.
+Set the upper bound on, or a fixed total of, a technology's flow capacity, for any technology with binary capacity purchasing.
 
 .. container:: scrolling-wrapper
 
@@ -1031,21 +1068,17 @@ Set the upper bound on, or a fixed total of, a technology's energy capacity, for
             \text{ node }\negthickspace \in \negthickspace\text{ nodes, }
             \text{ tech }\negthickspace \in \negthickspace\text{ techs }
             \\
-            \text{if } (\exists (\textbf{purchased}_\text{node,tech}) \land (\exists (\textit{energy_cap_max}_\text{node,tech}) \lor \exists (\textit{energy_cap_equals}_\text{node,tech})))
+            \text{if } (\exists (\textbf{purchased}_\text{node,tech}) \land \exists (\textit{flow_cap_max}_\text{node,tech}))
         \end{array}
         \begin{cases}
-            \textbf{energy_cap}_\text{node,tech} = \textit{energy_cap_equals}_\text{node,tech} \times \textit{energy_cap_scale}_\text{node,tech} \times \textbf{purchased}_\text{node,tech}&\quad
-            \text{if } (\exists (\textit{energy_cap_equals}_\text{node,tech}))
-            \\
-            \textbf{energy_cap}_\text{node,tech} \leq \textit{energy_cap_max}_\text{node,tech} \times \textit{energy_cap_scale}_\text{node,tech} \times \textbf{purchased}_\text{node,tech}&\quad
-            \text{if } (\neg (\exists (\textit{energy_cap_equals}_\text{node,tech})))
+            \textbf{flow_cap}_\text{node,tech} \leq \textit{flow_cap_max}_\text{node,tech} \times \textbf{purchased}_\text{node,tech}&\quad
             \\
         \end{cases}
 
-energy_capacity_min_purchase_milp
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+flow_capacity_min_purchase_milp
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Set the lower bound on a technology's energy capacity, for any technology with binary capacity purchasing.
+Set the lower bound on a technology's flow capacity, for any technology with binary capacity purchasing.
 
 .. container:: scrolling-wrapper
 
@@ -1055,10 +1088,10 @@ Set the lower bound on a technology's energy capacity, for any technology with b
             \text{ node }\negthickspace \in \negthickspace\text{ nodes, }
             \text{ tech }\negthickspace \in \negthickspace\text{ techs }
             \\
-            \text{if } (\exists (\textbf{purchased}_\text{node,tech}) \land \exists (\textit{energy_cap_min}_\text{node,tech}) \land \neg (\exists (\textit{energy_cap_equals}_\text{node,tech})))
+            \text{if } (\exists (\textbf{purchased}_\text{node,tech}) \land \exists (\textit{flow_cap_min}_\text{node,tech}) \land \neg (\exists (\textit{flow_cap_equals})))
         \end{array}
         \begin{cases}
-            \textbf{energy_cap}_\text{node,tech} \geq \textit{energy_cap_min}_\text{node,tech} \times \textit{energy_cap_scale}_\text{node,tech} \times \textbf{purchased}_\text{node,tech}&\quad
+            \textbf{flow_cap}_\text{node,tech} \geq \textit{flow_cap_min}_\text{node,tech} \times \textbf{purchased}_\text{node,tech}&\quad
             \\
         \end{cases}
 
@@ -1075,14 +1108,10 @@ Set the upper bound on, or a fixed total of, a technology's storage capacity, fo
             \text{ node }\negthickspace \in \negthickspace\text{ nodes, }
             \text{ tech }\negthickspace \in \negthickspace\text{ techs }
             \\
-            \text{if } (\exists (\textbf{purchased}_\text{node,tech}) \land (\exists (\textit{storage_cap_max}_\text{node,tech}) \lor \exists (\textit{storage_cap_equals}_\text{node,tech})))
+            \text{if } (\exists (\textbf{purchased}_\text{node,tech}) \land \exists (\textit{storage_cap_max}_\text{node,tech}))
         \end{array}
         \begin{cases}
-            \textbf{storage_cap}_\text{node,tech} = \textit{storage_cap_equals}_\text{node,tech} \times \textbf{purchased}_\text{node,tech}&\quad
-            \text{if } (\exists (\textit{storage_cap_equals}_\text{node,tech}))
-            \\
             \textbf{storage_cap}_\text{node,tech} \leq \textit{storage_cap_max}_\text{node,tech} \times \textbf{purchased}_\text{node,tech}&\quad
-            \text{if } (\neg (\exists (\textit{storage_cap_equals}_\text{node,tech})))
             \\
         \end{cases}
 
@@ -1099,17 +1128,17 @@ Set the lower bound on a technology's storage capacity, for any technology with
             \text{ node }\negthickspace \in \negthickspace\text{ nodes, }
             \text{ tech }\negthickspace \in \negthickspace\text{ techs }
             \\
-            \text{if } (\exists (\textbf{purchased}_\text{node,tech}) \land \exists (\textit{storage_cap_min}_\text{node,tech}) \land \neg (\exists (\textit{storage_cap_equals}_\text{node,tech})))
+            \text{if } (\exists (\textbf{purchased}_\text{node,tech}) \land \exists (\textit{storage_cap_min}_\text{node,tech}) \land \neg (\exists (\textit{storage_cap_equals})))
         \end{array}
         \begin{cases}
             \textbf{storage_cap}_\text{node,tech} \geq \textit{storage_cap_min}_\text{node,tech} \times \textbf{purchased}_\text{node,tech}&\quad
             \\
         \end{cases}
 
-unit_capacity_systemwide_milp
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+unit_capacity_max_systemwide_milp
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-Set the upper bound on, or a fixed total of, the total number of units of a technology that can be purchased across all nodes where the technology can exist, for any technology using integer units to define its capacity.
+Set the upper bound on the total number of units of a technology that can be purchased across all nodes where the technology can exist, for any technology using integer units to define its capacity.
 
 .. container:: scrolling-wrapper
 
@@ -1118,27 +1147,44 @@ Set the upper bound on, or a fixed total of, the total number of units of a tech
             \forall{}
             \text{ tech }\negthickspace \in \negthickspace\text{ techs }
             \\
-            \text{if } ((\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech})) \land (\exists (\textit{units_max_systemwide}_\text{tech}) \lor \exists (\textit{units_equals_systemwide}_\text{tech})))
+            \text{if } ((\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech})) \land \exists (\textit{units_max_systemwide}_\text{tech}))
         \end{array}
         \begin{cases}
-            \sum\limits_{\text{node} \in \text{nodes}} (\textbf{purchased}_\text{node,tech}) = \textit{units_equals_systemwide}_\text{tech}&\quad
-            \text{if } (\exists (\textit{units_equals_systemwide}_\text{tech}))\land{}(\exists (\textbf{purchased}_\text{node,tech}))
-            \\
-            \sum\limits_{\text{node} \in \text{nodes}} (\textbf{units}_\text{node,tech}) = \textit{units_equals_systemwide}_\text{tech}&\quad
-            \text{if } (\exists (\textit{units_equals_systemwide}_\text{tech}))\land{}(\exists (\textbf{units}_\text{node,tech}))
-            \\
             \sum\limits_{\text{node} \in \text{nodes}} (\textbf{purchased}_\text{node,tech}) \leq \textit{units_max_systemwide}_\text{tech}&\quad
-            \text{if } (\neg (\exists (\textit{units_equals_systemwide}_\text{tech})))\land{}(\exists (\textbf{purchased}_\text{node,tech}))
+            \text{if } (\exists (\textbf{purchased}_\text{node,tech}))
             \\
             \sum\limits_{\text{node} \in \text{nodes}} (\textbf{units}_\text{node,tech}) \leq \textit{units_max_systemwide}_\text{tech}&\quad
-            \text{if } (\neg (\exists (\textit{units_equals_systemwide}_\text{tech})))\land{}(\exists (\textbf{units}_\text{node,tech}))
+            \text{if } (\exists (\textbf{units}_\text{node,tech}))
+            \\
+        \end{cases}
+
+unit_capacity_min_systemwide_milp
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Set the lower bound on the total number of units of a technology that can be purchased across all nodes where the technology can exist, for any technology using integer units to define its capacity.
+
+.. container:: scrolling-wrapper
+
+    .. math::
+        \begin{array}{r}
+            \forall{}
+            \text{ tech }\negthickspace \in \negthickspace\text{ techs }
+            \\
+            \text{if } ((\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech})) \land \exists (\textit{units_min_systemwide}_\text{tech}))
+        \end{array}
+        \begin{cases}
+            \sum\limits_{\text{node} \in \text{nodes}} (\textbf{purchased}_\text{node,tech}) \geq \textit{units_min_systemwide}_\text{tech}&\quad
+            \text{if } (\exists (\textbf{purchased}_\text{node,tech}))
+            \\
+            \sum\limits_{\text{node} \in \text{nodes}} (\textbf{units}_\text{node,tech}) \geq \textit{units_min_systemwide}_\text{tech}&\quad
+            \text{if } (\exists (\textbf{units}_\text{node,tech}))
             \\
         \end{cases}
 
-asynchronous_con_milp
-^^^^^^^^^^^^^^^^^^^^^
+async_flow_in_milp
+^^^^^^^^^^^^^^^^^^
 
-Set a technology's ability to consume energy in the same timestep that it is producing energy, for any technology using the asynchronous production/consumption binary switch.
+Set a technology's ability to have inflow in the same timestep that it has outflow, for any technology using the asynchronous flow binary switch.
 
 .. container:: scrolling-wrapper
 
@@ -1149,17 +1195,17 @@ Set a technology's ability to consume energy in the same timestep that it is pro
             \text{ tech }\negthickspace \in \negthickspace\text{ techs, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\exists (\textbf{prod_con_switch}_\text{node,tech,timestep}))
+            \text{if } (\exists (\textbf{async_flow_switch}_\text{node,tech,timestep}))
         \end{array}
         \begin{cases}
-            -1 \times \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\textbf{carrier_con}_\text{node,tech,carrier,timestep}) \leq (1 - \textbf{prod_con_switch}_\text{node,tech,timestep}) \times \textit{bigM}&\quad
+            \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\textbf{flow_in}_\text{node,tech,carrier,timestep}) \leq (1 - \textbf{async_flow_switch}_\text{node,tech,timestep}) \times \textit{bigM}&\quad
             \\
         \end{cases}
 
-asynchronous_prod_milp
-^^^^^^^^^^^^^^^^^^^^^^
+async_flow_out_milp
+^^^^^^^^^^^^^^^^^^^
 
-Set a technology's ability to produce energy in the same timestep that it is consuming energy, for any technology using the asynchronous production/consumption binary switch.
+Set a technology's ability to have outflow in the same timestep that it has inflow, for any technology using the asynchronous flow binary switch.
 
 .. container:: scrolling-wrapper
 
@@ -1170,17 +1216,17 @@ Set a technology's ability to produce energy in the same timestep that it is con
             \text{ tech }\negthickspace \in \negthickspace\text{ techs, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\exists (\textbf{prod_con_switch}_\text{node,tech,timestep}))
+            \text{if } (\exists (\textbf{async_flow_switch}_\text{node,tech,timestep}))
         \end{array}
         \begin{cases}
-            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) \leq \textbf{prod_con_switch}_\text{node,tech,timestep} \times \textit{bigM}&\quad
+            \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) \leq \textbf{async_flow_switch}_\text{node,tech,timestep} \times \textit{bigM}&\quad
             \\
         \end{cases}
 
 ramping_up
 ^^^^^^^^^^
 
-Set the upper bound on a technology's ability to ramp energy production up beyond a certain percentage compared to the previous timestep.
+Set the upper bound on a technology's ability to ramp outflow up beyond a certain percentage compared to the previous timestep.
 
 .. container:: scrolling-wrapper
 
@@ -1192,24 +1238,24 @@ Set the upper bound on a technology's ability to ramp energy production up beyon
             \text{ carrier }\negthickspace \in \negthickspace\text{ carriers, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\exists (\textit{energy_ramping}_\text{node,tech,timestep}) \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]}))
+            \text{if } (\exists (\textit{flow_ramping}_\text{node,tech}) \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]}))
         \end{array}
         \begin{cases}
-            \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{timestep_resolution}_\text{timestep} } - \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep-1} }{ \textit{timestep_resolution}_\text{timestep-1} } \leq \textit{energy_ramping}_\text{node,tech,timestep} \times \textbf{energy_cap}_\text{node,tech}&\quad
-            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \textit{allowed_carrier_prod}_\text{node,tech}\mathord{=}\text{true} \land \neg (\textit{allowed_carrier_con}_\text{node,tech}\mathord{=}\text{true}))
+            \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{timestep_resolution}_\text{timestep} } - \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep-1} }{ \textit{timestep_resolution}_\text{timestep-1} } \leq \textit{flow_ramping}_\text{node,tech} \times \textbf{flow_cap}_\text{node,tech}&\quad
+            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \textit{allowed_flow_out}_\text{node,tech}\mathord{=}\text{true} \land \neg (\textit{allowed_flow_in}_\text{node,tech}\mathord{=}\text{true}))
             \\
-            \frac{ \textbf{carrier_con}_\text{node,tech,carrier,timestep} }{ \textit{timestep_resolution}_\text{timestep} } - \frac{ \textbf{carrier_con}_\text{node,tech,carrier,timestep-1} }{ \textit{timestep_resolution}_\text{timestep-1} } \leq \textit{energy_ramping}_\text{node,tech,timestep} \times \textbf{energy_cap}_\text{node,tech}&\quad
-            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \textit{allowed_carrier_con}_\text{node,tech}\mathord{=}\text{true} \land \neg (\textit{allowed_carrier_prod}_\text{node,tech}\mathord{=}\text{true}))
+            \frac{ \textbf{flow_in}_\text{node,tech,carrier,timestep} }{ \textit{timestep_resolution}_\text{timestep} } - \frac{ \textbf{flow_in}_\text{node,tech,carrier,timestep-1} }{ \textit{timestep_resolution}_\text{timestep-1} } \leq \textit{flow_ramping}_\text{node,tech} \times \textbf{flow_cap}_\text{node,tech}&\quad
+            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \textit{allowed_flow_in}_\text{node,tech}\mathord{=}\text{true} \land \neg (\textit{allowed_flow_out}_\text{node,tech}\mathord{=}\text{true}))
             \\
-            \frac{ (\textbf{carrier_con}_\text{node,tech,carrier,timestep} + \textbf{carrier_prod}_\text{node,tech,carrier,timestep}) }{ \textit{timestep_resolution}_\text{timestep} } - \frac{ (\textbf{carrier_con}_\text{node,tech,carrier,timestep-1} + \textbf{carrier_prod}_\text{node,tech,carrier,timestep-1}) }{ \textit{timestep_resolution}_\text{timestep-1} } \leq \textit{energy_ramping}_\text{node,tech,timestep} \times \textbf{energy_cap}_\text{node,tech}&\quad
-            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \textit{allowed_carrier_con}_\text{node,tech}\mathord{=}\text{true} \land \textit{allowed_carrier_prod}_\text{node,tech}\mathord{=}\text{true})
+            \frac{ (\textbf{flow_out}_\text{node,tech,carrier,timestep} - \textbf{flow_in}_\text{node,tech,carrier,timestep}) }{ \textit{timestep_resolution}_\text{timestep} } - \frac{ (\textbf{flow_out}_\text{node,tech,carrier,timestep-1} - \textbf{flow_in}_\text{node,tech,carrier,timestep-1}) }{ \textit{timestep_resolution}_\text{timestep-1} } \leq \textit{flow_ramping}_\text{node,tech} \times \textbf{flow_cap}_\text{node,tech}&\quad
+            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \textit{allowed_flow_in}_\text{node,tech}\mathord{=}\text{true} \land \textit{allowed_flow_out}_\text{node,tech}\mathord{=}\text{true})
             \\
         \end{cases}
 
 ramping_down
 ^^^^^^^^^^^^
 
-Set the upper bound on a technology's ability to ramp energy production down beyond a certain percentage compared to the previous timestep.
+Set the upper bound on a technology's ability to ramp outflow down beyond a certain percentage compared to the previous timestep.
 
 .. container:: scrolling-wrapper
 
@@ -1221,17 +1267,17 @@ Set the upper bound on a technology's ability to ramp energy production down bey
             \text{ carrier }\negthickspace \in \negthickspace\text{ carriers, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\exists (\textit{energy_ramping}_\text{node,tech,timestep}) \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]}))
+            \text{if } (\exists (\textit{flow_ramping}_\text{node,tech}) \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]}))
         \end{array}
         \begin{cases}
-            -1 \times \textit{energy_ramping}_\text{node,tech,timestep} \times \textbf{energy_cap}_\text{node,tech} \leq \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{timestep_resolution}_\text{timestep} } - \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep-1} }{ \textit{timestep_resolution}_\text{timestep-1} }&\quad
-            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \textit{allowed_carrier_prod}_\text{node,tech}\mathord{=}\text{true} \land \neg (\textit{allowed_carrier_con}_\text{node,tech}\mathord{=}\text{true}))
+            -1 \times \textit{flow_ramping}_\text{node,tech} \times \textbf{flow_cap}_\text{node,tech} \leq \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{timestep_resolution}_\text{timestep} } - \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep-1} }{ \textit{timestep_resolution}_\text{timestep-1} }&\quad
+            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \textit{allowed_flow_out}_\text{node,tech}\mathord{=}\text{true} \land \neg (\textit{allowed_flow_in}_\text{node,tech}\mathord{=}\text{true}))
             \\
-            -1 \times \textit{energy_ramping}_\text{node,tech,timestep} \times \textbf{energy_cap}_\text{node,tech} \leq \frac{ \textbf{carrier_con}_\text{node,tech,carrier,timestep} }{ \textit{timestep_resolution}_\text{timestep} } - \frac{ \textbf{carrier_con}_\text{node,tech,carrier,timestep-1} }{ \textit{timestep_resolution}_\text{timestep-1} }&\quad
-            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \textit{allowed_carrier_con}_\text{node,tech}\mathord{=}\text{true} \land \neg (\textit{allowed_carrier_prod}_\text{node,tech}\mathord{=}\text{true}))
+            -1 \times \textit{flow_ramping}_\text{node,tech} \times \textbf{flow_cap}_\text{node,tech} \leq \frac{ \textbf{flow_in}_\text{node,tech,carrier,timestep} }{ \textit{timestep_resolution}_\text{timestep} } - \frac{ \textbf{flow_in}_\text{node,tech,carrier,timestep-1} }{ \textit{timestep_resolution}_\text{timestep-1} }&\quad
+            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \textit{allowed_flow_in}_\text{node,tech}\mathord{=}\text{true} \land \neg (\textit{allowed_flow_out}_\text{node,tech}\mathord{=}\text{true}))
             \\
-            -1 \times \textit{energy_ramping}_\text{node,tech,timestep} \times \textbf{energy_cap}_\text{node,tech} \leq \frac{ (\textbf{carrier_con}_\text{node,tech,carrier,timestep} + \textbf{carrier_prod}_\text{node,tech,carrier,timestep}) }{ \textit{timestep_resolution}_\text{timestep} } - \frac{ (\textbf{carrier_con}_\text{node,tech,carrier,timestep-1} + \textbf{carrier_prod}_\text{node,tech,carrier,timestep-1}) }{ \textit{timestep_resolution}_\text{timestep-1} }&\quad
-            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \textit{allowed_carrier_con}_\text{node,tech}\mathord{=}\text{true} \land \textit{allowed_carrier_prod}_\text{node,tech}\mathord{=}\text{true})
+            -1 \times \textit{flow_ramping}_\text{node,tech} \times \textbf{flow_cap}_\text{node,tech} \leq \frac{ (\textbf{flow_out}_\text{node,tech,carrier,timestep} - \textbf{flow_in}_\text{node,tech,carrier,timestep}) }{ \textit{timestep_resolution}_\text{timestep} } - \frac{ (\textbf{flow_out}_\text{node,tech,carrier,timestep-1} - \textbf{flow_in}_\text{node,tech,carrier,timestep-1}) }{ \textit{timestep_resolution}_\text{timestep-1} }&\quad
+            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \textit{allowed_flow_in}_\text{node,tech}\mathord{=}\text{true} \land \textit{allowed_flow_out}_\text{node,tech}\mathord{=}\text{true})
             \\
         \end{cases}
 
@@ -1253,98 +1299,98 @@ The operating costs per timestep of a technology
             \text{ cost }\negthickspace \in \negthickspace\text{ costs, }
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
-            \text{if } (\exists (\textit{cost_export}_\text{node,tech,cost,timestep}) \lor \exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \lor \exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}))
+            \text{if } (\exists (\textit{cost_export}_\text{node,tech,cost}) \lor \exists (\textit{cost_om_con}_\text{node,tech,cost}) \lor \exists (\textit{cost_om_prod}_\text{node,tech,cost}))
         \end{array}
         \begin{cases}
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{carrier_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost,timestep} \times \textbf{resource_con}_\text{node,tech,timestep})&\quad
-            \text{if } (\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost,timestep}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \text{tech_group=supply_plus})\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \text{tech_group=conversion_plus})
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{flow_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost} \times \textbf{source_use}_\text{node,tech,timestep})&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \text{tech_group=conversion_plus})\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \text{tech_group=supply_plus})\land{}(\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost}))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{carrier_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost,timestep} \times \textbf{resource_con}_\text{node,tech,timestep})&\quad
-            \text{if } (\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost,timestep}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \text{tech_group=supply_plus})\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \neg (\text{tech_group=conversion_plus}))
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost} \times \textbf{source_use}_\text{node,tech,timestep})&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \text{tech_group=conversion_plus})\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \text{tech_group=supply_plus})\land{}(\neg (\exists (\textit{cost_export}_\text{node,tech,cost})))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{carrier_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost,timestep} \times \textbf{resource_con}_\text{node,tech,timestep})&\quad
-            \text{if } (\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost,timestep}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \text{tech_group=supply_plus})\land{}(\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep})))
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{flow_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) + \frac{ \textit{cost_om_con}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) }{ \textit{flow_eff}_\text{node,tech} })&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \text{tech_group=conversion_plus})\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \text{tech_group=supply} \land \textit{flow_eff}_\text{node,tech}\mathord{>}\text{0} \land \text{carrier_tier} \in \text{[out]})\land{}(\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost}))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{carrier_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \frac{ \textit{cost_om_con}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) }{ \textit{energy_eff}_\text{node,tech,timestep} })&\quad
-            \text{if } (\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost,timestep}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \text{tech_group=supply} \land \textit{energy_eff}_\text{node,tech,timestep}\mathord{>}\text{0} \land \text{carrier_tier} \in \text{[out]})\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \text{tech_group=conversion_plus})
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) + \frac{ \textit{cost_om_con}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) }{ \textit{flow_eff}_\text{node,tech} })&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \text{tech_group=conversion_plus})\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \text{tech_group=supply} \land \textit{flow_eff}_\text{node,tech}\mathord{>}\text{0} \land \text{carrier_tier} \in \text{[out]})\land{}(\neg (\exists (\textit{cost_export}_\text{node,tech,cost})))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{carrier_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \frac{ \textit{cost_om_con}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) }{ \textit{energy_eff}_\text{node,tech,timestep} })&\quad
-            \text{if } (\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost,timestep}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \text{tech_group=supply} \land \textit{energy_eff}_\text{node,tech,timestep}\mathord{>}\text{0} \land \text{carrier_tier} \in \text{[out]})\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \neg (\text{tech_group=conversion_plus}))
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{flow_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost} \times \sum\limits_{\text{carrier=primary_carrier_in}} (\textbf{flow_in}_\text{node,tech,carrier,timestep}))&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \text{tech_group=conversion_plus})\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \text{tech_group=conversion_plus})\land{}(\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost}))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{carrier_export}_\text{node,tech,carrier,timestep}) + \frac{ \textit{cost_om_con}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) }{ \textit{energy_eff}_\text{node,tech,timestep} })&\quad
-            \text{if } (\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost,timestep}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \text{tech_group=supply} \land \textit{energy_eff}_\text{node,tech,timestep}\mathord{>}\text{0} \land \text{carrier_tier} \in \text{[out]})\land{}(\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep})))
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost} \times \sum\limits_{\text{carrier=primary_carrier_in}} (\textbf{flow_in}_\text{node,tech,carrier,timestep}))&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \text{tech_group=conversion_plus})\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \text{tech_group=conversion_plus})\land{}(\neg (\exists (\textit{cost_export}_\text{node,tech,cost})))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{carrier_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost,timestep} \times -1 \times \sum\limits_{\text{carrier=primary_carrier_in}} (\textbf{carrier_con}_\text{node,tech,carrier,timestep}))&\quad
-            \text{if } (\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost,timestep}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \text{tech_group=conversion_plus})\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \text{tech_group=conversion_plus})
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{flow_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\textbf{flow_in}_\text{node,tech,carrier,timestep}))&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \text{tech_group=conversion_plus})\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \neg (\text{tech_group=conversion_plus} \lor \text{tech_group=supply_plus} \lor \text{tech_group=supply}) \land \text{carrier_tier} \in \text{[in]})\land{}(\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost}))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{carrier_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost,timestep} \times -1 \times \sum\limits_{\text{carrier=primary_carrier_in}} (\textbf{carrier_con}_\text{node,tech,carrier,timestep}))&\quad
-            \text{if } (\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost,timestep}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \text{tech_group=conversion_plus})\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \neg (\text{tech_group=conversion_plus}))
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\textbf{flow_in}_\text{node,tech,carrier,timestep}))&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \text{tech_group=conversion_plus})\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \neg (\text{tech_group=conversion_plus} \lor \text{tech_group=supply_plus} \lor \text{tech_group=supply}) \land \text{carrier_tier} \in \text{[in]})\land{}(\neg (\exists (\textit{cost_export}_\text{node,tech,cost})))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{carrier_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost,timestep} \times -1 \times \sum\limits_{\text{carrier=primary_carrier_in}} (\textbf{carrier_con}_\text{node,tech,carrier,timestep}))&\quad
-            \text{if } (\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost,timestep}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \text{tech_group=conversion_plus})\land{}(\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep})))
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{flow_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}))&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \text{tech_group=conversion_plus})\land{}(\neg (\exists (\textit{cost_om_con}_\text{node,tech,cost})))\land{}(\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost}))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{carrier_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost,timestep} \times -1 \times \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\textbf{carrier_con}_\text{node,tech,carrier,timestep}))&\quad
-            \text{if } (\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost,timestep}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \neg (\text{tech_group=conversion_plus} \lor \text{tech_group=supply_plus} \lor \text{tech_group=supply}) \land \text{carrier_tier} \in \text{[in]})\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \text{tech_group=conversion_plus})
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}))&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \text{tech_group=conversion_plus})\land{}(\neg (\exists (\textit{cost_om_con}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_export}_\text{node,tech,cost})))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{carrier_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost,timestep} \times -1 \times \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\textbf{carrier_con}_\text{node,tech,carrier,timestep}))&\quad
-            \text{if } (\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost,timestep}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \neg (\text{tech_group=conversion_plus} \lor \text{tech_group=supply_plus} \lor \text{tech_group=supply}) \land \text{carrier_tier} \in \text{[in]})\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \neg (\text{tech_group=conversion_plus}))
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{flow_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost} \times \textbf{source_use}_\text{node,tech,timestep})&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \neg (\text{tech_group=conversion_plus}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \text{tech_group=supply_plus})\land{}(\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost}))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{carrier_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost,timestep} \times -1 \times \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\textbf{carrier_con}_\text{node,tech,carrier,timestep}))&\quad
-            \text{if } (\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost,timestep}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \neg (\text{tech_group=conversion_plus} \lor \text{tech_group=supply_plus} \lor \text{tech_group=supply}) \land \text{carrier_tier} \in \text{[in]})\land{}(\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep})))
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost} \times \textbf{source_use}_\text{node,tech,timestep})&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \neg (\text{tech_group=conversion_plus}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \text{tech_group=supply_plus})\land{}(\neg (\exists (\textit{cost_export}_\text{node,tech,cost})))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{carrier_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}))&\quad
-            \text{if } (\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost,timestep}))\land{}(\neg (\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep})))\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \text{tech_group=conversion_plus})
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{flow_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) + \frac{ \textit{cost_om_con}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) }{ \textit{flow_eff}_\text{node,tech} })&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \neg (\text{tech_group=conversion_plus}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \text{tech_group=supply} \land \textit{flow_eff}_\text{node,tech}\mathord{>}\text{0} \land \text{carrier_tier} \in \text{[out]})\land{}(\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost}))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{carrier_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}))&\quad
-            \text{if } (\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost,timestep}))\land{}(\neg (\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep})))\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \neg (\text{tech_group=conversion_plus}))
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) + \frac{ \textit{cost_om_con}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) }{ \textit{flow_eff}_\text{node,tech} })&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \neg (\text{tech_group=conversion_plus}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \text{tech_group=supply} \land \textit{flow_eff}_\text{node,tech}\mathord{>}\text{0} \land \text{carrier_tier} \in \text{[out]})\land{}(\neg (\exists (\textit{cost_export}_\text{node,tech,cost})))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{carrier_export}_\text{node,tech,carrier,timestep}))&\quad
-            \text{if } (\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost,timestep}))\land{}(\neg (\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep})))\land{}(\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep})))
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{flow_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost} \times \sum\limits_{\text{carrier=primary_carrier_in}} (\textbf{flow_in}_\text{node,tech,carrier,timestep}))&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \neg (\text{tech_group=conversion_plus}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \text{tech_group=conversion_plus})\land{}(\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost}))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost,timestep} \times \textbf{resource_con}_\text{node,tech,timestep})&\quad
-            \text{if } (\neg (\exists (\textit{cost_export}_\text{node,tech,cost,timestep})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \text{tech_group=supply_plus})\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \text{tech_group=conversion_plus})
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost} \times \sum\limits_{\text{carrier=primary_carrier_in}} (\textbf{flow_in}_\text{node,tech,carrier,timestep}))&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \neg (\text{tech_group=conversion_plus}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \text{tech_group=conversion_plus})\land{}(\neg (\exists (\textit{cost_export}_\text{node,tech,cost})))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost,timestep} \times \textbf{resource_con}_\text{node,tech,timestep})&\quad
-            \text{if } (\neg (\exists (\textit{cost_export}_\text{node,tech,cost,timestep})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \text{tech_group=supply_plus})\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \neg (\text{tech_group=conversion_plus}))
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{flow_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\textbf{flow_in}_\text{node,tech,carrier,timestep}))&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \neg (\text{tech_group=conversion_plus}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \neg (\text{tech_group=conversion_plus} \lor \text{tech_group=supply_plus} \lor \text{tech_group=supply}) \land \text{carrier_tier} \in \text{[in]})\land{}(\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost}))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_con}_\text{node,tech,cost,timestep} \times \textbf{resource_con}_\text{node,tech,timestep})&\quad
-            \text{if } (\neg (\exists (\textit{cost_export}_\text{node,tech,cost,timestep})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \text{tech_group=supply_plus})\land{}(\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep})))
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\textbf{flow_in}_\text{node,tech,carrier,timestep}))&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \neg (\text{tech_group=conversion_plus}))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \neg (\text{tech_group=conversion_plus} \lor \text{tech_group=supply_plus} \lor \text{tech_group=supply}) \land \text{carrier_tier} \in \text{[in]})\land{}(\neg (\exists (\textit{cost_export}_\text{node,tech,cost})))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \frac{ \textit{cost_om_con}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) }{ \textit{energy_eff}_\text{node,tech,timestep} })&\quad
-            \text{if } (\neg (\exists (\textit{cost_export}_\text{node,tech,cost,timestep})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \text{tech_group=supply} \land \textit{energy_eff}_\text{node,tech,timestep}\mathord{>}\text{0} \land \text{carrier_tier} \in \text{[out]})\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \text{tech_group=conversion_plus})
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{flow_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}))&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \neg (\text{tech_group=conversion_plus}))\land{}(\neg (\exists (\textit{cost_om_con}_\text{node,tech,cost})))\land{}(\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost}))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \frac{ \textit{cost_om_con}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) }{ \textit{energy_eff}_\text{node,tech,timestep} })&\quad
-            \text{if } (\neg (\exists (\textit{cost_export}_\text{node,tech,cost,timestep})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \text{tech_group=supply} \land \textit{energy_eff}_\text{node,tech,timestep}\mathord{>}\text{0} \land \text{carrier_tier} \in \text{[out]})\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \neg (\text{tech_group=conversion_plus}))
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}))&\quad
+            \text{if } (\exists (\textit{cost_om_prod}_\text{node,tech,cost}) \land \neg (\text{tech_group=conversion_plus}))\land{}(\neg (\exists (\textit{cost_om_con}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_export}_\text{node,tech,cost})))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\frac{ \textit{cost_om_con}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) }{ \textit{energy_eff}_\text{node,tech,timestep} })&\quad
-            \text{if } (\neg (\exists (\textit{cost_export}_\text{node,tech,cost,timestep})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \text{tech_group=supply} \land \textit{energy_eff}_\text{node,tech,timestep}\mathord{>}\text{0} \land \text{carrier_tier} \in \text{[out]})\land{}(\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep})))
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{flow_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost} \times \textbf{source_use}_\text{node,tech,timestep})&\quad
+            \text{if } (\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \text{tech_group=supply_plus})\land{}(\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost}))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost,timestep} \times -1 \times \sum\limits_{\text{carrier=primary_carrier_in}} (\textbf{carrier_con}_\text{node,tech,carrier,timestep}))&\quad
-            \text{if } (\neg (\exists (\textit{cost_export}_\text{node,tech,cost,timestep})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \text{tech_group=conversion_plus})\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \text{tech_group=conversion_plus})
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_con}_\text{node,tech,cost} \times \textbf{source_use}_\text{node,tech,timestep})&\quad
+            \text{if } (\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \text{tech_group=supply_plus})\land{}(\neg (\exists (\textit{cost_export}_\text{node,tech,cost})))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost,timestep} \times -1 \times \sum\limits_{\text{carrier=primary_carrier_in}} (\textbf{carrier_con}_\text{node,tech,carrier,timestep}))&\quad
-            \text{if } (\neg (\exists (\textit{cost_export}_\text{node,tech,cost,timestep})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \text{tech_group=conversion_plus})\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \neg (\text{tech_group=conversion_plus}))
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{flow_export}_\text{node,tech,carrier,timestep}) + \frac{ \textit{cost_om_con}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) }{ \textit{flow_eff}_\text{node,tech} })&\quad
+            \text{if } (\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \text{tech_group=supply} \land \textit{flow_eff}_\text{node,tech}\mathord{>}\text{0} \land \text{carrier_tier} \in \text{[out]})\land{}(\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost}))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_con}_\text{node,tech,cost,timestep} \times -1 \times \sum\limits_{\text{carrier=primary_carrier_in}} (\textbf{carrier_con}_\text{node,tech,carrier,timestep}))&\quad
-            \text{if } (\neg (\exists (\textit{cost_export}_\text{node,tech,cost,timestep})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \text{tech_group=conversion_plus})\land{}(\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep})))
+            \textit{timestep_weights}_\text{timestep} \times (\frac{ \textit{cost_om_con}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{flow_out}_\text{node,tech,carrier,timestep}) }{ \textit{flow_eff}_\text{node,tech} })&\quad
+            \text{if } (\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \text{tech_group=supply} \land \textit{flow_eff}_\text{node,tech}\mathord{>}\text{0} \land \text{carrier_tier} \in \text{[out]})\land{}(\neg (\exists (\textit{cost_export}_\text{node,tech,cost})))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost,timestep} \times -1 \times \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\textbf{carrier_con}_\text{node,tech,carrier,timestep}))&\quad
-            \text{if } (\neg (\exists (\textit{cost_export}_\text{node,tech,cost,timestep})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \neg (\text{tech_group=conversion_plus} \lor \text{tech_group=supply_plus} \lor \text{tech_group=supply}) \land \text{carrier_tier} \in \text{[in]})\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \text{tech_group=conversion_plus})
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{flow_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost} \times \sum\limits_{\text{carrier=primary_carrier_in}} (\textbf{flow_in}_\text{node,tech,carrier,timestep}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \text{tech_group=conversion_plus})\land{}(\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost}))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost,timestep} \times -1 \times \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\textbf{carrier_con}_\text{node,tech,carrier,timestep}))&\quad
-            \text{if } (\neg (\exists (\textit{cost_export}_\text{node,tech,cost,timestep})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \neg (\text{tech_group=conversion_plus} \lor \text{tech_group=supply_plus} \lor \text{tech_group=supply}) \land \text{carrier_tier} \in \text{[in]})\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \neg (\text{tech_group=conversion_plus}))
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_con}_\text{node,tech,cost} \times \sum\limits_{\text{carrier=primary_carrier_in}} (\textbf{flow_in}_\text{node,tech,carrier,timestep}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \text{tech_group=conversion_plus})\land{}(\neg (\exists (\textit{cost_export}_\text{node,tech,cost})))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_con}_\text{node,tech,cost,timestep} \times -1 \times \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\textbf{carrier_con}_\text{node,tech,carrier,timestep}))&\quad
-            \text{if } (\neg (\exists (\textit{cost_export}_\text{node,tech,cost,timestep})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep}) \land \neg (\text{tech_group=conversion_plus} \lor \text{tech_group=supply_plus} \lor \text{tech_group=supply}) \land \text{carrier_tier} \in \text{[in]})\land{}(\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep})))
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{flow_export}_\text{node,tech,carrier,timestep}) + \textit{cost_om_con}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\textbf{flow_in}_\text{node,tech,carrier,timestep}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \neg (\text{tech_group=conversion_plus} \lor \text{tech_group=supply_plus} \lor \text{tech_group=supply}) \land \text{carrier_tier} \in \text{[in]})\land{}(\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost}))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier=primary_carrier_out}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}))&\quad
-            \text{if } (\neg (\exists (\textit{cost_export}_\text{node,tech,cost,timestep})))\land{}(\neg (\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep})))\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \text{tech_group=conversion_plus})
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_con}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(in)}} (\textbf{flow_in}_\text{node,tech,carrier,timestep}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_om_con}_\text{node,tech,cost}) \land \neg (\text{tech_group=conversion_plus} \lor \text{tech_group=supply_plus} \lor \text{tech_group=supply}) \land \text{carrier_tier} \in \text{[in]})\land{}(\neg (\exists (\textit{cost_export}_\text{node,tech,cost})))
             \\
-            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_om_prod}_\text{node,tech,cost,timestep} \times \sum\limits_{\text{carrier} \in \text{carrier_tier(out)}} (\textbf{carrier_prod}_\text{node,tech,carrier,timestep}))&\quad
-            \text{if } (\neg (\exists (\textit{cost_export}_\text{node,tech,cost,timestep})))\land{}(\neg (\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep})))\land{}(\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep}) \land \neg (\text{tech_group=conversion_plus}))
+            \textit{timestep_weights}_\text{timestep} \times (\textit{cost_export}_\text{node,tech,cost} \times \sum\limits_{\text{carrier} \in \text{carriers}} (\textbf{flow_export}_\text{node,tech,carrier,timestep}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_om_con}_\text{node,tech,cost})))\land{}(\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \exists (\textit{cost_export}_\text{node,tech,cost}))
             \\
             \textit{timestep_weights}_\text{timestep} \times (0)&\quad
-            \text{if } (\neg (\exists (\textit{cost_export}_\text{node,tech,cost,timestep})))\land{}(\neg (\exists (\textit{cost_om_con}_\text{node,tech,cost,timestep})))\land{}(\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost,timestep})))
+            \text{if } (\neg (\exists (\textit{cost_om_prod}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_om_con}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_export}_\text{node,tech,cost})))
             \\
         \end{cases}
 
@@ -1362,296 +1408,296 @@ The installation costs of a technology, including annualised investment costs an
             \text{ tech }\negthickspace \in \negthickspace\text{ techs, }
             \text{ cost }\negthickspace \in \negthickspace\text{ costs }
             \\
-            \text{if } (\exists (\textit{cost_energy_cap}_\text{node,tech,cost}) \lor \exists (\textit{cost_om_annual}_\text{node,tech,cost}) \lor \exists (\textit{cost_om_annual_investment_fraction}_\text{node,tech,cost}) \lor \exists (\textit{cost_purchase}_\text{node,tech,cost}) \lor \exists (\textit{cost_resource_area}_\text{node,tech,cost}) \lor \exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \lor \exists (\textit{cost_storage_cap}_\text{node,tech,cost}))
+            \text{if } (\exists (\textit{cost_flow_cap}_\text{node,tech,cost}) \lor \exists (\textit{cost_om_annual}_\text{node,tech,cost}) \lor \exists (\textit{cost_om_annual_investment_fraction}_\text{node,tech,cost}) \lor \exists (\textit{cost_purchase}_\text{node,tech,cost}) \lor \exists (\textit{cost_area_use}_\text{node,tech,cost}) \lor \exists (\textit{cost_source_cap}_\text{node,tech,cost}) \lor \exists (\textit{cost_storage_cap}_\text{node,tech,cost}))
         \end{array}
         \begin{cases}
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (0) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_purchase}_\text{node,tech,cost} \times \textbf{purchased}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{purchased}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_storage_cap}_\text{node,tech,cost} \times \textbf{storage_cap}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech} + \textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_purchase}_\text{node,tech,cost} \times \textbf{units}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land \exists (\textbf{units}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_source_cap}_\text{node,tech,cost} \times \textbf{source_cap}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech}))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_energy_cap}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\exists (\textit{cost_energy_cap}_\text{node,tech,cost}))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (0) \times (0.5 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\text{tech_group=transmission})\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech} + \textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech} + \textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_resource_cap}_\text{node,tech,cost} \times \textbf{resource_cap}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_area_use}_\text{node,tech,cost} \times \textbf{area_use}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech}))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_resource_area}_\text{node,tech,cost} \times \textbf{resource_area}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech}))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (\textit{cost_flow_cap}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\exists (\textit{cost_flow_cap}_\text{node,tech,cost}))
             \\
-            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (0) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{energy_cap}_\text{node,tech}))&\quad
-            \text{if } (\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_energy_cap}_\text{node,tech,cost})))\land{}(\neg (\exists (\textit{cost_resource_cap}_\text{node,tech,cost}) \land \exists (\textbf{resource_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_resource_area}_\text{node,tech,cost}) \land \exists (\textbf{resource_area}_\text{node,tech})))
+            \textit{annualisation_weight} \times ((\textit{cost_depreciation_rate}_\text{node,tech,cost} \times (0) \times (1 + \textit{cost_om_annual_investment_fraction}_\text{node,tech,cost})) + (\textit{cost_om_annual}_\text{node,tech,cost} \times \textbf{flow_cap}_\text{node,tech}))&\quad
+            \text{if } (\neg (\exists (\textit{cost_purchase}_\text{node,tech,cost}) \land (\exists (\textbf{purchased}_\text{node,tech}) \lor \exists (\textbf{units}_\text{node,tech}))))\land{}(\neg (\exists (\textit{cost_storage_cap}_\text{node,tech,cost}) \land \exists (\textbf{storage_cap}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_source_cap}_\text{node,tech,cost}) \land \exists (\textbf{source_cap}_\text{node,tech})))\land{}(\neg (\text{tech_group=transmission}))\land{}(\neg (\exists (\textit{cost_area_use}_\text{node,tech,cost}) \land \exists (\textbf{area_use}_\text{node,tech})))\land{}(\neg (\exists (\textit{cost_flow_cap}_\text{node,tech,cost})))
             \\
         \end{cases}
 
@@ -1673,26 +1719,26 @@ The total annualised costs of a technology, including installation and operation
         \end{array}
         \begin{cases}
             \textbf{cost_investment}_\text{node,tech,cost} + \sum\limits_{\text{timestep} \in \text{timesteps}} (\textbf{cost_var}_\text{node,tech,cost,timestep})&\quad
-            \text{if } (\exists (\textbf{cost_investment}_\text{node,tech,cost}))\land{}(\exists (\textbf{cost_var}_\text{node,tech,cost,timestep}))
-            \\
-            \textbf{cost_investment}_\text{node,tech,cost}&\quad
-            \text{if } (\exists (\textbf{cost_investment}_\text{node,tech,cost}))\land{}(\neg (\exists (\textbf{cost_var}_\text{node,tech,cost,timestep})))
+            \text{if } (\exists (\textbf{cost_var}_\text{node,tech,cost,timestep}))\land{}(\exists (\textbf{cost_investment}_\text{node,tech,cost}))
             \\
             \sum\limits_{\text{timestep} \in \text{timesteps}} (\textbf{cost_var}_\text{node,tech,cost,timestep})&\quad
-            \text{if } (\neg (\exists (\textbf{cost_investment}_\text{node,tech,cost})))\land{}(\exists (\textbf{cost_var}_\text{node,tech,cost,timestep}))
+            \text{if } (\exists (\textbf{cost_var}_\text{node,tech,cost,timestep}))\land{}(\neg (\exists (\textbf{cost_investment}_\text{node,tech,cost})))
+            \\
+            \textbf{cost_investment}_\text{node,tech,cost}&\quad
+            \text{if } (\neg (\exists (\textbf{cost_var}_\text{node,tech,cost,timestep})))\land{}(\exists (\textbf{cost_investment}_\text{node,tech,cost}))
             \\
             0&\quad
-            \text{if } (\neg (\exists (\textbf{cost_investment}_\text{node,tech,cost})))\land{}(\neg (\exists (\textbf{cost_var}_\text{node,tech,cost,timestep})))
+            \text{if } (\neg (\exists (\textbf{cost_var}_\text{node,tech,cost,timestep})))\land{}(\neg (\exists (\textbf{cost_investment}_\text{node,tech,cost})))
             \\
         \end{cases}
 
 Decision Variables
 ------------------
 
-energy_cap
-^^^^^^^^^^
+flow_cap
+^^^^^^^^
 
-A technology's energy capacity, also known as its nominal or nameplate capacity.
+A technology's flow capacity, also known as its nominal or nameplate capacity.
 
 .. container:: scrolling-wrapper
 
@@ -1705,16 +1751,16 @@ A technology's energy capacity, also known as its nominal or nameplate capacity.
             \forall\mathbb{R}\;
         \end{array}
         \begin{cases}
-            \textit{energy_cap_min}_\text{node,tech} \leq \textbf{energy_cap}_\text{node,tech}&\quad
+            \textit{flow_cap_min}_\text{node,tech} \leq \textbf{flow_cap}_\text{node,tech}&\quad
             \\
-            \textbf{energy_cap}_\text{node,tech} \leq \textit{energy_cap_max}_\text{node,tech}&\quad
+            \textbf{flow_cap}_\text{node,tech} \leq \textit{flow_cap_max}_\text{node,tech}&\quad
             \\
         \end{cases}
 
-carrier_prod
-^^^^^^^^^^^^
+flow_out
+^^^^^^^^
 
-The energy produced by a technology per timestep, also known as the energy discharged (from `storage` technologies) or the energy received (by `transmission` technologies) on a link.
+The outflow of a technology per timestep, also known as the flow discharged (from `storage` technologies) or the flow received (by `transmission` technologies) on a link.
 
 .. container:: scrolling-wrapper
 
@@ -1727,19 +1773,19 @@ The energy produced by a technology per timestep, also known as the energy disch
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
             \forall\mathbb{R}\;
-            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \textit{allowed_carrier_prod}_\text{node,tech}\mathord{=}\text{true} \land \text{carrier_tier} \in \text{[out,out_2,out_3]})
+            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \textit{allowed_flow_out}_\text{node,tech}\mathord{=}\text{true} \land \text{carrier_tier} \in \text{[out,out_2,out_3]})
         \end{array}
         \begin{cases}
-            0 \leq \textbf{carrier_prod}_\text{node,tech,carrier,timestep}&\quad
+            0 \leq \textbf{flow_out}_\text{node,tech,carrier,timestep}&\quad
             \\
-            \textbf{carrier_prod}_\text{node,tech,carrier,timestep} \leq inf&\quad
+            \textbf{flow_out}_\text{node,tech,carrier,timestep} \leq inf&\quad
             \\
         \end{cases}
 
-carrier_con
-^^^^^^^^^^^
+flow_in
+^^^^^^^
 
-The energy consumed by a technology per timestep, also known as the energy consumed (by `storage` technologies) or the energy sent (by `transmission` technologies) on a link.
+The inflow to a technology per timestep, also known as the flow consumed (by `storage` technologies) or the flow sent (by `transmission` technologies) on a link.
 
 .. container:: scrolling-wrapper
 
@@ -1752,19 +1798,19 @@ The energy consumed by a technology per timestep, also known as the energy consu
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
             \forall\mathbb{R}\;
-            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \textit{allowed_carrier_con}_\text{node,tech}\mathord{=}\text{true} \land \text{carrier_tier} \in \text{[in,in_2,in_3]})
+            \text{if } (\exists (\textit{carrier}_\text{tech,carrier_tier,carrier}) \land \textit{allowed_flow_in}_\text{node,tech}\mathord{=}\text{true} \land \text{carrier_tier} \in \text{[in,in_2,in_3]})
         \end{array}
         \begin{cases}
-            -inf \leq \textbf{carrier_con}_\text{node,tech,carrier,timestep}&\quad
+            0 \leq \textbf{flow_in}_\text{node,tech,carrier,timestep}&\quad
             \\
-            \textbf{carrier_con}_\text{node,tech,carrier,timestep} \leq 0&\quad
+            \textbf{flow_in}_\text{node,tech,carrier,timestep} \leq inf&\quad
             \\
         \end{cases}
 
-carrier_export
-^^^^^^^^^^^^^^
+flow_export
+^^^^^^^^^^^
 
-The energy exported outside the system boundaries by a technology per timestep.
+The flow of a carrier exported outside the system boundaries by a technology per timestep.
 
 .. container:: scrolling-wrapper
 
@@ -1780,14 +1826,14 @@ The energy exported outside the system boundaries by a technology per timestep.
             \text{if } (\exists (\textit{export_carrier}_\text{node,tech,carrier}) \land \textit{export}_\text{node,tech}\mathord{=}\text{true})
         \end{array}
         \begin{cases}
-            0 \leq \textbf{carrier_export}_\text{node,tech,carrier,timestep}&\quad
+            0 \leq \textbf{flow_export}_\text{node,tech,carrier,timestep}&\quad
             \\
-            \textbf{carrier_export}_\text{node,tech,carrier,timestep} \leq inf&\quad
+            \textbf{flow_export}_\text{node,tech,carrier,timestep} \leq inf&\quad
             \\
         \end{cases}
 
-resource_area
-^^^^^^^^^^^^^
+area_use
+^^^^^^^^
 
 The area in space utilised directly (e.g., solar PV panels) or indirectly (e.g., biofuel crops) by a technology.
 
@@ -1800,19 +1846,19 @@ The area in space utilised directly (e.g., solar PV panels) or indirectly (e.g.,
             \text{ tech }\negthickspace \in \negthickspace\text{ techs }
             \\
             \forall\mathbb{R}\;
-            \text{if } (\exists (\textit{resource_area_min}_\text{node,tech}) \lor \exists (\textit{resource_area_max}_\text{node,tech}) \lor \exists (\textit{resource_area_equals}_\text{node,tech}) \lor \exists (\textit{resource_area_per_energy_cap}_\text{node,tech}) \lor \textit{resource_unit}_\text{node,tech}\mathord{=}\text{energy_per_area})
+            \text{if } (\exists (\textit{area_use_min}_\text{node,tech}) \lor \exists (\textit{area_use_max}_\text{node,tech}) \lor \exists (\textit{area_use_per_flow_cap}_\text{node,tech}) \lor \textit{sink_unit}_\text{node,tech}\mathord{=}\text{per_area} \lor \textit{source_unit}_\text{node,tech}\mathord{=}\text{per_area})
         \end{array}
         \begin{cases}
-            \textit{resource_area_min}_\text{node,tech} \leq \textbf{resource_area}_\text{node,tech}&\quad
+            \textit{area_use_min}_\text{node,tech} \leq \textbf{area_use}_\text{node,tech}&\quad
             \\
-            \textbf{resource_area}_\text{node,tech} \leq \textit{resource_area_max}_\text{node,tech}&\quad
+            \textbf{area_use}_\text{node,tech} \leq \textit{area_use_max}_\text{node,tech}&\quad
             \\
         \end{cases}
 
-resource_con
-^^^^^^^^^^^^
+source_use
+^^^^^^^^^^
 
-The energy consumed from outside the system boundaries by a `supply_plus` technology.
+The carrier flow consumed from outside the system boundaries by a `supply_plus` technology.
 
 .. container:: scrolling-wrapper
 
@@ -1827,16 +1873,16 @@ The energy consumed from outside the system boundaries by a `supply_plus` techno
             \text{if } (\text{tech_group=supply_plus})
         \end{array}
         \begin{cases}
-            0 \leq \textbf{resource_con}_\text{node,tech,timestep}&\quad
+            0 \leq \textbf{source_use}_\text{node,tech,timestep}&\quad
             \\
-            \textbf{resource_con}_\text{node,tech,timestep} \leq inf&\quad
+            \textbf{source_use}_\text{node,tech,timestep} \leq inf&\quad
             \\
         \end{cases}
 
-resource_cap
-^^^^^^^^^^^^
+source_cap
+^^^^^^^^^^
 
-The upper limit on energy that can be consumed from outside the system boundaries by a `supply_plus` technology in each timestep.
+The upper limit on a flow that can be consumed from outside the system boundaries by a `supply_plus` technology in each timestep.
 
 .. container:: scrolling-wrapper
 
@@ -1850,16 +1896,16 @@ The upper limit on energy that can be consumed from outside the system boundarie
             \text{if } (\text{tech_group=supply_plus})
         \end{array}
         \begin{cases}
-            \textit{resource_cap_min}_\text{node,tech} \leq \textbf{resource_cap}_\text{node,tech}&\quad
+            \textit{source_cap_min}_\text{node,tech} \leq \textbf{source_cap}_\text{node,tech}&\quad
             \\
-            \textbf{resource_cap}_\text{node,tech} \leq \textit{resource_cap_max}_\text{node,tech}&\quad
+            \textbf{source_cap}_\text{node,tech} \leq \textit{source_cap_max}_\text{node,tech}&\quad
             \\
         \end{cases}
 
 storage_cap
 ^^^^^^^^^^^
 
-The upper limit on energy that can be stored by a `supply_plus` or `storage` technology in any timestep.
+The upper limit on a carrier that can be stored by a `supply_plus` or `storage` technology in any timestep.
 
 .. container:: scrolling-wrapper
 
@@ -1882,7 +1928,7 @@ The upper limit on energy that can be stored by a `supply_plus` or `storage` tec
 storage
 ^^^^^^^
 
-The energy stored by a `supply_plus` or `storage` technology in each timestep.
+The carrier stored by a `supply_plus` or `storage` technology in each timestep.
 
 .. container:: scrolling-wrapper
 
@@ -1929,7 +1975,7 @@ Binary switch defining whether a technology has been purchased or not, for any t
 units
 ^^^^^
 
-Integer number of a technology that has been purchased, for any technology set to require inteter capacity purchasing. This is used to allow installation of fixed capacity units of technologies. Since technology capacity is no longer a continuous decision variable, it is possible for these technologies to have a lower bound set on carrier production/consumption which will only be enforced in those timesteps that the technology is operating (otherwise, the same lower bound forces the technology to produce/consume that minimum amount of energy in *every* timestep).
+Integer number of a technology that has been purchased, for any technology set to require inteter capacity purchasing. This is used to allow installation of fixed capacity units of technologies. Since technology capacity is no longer a continuous decision variable, it is possible for these technologies to have a lower bound set on outflow/consumption which will only be enforced in those timesteps that the technology is operating (otherwise, the same lower bound forces the technology to produce/consume that minimum amount of carrier in *every* timestep).
 
 .. container:: scrolling-wrapper
 
@@ -1973,10 +2019,10 @@ Integer number of a technology that is operating in each timestep, for any techn
             \\
         \end{cases}
 
-prod_con_switch
-^^^^^^^^^^^^^^^
+async_flow_switch
+^^^^^^^^^^^^^^^^^
 
-Binary switch to force asynchronous carrier production/consumption of a `storage`/`supply_plus`/`transmission` technology. This ensures that a technology with carrier flow efficiencies < 100% cannot produce and consume energy simultaneously to remove unwanted energy from the system.
+Binary switch to force asynchronous outflow/consumption of a `storage`/`supply_plus`/`transmission` technology. This ensures that a technology with carrier flow efficiencies < 100% cannot produce and consume a flow simultaneously to remove unwanted carrier from the system.
 
 .. container:: scrolling-wrapper
 
@@ -1988,19 +2034,19 @@ Binary switch to force asynchronous carrier production/consumption of a `storage
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
             \forall\mathbb{Z}\;
-            \text{if } (\textit{force_asynchronous_prod_con}_\text{node,tech}\mathord{=}\text{true})
+            \text{if } (\textit{force_async_flow}_\text{node,tech}\mathord{=}\text{true})
         \end{array}
         \begin{cases}
-            0 \leq \textbf{prod_con_switch}_\text{node,tech,timestep}&\quad
+            0 \leq \textbf{async_flow_switch}_\text{node,tech,timestep}&\quad
             \\
-            \textbf{prod_con_switch}_\text{node,tech,timestep} \leq 1&\quad
+            \textbf{async_flow_switch}_\text{node,tech,timestep} \leq 1&\quad
             \\
         \end{cases}
 
 unmet_demand
 ^^^^^^^^^^^^
 
-Virtual source of energy to ensure model feasibility. This should only be considered a debugging rather than a modelling tool as it may distort the model in other ways due to the large impact it has on the objective function value. When present in a model in which it has been requested, it indicates an inability for technologies in the model to reach a sufficient combined supply capacity to meet demand.
+Virtual source of carrier flow to ensure model feasibility. This should only be considered a debugging rather than a modelling tool as it may distort the model in other ways due to the large impact it has on the objective function value. When present in a model in which it has been requested, it indicates an inability for technologies in the model to reach a sufficient combined supply capacity to meet demand.
 
 .. container:: scrolling-wrapper
 
@@ -2012,7 +2058,7 @@ Virtual source of energy to ensure model feasibility. This should only be consid
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
             \forall\mathbb{R}\;
-            \text{if } (\text{run_config.ensure_feasibility}\mathord{=}\text{true})
+            \text{if } (\text{config.ensure_feasibility}\mathord{=}\text{true})
         \end{array}
         \begin{cases}
             0 \leq \textbf{unmet_demand}_\text{node,carrier,timestep}&\quad
@@ -2024,7 +2070,7 @@ Virtual source of energy to ensure model feasibility. This should only be consid
 unused_supply
 ^^^^^^^^^^^^^
 
-Virtual sink of energy to ensure model feasibility. This should only be considered a debugging rather than a modelling tool as it may distort the model in other ways due to the large impact it has on the objective function value. In model results, the negation of this variable is combined with `unmet_demand` and presented as only one variable: `unmet_demand`. When present in a model in which it has been requested, it indicates an inability for technologies in the model to reach a sufficient combined consumption capacity to meet required energy production (e.g. from renewables without the possibility of curtailment).
+Virtual sink of carrier flow to ensure model feasibility. This should only be considered a debugging rather than a modelling tool as it may distort the model in other ways due to the large impact it has on the objective function value. In model results, the negation of this variable is combined with `unmet_demand` and presented as only one variable: `unmet_demand`. When present in a model in which it has been requested, it indicates an inability for technologies in the model to reach a sufficient combined consumption capacity to meet required outflow (e.g. from renewables without the possibility of curtailment).
 
 .. container:: scrolling-wrapper
 
@@ -2036,7 +2082,7 @@ Virtual sink of energy to ensure model feasibility. This should only be consider
             \text{ timestep }\negthickspace \in \negthickspace\text{ timesteps }
             \\
             \forall\mathbb{R}\;
-            \text{if } (\text{run_config.ensure_feasibility}\mathord{=}\text{true})
+            \text{if } (\text{config.ensure_feasibility}\mathord{=}\text{true})
         \end{array}
         \begin{cases}
             -inf \leq \textbf{unused_supply}_\text{node,carrier,timestep}&\quad
diff --git a/doc/_static/math_storage_inter_cluster.rst b/doc/_static/math_storage_inter_cluster.rst
index d9de0e215..108f4d4ff 100644
--- a/doc/_static/math_storage_inter_cluster.rst
+++ b/doc/_static/math_storage_inter_cluster.rst
@@ -13,7 +13,7 @@ balance_supply_plus_with_storage
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 :yellow:`UPDATED`
-Set the upper bound on, or a fixed total of, a `supply_plus` (with storage) technology's ability to produce energy based on the quantity of consumed resource and available stored energy.
+Set the upper bound on, or a fixed total of, a `supply_plus` (with storage) technology's ability to produce flow based on the quantity of consumed resource and available stored carrier.
 
 .. container:: scrolling-wrapper
 
@@ -28,23 +28,23 @@ Set the upper bound on, or a fixed total of, a `supply_plus` (with storage) tech
             \text{if } (\exists (\textbf{storage}_\text{node,tech,timestep}) \land \text{tech_group=supply_plus})
         \end{array}
         \begin{cases}
-            \textbf{storage}_\text{node,tech,timestep} = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech} + (\textbf{resource_con}_\text{node,tech,timestep} \times \textit{resource_eff}_\text{node,tech,timestep})&\quad
-            \text{if } (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true}))\land{}(\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech,timestep}\mathord{=}\text{0})
+            \textbf{storage}_\text{node,tech,timestep} = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech} + (\textbf{source_use}_\text{node,tech,timestep} \times \textit{source_eff}_\text{node,tech})&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech}\mathord{=}\text{0})\land{}(\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true}))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech} + (\textbf{resource_con}_\text{node,tech,timestep} \times \textit{resource_eff}_\text{node,tech,timestep}) - \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ (\textit{energy_eff}_\text{node,tech,timestep} \times \textit{parasitic_eff}_\text{node,tech,timestep}) }&\quad
-            \text{if } (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true}))\land{}(\neg (\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech,timestep}\mathord{=}\text{0}))
+            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech})^{\textit{timestep_resolution}_\text{timestep-1}}) \times \textbf{storage}_\text{node,tech,timestep-1} + (\textbf{source_use}_\text{node,tech,timestep} \times \textit{source_eff}_\text{node,tech})&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech}\mathord{=}\text{0})\land{}(((\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \text{config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]})) \land \neg (\exists (\textit{lookup_cluster_last_timestep}_\text{timestep})))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech,timestep})^{\textit{timestep_resolution}_\text{timestep-1}}) \times \textbf{storage}_\text{node,tech,timestep-1} + (\textbf{resource_con}_\text{node,tech,timestep} \times \textit{resource_eff}_\text{node,tech,timestep})&\quad
-            \text{if } (((\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \text{run_config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]})) \land \neg (\exists (\textit{lookup_cluster_last_timestep}_\text{timestep})))\land{}(\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech,timestep}\mathord{=}\text{0})
+            \textbf{storage}_\text{node,tech,timestep} = (\textbf{source_use}_\text{node,tech,timestep} \times \textit{source_eff}_\text{node,tech})&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech}\mathord{=}\text{0})\land{}(\exists (\textit{lookup_cluster_last_timestep}_\text{timestep}) \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true})))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech,timestep})^{\textit{timestep_resolution}_\text{timestep-1}}) \times \textbf{storage}_\text{node,tech,timestep-1} + (\textbf{resource_con}_\text{node,tech,timestep} \times \textit{resource_eff}_\text{node,tech,timestep}) - \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ (\textit{energy_eff}_\text{node,tech,timestep} \times \textit{parasitic_eff}_\text{node,tech,timestep}) }&\quad
-            \text{if } (((\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \text{run_config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]})) \land \neg (\exists (\textit{lookup_cluster_last_timestep}_\text{timestep})))\land{}(\neg (\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech,timestep}\mathord{=}\text{0}))
+            \textbf{storage}_\text{node,tech,timestep} = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech} + (\textbf{source_use}_\text{node,tech,timestep} \times \textit{source_eff}_\text{node,tech}) - \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ (\textit{flow_eff}_\text{node,tech} \times \textit{parasitic_eff}_\text{node,tech}) }&\quad
+            \text{if } (\neg (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech}\mathord{=}\text{0}))\land{}(\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true}))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = (\textbf{resource_con}_\text{node,tech,timestep} \times \textit{resource_eff}_\text{node,tech,timestep})&\quad
-            \text{if } (\exists (\textit{lookup_cluster_last_timestep}_\text{timestep}) \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true})))\land{}(\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech,timestep}\mathord{=}\text{0})
+            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech})^{\textit{timestep_resolution}_\text{timestep-1}}) \times \textbf{storage}_\text{node,tech,timestep-1} + (\textbf{source_use}_\text{node,tech,timestep} \times \textit{source_eff}_\text{node,tech}) - \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ (\textit{flow_eff}_\text{node,tech} \times \textit{parasitic_eff}_\text{node,tech}) }&\quad
+            \text{if } (\neg (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech}\mathord{=}\text{0}))\land{}(((\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \text{config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]})) \land \neg (\exists (\textit{lookup_cluster_last_timestep}_\text{timestep})))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = (\textbf{resource_con}_\text{node,tech,timestep} \times \textit{resource_eff}_\text{node,tech,timestep}) - \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ (\textit{energy_eff}_\text{node,tech,timestep} \times \textit{parasitic_eff}_\text{node,tech,timestep}) }&\quad
-            \text{if } (\exists (\textit{lookup_cluster_last_timestep}_\text{timestep}) \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true})))\land{}(\neg (\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech,timestep}\mathord{=}\text{0}))
+            \textbf{storage}_\text{node,tech,timestep} = (\textbf{source_use}_\text{node,tech,timestep} \times \textit{source_eff}_\text{node,tech}) - \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ (\textit{flow_eff}_\text{node,tech} \times \textit{parasitic_eff}_\text{node,tech}) }&\quad
+            \text{if } (\neg (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0} \lor \textit{parasitic_eff}_\text{node,tech}\mathord{=}\text{0}))\land{}(\exists (\textit{lookup_cluster_last_timestep}_\text{timestep}) \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true})))
             \\
         \end{cases}
 
@@ -52,7 +52,7 @@ balance_storage
 ^^^^^^^^^^^^^^^
 
 :yellow:`UPDATED`
-Fix the quantity of energy stored in a `storage` technology at the end of each timestep based on the net flow of energy charged and discharged and the quantity of energy stored at the start of the timestep.
+Fix the quantity of carrier stored in a `storage` technology at the end of each timestep based on the net flow of carrier charged and discharged and the quantity of carrier stored at the start of the timestep.
 
 .. container:: scrolling-wrapper
 
@@ -67,23 +67,23 @@ Fix the quantity of energy stored in a `storage` technology at the end of each t
             \text{if } (\text{tech_group=storage})
         \end{array}
         \begin{cases}
-            \textbf{storage}_\text{node,tech,timestep} = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech} - \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{energy_eff}_\text{node,tech,timestep} } - (\textbf{carrier_con}_\text{node,tech,carrier,timestep} \times \textit{energy_eff}_\text{node,tech,timestep})&\quad
-            \text{if } (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true}))\land{}(\textit{energy_eff}_\text{node,tech,timestep}\mathord{>}\text{0})
+            \textbf{storage}_\text{node,tech,timestep} = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech} - \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{flow_eff}_\text{node,tech} } + (\textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech})&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{>}\text{0})\land{}(\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true}))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech} - (\textbf{carrier_con}_\text{node,tech,carrier,timestep} \times \textit{energy_eff}_\text{node,tech,timestep})&\quad
-            \text{if } (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true}))\land{}(\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0})
+            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech})^{\textit{timestep_resolution}_\text{timestep-1}}) \times \textbf{storage}_\text{node,tech,timestep-1} - \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{flow_eff}_\text{node,tech} } + (\textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech})&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{>}\text{0})\land{}(((\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \text{config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]})) \land \neg (\exists (\textit{lookup_cluster_last_timestep}_\text{timestep})))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech,timestep})^{\textit{timestep_resolution}_\text{timestep-1}}) \times \textbf{storage}_\text{node,tech,timestep-1} - \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{energy_eff}_\text{node,tech,timestep} } - (\textbf{carrier_con}_\text{node,tech,carrier,timestep} \times \textit{energy_eff}_\text{node,tech,timestep})&\quad
-            \text{if } (((\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \text{run_config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]})) \land \neg (\exists (\textit{lookup_cluster_last_timestep}_\text{timestep})))\land{}(\textit{energy_eff}_\text{node,tech,timestep}\mathord{>}\text{0})
+            \textbf{storage}_\text{node,tech,timestep} = \frac{ \textbf{flow_out}_\text{node,tech,carrier,timestep} }{ \textit{flow_eff}_\text{node,tech} } + (\textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech})&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{>}\text{0})\land{}(\exists (\textit{lookup_cluster_last_timestep}_\text{timestep}) \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true})))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech,timestep})^{\textit{timestep_resolution}_\text{timestep-1}}) \times \textbf{storage}_\text{node,tech,timestep-1} - (\textbf{carrier_con}_\text{node,tech,carrier,timestep} \times \textit{energy_eff}_\text{node,tech,timestep})&\quad
-            \text{if } (((\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \text{run_config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]})) \land \neg (\exists (\textit{lookup_cluster_last_timestep}_\text{timestep})))\land{}(\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0})
+            \textbf{storage}_\text{node,tech,timestep} = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech} + (\textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech})&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0})\land{}(\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true}))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = \frac{ \textbf{carrier_prod}_\text{node,tech,carrier,timestep} }{ \textit{energy_eff}_\text{node,tech,timestep} } - (\textbf{carrier_con}_\text{node,tech,carrier,timestep} \times \textit{energy_eff}_\text{node,tech,timestep})&\quad
-            \text{if } (\exists (\textit{lookup_cluster_last_timestep}_\text{timestep}) \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true})))\land{}(\textit{energy_eff}_\text{node,tech,timestep}\mathord{>}\text{0})
+            \textbf{storage}_\text{node,tech,timestep} = ((1 - \textit{storage_loss}_\text{node,tech})^{\textit{timestep_resolution}_\text{timestep-1}}) \times \textbf{storage}_\text{node,tech,timestep-1} + (\textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech})&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0})\land{}(((\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \text{config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]})) \land \neg (\exists (\textit{lookup_cluster_last_timestep}_\text{timestep})))
             \\
-            \textbf{storage}_\text{node,tech,timestep} = (\textbf{carrier_con}_\text{node,tech,carrier,timestep} \times \textit{energy_eff}_\text{node,tech,timestep})&\quad
-            \text{if } (\exists (\textit{lookup_cluster_last_timestep}_\text{timestep}) \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true})))\land{}(\textit{energy_eff}_\text{node,tech,timestep}\mathord{=}\text{0})
+            \textbf{storage}_\text{node,tech,timestep} = (\textbf{flow_in}_\text{node,tech,carrier,timestep} \times \textit{flow_eff}_\text{node,tech})&\quad
+            \text{if } (\textit{flow_eff}_\text{node,tech}\mathord{=}\text{0})\land{}(\exists (\textit{lookup_cluster_last_timestep}_\text{timestep}) \land \neg (\textit{timesteps}_\text{timestep}\mathord{=}\text{timesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true})))
             \\
         \end{cases}
 
@@ -91,7 +91,7 @@ set_storage_initial
 ^^^^^^^^^^^^^^^^^^^
 
 :yellow:`UPDATED`
-Fix the relationship between energy stored in a `storage` technology at the start and end of the whole model period.
+Fix the relationship between carrier stored in a `storage` technology at the start and end of the whole model period.
 
 .. container:: scrolling-wrapper
 
@@ -101,10 +101,10 @@ Fix the relationship between energy stored in a `storage` technology at the star
             \text{ node }\negthickspace \in \negthickspace\text{ nodes, }
             \text{ tech }\negthickspace \in \negthickspace\text{ techs }
             \\
-            \text{if } (\exists (\textbf{storage}_\text{node,tech,timestep}) \land \exists (\textit{storage_initial}_\text{node,tech}) \land \text{run_config.cyclic_storage}\mathord{=}\text{true})
+            \text{if } (\exists (\textbf{storage}_\text{node,tech,timestep}) \land \exists (\textit{storage_initial}_\text{node,tech}) \land \text{config.cyclic_storage}\mathord{=}\text{true})
         \end{array}
         \begin{cases}
-            \textbf{storage_inter_cluster}_\text{node,tech,datestep=datesteps[-1]} \times ((1 - \textit{storage_loss}_\text{node,tech,timestep})^{24}) = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech}&\quad
+            \textbf{storage_inter_cluster}_\text{node,tech,datestep=datesteps[-1]} \times ((1 - \textit{storage_loss}_\text{node,tech})^{24}) = \textit{storage_initial}_\text{node,tech} \times \textbf{storage_cap}_\text{node,tech}&\quad
             \\
         \end{cases}
 
@@ -112,7 +112,7 @@ balance_storage_inter
 ^^^^^^^^^^^^^^^^^^^^^
 
 :green:`NEW`
-Fix the relationship between one day and the next of a `storage` technology's available stored energy, according to the previous day's representative storage fluctuations and the excess stored energy available from all days up to this day.
+Fix the relationship between one day and the next of a `storage` technology's available stored carrier, according to the previous day's representative storage fluctuations and the excess stored carrier available from all days up to this day.
 
 .. container:: scrolling-wrapper
 
@@ -127,16 +127,16 @@ Fix the relationship between one day and the next of a `storage` technology's av
         \end{array}
         \begin{cases}
             \textbf{storage_inter_cluster}_\text{node,tech,datestep} = \textit{storage_initial}_\text{node,tech}&\quad
-            \text{if } (\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true}))\land{}(\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true}))
+            \text{if } (\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true}))\land{}(\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true}))
             \\
-            \textbf{storage_inter_cluster}_\text{node,tech,datestep} = \textit{storage_initial}_\text{node,tech} + \textbf{storage}_\text{node,tech,timestep=\textit{lookup_datestep_last_cluster_timestep}_\text{datestep-1}}&\quad
-            \text{if } (\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true}))\land{}(\neg (\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true})))
+            \textbf{storage_inter_cluster}_\text{node,tech,datestep} = ((1 - \textit{storage_loss}_\text{node,tech})^{24}) \times \textbf{storage_inter_cluster}_\text{node,tech,datestep-1}&\quad
+            \text{if } (\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true}))\land{}((\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]} \land \text{config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]}))
             \\
-            \textbf{storage_inter_cluster}_\text{node,tech,datestep} = ((1 - \textit{storage_loss}_\text{node,tech,timestep})^{24}) \times \textbf{storage_inter_cluster}_\text{node,tech,datestep-1}&\quad
-            \text{if } ((\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]} \land \text{run_config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]}))\land{}(\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true}))
+            \textbf{storage_inter_cluster}_\text{node,tech,datestep} = \textit{storage_initial}_\text{node,tech} + \textbf{storage}_\text{node,tech,timestep=\textit{lookup_datestep_last_cluster_timestep}_\text{datestep-1}}&\quad
+            \text{if } (\neg (\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true})))\land{}(\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true}))
             \\
-            \textbf{storage_inter_cluster}_\text{node,tech,datestep} = ((1 - \textit{storage_loss}_\text{node,tech,timestep})^{24}) \times \textbf{storage_inter_cluster}_\text{node,tech,datestep-1} + \textbf{storage}_\text{node,tech,timestep=\textit{lookup_datestep_last_cluster_timestep}_\text{datestep-1}}&\quad
-            \text{if } ((\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]} \land \text{run_config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]}))\land{}(\neg (\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]} \land \neg (\text{run_config.cyclic_storage}\mathord{=}\text{true})))
+            \textbf{storage_inter_cluster}_\text{node,tech,datestep} = ((1 - \textit{storage_loss}_\text{node,tech})^{24}) \times \textbf{storage_inter_cluster}_\text{node,tech,datestep-1} + \textbf{storage}_\text{node,tech,timestep=\textit{lookup_datestep_last_cluster_timestep}_\text{datestep-1}}&\quad
+            \text{if } (\neg (\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]} \land \neg (\text{config.cyclic_storage}\mathord{=}\text{true})))\land{}((\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]} \land \text{config.cyclic_storage}\mathord{=}\text{true}) \lor \neg (\textit{datesteps}_\text{datestep}\mathord{=}\text{datesteps[0]}))
             \\
         \end{cases}
 
@@ -144,7 +144,7 @@ storage_inter_max
 ^^^^^^^^^^^^^^^^^
 
 :green:`NEW`
-Set the upper bound of a `storage` technology's stored energy across all days in the timeseries
+Set the upper bound of a `storage` technology's stored carrier across all days in the timeseries
 
 .. container:: scrolling-wrapper
 
@@ -166,7 +166,7 @@ storage_inter_min
 ^^^^^^^^^^^^^^^^^
 
 :green:`NEW`
-Set the lower bound of a `storage` technology's stored energy across all days in the timeseries
+Set the lower bound of a `storage` technology's stored carrier across all days in the timeseries
 
 .. container:: scrolling-wrapper
 
@@ -180,7 +180,7 @@ Set the lower bound of a `storage` technology's stored energy across all days in
             \text{if } (\textit{include_storage}_\text{node,tech}\mathord{=}\text{true})
         \end{array}
         \begin{cases}
-            (\textbf{storage_inter_cluster}_\text{node,tech,datestep} \times ((1 - \textit{storage_loss}_\text{node,tech,timestep})^{24})) + \textbf{storage_intra_cluster_min}_\text{node,tech,cluster=\textit{lookup_datestep_cluster}_\text{datestep}} \geq 0&\quad
+            (\textbf{storage_inter_cluster}_\text{node,tech,datestep} \times ((1 - \textit{storage_loss}_\text{node,tech})^{24})) + \textbf{storage_intra_cluster_min}_\text{node,tech,cluster=\textit{lookup_datestep_cluster}_\text{datestep}} \geq 0&\quad
             \\
         \end{cases}
 
@@ -188,7 +188,7 @@ storage_intra_max
 ^^^^^^^^^^^^^^^^^
 
 :green:`NEW`
-Set the upper bound of a `storage` technology's stored energy within a clustered day
+Set the upper bound of a `storage` technology's stored carrier within a clustered day
 
 .. container:: scrolling-wrapper
 
@@ -210,7 +210,7 @@ storage_intra_min
 ^^^^^^^^^^^^^^^^^
 
 :green:`NEW`
-Set the lower bound of a `storage` technology's stored energy within a clustered day
+Set the lower bound of a `storage` technology's stored carrier within a clustered day
 
 .. container:: scrolling-wrapper
 
@@ -235,7 +235,7 @@ storage
 ^^^^^^^
 
 :yellow:`UPDATED`
-The virtual energy stored by a `supply_plus` or `storage` technology in each timestep of a clustered day. Stored energy can be negative so long as it does not go below the energy stored in `storage_inter_cluster`. Only together with `storage_inter_cluster` does this variable's values gain physical significance.
+The virtual carrier stored by a `supply_plus` or `storage` technology in each timestep of a clustered day. Stored carrier can be negative so long as it does not go below the carrier stored in `storage_inter_cluster`. Only together with `storage_inter_cluster` does this variable's values gain physical significance.
 
 .. container:: scrolling-wrapper
 
@@ -260,7 +260,7 @@ storage_inter_cluster
 ^^^^^^^^^^^^^^^^^^^^^
 
 :green:`NEW`
-The virtual energy stored by a `supply_plus` or `storage` technology between days of the entire timeseries. Only together with `storage` does this variable's values gain physical significance.
+The virtual carrier stored by a `supply_plus` or `storage` technology between days of the entire timeseries. Only together with `storage` does this variable's values gain physical significance.
 
 .. container:: scrolling-wrapper
 
diff --git a/doc/helpers/generate_math.py b/doc/helpers/generate_math.py
index d6f5e438f..dd0b5e6d5 100644
--- a/doc/helpers/generate_math.py
+++ b/doc/helpers/generate_math.py
@@ -34,7 +34,9 @@ def generate_base_math_model(model_config: dict) -> calliope.Model:
     Returns:
         calliope.Model: Base math model to use in generating custom math docs.
     """
-    model = calliope.Model(config=model_config, timeseries_dataframes=_ts_dfs())
+    model = calliope.Model(
+        model_definition=model_config, timeseries_dataframes=_ts_dfs()
+    )
     model.math_documentation.build()
     model.math_documentation.write(STATICPATH / "math.rst")
     return model
@@ -58,7 +60,9 @@ def generate_custom_math_model(
     model_config = calliope.AttrDict(model_config)
     model_config_updates = calliope.AttrDict(model_config_updates)
     model_config.union(model_config_updates)
-    model = calliope.Model(config=model_config, timeseries_dataframes=_ts_dfs())
+    model = calliope.Model(
+        model_definition=model_config, timeseries_dataframes=_ts_dfs()
+    )
     _keep_only_changes(base_model, model)
 
     model.math_documentation.write(STATICPATH / f"math_{name}.rst")
@@ -67,9 +71,10 @@ def generate_custom_math_model(
 def generate_model_config() -> dict[str, dict]:
     """To generate the written mathematical formulation of all possible base constraints, we first create a dummy model.
 
-    This dummy has all the relevant technology groups defining all their allowed parameters defined.
+    This dummy has all the relevant technology groups defining all their allowed parameters.
 
-    Parameters that can be defined over a timeseries are forced to be defined over a timeseries. Accordingly, the parameters will have "timesteps" in their dimensions in the formulation.
+    Parameters that can be defined over a timeseries are forced to be defined over a timeseries.
+    Accordingly, the parameters will have "timesteps" in their dimensions in the formulation.
     """
     defaults = calliope.AttrDict.from_yaml(
         BASEPATH / ".." / ".." / "src" / "calliope" / "config" / "defaults.yaml"
@@ -107,13 +112,13 @@ def generate_model_config() -> dict[str, dict]:
         dummy_techs[f"{tech_group}_tech"] = {
             "essentials": {"parent": tech_group, **carriers},
             "constraints": {
-                k: _add_data(k, v, defaults)
+                k: _add_data(k, v)
                 for k, v in defaults.techs.default_tech.constraints.items()
                 if k in allowed_["constraints"][tech_group]
             },
             "costs": {
                 "monetary": {
-                    k: _add_data(k, v, defaults)
+                    k: _add_data(k, v)
                     for k, v in defaults.techs.default_tech.costs.default_cost.items()
                     if k in allowed_["costs"][tech_group]
                 }
@@ -121,8 +126,6 @@ def generate_model_config() -> dict[str, dict]:
         }
 
     return {
-        "model": {},
-        "run": {"objective_options": {"cost_class": {"monetary": 1}}},
         "nodes": {
             "A": {"techs": {k: None for k in dummy_techs.keys()}, "available_area": 1}
         },
@@ -130,13 +133,10 @@ def generate_model_config() -> dict[str, dict]:
     }
 
 
-def _add_data(name, default_val, defaults):
-    "If timeseries is allowed, we reference timeseries data. Some parameters need hardcoded values to be returned"
-    if name in defaults["model"]["file_allowed"]:
-        if name == "carrier_ratios":
-            return {"carrier_in.electricity": "df=ts"}
-        else:
-            return "df=ts"
+def _add_data(name, default_val):
+    "Some parameters need hardcoded values to be returned"
+    if name == "carrier_ratios":
+        return {"carrier_in.electricity": 1}
     elif name == "export_carrier":
         return "electricity"
     elif default_val is None or name == "interest_rate":
@@ -187,7 +187,7 @@ def _ts_dfs() -> dict[str, pd.DataFrame]:
         index=pd.date_range("2005-01-01 00:00", "2005-01-01 02:00", freq="H"),
         columns=["A"],
     )
-    return {"ts": ts, "ts_neg": -1 * ts}
+    return {"ts": ts}
 
 
 if __name__ == "__main__":
@@ -198,16 +198,18 @@ def _ts_dfs() -> dict[str, pd.DataFrame]:
         base_model,
         base_model_config,
         {
-            "model": {
-                "custom_math": ["storage_inter_cluster"],
-                "time": {
-                    "function": "apply_clustering",
-                    "function_options": {
-                        "clustering_func": "kmeans",
-                        "how": "mean",
-                        "k": 1,
+            "config": {
+                "init": {
+                    "custom_math": ["storage_inter_cluster"],
+                    "time": {
+                        "function": "apply_clustering",
+                        "function_options": {
+                            "clustering_func": "kmeans",
+                            "how": "mean",
+                            "k": 1,
+                        },
                     },
-                },
+                }
             },
         },
         "storage_inter_cluster",
diff --git a/doc/helpers/generate_tables.py b/doc/helpers/generate_tables.py
index 56f0cbbc5..f03c484b0 100644
--- a/doc/helpers/generate_tables.py
+++ b/doc/helpers/generate_tables.py
@@ -59,8 +59,15 @@ def process():
         get_section(defaults["techs"]["default_tech"]["costs"]["default_cost"]),
     )
 
-    write_csv("./user/includes/model_settings.csv", get_section(defaults["model"]))
-    write_csv("./user/includes/run_settings.csv", get_section(defaults["run"]))
+    write_csv(
+        "./user/includes/config_init.csv", get_section(defaults["config"]["init"])
+    )
+    write_csv(
+        "./user/includes/config_build.csv", get_section(defaults["config"]["build"])
+    )
+    write_csv(
+        "./user/includes/config_solve.csv", get_section(defaults["config"]["solve"])
+    )
 
     y = yaml.YAML()
 
diff --git a/doc/user/advanced_constraints.rst b/doc/user/advanced_constraints.rst
index 4256a0f7e..66444dd3a 100644
--- a/doc/user/advanced_constraints.rst
+++ b/doc/user/advanced_constraints.rst
@@ -256,9 +256,9 @@ This will only allow transmission from ``location1`` to ``location2``. To swap t
 Cyclic storage
 --------------
 
-With ``storage`` and ``supply_plus`` techs, it is possible to link the storage at either end of the timeseries, using cyclic storage. This allows the user to better represent multiple years by just modelling one year. Cyclic storage is activated by default (to deactivate: ``run.cyclic_storage: false``). As a result, a technology's initial stored energy at a given location will be equal to its stored energy at the end of the model's last timestep.
+With ``storage`` and ``supply_plus`` techs, it is possible to link the storage at either end of the timeseries, using cyclic storage. This allows the user to better represent multiple years by just modelling one year. Cyclic storage is activated by default (to deactivate: ``config.build.cyclic_storage: false``). As a result, a technology's initial stored energy at a given location will be equal to its stored energy at the end of the model's last timestep.
 
-For example, for a model running over a full year at hourly resolution, the initial storage at `Jan 1st 00:00:00` will be forced equal to the storage at the end of the timestep `Dec 31st 23:00:00`. By setting ``storage_initial`` for a technology, it is also possible to fix the value in the last timestep. For instance, with ``run.cyclic_storage: true`` and a ``storage_initial`` of zero, the stored energy *must* be zero by the end of the time horizon.
+For example, for a model running over a full year at hourly resolution, the initial storage at `Jan 1st 00:00:00` will be forced equal to the storage at the end of the timestep `Dec 31st 23:00:00`. By setting ``storage_initial`` for a technology, it is also possible to fix the value in the last timestep. For instance, with ``config.build.cyclic_storage: true`` and a ``storage_initial`` of zero, the stored energy *must* be zero by the end of the time horizon.
 
 Without cyclic storage in place (as was the case prior to v0.6.2), the storage tech can have any amount of stored energy by the end of the timeseries. This may prove useful in some cases, but has less physical meaning than assuming cyclic storage.
 
diff --git a/doc/user/advanced_features.rst b/doc/user/advanced_features.rst
index 1ba16184a..1846d1c43 100644
--- a/doc/user/advanced_features.rst
+++ b/doc/user/advanced_features.rst
@@ -13,10 +13,11 @@ Models have a default timestep length (defined implicitly by the timesteps of th
 
 .. code-block:: yaml
 
-    model:
-        time:
-            function: resample
-            function_options: {'resolution': '6H'}
+    config:
+        init:
+            time:
+                function: resample
+                function_options: {'resolution': '6H'}
 
 In the above example, this would resample all time series data to 6-hourly timesteps.
 
@@ -30,13 +31,14 @@ The available options include:
 
 .. code-block:: yaml
 
-    model:
-        time:
-            function: apply_clustering
-            function_options:
-                clustering_func: kmeans
-                how: mean
-                k: 20
+    config:
+        init:
+            time:
+                function: apply_clustering
+                function_options:
+                    clustering_func: kmeans
+                    how: mean
+                    k: 20
 
 When using representative days, a number of additional constraints are added, based on the study undertaken by `Kotzur et al <https://doi.org/10.1016/j.apenergy.2018.01.023>`_. These constraints require a new decision variable ``storage_inter_cluster``, which tracks storage between all the dates of the original timeseries. This particular functionality can be disabled by including :yaml:`storage_inter_cluster: false` in the `function_options` given above.
 
@@ -48,13 +50,14 @@ When using representative days, a number of additional constraints are added, ba
 
 .. code-block:: yaml
 
-    model:
-        time:
-            masks:
-                - {function: extreme, options: {padding: 'calendar_week', tech: 'wind', how: 'max'}}
-                - {function: extreme, options: {padding: 'calendar_week', tech: 'wind', how: 'min'}}
-            function: resample
-            function_options: {'resolution': '6H'}
+    config:
+        init:
+            time:
+                masks:
+                    - {function: extreme, options: {padding: 'calendar_week', tech: 'wind', how: 'max'}}
+                    - {function: extreme, options: {padding: 'calendar_week', tech: 'wind', how: 'min'}}
+                function: resample
+                function_options: {'resolution': '6H'}
 
 .. Warning::
 
@@ -156,10 +159,9 @@ Operational mode runs a model with a receding horizon control algorithm. This re
 
 .. code-block:: yaml
 
-    run:
-        operation:
-            horizon: 48  # hours
-            window: 24  # hours
+    config.build:
+        operate_horizon: 48  # hours
+        operate_window: 24  # hours
 
 ``horizon`` specifies how far into the future the control algorithm optimises in each iteration. ``window`` specifies how many of the hours within ``horizon`` are actually used. In the above example, decisions on how to operate for each 24-hour window are made by optimising over 48-hour horizons (i.e., the second half of each optimisation run is discarded). For this reason, ``horizon`` must always be larger than ``window``.
 
@@ -172,12 +174,14 @@ As an example, if you wanted to generate 10 SPORES, all of which are within 10%
 
 .. code-block:: yaml
 
-    run.mode: spores
-    run.spores_options:
+    config.build.mode: spores
+    config.solve:
         spores_number: 10  # The number of SPORES to generate
-        slack: 0.1  # The fraction above the cost-optimal cost to set the maximum cost during SPORES
-        score_cost_class: spores_score  # The cost class to optimise against when generating SPORES
-        slack_cost_group: systemwide_cost_max  # The group constraint name in which the `cost_max` constraint is assigned, for use alongside the slack and cost-optimal cost
+        spores_score_cost_class: spores_score  # The cost class to optimise against when generating SPORES
+        spores_slack_cost_group: systemwide_cost_max  # The group constraint name in which the `cost_max` constraint is assigned, for use alongside the slack and cost-optimal cost
+    parameters:
+        slack:
+            data: 0.1  # The fraction above the cost-optimal cost to set the maximum cost during SPORES
 
 You will also need to manually set up some other parts of your model to deal with SPORES:
 
@@ -290,7 +294,7 @@ This is equivalent to the following override:
 Interfacing with the solver backend
 -----------------------------------
 
-On loading a model, there is no solver backend, only the input dataset. The backend is generated when a user calls `run()` on their model. Currently this will call back to Pyomo to build the model and send it off to the solver, given by the user in the run configuration :yaml:`run.solver`. Once built, solved, and returned, the user has access to the results dataset :python:`model.results` and interface functions with the backend :python:`model.backend`.
+On loading a model, there is no solver backend, only the input dataset. The backend is generated when a user calls `run()` on their model. Currently this will call back to Pyomo to build the model and send it off to the solver, given by the user in the run configuration :yaml:`config.solve.solver`. Once built, solved, and returned, the user has access to the results dataset :python:`model.results` and interface functions with the backend :python:`model.backend`.
 
 You can use this interface to:
 
@@ -326,7 +330,7 @@ Refer to the `Gurobi manual <https://www.gurobi.com/documentation/>`_, which con
 
 .. code-block:: yaml
 
-    run:
+    config.solve:
         solver: gurobi
         solver_options:
             Threads: 3
@@ -339,7 +343,7 @@ Refer to the `CPLEX parameter list <https://www.ibm.com/docs/en/icos/22.1.1?topi
 
 .. code-block:: yaml
 
-    run:
+    config.solve:
         solver: cplex
         solver_options:
             mipgap: 0.01
diff --git a/doc/user/building.rst b/doc/user/building.rst
index fb74232ed..19a6261c6 100644
--- a/doc/user/building.rst
+++ b/doc/user/building.rst
@@ -63,28 +63,130 @@ Inside the ``timeseries_data`` directory, timeseries are stored as CSV files. Th
 
     :ref:`yaml_format`, :doc:`ref_example_models`, :ref:`configuration_timeseries`
 
--------------------------------
-Model configuration (``model``)
--------------------------------
+.. _config:
 
-The model configuration specifies all aspects of the model to run. It is structured into several top-level headings (keys in the YAML file): ``model``, ``techs``, ``locations``, ``links``, and ``run``. We will discuss each of these in turn, starting with ``model``:
+--------------------------------
+Model configuration (``config``)
+--------------------------------
+
+The model configuration specifies all aspects of the model to run.
+It is structured into several top-level headings (keys in the YAML file): ``config``, ``parameters``, ``techs``, ``locations``, ``links``.
+We will discuss each of these in turn, starting with ``config``:
 
 .. code-block:: yaml
 
-    model:
-        name: 'My energy model'
-        timeseries_data_path: 'timeseries_data'
-        reserve_margin:
-            power: 0
-        subset_time: ['2005-01-01', '2005-01-05']
+    config:
+        init:
+            name: 'My energy model'
+            timeseries_data_path: 'timeseries_data'
+            subset_time: ['2005-01-01', '2005-01-05']
+        build:
+            mode: plan
+        solve:
+            solver: cbc
+
+The ``init`` configuration items are accessed when you initialise your model (`calliope.Model(...)`).
+The ``build`` configuration items are accessed when you build your optimisation problem (`calliope.Model.build(...)`).
+The ``solve`` configuration items are accessed when you solve your optimisation problem (`calliope.Model.solve(...)`).
+
+At each of these stages you can override what you have put in your YAML file (or if not in your YAML file, the default that Calliope uses), by providing additional keyword arguments on calling `calliope.Model` or its methods. E.g.,:
+
+.. code-block:: python
+
+    # Overriding `config.init` items in `calliope.Model`
+    model = calliope.Model("path/to/model.yaml", subset_time=["2005-01", "2005-02"])
+    # Overriding `config.build` items in `calliope.Model.build`
+    model.build(ensure_feasibility=True)
+    # Overriding `config.solve` items in `calliope.Model.solve`
+    model.solve(save_logs="path/to/logs/dir")
+
+None of the configuration options are _required_ as there is a default value for them all, but you will likely want to set `init.name`, `init.calliope_version`, `init.timeseries_data_path`, `build.mode`, and `solve.solver`.
+
+To test your model pipeline, `config.init.subset_time` is a good way to limit your model size by slicing the time dimension to a smaller range.
 
-Besides the model's name (``name``) and the path for CSV time series data (``timeseries_data_path``), group constraints can be set, like ``reserve_margin``.
+`config.build.mode`
+^^^^^^^^^^^^^^^^^^^
 
-To speed up model runs, the above example specifies a time subset to run the model over only five days of time series data (:yaml:`subset_time: ['2005-01-01', '2005-01-05']`)-- this is entirely optional. Usually, a full model will contain at least one year of data, but subsetting time can be useful to speed up a model for testing purposes.
+In the ``build`` section we have ``mode``.
+A model can run in ``plan``, ``operate``, or ``spores`` mode.
+In `plan` mode, capacities are determined by the model, whereas in `operate` mode, capacities are fixed and the system is operated with a receding horizon control algorithm.
+In `spores` mode, the model is first run in `plan` mode, then run `N` number of times to find alternative system configurations with similar monetary cost, but maximally different choice of technology capacity and location.
+
+`config.solve.solver`
+^^^^^^^^^^^^^^^^^^^^^
+Possible options for solver include ``glpk``, ``gurobi``, ``cplex``, and ``cbc``.
+The interface to these solvers is done through the Pyomo library. Any `solver compatible with Pyomo <https://pyomo.readthedocs.io/en/6.5.0/solving_pyomo_models.html#supported-solvers>`_ should work with Calliope.
+
+For solvers with which Pyomo provides more than one way to interface, the additional ``solver_io`` option can be used.
+In the case of Gurobi, for example, it is usually fastest to use the direct Python interface:
+
+.. code-block:: yaml
+
+    config:
+        solve:
+            solver: gurobi
+            solver_io: python
+
+.. note:: The opposite is currently true for CPLEX, which runs faster with the default ``solver_io``.
 
 .. seealso::
 
-    :ref:`National scale example model <examplemodels_nationalscale_settings>`, :ref:`config_reference_model`
+    :ref:`config_reference_config`, :doc:`troubleshooting`, :ref:`solver_options`, :ref:`documentation on operate mode <operational_mode>`, :ref:`documentation on SPORES mode <spores_mode>`, :doc:`built-in examples <ref_example_models>`
+
+-------------------------------------
+Top-level parameters (``parameters``)
+-------------------------------------
+
+Some data is not indexed over technologies / nodes (as will be described in more detail below).
+This data can be defined under the top-level key `parameters`.
+This could be a single value:
+
+.. code-block:: yaml
+
+    parameters:
+        my_param: 10
+
+or (equivalent):
+
+.. code-block:: yaml
+
+    parameters:
+        my_param:
+            data: 10
+
+which can then be accessed in the model inputs `model.inputs.my_param` and used in custom math as `my_param`.
+
+Or it can be indexed over one or more model dimension(s):
+
+.. code-block:: yaml
+
+    parameters:
+        my_indexed_param:
+            data: 100
+            index: [monetary]
+            dims: costs
+        my_multiindexed_param:
+            data: [2, 10]
+            index: [[monetary, electricity], [monetary, heat]]
+            dims: [costs, carriers]
+
+which can be accessed in the model inputs and custom math, e.g., `model.inputs.my_multiindexed_param.sel(costs="monetary")` and `my_multiindexed_param`.
+
+You can also index over a new dimension:
+
+.. code-block:: yaml
+
+    parameters:
+        my_indexed_param:
+            data: { my_coord: 100 }
+            dims: my_new_dim
+
+Which will add the new dimension `my_new_dim` to your model: `model.inputs.my_new_dim` which you could choose to build a math component over:
+`foreach: [my_new_dim]`.
+
+.. warning::
+
+    The `parameter` section should not be used for large datasets (e.g., indexing over the time dimension) as it will have a high memory overhead on loading the data.
 
 ------------------------
 Technologies (``techs``)
@@ -142,19 +244,19 @@ To use a single alternative cost class, disabling the consideration of the defau
     :ref:`config_reference_constraints`, :ref:`config_reference_costs`, :doc:`tutorials <tutorials>`, :doc:`built-in examples <ref_example_models>`
 
 Allowing for unmet demand
--------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^
 
 For a model to find a feasible solution, supply must always be able to meet demand. To avoid the solver failing to find a solution, you can ensure feasibility:
 
 .. code-block:: yaml
 
-    run:
+    config.build:
         ensure_feasibility: true
 
 This will create an ``unmet_demand`` decision variable in the optimisation, which can pick up any mismatch between supply and demand, across all carriers. It has a very high cost associated with its use, so it will only appear when absolutely necessary.
 
 .. note::
-    When ensuring feasibility, you can also set a `big M value <https://en.wikipedia.org/wiki/Big_M_method>`_ (:yaml:`run.bigM`). This is the "cost" of unmet demand. It is possible to make model convergence very slow if bigM is set too high. default bigM is 1x10 :sup:`9`, but should be close to the maximum total system cost that you can imagine. This is perhaps closer to 1x10 :sup:`6` for urban scale models.
+    When ensuring feasibility, you can also set a `big M value <https://en.wikipedia.org/wiki/Big_M_method>`_ (:yaml:`parameters.bigM`). This is the "cost" of unmet demand. It is possible to make model convergence very slow if bigM is set too high. default bigM is 1x10 :sup:`9`, but should be close to the maximum total system cost that you can imagine. This is perhaps closer to 1x10 :sup:`6` for urban scale models.
 
 .. _configuration_timeseries:
 
@@ -170,7 +272,7 @@ For parameters that vary in time, time series data can be added to a model in tw
 Reading in CSV files is possible from both the command-line tool as well running interactively with python (see :doc:`running` for details). However, passing dataframes as arguments in ``calliope.Model`` is possible only when running from a python session.
 
 Reading in CSV files
---------------------
+^^^^^^^^^^^^^^^^^^^^
 To read in CSV files, specify e.g., :yaml:`source: file=filename.csv` to pick the desired CSV file from within the configured timeseries data path (``model.timeseries_data_path``).
 
 By default, Calliope looks for a column in the CSV file with the same name as the location. It is also possible to specify a column to use when setting ``source`` per location, by giving the column name with a colon following the filename: :yaml:`source: file=filename.csv:column`
@@ -205,7 +307,7 @@ For example, the first few lines of a CSV file, called ``pv_resource.csv`` givin
     2005-01-01 06:00:00,90,458
 
 Reading in timeseries from ``pandas`` dataframes
-------------------------------------------------
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 When running models from python scripts or shells, it is also possible to pass timeseries directly as ``pandas`` dataframes. This is done by specifying :yaml:`source: df=tskey` where ``tskey`` is the key in a dictionary containing the relevant dataframes. For example, if the same timeseries as above is to be passed, a dataframe called ``pv_resource`` may be in the python namespace:
 
 .. code-block:: python
@@ -249,7 +351,6 @@ The time series index must be ISO 8601 compatible time stamps and can be a stand
 .. Note::
 
    * If a parameter is not explicit in time and space, it can be specified as a single value in the model definition (or, using location-specific definitions, be made spatially explicit). This applies both to parameters that never vary through time (for example, cost of installed capacity) and for those that may be time-varying (for example, a technology's available resource). However, each model must contain at least one time series.
-   * Only the subset of parameters listed in `file_allowed` in the :ref:`model configuration <config_reference_model>` can be loaded from file or dataframe in this way. It is advised not to update this default list unless you are developing the core code, since the model will likely behave unexpectedly.
    * You _cannot_ have a space around the ``=`` symbol when pointing to a timeseries file or dataframe key, i.e. :yaml:`source: file = filename.csv` is not valid.
    * If running from a command line interface (see :doc:`running`), timeseries must be read from CSV and cannot be passed from dataframes via ``df=...``.
    * It's possible to mix reading in from CSVs and dataframes, by setting some config values as ``file=...`` and some as ``df=...``.
@@ -298,40 +399,6 @@ The modeller can also specify a distance for each link, and use per-distance con
 
     :ref:`config_reference_constraints`, :ref:`config_reference_costs`.
 
-.. _run_config:
-
----------------------------
-Run configuration (``run``)
----------------------------
-
-The only required setting in the run configuration is the solver to use:
-
-.. code-block:: yaml
-
-    run:
-        solver: cbc
-        mode: plan
-
-the most important parts of the ``run`` section are ``solver`` and  ``mode``. A model can run in planning mode (``plan``), operational mode (``operate``), or SPORES mode (``spores``). In planning mode, capacities are determined by the model, whereas in operational mode, capacities are fixed and the system is operated with a receding horizon control algorithm. In SPORES mode, the model is first run in planning mode, then run `N` number of times to find alternative system configurations with similar monetary cost, but maximally different choice of technology capacity and location.
-
-Possible options for solver include ``glpk``, ``gurobi``, ``cplex``, and ``cbc``. The interface to these solvers is done through the Pyomo library. Any `solver compatible with Pyomo <https://pyomo.readthedocs.io/en/6.5.0/solving_pyomo_models.html#supported-solvers>`_ should work with Calliope.
-
-For solvers with which Pyomo provides more than one way to interface, the additional ``solver_io`` option can be used. In the case of Gurobi, for example, it is usually fastest to use the direct Python interface:
-
-.. code-block:: yaml
-
-    run:
-        solver: gurobi
-        solver_io: python
-
-.. note:: The opposite is currently true for CPLEX, which runs faster with the default ``solver_io``.
-
-Further optional settings, including debug settings, can be specified in the run configuration.
-
-.. seealso::
-
-    :ref:`config_reference_run`, :doc:`troubleshooting`, :ref:`solver_options`, :ref:`documentation on operational mode <operational_mode>`, :ref:`documentation on SPORES mode <spores_mode>`.
-
 .. _building_overrides:
 
 -----------------------
@@ -354,10 +421,7 @@ To make it easier to run a given model multiple times with slightly changed sett
         year2006:
             model.subset_time: ['2006-01-01', '2006-12-31']
 
-    model:
-        ...
-
-    run:
+    config:
         ...
 
 Each override is given by a name (e.g. ``high_cost``) and any number of model settings -- anything in the model configuration can be overridden by an override. In the above example, one override defines higher costs for an ``onshore_wind`` tech while the two other overrides specify different time subsets, so would run an otherwise identical model over two different periods of time series data.
diff --git a/doc/user/config_defaults.rst b/doc/user/config_defaults.rst
index 0fa626201..119eb9044 100644
--- a/doc/user/config_defaults.rst
+++ b/doc/user/config_defaults.rst
@@ -5,24 +5,31 @@ Configuration and defaults
 This section lists the available configuration options and constraints along with their default values.
 Defaults are automatically applied in constraints whenever there is no user input for a particular value.
 
-.. _config_reference_model:
+.. _config_reference_config:
 
-Model configuration
--------------------
+Model initialisation (``config.init``)
+--------------------------------------
 
 .. csv-table::
-   :file: includes/model_settings.csv
+   :file: includes/config_init.csv
    :header: Setting,Default,Comments
    :widths: 10, 5, 15
    :stub-columns: 0
 
-.. _config_reference_run:
+Optimisation problem build (``config.build``)
+---------------------------------------------
 
-Run configuration
------------------
+.. csv-table::
+   :file: includes/config_build.csv
+   :header: Setting,Default,Comments
+   :widths: 10, 5, 15
+   :stub-columns: 0
+
+Optimisation problem solve (``config.solve``)
+---------------------------------------------
 
 .. csv-table::
-   :file: includes/run_settings.csv
+   :file: includes/config_solve.csv
    :header: Setting,Default,Comments
    :widths: 10, 5, 15
    :stub-columns: 0
diff --git a/doc/user/ref_formulation.rst b/doc/user/ref_formulation.rst
index 3517f430f..c5380401f 100644
--- a/doc/user/ref_formulation.rst
+++ b/doc/user/ref_formulation.rst
@@ -10,7 +10,7 @@ All built-in Calliope math can be found in the calliope `math directory <https:/
 
 By default, the :ref:`base math <base_math>` is loaded from file.
 If you want to overwrite the base math with other built-in math, you can do so by referring to the file by its name (without the file extension) in :yaml:`model.custom_math`, e.g. :yaml:`model.custom_math: [storage_inter_cluster]`.
-When solving the model in a :ref:`run mode <run_config>` other than `plan`, some built-in custom math will be applied automatically from a file of the same name (`spores` mode custom math is stored in `math/spores.yaml <https://github.com/calliope-project/calliope/blob/main/calliope/math/spores.yaml>`_).
+When solving the model in a :ref:`run mode <config_reference_config>` other than `plan`, some built-in custom math will be applied automatically from a file of the same name (e.g., `spores` mode custom math is stored in `math/spores.yaml <https://github.com/calliope-project/calliope/blob/main/calliope/math/spores.yaml>`_).
 The changes made by the built-in custom math are detailed in this page.
 
 .. note:: Custom math is applied in the order it appears in the :yaml:`model.custom_math` list. By default, any run mode custom math will be applied as the final step. If you want to apply your own custom math *after* the run mode custom math, you should add it explicitly to the :yaml:`model.custom_math` list, e.g., :yaml:`model.custom_math: [operate, my_custom_math.yaml]`.
@@ -64,4 +64,4 @@ SPORES mode custom math
 Below are the changes from the base math introduced by the built-in custom math file ``spores``.
 These changes are applied automatically if selecting the run mode ``spores``
 
-TODO: Add spores math
\ No newline at end of file
+TODO: Add spores math
diff --git a/doc/user/running.rst b/doc/user/running.rst
index d51e33ac0..c17b87873 100644
--- a/doc/user/running.rst
+++ b/doc/user/running.rst
@@ -110,7 +110,7 @@ There are two ways to override a base model when running interactively, analogou
 
         model = calliope.Model(
             'model.yaml',
-            override_dict={'run.solver': 'gurobi'}
+            override_dict={'config.solve.solver': 'gurobi'}
         )
 
 .. note:: Both `scenario` and `override_dict` can be defined at once. They will be applied in order, such that scenarios are applied first, followed by dictionary overrides. As such, the `override_dict` can be used to override scenarios.
diff --git a/doc/user/troubleshooting.rst b/doc/user/troubleshooting.rst
index 4fac3322c..f63986470 100644
--- a/doc/user/troubleshooting.rst
+++ b/doc/user/troubleshooting.rst
@@ -7,10 +7,21 @@ General strategies
 
 * **Building a smaller model**: :yaml:`model.subset_time` allows specifying a subset of timesteps to be used. This can be useful for debugging purposes as it can dramatically speed up model solution times. The timestep subset can be specified as :yaml:`[startdate, enddate]`, e.g. :yaml:`['2005-01-01', '2005-01-31']`, or as a single time period, such as :yaml:`2005-01` to select January only. The subsets are processed before building the model and applying time resolution adjustments, so time resolution reduction functions will only see the reduced set of data.
 
-* **Retaining logs and temporary files**: The setting :yaml:`run.save_logs`, disabled by default, sets the directory into which to save logs and temporary files from the backend, to inspect solver logs and solver-generated model files. This also turns on symbolic solver labels in the Pyomo backend, so that all model components in the backend model are named according to the corresponding Calliope model components (by default, Pyomo uses short random names for all generated model components).
+* **Retaining logs and temporary files**: The setting :yaml:`config.solve.save_logs`, disabled by default, sets the directory into which to save logs and temporary files from the backend, to inspect solver logs and solver-generated model files. This also turns on symbolic solver labels in the Pyomo backend, so that all model components in the backend model are named according to the corresponding Calliope model components (by default, Pyomo uses short random names for all generated model components).
 
 *
-  **Analysing the optimisation problem without running the model**: If you are comfortable with navigating Pyomo objects, then you can build the Pyomo model backend without running the optimisation problem, using :python:`model.run(build_only=True)`. Pyomo objects are then accessible within :python:`model._backend_model`. For instance, the constraint limiting flow capacity can be viewed by calling :python:`model._backend_model.flow_capacity_constraint.pprint('hi')`. Alternatively, if you are working from the command line or have little experience with Pyomo, you can generate an LP file. The LP file contains the mathematical model formulation of a fully built Calliope model. It is a standard format that can be passed to various solvers. Examining the LP file manually or using additional tools (see below) can help find issues when a model is infeasible or unbounded. To build a model and save it to LP without actually solving it, use:
+  **Analysing the optimisation problem without running the model**: If you are comfortable with navigating Pyomo objects, then you can inspect the Pyomo model backend after building it using :python:`model.build()`.
+  Pyomo objects are then accessible within :python:`model.backend`.
+  For instance, the constraints limiting outflows can be viewed by calling :python:`model.backend.get_constraint("flow_out_max")`.
+  A single Pyomo object can be then accessed by slicing the resulting array: :python:`model.backend.get_constraint("flow_out_max").sel(techs=...)`.
+  You can also view the data in a more readable format by using setting the `as_backend_objs` option to false: :python:`constr = model.backend.get_constraint("flow_out_max", as_backend_objs=False)`.
+  This will allow you to inspect constraint upper bounds (`constr.ub`), lower bounds (`constr.lb`), and bodies as math strings (`constr.body`).
+
+  Alternatively, if you are working from the command line or have little experience with Pyomo, you can generate an LP file.
+  The LP file contains the mathematical model formulation of a fully built Calliope model.
+  It is a standard format that can be passed to various solvers.
+  Examining the LP file manually or using additional tools (see below) can help find issues when a model is infeasible or unbounded.
+  To build a model and save it to LP without actually solving it, use:
 
   .. code-block:: shell
 
@@ -111,7 +122,7 @@ Using the Gurobi solver
 
 To understand infeasible models:
 
-* Set :yaml:`run.solver_options.DualReductions: 0` to see whether a model is infeasible or unbounded.
+* Set :yaml:`config.solve.solver_options: {DualReductions: 0}` to see whether a model is infeasible or unbounded.
 * To analyse infeasible models, save an LP file with the :sh:`--save_lp` command-line option, then use Gurobi to generate an Irreducible Inconsistent Subsystem that shows which constraints are infeasible:
 
   .. code-block:: shell
@@ -120,18 +131,18 @@ To understand infeasible models:
 
   More detail on this is in the `official Gurobi documentation <https://www.gurobi.com/documentation/current/refman/solving_a_model2.html>`_.
 
-To deal with numerically unstable models, try setting :yaml:`run.solver_options.Presolve: 0`, as large numeric ranges can cause the pre-solver to generate an `infeasible or numerically unstable model <https://www.gurobi.com/documentation/current/refman/numerics_why_scaling_and_g.html>`_. The `Gurobi Guidelines for Numerical Issues <https://www.gurobi.com/documentation/current/refman/numerics_gurobi_guidelines.html>`_ give detailed guidance for strategies to address numerically difficult optimisation problems.
+To deal with numerically unstable models, try setting :yaml:`config.solve.solver_options: {Presolve: 0}`, as large numeric ranges can cause the pre-solver to generate an `infeasible or numerically unstable model <https://www.gurobi.com/documentation/current/refman/numerics_why_scaling_and_g.html>`_. The `Gurobi Guidelines for Numerical Issues <https://www.gurobi.com/documentation/current/refman/numerics_gurobi_guidelines.html>`_ give detailed guidance for strategies to address numerically difficult optimisation problems.
 
 Using the CPLEX solver
 ^^^^^^^^^^^^^^^^^^^^^^
 
 There are two ways to understand infeasibility when using the CPLEX solver, the first is quick and the second is more involved:
 
-1. Save solver logs for your model (:yaml:`run.save_logs: path/to/log_directory`). In the directory, open the file ending in '.cplex.log' to see the CPLEX solver report. If the model is infeasible or unbounded, the offending constraint will be identified (e.g. "`SOLVER: Infeasible variable = slack c_u_flow_out_max_constraint(region1_2__csp__power_2005_01_01_07_00_00)_`"). This may be enough to understand why the model is failing, if not...
+1. Save solver logs for your model (:yaml:`config.solve.save_logs: path/to/log_directory`). In the directory, open the file ending in '.cplex.log' to see the CPLEX solver report. If the model is infeasible or unbounded, the offending constraint will be identified (e.g. "`SOLVER: Infeasible variable = slack c_u_flow_out_max_constraint(region1_2__csp__power_2005_01_01_07_00_00)_`"). This may be enough to understand why the model is failing, if not...
 
 2. Open the LP file in CPLEX interactive (run `cplex` in the command line to invoke a CPLEX interactive session). The LP file for the problem ends with '.lp' in the log folder (`read path/to/file.lp`). Once loaded, you can try relaxing variables / constraints to see if the problem can be solved with relaxation (`FeasOpt`). You can also identify conflicting constraints (`tools conflict`) and print those constraints directly (`display conflict all`). There are many more commands available to analyse individual constraints and variables in the `Official CPLEX documentation <https://www.ibm.com/docs/en/icos/22.1.0?topic=cplex-infeasibility-unboundedness>`_.
 
-Similar to Gurobi, numerically unstable models may lead to unexpected infeasibility, so you can try :yaml:`run.solver_options.preprocessing_presolve: 0` or you can request CPLEX to more aggressively scale the problem itself using the `solver option <https://www.ibm.com/docs/en/icos/22.1.1?topic=parameters-scale-parameter>`_ ``read_scale: 1`` . The `CPLEX documentation page on numeric difficulties <https://www.ibm.com/docs/en/icos/22.1.1?topic=problems-numeric-difficulties>`_ goes into more detail on numeric instability.
+Similar to Gurobi, numerically unstable models may lead to unexpected infeasibility, so you can try :yaml:`config.solve.solver_options: {preprocessing_presolve: 0}` or you can request CPLEX to more aggressively scale the problem itself using the `solver option <https://www.ibm.com/docs/en/icos/22.1.1?topic=parameters-scale-parameter>`_ ``read_scale: 1`` . The `CPLEX documentation page on numeric difficulties <https://www.ibm.com/docs/en/icos/22.1.1?topic=problems-numeric-difficulties>`_ goes into more detail on numeric instability.
 
 
 Rerunning a model
diff --git a/src/calliope/backend/backend_model.py b/src/calliope/backend/backend_model.py
index 34d3052f8..8cb86cee9 100644
--- a/src/calliope/backend/backend_model.py
+++ b/src/calliope/backend/backend_model.py
@@ -3,9 +3,11 @@
 
 from __future__ import annotations
 
+import importlib
 import logging
 import typing
 from abc import ABC, abstractmethod
+from copy import deepcopy
 from pathlib import Path
 from typing import (
     TYPE_CHECKING,
@@ -20,10 +22,12 @@
 )
 
 import numpy as np
-import pandas as pd
 import xarray as xr
 
+from calliope import exceptions
 from calliope.backend import parsing
+from calliope.core.attrdict import AttrDict
+from calliope.core.util.tools import validate_dict
 
 if TYPE_CHECKING:
     from calliope.backend.parsing import T as Tp
@@ -42,7 +46,7 @@ class BackendModelGenerator(ABC):
     _VALID_COMPONENTS: tuple[_COMPONENTS_T, ...] = typing.get_args(_COMPONENTS_T)
     _COMPONENT_ATTR_METADATA = ["description", "unit"]
 
-    def __init__(self, inputs: xr.Dataset):
+    def __init__(self, inputs: xr.Dataset, **config_overrides):
         """Abstract base class to build a representation of the optimisation problem.
 
         Args:
@@ -50,7 +54,11 @@ def __init__(self, inputs: xr.Dataset):
         """
 
         self._dataset = xr.Dataset()
-        self.inputs = inputs
+        self.inputs = inputs.copy()
+        self.inputs.attrs = deepcopy(inputs.attrs)
+        self.inputs.attrs["config"].build.union(
+            AttrDict(config_overrides), allow_override=True
+        )
         self.valid_math_element_names: set = set()
         self._solve_logger = logging.getLogger(__name__ + ".<solve>")
 
@@ -178,6 +186,50 @@ def log(
             f"Optimisation model | {component_type}:{component_name} | {message}"
         )
 
+    def _build(self) -> None:
+        self._add_run_mode_custom_math()
+        # The order of adding components matters!
+        # 1. Variables, 2. Global Expressions, 3. Constraints, 4. Objectives
+        for components in [
+            "variables",
+            "global_expressions",
+            "constraints",
+            "objectives",
+        ]:
+            component = components.removesuffix("s")
+            if components in ["variables", "global_expressions"]:
+                self.valid_math_element_names.update(
+                    self.inputs.math[components].keys()
+                )
+            for name in self.inputs.math[components]:
+                getattr(self, f"add_{component}")(name)
+            LOGGER.info(
+                f"Optimisation Model: Generated optimisation problem {components}"
+            )
+
+    def _add_run_mode_custom_math(self) -> None:
+        """If not given in the custom_math list, override model math with run mode math"""
+
+        # FIXME: available modes should not be hardcoded here. They should come from a YAML schema.
+        mode = self.inputs.attrs["config"].build.mode
+        custom_math = self.inputs.attrs["applied_custom_math"]
+        not_run_mode = {"plan", "operate", "spores"}.difference([mode])
+        run_mode_mismatch = not_run_mode.intersection(custom_math)
+        if run_mode_mismatch:
+            exceptions.warn(
+                f"Running in {mode} mode, but run mode(s) {run_mode_mismatch} custom "
+                "math being loaded from file via the model configuration"
+            )
+
+        if mode != "plan" and mode not in custom_math:
+            LOGGER.debug(f"Updating math formulation with {mode} mode custom math.")
+            filepath = importlib.resources.files("calliope") / "math" / f"{mode}.yaml"
+            self.inputs.math.union(AttrDict.from_yaml(filepath), allow_override=True)
+        math_schema = AttrDict.from_yaml(
+            importlib.resources.files("calliope") / "config" / "math_schema.yaml"
+        )
+        validate_dict(self.inputs.math, math_schema, "math")
+
     def _add_component(
         self,
         name: str,
@@ -211,7 +263,7 @@ def _add_component(
         if component_dict is None:
             component_dict = self.inputs.math[component_type][name]
 
-        if break_early and component_dict.get("active", False):
+        if break_early and not component_dict.get("active", True):
             self.log(
                 component_type, name, "Component deactivated and therefore not built."
             )
@@ -302,19 +354,13 @@ def _create_obj_list(self, key: str, component_type: _COMPONENTS_T) -> None:
 
     def _add_all_inputs_as_parameters(self) -> None:
         """
-        Add all parameters to backend dataset in-place, including those in the run configuration.
+        Add all parameters to backend dataset in-place.
         If model data does not include a parameter, their default values will be added here
         as unindexed backend dataset parameters.
 
-        TODO: Move the decision on which run config params to generate as backend params
-              earlier in the process.
-        Parameters in "objective_options" and the bigM parameter will be added from
-        run configuration.
-
         Args:
             model_data (xr.Dataset): Input model data.
             defaults (dict): Parameter defaults.
-            run_config (UpdateObserverDict): Run configuration dictionary.
         """
 
         for param_name, param_data in self.inputs.filter_by_attrs(
@@ -331,25 +377,7 @@ def _add_all_inputs_as_parameters(self) -> None:
             self.add_parameter(
                 param_name, xr.DataArray(default_val), use_inf_as_na=False
             )
-
-        for option_name, option_val in self.inputs.run_config.get(
-            "objective_options", {}
-        ).items():
-            if option_name == "cost_class":
-                objective_cost_class = {
-                    k: v for k, v in option_val.items() if k in self.inputs.costs
-                }
-                self.add_parameter(
-                    "objective_cost_class",
-                    xr.DataArray.from_series(
-                        pd.Series(objective_cost_class).rename_axis(index="costs")
-                    ),
-                )
-            else:
-                self.add_parameter("objective_" + option_name, xr.DataArray(option_val))
-        self.add_parameter(
-            "bigM", xr.DataArray(self.inputs.run_config.get("bigM", 1e10))
-        )
+        LOGGER.info("Optimisation Model: Generated optimisation problem parameters")
 
     @staticmethod
     def _clean_arrays(*args) -> None:
@@ -493,14 +521,14 @@ def objectives(self):
 
 
 class BackendModel(BackendModelGenerator, Generic[T]):
-    def __init__(self, inputs: xr.Dataset, instance: T) -> None:
-        """Abstract base class to build bakcend models that interface with solvers.
+    def __init__(self, inputs: xr.Dataset, instance: T, **config_overrides) -> None:
+        """Abstract base class to build backend models that interface with solvers.
 
         Args:
             inputs (xr.Dataset): Calliope model data.
             instance (T): Interface model instance.
         """
-        super().__init__(inputs)
+        super().__init__(inputs, **config_overrides)
         self._instance = instance
 
     @abstractmethod
diff --git a/src/calliope/backend/helper_functions.py b/src/calliope/backend/helper_functions.py
index 877462083..eb0850d3b 100644
--- a/src/calliope/backend/helper_functions.py
+++ b/src/calliope/backend/helper_functions.py
@@ -194,10 +194,16 @@ def as_array(self, parameter: str, *, over: Union[str, list[str]]) -> xr.DataArr
                 parameter_da.notnull()
                 & (parameter_da != np.inf)
                 & (parameter_da != -np.inf)
-            ).any(dim=over, keep_attrs=True)
+            )
+        elif parameter in self._kwargs.get("backend_dataset", xr.Dataset()).data_vars:
+            bool_parameter_da = self._kwargs["backend_dataset"][parameter].notnull()
         else:
             bool_parameter_da = xr.DataArray(False)
-        return bool_parameter_da
+        if not isinstance(over, list):
+            over = [over]
+        available_dims = set(bool_parameter_da.dims).intersection(over)
+
+        return bool_parameter_da.any(dim=available_dims, keep_attrs=True)
 
 
 class Sum(ParsingHelperFunction):
diff --git a/src/calliope/backend/latex_backend_model.py b/src/calliope/backend/latex_backend_model.py
index 19dbeafa9..36b109550 100644
--- a/src/calliope/backend/latex_backend_model.py
+++ b/src/calliope/backend/latex_backend_model.py
@@ -4,7 +4,7 @@
 import textwrap
 import typing
 from pathlib import Path
-from typing import Any, Callable, Literal, Optional, Union, overload
+from typing import TYPE_CHECKING, Any, Literal, Optional, Union, overload
 
 import jinja2
 import numpy as np
@@ -13,6 +13,9 @@
 from calliope.backend import backend_model, parsing
 from calliope.exceptions import ModelError
 
+if TYPE_CHECKING:
+    pass
+
 _ALLOWED_MATH_FILE_FORMATS = Literal["tex", "rst", "md"]
 
 
@@ -20,20 +23,16 @@
 
 
 class MathDocumentation:
-    def __init__(self, backend_builder: Callable) -> None:
+    def __init__(self) -> None:
         """Math documentation builder/writer
 
         Args:
             backend_builder (Callable):
                 Method to generate all optimisation problem components on a calliope.backend_model.BackendModel object.
         """
-        self._builder = backend_builder
         self._inputs: xr.Dataset
 
-    def build(
-        self,
-        include: Literal["all", "valid"] = "all",
-    ) -> None:
+    def build(self, include: Literal["all", "valid"] = "all", **kwargs) -> None:
         """Build string representations of the mathematical formulation using LaTeX math notation, ready to be written with `write`.
 
         Args:
@@ -41,9 +40,10 @@ def build(
                 Defines whether to include all possible math equations ("all") or only those for which at least one index item in the "where" string is valid ("valid"). Defaults to "all".
         """
 
-        backend = LatexBackendModel(self._inputs, include=include)
+        backend = LatexBackendModel(self._inputs, include=include, **kwargs)
+        backend._build()
 
-        self._instance = self._builder(backend)
+        self._instance = backend
 
     @property
     def inputs(self):
@@ -263,7 +263,10 @@ class LatexBackendModel(backend_model.BackendModelGenerator):
     FORMAT_STRINGS = {"rst": RST_DOC, "tex": TEX_DOC, "md": MD_DOC}
 
     def __init__(
-        self, inputs: xr.Dataset, include: Literal["all", "valid"] = "all"
+        self,
+        inputs: xr.Dataset,
+        include: Literal["all", "valid"] = "all",
+        **config_overrides,
     ) -> None:
         """Interface to build a string representation of the mathematical formulation using LaTeX math notation.
 
@@ -271,7 +274,7 @@ def __init__(
             include (Literal["all", "valid"], optional):
                 Defines whether to include all possible math equations ("all") or only those for which at least one index item in the "where" string is valid ("valid"). Defaults to "all".
         """
-        super().__init__(inputs)
+        super().__init__(inputs, **config_overrides)
         self.include = include
 
         self._add_all_inputs_as_parameters()
@@ -355,7 +358,7 @@ def _variable_setter(where: xr.DataArray) -> xr.DataArray:
             return where.where(where)
 
         if variable_dict is None:
-            variable_dict = self.inputs.math["variables"][name]
+            variable_dict = self.inputs.attrs["math"]["variables"][name]
 
         parsed_component = self._add_component(
             name,
@@ -388,7 +391,7 @@ def add_objective(
             "maximise": r"\max{}",
         }
         if objective_dict is None:
-            objective_dict = self.inputs.math["objectives"][name]
+            objective_dict = self.inputs.attrs["math"]["objectives"][name]
         equation_strings: list = []
 
         def _objective_setter(
diff --git a/src/calliope/backend/pyomo_backend_model.py b/src/calliope/backend/pyomo_backend_model.py
index 21cf20e31..95ceab400 100644
--- a/src/calliope/backend/pyomo_backend_model.py
+++ b/src/calliope/backend/pyomo_backend_model.py
@@ -50,8 +50,8 @@
 
 
 class PyomoBackendModel(backend_model.BackendModel):
-    def __init__(self, inputs: xr.Dataset):
-        super().__init__(inputs, instance=pmo.block())
+    def __init__(self, inputs: xr.Dataset, **config_overrides):
+        super().__init__(inputs, instance=pmo.block(), **config_overrides)
 
         self._instance.parameters = pmo.parameter_dict()
         self._instance.variables = pmo.variable_dict()
@@ -159,7 +159,7 @@ def add_variable(
         domain_dict = {"real": pmo.RealSet, "integer": pmo.IntegerSet}
 
         if variable_dict is None:
-            variable_dict = self.inputs.math["variables"][name]
+            variable_dict = self.inputs.attrs["math"]["variables"][name]
         self.valid_math_element_names.add(name)
 
         def _variable_setter(where):
@@ -186,15 +186,15 @@ def add_objective(
         sense_dict = {"minimize": 1, "minimise": 1, "maximize": -1, "maximise": -1}
 
         if objective_dict is None:
-            objective_dict = self.inputs.math["objectives"][name]
+            objective_dict = self.inputs.attrs["math"]["objectives"][name]
         sense = sense_dict[objective_dict["sense"]]
 
         def _objective_setter(
             element: parsing.ParsedBackendEquation, where: xr.DataArray, references: set
         ) -> xr.DataArray:
             expr = element.evaluate_expression(self.inputs, self, references=references)
-            objective = pmo.objective(expr.item(), sense=sense)
-            if name == self.inputs.run_config["objective"]:
+            objective = pmo.objective(xr.DataArray(expr).item(), sense=sense)
+            if name == self.inputs.attrs["config"].build.objective:
                 text = "activated"
                 objective.activate()
             else:
@@ -416,7 +416,9 @@ def update_parameter(
                 )
             self.delete_component(name, "parameters")
             self.add_parameter(
-                name, new_values, default=self.inputs.defaults.get(name, np.nan)
+                name,
+                new_values,
+                default=self.inputs.attrs["defaults"].get(name, np.nan),
             )
             for ref in refs_to_update:
                 self._rebuild_reference(ref)
@@ -451,7 +453,7 @@ def update_variable_bounds(
                 )
                 continue
 
-            existing_bound_param = self.inputs.math.get_key(
+            existing_bound_param = self.inputs.attrs["math"].get_key(
                 f"variables.{name}.bounds.{bound_name}", None
             )
             if existing_bound_param in self.parameters:
diff --git a/src/calliope/backend/where_parser.py b/src/calliope/backend/where_parser.py
index c9723591c..75887d558 100644
--- a/src/calliope/backend/where_parser.py
+++ b/src/calliope/backend/where_parser.py
@@ -94,18 +94,17 @@ def __init__(self, instring: str, loc: int, tokens: pp.ParseResults) -> None:
             tokens (pp.ParseResults):
                 Has two parsed elements: config group name (str) and config option (str).
         """
-        config_group, self.config_option = tokens
-        self.config_group = f"{config_group}_config"
+        self.config_option = tokens[0]
         self.instring = instring
         self.loc = loc
 
     def __repr__(self):
         "Return string representation of the parsed grammar"
-        return f"CONFIG:{self.config_group}.{self.config_option}"
+        return f"CONFIG:{self.config_option}"
 
     def as_latex(self) -> str:
         """Add return input string for use in a LaTex math formula"""
-        return rf"\text{{{self.config_group}.{self.config_option}}}"
+        return rf"\text{{config.{self.config_option}}}"
 
     def eval(
         self, model_data: xr.Dataset, **kwargs
@@ -120,17 +119,11 @@ def eval(
         Returns:
             Optional[Union[int, float, str, bool, np.bool_]]: Configuration option value.
         """
-        if self.config_group not in model_data.attrs:
-            raise BackendError(
-                f"(where, {self.instring}): Invalid configuration group defined"
-            )
-        elif kwargs.get("as_latex", False):
+
+        if kwargs.get("as_latex", False):
             return self.as_latex()
         else:
-            config_dict = model_data.attrs[self.config_group]
-            # TODO: either remove the default key return or make it optional with
-            # a "strict" arg
-            config_val = config_dict.get_key(self.config_option, np.nan)
+            config_val = model_data.attrs["config"].build[self.config_option]
 
             if not isinstance(config_val, (int, float, str, bool, np.bool_)):
                 raise BackendError(
@@ -410,13 +403,7 @@ def config_option_parser(generic_identifier: pp.ParserElement) -> pp.ParserEleme
             Parser for configuration options which will be accessed from the configuration
             dictionary attached to the attributes of the Calliope model dataset.
     """
-    config_group = generic_identifier + pp.FollowedBy(".")
-    config_options = pp.ZeroOrMore("." + generic_identifier)
-    data_var = (
-        config_group
-        + pp.Suppress(".")
-        + pp.Combine(generic_identifier + config_options)
-    )
+    data_var = pp.Suppress("config.") + generic_identifier
     data_var.set_parse_action(ConfigOptionParser)
 
     return data_var
@@ -555,8 +542,11 @@ def generate_where_string_parser() -> pp.ParserElement:
     config_option = config_option_parser(generic_identifier)
     bool_operand = bool_parser()
     evaluatable_string = evaluatable_string_parser(generic_identifier)
+    id_list = (
+        pp.Suppress("[") + pp.delimited_list(evaluatable_string) + pp.Suppress("]")
+    )
     helper_function = expression_parser.helper_function_parser(
-        evaluatable_string, number, generic_identifier=generic_identifier
+        evaluatable_string, number, id_list, generic_identifier=generic_identifier
     )
     comparison = comparison_parser(
         evaluatable_string,
diff --git a/src/calliope/cli.py b/src/calliope/cli.py
index dcf4eeb93..e5678c3f5 100644
--- a/src/calliope/cli.py
+++ b/src/calliope/cli.py
@@ -182,7 +182,7 @@ def new(path, template, debug):
     with format_exceptions(debug):
         if template is None:
             template = "national_scale"
-        source_path = examples._PATHS[template]
+        source_path = examples.EXAMPLE_MODEL_DIR / template
         click.echo("Copying {} template to target directory: {}".format(template, path))
         shutil.copytree(source_path, path)
 
@@ -292,7 +292,7 @@ def run(
             click.secho("Starting model run...")
 
             if save_logs:
-                model.run_config["save_logs"] = save_logs
+                model.config.set_key("solve.save_logs", save_logs)
 
             if save_csv is None and save_netcdf is None:
                 click.secho(
@@ -304,12 +304,11 @@ def run(
             # If save_netcdf is used, override the 'save_per_spore_path' to point to a
             # directory of the same name as the planned netcdf
 
-            if save_netcdf and model.run_config.get("spores_options", {}).get(
-                "save_per_spore", False
-            ):
-                model.run_config["spores_options"][
-                    "save_per_spore_path"
-                ] = save_netcdf.replace(".nc", "/spore_{}.nc")
+            if save_netcdf and model.config.solve.spores_save_per_spore:
+                model.config.set_key(
+                    "solve.spores_save_per_spore_path",
+                    save_netcdf.replace(".nc", "/spore_{}.nc"),
+                )
 
             model.build()
             model.solve()
diff --git a/src/calliope/config/defaults.yaml b/src/calliope/config/defaults.yaml
index ae8c10254..4ca530c2e 100644
--- a/src/calliope/config/defaults.yaml
+++ b/src/calliope/config/defaults.yaml
@@ -8,62 +8,49 @@
 # Model-wide default settings
 ##
 
-run:
-  backend: pyomo # Backend to use to build and solve the model. As of v0.6.0, only `pyomo` is available
-  bigM: 1e9 # Used for unmet demand, but should be of a similar order of magnitude as the largest cost that the model could achieve. Too high and the model will not converge
-  cyclic_storage: true # If true, storage in the last timestep of the timeseries is considered to be the 'previous timestep' in the first timestep of the timeseries
-  ensure_feasibility: false # If true, unmet_demand will be a decision variable, to account for an ability to meet demand with the available supply. If False and a mismatch occurs, the optimisation will fail due to infeasibility
-  mode: plan # Which mode to run the model in: 'plan', 'operation' or 'spores'
-  objective_options: { "cost_class": { "monetary": 1 }, "sense": "minimize" } # Arguments to pass to objective function. If cost-based objective function in use, should include 'cost_class' and 'sense' (maximize/minimize)
-  objective: minmax_cost_optimisation # Name of internal objective function to use, currently only min/max cost-based optimisation is available
-  operation: # Settings for operational mode
-    window: null
-    horizon: null
-    use_cap_results: false
-  spores_options: # settings for SPORES (spatially-explicit, practically optimal results) mode
-    spores_number: 3 # The number of SPORES to generate
-    slack: 0.1 # The fraction above the cost-optimal cost to set the maximum cost during SPORES
-    score_cost_class: spores_score # The cost class to optimise against when generating SPORES
-    objective_cost_class: { spores_score: 1, monetary: 0 } # The updated cost class weightings inthe objective when running SPORES
-    slack_cost_group: null # The group constraint name in which the `cost_max` constraint is assigned, for use alongside the slack and cost-optimal cost
-    save_per_spore: false # whether or not to save each SPORE run results separately or as one concatenated NetCDF. If True, "save_per_spore_path" or CLI argument "--to_netcdf" must be defined (to_netcdf will take precendence and be used a the directory name).
-    save_per_spore_path: null # file path for each spore run, which will be used if save_per_spore is used, and CLI command "--to_netcdf" is not defined. Will apply spore number using the python "format" method, so the path should include a "{}" at the position where the spore number should be included (e.g. "/path/to/spores/spore_{}.nc" will save results for SPORE 1 to "/path/to/spores/spore_1.nc"). The cost-optimal solution will be saved by using spore number 0.
-    skip_cost_op: false # whether or not to run the initial cost optimisation model to ascertain the cost-optimal cost and initial spores scores. If True, will take the group constraint and cost_flow_cap values directly.
-  save_logs: null # Directory into which to save logs and temporary files. Also turns on symbolic solver labels in the Pyomo backend
-  solver_io: null # What method the Pyomo backend should use to communicate with the solver
-  solver_options: null # A list of options, which are passed on to the chosen solver, and are therefore solver-dependent
-  solver: cbc # Which solver to use
-  zero_threshold: 1e-10 # Any value coming out of the backend that is smaller than this threshold (due to floating point errors, probably) will be set to zero
+config:
+  init:
+    name: null # Model name
+    calliope_version: null # Calliope framework version this model is intended for
+    random_seed: null # Seed for random number generator used during clustering
+    subset_time: null # Subset of timesteps as a two-element list giving the range, e.g. ['2005-01-01', '2005-01-05'], or a single string, e.g. '2005-01'
+    time: null # Optional settings to adjust time resolution, see :ref:`time_clustering` for the available options
+    timeseries_data_path: null # Path to time series data
+    timeseries_dateformat: "ISO8601" # Timestamp format of all time series data when read from file. "ISO8601" means "YYYY-mm-dd HH:MM:SS".
+    custom_math: [] # List of references to files which contain custom mathematical formulations. If referring to an in-built Calliope custom math file (see documentation for available files), do not append the reference with ".yaml". If referring to your own custom math file, ensure the file type is given as a suffix (".yaml" or ".yml"). Relative paths will be assumed to be relative to the `config` file given when creating a calliope Model (`calliope.Model(config)`)
+  build:
+    backend: pyomo  # Module with which to build the optimisation problem
+    cyclic_storage: true  # whether or not to link storage levels in the last model timestep with the first model timestep. `inter_cluster_storage` custom math must be included if using time clustering and setting this to True.
+    ensure_feasibility: false  # whether to include decision variables in the model which will meet unmet demand or consume unused supply in the model so that the optimisation solves successfully. This should only be used as a debugging option (as any unmet demand/unused supply is a sign of improper model formulation).
+    mode: plan  # Mode in which to run the optimisation. Options: [plan, operate, spores]
+    objective: minmax_cost_optimisation # Name of internal objective function to use, currently only min/max cost-based optimisation is available
+  solve:
+    operate_window: null  # Operate mode rolling `window`
+    operate_horizon: null  # Operate mode rolling `horizon` (≥ `window`)
+    operate_use_cap_results: false  # If the model already contains `plan` mode results, use those optimal capacities as input parameters to the `operate` mode run.
+    spores_number: 3  # SPORES mode number of iterations after the initial base run.
+    spores_score_cost_class: spores_score  # SPORES mode cost class to vary between iterations after the initial base run.
+    spores_slack_cost_group: null  # SPORES mode cost class to keep below the given `slack` (usually "monetary").
+    spores_save_per_spore: false  # Whether or not to save the result of each SPORES mode run between iterations. If False, will consolidate all iterations into one dataset after completion of N iterations (defined by `spores_number`) and save that one dataset.
+    spores_save_per_spore_path: null  # If saving per spore, the path to save to.
+    spores_skip_cost_op: false  # If the model already contains `plan` mode results, use those as the initial base run results and start with SPORES iterations immediately.
+    save_logs: null  # If given, should be a path to a directory in which to save optimisation logs.
+    solver_io: null  # Some solvers have different interfaces that perform differently. For instance, setting `solver_io="python"` when using the solver `gurobi` tends to reduce the time to send the optimisation problem to the solver.
+    solver_options: null  # Any solver options, as key-value pairs, to pass to the chosen solver
+    solver: cbc  # Solver to use. Any solvers that have Pyomo interfaces can be used. Refer to the Pyomo documentation for the latest list.
+    zero_threshold: 1e-10  # On postprocessing the optimisation results, values smaller than this threshold will be considered as optimisation artefacts and will be set to zero.
 
-model:
-  calliope_version: null # Calliope framework version this model is intended for
-  name: null # Model name
-  random_seed: null # Seed for random number generator used during clustering
-  reserve_margin: {} # Per-carrier system-wide reserve margins
-  subset_time: null # Subset of timesteps as a two-element list giving the range, e.g. ['2005-01-01', '2005-01-05'], or a single string, e.g. '2005-01'
-  time: {} # Optional settings to adjust time resolution, see :ref:`time_clustering` for the available options
-  timeseries_data_path: null # Path to time series data
-  timeseries_data: null # Dict of dataframes with time series data (when passing in dicts rather than YAML files to Model constructor)
-  timeseries_dateformat: "ISO8601" # Timestamp format of all time series data when read from file. "ISO8601" means "YYYY-mm-dd HH:MM:SS".
-  file_allowed: [
-      "clustering_func",
-      "flow_eff",
-      "flow_ramping",
-      "export",
-      "om_con",
-      "om_prod",
-      "parasitic_eff",
-      "sink_min",
-      "sink_max",
-      "sink_equals",
-      "source_min",
-      "source_max",
-      "source_equals",
-      "source_eff",
-      "storage_loss",
-      "carrier_ratios",
-    ] # List of configuration options allowed to specify "file=" to load timeseries data. This can be updated if you're adding a new custom constraint that requires a newly defined parameter to be a timeseries. If updating existing parameters, you can expect existing constraints to not change behaviour or to break on being constructed.
-  custom_math: [] # List of references to files which contain custom mathematical formulations. If referring to an in-built Calliope custom math file (see documentation for available files), do not append the reference with ".yaml". If referring to your own custom math file, ensure the file type is given as a suffix (".yaml" or ".yml"). Relative paths will be assumed to be relative to the `config` file given when creating a calliope Model (`calliope.Model(config)`)
+parameters:
+  # BigM is a large value used to define certain optimisation problems.
+  # See https://en.wikipedia.org/wiki/Big_M_method for more information.
+  # This value should be larger than the largest values that any decision variables can take,
+  # but should not be **too** large (i.e., do not set it greater than 3 orders of magnitude above the numeric range of the model).
+  # if too large, numerical problems may arise in the optimisation.
+  bigM: 1e9
+  objective_cost_class: # Weightings for cost classes to apply in the objective function.
+    data: 1
+    index: [monetary]
+    dims: costs
 
 ##
 # Base technology groups
diff --git a/src/calliope/core/attrdict.py b/src/calliope/core/attrdict.py
index f6d07f0e8..653ced493 100644
--- a/src/calliope/core/attrdict.py
+++ b/src/calliope/core/attrdict.py
@@ -177,7 +177,7 @@ def from_yaml(cls, f, resolve_imports=True):
             overrides definitions in the imported file.
 
         """
-        if isinstance(f, str) or isinstance(f, Path):
+        if isinstance(f, (str, Path)):
             with open(
                 f,
                 "r",
diff --git a/src/calliope/core/model.py b/src/calliope/core/model.py
index dc37fc562..a20e94602 100644
--- a/src/calliope/core/model.py
+++ b/src/calliope/core/model.py
@@ -10,11 +10,14 @@
 """
 from __future__ import annotations
 
+import importlib
 import logging
 import warnings
+from copy import deepcopy
 from pathlib import Path
-from typing import Callable, Literal, Optional, TypeVar, Union
+from typing import Callable, Optional, TypeVar, Union
 
+import pandas as pd
 import xarray
 
 import calliope
@@ -52,16 +55,15 @@ class Model(object):
     """
 
     _BACKENDS: dict[str, Callable] = {"pyomo": PyomoBackendModel}
-    _MATH_SCHEMA = AttrDict.from_yaml(
-        Path(calliope.__file__).parent / "config" / "math_schema.yaml"
-    )
 
     def __init__(
         self,
-        config: Optional[Union[str, dict]],
+        model_definition: Optional[Union[str, Path, dict]] = None,
         model_data: Optional[xarray.Dataset] = None,
         debug: bool = False,
-        *args,
+        scenario: Optional[str] = None,
+        override_dict: Optional[dict] = None,
+        timeseries_dataframes: Optional[dict[str, pd.DataFrame]] = None,
         **kwargs,
     ):
         """
@@ -69,7 +71,7 @@ def __init__(
         configuration file or a dict fully specifying the model.
 
         Args:
-            config (Optional[Union[str, dict]]):
+            config (Optional[Union[str, Path, dict]]):
                 If str, must be the path to a model configuration file.
                 If dict or AttrDict, must fully specify the model.
             model_data (Optional[xarray.Dataset], optional):
@@ -79,40 +81,50 @@ def __init__(
             debug (bool, optional):
                 If True, additional debug data will be included in the built model.
                 Defaults to False.
-
-        Keyword Args:
-            timeseries_dataframes (dict[str, pd.DataFrame]):
-                If supplying `config` as a dictionary, in-memory timeseries data can be referred to using `df=...`.
-                The referenced data must be supplied here as a dicitionary of dataframes.
             scenario (str):
                 Comma delimited string of pre-defined `scenarios` to apply to the model,
             override_dict (dict):
                 Additional overrides to apply to `config`.
                 These will be applied *after* applying any defined `scenario` overrides.
+            timeseries_dataframes (dict[str, pd.DataFrame], optional):
+                If supplying `config` as a dictionary, in-memory timeseries data can be referred to using `df=...`.
+                The referenced data must be supplied here as a dicitionary of dataframes.
+                Defaults to None.
 
         Raises:
             ValueError: `config` must be provided (as one of `str`, `int`, `None`).
         """
         self._timings: dict = {}
         self.defaults: AttrDict
-        self.model_config: AttrDict
-        self.run_config: AttrDict
+        self.config: AttrDict
         self.math: AttrDict
-        self._config_path: Optional[str]
-        self.math_documentation = MathDocumentation(self._build)
+        self._model_def_path: Optional[str]
+        self.math_documentation = MathDocumentation()
 
         # try to set logging output format assuming python interactive. Will
         # use CLI logging format if model called from CLI
         log_time(LOGGER, self._timings, "model_creation", comment="Model: initialising")
-        if isinstance(config, str):
-            self._config_path = config
-            model_run, debug_data = model_run_from_yaml(config, *args, **kwargs)
+        if isinstance(model_definition, (str, Path)):
+            self._model_def_path = Path(model_definition).as_posix()
+            model_run, debug_data = model_run_from_yaml(
+                model_definition,
+                scenario,
+                override_dict,
+                timeseries_dataframes,
+                **kwargs,
+            )
             self._init_from_model_run(model_run, debug_data, debug)
-        elif isinstance(config, dict):
-            self._config_path = None
-            model_run, debug_data = model_run_from_dict(config, *args, **kwargs)
+        elif isinstance(model_definition, dict):
+            self._model_def_path = None
+            model_run, debug_data = model_run_from_dict(
+                model_definition,
+                scenario,
+                override_dict,
+                timeseries_dataframes,
+                **kwargs,
+            )
             self._init_from_model_run(model_run, debug_data, debug)
-        elif model_data is not None and config is None:
+        elif model_data is not None and model_definition is None:
             self._init_from_model_data(model_data)
         else:
             # expected input is a string pointing to a YAML file of the run
@@ -122,6 +134,10 @@ def __init__(
                 "Input configuration must either be a string or a dictionary."
             )
 
+    @property
+    def name(self):
+        return self._model_data.attrs["name"]
+
     def _init_from_model_run(
         self, model_run: calliope.AttrDict, debug_data: calliope.AttrDict, debug: bool
     ) -> None:
@@ -162,20 +178,19 @@ def _init_from_model_run(
         )
 
         # Ensure model and run attributes of _model_data update themselves
-        model_config = {
-            k: v for k, v in model_run.get("model", {}).items() if k != "file_allowed"
-        }
+        init_config = model_run.config.pop("init")
+        build_solve_config = model_run.config
 
-        self._add_observed_dict("model_config", model_config)
-        self._add_observed_dict("run_config", model_run["run"])
+        self._add_observed_dict("config", build_solve_config)
         self._add_observed_dict("defaults", self._generate_default_dict())
 
-        math = self._add_math(model_config["custom_math"])
+        math = self._add_math(init_config.custom_math)
         self._add_observed_dict("math", math)
 
         self.inputs = self._model_data.filter_by_attrs(is_result=0)
         self.math_documentation.inputs = self._model_data
 
+        self._model_data.attrs["name"] = init_config["name"]
         log_time(
             LOGGER,
             self._timings,
@@ -220,8 +235,7 @@ def _add_model_data_methods(self):
         """
         self.inputs = self._model_data.filter_by_attrs(is_result=0)
         self.results = self._model_data.filter_by_attrs(is_result=1)
-        self._add_observed_dict("model_config")
-        self._add_observed_dict("run_config")
+        self._add_observed_dict("config")
         self._add_observed_dict("math")
 
         self.inputs = self._model_data.filter_by_attrs(is_result=0)
@@ -291,7 +305,7 @@ def _add_math(self, custom_math: list) -> AttrDict:
             if not f"{filename}".endswith((".yaml", ".yml")):
                 yaml_filepath = math_dir / f"{filename}.yaml"
             else:
-                yaml_filepath = Path(relative_path(self._config_path, filename))
+                yaml_filepath = Path(relative_path(self._model_def_path, filename))
 
             if not yaml_filepath.is_file():
                 file_errors.append(filename)
@@ -304,6 +318,7 @@ def _add_math(self, custom_math: list) -> AttrDict:
             raise exceptions.ModelError(
                 f"Attempted to load custom math that does not exist: {file_errors}"
             )
+        self._model_data.attrs["applied_custom_math"] = custom_math
         return base_math
 
     def _generate_default_dict(self) -> AttrDict:
@@ -335,26 +350,7 @@ def _generate_default_dict(self) -> AttrDict:
             }
         )
 
-    def _add_run_mode_custom_math(self) -> None:
-        """If not given in the custom_math list, override model math with run mode math"""
-        run_mode = self.run_config["mode"]
-        # FIXME: available modes should not be hardcoded here.
-        # They should come from a YAML schema.
-        not_run_mode = {"plan", "operate", "spores"}.difference([run_mode])
-        run_mode_mismatch = not_run_mode.intersection(self.model_config["custom_math"])
-        if run_mode_mismatch:
-            exceptions.warn(
-                f"Running in {run_mode} mode, but run mode(s) {run_mode_mismatch} custom "
-                "math being loaded from file via the model configuration"
-            )
-
-        if run_mode != "plan" and run_mode not in self.model_config["custom_math"]:
-            filepath = Path(calliope.__file__).parent / "math" / f"{run_mode}.yaml"
-            self.math.union(AttrDict.from_yaml(filepath), allow_override=True)
-
-    def build(
-        self, force: bool = False, backend_interface: Literal["pyomo"] = "pyomo"
-    ) -> None:
+    def build(self, force: bool = False, **kwargs) -> None:
         """Build description of the optimisation problem in the chosen backend interface.
 
         Args:
@@ -370,41 +366,13 @@ def build(
                 "This model object already has a built optimisation problem. Use model.build(force=True) "
                 "to force the existing optimisation problem to be overwritten with a new one."
             )
-        backend = self._BACKENDS[backend_interface](self._model_data)
-        self.backend = self._build(backend)
+        backend_name = kwargs.get("backend", self.config.build.backend)
 
-    def _build(self, backend: T) -> T:
-        log_time(
-            LOGGER,
-            self._timings,
-            "backend_parameters_generated",
-            comment="Model: Generated optimisation problem parameters",
-        )
-        self._add_run_mode_custom_math()
-        validate_dict(self.math, self._MATH_SCHEMA, "math")
-        # The order of adding components matters!
-        # 1. Variables, 2. Global Expressions, 3. Constraints, 4. Objectives
-        for components in [
-            "variables",
-            "global_expressions",
-            "constraints",
-            "objectives",
-        ]:
-            component = components.removesuffix("s")
-            if components in ["variables", "global_expressions"]:
-                backend.valid_math_element_names.update(self.math[components].keys())
-            for name in self.math[components]:
-                getattr(backend, f"add_{component}")(name)
-
-            log_time(
-                LOGGER,
-                self._timings,
-                f"backend_{components}_generated",
-                comment=f"Model: Generated optimisation problem {components}",
-            )
-        return backend
+        backend = self._BACKENDS[backend_name](self._model_data, **kwargs)
+        backend._build()
+        self.backend = backend
 
-    def solve(self, force: bool = False, warmstart: bool = False) -> None:
+    def solve(self, force: bool = False, warmstart: bool = False, **kwargs) -> None:
         """
         Run the built optimisation problem.
 
@@ -426,7 +394,9 @@ def solve(self, force: bool = False, warmstart: bool = False) -> None:
             exceptions.ModelError: Cannot run the model if there are already results loaded, unless `force` is True.
             exceptions.ModelError: Some preprocessing steps will stop a run mode of "operate" from being possible.
         """
-        run_mode = self.run_config["mode"]
+        run_mode = self.config.build.mode
+        solver_config = deepcopy(self.config.solve)
+        solver_config.union(AttrDict(kwargs), allow_override=True)
 
         # Check that results exist and are non-empty
         if not hasattr(self, "backend"):
@@ -461,10 +431,10 @@ def solve(self, force: bool = False, warmstart: bool = False) -> None:
         )
 
         termination_condition = self.backend.solve(
-            solver=self.run_config["solver"],
-            solver_io=self.run_config.get("solver_io", None),
-            solver_options=self.run_config.get("solver_options", None),
-            save_logs=self.run_config.get("save_logs", None),
+            solver=solver_config["solver"],
+            solver_io=solver_config["solver_io"],
+            solver_options=solver_config["solver_options"],
+            save_logs=solver_config["save_logs"],
             warmstart=warmstart,
         )
 
@@ -539,7 +509,7 @@ def info(self) -> str:
             str: Basic description of the model.
         """
         info_strings = []
-        model_name = self.model_config.get("name", "None")
+        model_name = self.name
         info_strings.append(f"Model name:   {model_name}")
         msize = dict(self._model_data.dims)
         msize_exists = (self._model_data.node_tech * self._model_data.carrier).sum()
@@ -572,8 +542,10 @@ def validate_math_strings(self, math_dict: dict) -> None:
             If all components of the dictionary are parsed successfully, this function will log a success message to the INFO logging level and return None.
             Otherwise, a calliope.ModelError will be raised with parsing issues listed.
         """
-
-        validate_dict(math_dict, self._MATH_SCHEMA, "math")
+        math_schema = AttrDict.from_yaml(
+            importlib.resources.files("calliope") / "config" / "math_schema.yaml"
+        )
+        validate_dict(math_dict, math_schema, "math")
         valid_math_element_names = [
             *self.math["variables"].keys(),
             *self.math["global_expressions"].keys(),
@@ -581,9 +553,6 @@ def validate_math_strings(self, math_dict: dict) -> None:
             *math_dict.get("global_expressions", {}).keys(),
             *self.inputs.data_vars.keys(),
             *self.defaults.keys(),
-            # FIXME: these should not be hardcoded, but rather end up in model data keys
-            "bigM",
-            *["objective_" + k for k in self.run_config["objective_options"].keys()],
         ]
         collected_errors: dict = dict()
         for component_group, component_dicts in math_dict.items():
diff --git a/src/calliope/core/util/tools.py b/src/calliope/core/util/tools.py
index ef4223a99..f5d5bbf41 100644
--- a/src/calliope/core/util/tools.py
+++ b/src/calliope/core/util/tools.py
@@ -6,6 +6,7 @@
 import importlib
 import os
 import sys
+from pathlib import Path
 from typing import TypeVar
 
 import jsonschema
@@ -67,7 +68,7 @@ def relative_path(base_path_file, path):
 
     """
     # Check if base_path_file is a string because it might be an AttrDict
-    if not os.path.isabs(path) and isinstance(base_path_file, str):
+    if not os.path.isabs(path) and isinstance(base_path_file, (str, Path)):
         path = os.path.join(os.path.dirname(base_path_file), path)
     return path
 
diff --git a/src/calliope/example_models/national_scale/model.yaml b/src/calliope/example_models/national_scale/model.yaml
index a8aae5863..1f40e98dc 100644
--- a/src/calliope/example_models/national_scale/model.yaml
+++ b/src/calliope/example_models/national_scale/model.yaml
@@ -4,27 +4,27 @@ import: # Import other files from paths relative to this file, or absolute paths
   - "scenarios.yaml" # Scenario and override group definitions
 
 # Model configuration: all settings that affect the built model
-model:
-  name: National-scale example model
-
-  # What version of Calliope this model is intended for
-  calliope_version: 0.7.0
-
-  # Time series data path - can either be a path relative to this file, or an absolute path
-  timeseries_data_path: "timeseries_data"
-
-  subset_time: ["2005-01-01", "2005-01-05"] # Subset of timesteps
-
-# Run configuration: all settings that affect how the built model is run
-run:
-  solver: cbc
-
-  ensure_feasibility: true # Switches on the "unmet demand" constraint
+config:
+  init:
+    name: National-scale example model
+    # What version of Calliope this model is intended for
+    calliope_version: 0.7.0
+    # Time series data path - can either be a path relative to this file, or an absolute path
+    timeseries_data_path: "timeseries_data"
+    subset_time: ["2005-01-01", "2005-01-05"] # Subset of timesteps
+
+  build:
+    ensure_feasibility: true # Switches on the "unmet demand" constraint
+    mode: plan # Choices: plan, operate
+
+  solve:
+    solver: cbc
+    zero_threshold: 1e-10 # Any value coming out of the backend that is smaller than this (due to floating point errors, probably) will be set to zero
+
+parameters:
+  objective_cost_class:
+    data: 1
+    index: [monetary]
+    dims: costs
 
   bigM: 1e6 # Sets the scale of unmet demand, which cannot be too high, otherwise the optimisation will not converge
-
-  zero_threshold: 1e-10 # Any value coming out of the backend that is smaller than this (due to floating point errors, probably) will be set to zero
-
-  mode: plan # Choices: plan, operate
-
-  objective_options.cost_class: { monetary: 1 }
diff --git a/src/calliope/example_models/national_scale/scenarios.yaml b/src/calliope/example_models/national_scale/scenarios.yaml
index 24ac55d4f..1d50e7aca 100644
--- a/src/calliope/example_models/national_scale/scenarios.yaml
+++ b/src/calliope/example_models/national_scale/scenarios.yaml
@@ -10,35 +10,46 @@ scenarios:
 ##
 overrides:
   profiling:
-    model.name: "National-scale example model (profiling run)"
-    model.subset_time: ["2005-01-01", "2005-01-15"]
-    run.solver: cbc
+    config:
+      init.name: "National-scale example model (profiling run)"
+      init.subset_time: ["2005-01-01", "2005-01-15"]
+      solve.solver: cbc
 
   time_resampling:
-    model.name: "National-scale example model with time resampling"
-    model.subset_time: ["2005-01", "2005-01"]
-    # Resample time resolution to 6-hourly
-    model.time: { function: resample, function_options: { "resolution": "6H" } }
+    config:
+      init:
+        name: "National-scale example model with time resampling"
+        subset_time: ["2005-01", "2005-01"]
+        # Resample time resolution to 6-hourly
+        time: { function: resample, function_options: { "resolution": "6H" } }
 
   time_clustering:
-    model.random_seed: 23
-    model.name: "National-scale example model with time clustering"
-    model.subset_time: null # No time subsetting
-    # Cluster timesteps using k-means
-    model.time:
-      {
-        function: apply_clustering,
-        function_options: { clustering_func: "kmeans", how: "closest", k: 10 },
-      }
+    config:
+      init:
+        random_seed: 23
+        name: "National-scale example model with time clustering"
+        subset_time: null # No time subsetting
+        # Cluster timesteps using k-means
+        time:
+          function: apply_clustering
+          function_options: { clustering_func: "kmeans", how: "closest", k: 10 }
 
   spores:
-    run.mode: spores
-    run.spores_options:
-      score_cost_class: "spores_score"
-      slack: 0.1
-      spores_number: 3
-      objective_cost_class: { "monetary": 0, "spores_score": 1 }
-    run.objective_options.cost_class: { "monetary": 1, "spores_score": 0 }
+    config:
+      build.mode: spores
+      solve:
+        spores_score_cost_class: "spores_score"
+        spores_number: 3
+    parameters:
+      spores_slack: # In SPORES mode, slack to apply when setting the upper limit on system `spores_slack_cost_group` costs. The constraint will limit the costs to `(spores_slack + 1) * sum(costs[cost=spores_slack_cost_group])`.
+        data: 0.1
+      objective_cost_class:
+        data: [1, 0]
+        index: ["monetary", "spores_score"]
+      spores_objective_cost_class:  # In SPORES mode, the new objective function cost class weightings to apply after the initial base run.
+        data: [1, 0]
+        index: [spores_score, monetary]
+        dims: costs
     # FIXME: replace group constraint in SPORES mode
     # group_constraints:
     #    systemwide_cost_max.cost_max.monetary: 1e10  # very large, non-infinite value
@@ -53,11 +64,12 @@ overrides:
     techs.ac_transmission.costs.spores_score.interest_rate: 1
 
   operate:
-    run.mode: operate
-    run.operation:
-      window: 12
-      horizon: 24
-    model.subset_time: ["2005-01-01", "2005-01-10"]
+    config:
+      init.subset_time: ["2005-01-01", "2005-01-10"]
+      build.mode: operate
+      solve:
+        operate_window: 12
+        operate_horizon: 24
     nodes:
       region1.techs.ccgt.constraints.flow_cap_max: 30000
 
@@ -83,31 +95,34 @@ overrides:
       region1,region1-3.techs.free_transmission.constraints.flow_cap_max: 2281
 
   check_feasibility:
-    run:
-      ensure_feasibility: False
-      objective: "check_feasibility"
-    model:
-      subset_time: ["2005-01-04", "2005-01-04"]
+    config:
+      build:
+        ensure_feasibility: False
+        objective: "check_feasibility"
+      init:
+        subset_time: ["2005-01-04", "2005-01-04"]
 
   reserve_margin:
-    model:
+    parameters:
       # Model-wide settings for the system-wide reserve margin
       # Even setting a reserve margin of zero activates the constraint,
       # forcing enough installed capacity to cover demand in
       # the maximum demand timestep
       reserve_margin:
-        power: 0.10 # 10% reserve margin for power
+        data: 0.10 # 10% reserve margin for power
+        index: power
+        dims: carriers
 
   ##
   # Overrides to demonstrate the run generator ("calliope generate_runs")
   ##
 
   run1:
-    model.subset_time: ["2005-01-01", "2005-01-31"]
+    config.init.subset_time: ["2005-01-01", "2005-01-31"]
   run2:
-    model.subset_time: ["2005-02-01", "2005-02-31"]
+    config.init.subset_time: ["2005-02-01", "2005-02-31"]
   run3:
-    model.subset_time: ["2005-01-01", "2005-01-31"]
+    config.init.subset_time: ["2005-01-01", "2005-01-31"]
     nodes.region1.techs.ccgt.constraints.flow_cap_max: 0 # Disallow CCGT
   run4:
     subset_time: ["2005-02-01", "2005-02-31"]
@@ -158,9 +173,8 @@ overrides:
   #                         flow_cap_max: 100000  # Increased to keep model feasible
 
   minimize_emissions_costs:
-    run:
-      objective_options:
-        cost_class: { "emissions": 1, "monetary": 0 }
+    parameters:
+      objective_cost_class.data: { "emissions": 1, "monetary": 0 }
     techs:
       ccgt:
         costs:
@@ -172,10 +186,8 @@ overrides:
             om_prod: 10 # kgCO2/kWh
 
   maximize_utility_costs:
-    run:
-      objective_options:
-        cost_class: { "utility": 1, "monetary": 0 }
-        sense: maximize
+    parameters:
+      objective_cost_class.data: { "utility": -1, "monetary": 0 }
     techs:
       ccgt:
         costs:
diff --git a/src/calliope/example_models/urban_scale/model.yaml b/src/calliope/example_models/urban_scale/model.yaml
index 91d70caf5..58fe595e7 100644
--- a/src/calliope/example_models/urban_scale/model.yaml
+++ b/src/calliope/example_models/urban_scale/model.yaml
@@ -3,24 +3,25 @@ import: # Import other files from paths relative to this file, or absolute paths
   - "model_config/locations.yaml"
   - "scenarios.yaml"
 
-model:
-  name: Urban-scale example model
-
-  # What version of Calliope this model is intended for
-  calliope_version: 0.7.0
-
-  # Time series data path - can either be a path relative to this file, or an absolute path
-  timeseries_data_path: "timeseries_data"
-
-  subset_time: ["2005-07-01", "2005-07-02"] # Subset of timesteps
-
-run:
-  mode: plan # Choices: plan, operate
-
-  solver: cbc
-
-  ensure_feasibility: true # Switching on unmet demand
-
+config:
+  init:
+    name: Urban-scale example model
+    # What version of Calliope this model is intended for
+    calliope_version: 0.7.0
+    # Time series data path - can either be a path relative to this file, or an absolute path
+    timeseries_data_path: "timeseries_data"
+    subset_time: ["2005-07-01", "2005-07-02"] # Subset of timesteps
+
+  build:
+    mode: plan # Choices: plan, operate
+    ensure_feasibility: true # Switching on unmet demand
+
+  solve:
+    solver: cbc
+
+parameters:
+  objective_cost_class:
+    data: 1
+    index: [monetary]
+    dims: costs
   bigM: 1e6 # setting the scale of unmet demand, which cannot be too high, otherwise the optimisation will not converge
-
-  objective_options.cost_class: { monetary: 1 }
diff --git a/src/calliope/example_models/urban_scale/scenarios.yaml b/src/calliope/example_models/urban_scale/scenarios.yaml
index aceaabd34..21af5777e 100644
--- a/src/calliope/example_models/urban_scale/scenarios.yaml
+++ b/src/calliope/example_models/urban_scale/scenarios.yaml
@@ -4,8 +4,9 @@
 
 overrides:
   milp:
-    model.name: "Urban-scale example model with MILP"
-    run.solver_options.mipgap: 0.05
+    config:
+      init.name: "Urban-scale example model with MILP"
+      solve.solver_options: { mipgap: 0.05 }
     techs:
       # chp-start
       chp:
@@ -47,11 +48,13 @@ overrides:
       N1,X3.techs.heat_pipes.distance: 4
 
   operate:
-    run.mode: operate
-    run.operation:
-      window: 24
-      horizon: 48
-    model.subset_time: ["2005-07-01", "2005-07-10"]
+    config:
+      init.subset_time: ["2005-07-01", "2005-07-10"]
+      build.mode: operate
+      solve:
+        operate_window: 24
+        operate_horizon: 48
+
     nodes:
       X1:
         techs:
@@ -80,17 +83,19 @@ overrides:
       N1,X3.techs.heat_pipes.constraints.flow_cap_max: 320
 
   time_masking:
-    model.name: "Urban-scale example model with time masking"
-    model.subset_time: ["2005-01", "2005-01"]
-    # Resample time resolution to 6-hourly
-    model.time:
-      masks:
-        - function: extreme_diff
-          options:
-            tech0: demand_heat
-            tech1: demand_electricity
-            how: max
-            n: 2
-            var: sink_equals
-      function: resample
-      function_options: { resolution: 6H }
+    config:
+      init:
+      name: "Urban-scale example model with time masking"
+      subset_time: ["2005-01", "2005-01"]
+      # Resample time resolution to 6-hourly
+      time:
+        masks:
+          - function: extreme_diff
+            options:
+              tech0: demand_heat
+              tech1: demand_electricity
+              how: max
+              n: 2
+              var: sink_equals
+        function: resample
+        function_options: { resolution: 6H }
diff --git a/src/calliope/examples.py b/src/calliope/examples.py
index 19734be18..ada4a4d4e 100644
--- a/src/calliope/examples.py
+++ b/src/calliope/examples.py
@@ -9,75 +9,51 @@
 
 """
 
-import os
+import importlib
 
 from calliope.core.model import Model
 
-_PATHS = {
-    "national_scale": os.path.join(
-        os.path.dirname(__file__), "example_models", "national_scale"
-    ),
-    "urban_scale": os.path.join(
-        os.path.dirname(__file__), "example_models", "urban_scale"
-    ),
-}
+EXAMPLE_MODEL_DIR = importlib.resources.files("calliope") / "example_models"
 
 
 def national_scale(*args, **kwargs):
     """Returns the built-in national-scale example model."""
-    return Model(os.path.join(_PATHS["national_scale"], "model.yaml"), *args, **kwargs)
-
-
-def time_clustering(*args, **kwargs):
-    """Returns the built-in national-scale example model with time clustering."""
     return Model(
-        os.path.join(_PATHS["national_scale"], "model.yaml"),
-        scenario="time_clustering",
+        model_definition=EXAMPLE_MODEL_DIR / "national_scale" / "model.yaml",
         *args,
         **kwargs,
     )
 
 
+def time_clustering(*args, **kwargs):
+    """Returns the built-in national-scale example model with time clustering."""
+    return national_scale(scenario="time_clustering", *args, **kwargs)
+
+
 def time_resampling(*args, **kwargs):
     """Returns the built-in national-scale example model with time resampling."""
-    return Model(
-        os.path.join(_PATHS["national_scale"], "model.yaml"),
-        scenario="time_resampling",
-        *args,
-        **kwargs,
-    )
+    return national_scale(scenario="time_resampling", *args, **kwargs)
 
 
 def urban_scale(*args, **kwargs):
     """Returns the built-in urban-scale example model."""
-    return Model(os.path.join(_PATHS["urban_scale"], "model.yaml"), *args, **kwargs)
-
-
-def milp(*args, **kwargs):
-    """Returns the built-in urban-scale example model with MILP constraints enabled."""
     return Model(
-        os.path.join(_PATHS["urban_scale"], "model.yaml"),
-        scenario="milp",
+        model_definition=EXAMPLE_MODEL_DIR / "urban_scale" / "model.yaml",
         *args,
         **kwargs,
     )
 
 
+def milp(*args, **kwargs):
+    """Returns the built-in urban-scale example model with MILP constraints enabled."""
+    return urban_scale(scenario="milp", *args, **kwargs)
+
+
 def operate(*args, **kwargs):
     """Returns the built-in urban-scale example model in operate mode."""
-    return Model(
-        os.path.join(_PATHS["urban_scale"], "model.yaml"),
-        scenario="operate",
-        *args,
-        **kwargs,
-    )
+    return urban_scale(scenario="operate", *args, **kwargs)
 
 
 def time_masking(*args, **kwargs):
     """Returns the built-in urban-scale example model with time masking."""
-    return Model(
-        os.path.join(_PATHS["urban_scale"], "model.yaml"),
-        scenario="time_masking",
-        *args,
-        **kwargs,
-    )
+    return urban_scale(scenario="time_masking", *args, **kwargs)
diff --git a/src/calliope/math/base.yaml b/src/calliope/math/base.yaml
index 580655ce2..5770329e2 100644
--- a/src/calliope/math/base.yaml
+++ b/src/calliope/math/base.yaml
@@ -172,9 +172,9 @@ constraints:
         - where: "NOT any(export_carrier, over=techs)"
           expression: "0"
       unmet_demand_and_unused_supply:
-        - where: "run.ensure_feasibility=True"
+        - where: "config.ensure_feasibility=True"
           expression: unmet_demand + unused_supply
-        - where: "NOT run.ensure_feasibility=True"
+        - where: "NOT config.ensure_feasibility=True"
           expression: "0"
 
   balance_supply:
@@ -256,11 +256,11 @@ constraints:
     sub_expressions:
       flow_out: *flow_out_with_parasitic
       storage_previous_step: &storage_previous_step
-        - where: timesteps=get_val_at_index(timesteps=0) AND NOT run.cyclic_storage=True
+        - where: timesteps=get_val_at_index(timesteps=0) AND NOT config.cyclic_storage=True
           expression: storage_initial * storage_cap
-        - where: ((timesteps=get_val_at_index(timesteps=0) AND run.cyclic_storage=True) OR NOT timesteps=get_val_at_index(timesteps=0)) AND NOT lookup_cluster_first_timestep=True
+        - where: ((timesteps=get_val_at_index(timesteps=0) AND config.cyclic_storage=True) OR NOT timesteps=get_val_at_index(timesteps=0)) AND NOT lookup_cluster_first_timestep=True
           expression: (1 - storage_loss) ** roll(timestep_resolution, timesteps=1) * roll(storage, timesteps=1)
-        - where: lookup_cluster_first_timestep=True AND NOT (timesteps=get_val_at_index(timesteps=0) AND NOT run.cyclic_storage=True)
+        - where: lookup_cluster_first_timestep=True AND NOT (timesteps=get_val_at_index(timesteps=0) AND NOT config.cyclic_storage=True)
           expression: (1 - storage_loss) ** select_from_lookup_arrays(timestep_resolution, timesteps=lookup_cluster_last_timestep) * select_from_lookup_arrays(storage, timesteps=lookup_cluster_last_timestep)
 
   source_availability_supply_plus:
@@ -292,7 +292,7 @@ constraints:
   set_storage_initial:
     description: "Fix the relationship between carrier stored in a `storage` technology at the start and end of the whole model period."
     foreach: [nodes, techs]
-    where: "storage AND storage_initial AND run.cyclic_storage=True"
+    where: "storage AND storage_initial AND config.cyclic_storage=True"
     equations:
       - expression: storage[timesteps=$final_step] * ((1 - storage_loss) ** timestep_resolution[timesteps=$final_step]) == storage_initial * storage_cap
     slices:
@@ -598,7 +598,7 @@ variables:
     description: "Virtual source of carrier flow to ensure model feasibility. This should only be considered a debugging rather than a modelling tool as it may distort the model in other ways due to the large impact it has on the objective function value. When present in a model in which it has been requested, it indicates an inability for technologies in the model to reach a sufficient combined supply capacity to meet demand."
     unit: energy
     foreach: [nodes, carriers, timesteps]
-    where: "run.ensure_feasibility=True"
+    where: "config.ensure_feasibility=True"
     bounds:
       min: 0
       max: .inf
@@ -607,21 +607,24 @@ variables:
     description: "Virtual sink of carrier flow to ensure model feasibility. This should only be considered a debugging rather than a modelling tool as it may distort the model in other ways due to the large impact it has on the objective function value. In model results, the negation of this variable is combined with `unmet_demand` and presented as only one variable: `unmet_demand`. When present in a model in which it has been requested, it indicates an inability for technologies in the model to reach a sufficient combined consumption capacity to meet required outflow (e.g. from renewables without the possibility of curtailment)."
     unit: energy
     foreach: [nodes, carriers, timesteps]
-    where: "run.ensure_feasibility=True"
+    where: "config.ensure_feasibility=True"
     bounds:
       min: -.inf
       max: 0
 
 objectives:
   minmax_cost_optimisation:
-    description: "Minimise the total cost of installing and operation all technologies in the system. If multiple cost classes are present (e.g., monetary and co2 emissions), the weighted sum of total costs is minimised. Cost class weights can be defined in `run.objective_options.cost_class`."
+    description: "Minimise the total cost of installing and operation all technologies in the system. If multiple cost classes are present (e.g., monetary and co2 emissions), the weighted sum of total costs is minimised. Cost class weights can be defined in the top-level parameter `objective_cost_class`."
     equations:
-      - expression: sum(sum(cost, over=[nodes, techs]) * objective_cost_class, over=costs) + $unmet_demand
+      - where: "any(cost, over=[nodes, techs, costs])"
+        expression: sum(sum(cost, over=[nodes, techs]) * objective_cost_class, over=costs) + $unmet_demand
+      - where: "NOT any(cost, over=[nodes, techs, costs])"
+        expression: $unmet_demand
     sub_expressions:
       unmet_demand:
-        - where: "run.ensure_feasibility=True"
+        - where: "config.ensure_feasibility=True"
           expression: sum(sum(unmet_demand - unused_supply, over=[carriers, nodes])  * timestep_weights, over=timesteps) * bigM
-        - where: "NOT run.ensure_feasibility=True"
+        - where: "NOT config.ensure_feasibility=True"
           expression: "0"
     sense: minimise
 
diff --git a/src/calliope/math/operate.yaml b/src/calliope/math/operate.yaml
index ace286855..5d5672c20 100644
--- a/src/calliope/math/operate.yaml
+++ b/src/calliope/math/operate.yaml
@@ -5,11 +5,13 @@ constraints:
   force_zero_area_use.active: false
   area_use_per_flow_capacity.active: false
   area_use_capacity_per_loc.active: false
-  flow_capacity_systemwide.active: false
+  flow_capacity_systemwide_max.active: false
+  flow_capacity_systemwide_min.active: false
   symmetric_transmission.active: false
   storage_capacity_units_milp.active: false
   flow_capacity_units_milp.active: false
-  unit_capacity_systemwide_milp.active: false
+  unit_capacity_max_systemwide_milp.active: false
+  unit_capacity_min_systemwide_milp.active: false
 
 variables:
   flow_cap.active: false
diff --git a/src/calliope/math/storage_inter_cluster.yaml b/src/calliope/math/storage_inter_cluster.yaml
index 9107bad95..23f300c4e 100644
--- a/src/calliope/math/storage_inter_cluster.yaml
+++ b/src/calliope/math/storage_inter_cluster.yaml
@@ -7,11 +7,11 @@ constraints:
   balance_supply_plus_with_storage:
     sub_expressions:
       storage_previous_step: &storage_previous_step
-        - where: timesteps=get_val_at_index(timesteps=0) AND NOT run.cyclic_storage=True
+        - where: timesteps=get_val_at_index(timesteps=0) AND NOT config.cyclic_storage=True
           expression: storage_initial * storage_cap
-        - where: ((timesteps=get_val_at_index(timesteps=0) AND run.cyclic_storage=True) OR NOT timesteps=get_val_at_index(timesteps=0)) AND NOT lookup_cluster_last_timestep
+        - where: ((timesteps=get_val_at_index(timesteps=0) AND config.cyclic_storage=True) OR NOT timesteps=get_val_at_index(timesteps=0)) AND NOT lookup_cluster_last_timestep
           expression: (1 - storage_loss) ** roll(timestep_resolution, timesteps=1) * roll(storage, timesteps=1)
-        - where: lookup_cluster_last_timestep AND NOT (timesteps=get_val_at_index(timesteps=0) AND NOT run.cyclic_storage=True)
+        - where: lookup_cluster_last_timestep AND NOT (timesteps=get_val_at_index(timesteps=0) AND NOT config.cyclic_storage=True)
           expression: "0"
 
   balance_storage:
@@ -69,14 +69,14 @@ constraints:
       - expression: storage_inter_cluster == $storage_previous_step + $storage_intra
     sub_expressions:
       storage_previous_step:
-        - where: datesteps=get_val_at_index(datesteps=0) AND NOT run.cyclic_storage=True
+        - where: datesteps=get_val_at_index(datesteps=0) AND NOT config.cyclic_storage=True
           expression: storage_initial
-        - where: (datesteps=get_val_at_index(datesteps=0) AND run.cyclic_storage=True) OR NOT datesteps=get_val_at_index(datesteps=0)
+        - where: (datesteps=get_val_at_index(datesteps=0) AND config.cyclic_storage=True) OR NOT datesteps=get_val_at_index(datesteps=0)
           expression: ((1 - storage_loss) ** 24) * roll(storage_inter_cluster, datesteps=1)
       storage_intra:
-        - where: datesteps=get_val_at_index(datesteps=0) AND NOT run.cyclic_storage=True
+        - where: datesteps=get_val_at_index(datesteps=0) AND NOT config.cyclic_storage=True
           expression: "0"
-        - where: NOT (datesteps=get_val_at_index(datesteps=0) AND NOT run.cyclic_storage=True)
+        - where: NOT (datesteps=get_val_at_index(datesteps=0) AND NOT config.cyclic_storage=True)
           expression: storage[timesteps=$final_step]
     slices:
       final_step:
diff --git a/src/calliope/postprocess/results.py b/src/calliope/postprocess/results.py
index ded043db9..9e6d3cbc2 100644
--- a/src/calliope/postprocess/results.py
+++ b/src/calliope/postprocess/results.py
@@ -42,7 +42,7 @@ def postprocess_model_results(results, model_data, timings):
     """
     log_time(logger, timings, "post_process_start", comment="Postprocessing: started")
 
-    run_config = model_data.attrs["run_config"]
+    zero_threshold = model_data.config.solve.zero_threshold
     results["capacity_factor"] = capacity_factor(results, model_data)
     results["systemwide_capacity_factor"] = capacity_factor(
         results, model_data, systemwide=True
@@ -53,7 +53,7 @@ def postprocess_model_results(results, model_data, timings):
     results["total_levelised_cost"] = systemwide_levelised_cost(
         results, model_data, total=True
     )
-    results = clean_results(results, run_config.get("zero_threshold", 0), timings)
+    results = clean_results(results, zero_threshold, timings)
 
     for var_data in results.data_vars.values():
         if "is_result" not in var_data.attrs.keys():
diff --git a/src/calliope/preprocess/checks.py b/src/calliope/preprocess/checks.py
index 690ddff7b..359a22b56 100644
--- a/src/calliope/preprocess/checks.py
+++ b/src/calliope/preprocess/checks.py
@@ -86,7 +86,7 @@ def check_overrides(config_model, override):
     return model_warnings
 
 
-def check_initial(config_model):
+def check_initial(config_model: AttrDict):
     """
     Perform initial checks of model and run config dicts.
 
@@ -103,8 +103,8 @@ def check_initial(config_model):
     model_warnings = []
 
     # Check for version mismatch
-    model_version = config_model.model.get("calliope_version", False)
-    if model_version:
+    model_version = config_model.config.init["calliope_version"]
+    if model_version is not None:
         if str(model_version) not in __version__:
             model_warnings.append(
                 "Model configuration specifies calliope_version={}, "
@@ -116,8 +116,8 @@ def check_initial(config_model):
     # Check top-level keys
     for k in config_model.keys():
         if k not in [
-            "model",
-            "run",
+            "config",
+            "parameters",
             "nodes",
             "locations",  # TODO: remove in v0.7.1
             "tech_groups",
@@ -125,14 +125,14 @@ def check_initial(config_model):
             "links",
             "overrides",
             "scenarios",
-            "config_path",
+            "_model_def_path",
         ]:
             model_warnings.append(
                 "Unrecognised top-level configuration item: {}".format(k)
             )
 
     # Check that all required top-level keys are specified
-    for k in ["model", "run", "nodes", "techs"]:
+    for k in ["config", "nodes", "techs"]:
         if k not in config_model.keys():
             if k == "nodes" and "locations" in config_model.keys():
                 # TODO: remove in v0.7.1
@@ -151,39 +151,28 @@ def check_initial(config_model):
     # Check run configuration
     # Exclude solver_options and objective_options.cost_class from checks,
     # as we don't know all possible options for all solvers
-    for k in config_model["run"].keys_nested():
-        if (
-            k not in DEFAULTS["run"].keys_nested()
-            and "solver_options" not in k
-            and "objective_options.cost_class" not in k
-        ):
-            model_warnings.append(
-                "Unrecognised setting in run configuration: {}".format(k)
-            )
+    for config_group in ["init", "build", "solve"]:
+        for k in config_model.config[config_group].keys():
+            if k not in DEFAULTS.config[config_group].keys():
+                model_warnings.append(
+                    f"Unrecognised setting in `{config_group}` configuration: {k}"
+                )
 
-    # Check model configuration, but top-level keys only
-    for k in config_model["model"].keys():
-        if k not in DEFAULTS["model"].keys():
-            model_warnings.append(
-                "Unrecognised setting in model configuration: {}".format(k)
-            )
     # If spores run mode is selected, check the correct definition of all needed parameters
-    if config_model.run.mode == "spores":
+    if config_model.config.build.mode == "spores":
         # Check that spores number is greater than 0, otherwise raise warning
-        if config_model.run.spores_options.spores_number == 0:
+        if config_model.config.solve.spores_number == 0:
             model_warnings.append(
                 "spores run mode is selected, but a number of 0 spores is requested"
             )
-        # Check that slack cost is greater than 0, otherwise set to default (0.1) and raise warning
-        if config_model.run.spores_options.slack <= 0:
-            config_model.run.spores_options.slack = 0.1
-            model_warnings.append(
-                "Slack must be greater than zero, setting slack to default value of 0.1 "
-            )
+        # Check that slack cost is greater than 0
+        if config_model.parameters.spores_slack <= 0:
+            errors.append("`parameters.spores_slack` must be > 0")
+
         # Check that score_cost_class is a string
-        _spores_cost_class = config_model.run.spores_options.get("score_cost_class", {})
+        _spores_cost_class = config_model.config.solve.spores_score_cost_class
         if not isinstance(_spores_cost_class, str):
-            errors.append("`run.spores_options.score_cost_class` must be a string")
+            errors.append("`config.solve.spores_score_cost_class` must be a string")
 
     # Only ['in', 'out', 'in_2', 'out_2', 'in_3', 'out_3']
     # are allowed as carrier tiers
@@ -309,72 +298,18 @@ def check_initial(config_model):
             "(i.e. `one_way: true`).".format(tech_end, ", ".join(duplicated_techs))
         )
 
-    # Error if a constraint is loaded from file that must not be
-    allowed_from_file = DEFAULTS.model.file_allowed
-    for k, v in config_model.as_dict_flat().items():
-        if "file=" in str(v):
-            possible_identifiers = k.split(".")
-            is_time_varying = any("_time_varying" in i for i in possible_identifiers)
-            if is_time_varying:
-                model_warnings.append(
-                    "Using custom constraint `{}` with time-varying data.".format(k)
-                )
-            elif (
-                not set(possible_identifiers).intersection(allowed_from_file)
-                and not is_time_varying
-            ):
-                errors.append(
-                    "Cannot load data from file for configuration `{}`.".format(k)
-                )
-
-    # We no longer allow cost_class in objective_obtions to be a string
-    _cost_class = config_model.run.objective_options.get("cost_class", {})
+    # We no longer allow cost_class in objective_options to be a string
+    _cost_class = config_model.parameters.objective_cost_class
 
-    if not isinstance(_cost_class, dict):
-        errors.append(
-            "`run.objective_options.cost_class` must be a dictionary."
-            "If you want to minimise or maximise with a single cost class, "
-            'use e.g. "{monetary: 1}", which gives the monetary cost class a weight '
-            "of 1 in the objective, and ignores any other cost classes."
-        )
+    if not isinstance(_cost_class.data, list):
+        _data = [_cost_class.data]
     else:
-        # This next check is only run if we have confirmed that cost_class is
-        # a dict, as it errors otherwise
-
-        # For cost minimisation objective, check for cost_class: None and set to one
-        for k, v in _cost_class.items():
-            if v is None:
-                config_model.run.objective_options.cost_class[k] = 1
-                model_warnings.append(
-                    "cost class {} has weight = None, setting weight to 1".format(k)
-                )
-
-    if (
-        isinstance(_cost_class, dict)
-        and _cost_class.get("monetary", 0) == 1
-        and len(_cost_class.keys()) > 1
-    ):
-        # Warn that {monetary: 1} is still in the objective, since it is not
-        # automatically overidden on setting another objective.
-        model_warnings.append(
-            "Monetary cost class with a weight of 1 is still included "
-            "in the objective. If you want to remove the monetary cost class, "
-            'add `{"monetary": 0}` to the dictionary nested under '
-            " `run.objective_options.cost_class`."
-        )
-
-    # Don't allow time clustering with cyclic storage if not also using
-    # storage_inter_cluster
-    storage_inter_cluster = "model.time.function_options.storage_inter_cluster"
-    if (
-        config_model.get_key("model.time.function", None) == "apply_clustering"
-        and config_model.get_key("run.cyclic_storage", True)
-        and not config_model.get_key(storage_inter_cluster, True)
-    ):
-        errors.append(
-            "When time clustering, cannot have cyclic storage constraints if "
-            "`storage_inter_cluster` decision variable is not activated."
-        )
+        _data = _cost_class.data
+    for _val in _data:
+        if not isinstance(_val, (int, float)):
+            errors.append(
+                f"Objective cost class weights must be numeric, received:{_val}"
+            )
 
     return model_warnings, errors
 
@@ -610,10 +545,6 @@ def check_final(model_run):
                 "Time series `{}` contains non-unique timestamp values.".format(k)
             )
 
-    # FIXME:
-    # make sure `comments` is at the the base level:
-    # i.e. comments.model_run.xxxxx....
-
     return comments, model_warnings, errors
 
 
@@ -666,7 +597,10 @@ def check_model_data(model_data):
             model_data.timestep_resolution.loc[i].values
             for i in np.unique(model_data.timesteps.to_index().strftime("%Y-%m-%d"))
         ]
-        if not np.all(daily_timesteps == daily_timesteps[0]):
+        daily_timestep_shapes = set(day.shape for day in daily_timesteps)
+        if len(daily_timestep_shapes) > 1 or not np.all(
+            daily_timesteps == daily_timesteps[0]
+        ):
             model_data.attrs["allow_operate_mode"] = 0
             model_warnings.append(
                 "Operational mode requires the same timestep resolution profile "
diff --git a/src/calliope/preprocess/model_data.py b/src/calliope/preprocess/model_data.py
index d8badd8a2..ce4b261f3 100644
--- a/src/calliope/preprocess/model_data.py
+++ b/src/calliope/preprocess/model_data.py
@@ -12,6 +12,7 @@
 import logging
 import os
 import re
+from typing import Optional
 
 import numpy as np
 import pandas as pd
@@ -61,12 +62,15 @@ def __init__(self, model_run_dict):
             in attributes.
 
         """
-        self.node_dict = model_run_dict.nodes.as_dict_flat()
-        self.tech_dict = model_run_dict.techs.as_dict_flat()
-        self.model_run = model_run_dict
-        self.model_data = xr.Dataset(
-            coords={"timesteps": model_run_dict.timeseries_data.index}
-        )
+        self.node_dict: dict = model_run_dict.nodes.as_dict_flat()
+        self.tech_dict: dict = model_run_dict.techs.as_dict_flat()
+        self.timeseries_vars: pd.DataFrame = model_run_dict.timeseries_vars
+        self.timeseries_data: set[str] = model_run_dict.timeseries_data
+        self.time_config: Optional[AttrDict] = model_run_dict.config.init.time
+        self.random_seed: Optional[int] = model_run_dict.config.init.random_seed
+        self.params: AttrDict = model_run_dict.parameters
+
+        self.model_data = xr.Dataset(coords={"timesteps": self.timeseries_data.index})
         self._add_attributes(model_run_dict)
         self.template_config = AttrDict.from_yaml(
             os.path.join(
@@ -90,19 +94,110 @@ def __call__(self):
 
     def _extract_node_tech_data(self):
         self._add_param_from_template()
+        self._add_top_level_params()
         self._clean_unused_techs_nodes_and_carriers()
 
+    def _add_top_level_params(self):
+        for param_name, param_data in self.params.items():
+            if param_name in self.model_data.data_vars:
+                raise KeyError(
+                    f"Trying to add top-level parameter with same name as a node/tech level parameter: {param_name}"
+                )
+
+            if not isinstance(param_data, dict):
+                param_data = {"data": param_data}
+
+            if "dims" in param_data:
+                index = param_data.get("index", None)
+                if index is None or not isinstance(index, list):
+                    raise ValueError(
+                        f"(parameters, {param_name}) | Expected list for `index`, received: {index}"
+                    )
+                _index = [
+                    tuple(idx) if isinstance(idx, list) else tuple([idx])
+                    for idx in param_data["index"]
+                ]
+                _dims = (
+                    param_data["dims"]
+                    if isinstance(param_data["dims"], list)
+                    else [param_data["dims"]]
+                )
+                param_series = pd.Series(
+                    data=param_data["data"],
+                    index=pd.MultiIndex.from_tuples(_index, names=_dims),
+                    name=param_name,
+                )
+                param_da = param_series.to_xarray()
+            else:
+                param_da = xr.DataArray(param_data["data"], name=param_name)
+
+            self._update_param_coords(param_name, param_da)
+            self._log_param_updates(param_name, param_da)
+
+            self.model_data = self.model_data.merge(param_da.to_dataset())
+
+    def _update_param_coords(self, param_name: str, param_da: xr.DataArray) -> None:
+        """
+        Check array coordinates to see if any should be in datetime format,
+        if the base model coordinate is in datetime format.
+
+        Args:
+            param_name (str): name of parameter being added to the model.
+            param_da (xr.DataArray): array of parameter data.
+        """
+        coords_to_update = {}
+        for coord_name, coord_data in param_da.coords.items():
+            if self.model_data.coords.get(coord_name, xr.DataArray()).dtype.kind == "M":
+                LOGGER.debug(
+                    f"(parameters, {param_name}) | Updating {coord_name} dimension index values to datetime format"
+                )
+                coords_to_update[coord_name] = pd.to_datetime(
+                    coord_data, format="ISO8601"
+                )
+        for coord_name, coord_data in coords_to_update.items():
+            param_da.coords[coord_name] = coord_data
+
+    def _log_param_updates(self, param_name: str, param_da: xr.DataArray) -> None:
+        """
+        Check array coordinates to see if:
+            1. any are new compared to the base model dimensions.
+            2. any are adding new elements to an existing base model dimension.
+
+        Args:
+            param_name (str): name of parameter being added to the model.
+            param_da (xr.DataArray): array of parameter data.
+        """
+        for coord_name, coord_data in param_da.coords.items():
+            if coord_name not in self.model_data.coords:
+                LOGGER.debug(
+                    f"(parameters, {param_name}) | Adding a new dimension to the model: {coord_name}"
+                )
+            else:
+                new_coord_data = coord_data[
+                    ~coord_data.isin(self.model_data.coords[coord_name])
+                ]
+                if new_coord_data.size > 0:
+                    LOGGER.debug(
+                        f"(parameters, {param_name}) | Adding a new value to the "
+                        f"`{coord_name}` model coordinate: {new_coord_data.values}"
+                    )
+
     def _add_time_dimension(self):
         self.data_pre_time = self.model_data.copy(deep=True)
-        self.model_data = time.add_time_dimension(self.model_data, self.model_run)
+        self.model_data = time.add_time_dimension(
+            self.model_data,
+            self.timeseries_vars,
+            self.timeseries_data,
+        )
         self._update_dtypes()
 
-        if self.model_run.get_key("model.random_seed", None):
-            np.random.seed(seed=self.model_run.model.random_seed)
+        # TODO: this is a legacy function, so should be updated to numpy best-practice
+        np.random.seed(seed=self.random_seed)
+
         self.model_data_pre_clustering = self.model_data.copy(deep=True)
-        if self.model_run.get_key("model.time", None):
+        if self.time_config is not None:
             self.model_data = time.apply_time_clustering(
-                self.model_data, self.model_run
+                self.model_data, self.time_config, self.timeseries_data
             )
 
         self.model_data["annualisation_weight"] = (
diff --git a/src/calliope/preprocess/model_run.py b/src/calliope/preprocess/model_run.py
index 6555c8a41..09a125e23 100644
--- a/src/calliope/preprocess/model_run.py
+++ b/src/calliope/preprocess/model_run.py
@@ -13,7 +13,8 @@
 import itertools
 import logging
 import os
-import warnings
+from pathlib import Path
+from typing import Optional
 
 import pandas as pd
 
@@ -42,7 +43,7 @@
 
 
 def model_run_from_yaml(
-    model_file, timeseries_dataframes=None, scenario=None, override_dict=None
+    model_file, scenario=None, override_dict=None, timeseries_dataframes=None, **kwargs
 ):
     """
     Generate processed ModelRun configuration from a
@@ -64,11 +65,12 @@ def model_run_from_yaml(
 
     """
     config = AttrDict.from_yaml(model_file)
-    config.config_path = model_file
+    config._model_def_path = Path(model_file).as_posix()
 
     config_with_overrides, debug_comments, overrides, scenario = apply_overrides(
         config, scenario=scenario, override_dict=override_dict
     )
+    config_with_overrides.union(AttrDict({"config.init": kwargs}), allow_override=True)
 
     return generate_model_run(
         config_with_overrides,
@@ -80,7 +82,7 @@ def model_run_from_yaml(
 
 
 def model_run_from_dict(
-    config_dict, timeseries_dataframes=None, scenario=None, override_dict=None
+    config_dict, scenario=None, override_dict=None, timeseries_dataframes=None, **kwargs
 ):
     """
     Generate processed ModelRun configuration from a
@@ -104,11 +106,12 @@ def model_run_from_dict(
         config = AttrDict(config_dict)
     else:
         config = config_dict
-    config.config_path = None
+    config._model_def_path = None
 
     config_with_overrides, debug_comments, overrides, scenario = apply_overrides(
         config, scenario=scenario, override_dict=override_dict
     )
+    config_with_overrides.union(AttrDict({"config.init": kwargs}), allow_override=True)
 
     return generate_model_run(
         config_with_overrides,
@@ -140,13 +143,13 @@ def combine_overrides(config_model, overrides):
     return override_dict
 
 
-def apply_overrides(config, scenario=None, override_dict=None):
+def apply_overrides(model_dict, scenario=None, override_dict=None):
     """
     Generate processed Model configuration, applying any scenarios overrides.
 
     Parameters
     ----------
-    config : AttrDict
+    model_dict : AttrDict
         a model configuration AttrDict
     scenario : str, optional
     override_dict : str or dict or AttrDict, optional
@@ -155,24 +158,19 @@ def apply_overrides(config, scenario=None, override_dict=None):
     """
     debug_comments = AttrDict()
 
-    config_model = AttrDict.from_yaml(
+    default_model_dict = AttrDict.from_yaml(
         os.path.join(os.path.dirname(calliope.__file__), "config", "defaults.yaml")
     )
 
     # Interpret timeseries_data_path as relative
-    if "timeseries_data_path" in config.model:
-        config.model.timeseries_data_path = relative_path(
-            config.config_path, config.model.timeseries_data_path
+    if "timeseries_data_path" in model_dict.get_key("config.init", default={}):
+        model_dict.config.init.timeseries_data_path = relative_path(
+            model_dict._model_def_path, model_dict.config.init.timeseries_data_path
         )
 
-    # FutureWarning: check if config includes an explicit objective cost class.
-    # Added in 0.6.4-dev, to be removed in v0.7.0-dev.
-    has_explicit_cost_class = isinstance(
-        config.get_key("run.objective_options.cost_class", None), dict
-    )
-
     # The input files are allowed to override other model defaults
-    config_model.union(config, allow_override=True)
+    default_model_dict.union(model_dict, allow_override=True)
+    config_model = default_model_dict.copy()
 
     # First pass of applying override dict before applying scenarios,
     # so that can override scenario definitions by override_dict
@@ -185,13 +183,6 @@ def apply_overrides(config, scenario=None, override_dict=None):
         warning_messages = checks.check_overrides(config_model, override_dict)
         exceptions.print_warnings_and_raise_errors(warnings=warning_messages)
 
-        # FutureWarning: If config does not include an explicit objective cost class, check override dict.
-        # Added in 0.6.4-dev, to be removed in v0.7.0-dev.
-        if has_explicit_cost_class is False:
-            has_explicit_cost_class = isinstance(
-                override_dict.get_key("run.objective_options.cost_class", None), dict
-            )
-
         config_model.union(override_dict, allow_override=True, allow_replacement=True)
 
     if scenario:
@@ -211,16 +202,6 @@ def apply_overrides(config, scenario=None, override_dict=None):
         warning_messages = checks.check_overrides(config_model, overrides_from_scenario)
         exceptions.print_warnings_and_raise_errors(warnings=warning_messages)
 
-        # FutureWarning: If config nor override_dict include an explicit objective cost class, check scenario dict.
-        # Added in 0.6.4-dev, to be removed in v0.7.0-dev
-        if has_explicit_cost_class is False:
-            has_explicit_cost_class = isinstance(
-                overrides_from_scenario.get_key(
-                    "run.objective_options.cost_class", None
-                ),
-                dict,
-            )
-
         config_model.union(
             overrides_from_scenario, allow_override=True, allow_replacement=True
         )
@@ -238,19 +219,6 @@ def apply_overrides(config, scenario=None, override_dict=None):
                 "{}".format(k), "Overridden via override dictionary."
             )
 
-    # FutureWarning: raise cost class warning here.
-    # Warning that there will be no default cost class in 0.7.0 #
-    # Added in 0.6.4-dev, to be removed in v0.7.0-dev
-    if has_explicit_cost_class is False:
-        warnings.warn(
-            "There will be no default cost class for the objective function in "
-            'v0.7.0 (currently "monetary" with a weight of 1). '
-            "Explicitly specify the cost class(es) you would like to use "
-            'under `run.objective_options.cost_class`. E.g. `{"monetary": 1}` to '
-            "replicate the current default.",
-            FutureWarning,
-        )
-
     # Drop default nodes, links, and techs
     config_model.del_key("techs.default_tech")
     config_model.del_key("nodes.default_node")
@@ -468,8 +436,8 @@ def process_tech_groups(config_model, techs):
     return tech_groups
 
 
-def load_timeseries_from_file(config_model, tskey):
-    file_path = os.path.join(config_model.model.timeseries_data_path, tskey)
+def load_timeseries_from_file(timeseries_data_path, tskey):
+    file_path = os.path.join(timeseries_data_path, tskey)
     df = pd.read_csv(file_path, index_col=0)
     df.columns = pd.MultiIndex.from_product(
         [[tskey], df.columns], names=["source", "column"]
@@ -542,22 +510,24 @@ def _get_names(config):
     return set(tsnames), set(tsvars)
 
 
-def process_timeseries_data(config_model, model_run, timeseries_dataframes):
-    timeseries_data = config_model.model.get("timeseries_data", None)
-
-    dtformat = config_model.model["timeseries_dateformat"]
-
+def process_timeseries_data(
+    model_run: AttrDict,
+    timeseries_dfs: Optional[pd.DataFrame],
+    timeseries_data_path: Optional[str],
+    time_config: Optional[AttrDict],
+    subset_time_config: Optional[list[str]],
+    datetime_format: str,
+):
     # Generate set of all files and dataframes we want to load
-    node_config = model_run.nodes.as_dict_flat()
-    model_config = config_model.model.as_dict_flat()
-
-    constraint_tsnames, constraint_tsvars = _get_names(node_config)
-    cluster_tsnames, cluster_tsvars = _get_names(model_config)
+    constraint_tsnames, constraint_tsvars = _get_names(model_run.nodes.as_dict_flat())
+    cluster_tsnames = set()
+    if time_config is not None:
+        cluster_tsnames, _ = _get_names(time_config.as_dict_flat())
 
     # Check if timeseries_dataframes is in the correct format (dict of
     # pandas DataFrames)
-    if timeseries_dataframes is not None:
-        check_timeseries_dataframes(timeseries_dataframes)
+    if timeseries_dfs is not None:
+        check_timeseries_dataframes(timeseries_dfs)
 
     # Check there is at least one timeseries present
     if len(constraint_tsnames) == 0:
@@ -568,13 +538,14 @@ def process_timeseries_data(config_model, model_run, timeseries_dataframes):
 
     # Load each timeseries into timeseries data. tskey is either a filename
     # (called by file=...) or a key in timeseries_dataframes (called by df=...)
+    timeseries_data = pd.DataFrame(dtype=float)
     for tskey in constraint_tsnames | cluster_tsnames:
         # If tskey is a CSV path, load the CSV, else load the dataframe
 
         if tskey[0] == "file":
-            df = load_timeseries_from_file(config_model, tskey[1])
+            df = load_timeseries_from_file(timeseries_data_path, tskey[1])
         elif tskey[0] == "df":
-            df = load_timeseries_from_dataframe(timeseries_dataframes, tskey[1])
+            df = load_timeseries_from_dataframe(timeseries_dfs, tskey[1])
         else:
             raise KeyError(f"Unrecognised timeseries data source {tskey[0]}")
 
@@ -587,19 +558,15 @@ def process_timeseries_data(config_model, model_run, timeseries_dataframes):
             )
         # Parse the dates, checking for errors specific to this
         try:
-            df.index = _parser(df.index, dtformat)
+            df.index = _parser(df.index, datetime_format)
         except ValueError as e:
             raise exceptions.ModelError(
                 "Error in parsing dates in timeseries data from {}, "
-                "using datetime format `{}`: {}".format(tskey[1], dtformat, e)
+                "using datetime format `{}`: {}".format(tskey[1], datetime_format, e)
             )
-        if timeseries_data is None:
-            timeseries_data = df
-        else:
-            timeseries_data = pd.concat([timeseries_data, df], axis=1)
+        timeseries_data = pd.concat([timeseries_data, df], axis=1)
 
     # Apply time subsetting, if supplied in model_run
-    subset_time_config = config_model.model.get("subset_time", None)
     if subset_time_config is not None:
         # Test parsing dates first, to make sure they fit our required subset format
         try:
@@ -711,11 +678,18 @@ def generate_model_run(
     (
         model_run["timeseries_data"],
         model_run["timeseries_vars"],
-    ) = process_timeseries_data(config, model_run, timeseries_dataframes)
+    ) = process_timeseries_data(
+        model_run,
+        timeseries_dataframes,
+        config.config.init.timeseries_data_path,
+        config.config.init.time,
+        config.config.init.subset_time,
+        config.config.init.timeseries_dateformat,
+    )
 
     # 6) Grab additional relevant bits from run and model config
-    model_run["run"] = config["run"]
-    model_run["model"] = config["model"]
+    model_run["config"] = config.config
+    model_run["parameters"] = config.parameters
 
     # 8) Final sense-checking
     final_check_comments, warning_messages, errors = checks.check_final(model_run)
diff --git a/src/calliope/preprocess/time.py b/src/calliope/preprocess/time.py
index e003c5bf0..771e77962 100644
--- a/src/calliope/preprocess/time.py
+++ b/src/calliope/preprocess/time.py
@@ -17,7 +17,9 @@
 from calliope.core.util.tools import plugin_load
 
 
-def apply_time_clustering(model_data, model_run):
+def apply_time_clustering(
+    model_data: xr.Dataset, time_config: AttrDict, input_timeseries_dfs: pd.DataFrame
+):
     """
     Take a Calliope model_data post time dimension addition, prior to any time
     clustering, and apply relevant time clustering/masking techniques.
@@ -56,7 +58,6 @@ def apply_time_clustering(model_data, model_run):
         been updated as per user-defined clustering techniques (from model_run)
 
     """
-    time_config = model_run.model["time"]
 
     data = model_data.copy(deep=True)
 
@@ -90,13 +91,15 @@ def apply_time_clustering(model_data, model_run):
         func = plugin_load(time_config.function, builtin_module="calliope.time.funcs")
         func_kwargs = time_config.get("function_options", AttrDict()).as_dict()
         if "file=" in func_kwargs.get("clustering_func", ""):
-            func_kwargs.update({"model_run": model_run})
+            func_kwargs.update({"clustering_timeseries": input_timeseries_dfs})
         data = func(data=data, timesteps=timesteps, **func_kwargs)
 
     return data
 
 
-def add_time_dimension(data, model_run):
+def add_time_dimension(
+    data: xr.Dataset, timeseries_vars: set[str], timeseries_data: pd.DataFrame
+):
     """
     Once all constraints and costs have been loaded into the model dataset, any
     timeseries data is loaded from file and substituted into the model dataset
@@ -118,7 +121,7 @@ def add_time_dimension(data, model_run):
     """
     key_errors = []
     # Search through every constraint/cost for use of '='
-    for variable in model_run.timeseries_vars:
+    for variable in timeseries_vars:
         # 2) convert to a Pandas Series to do 'string contains' search
         data_series = data[variable].to_series().dropna()
 
@@ -146,7 +149,7 @@ def add_time_dimension(data, model_run):
 
         # 6) Get all timeseries data from dataframes stored in model_run
         try:
-            timeseries_data = model_run.timeseries_data.loc[:, tskeys.index]
+            var_timeseries_data = timeseries_data.loc[:, tskeys.index]
         except KeyError:
             key_errors.append(
                 f"file:column combinations `{tskeys.index.values}` not found, but are"
@@ -154,14 +157,14 @@ def add_time_dimension(data, model_run):
             )
             continue
 
-        timeseries_data.columns = pd.MultiIndex.from_frame(tskeys)
+        var_timeseries_data.columns = pd.MultiIndex.from_frame(tskeys)
 
         # 7) Add time dimension to the relevent DataArray and update the '='
         # dimensions with the time varying data (static data is just duplicated
         # at each timestep)
 
         data[variable] = (
-            xr.DataArray.from_series(timeseries_data.unstack())
+            xr.DataArray.from_series(var_timeseries_data.unstack())
             .reindex(data[variable].coords)
             .fillna(data[variable])
         )
diff --git a/src/calliope/time/funcs.py b/src/calliope/time/funcs.py
index cce1b64d9..30055f743 100644
--- a/src/calliope/time/funcs.py
+++ b/src/calliope/time/funcs.py
@@ -111,7 +111,7 @@ def apply_clustering(
     normalize=True,
     scale_clusters="mean",
     storage_inter_cluster=True,
-    model_run=None,
+    clustering_timeseries=None,
     **kwargs,
 ):
     """
@@ -173,7 +173,7 @@ def apply_clustering(
         else:
             column = None
 
-        df = model_run.timeseries_data[file]
+        df = clustering_timeseries[file]
         if isinstance(df, pd.Series) and column is not None:
             exceptions.warn(
                 "{} given as time clustering column, but only one column to "


Test patch:
diff --git a/tests/common/test_model/energy_cap_per_storage_cap.yaml b/tests/common/test_model/energy_cap_per_storage_cap.yaml
index 245efd733..f543e62b9 100644
--- a/tests/common/test_model/energy_cap_per_storage_cap.yaml
+++ b/tests/common/test_model/energy_cap_per_storage_cap.yaml
@@ -1,13 +1,15 @@
-model:
-  name: Test model for flow capacity per storage capacity
-  timeseries_data_path: "timeseries_data"
-  subset_time: ["2005-01-01 00:00", "2005-01-01 01:00"]
+config:
+  init:
+    name: Test model for energy capacity per storage capacity
+    timeseries_data_path: "timeseries_data"
+    subset_time: ["2005-01-01 00:00", "2005-01-01 01:00"]
 
-run:
-  mode: plan
-  solver: cbc
-  cyclic_storage: False # necessary so demand can be fed from stored carrier
-  ensure_feasibility: true
+  build:
+    mode: plan
+    cyclic_storage: False # necessary so demand can be fed from stored energy
+    ensure_feasibility: true
+  solve:
+    solver: cbc
 
 techs:
   electricity_demand:
@@ -43,7 +45,7 @@ overrides:
     techs.my_storage.constraints.flow_cap_per_storage_cap_min: 1
   operate_mode_min:
     techs.my_storage.constraints.flow_cap_per_storage_cap_min: 1
-    run.mode: operate
-    run.operation:
-      window: 24
-      horizon: 24
+    config:
+      build.mode: operate
+      solve.operate_window: 24
+      solve.operate_horizon: 24
diff --git a/tests/common/test_model/model.yaml b/tests/common/test_model/model.yaml
index 01af33f94..2452e6188 100644
--- a/tests/common/test_model/model.yaml
+++ b/tests/common/test_model/model.yaml
@@ -11,14 +11,14 @@
 import:
   - scenarios.yaml
 
-model:
-  name: Test model
-
-  timeseries_data_path: "timeseries_data"
-
-run:
-  mode: plan
-  solver: cbc
+config:
+  init:
+    name: Test model
+    timeseries_data_path: "timeseries_data"
+  build:
+    mode: plan
+  solve:
+    solver: cbc
 
 techs:
   test_supply_gas:
diff --git a/tests/common/test_model/model_minimal.yaml b/tests/common/test_model/model_minimal.yaml
index 80ab1625f..78f1dc383 100644
--- a/tests/common/test_model/model_minimal.yaml
+++ b/tests/common/test_model/model_minimal.yaml
@@ -1,15 +1,20 @@
 import:
   - scenarios.yaml
 
-model:
-  name: Minimal test model
+config:
+  init:
+    name: Minimal test model
+    timeseries_data_path: "timeseries_data"
+  build:
+    mode: plan
+  solve:
+    solver: cbc
 
-  timeseries_data_path: "timeseries_data"
-
-run:
-  mode: plan
-  solver: cbc
-  objective_options.cost_class.monetary: 1
+parameters:
+  objective_cost_class:
+    data: 1
+    index: [monetary]
+    dims: costs
 
 techs:
   test_supply_elec:
diff --git a/tests/common/test_model/scenarios.yaml b/tests/common/test_model/scenarios.yaml
index 52d38a2b2..a274cc684 100644
--- a/tests/common/test_model/scenarios.yaml
+++ b/tests/common/test_model/scenarios.yaml
@@ -241,7 +241,7 @@ overrides:
     links.a,b.active: false
 
   clustering:
-    model.time:
+    config.init.time:
       function: apply_clustering
       function_options:
         clustering_func: file=cluster_days.csv:a
@@ -249,36 +249,38 @@ overrides:
         storage_inter_cluster: True
 
   spores:
-    run.mode: spores
-    run.spores_options:
-      score_cost_class: "spores_score"
-      slack: 0.1
-      spores_number: 3
-    run.objective_options.cost_class: { "monetary": 1, "spores_score": 0 }
+    config:
+      build.mode: spores
+      solve:
+        spores_score_cost_class: "spores_score"
+        spores_number: 3
+      parameters:
+        spores_slack.data: 0.1
+        objective_cost_class.data: { "monetary": 1, "spores_score": 0 }
 
     techs.test_supply_elec.costs.spores_score.flow_cap: 0
     techs.test_supply_elec.costs.spores_score.interest_rate: 0
     techs.test_supply_elec.constraints.lifetime: 1
 
   one_day:
-    model.subset_time: ["2005-01-01", "2005-01-01"]
+    config.init.subset_time: ["2005-01-01", "2005-01-01"]
 
   two_hours:
-    model.subset_time: ["2005-01-01 00:00:00", "2005-01-01 01:00:00"]
+    config.init.subset_time: ["2005-01-01 00:00:00", "2005-01-01 01:00:00"]
 
   resample_two_days:
-    model:
-      subset_time: ["2005-01-01", "2005-01-02"]
-      time:
-        function: resample
-        function_options.resolution: 24h
+    config:
+      init:
+        subset_time: ["2005-01-01", "2005-01-02"]
+        time:
+          function: resample
+          function_options.resolution: 24h
 
   operate:
-    run.mode: operate
-    model.subset_time: ["2005-01-01", "2005-01-04"]
-    run.operation:
-      window: 12
-      horizon: 24
+    config.build.mode: operate
+    config.init.subset_time: ["2005-01-01", "2005-01-04"]
+    config.solve.operate_window: 12
+    config.solve.operate_horizon: 24
 
   investment_costs:
     tech_groups:
@@ -317,6 +319,3 @@ overrides:
           monetary:
             interest_rate: 0.1
             flow_cap: 10
-
-  explicit_cost_class:
-    run.objective_options.cost_class.monetary: 1
diff --git a/tests/common/test_model/weighted_obj_func.yaml b/tests/common/test_model/weighted_obj_func.yaml
index 6ce326635..052af4762 100644
--- a/tests/common/test_model/weighted_obj_func.yaml
+++ b/tests/common/test_model/weighted_obj_func.yaml
@@ -1,11 +1,12 @@
-model:
-  name: Cost capacity constraint test model
-  timeseries_data_path: "timeseries_data"
-  subset_time: ["2005-01-01", "2005-01-01"]
-
-run:
-  mode: plan
-  solver: cbc
+config:
+  init:
+    name: Cost capacity constraint test model
+    timeseries_data_path: "timeseries_data"
+    subset_time: ["2005-01-01", "2005-01-01"]
+  build:
+    mode: plan
+  solve:
+    solver: cbc
 
 techs:
   cheap_polluting_supply:
@@ -76,15 +77,24 @@ nodes:
 
 overrides:
   illegal_string_cost_class:
-    run.objective_options.cost_class: "monetary"
+    parameters.objective_cost_class.data: "monetary"
   emissions_objective_without_removing_monetary_default:
-    run.objective_options.cost_class: { "emissions": 0.1 }
+    parameters.objective_cost_class:
+      data: 0.1
+      index: ["emissions"]
   monetary_objective:
-    run.objective_options.cost_class: { "monetary": 1 }
+    parameters.objective_cost_class:
+      data: 1
+      index: ["monetary"]
   emissions_objective:
-    run.objective_options.cost_class: { "monetary": 0, "emissions": 1 }
+    parameters.objective_cost_class:
+      data: [0, 1]
+      index: [monetary, emissions]
   weighted_objective:
-    run.objective_options.cost_class: { "monetary": 0.9, "emissions": 0.1 }
+    parameters.objective_cost_class:
+      data: [0.9, 0.1]
+      index: [monetary, emissions]
   undefined_class_objective:
-    run.objective_options.cost_class:
-      { "monetary": 0.8, "emissions": 0.1, "random_class": 0.2 }
+    parameters.objective_cost_class:
+      data: [0.8, 0.1, 0.2]
+      index: ["monetary", "emissions", "random_class"]
diff --git a/tests/conftest.py b/tests/conftest.py
index 3823cad61..666adadeb 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -217,10 +217,18 @@ def dummy_model_data():
     for param in model_data.data_vars.values():
         param.attrs["is_result"] = 0
 
-    model_data.attrs["run_config"] = AttrDict(
-        {"foo": True, "bar": {"foobar": "baz"}, "foobar": {"baz": {"foo": np.inf}}}
+    model_data.attrs["config"] = AttrDict(
+        {
+            "build": {
+                "foo": True,
+                "FOO": "baz",
+                "foo1": np.inf,
+                "bar": {"foobar": "baz"},
+                "a_b": 0,
+                "b_a": [1, 2],
+            }
+        }
     )
-    model_data.attrs["model_config"] = AttrDict({"a_b": 0, "b_a": [1, 2]})
 
     model_data.attrs["defaults"] = AttrDict(
         {"all_inf": np.inf, "all_nan": np.nan, "with_inf": 100, "only_techs": 5}
diff --git a/tests/test_backend_pyomo.py b/tests/test_backend_pyomo.py
index 28b943cb8..da8bb9cd6 100755
--- a/tests/test_backend_pyomo.py
+++ b/tests/test_backend_pyomo.py
@@ -1,4 +1,6 @@
+import importlib
 import logging
+from copy import deepcopy
 from itertools import product
 
 import calliope.exceptions as exceptions
@@ -7,6 +9,8 @@
 import pyomo.kernel as pmo
 import pytest  # noqa: F401
 import xarray as xr
+from calliope.backend.pyomo_backend_model import PyomoBackendModel
+from calliope.core.attrdict import AttrDict
 
 from .common.util import build_test_model as build_model
 from .common.util import check_error_or_warning, check_variable_exists
@@ -22,13 +26,13 @@ def test_operate_cyclic_storage(self, on):
             m = build_model(
                 override, "simple_supply_and_supply_plus,operate,investment_costs"
             )
-            assert m.run_config["cyclic_storage"] is True
+            assert m.config.build["cyclic_storage"] is True
         elif on is False:
-            override = {"run.cyclic_storage": False}
+            override = {"config.build.cyclic_storage": False}
             m = build_model(
                 override, "simple_supply_and_supply_plus,operate,investment_costs"
             )
-            assert m.run_config["cyclic_storage"] is False
+            assert m.config.build["cyclic_storage"] is False
         with pytest.warns(exceptions.ModelWarning) as warning:
             m.build()
         check_warn = check_error_or_warning(
@@ -38,7 +42,7 @@ def test_operate_cyclic_storage(self, on):
             assert check_warn
         elif on is True:
             assert not check_warn
-        assert m._model_data.attrs["run_config"].cyclic_storage is False
+        assert m._model_data.attrs["config"].build.cyclic_storage is False
 
     @pytest.mark.parametrize("param", [("flow_eff"), ("source_eff"), ("parasitic_eff")])
     def test_loading_timeseries_operate_efficiencies(self, param):
@@ -153,7 +157,7 @@ def test_operate_source_unit_without_area_use(self, source_unit):
             {
                 "techs.test_supply_elec": {
                     "constraints": {
-                        "source": "file=supply_plus_resource.csv:1",
+                        "source_max": "file=supply_plus_resource.csv:1",
                         "flow_cap_max": 15,
                     },
                     "switches": {
@@ -489,7 +493,6 @@ def test_loc_techs_cost_investment_constraint(self, simple_conversion):
         """
         assert "cost_investment" in simple_conversion.backend.expressions
 
-    @pytest.mark.filterwarnings("ignore:(?s).*Integer:calliope.exceptions.ModelWarning")
     def test_loc_techs_cost_investment_milp_constraint(self):
         m = build_model(
             {
@@ -660,7 +663,6 @@ def test_loc_techs_storage_capacity_constraint(
             == 20
         )
 
-    @pytest.mark.filterwarnings("ignore:(?s).*Integer:calliope.exceptions.ModelWarning")
     def test_loc_techs_storage_capacity_milp_constraint(self):
         m = build_model(
             {
@@ -920,7 +922,6 @@ def test_loc_techs_flow_capacity_constraint(self, simple_supply_and_supply_plus)
             * 5
         )
 
-    @pytest.mark.filterwarnings("ignore:(?s).*Integer:calliope.exceptions.ModelWarning")
     def test_loc_techs_flow_capacity_milp_constraint(self):
         m = build_model(
             {}, "supply_milp,two_hours,investment_costs"
@@ -1024,7 +1025,6 @@ def test_loc_tech_carriers_flow_out_max_constraint(self, simple_supply):
         """
         assert "flow_out_max" in simple_supply.backend.constraints
 
-    @pytest.mark.filterwarnings("ignore:(?s).*Integer:calliope.exceptions.ModelWarning")
     def test_loc_tech_carriers_flow_out_max_milp_constraint(self, supply_milp):
         assert "flow_out_max" not in supply_milp.backend.constraints
 
@@ -1044,7 +1044,6 @@ def test_loc_tech_carriers_flow_out_min_constraint(self, simple_supply):
         m.build()
         assert "flow_out_min" in m.backend.constraints
 
-    @pytest.mark.filterwarnings("ignore:(?s).*Integer:calliope.exceptions.ModelWarning")
     def test_loc_tech_carriers_flow_out_min_milp_constraint(self, supply_milp):
         assert "flow_out_min" not in supply_milp.backend.constraints
 
@@ -1064,7 +1063,6 @@ def test_loc_tech_carriers_flow_in_max_constraint(self, simple_supply):
         """
         assert "flow_in_max" in simple_supply.backend.constraints
 
-    @pytest.mark.filterwarnings("ignore:(?s).*Integer:calliope.exceptions.ModelWarning")
     def test_loc_tech_carriers_flow_in_max_milp_constraint(self, supply_milp):
         assert "flow_in_max" in supply_milp.backend.constraints
 
@@ -1119,7 +1117,6 @@ def test_loc_tech_carriers_ramping_constraint(self, simple_supply):
         assert "ramping_down" in m.backend.constraints
 
 
-@pytest.mark.filterwarnings("ignore:(?s).*Integer:calliope.exceptions.ModelWarning")
 @pytest.mark.skip(reason="to be reimplemented by comparison to LP files")
 class TestMILPConstraints:
     # milp.py
@@ -1501,48 +1498,16 @@ def test_techs_unit_capacity_max_systemwide_milp_constraint(self):
         }
         m = build_model(override_max, "conversion_plus_milp,two_hours,investment_costs")
         m.build()
-        assert "unit_capacity_systemwide_milp" in m.backend.constraints
+        assert "unit_capacity_max_systemwide_milp" in m.backend.constraints
         assert (
             m.backend.get_constraint(
-                "unit_capacity_systemwide_milp", as_backend_objs=False
+                "unit_capacity_max_systemwide_milp", as_backend_objs=False
             )
             .sel(techs="test_conversion_plus")
             .ub.item()
             == 2
         )
 
-    @pytest.mark.xfail(reason="unit_cap_equals_systemwide is no more")
-    def test_techs_unit_capacity_equals_systemwide_milp_constraint(self):
-        """
-        sets.techs if unit_cap_max_systemwide or unit_cap_equals_systemwide
-        """
-        override_equals = {
-            "links.a,b.exists": True,
-            "techs.test_conversion_plus.constraints.units_equals_systemwide": 1,
-            "nodes.b.techs.test_conversion_plus.costs.monetary.purchase": 1,
-        }
-        m = build_model(
-            override_equals, "conversion_plus_milp,two_hours,investment_costs"
-        )
-        m.build()
-        assert "unit_capacity_systemwide_milp" in m.backend.constraints
-        assert (
-            m.backend.get_constraint(
-                "unit_capacity_systemwide_milp", as_backend_objs=False
-            )
-            .sel(techs="test_conversion_plus")
-            .lb.item()
-            == 1
-        )
-        assert (
-            m.backend.get_constraint(
-                "unit_capacity_systemwide_milp", as_backend_objs=False
-            )
-            .sel(techs="test_conversion_plus")
-            .ub.item()
-            == 1
-        )
-
     # TODO: always have transmission techs be independent of node names
     @pytest.mark.xfail(
         reason="systemwide constraints now don't work with transmission techs, since transmission tech names are now never independent of a node"
@@ -1588,7 +1553,7 @@ def test_techs_unit_capacity_max_systemwide_no_transmission_milp_constraint(self
             model_file="model_minimal.yaml",
         )
         m.build()
-        assert "unit_capacity_systemwide_milp" in m.backend.constraints
+        assert "unit_capacity_max_systemwide_milp" in m.backend.constraints
 
     @pytest.mark.parametrize("tech", (("test_storage"), ("test_transmission_elec")))
     def test_asynchronous_flow_constraint(self, tech):
@@ -1661,18 +1626,18 @@ def cluster_model(
         storage_initial=False,
     ):
         override = {
-            "model.subset_time": ["2005-01-01", "2005-01-04"],
-            "model.time": {
+            "config.init.subset_time": ["2005-01-01", "2005-01-04"],
+            "config.init.time": {
                 "function": "apply_clustering",
                 "function_options": {
                     "clustering_func": "file=cluster_days.csv:a",
                     "how": how,
                 },
             },
-            "model.custom_math": ["storage_inter_cluster"]
+            "config.init.custom_math": ["storage_inter_cluster"]
             if storage_inter_cluster
             else [],
-            "run.cyclic_storage": cyclic,
+            "config.build.cyclic_storage": cyclic,
         }
         if storage_initial:
             override.update({"techs.test_storage.constraints.storage_initial": 0})
@@ -1725,7 +1690,7 @@ def gurobi_model(self):
         model = build_model(
             model_file=model_file,
             scenario="simple_supply,investment_costs",
-            override_dict={"run": {"solver": "gurobi", "solver_io": "python"}},
+            override_dict={"config.solve": {"solver": "gurobi", "solver_io": "python"}},
         )
         model.build()
         return model
@@ -1747,6 +1712,10 @@ def simple_supply_longnames(self):
         m.backend.verbose_strings()
         return m
 
+    @pytest.fixture
+    def temp_path(self, tmpdir_factory):
+        return tmpdir_factory.mktemp("custom_math")
+
     def test_new_build_has_backend(self, simple_supply):
         assert hasattr(simple_supply, "backend")
 
@@ -1754,6 +1723,61 @@ def test_new_build_optimal(self, simple_supply):
         assert hasattr(simple_supply, "results")
         assert simple_supply._model_data.attrs["termination_condition"] == "optimal"
 
+    @pytest.mark.parametrize("mode", ["operate", "spores"])
+    def test_add_run_mode_custom_math(self, caplog, mode):
+        caplog.set_level(logging.DEBUG)
+        mode_custom_math = AttrDict.from_yaml(
+            importlib.resources.files("calliope") / "math" / f"{mode}.yaml"
+        )
+        m = build_model({}, "simple_supply,two_hours,investment_costs")
+
+        base_math = deepcopy(m.math)
+        base_math.union(mode_custom_math, allow_override=True)
+
+        backend = PyomoBackendModel(m.inputs, mode=mode)
+        backend._add_run_mode_custom_math()
+
+        assert f"Updating math formulation with {mode} mode custom math." in caplog.text
+        assert m.math != base_math
+        assert backend.inputs.attrs["math"].as_dict() == base_math.as_dict()
+
+    def test_add_run_mode_custom_math_before_build(self, caplog, temp_path):
+        """A user can override the run mode custom math by including it directly in the custom math string"""
+        caplog.set_level(logging.DEBUG)
+        custom_math = AttrDict({"variables": {"flow_cap": {"active": True}}})
+        file_path = temp_path.join("custom-math.yaml")
+        custom_math.to_yaml(file_path)
+
+        m = build_model(
+            {"config.init.custom_math": ["operate", file_path]},
+            "simple_supply,two_hours,investment_costs",
+        )
+        m.build(mode="operate")
+
+        # We set operate mode explicitly in our custom math so it won't be added again
+        assert (
+            "Updating math formulation with operate mode custom math."
+            not in caplog.text
+        )
+
+        # operate mode set it to false, then our custom math set it back to active
+        assert m.math.variables.flow_cap.active
+        # operate mode set it to false and our custom math did not override that
+        assert not m.math.variables.storage_cap.active
+
+    def test_run_mode_mismatch(self):
+        m = build_model(
+            {"config.init.custom_math": ["operate"]},
+            "simple_supply,two_hours,investment_costs",
+        )
+        backend = PyomoBackendModel(m.inputs, mode="plan")
+        with pytest.warns(exceptions.ModelWarning) as excinfo:
+            backend._add_run_mode_custom_math()
+
+        assert check_error_or_warning(
+            excinfo, "Running in plan mode, but run mode(s) {'operate'}"
+        )
+
     @pytest.mark.parametrize(
         "component_type", ["variable", "global_expression", "parameter", "constraint"]
     )
@@ -1898,7 +1922,7 @@ def test_solve_after_solve(self, simple_supply):
         assert check_error_or_warning(excinfo, "This model object already has results.")
 
     def test_solve_operate_not_allowed(self, simple_supply):
-        simple_supply.run_config["mode"] = "operate"
+        simple_supply.config.build.mode = "operate"
         simple_supply._model_data.attrs["allow_operate_mode"] = False
 
         try:
@@ -1906,11 +1930,11 @@ def test_solve_operate_not_allowed(self, simple_supply):
                 simple_supply.solve(force=True)
             assert check_error_or_warning(excinfo, "Unable to run this model in op")
         except AssertionError as e:
-            simple_supply.run_config["mode"] = "plan"
+            simple_supply.config.build.mode = "plan"
             simple_supply._model_data.attrs["allow_operate_mode"] = True
             raise e
         else:
-            simple_supply.run_config["mode"] = "plan"
+            simple_supply.config.build.mode = "plan"
             simple_supply._model_data.attrs["allow_operate_mode"] = True
 
     def test_solve_warmstart_not_possible(self, simple_supply):
diff --git a/tests/test_backend_pyomo_objective.py b/tests/test_backend_pyomo_objective.py
index 1bd301b93..6f166abf6 100644
--- a/tests/test_backend_pyomo_objective.py
+++ b/tests/test_backend_pyomo_objective.py
@@ -11,7 +11,7 @@ class TestCostMinimisationObjective:
     def test_nationalscale_minimize_emissions(self):
         model = calliope.examples.national_scale(
             scenario="minimize_emissions_costs",
-            override_dict={"model.subset_time": ["2005-01-01", "2005-01-01"]},
+            override_dict={"config.init.subset_time": ["2005-01-01", "2005-01-01"]},
         )
         model.build()
         model.solve()
@@ -34,7 +34,7 @@ def test_nationalscale_minimize_emissions(self):
     def test_nationalscale_maximize_utility(self):
         model = calliope.examples.national_scale(
             scenario="maximize_utility_costs",
-            override_dict={"model.subset_time": ["2005-01-01", "2005-01-01"]},
+            override_dict={"config.init.subset_time": ["2005-01-01", "2005-01-01"]},
         )
         model.build()
         model.solve()
diff --git a/tests/test_backend_where_parser.py b/tests/test_backend_where_parser.py
index 51e358a90..0d74b395f 100644
--- a/tests/test_backend_where_parser.py
+++ b/tests/test_backend_where_parser.py
@@ -208,10 +208,10 @@ def test_data_var_fail_cannot_handle_constraint(self, data_var, eval_kwargs):
     @pytest.mark.parametrize(
         ["config_string", "expected_val"],
         [
-            ("run.foo", True),
-            ("run.bar.foobar", "baz"),
-            ("run.foobar.baz.foo", np.inf),
-            ("model.a_b", 0),
+            ("config.foo", True),
+            ("config.FOO", "baz"),
+            ("config.foo1", np.inf),
+            ("config.a_b", 0),
         ],
     )
     def test_config_option_valid(
@@ -220,32 +220,37 @@ def test_config_option_valid(
         parsed_ = config_option.parse_string(config_string, parse_all=True)
         assert parsed_[0].eval(**eval_kwargs) == expected_val
 
-    @pytest.mark.parametrize("config_string", ["run.a", "run.a.b", "model.a.b.c"])
-    def test_config_option_missing_but_valid(
-        self, config_option, config_string, eval_kwargs
-    ):
+    @pytest.mark.parametrize("config_string", ["config.a"])
+    def test_config_option_missing(self, config_option, config_string, eval_kwargs):
         parsed_ = config_option.parse_string(config_string, parse_all=True)
-        assert np.isnan(parsed_[0].eval(**eval_kwargs))
+        with pytest.raises(KeyError):
+            parsed_[0].eval(**eval_kwargs)
 
     @pytest.mark.parametrize(
-        "config_string", ["run.", "run.", "RUN", "r un.foo", "model,a_b", "scenarios"]
+        "config_string",
+        ["config.", "config.bar.foobar", "RUN", "r un.foo", "model,a_b", "scenarios"],
     )
     def test_config_fail_malformed_string(self, config_option, config_string):
         with pytest.raises(pyparsing.ParseException) as excinfo:
             config_option.parse_string(config_string, parse_all=True)
         assert check_error_or_warning(excinfo, "Expected")
 
-    @pytest.mark.parametrize("config_string", ["foo.bar", "all_inf.is_result"])
-    def test_config_missing_config_group(
-        self, config_option, eval_kwargs, config_string
-    ):
+    @pytest.mark.parametrize(
+        "config_string", ["CONFIG.bar", "foo.bar", "all_inf.is_result"]
+    )
+    def test_config_missing_config_identifier(self, config_option, config_string):
+        with pytest.raises(pyparsing.ParseException) as excinfo:
+            config_option.parse_string(config_string, parse_all=True)
+        assert check_error_or_warning(excinfo, "Expected")
+
+    @pytest.mark.parametrize("config_string", ["config.nonexistent", "config.config"])
+    def test_config_missing_from_data(self, config_option, eval_kwargs, config_string):
         parsed_ = config_option.parse_string(config_string, parse_all=True)
-        with pytest.raises(BackendError) as excinfo:
+        with pytest.raises(KeyError):
             parsed_[0].eval(**eval_kwargs)
-        assert check_error_or_warning(excinfo, "Invalid configuration group")
 
     @pytest.mark.parametrize(
-        ["config_string", "type_"], [("model.b_a", "list"), ("run.bar", "AttrDict")]
+        ["config_string", "type_"], [("config.b_a", "list"), ("config.bar", "AttrDict")]
     )
     def test_config_fail_datatype(
         self, config_option, eval_kwargs, config_string, type_
@@ -343,16 +348,13 @@ def test_comparison_parser_data_var_different_ops(
     @pytest.mark.parametrize(
         ["config_string", "comparison_val", "expected_true"],
         [
-            ("run.foo", "True", True),
-            ("run.foo", "False", False),
-            ("run.foo", 1, True),
-            ("run.bar.foobar", "baz", True),
-            ("run.bar.foobar", True, False),
-            ("run.bar.foobar", "aaa", False),
-            ("model.a_b", 0, True),
-            ("model.a_b", 0.0, True),
-            ("model.a_b", False, True),  # FIXME: should this be expected (0 == False)?
-            ("model.a_b", 1, False),
+            ("config.foo", "True", True),
+            ("config.foo", "False", False),
+            ("config.foo", 1, True),
+            ("config.a_b", 0, True),
+            ("config.a_b", 0.0, True),
+            ("config.a_b", False, True),  # FIXME: should this be expected (0 == False)?
+            ("config.a_b", 1, False),
         ],
     )
     def test_comparison_parser_model_config(
@@ -367,12 +369,12 @@ def test_comparison_parser_model_config(
         "comparison_string",
         [
             "1=1",
-            "run.foo==bar",
+            "config.foo==bar",
             "all_inf=__type__",
             "$foo=bar",
             "foo=$bar",
-            "foo=run.bar",
-            "run.foo=_bar",
+            "foo=config.bar",
+            "config.foo=_bar",
         ],
     )
     def test_comparison_malformed_string(self, comparison, comparison_string):
@@ -415,9 +417,9 @@ def test_subsetting_parser_malformed(self, subset, subset_string):
         ["parser_name", "parse_string", "expected"],
         [
             ("data_var", "foo", "DATA_VAR:foo"),
-            ("config_option", "model.bar", "CONFIG:model_config.bar"),
+            ("config_option", "config.bar", "CONFIG:bar"),
             ("bool_operand", "TRUE", "BOOL:true"),
-            ("comparison", "model.bar=True", "CONFIG:model_config.bar=BOOL:true"),
+            ("comparison", "config.bar=True", "CONFIG:bar=BOOL:true"),
             ("subset", "[foo, 1] in foos", "SUBSET:foos[STRING:foo, NUM:1]"),
         ],
     )
@@ -432,7 +434,7 @@ class TestParserMasking:
         ["instring", "expected"],
         [
             ("all_inf", "all_false"),
-            ("run.foo=True", True),
+            ("config.foo=True", True),
             ("inheritance(boo)", "boo_inheritance_bool"),
         ],
     )
@@ -448,11 +450,11 @@ def test_no_aggregation(
     @pytest.mark.parametrize(
         ["instring", "expected_true"],
         [
-            ("run.foo=True and model.a_b=0", True),
-            ("run.foo=False And model.a_b=0", False),
-            ("run.foo=True AND model.a_b=1", False),
-            ("run.foo=False and model.a_b=1", False),
-            ("run.foo=1  and  model.a_b=0", True),
+            ("config.foo=True and config.a_b=0", True),
+            ("config.foo=False And config.a_b=0", False),
+            ("config.foo=True AND config.a_b=1", False),
+            ("config.foo=False and config.a_b=1", False),
+            ("config.foo=1  and  config.a_b=0", True),
         ],
     )
     def test_where_string_and(self, parse_where_string, instring, expected_true):
@@ -462,11 +464,11 @@ def test_where_string_and(self, parse_where_string, instring, expected_true):
     @pytest.mark.parametrize(
         ["instring", "expected_true"],
         [
-            ("run.foo=True or model.a_b=0", True),
-            ("run.foo=False Or model.a_b=0", True),
-            ("run.foo=True OR model.a_b=1", True),
-            ("run.foo=False or model.a_b=1", False),
-            ("run.foo=1 or model.a_b=0", True),
+            ("config.foo=True or config.a_b=0", True),
+            ("config.foo=False Or config.a_b=0", True),
+            ("config.foo=True OR config.a_b=1", True),
+            ("config.foo=False or config.a_b=1", False),
+            ("config.foo=1 or config.a_b=0", True),
         ],
     )
     def test_where_string_or(self, parse_where_string, instring, expected_true):
@@ -476,11 +478,11 @@ def test_where_string_or(self, parse_where_string, instring, expected_true):
     @pytest.mark.parametrize(
         ["instring", "expected_true"],
         [
-            ("not run.foo=True", False),
-            ("Not run.foo=False and model.a_b=0", True),
-            ("run.foo=True and NOT model.a_b=1", True),
-            ("not run.foo=False and not model.a_b=1", True),
-            ("run.foo=False or not model.a_b=0", False),
+            ("not config.foo=True", False),
+            ("Not config.foo=False and config.a_b=0", True),
+            ("config.foo=True and NOT config.a_b=1", True),
+            ("not config.foo=False and not config.a_b=1", True),
+            ("config.foo=False or not config.a_b=0", False),
         ],
     )
     def test_where_string_not(self, parse_where_string, instring, expected_true):
@@ -539,11 +541,11 @@ def test_where_arrays_subsetting(
     @pytest.mark.parametrize(
         ["instring", "expected"],
         [
-            ("all_inf and all_nan or run.foo=True", "all_true"),
-            ("all_inf and (all_nan or run.foo=True)", "all_false"),
-            ("not all_inf and not run.foo=False ", "all_true"),
+            ("all_inf and all_nan or config.foo=True", "all_true"),
+            ("all_inf and (all_nan or config.foo=True)", "all_false"),
+            ("not all_inf and not config.foo=False ", "all_true"),
             (
-                "(all_inf=inf and with_inf) or (run.foo=True and all_nan)",
+                "(all_inf=inf and with_inf) or (config.foo=True and all_nan)",
                 "with_inf_as_bool",
             ),
         ],
@@ -567,8 +569,8 @@ def test_mixed_where(
             "and all_inf",
             "with_inf not and all_inf",
             "with_inf and or all_inf",
-            "run.foo=True and and run.foo=True",
-            "run.foo=True andnot all_inf",
+            "config.foo=True and and config.foo=True",
+            "config.foo=True andnot all_inf",
         ],
     )
     def test_where_malformed(self, where, instring):
@@ -589,9 +591,9 @@ def latex_eval_kwargs(self, eval_kwargs):
             ("data_var", "with_inf", r"\exists (\textit{with_inf}_\text{node,tech})"),
             ("data_var", "foo", r"\exists (\textit{foo})"),
             ("data_var", "no_dims", r"\exists (\textit{no_dims})"),
-            ("config_option", "run.foo", r"\text{run_config.foo}"),
+            ("config_option", "config.foo", r"\text{config.foo}"),
             ("bool_operand", "True", "true"),
-            ("comparison", "run.foo>1", r"\text{run_config.foo}\mathord{>}\text{1}"),
+            ("comparison", "config.foo>1", r"\text{config.foo}\mathord{>}\text{1}"),
             (
                 "comparison",
                 "with_inf=True",
@@ -611,8 +613,8 @@ def latex_eval_kwargs(self, eval_kwargs):
             ),
             (
                 "where",
-                "no_dims AND (with_inf OR run.foo>1)",
-                r"\exists (\textit{no_dims}) \land (\exists (\textit{with_inf}_\text{node,tech}) \lor \text{run_config.foo}\mathord{>}\text{1})",
+                "no_dims AND (with_inf OR config.foo>1)",
+                r"\exists (\textit{no_dims}) \land (\exists (\textit{with_inf}_\text{node,tech}) \lor \text{config.foo}\mathord{>}\text{1})",
             ),
         ],
     )
diff --git a/tests/test_cli.py b/tests/test_cli.py
index d24714a7b..e00476cb1 100644
--- a/tests/test_cli.py
+++ b/tests/test_cli.py
@@ -41,7 +41,7 @@ def test_run_from_yaml(self):
                     "--save_netcdf=output.nc",
                     # FIXME: should be CBC but a timeout error causes issues on OSX CI
                     # (likely fixed by updating pyomo)
-                    "--override_dict={'run.solver': 'glpk'}",
+                    "--override_dict={'config.solve.solver': 'glpk'}",
                 ],
             )
             assert result.exit_code == 0
@@ -62,7 +62,7 @@ def test_save_per_spore(self):
                     _MODEL_NATIONAL,
                     "--save_netcdf=output.nc",
                     "--scenario=spores",
-                    "--override_dict={'run.spores_options.save_per_spore': True}",
+                    "--override_dict={'config.solve.spores_save_per_spore': True}",
                 ],
             )
             print(os.listdir(os.path.join(tempdir, "output")))
@@ -88,7 +88,7 @@ def test_incorrect_model_format(self):
         assert result.exit_code == 1
 
     @pytest.mark.parametrize(
-        "arg", (("--scenario=test"), ("--override_dict={'model.name': 'test'}"))
+        "arg", (("--scenario=test"), ("--override_dict={'config.init.name': 'test'}"))
     )
     def test_unavailable_arguments(self, arg):
         runner = CliRunner()
diff --git a/tests/test_constraint_results.py b/tests/test_constraint_results.py
index 3e95be549..b96213087 100644
--- a/tests/test_constraint_results.py
+++ b/tests/test_constraint_results.py
@@ -83,22 +83,20 @@ def _get_flow(model, flow):
                 .dropna(how="all")
             )
 
-        m = calliope.examples.urban_scale(override_dict={"run.zero_threshold": 1e-6})
+        m = calliope.examples.urban_scale()
         m.build()
-        m.solve()
+        m.solve(zero_threshold=1e-6)
         _out = _get_flow(m, "out")
         _in = _get_flow(m, "in")
         assert any(((_in < 0) & (_out > 0)).any()) is True
 
         m_bin = calliope.examples.urban_scale(
             override_dict={
-                "techs.heat_pipes.constraints.force_async_flow": True,
-                "run.solver_options.mipgap": 0.05,
-                "run.zero_threshold": 1e-6,
+                "techs.heat_pipes.constraints.force_asynchronous_flow": True,
             }
         )
-        m_bin.build()
-        m_bin.solve()
+        m_bin.build(solver_options={"mipgap": 0.05})
+        m_bin.solve(zero_threshold=1e-6)
         _out = _get_flow(m_bin, "out")
         _in = _get_flow(m_bin, "in")
         assert any(((_in < 0) & (_out > 0)).any()) is False
@@ -113,9 +111,11 @@ def _run_model(feasibility, cap_val):
                 "nodes.a.techs": {"test_supply_elec": {}, "test_demand_elec": {}},
                 "links.a,b.active": False,
                 # pick a time subset where demand is uniformally -10 throughout
-                "model.subset_time": ["2005-01-01 06:00:00", "2005-01-01 08:00:00"],
-                "run.ensure_feasibility": feasibility,
-                "run.bigM": 1e3,
+                "config.init.subset_time": [
+                    "2005-01-01 06:00:00",
+                    "2005-01-01 08:00:00",
+                ],
+                "parameters.bigM": 1e3,
                 # Allow setting resource and flow_cap_max/equals to force infeasibility
                 "techs.test_supply_elec.constraints": {
                     "source_equals": cap_val,
@@ -126,7 +126,7 @@ def _run_model(feasibility, cap_val):
             model = build_model(
                 override_dict=override_dict, scenario="investment_costs"
             )
-            model.build()
+            model.build(ensure_feasibility=feasibility)
             model.solve()
             return model
 
@@ -267,9 +267,7 @@ def test_operate_mode(self, model_file):
     def test_operate_mode_horizon_window(self, model_file, horizon_window):
         horizon, window = horizon_window
         override_dict = {
-            "model.subset_time": ["2005-01-01", "2005-01-05"],
-            "run.operation.horizon": horizon,
-            "run.operation.window": window,
+            "config.init.subset_time": ["2005-01-01", "2005-01-05"],
         }
         model = build_model(
             model_file=model_file,
@@ -277,4 +275,4 @@ def test_operate_mode_horizon_window(self, model_file, horizon_window):
             override_dict=override_dict,
         )
         model.build()
-        model.solve()
+        model.solve(operate_horizon=horizon, operate_window=window)
diff --git a/tests/test_core_model.py b/tests/test_core_model.py
index 7bcc6141b..775a0e564 100644
--- a/tests/test_core_model.py
+++ b/tests/test_core_model.py
@@ -1,6 +1,5 @@
 import logging
 import os
-from pathlib import Path
 
 import calliope
 import numpy as np
@@ -16,7 +15,7 @@ class TestModel:
     @pytest.fixture(scope="module")
     def national_scale_example(self):
         model = calliope.examples.national_scale(
-            override_dict={"model.subset_time": ["2005-01-01", "2005-01-01"]}
+            override_dict={"config.init.subset_time": ["2005-01-01", "2005-01-01"]}
         )
         return model
 
@@ -37,8 +36,8 @@ def test_info_minimal_model(self):
         model.info()
 
     def test_update_observed_dict(self, national_scale_example):
-        national_scale_example.model_config.name = "foo"
-        assert national_scale_example._model_data.attrs["model_config"].name == "foo"
+        national_scale_example.config.build["backend"] = "foo"
+        assert national_scale_example._model_data.attrs["config"].build.backend == "foo"
 
     def test_add_observed_dict_from_model_data(
         self, national_scale_example, dict_to_add
@@ -77,7 +76,7 @@ def storage_inter_cluster(
         self,
     ):
         return build_model(
-            {"model.custom_math": ["storage_inter_cluster"]},
+            {"config.init.custom_math": ["storage_inter_cluster"]},
             "simple_supply,two_hours,investment_costs",
         )
 
@@ -106,7 +105,7 @@ def test_variable_bound(self, storage_inter_cluster):
     def test_allowed_internal_constraint(self, override, expected):
         with pytest.raises(calliope.exceptions.ModelError) as excinfo:
             build_model(
-                {"model.custom_math": override},
+                {"config.init.custom_math": override},
                 "simple_supply,two_hours,investment_costs",
             )
         assert check_error_or_warning(
@@ -128,7 +127,7 @@ def test_internal_override_from_yaml(self, temp_path):
         )
         new_constraint.to_yaml(temp_path.join("custom-math.yaml"))
         m = build_model(
-            {"model.custom_math": [temp_path.join("custom-math.yaml")]},
+            {"config.init.custom_math": [temp_path.join("custom-math.yaml")]},
             "simple_supply,two_hours,investment_costs",
         )
         assert "constraint_name" in m.math["constraints"].keys()
@@ -144,7 +143,7 @@ def test_override_existing_internal_constraint(self, temp_path, simple_supply):
         )
         new_constraint.to_yaml(file_path)
         m = build_model(
-            {"model.custom_math": [file_path]},
+            {"config.init.custom_math": [file_path]},
             "simple_supply,two_hours,investment_costs",
         )
         base = simple_supply.math["constraints"][
@@ -173,7 +172,7 @@ def test_override_order(self, temp_path, simple_supply):
             to_add.append(filepath)
 
         m = build_model(
-            {"model.custom_math": to_add},
+            {"config.init.custom_math": to_add},
             "simple_supply,two_hours,investment_costs",
         )
 
@@ -198,7 +197,7 @@ def test_override_existing_internal_constraint_merge(
         new_constraint.to_yaml(file_path)
         m = build_model(
             {
-                "model.custom_math": [
+                "config.init.custom_math": [
                     "storage_inter_cluster",
                     file_path,
                 ]
@@ -219,47 +218,6 @@ def test_override_existing_internal_constraint_merge(
             else:
                 assert base[i] == new[i]
 
-    @pytest.mark.parametrize("mode", ["operate", "spores"])
-    def test_add_run_mode_custom_math(self, simple_supply, mode):
-        mode_custom_math = calliope.AttrDict.from_yaml(
-            Path(calliope.__file__).parent / "math" / f"{mode}.yaml"
-        )
-        m = build_model(scenario="simple_supply,two_hours,investment_costs")
-        m.run_config.mode = mode
-        m._add_run_mode_custom_math()
-
-        base_math = simple_supply.math.copy()
-        base_math.union(mode_custom_math, allow_override=True)
-        assert m.math == base_math
-
-    def test_add_run_mode_custom_math_before_build(self, temp_path):
-        """A user can override the run mode custom math by including it directly in the custom math string"""
-        custom_math = calliope.AttrDict({"variables": {"flow_cap": {"active": True}}})
-        file_path = temp_path.join("custom-math.yaml")
-        custom_math.to_yaml(file_path)
-
-        m = build_model(
-            {"model.custom_math": ["operate", file_path]},
-            "simple_supply,two_hours,investment_costs",
-        )
-        m.run_config.mode = "operate"
-        m._add_run_mode_custom_math()
-
-        assert m.math.variables.flow_cap.active
-
-    def test_run_mode_mismatch(self):
-        m = build_model(
-            {"model.custom_math": ["operate"]},
-            "simple_supply,two_hours,investment_costs",
-        )
-        m.run_config.mode = "plan"
-        with pytest.warns(calliope.exceptions.ModelWarning) as excinfo:
-            m._add_run_mode_custom_math()
-
-        assert check_error_or_warning(
-            excinfo, "Running in plan mode, but run mode(s) {'operate'}"
-        )
-
 
 class TestValidateMathDict:
     def test_base_math(self, caplog, simple_supply):
diff --git a/tests/test_core_preprocess.py b/tests/test_core_preprocess.py
index c4c8f9a45..a8b1a2454 100644
--- a/tests/test_core_preprocess.py
+++ b/tests/test_core_preprocess.py
@@ -9,7 +9,7 @@
 from pytest import approx
 
 from .common.util import build_test_model as build_model
-from .common.util import check_error_or_warning, defaults
+from .common.util import check_error_or_warning
 
 
 class TestModelRun:
@@ -29,8 +29,11 @@ def test_model_from_dict(self):
             }
         )
         model_dict.union(node_dict)
-        model_dict.model["timeseries_data_path"] = os.path.join(
-            this_path, "common", "test_model", model_dict.model["timeseries_data_path"]
+        model_dict.config.init["timeseries_data_path"] = os.path.join(
+            this_path,
+            "common",
+            "test_model",
+            model_dict.config.init["timeseries_data_path"],
         )
         # test as AttrDict
         calliope.Model(model_dict)
@@ -238,7 +241,9 @@ def test_incorrect_subset_time(self):
         """
 
         def override(param):
-            return AttrDict.from_yaml_string("model.subset_time: {}".format(param))
+            return AttrDict.from_yaml_string(
+                "config.init.subset_time: {}".format(param)
+            )
 
         # should fail: one string in list
         with pytest.raises(exceptions.ModelError):
@@ -293,7 +298,7 @@ def test_incorrect_date_format(self):
 
         # should pass: changing datetime format from default
         override1 = {
-            "model.timeseries_dateformat": "%d/%m/%Y %H:%M:%S",
+            "config.init.timeseries_dateformat": "%d/%m/%Y %H:%M:%S",
             "techs.test_demand_heat.constraints.sink_equals": "file=demand_heat_diff_dateformat.csv",
             "techs.test_demand_elec.constraints.sink_equals": "file=demand_heat_diff_dateformat.csv",
         }
@@ -312,7 +317,7 @@ def test_incorrect_date_format(self):
             build_model(override_dict=override2, scenario="simple_conversion")
 
         # should fail: wrong dateformat input for all files
-        override3 = {"model.timeseries_dateformat": "%d/%m/%Y %H:%M:%S"}
+        override3 = {"config.init.timeseries_dateformat": "%d/%m/%Y %H:%M:%S"}
 
         with pytest.raises(exceptions.ModelError):
             build_model(override_dict=override3, scenario="simple_supply")
@@ -347,7 +352,7 @@ def test_single_timestep(self):
         be inferred to be 1 hour
         """
         override1 = {
-            "model.subset_time": ["2005-01-01 00:00:00", "2005-01-01 00:00:00"]
+            "config.init.subset_time": ["2005-01-01 00:00:00", "2005-01-01 00:00:00"]
         }
         # check in output error that it points to: 07/01/2005 10:00:00
         with pytest.warns(exceptions.ModelWarning) as warn_info:
@@ -553,10 +558,10 @@ def test_invalid_dataframes_passed(self):
 
 
 class TestChecks:
-    def test_unrecognised_config_keys(self):
+    def test_unrecognised_top_level_keys(self):
         """
         Check that the only top level keys can be 'model', 'run', 'nodes',
-        'techs', 'tech_groups' (+ 'config_path', but that is an internal addition)
+        'techs', 'tech_groups' (+ '_model_def_path', but that is an internal addition)
         """
         override = {"nonsensical_key": "random_string"}
 
@@ -578,47 +583,20 @@ def test_missing_config_key(self):
             excinfo, "Model is missing required top-level configuration item: nodes"
         )
 
-    def test_unrecognised_model_run_keys(self):
+    @pytest.mark.parametrize("top_level_key", ["init", "build", "solve"])
+    def test_unrecognised_config_keys(self, top_level_key):
         """
         Check that the only keys allowed in 'model' and 'run' are those in the
         model defaults
         """
-        override1 = {"model.nonsensical_key": "random_string"}
-
-        with pytest.warns(exceptions.ModelWarning) as excinfo:
-            build_model(override_dict=override1, scenario="simple_supply")
-
-        assert check_error_or_warning(
-            excinfo, "Unrecognised setting in model configuration: nonsensical_key"
-        )
-
-        override2 = {"run.nonsensical_key": "random_string"}
-
-        with pytest.warns(exceptions.ModelWarning) as excinfo:
-            build_model(override_dict=override2, scenario="simple_supply")
-
-        assert check_error_or_warning(
-            excinfo, "Unrecognised setting in run configuration: nonsensical_key"
-        )
-
-        # A key that should be in run but is given in model
-        override3 = {"model.solver": "glpk"}
+        override = {f"config.{top_level_key}.nonsensical_key": "random_string"}
 
         with pytest.warns(exceptions.ModelWarning) as excinfo:
-            build_model(override_dict=override3, scenario="simple_supply")
-
-        assert check_error_or_warning(
-            excinfo, "Unrecognised setting in model configuration: solver"
-        )
-
-        # A key that should be in model but is given in run
-        override4 = {"run.subset_time": None}
-
-        with pytest.warns(exceptions.ModelWarning) as excinfo:
-            build_model(override_dict=override4, scenario="simple_supply")
+            build_model(override_dict=override, scenario="simple_supply")
 
         assert check_error_or_warning(
-            excinfo, "Unrecognised setting in run configuration: subset_time"
+            excinfo,
+            f"Unrecognised setting in `{top_level_key}` configuration: nonsensical_key",
         )
 
     @pytest.mark.skip(
@@ -628,7 +606,7 @@ def test_warn_null_number_of_spores(self):
         """
         Check that spores number is greater than 0 if spores run mode is selected
         """
-        override = {"run.spores_options.spores_number": 0}
+        override = {"config.build.spores_number": 0}
 
         with pytest.warns(exceptions.ModelWarning) as warn:
             build_model(scenario="spores,simple_supply", override_dict=override)
@@ -644,13 +622,13 @@ def test_non_string_score_cost_class(self):
         """
         Check that the score_cost_class for spores scoring is a string
         """
-        override = {"run.spores_options.score_cost_class": 0}
+        override = {"config.build.spores_score_cost_class": 0}
 
         with pytest.raises(exceptions.ModelError) as excinfo:
             build_model(scenario="spores,simple_supply", override_dict=override)
 
         assert check_error_or_warning(
-            excinfo, "`run.spores_options.score_cost_class` must be a string"
+            excinfo, "`config.build.spores_score_cost_class` must be a string"
         )
 
     @pytest.mark.parametrize(
@@ -667,10 +645,10 @@ def test_unrecognised_tech_keys(self, invalid_key):
 
     def test_model_version_mismatch(self):
         """
-        Model config says model.calliope_version = 0.1, which is not what we
+        Model config says config.init.calliope_version = 0.1, which is not what we
         are running, so we want a warning.
         """
-        override = {"model.calliope_version": 0.1}
+        override = {"config.init.calliope_version": 0.1}
 
         with pytest.warns(exceptions.ModelWarning) as excinfo:
             build_model(override_dict=override, scenario="simple_supply,one_day")
@@ -1058,49 +1036,6 @@ def test_tech_defined_twice_in_links(self):
         }
         build_model(override_dict=override, scenario="simple_supply,one_day")
 
-    def test_allowed_time_varying_constraints(self):
-        """
-        `file=` is only allowed on a hardcoded list of constraints, unless
-        `_time_varying` is appended to the constraint (i.e. user input)
-        """
-
-        allowed_constraints_no_file = list(
-            set(defaults.tech_groups.storage.allowed_constraints).difference(
-                defaults.model.file_allowed
-            )
-        )
-
-        allowed_constraints_file = list(
-            set(defaults.tech_groups.storage.allowed_constraints).intersection(
-                defaults.model.file_allowed
-            )
-        )
-
-        def override(param):
-            return AttrDict.from_yaml_string(
-                "techs.test_storage.constraints.{}: file=binary_one_day.csv".format(
-                    param
-                )
-            )
-
-        # should fail: Cannot have `file=` on the following constraints
-        for param in allowed_constraints_no_file:
-            with pytest.raises(exceptions.ModelError) as errors:
-                build_model(
-                    override_dict=override(param), scenario="simple_storage,one_day"
-                )
-            assert check_error_or_warning(
-                errors,
-                "Cannot load data from file for configuration"
-                " `techs.test_storage.constraints.{}`".format(param),
-            )
-
-        # should pass: can have `file=` on the following constraints
-        for param in allowed_constraints_file:
-            build_model(
-                override_dict=override(param), scenario="simple_storage,one_day"
-            )
-
     @pytest.mark.filterwarnings(
         "ignore:(?s).*Updated from coordinate system:calliope.exceptions.ModelWarning"
     )
@@ -1180,9 +1115,10 @@ def test_one_way(self):
             "links.X1,N1.techs.heat_pipes.switches.one_way": True,
             "links.N1,X2.techs.heat_pipes.switches.one_way": True,
             "links.N1,X3.techs.heat_pipes.switches.one_way": True,
-            "model.subset_time": ["2005-01-01", "2005-01-01"],
         }
-        m = calliope.examples.urban_scale(override_dict=override)
+        m = calliope.examples.urban_scale(
+            override_dict=override, subset_time=["2005-01-01", "2005-01-01"]
+        )
         m.build()
         removed_prod_links = [
             {"nodes": "X1", "techs": "heat_pipes:N1"},
@@ -1225,7 +1161,7 @@ def test_carrier_ratio_for_inexistent_carrier(self):
             "Tech `test_conversion_plus` gives a carrier ratio for `another_carrier`, but does not actually",
         )
 
-    def test_carrier_ratio_for_specified_carrier(self):
+    def test_carrier_ratio_for_specified_carrier(self, recwarn):
         """
         The warning for not defining a carrier ratio for a carrier a tech does
         not actually use should not be triggered if the carrier is defined.
@@ -1237,16 +1173,14 @@ def test_carrier_ratio_for_specified_carrier(self):
                     heat: 1.0
             """
         )
-        with pytest.warns() as excinfo:
-            build_model(
-                override_dict=override, scenario="simple_conversion_plus,one_day"
-            )
+
+        build_model(override_dict=override, scenario="simple_conversion_plus,one_day")
 
         assert "Tech `test_conversion_plus` gives a carrier ratio" not in [
-            str(i) for i in excinfo.list
+            str(i) for i in recwarn.list
         ]
 
-    def test_carrier_ratio_from_file(self):
+    def test_carrier_ratio_from_file(self, recwarn):
         """
         It is possible to load a timeseries carrier_ratio from file
         """
@@ -1256,13 +1190,10 @@ def test_carrier_ratio_from_file(self):
                 carrier_out.heat: file=carrier_ratio.csv
             """
         )
-        with pytest.warns() as excinfo:
-            build_model(
-                override_dict=override, scenario="simple_conversion_plus,one_day"
-            )
+        build_model(override_dict=override, scenario="simple_conversion_plus,one_day")
 
         assert "Cannot load data from file for configuration" not in [
-            str(i) for i in excinfo.list
+            str(i) for i in recwarn.list
         ]
 
     @pytest.mark.filterwarnings("ignore:(?s).*Integer:calliope.exceptions.ModelWarning")
@@ -1325,6 +1256,9 @@ def test_override_coordinates(self):
 
         assert check_error_or_warning(excinfo, "Updated from coordinate system")
 
+    @pytest.mark.xfail(
+        reason="Removed this check because it has to happen *after* calling `build`"
+    )
     def test_clustering_and_cyclic_storage(self):
         """
         Don't allow time clustering with cyclic storage if not also using
@@ -1332,16 +1266,16 @@ def test_clustering_and_cyclic_storage(self):
         """
 
         override = {
-            "model.subset_time": ["2005-01-01", "2005-01-04"],
-            "model.time": {
+            "config.init.subset_time": ["2005-01-01", "2005-01-04"],
+            "config.init.time": {
                 "function": "apply_clustering",
                 "function_options": {
-                    "clustering_func": "file=cluster_days.csv:0",
+                    "clustering_func": "file=cluster_days.csv:a",
                     "how": "mean",
                     "storage_inter_cluster": False,
                 },
             },
-            "run.cyclic_storage": True,
+            "config.build.cyclic_storage": True,
         }
 
         with pytest.raises(exceptions.ModelError) as error:
@@ -1447,54 +1381,26 @@ def test_milp_storage_warning(self, constraints, costs):
             "Integer and / or binary decision variables are included in this model",
         )
 
-    def test_fail_on_string(self):
-        with pytest.raises(calliope.exceptions.ModelError) as exception:
-            build_model(
-                model_file="weighted_obj_func.yaml",
-                scenario="illegal_string_cost_class",
-            )
-
-        assert check_error_or_warning(
-            exception, "`run.objective_options.cost_class` must be a dictionary."
-        )
-
-    def test_warn_on_using_default(self):
-        with pytest.warns(exceptions.ModelWarning) as warn:
-            build_model(
-                model_file="weighted_obj_func.yaml",
-                scenario="emissions_objective_without_removing_monetary_default",
-            )
-
-        assert check_error_or_warning(
-            warn, "Monetary cost class with a weight of 1 is still included"
-        )
-
     @pytest.mark.parametrize(
         "override",
         [
-            ({"run.objective_options.cost_class": {"monetary": None}}),
+            ({"parameters.objective_cost_class.data": None}),
             (
                 {
-                    "run.objective_options.cost_class": {
-                        "monetary": None,
-                        "emissions": None,
+                    "parameters.objective_cost_class": {
+                        "data": [None, 1],
+                        "index": ["monetary", "emissions"],
                     }
                 }
             ),
         ],
     )
     def test_warn_on_no_weight(self, override):
-        with pytest.warns(exceptions.ModelWarning) as warn:
-            model = build_model(
-                model_file="weighted_obj_func.yaml", override_dict=override
-            )
+        with pytest.raises(exceptions.ModelError) as excinfo:
+            build_model(model_file="weighted_obj_func.yaml", override_dict=override)
 
         assert check_error_or_warning(
-            warn, "cost class monetary has weight = None, setting weight to 1"
-        )
-        assert all(
-            model.run_config["objective_options"]["cost_class"][i] == 1
-            for i in override["run.objective_options.cost_class"].keys()
+            excinfo, "Objective cost class weights must be numeric"
         )
 
     @pytest.mark.skip(reason="check is now taken care of in typedconfig")
@@ -1533,7 +1439,7 @@ def test_storage_inter_cluster_vs_storage_discharge_depth(self):
         Check that the storage_inter_cluster is not used together with storage_discharge_depth
         """
         with pytest.raises(exceptions.ModelError) as error:
-            override = {"model.subset_time": ["2005-01-01", "2005-01-04"]}
+            override = {"config.init.subset_time": ["2005-01-01", "2005-01-04"]}
             build_model(override, "clustering,simple_storage,storage_discharge_depth")
 
         assert check_error_or_warning(
@@ -1573,18 +1479,20 @@ def model_national(self, load_timeseries_from_dataframes):
         """
         if load_timeseries_from_dataframes:
             # Create dictionary with dataframes
-            timeseries_data_path = os.path.join(
-                calliope.examples._PATHS["national_scale"], "timeseries_data/"
+            timeseries_data_path = (
+                calliope.examples.EXAMPLE_MODEL_DIR
+                / "national_scale"
+                / "timeseries_data"
             )
             timeseries_dataframes = {}
             timeseries_dataframes["csp_resource"] = pd.read_csv(
-                os.path.join(timeseries_data_path, "csp_resource.csv"), index_col=0
+                timeseries_data_path / "csp_resource.csv", index_col=0
             )
             timeseries_dataframes["demand_1"] = pd.read_csv(
-                os.path.join(timeseries_data_path, "demand-1.csv"), index_col=0
+                timeseries_data_path / "demand-1.csv", index_col=0
             )
             timeseries_dataframes["demand_2"] = pd.read_csv(
-                os.path.join(timeseries_data_path, "demand-2.csv"), index_col=0
+                timeseries_data_path / "demand-2.csv", index_col=0
             )
             # Create override dict telling calliope to load timeseries from df
             override_dict = {
@@ -1601,7 +1509,7 @@ def model_national(self, load_timeseries_from_dataframes):
     @pytest.fixture
     def model_urban(self):
         return calliope.examples.urban_scale(
-            override_dict={"model.subset_time": ["2005-01-01", "2005-01-10"]}
+            override_dict={"config.init.subset_time": ["2005-01-01", "2005-01-10"]}
         )
 
     @pytest.mark.parametrize("load_timeseries_from_dataframes", [False, True])
diff --git a/tests/test_core_time.py b/tests/test_core_time.py
index d6a295ce0..d8085d86f 100644
--- a/tests/test_core_time.py
+++ b/tests/test_core_time.py
@@ -13,8 +13,8 @@ class TestClustering:
     def model_national(self, scope="module"):
         return calliope.examples.national_scale(
             override_dict={
-                "model.random_seed": 23,
-                "model.subset_time": ["2005-01-01", "2005-03-31"],
+                "config.init.random_seed": 23,
+                "config.init.subset_time": ["2005-01-01", "2005-03-31"],
             }
         )
 
@@ -108,7 +108,7 @@ def test_15min_clustering(self):
         # it is only different for '2005-01-02'
         override = {
             "techs.test_demand_elec.constraints.sink_equals": "file=demand_elec_15mins.csv",
-            "model.subset_time": None,
+            "config.init.subset_time": None,
         }
 
         model = build_test_model(override, scenario="simple_supply,one_day")
@@ -151,7 +151,7 @@ def test_15min_to_2h_clustering(self):
         # it is only different for '2005-01-02'
         override = {
             "techs.test_demand_elec.constraints.sink_equals": "file=demand_elec_15T_to_2h.csv",
-            "model.subset_time": None,
+            "config.init.subset_time": None,
         }
 
         model = build_test_model(override, scenario="simple_supply,one_day")
@@ -235,8 +235,8 @@ def test_15min_to_2h_clustering(self):
     @pytest.fixture
     def predefined_cluster_override(self):
         return {
-            "model.subset_time": ["2005-01-01", "2005-01-04"],
-            "model.time": {
+            "config.init.subset_time": ["2005-01-01", "2005-01-04"],
+            "config.init.time": {
                 "function": "apply_clustering",
                 "function_options": {
                     "clustering_func": "file=clusters.csv:a",
@@ -255,7 +255,7 @@ def test_predefined_clusters(self, predefined_cluster_override):
         override2 = {
             **predefined_cluster_override,
             **{
-                "model.time.function_options.clustering_func": "file=cluster_days.csv:b"
+                "config.init.time.function_options.clustering_func": "file=cluster_days.csv:b"
             },
         }
 
@@ -272,8 +272,8 @@ def test_predefined_clusters_closest(self, predefined_cluster_override):
         override3 = {
             **predefined_cluster_override,
             **{
-                "model.time.function_options.clustering_func": "file=cluster_days.csv:b",
-                "model.time.function_options.how": "closest",
+                "config.init.time.function_options.clustering_func": "file=cluster_days.csv:b",
+                "config.init.time.function_options.how": "closest",
             },
         }
 
@@ -283,8 +283,8 @@ def test_predefined_clusters_closest(self, predefined_cluster_override):
 
     def test_predefined_clusters_fail(self):
         override = {
-            "model.subset_time": ["2005-01-01", "2005-01-04"],
-            "model.time": {
+            "config.init.subset_time": ["2005-01-01", "2005-01-04"],
+            "config.init.time": {
                 "function": "apply_clustering",
                 "function_options": {
                     "clustering_func": "file=clusters.csv:a",
@@ -295,7 +295,9 @@ def test_predefined_clusters_fail(self):
         # should fail - no CSV data column defined
         override1 = {
             **override,
-            **{"model.time.function_options.clustering_func": "file=clusters.csv"},
+            **{
+                "config.init.time.function_options.clustering_func": "file=clusters.csv"
+            },
         }
         with pytest.raises(exceptions.ModelError) as error:
             build_test_model(override1, scenario="simple_supply")
@@ -305,7 +307,9 @@ def test_predefined_clusters_fail(self):
         # should fail - unknown CSV data column defined
         override2 = {
             **override,
-            **{"model.time.function_options.clustering_func": "file=clusters.csv:1"},
+            **{
+                "config.init.time.function_options.clustering_func": "file=clusters.csv:1"
+            },
         }
 
         with pytest.raises(KeyError) as error:
@@ -316,7 +320,9 @@ def test_predefined_clusters_fail(self):
         # should fail - more than one cluster given to any one day
         override3 = {
             **override,
-            **{"model.time.function_options.clustering_func": "file=clusters.csv:b"},
+            **{
+                "config.init.time.function_options.clustering_func": "file=clusters.csv:b"
+            },
         }
 
         with pytest.raises(exceptions.ModelError) as error:
@@ -330,8 +336,8 @@ def test_predefined_clusters_fail(self):
         override4 = {
             **override,
             **{
-                "model.subset_time": ["2005-01-01", "2005-01-06"],
-                "model.time.function_options.clustering_func": "file=cluster_days.csv:b",
+                "config.init.subset_time": ["2005-01-01", "2005-01-06"],
+                "config.init.time.function_options.clustering_func": "file=cluster_days.csv:b",
             },
         }
 
@@ -348,13 +354,13 @@ class TestMasks:
     @pytest.fixture
     def model_national(self, scope="module"):
         return calliope.examples.national_scale(
-            override_dict={"model.subset_time": ["2005-01-01", "2005-01-31"]}
+            override_dict={"config.init.subset_time": ["2005-01-01", "2005-01-31"]}
         )
 
     @pytest.fixture
     def model_urban(self, scope="module"):
         return calliope.examples.urban_scale(
-            override_dict={"model.subset_time": ["2005-01-01", "2005-01-31"]}
+            override_dict={"config.init.subset_time": ["2005-01-01", "2005-01-31"]}
         )
 
     def test_zero(self, model_national):
@@ -611,7 +617,7 @@ def test_15min_masking_1D(self):
         # it is only different for '2005-01-02'
         override = {
             "techs.test_demand_elec.constraints.sink_equals": "file=demand_elec_15mins.csv",
-            "model.subset_time": None,
+            "config.init.subset_time": None,
         }
 
         model = build_test_model(override, scenario="simple_supply,one_day")
@@ -729,7 +735,7 @@ def test_15min_to_2h_masking_1D(self):
         # it is only different for '2005-01-02'
         override = {
             "techs.test_demand_elec.constraints.sink_equals": "file=demand_elec_15T_to_2h.csv",
-            "model.subset_time": None,
+            "config.init.subset_time": None,
         }
 
         model = build_test_model(override, scenario="simple_supply,one_day")
@@ -774,8 +780,8 @@ def test_15min_masking_1D_resampling_to_2h(self):
         # it is only different for '2005-01-02'
         override = {
             "techs.test_demand_elec.constraints.sink_equals": "file=demand_elec_15mins.csv",
-            "model.subset_time": None,
-            "model.time": {
+            "config.init.subset_time": None,
+            "config.init.time": {
                 "masks": [
                     {
                         "function": "extreme",
@@ -926,8 +932,8 @@ def test_15min_resampling_to_6h(self):
         # it is only different for '2005-01-02'
         override = {
             "techs.test_demand_elec.constraints.sink_equals": "file=demand_elec_15mins.csv",
-            "model.subset_time": None,
-            "model.time": {
+            "config.init.subset_time": None,
+            "config.init.time": {
                 "function": "resample",
                 "function_options": {"resolution": "6H"},
             },
@@ -961,8 +967,8 @@ def test_15min_to_2h_resampling_to_2h(self):
         """
         override = {
             "techs.test_demand_elec.constraints.sink_equals": "file=demand_elec_15T_to_2h.csv",
-            "model.subset_time": None,
-            "model.time": {
+            "config.init.subset_time": None,
+            "config.init.time": {
                 "function": "resample",
                 "function_options": {"resolution": "2H"},
             },
@@ -1019,7 +1025,7 @@ class TestFuncs:
     @pytest.fixture
     def model_national(self, scope="module"):
         return calliope.examples.national_scale(
-            override_dict={"model.subset_time": ["2005-01", "2005-01"]}
+            override_dict={"config.init.subset_time": ["2005-01", "2005-01"]}
         )
 
     def test_drop_invalid_timesteps(self, model_national):
diff --git a/tests/test_example_models.py b/tests/test_example_models.py
index a872a54e2..ccac2980f 100755
--- a/tests/test_example_models.py
+++ b/tests/test_example_models.py
@@ -39,14 +39,14 @@ def test_preprocess_time_masking(self):
 class TestNationalScaleExampleModelSenseChecks:
     def example_tester(self, solver="cbc", solver_io=None):
         model = calliope.examples.national_scale(
-            override_dict={"model.subset_time": ["2005-01-01", "2005-01-01"]}
+            override_dict={"config.init.subset_time": ["2005-01-01", "2005-01-01"]}
         )
-
-        model.run_config["solver"] = solver
-        model.run_config["solver_io"] = solver_io
+        solve_kwargs = {"solver": solver}
+        if solver_io:
+            solve_kwargs["solver_io"] = solver_io
 
         model.build()
-        model.solve()
+        model.solve(**solve_kwargs)
 
         assert model.results.storage_cap.sel(nodes="region1-1", techs="csp") == approx(
             45129.950
@@ -121,11 +121,9 @@ def test_fails_gracefully_without_timeseries(self):
 @pytest.mark.xfail(reason="Not reimplemented the 'check feasibility' objective")
 class TestNationalScaleExampleModelInfeasibility:
     def example_tester(self):
-        model = calliope.examples.national_scale(
-            scenario="check_feasibility", override_dict={"run.cyclic_storage": False}
-        )
+        model = calliope.examples.national_scale(scenario="check_feasibility")
 
-        model.build()
+        model.build(cyclic_storage=False)
         model.solve()
 
         assert model.results.termination_condition in [
@@ -145,7 +143,7 @@ class TestNationalScaleExampleModelOperate:
     def example_tester(self):
         with pytest.warns(calliope.exceptions.ModelWarning) as excinfo:
             model = calliope.examples.national_scale(
-                override_dict={"model.subset_time": ["2005-01-01", "2005-01-03"]},
+                override_dict={"config.init.subset_time": ["2005-01-01", "2005-01-03"]},
                 scenario="operate",
             )
             model.build()
@@ -170,13 +168,12 @@ def test_nationalscale_example_results_cbc(self):
 class TestNationalScaleExampleModelSpores:
     def example_tester(self, solver="cbc", solver_io=None):
         model = calliope.examples.national_scale(
-            override_dict={
-                "model.subset_time": ["2005-01-01", "2005-01-03"],
-                "run.solver": solver,
-                "run.solver_io": solver_io,
-            },
+            override_dict={"config.init.subset_time": ["2005-01-01", "2005-01-03"]},
             scenario="spores",
         )
+        solve_kwargs = {"solver": solver}
+        if solver_io:
+            solve_kwargs["solver_io"] = solver_io
 
         model.build()
 
@@ -189,7 +186,7 @@ def example_tester(self, solver="cbc", solver_io=None):
             == 0
         )
 
-        model.solve()
+        model.solve(**solve_kwargs)
         # Expecting three spores + first optimal run
         assert np.allclose(model.results.spores, [0, 1, 2, 3])
 
@@ -198,7 +195,7 @@ def example_tester(self, solver="cbc", solver_io=None):
 
         # First run is the optimal run, everything else is coming up against the slack cost
         assert costs.loc[{"spores": 0, "costs": "monetary"}] * (
-            1 + model.run_config["spores_options"]["slack"]
+            1 + model.inputs.spores_slack
         ) == approx(slack_cost)
         assert all(
             costs.loc[{"spores": slice(1, None), "costs": "monetary"}]
@@ -239,15 +236,12 @@ def test_nationalscale_example_results_gurobi(self):
     @pytest.fixture
     def base_model_data(self):
         model = calliope.examples.national_scale(
-            override_dict={
-                "model.subset_time": ["2005-01-01", "2005-01-03"],
-                "run.solver": "cbc",
-            },
+            override_dict={"config.init.subset_time": ["2005-01-01", "2005-01-03"]},
             scenario="spores",
         )
 
         model.build()
-        model.solve()
+        model.solve(solver="cbc")
 
         return model._model_data
 
@@ -354,17 +348,14 @@ def test_ignore_forced_flow_cap_spores_no_double_counting(
 
 class TestNationalScaleResampledExampleModelSenseChecks:
     def example_tester(self, solver="cbc", solver_io=None):
-        override = {
-            "model.subset_time": ["2005-01-01", "2005-01-01"],
-            "run.solver": solver,
-        }
-
+        override = {"config.init.subset_time": ["2005-01-01", "2005-01-01"]}
+        solve_kwargs = {"solver": solver}
         if solver_io:
-            override["run.solver_io"] = solver_io
+            solve_kwargs["solver_io"] = solver_io
 
         model = calliope.examples.time_resampling(override_dict=override)
         model.build()
-        model.solve()
+        model.solve(**solve_kwargs)
 
         assert model.results.storage_cap.sel(nodes="region1-1", techs="csp") == approx(
             23563.444
@@ -422,23 +413,25 @@ def model_runner(
         backend_runner="run",
     ):
         override = {
-            "model.time.function_options": {
+            "config.init.time.function_options": {
                 "how": how,
                 "storage_inter_cluster": storage_inter_cluster,
             },
-            "run.solver": solver,
-            "run.cyclic_storage": cyclic,
         }
         if storage is False:
             override.update({"techs.battery.active": False, "techs.csp.active": False})
         if storage_inter_cluster and backend_runner == "solve":
-            override["model.custom_math"] = ["storage_inter_cluster"]
+            override["config.init.custom_math"] = ["storage_inter_cluster"]
+
+        solve_kwargs = {"solver": solver}
+        if solver_io:
+            solve_kwargs["solver_io"] = solver_io
 
         model = calliope.examples.time_clustering(override_dict=override)
         timesteps = model._model_data.timesteps.copy(deep=True)
 
-        model.build()
-        model.solve()
+        model.build(cyclic_storage=cyclic)
+        model.solve(**solve_kwargs)
 
         # make sure the dimension items have not been accidentally reordered
         assert timesteps.equals(model._model_data.timesteps)
@@ -522,17 +515,18 @@ def example_tester(self, source_unit, solver="cbc", solver_io=None):
                 source_unit
             ),
             "techs.pv.switches.source_unit": source_unit,
-            "run.solver": solver,
         }
-        override = {"model.subset_time": ["2005-07-01", "2005-07-01"], **unit_override}
 
-        if solver_io:
-            override["run.solver_io"] = solver_io
+        model = calliope.examples.urban_scale(
+            override_dict=unit_override, subset_time=["2005-07-01", "2005-07-01"]
+        )
 
-        model = calliope.examples.urban_scale(override_dict=override)
+        solve_kwargs = {"solver": solver}
+        if solver_io:
+            solve_kwargs["solver_io"] = solver_io
 
         model.build()
-        model.solve()
+        model.solve(**solve_kwargs)
 
         assert model.results.flow_cap.sel(nodes="X1", techs="chp") == approx(250.090112)
 
@@ -575,8 +569,8 @@ def test_urban_example_results_cap_gurobi(self):
     def test_milp_example_results(self):
         model = calliope.examples.milp(
             override_dict={
-                "model.subset_time": ["2005-01-01", "2005-01-01"],
-                "run.solver_options.mipgap": 0.001,
+                "config.init.subset_time": ["2005-01-01", "2005-01-01"],
+                "config.solve.solver_options": {"mipgap": 0.001},
             }
         )
         model.build()
@@ -602,7 +596,7 @@ def test_milp_example_results(self):
     @pytest.mark.xfail(reason="Not expecting operate mode to work at the moment")
     def test_operate_example_results(self):
         model = calliope.examples.operate(
-            override_dict={"model.subset_time": ["2005-07-01", "2005-07-04"]}
+            override_dict={"config.init.subset_time": ["2005-07-01", "2005-07-04"]}
         )
         with pytest.warns(calliope.exceptions.ModelWarning) as excinfo:
             model.build()
diff --git a/tests/test_io.py b/tests/test_io.py
index 67ad697f9..a1ba68389 100644
--- a/tests/test_io.py
+++ b/tests/test_io.py
@@ -102,8 +102,7 @@ def test_serialised_list_popped(self, request, serialised_list, model_name):
                     "foo_dict",
                     "foo_attrdict",
                     "defaults",
-                    "model_config",
-                    "run_config",
+                    "config",
                     "math",
                 ],
             ),
@@ -166,7 +165,8 @@ def test_save_csv_no_dropna(self, model):
     @pytest.mark.xfail(reason="Not reimplemented the 'check feasibility' objective")
     def test_save_csv_not_optimal(self):
         model = calliope.examples.national_scale(
-            scenario="check_feasibility", override_dict={"run.cyclic_storage": False}
+            scenario="check_feasibility",
+            override_dict={"config.build.cyclic_storage": False},
         )
 
         model.build()
@@ -177,7 +177,7 @@ def test_save_csv_not_optimal(self):
             with pytest.warns(exceptions.ModelWarning):
                 model.to_csv(out_path, dropna=False)
 
-    @pytest.mark.parametrize("attr", ["run_config", "model_config", "math"])
+    @pytest.mark.parametrize("attr", ["config", "math"])
     def test_dicts_as_model_attrs_and_property(self, model_from_file, attr):
         assert attr in model_from_file._model_data.attrs.keys()
         assert hasattr(model_from_file, attr)
@@ -221,17 +221,12 @@ def test_save_lp(self, model):
     def test_save_per_spore(self):
         with tempfile.TemporaryDirectory() as tempdir:
             os.mkdir(os.path.join(tempdir, "output"))
-            model = calliope.examples.national_scale(
-                scenario="spores",
-                override_dict={
-                    "run.spores_options.save_per_spore": True,
-                    "run.spores_options.save_per_spore_path": os.path.join(
-                        tempdir, "output/spore_{}.nc"
-                    ),
-                },
-            )
+            model = calliope.examples.national_scale(scenario="spores")
             model.build()
-            model.solve()
+            model.solve(
+                spores_save_per_spore=True,
+                save_per_spore_path=os.path.join(tempdir, "output/spore_{}.nc"),
+            )
 
             for i in ["0", "1", "2", "3"]:
                 assert os.path.isfile(os.path.join(tempdir, "output", f"spore_{i}.nc"))
diff --git a/tests/test_model_data.py b/tests/test_model_data.py
index d338a20d6..071b8d187 100644
--- a/tests/test_model_data.py
+++ b/tests/test_model_data.py
@@ -5,11 +5,13 @@
 import numpy as np
 import pandas as pd
 import pytest
+import xarray as xr
 from calliope._version import __version__
 from calliope.core.attrdict import AttrDict
 from calliope.preprocess import model_run_from_yaml
 from calliope.preprocess.model_data import ModelDataFactory
 
+from .common.util import build_test_model as build_model
 from .common.util import check_error_or_warning
 
 
@@ -19,10 +21,17 @@ def model_run():
     return model_run_from_yaml(filepath.as_posix(), scenario="simple_supply")[0]
 
 
+@pytest.fixture(scope="function")
+def model_data(model_run):
+    return ModelDataFactory(model_run)
+
+
 class TestModelData:
     @pytest.fixture(scope="class")
-    def model_data(self, model_run):
-        return ModelDataFactory(model_run)
+    def model_data_w_params(self, model_run):
+        model_data = ModelDataFactory(model_run)
+        model_data._extract_node_tech_data()
+        return model_data
 
     def test_model_data_init(self, model_data):
         for attr in [
@@ -340,15 +349,13 @@ def test_all_df_to_true(self, model_data):
         assert new_df.foobar.dtype.kind == "b"
         assert new_df.foobar.sum() == len(new_df)
 
-    def test_extract_node_tech_data(self, model_data, model_run):
+    def test_add_param_from_template(self, model_data, model_run):
         assert not set(model_data.model_data.data_vars.keys()).difference(
             ["node_tech", "link_remote_techs", "link_remote_nodes"]
         )
         model_data_init = model_data.model_data.copy()
-        model_data._extract_node_tech_data()
+        model_data._add_param_from_template()
         model_data_new = model_data.model_data
-        for data_var in ["node_tech", "link_remote_techs", "link_remote_nodes"]:
-            assert model_data_init[data_var].equals(model_data_new[data_var])
         for coord in ["carriers", "carrier_tiers"]:
             assert coord not in model_data_init
             assert coord in model_data.model_data
@@ -359,49 +366,256 @@ def test_extract_node_tech_data(self, model_data, model_run):
             if "constraints" in key or "switches" in key:
                 assert key.split(".")[-1] in model_data_new.data_vars.keys()
 
-    def test_add_time_dimension(self, model_data):
-        model_data._extract_node_tech_data()
-        assert not hasattr(model_data, "data_pre_time")
-        assert not hasattr(model_data, "model_data_pre_clustering")
+    def test_clean_unused_techs_nodes_and_carriers(self, model_data):
+        model_data_init = model_data.model_data.copy()
+        model_data._add_param_from_template()
+        model_data._clean_unused_techs_nodes_and_carriers()
+        model_data_new = model_data.model_data
+        for data_var in ["link_remote_techs", "link_remote_nodes", "node_tech"]:
+            assert model_data_init[data_var].equals(model_data_new[data_var])
 
-        model_data._add_time_dimension()
-        assert hasattr(model_data, "data_pre_time")
-        assert hasattr(model_data, "model_data_pre_clustering")
+    def test_add_time_dimension(self, model_data_w_params):
+        assert not hasattr(model_data_w_params, "data_pre_time")
+        assert not hasattr(model_data_w_params, "model_data_pre_clustering")
 
-        assert "timesteps" not in model_data.model_data.source_max.dims
-        assert "timesteps" in model_data.model_data.sink_equals.dims
-        for var in model_data.model_data.data_vars.values():
+        model_data_w_params._add_time_dimension()
+        assert hasattr(model_data_w_params, "data_pre_time")
+        assert hasattr(model_data_w_params, "model_data_pre_clustering")
+
+        assert "timesteps" not in model_data_w_params.model_data.source_max.dims
+        assert "timesteps" in model_data_w_params.model_data.sink_equals.dims
+        for var in model_data_w_params.model_data.data_vars.values():
             var_ = var.astype(str)
             assert not var_.str.match(r"df=|file=").any()
 
-    def test_clean_model_data(self, model_data):
-        model_data._extract_node_tech_data()
-        model_data._add_time_dimension()
-        for var in model_data.model_data.data_vars.values():
+    def test_clean_model_data(self, model_data_w_params):
+        for var in model_data_w_params.model_data.data_vars.values():
             assert var.attrs == {}
 
-        model_data._clean_model_data()
-        for var in model_data.model_data.data_vars.values():
+        model_data_w_params._clean_model_data()
+        for var in model_data_w_params.model_data.data_vars.values():
             assert var.attrs == {"is_result": 0}
 
     @pytest.mark.parametrize("subdict", ["tech", "node"])
-    def test_check_data(self, model_data, subdict):
-        model_data._extract_node_tech_data()
-        setattr(model_data, f"{subdict}_dict", {"foo": 1})
+    def test_check_data(self, model_data_w_params, subdict):
+        setattr(model_data_w_params, f"{subdict}_dict", {"foo": 1})
         with pytest.raises(exceptions.ModelError) as errmsg:
-            model_data._check_data()
+            model_data_w_params._check_data()
         assert check_error_or_warning(
             errmsg, "Some data not extracted from inputs into model dataset"
         )
 
-    def test_add_attributes(self, model_data):
-        model_data.model_data.attrs = {}
+    def test_add_attributes(self, model_data_w_params):
+        model_data_w_params.model_data.attrs = {}
         model_run = AttrDict({"applied_overrides": "foo", "scenario": "bar"})
-        model_data._add_attributes(model_run)
-        attr_dict = model_data.model_data.attrs
+        model_data_w_params._add_attributes(model_run)
+        attr_dict = model_data_w_params.model_data.attrs
         assert set(attr_dict.keys()) == set(
             ["calliope_version", "applied_overrides", "scenario"]
         )
         attr_dict["calliope_version"] == __version__
         assert attr_dict["applied_overrides"] == "foo"
         assert attr_dict["scenario"] == "bar"
+
+
+class TestTopLevelParams:
+    @pytest.fixture(scope="function")
+    def run_and_test(self, model_data):
+        def _run_and_test(in_dict, out_dict, dims):
+            model_data._extract_node_tech_data()
+            model_data._add_time_dimension()
+            model_data.params = {"my_val": in_dict}
+            model_data._add_top_level_params()
+
+            _data = pd.Series(out_dict).rename_axis(index=dims)
+            pd.testing.assert_series_equal(
+                model_data.model_data.my_val.to_series().dropna().reindex(_data.index),
+                _data,
+                check_dtype=False,
+                check_names=False,
+                check_exact=False,
+            )
+
+        return _run_and_test
+
+    def test_protected_parameter_names(self):
+        with pytest.raises(KeyError) as excinfo:
+            build_model(
+                {"parameters.flow_eff.data": 1},
+                "simple_supply,two_hours",
+            )
+        assert check_error_or_warning(
+            excinfo,
+            "Trying to add top-level parameter with same name as a node/tech level parameter: flow_eff",
+        )
+
+    @pytest.mark.parametrize("val", [1, 1.0, np.inf, "foo"])
+    @pytest.mark.parametrize("dict_nesting", ["", ".data"])
+    def test_top_level_param_single_val(self, val, dict_nesting):
+        model = build_model(
+            {f"parameters.my_val{dict_nesting}": val},
+            "simple_supply,two_hours",
+        )
+        assert model.inputs.my_val == xr.DataArray(val)
+
+    @pytest.mark.parametrize("val", [None, np.nan])
+    @pytest.mark.parametrize("dict_nesting", ["", ".data"])
+    def test_top_level_param_single_val_cleaned_out_in_preprocessing(
+        self, val, dict_nesting
+    ):
+        model = build_model(
+            {f"parameters.my_val{dict_nesting}": val},
+            "simple_supply,two_hours",
+        )
+        assert "my_val" not in model.inputs
+
+    def test_top_level_param_dims_no_index(self):
+        with pytest.raises(ValueError) as excinfo:
+            build_model(
+                {"parameters.my_val": {"data": 1, "dims": "techs"}},
+                "simple_supply,two_hours",
+            )
+        assert check_error_or_warning(
+            excinfo,
+            "(parameters, my_val) | Expected list for `index`, received: None",
+        )
+
+    def test_top_level_param_dims_not_list_index(self):
+        with pytest.raises(ValueError) as excinfo:
+            build_model(
+                {"parameters.my_val": {"data": 1, "dims": "techs", "index": "foo"}},
+                "simple_supply,two_hours",
+            )
+        assert check_error_or_warning(
+            excinfo,
+            "(parameters, my_val) | Expected list for `index`, received: foo",
+        )
+
+    @pytest.mark.parametrize("val", [1, 1.0, np.inf, "foo"])
+    def test_top_level_param_single_data_single_known_dim(self, val, run_and_test):
+        run_and_test(
+            {
+                "data": val,
+                "index": ["test_supply_elec"],
+                "dims": "techs",
+            },
+            {"test_supply_elec": val},
+            "techs",
+        )
+
+    def test_top_level_param_multi_data_single_known_dim(self, run_and_test):
+        run_and_test(
+            {
+                "data": [1, "foo"],
+                "index": ["test_supply_elec", "test_demand_elec"],
+                "dims": "techs",
+            },
+            {"test_supply_elec": 1, "test_demand_elec": "foo"},
+            "techs",
+        )
+
+    def test_top_level_param_single_data_multi_known_dim(self, run_and_test):
+        run_and_test(
+            {
+                "data": 10,
+                "index": [["a", "test_supply_elec"], ["b", "test_demand_elec"]],
+                "dims": ["nodes", "techs"],
+            },
+            {("a", "test_supply_elec"): 10, ("b", "test_demand_elec"): 10},
+            ["nodes", "techs"],
+        )
+
+    def test_top_level_param_multi_data_multi_known_dim(self, run_and_test):
+        run_and_test(
+            {
+                "data": [10, 20],
+                "index": [["a", "test_supply_elec"], ["b", "test_demand_elec"]],
+                "dims": ["nodes", "techs"],
+            },
+            {("a", "test_supply_elec"): 10, ("b", "test_demand_elec"): 20},
+            ["nodes", "techs"],
+        )
+
+    def test_top_level_param_unknown_dim_only(self, caplog, run_and_test):
+        caplog.set_level(logging.DEBUG, logger="calliope.preprocess.model_data")
+        run_and_test(
+            {"data": 10, "index": ["foo"], "dims": "bar"},
+            {"foo": 10},
+            "bar",
+        )
+        assert (
+            "(parameters, my_val) | Adding a new dimension to the model: bar"
+            in caplog.text
+        )
+
+    def test_top_level_param_multi_unknown_dim(self, caplog, run_and_test):
+        caplog.set_level(logging.DEBUG, logger="calliope.preprocess.model_data")
+        run_and_test(
+            {
+                "data": 10,
+                "index": [["foo", "foobar"]],
+                "dims": ["bar", "baz"],
+            },
+            {("foo", "foobar"): 10},
+            ["bar", "baz"],
+        )
+        assert (
+            "(parameters, my_val) | Adding a new dimension to the model: bar"
+            in caplog.text
+        )
+        assert (
+            "(parameters, my_val) | Adding a new dimension to the model: baz"
+            in caplog.text
+        )
+
+    def test_top_level_param_unknown_dim_mixed(self, caplog, run_and_test):
+        caplog.set_level(logging.DEBUG, logger="calliope.preprocess.model_data")
+        run_and_test(
+            {
+                "data": 10,
+                "index": [["test_supply_elec", "foobar"]],
+                "dims": ["techs", "baz"],
+            },
+            {("test_supply_elec", "foobar"): 10},
+            ["techs", "baz"],
+        )
+        assert (
+            "(parameters, my_val) | Adding a new dimension to the model: baz"
+            in caplog.text
+        )
+
+    def test_top_level_param_timeseries(self, caplog, run_and_test):
+        caplog.set_level(logging.DEBUG, logger="calliope.preprocess.model_data")
+        run_and_test(
+            {
+                "data": 10,
+                "index": ["2005-01-01"],
+                "dims": ["timesteps"],
+            },
+            {pd.to_datetime("2005-01-01"): 10},
+            "timesteps",
+        )
+        assert (
+            "(parameters, my_val) | Updating timesteps dimension index values to datetime format"
+            in caplog.text
+        )
+
+    @pytest.mark.filterwarnings(
+        "ignore:(?s).*Operational mode requires the same timestep resolution:calliope.exceptions.ModelWarning"
+    )
+    def test_top_level_param_extend_dim_vals(self, caplog, run_and_test):
+        # We do this test with timesteps as all other dimension elements are filtered out if there is no matching True element in `definition_matrix`
+        caplog.set_level(logging.DEBUG, logger="calliope.preprocess.model_data")
+        run_and_test(
+            {
+                "data": 10,
+                "index": ["2006-01-01"],
+                "dims": ["timesteps"],
+            },
+            {pd.to_datetime("2006-01-01"): 10},
+            "timesteps",
+        )
+        assert (
+            "(parameters, my_val) | Adding a new value to the `timesteps` model coordinate: ['2006-01-01T00:00:00.000000000']"
+            in caplog.text
+        )