Optimization
============
carbatpy supports optimization workflows for steady-state cycle models (Heat pump, ORC,
Carnot battery) based on the current ``comp`` infrastructure.
Two optimization approaches are supported: a **single-objective** and a **multi-objective** optimization.
Single-objective optimization can be performed using :mod:`scipy.optimize` as well as a differential evolution algorithm provided by the ``pymoo`` framework.
Multi-objective optimization is currently available only for the Carnot Battery as a whole, using the NSGA-II algorithm from the ``pymoo`` framework.
Typical optimization variables
------------------------------
Examples of objective variables are:
* costs: by default the capital expenditures (CAPEX)
* performance: by default the Round-trip efficiency (RTE)
Examples of optimization variables are:
* working fluid mixture composition (molar fractions)
* pressure levels (e.g. ``p_high``, ``p_low``)
* component parameters (e.g. superheat/minimum approach temperatures)
* storage boundary conditions (e.g. cold tank temperature level)
Optimization using scipy
------------------------
Fixed parameters vs. optimization variables
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In the current workflow, most cycle parameters are read from a YAML configuration file.
The optimization scripts then provide a *partial configuration* (``conf_m``) and
corresponding bounds (``bounds_m``) for the variables that shall be optimized.
Examples (SciPy single-objective)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Heat pump optimization (``opti_hp_comp.py``)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Download:
:download:`opti_hp_comp.py <../src/carbatpy/examples/optimizations/opti_hp_comp.py>`
YAML configuration used by this example:
:download:`io-hp-data.yaml <../src/carbatpy/data/io-hp-data.yaml>`
This example performs a baseline run of the heat pump model, and then optimizes selected
variables (e.g. mixture fractions, pressure levels, cold storage temperature) using
``scipy.optimize`` via helper functions in ``cb.opti_cycle_comp_helpers``.
.. literalinclude:: ../src/carbatpy/examples/optimizations/opti_hp_comp.py
:language: python
ORC optimization (``opti_orc_comp.py``)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Download:
:download:`opti_orc_comp.py <../src/carbatpy/examples/optimizations/opti_orc_comp.py>`
YAML configuration used by this example:
:download:`io-orc-data.yaml <../src/carbatpy/data/io-orc-data.yaml>`
.. literalinclude:: ../src/carbatpy/examples/optimizations/opti_orc_comp.py
:language: python
Carnot battery optimization (``opti_cb_comp.py``)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Download:
:download:`opti_cb_comp.py <../src/carbatpy/examples/optimizations/opti_cb_comp.py>`
YAML configurations used by this example (charge/discharge models):
:download:`io-hp-data.yaml <../src/carbatpy/data/io-hp-data.yaml>`
:download:`io-orc-data.yaml <../src/carbatpy/data/io-orc-data.yaml>`
.. literalinclude:: ../src/carbatpy/examples/optimizations/opti_cb_comp.py
:language: python
Outputs / Results
~~~~~~~~~~~~~~~~~
The optimization examples typically write:
* an output folder under the configured results directory (timestamped)
* a YAML file with the best point (``x``), objective value (``fun``), and a mapping to
named variables
* optional CSV data (e.g. population + energies for differential evolution)
* optional figures from the best design point
Optimization using pymoo
------------------------
The pymoo-based optimization provides a unified interface for both single-objective and multi-objective optimization of implemented thermodynamic cycles (Heat pump, ORC, Carnot battery).
It is build on the `pymoo framework `_ and includes cycle-specific problem definitions as well as customizable parallelization parameters.
Architecture
~~~~~~~~~~~~
The optimization is structured into two layers:
1. Core helpers (``helpers_optimization.py``)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Located in ``src/carbatpy/optimizations/helpers_optimizations.py``, this module contains all building blocks shared across optimization algorithms.
``opti_func`` Wraps the simulation of a Heat pump, ORC, or Carnot battery.
It takes a vector of decision variables, maps them to the corresponding cycle parameters,
runs the steady-state model, and returns the objective value(s) together with any constraint violations.
``OptiProblem`` is a pymoo-compatible problem class.
It is responsible for the evaluation logic by calling opti_func, constraint handling and deciding the number of objective values.
The class supports both single-objective (n_obj=1) and multi-objective (n_obj=2) formulations.
``CombinedTermination`` is a termination class that combines multiple stopping criteria.
Supported criteria include the maximum number of generation and the objective variable convergence.
2. Algorithm scripts
^^^^^^^^^^^^^^^^^^^^
The individual scripts for the algorithms (``opti_de`` and ``opti_NSGA2``) then use ``OptiProblem`` and ``CombinedTermination`` for the calculation in ``optimize``.
This function can be called by the user to perform any optimization.
The ``optimize`` function accepts a range of parameters that can be grouped into three categories:
carbatpy specific:
""""""""""""""""""
.. list-table::
:header-rows: 1
:widths: 25 50 25
* - Parameter
- Description
- Relevant mode
* - ``mode``
- Optimization mode: ``'hp'``, ``'orc'``, or ``'cb'``
- all
* - ``config``
- Configuration dictionary or path to a YAML configuration file
- all
* - ``boundaries``
- Lower and upper bounds for all decision variables
- all
* - ``same_fluid``
- Whether the same working fluid is used across HP and ORC
- ``'cb'``
* - ``heat_losses``
- Heat loss fraction of the system
- ``'cb'``
* - ``COP``
- Coefficient of performance
- ``'orc'``
* - ``q_dot``
- Heat input/output rate
- ``'orc'``
parallelization specific:
"""""""""""""""""""""""""
.. list-table::
:header-rows: 1
:widths: 25 55 20
* - Parameter
- Description
- Default
* - ``n_processes``
- Number of worker processes. Auto-detected via ``default_n_processes()`` if ``None``
- ``None``
* - ``maxtasksperchild``
- Maximum number of tasks a single worker process executes before being replaced
- ``20``
pymoo specific:
"""""""""""""""
.. list-table::
:header-rows: 1
:widths: 25 55 20
* - Parameter
- Description
- Default
* - ``pop_size``
- Population size
- ``50``
* - ``sampling_iterations``
- Number of iterations for Latin Hypercube Sampling (LHS) initialization
- ``50``
* - ``n_gen``
- Maximum number of generations
- ``100``
* - ``period``
- Number of generations over which convergence is checked
- ``20``
* - ``ftol``
- Function value tolerance for the convergence termination criterion
- ``1e-4``
* - ``verbose``
- Print optimization progress to stdout
- ``True``
* - ``n_ieq_constr``
- Number of inequality constraints passed to ``OptiProblem``
- ``3``
* - ``return_least_infeasible``
- Return the least infeasible solution if no feasible solution is found
- ``False``
pymoo specific (DE):
""""""""""""""""""""
.. list-table::
:header-rows: 1
:widths: 25 55 20
* - Parameter
- Description
- Default
* - ``de_variant``
- DE mutation/crossover strategy, e.g. ``'DE/rand/1/bin'``
- ``'DE/rand/1/bin'``
* - ``CR``
- Crossover probability
- ``0.3``
* - ``dither``
- Dithering strategy for the scaling factor F: ``'vector'``, ``'scalar'``, or ``None``
- ``'vector'``
* - ``jitter``
- Apply jitter to the scaling factor F
- ``False``
pymoo specific (NSGA-II):
"""""""""""""""""""""""""
.. list-table::
:header-rows: 1
:widths: 25 55 20
* - Parameter
- Description
- Default
* - ``n_offspring``
- Number of offspring per generation. Uses pymoo default if ``None``
- ``None``
* - ``crowding_func``
- Crowding distance function for survival selection, e.g. ``'pcd'``
- ``'pcd'``
* - ``eliminate_duplicates``
- Remove duplicate individuals from the population
- ``True``
* - ``save_history``
- Save the per-generation optimization history to the result object
- ``False``
Further information on the functions and classes are provided in the API Reference and the following examples.
Single-objective
~~~~~~~~~~~~~~~~
The single-objective optimization uses the differential evolution algorithm from ``pymoo``.
For further information, see the `Pymoo DE documentation `_.
Problem formulation
^^^^^^^^^^^^^^^^^^^
Objective
"""""""""
By default, the RTE, COP and the thermal efficiency are maximized (internally passed as a negative value since pymoo minimizes by default).
Constraints
"""""""""""
The following constraints are enforced by default:
* Carnot Battery: pressure in the heat pump ≥ 1 bar; RTE ≥ 0.05
* Heat Pump: pressure ≥ 1 bar; COP ≥ 0.05
* ORC: pressure ≥ 1 bar; Thermal efficiency ≥ 0.05
Decision variables
""""""""""""""""""
Decision variables are defined by the user through lower and upper bounds in the form of a dictionary corresponding to the parameter definition in the config.
Example for a Carnot battery
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. toctree::
:maxdepth: 1
examples/opti_cb_DE
Multi-objective
~~~~~~~~~~~~~~~
The multi-objective optimization uses the NSGA-II (Non-dominated Sorting Genetic Algorithm II) from pymoo.
For further information, see the `Pymoo NSGA2 documentation `_.
Multi-objective optimization is currently available for the Carnot battery model only.
Problem formulation
^^^^^^^^^^^^^^^^^^^
Objectives
""""""""""
By default, the following two objective variables are optimized:
* RTE
* CAPEX
The result is a Pareto-front — a set of non-dominated solutions representing the trade-off between the two objectives.
Constraints
"""""""""""
The same default constraints as in the single-objective case apply (minimum pressures, minimum RTE).
Decision variables
""""""""""""""""""
Decision variables are defined by the user through lower and upper bounds in the form of a dictionary corresponding to the parameter definition in the config
and including the thermodynamic cycles ``hp`` and ``orc`` as the first keys.
Example for a Carnot battery
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.. toctree::
:maxdepth: 1
examples/opti_cb_nsga2
Outputs / Results
~~~~~~~~~~~~~~~~
The optimization function returns the pymoo results object.
For further information on attributes see the `Pymoo Results documentation `_.