Skip to content

Commit

Permalink
Finalize second stage output
Browse files Browse the repository at this point in the history
  • Loading branch information
luca-tomasini committed Dec 4, 2024
1 parent f36f14c commit 93ffdae
Show file tree
Hide file tree
Showing 29 changed files with 1,633 additions and 1,309 deletions.
Binary file modified docs/_build/doctrees/environment.pickle
Binary file not shown.
Binary file modified docs/_build/doctrees/first_model_baseline.doctree
Binary file not shown.
14 changes: 7 additions & 7 deletions docs/_build/html/_sources/first_model_baseline.rst.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ Sets
:file: /tables/sets_docs.csv
:header-rows: 1

.. automodule:: optimization.pyomo_models.sets
.. automodule:: pyomo_models.baseline.first_stage.sets
:no-index:

Variables
----------

.. automodule:: optimization.pyomo_models.variables
.. automodule:: pyomo_models.baseline.first_stage.variables
:no-index:

.. csv-table::
Expand All @@ -24,7 +24,7 @@ Variables
Parameters
----------

.. automodule:: optimization.pyomo_models.parameters
.. automodule:: pyomo_models.baseline.first_stage.parameters
:no-index:

.. csv-table::
Expand All @@ -34,18 +34,18 @@ Parameters
Objective
----------

.. automodule:: optimization.pyomo_models.objective
.. automodule:: pyomo_models.baseline.first_stage.objective
:no-index:

Constraints
------------


.. automodule:: optimization.pyomo_models.constraints.basin_volume
.. automodule:: pyomo_models.baseline.first_stage.constraints.basin_volume
:no-index:

.. automodule:: optimization.pyomo_models.constraints.turbine
.. automodule:: pyomo_models.baseline.first_stage.constraints.turbine
:no-index:

.. automodule:: optimization.pyomo_models.constraints.pump
.. automodule:: pyomo_models.baseline.first_stage.constraints.pump
:no-index:
14 changes: 7 additions & 7 deletions docs/first_model_baseline.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ Sets
:file: /tables/sets_docs.csv
:header-rows: 1

.. automodule:: optimization.pyomo_models.sets
.. automodule:: pyomo_models.baseline.first_stage.sets
:no-index:

Variables
----------

.. automodule:: optimization.pyomo_models.variables
.. automodule:: pyomo_models.baseline.first_stage.variables
:no-index:

.. csv-table::
Expand All @@ -24,7 +24,7 @@ Variables
Parameters
----------

.. automodule:: optimization.pyomo_models.parameters
.. automodule:: pyomo_models.baseline.first_stage.parameters
:no-index:

.. csv-table::
Expand All @@ -34,18 +34,18 @@ Parameters
Objective
----------

.. automodule:: optimization.pyomo_models.objective
.. automodule:: pyomo_models.baseline.first_stage.objective
:no-index:

Constraints
------------


.. automodule:: optimization.pyomo_models.constraints.basin_volume
.. automodule:: pyomo_models.baseline.first_stage.constraints.basin_volume
:no-index:

.. automodule:: optimization.pyomo_models.constraints.turbine
.. automodule:: pyomo_models.baseline.first_stage.constraints.turbine
:no-index:

.. automodule:: optimization.pyomo_models.constraints.pump
.. automodule:: pyomo_models.baseline.first_stage.constraints.pump
:no-index:
3 changes: 2 additions & 1 deletion settings.toml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
INPUT_FILE_NAMES = "data/input_file_names.json"
OUTPUT_FILE_NAMES = "data/output_file_names.json"
OUTPUT_FILE_NAMES = "data/output_file_names.json"
LOG_LEVEL = "INFO"
6 changes: 3 additions & 3 deletions src/data_display/first_stage_optimization_plots.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,19 +95,19 @@ def plot_powered_volume(
go.Bar(
x=results["T"].to_list(), y=(factor*results[col_name]).to_list(), showlegend=True,
marker=dict(color=COLORS[c_nb]), width=1, name= col_name.replace("_", " ") + " " + var_name.replace("_", " "),
legendgroup="volume_powered"
legendgroup="volume_flowed"
), row=row, col=1
)
c_nb += 1
fig.update_traces(selector=dict(legendgroup="volume_powered"), legendgrouptitle_text="Powered water volume")
fig.update_traces(selector=dict(legendgroup="volume_flowed"), legendgrouptitle_text="Powered water flow")
return fig

def plot_result_summarized(
model_instance: pyo.Model, index: dict[str, pl.DataFrame],subset_mapping: dict, time_divider: int) -> Figure:

fig: Figure = make_subplots(
rows=3, cols = 1, shared_xaxes=True, vertical_spacing=0.02, x_title="<b>Weeks<b>",
row_titles= ["DA price [EUR/MWh]", "Basin water volume [%]", "Powered volume [Mm3]"])
row_titles= ["DA price [EUR/MWh]", "Basin water volume [%]", "Avg powered flow [Mm3/s]"])

kwargs: dict = {
"model_instance": model_instance,
Expand Down
24 changes: 0 additions & 24 deletions src/optimization/first_model_baseline.py

This file was deleted.

38 changes: 0 additions & 38 deletions src/optimization/optimizaztion_pipeline.py

This file was deleted.

52 changes: 52 additions & 0 deletions src/pyomo_models/baseline/baseline_input.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from typing import Optional
from datetime import datetime, timedelta, timezone
import polars as pl
from polars import col as c
import pyomo.environ as pyo
import tqdm

from data_federation.input_model import SmallflexInputSchema
from pyomo_models.input_data_preprocessing import (
generate_baseline_index, generate_clean_timeseries, generate_water_flow_factor, generate_basin_volume_table,
clean_hydro_power_performance_table, generate_hydro_power_state
)
from utility.general_function import pl_to_dict, pl_to_dict_with_tuple, generate_log

from pyomo_models.baseline.first_stage.sets import baseline_sets
from pyomo_models.baseline.first_stage.parameters import baseline_parameters
from pyomo_models.baseline.first_stage.variables import baseline_variables
from pyomo_models.baseline.first_stage.objective import baseline_objective
from pyomo_models.baseline.first_stage.constraints.basin_volume import basin_volume_constraints
from pyomo_models.baseline.first_stage.constraints.turbine import turbine_constraints
from pyomo_models.baseline.first_stage.constraints.pump import pump_constraints

class BaseLineInput():
def __init__(
self, input_schema_file_name: str, real_time_step: timedelta, year: int, market_country: str = "CH",
market: str = "DA", hydro_power_mask: Optional[pl.Expr] = None, max_alpha_error: float = 1.3,
solver_name: str = 'gurobi'):

self.real_time_step = real_time_step
self.min_datetime = datetime(year, 1, 1, tzinfo=timezone.utc)
self.max_datetime = datetime(year + 1, 1, 1, tzinfo=timezone.utc)
self.small_flex_input_schema: SmallflexInputSchema = SmallflexInputSchema()\
.duckdb_to_schema(file_path=input_schema_file_name)
self.year = year
self.market_country = market_country
self.market = market
self.hydro_power_mask = hydro_power_mask
self.max_alpha_error = max_alpha_error
self.solver= pyo.SolverFactory(solver_name)

self.discharge_flow_measurement: pl.DataFrame = self.small_flex_input_schema.discharge_flow_measurement\
.filter(c("river") == "Griessee")\
.with_columns(
(c("value") * real_time_step.total_seconds()).alias("discharge_volume"),
pl.lit(0).alias("B")
)

self.market_price_measurement:pl.DataFrame = self.small_flex_input_schema.market_price_measurement\
.filter(c("country") == self.market_country)\
.filter(c("market") == self.market)


File renamed without changes.
File renamed without changes.
137 changes: 137 additions & 0 deletions src/pyomo_models/baseline/first_stage/pipeline.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import re
from typing import Optional
from datetime import datetime, timedelta, timezone
import polars as pl
from polars import col as c
import pyomo.environ as pyo
import tqdm

from data_federation.input_model import SmallflexInputSchema
from pyomo_models.input_data_preprocessing import (
generate_baseline_index, generate_clean_timeseries, generate_water_flow_factor, generate_basin_volume_table,
clean_hydro_power_performance_table, generate_hydro_power_state
)
from utility.general_function import pl_to_dict, pl_to_dict_with_tuple, generate_log
from pyomo_models.baseline.baseline_input import BaseLineInput
from pyomo_models.baseline.first_stage.sets import baseline_sets
from pyomo_models.baseline.first_stage.parameters import baseline_parameters
from pyomo_models.baseline.first_stage.variables import baseline_variables
from pyomo_models.baseline.first_stage.objective import baseline_objective
from pyomo_models.baseline.first_stage.constraints.basin_volume import basin_volume_constraints
from pyomo_models.baseline.first_stage.constraints.turbine import turbine_constraints
from pyomo_models.baseline.first_stage.constraints.pump import pump_constraints

log = generate_log(name=__name__)

class BaselineFirstStage(BaseLineInput):
def __init__(self, input_instance: BaseLineInput, first_time_step: timedelta):
self.subset_mapping = {
"T": "T", "H": "H", "B": "B", "BS": ["B", "S_B"], "HS": ["H", "S_H"], "S_BH": {"H", "H", "S_B", "S_H"}
}
self.first_time_step = first_time_step
self.retrieve_input(input_instance)
self.model_instance: pyo.Model = pyo.ConcreteModel()
self.generate_index()
self.process_timeseries()
self.generate_model()

def retrieve_input(self, input_instance):
for name, value in input_instance.__dict__.items():
setattr(self, name, value)


def generate_index(self):
self.index : dict[str, pl.DataFrame]= generate_baseline_index(
small_flex_input_schema=self.small_flex_input_schema,
year=self.year,
timestep=self.first_time_step,
real_timestep=self.real_time_step,
hydro_power_mask=self.hydro_power_mask
)

self.water_flow_factor: pl.DataFrame = generate_water_flow_factor(index=self.index)
basin_volume_table: dict[int, Optional[pl.DataFrame]] = generate_basin_volume_table(
small_flex_input_schema=self.small_flex_input_schema, index=self.index)

self.power_performance_table: list[dict] = clean_hydro_power_performance_table(
small_flex_input_schema=self.small_flex_input_schema, index=self.index,
basin_volume_table=basin_volume_table)

self.index: dict[str, pl.DataFrame] = generate_hydro_power_state(
power_performance_table=self.power_performance_table, index=self.index, error_percent=1.3
)

def process_timeseries(self):
### Discharge_flow ##############################################################################################
self.discharge_volume: pl.DataFrame = generate_clean_timeseries(
data=self.discharge_flow_measurement,
col_name="discharge_volume",
min_datetime=self.min_datetime,
max_datetime=self.max_datetime,
timestep=self.first_time_step ,
agg_type="sum"
).with_columns(
pl.concat_list(["T", pl.lit(0).alias("B")]).alias("TB")
)
### Market price ###############################################################################################
self.market_price: pl.DataFrame = generate_clean_timeseries(
data=self.market_price_measurement,
col_name="avg",
min_datetime=self.min_datetime,
max_datetime=self.max_datetime,
timestep=self.first_time_step,
agg_type="mean"
)


def generate_model(self):
self.model: pyo.AbstractModel = pyo.AbstractModel()
self.model = baseline_sets(self.model)
self.model = baseline_parameters(self.model)
self.model = baseline_variables(self.model)

self.model = baseline_objective(self.model)
self.model = basin_volume_constraints(self.model)
self.model = turbine_constraints(self.model)
self.model = pump_constraints(self.model)

def create_model_instance(self):
hydropower_state: pl.DataFrame = self.index["state"].drop_nulls("H")
data: dict = {}

data["T"] = {None: self.index["datetime"]["T"].to_list()}
data["H"] = {None: self.index["hydro_power_plant"]["H"].to_list()}
data["B"] = {None: self.index["water_basin"]["B"].to_list()}
data["S_b"] = pl_to_dict(self.index["state"].group_by("B", maintain_order=True).agg("S"))
data["S_h"] = pl_to_dict(self.index["state"].drop_nulls("H").group_by("H", maintain_order=True).agg("S"))
data["S_BH"] = {None: list(map(tuple, self.index["state"].drop_nulls("H")["S_BH"].to_list()))}

data["start_basin_volume"] = pl_to_dict(self.index["water_basin"][["B", "start_volume"]])
data["water_pumped_factor"] = pl_to_dict_with_tuple(self.water_flow_factor["BH", "pumped_factor"])
data["water_turbined_factor"] = pl_to_dict_with_tuple(self.water_flow_factor["BH", "turbined_factor"])
data["min_basin_volume"] = pl_to_dict_with_tuple(
self.index["state"].select("BS", c("volume").struct.field("min")))
data["max_basin_volume"] = pl_to_dict_with_tuple(
self.index["state"].select("BS", c("volume").struct.field("max")))
data["max_flow_turbined"] = pl_to_dict_with_tuple(
hydropower_state.select("HS", c("flow_turbined").struct.field("min")))
data["max_flow_pumped"] = pl_to_dict_with_tuple(
hydropower_state.select("HS", c("flow_pumped").struct.field("min")))
data["alpha_turbined"] = pl_to_dict_with_tuple(
hydropower_state.select("HS", c("alpha_turbined").struct.field("min")))
data["alpha_pumped"] = pl_to_dict_with_tuple(
hydropower_state.select("HS", c("alpha_pumped").struct.field("min")))
data["discharge_volume"] = pl_to_dict_with_tuple(self.discharge_volume[["TB", "discharge_volume"]])
data["market_price"] = pl_to_dict(self.market_price[["T", "avg"]])
data["max_market_price"] = pl_to_dict(self.market_price[["T", "max_avg"]])
data["min_market_price"] = pl_to_dict(self.market_price[["T", "min_avg"]])
data["nb_hours"] = pl_to_dict(self.index["datetime"][["T", "n_index"]])

self.model_instance: pyo.Model = self.model.create_instance({None: data})

def solve_model(self):
with tqdm.tqdm(total=1, desc="Solving first stage optimization problem") as pbar:

_ = self.solver.solve(self.model_instance)
pbar.update()

File renamed without changes.
File renamed without changes.
Loading

0 comments on commit 93ffdae

Please sign in to comment.