Work-in-progress tools for multi-objective optimization of Drogon-style energy system cases (wind + gas and wind + hydrogen scenarios).
From the project root:
python -m pip install -e .Optional extras:
python -m pip install -e .[analysis]
python -m pip install -e .[dev]Note: runtime dependencies used by optimization backends (for example PET-related packages such as popt/subsurface) are expected to be available in your environment.
Both examples run a Pareto sweep over the weights in objective_weights: for each weight w the optimizer minimizes w * f1 + (1 - w) * (-NPV), where f1 is total CO2 emissions or CAPEX. Results for each weight go to <save_folder>/weight_<w>/, and plots are written after the sweep.
Run the examples from the examples directory (the scripts use relative paths):
cd examples
python run-wind_gas.py
python run-wind_hydrogen.pyUser-editable variables at the top of each script:
energy_sources: energy sources in the case (checked against the script's case)random_seed: random seed for reproducibilityobjective_weights: weights to run for the Pareto sweepsave_folder: where results are writtenparallel: number of simulations to run in parallelrun_optimization: set toFalseto skip optimization and only plot existing resultsshow_plots: show figures on screen after plotting (figures are saved either way)
Offshore power comes from wind turbines, with gas turbines covering any shortfall. The controls are the time-varying rates of the seven Drogon wells (RATE_A1–RATE_A6, RATE_OP5). The two objectives are NPV and total CO2 emissions from the gas turbines. Emissions are costed in the NPV, and fuel gas is subtracted from exported gas. Config: data/config/wind_gas.py. Default output: outputs/wind_gas/.
Wind power, with hydrogen storage (electrolysis and fuel cell) covering shortfalls instead of gas turbines. On top of the well rates, it optimizes the number of wind turbines (N_WT) and the hydrogen storage capacity (N_H2). The two objectives are NPV and CAPEX, and a penalty (EPF) handles hydrogen shortfalls. Config: data/config/wind_hydrogen.py. Default output: outputs/wind_hydrogen/.
Plotting code lives in examples/plot_results.py. For each weight, figures are written to weight_<w>/figures/:
obj_func.png(orobj_func_epf.pngwith penalty loops): objective historyvariable_<i>.png: initial vs. final well-rate controlsfree_variable_<i>.png(hydrogen only): initial vs. finalN_WT/N_H2pareto_point.png:- Gas: histograms of NPV and total CO2 across the ensemble
- Hydrogen: NPV histogram and CAPEX breakdown
In save_folder itself:
pareto_curve.png: mean NPV against CO2 (gas) or CAPEX (hydrogen), one point per weightwind_power_profiles.png: sample wind power profiles
The closed_loop package holds the closed-loop short-term optimization (ECMOR 2026). It needs OPM Flow and the closed-loop extra:
python -m pip install -e .[closed-loop]
cd examples
python run-target_optimization.py # optional: recompute the target rates (needs PET)
python run-closed_loop.pyclosed_loop.target_optimization: life-cycle (NPV) optimization of the target rates with PET (run.py), andtarget_controls.py, which simulates the optimum and writes its monthly rates.examples/run-target_optimization.pyruns both inoutputs/target_optimization/. Copy the resultingtarget_controls.csvtodata/closed_loop/to use it in the loop.closed_loop.workflow: the closed loop with the RBF proxy, run byexamples/run-closed_loop.py. Seesrc/closed_loop/workflow/README.md.
Inputs:
data/config/target_optimization.yaml,data/config/closed_loop.yaml: settings.data/closed_loop/: the two deck templates, the initial and target rates, and the wind power.data/drogon_ensemble/Drogon_Mean/: the mean Drogon model, with the restart files of its history run that start the loop. The decks read it andinclude/fromdata/drogon_ensemble/.
python -m pip install -e .[dev,analysis]
python -m pytestThe tests cover src/facility, src/multi_objective_optimization and examples/. They use small synthetic data and stand-ins for PET and OPM Flow, so no reservoir simulations are run.