diff --git a/src/andromede/hydro_heuristic/data.py b/src/andromede/hydro_heuristic/data.py index 95bf12aa..d5153501 100644 --- a/src/andromede/hydro_heuristic/data.py +++ b/src/andromede/hydro_heuristic/data.py @@ -10,111 +10,133 @@ # # This file is part of the Antares project. +from dataclasses import dataclass from pathlib import Path from typing import List, Optional import numpy as np +@dataclass +class ReservoirParameters: + capacity: float + initial_level: float + folder_name: str + scenario: int + + +@dataclass +class HydroHeuristicParameters: + inter_breakdown: int = 1 + total_target: Optional[float] = None + + +@dataclass +class DataAggregatorParameters: + hours_aggregated_time_steps: List[int] + timesteps: List[int] + + def get_number_of_days_in_month(month: int) -> int: number_day_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month] return number_day_month class RawHydroData: + def __init__(self, folder_name: str, scenario: int) -> None: + self.folder_name = folder_name + self.scenario = scenario - def __init__(self, name: str, folder_name: str, scenario: int) -> None: - - name_file = { + self.name_file = { "demand": "load", "inflow": "mod", "lower_rule_curve": "reservoir", "upper_rule_curve": "reservoir", "max_generating": "maxpower", - }[name] + } - column = { - "demand": scenario, - "inflow": scenario, + self.column = { + "demand": self.scenario, + "inflow": self.scenario, "lower_rule_curve": 0, "upper_rule_curve": 2, "max_generating": 0, - }[name] + } + def read_data(self, name: str) -> list[float]: hours_input = 1 if name == "demand" else 24 data = np.loadtxt( Path(__file__).parent / ( "../../../tests/functional/data/" - + folder_name + + self.folder_name + "/" - + name_file + + self.name_file[name] + ".txt" ) ) - data = data[:, column] + data = data[:, self.column[name]] data = np.repeat(data, hours_input) - if name_file == "mod": + if self.name_file[name] == "mod": data = data / hours_input - self.time_series = data + return list(data) class HydroHeuristicData: def __init__( self, - scenario: int, - hours_aggregated_time_steps: List[int], - folder_name: str, - timesteps: List[int], - capacity: float, - initial_level: float, + data_aggregator_parameters: DataAggregatorParameters, + reservoir_data: ReservoirParameters, ): - self.folder_name = folder_name + self.reservoir_data = reservoir_data - self.capacity = capacity - self.initial_level = initial_level + data_aggregator = DataAggregator( + data_aggregator_parameters.hours_aggregated_time_steps, + data_aggregator_parameters.timesteps, + ) - data_aggregator = DataAggregator(hours_aggregated_time_steps, timesteps) + raw_data_reader = RawHydroData( + reservoir_data.folder_name, reservoir_data.scenario + ) self.demand = data_aggregator.aggregate_data( operator="sum", - raw_data=RawHydroData("demand", folder_name, scenario), + data=raw_data_reader.read_data("demand"), ) self.inflow = data_aggregator.aggregate_data( operator="sum", - raw_data=RawHydroData("inflow", folder_name, scenario), + data=raw_data_reader.read_data("inflow"), ) self.lower_rule_curve = data_aggregator.aggregate_data( operator="lag_first_element", - raw_data=RawHydroData("lower_rule_curve", folder_name, scenario), + data=raw_data_reader.read_data("lower_rule_curve"), ) self.upper_rule_curve = data_aggregator.aggregate_data( operator="lag_first_element", - raw_data=RawHydroData("upper_rule_curve", folder_name, scenario), + data=raw_data_reader.read_data("upper_rule_curve"), ) self.max_generating = data_aggregator.aggregate_data( operator="sum", - raw_data=RawHydroData("max_generating", folder_name, scenario), + data=raw_data_reader.read_data("max_generating"), ) - def compute_target( # TODO : rajouter un test avec vraiment très peu de données - self, total_target: Optional[float], inter_breakdown: int = 1 - ) -> None: - if total_target is None: + def compute_target(self, heuristic_parameters: HydroHeuristicParameters) -> None: + if heuristic_parameters.total_target is None: total_target = sum(self.inflow) + else: + total_target = heuristic_parameters.total_target target = ( total_target - * np.power(self.demand, inter_breakdown) - / sum(np.power(self.demand, inter_breakdown)) + * np.power(self.demand, heuristic_parameters.inter_breakdown) + / sum(np.power(self.demand, heuristic_parameters.inter_breakdown)) ) self.target = list(target) class DataAggregator: - def __init__( self, hours_aggregated_time_steps: List[int], @@ -123,8 +145,7 @@ def __init__( self.hours_aggregated_time_steps = hours_aggregated_time_steps self.timesteps = timesteps - def aggregate_data(self, operator: str, raw_data: RawHydroData) -> List[float]: - data = raw_data.time_series + def aggregate_data(self, operator: str, data: list[float]) -> List[float]: aggregated_data: List[float] = [] hour = 0 for time_step, hours_time_step in enumerate(self.hours_aggregated_time_steps): diff --git a/src/andromede/hydro_heuristic/heuristic_model.py b/src/andromede/hydro_heuristic/heuristic_model.py index 88238d52..b3effadb 100644 --- a/src/andromede/hydro_heuristic/heuristic_model.py +++ b/src/andromede/hydro_heuristic/heuristic_model.py @@ -27,7 +27,6 @@ class HeuristicHydroModelBuilder: - def __init__( self, hydro_model: Model, diff --git a/src/andromede/hydro_heuristic/problem.py b/src/andromede/hydro_heuristic/problem.py index 3149bc70..d4889e96 100644 --- a/src/andromede/hydro_heuristic/problem.py +++ b/src/andromede/hydro_heuristic/problem.py @@ -10,12 +10,19 @@ # # This file is part of the Antares project. -from typing import Optional, List +from dataclasses import dataclass +from typing import List, Optional import ortools.linear_solver.pywraplp as pywraplp import pandas as pd -from andromede.hydro_heuristic.data import HydroHeuristicData +from andromede.hydro_heuristic.data import ( + DataAggregatorParameters, + HydroHeuristicData, + HydroHeuristicParameters, + ReservoirParameters, +) +from andromede.model import Model from andromede.simulation import ( BlockBorderManagement, OutputValues, @@ -31,7 +38,18 @@ TimeSeriesData, create_component, ) -from andromede.model import Model + + +@dataclass +class SolvingOutput: + status: str + objective: float + + +@dataclass +class OutputHeuristic: + generating: list[float] + level: float class HydroHeuristicProblem: @@ -40,9 +58,6 @@ def __init__(self, hydro_data: HydroHeuristicData, heuristic_model: Model) -> No self.id = "H" database = self.generate_database() - time_block = TimeBlock(1, [i for i in range(len(hydro_data.target))]) - scenarios = 1 - hydro = create_component( model=heuristic_model, id=self.id, @@ -54,14 +69,14 @@ def __init__(self, hydro_data: HydroHeuristicData, heuristic_model: Model) -> No problem = build_problem( network, database, - time_block, - scenarios, + TimeBlock(1, [i for i in range(len(hydro_data.target))]), + 1, border_management=(BlockBorderManagement.CYCLE), ) self.problem = problem - def solve_hydro_problem(self) -> tuple[int, float, list[float], float]: + def solve_hydro_problem(self) -> tuple[SolvingOutput, OutputHeuristic]: parameters = pywraplp.MPSolverParameters() parameters.SetIntegerParam(parameters.PRESOLVE, parameters.PRESOLVE_OFF) parameters.SetIntegerParam(parameters.SCALING, 0) @@ -71,10 +86,11 @@ def solve_hydro_problem(self) -> tuple[int, float, list[float], float]: output = OutputValues(self.problem) return ( - status, - self.problem.solver.Objective().Value(), - output.component(self.id).var("generating").value[0], # type:ignore - output.component(self.id).var("level").value[0][-1], # type:ignore + SolvingOutput(status, self.problem.solver.Objective().Value()), + OutputHeuristic( + output.component(self.id).var("generating").value[0], # type:ignore + output.component(self.id).var("level").value[0][-1], # type:ignore + ), ) def generate_database( @@ -82,9 +98,13 @@ def generate_database( ) -> DataBase: database = DataBase() - database.add_data(self.id, "capacity", ConstantData(self.hydro_data.capacity)) database.add_data( - self.id, "initial_level", ConstantData(self.hydro_data.initial_level) + self.id, "capacity", ConstantData(self.hydro_data.reservoir_data.capacity) + ) + database.add_data( + self.id, + "initial_level", + ConstantData(self.hydro_data.reservoir_data.initial_level), ) inflow_data = pd.DataFrame( @@ -112,7 +132,7 @@ def generate_database( TimeSeriesData( { TimeIndex(i): self.hydro_data.lower_rule_curve[i] - * self.hydro_data.capacity + * self.hydro_data.reservoir_data.capacity for i in range(len(self.hydro_data.lower_rule_curve)) } ), @@ -123,7 +143,7 @@ def generate_database( TimeSeriesData( { TimeIndex(i): self.hydro_data.upper_rule_curve[i] - * self.hydro_data.capacity + * self.hydro_data.reservoir_data.capacity for i in range(len(self.hydro_data.lower_rule_curve)) } ), @@ -146,7 +166,9 @@ def generate_database( "max_epsilon", TimeSeriesData( { - TimeIndex(i): self.hydro_data.capacity if i == 0 else 0 + TimeIndex(i): ( + self.hydro_data.reservoir_data.capacity if i == 0 else 0 + ) for i in range(len(self.hydro_data.max_generating)) } ), @@ -156,33 +178,24 @@ def generate_database( def optimize_target( - inter_breakdown: int, - folder_name: str, - capacity: float, - scenario: int, - initial_level: float, - hours_aggregated_time_steps: List[int], - timesteps: list[int], - total_target: Optional[float], + heuristic_parameters: HydroHeuristicParameters, + data_aggregator_parameters: DataAggregatorParameters, + reservoir_data: ReservoirParameters, heuristic_model: Model, -) -> tuple[float, int, float, list[float]]: +) -> tuple[SolvingOutput, OutputHeuristic]: # Récupération des données data = HydroHeuristicData( - scenario, - hours_aggregated_time_steps=hours_aggregated_time_steps, - folder_name=folder_name, - timesteps=timesteps, - capacity=capacity, - initial_level=initial_level, + data_aggregator_parameters, + reservoir_data, ) # Calcul de la préallocation - data.compute_target(total_target, inter_breakdown=inter_breakdown) + data.compute_target(heuristic_parameters) # Ajustement de la réapartition heuristic_problem = HydroHeuristicProblem( hydro_data=data, heuristic_model=heuristic_model ) - status, obj, generation, initial_level = heuristic_problem.solve_hydro_problem() + solving_output, heuristic_output = heuristic_problem.solve_hydro_problem() - return initial_level, status, obj, generation + return solving_output, heuristic_output diff --git a/tests/functional/test_hydro_large_load_at_the_end.py b/tests/functional/test_hydro_large_load_at_the_end.py index 048057d7..d994b867 100644 --- a/tests/functional/test_hydro_large_load_at_the_end.py +++ b/tests/functional/test_hydro_large_load_at_the_end.py @@ -22,7 +22,13 @@ get_number_of_days_in_month, update_generation_target, ) -from andromede.hydro_heuristic.problem import optimize_target +from andromede.hydro_heuristic.heuristic_model import HeuristicHydroModelBuilder +from andromede.hydro_heuristic.problem import ( + DataAggregatorParameters, + HydroHeuristicParameters, + ReservoirParameters, + optimize_target, +) from andromede.libs.standard import ( DEMAND_MODEL, GENERATOR_MODEL, @@ -41,11 +47,10 @@ create_component, ) from tests.functional.libs.lib_hydro_heuristic import ( + HYDRO_MODEL, HYDRO_MODEL_RULE_CURVES, HYDRO_MODEL_WITH_TARGET, - HYDRO_MODEL, ) -from andromede.hydro_heuristic.heuristic_model import HeuristicHydroModelBuilder optimal_generation = np.array( [ @@ -206,74 +211,63 @@ def test_complete_year_as_one_block() -> None: def test_hydro_heuristic() -> None: """ """ - scenarios = 1 - intermonthly_breakdown = 5 - interdaily_breakdown = 5 - folder_name = "hydro_with_large_load" - - capacity = 1e7 - - for scenario in range(scenarios): - initial_level = 0.445 * capacity - - initial_level, status, _, monthly_generation = optimize_target( - intermonthly_breakdown, - folder_name, - capacity, - scenario, - initial_level, - hours_aggregated_time_steps=[ - 24 * get_number_of_days_in_month(m) for m in range(12) - ], - timesteps=list(range(12)), - total_target=None, + + reservoir_data = ReservoirParameters( + capacity=1e7, + initial_level=0.445 * 1e7, + folder_name="hydro_with_large_load", + scenario=1, + ) + + solving_output, monthly_output = optimize_target( + heuristic_parameters=HydroHeuristicParameters(5), + data_aggregator_parameters=DataAggregatorParameters( + [24 * get_number_of_days_in_month(m) for m in range(12)], + list(range(12)), + ), + reservoir_data=reservoir_data, + heuristic_model=HeuristicHydroModelBuilder(HYDRO_MODEL, "monthly").get_model(), + ) + + assert solving_output.status == pywraplp.Solver.OPTIMAL + assert monthly_output.generating == pytest.approx(expected_monthly_generation) + + all_daily_generation: List[float] = [] + day_in_year = 0 + + for month in range(12): + number_day_month = get_number_of_days_in_month(month) + + solving_output, daily_output = optimize_target( + heuristic_parameters=HydroHeuristicParameters( + 5, monthly_output.generating[month] + ), + data_aggregator_parameters=DataAggregatorParameters( + [24] * 365, + list(range(day_in_year, day_in_year + number_day_month)), + ), + reservoir_data=reservoir_data, heuristic_model=HeuristicHydroModelBuilder( - HYDRO_MODEL, "monthly" + HYDRO_MODEL, "daily" ).get_model(), ) - assert status == pywraplp.Solver.OPTIMAL - assert monthly_generation == pytest.approx(expected_monthly_generation) - - all_daily_generation: List[float] = [] - day_in_year = 0 - - for month in range(12): - number_day_month = get_number_of_days_in_month(month) - - ( - initial_level, - status, - obj, - daily_generation, - ) = optimize_target( - interdaily_breakdown, - folder_name, - capacity, - scenario, - initial_level, - hours_aggregated_time_steps=[24 for d in range(365)], - timesteps=list(range(day_in_year, day_in_year + number_day_month)), - total_target=monthly_generation[month], - heuristic_model=HeuristicHydroModelBuilder( - HYDRO_MODEL, "daily" - ).get_model(), - ) - - assert status == pywraplp.Solver.OPTIMAL - - all_daily_generation = update_generation_target( - all_daily_generation, daily_generation - ) - day_in_year += number_day_month - - # Calcul des cibles hebdomadaires - weekly_target = calculate_weekly_target( - all_daily_generation, + reservoir_data.initial_level = daily_output.level + + assert solving_output.status == pywraplp.Solver.OPTIMAL + + all_daily_generation = update_generation_target( + all_daily_generation, daily_output.generating ) + day_in_year += number_day_month + + # Calcul des cibles hebdomadaires + weekly_target = calculate_weekly_target( + all_daily_generation, + ) - # Vérification des valeurs trouvées - assert weekly_target == pytest.approx(expected_weekly_target) + # Vérification des valeurs trouvées + assert weekly_target == pytest.approx(expected_weekly_target) def test_complete_year_as_weekly_blocks_with_hydro_heuristic() -> None: diff --git a/tests/functional/test_hydro_with_rulecurves.py b/tests/functional/test_hydro_with_rulecurves.py index 76c2426d..ebd286b9 100644 --- a/tests/functional/test_hydro_with_rulecurves.py +++ b/tests/functional/test_hydro_with_rulecurves.py @@ -22,7 +22,13 @@ get_number_of_days_in_month, update_generation_target, ) -from andromede.hydro_heuristic.problem import optimize_target +from andromede.hydro_heuristic.heuristic_model import HeuristicHydroModelBuilder +from andromede.hydro_heuristic.problem import ( + DataAggregatorParameters, + HydroHeuristicParameters, + ReservoirParameters, + optimize_target, +) from andromede.libs.standard import ( DEMAND_MODEL, GENERATOR_MODEL, @@ -41,10 +47,9 @@ create_component, ) from tests.functional.libs.lib_hydro_heuristic import ( - HYDRO_MODEL_WITH_TARGET, HYDRO_MODEL, + HYDRO_MODEL_WITH_TARGET, ) -from andromede.hydro_heuristic.heuristic_model import HeuristicHydroModelBuilder expected_weekly_target = [ 109351.86292514109, @@ -105,36 +110,36 @@ def test_hydro_heuristic_monthly_part() -> None: """ """ capacity = 1e07 - intermonthly_breakdown = 1 - folder_name = "hydro_with_rulecurves" - initial_level = 0.445 * capacity - initial_level, status, obj, _ = optimize_target( - inter_breakdown=intermonthly_breakdown, - folder_name=folder_name, - capacity=capacity, - scenario=0, - initial_level=initial_level, - hours_aggregated_time_steps=[ - 24 * get_number_of_days_in_month(m) for m in range(12) - ], - timesteps=list(range(12)), - total_target=None, + solving_output, monthly_output = optimize_target( + heuristic_parameters=HydroHeuristicParameters(1), + data_aggregator_parameters=DataAggregatorParameters( + [24 * get_number_of_days_in_month(m) for m in range(12)], + list(range(12)), + ), + reservoir_data=ReservoirParameters( + capacity, + initial_level=0.445 * capacity, + folder_name="hydro_with_rulecurves", + scenario=0, + ), heuristic_model=HeuristicHydroModelBuilder(HYDRO_MODEL, "monthly").get_model(), ) - assert status == pywraplp.Solver.OPTIMAL - - assert obj / capacity == pytest.approx(10.1423117689793) + assert solving_output.status == pywraplp.Solver.OPTIMAL + assert solving_output.objective / capacity == pytest.approx(10.1423117689793) def test_hydro_heuristic_daily_part() -> None: """ """ - scenario = 0 capacity = 1e07 - interdaily_breakdown = 1 - folder_name = "hydro_with_rulecurves" - initial_level = 0.445 * capacity + + reservoir_data = ReservoirParameters( + capacity, + initial_level=0.445 * capacity, + folder_name="hydro_with_rulecurves", + scenario=0, + ) monthly_generation = [ capacity * target @@ -160,21 +165,21 @@ def test_hydro_heuristic_daily_part() -> None: for month in range(12): number_day_month = get_number_of_days_in_month(month) - initial_level, status, obj, daily_generation = optimize_target( - inter_breakdown=interdaily_breakdown, - folder_name=folder_name, - capacity=capacity, - scenario=scenario, - initial_level=initial_level, - hours_aggregated_time_steps=[24 for d in range(365)], - timesteps=list(range(day_in_year, day_in_year + number_day_month)), - total_target=monthly_generation[month], + solving_output, daily_output = optimize_target( + heuristic_parameters=HydroHeuristicParameters(1, monthly_generation[month]), + data_aggregator_parameters=DataAggregatorParameters( + [24 for d in range(365)], + list(range(day_in_year, day_in_year + number_day_month)), + ), + reservoir_data=reservoir_data, heuristic_model=HeuristicHydroModelBuilder( HYDRO_MODEL, "daily" ).get_model(), ) - assert status == pywraplp.Solver.OPTIMAL - assert obj / capacity == pytest.approx( + reservoir_data.initial_level = daily_output.level + + assert solving_output.status == pywraplp.Solver.OPTIMAL + assert solving_output.objective / capacity == pytest.approx( [ -0.405595, -0.354666, @@ -193,7 +198,7 @@ def test_hydro_heuristic_daily_part() -> None: ) all_daily_generation = update_generation_target( - all_daily_generation, daily_generation + all_daily_generation, daily_output.generating ) day_in_year += number_day_month diff --git a/tests/functional/test_hydro_with_unavaibility.py b/tests/functional/test_hydro_with_unavaibility.py index 451a7724..315bf22b 100644 --- a/tests/functional/test_hydro_with_unavaibility.py +++ b/tests/functional/test_hydro_with_unavaibility.py @@ -22,7 +22,13 @@ get_number_of_days_in_month, update_generation_target, ) -from andromede.hydro_heuristic.problem import optimize_target +from andromede.hydro_heuristic.heuristic_model import HeuristicHydroModelBuilder +from andromede.hydro_heuristic.problem import ( + DataAggregatorParameters, + HydroHeuristicParameters, + ReservoirParameters, + optimize_target, +) from andromede.libs.standard import ( DEMAND_MODEL, GENERATOR_MODEL_WITH_AVAILIBILITY, @@ -41,11 +47,10 @@ create_component, ) from tests.functional.libs.lib_hydro_heuristic import ( + HYDRO_MODEL, HYDRO_MODEL_RULE_CURVES, HYDRO_MODEL_WITH_TARGET, - HYDRO_MODEL, ) -from andromede.hydro_heuristic.heuristic_model import HeuristicHydroModelBuilder optimal_generation = np.array( [ @@ -206,74 +211,63 @@ def test_complete_year_as_one_block() -> None: def test_hydro_heuristic() -> None: """ """ - scenarios = 1 - intermonthly_breakdown = 3 - interdaily_breakdown = 3 - folder_name = "hydro_with_rulecurves" - capacity = 1e7 - for scenario in range(scenarios): - initial_level = 0.445 * capacity - - initial_level, status, _, monthly_generation = optimize_target( - intermonthly_breakdown, - folder_name, - capacity, - scenario, - initial_level, - hours_aggregated_time_steps=[ - 24 * get_number_of_days_in_month(m) for m in range(12) - ], - timesteps=list(range(12)), - total_target=None, + reservoir_data = ReservoirParameters( + capacity, + initial_level=0.445 * capacity, + folder_name="hydro_with_rulecurves", + scenario=0, + ) + + solving_output, monthly_output = optimize_target( + heuristic_parameters=HydroHeuristicParameters(3), + data_aggregator_parameters=DataAggregatorParameters( + [24 * get_number_of_days_in_month(m) for m in range(12)], + list(range(12)), + ), + reservoir_data=reservoir_data, + heuristic_model=HeuristicHydroModelBuilder(HYDRO_MODEL, "monthly").get_model(), + ) + + assert solving_output.status == pywraplp.Solver.OPTIMAL + assert monthly_output.generating == expected_monthly_generation + + all_daily_generation: List[float] = [] + day_in_year = 0 + + for month in range(12): + number_day_month = get_number_of_days_in_month(month) + + solving_output, daily_output = optimize_target( + heuristic_parameters=HydroHeuristicParameters( + 3, monthly_output.generating[month] + ), + data_aggregator_parameters=DataAggregatorParameters( + [24 for d in range(365)], + list(range(day_in_year, day_in_year + number_day_month)), + ), + reservoir_data=reservoir_data, heuristic_model=HeuristicHydroModelBuilder( - HYDRO_MODEL, "monthly" + HYDRO_MODEL, "daily" ).get_model(), ) + reservoir_data.initial_level = daily_output.level + + assert solving_output.status == pywraplp.Solver.OPTIMAL - assert status == pywraplp.Solver.OPTIMAL - assert monthly_generation == expected_monthly_generation - - all_daily_generation: List[float] = [] - day_in_year = 0 - - for month in range(12): - number_day_month = get_number_of_days_in_month(month) - - ( - initial_level, - status, - obj, - daily_generation, - ) = optimize_target( - interdaily_breakdown, - folder_name, - capacity, - scenario, - initial_level, - hours_aggregated_time_steps=[24 for d in range(365)], - timesteps=list(range(day_in_year, day_in_year + number_day_month)), - total_target=monthly_generation[month], - heuristic_model=HeuristicHydroModelBuilder( - HYDRO_MODEL, "daily" - ).get_model(), - ) - - assert status == pywraplp.Solver.OPTIMAL - - all_daily_generation = update_generation_target( - all_daily_generation, daily_generation - ) - day_in_year += number_day_month - - # Calcul des cibles hebdomadaires - weekly_target = calculate_weekly_target( - all_daily_generation, + all_daily_generation = update_generation_target( + all_daily_generation, daily_output.generating ) + day_in_year += number_day_month + + # Calcul des cibles hebdomadaires + weekly_target = calculate_weekly_target( + all_daily_generation, + ) - # Vérification des valeurs trouvées - assert weekly_target == pytest.approx(expected_weekly_target) + # Vérification des valeurs trouvées + assert weekly_target == pytest.approx(expected_weekly_target) def test_complete_year_as_weekly_blocks_with_hydro_heuristic() -> None: diff --git a/tests/functional/test_hydro_without_inflow.py b/tests/functional/test_hydro_without_inflow.py index 8b32dd37..2052f27a 100644 --- a/tests/functional/test_hydro_without_inflow.py +++ b/tests/functional/test_hydro_without_inflow.py @@ -22,7 +22,13 @@ get_number_of_days_in_month, update_generation_target, ) -from andromede.hydro_heuristic.problem import optimize_target +from andromede.hydro_heuristic.heuristic_model import HeuristicHydroModelBuilder +from andromede.hydro_heuristic.problem import ( + DataAggregatorParameters, + HydroHeuristicParameters, + ReservoirParameters, + optimize_target, +) from andromede.libs.standard import ( DEMAND_MODEL, GENERATOR_MODEL, @@ -44,7 +50,6 @@ HYDRO_MODEL, HYDRO_MODEL_WITH_TARGET, ) -from andromede.hydro_heuristic.heuristic_model import HeuristicHydroModelBuilder weekly_generation = np.array( [ @@ -135,74 +140,62 @@ def test_complete_year_as_one_block() -> None: def test_hydro_heuristic() -> None: """ """ - scenarios = 1 - intermonthly_breakdown = 1 - interdaily_breakdown = 1 - folder_name = "hydro_without_inflow" - capacity = 1e7 + reservoir_data = ReservoirParameters( + capacity, + initial_level=0.445 * capacity, + folder_name="hydro_without_inflow", + scenario=0, + ) + + solving_output, monthly_output = optimize_target( + heuristic_parameters=HydroHeuristicParameters(1), + data_aggregator_parameters=DataAggregatorParameters( + [24 * get_number_of_days_in_month(m) for m in range(12)], + list(range(12)), + ), + reservoir_data=reservoir_data, + heuristic_model=HeuristicHydroModelBuilder(HYDRO_MODEL, "monthly").get_model(), + ) - for scenario in range(scenarios): - initial_level = 0.445 * capacity - - initial_level, status, _, monthly_generation = optimize_target( - intermonthly_breakdown, - folder_name, - capacity, - scenario, - initial_level, - hours_aggregated_time_steps=[ - 24 * get_number_of_days_in_month(m) for m in range(12) - ], - timesteps=list(range(12)), - total_target=None, + assert solving_output.status == pywraplp.Solver.OPTIMAL + assert monthly_output.generating == [0 for m in range(12)] + + all_daily_generation: List[float] = [] + day_in_year = 0 + + for month in range(12): + number_day_month = get_number_of_days_in_month(month) + + solving_output, daily_output = optimize_target( + heuristic_parameters=HydroHeuristicParameters( + 1, monthly_output.generating[month] + ), + data_aggregator_parameters=DataAggregatorParameters( + [24 for d in range(365)], + list(range(day_in_year, day_in_year + number_day_month)), + ), + reservoir_data=reservoir_data, heuristic_model=HeuristicHydroModelBuilder( - HYDRO_MODEL, "monthly" + HYDRO_MODEL, "daily" ).get_model(), ) + reservoir_data.initial_level = daily_output.level + + assert solving_output.status == pywraplp.Solver.OPTIMAL - assert status == pywraplp.Solver.OPTIMAL - assert monthly_generation == [0 for m in range(12)] - - all_daily_generation: List[float] = [] - day_in_year = 0 - - for month in range(12): - number_day_month = get_number_of_days_in_month(month) - - ( - initial_level, - status, - obj, - daily_generation, - ) = optimize_target( - interdaily_breakdown, - folder_name, - capacity, - scenario, - initial_level, - hours_aggregated_time_steps=[24 for d in range(365)], - timesteps=list(range(day_in_year, day_in_year + number_day_month)), - total_target=monthly_generation[month], - heuristic_model=HeuristicHydroModelBuilder( - HYDRO_MODEL, "daily" - ).get_model(), - ) - - assert status == pywraplp.Solver.OPTIMAL - - all_daily_generation = update_generation_target( - all_daily_generation, daily_generation - ) - day_in_year += number_day_month - - # Calcul des cibles hebdomadaires - weekly_target = calculate_weekly_target( - all_daily_generation, + all_daily_generation = update_generation_target( + all_daily_generation, daily_output.generating ) + day_in_year += number_day_month + + # Calcul des cibles hebdomadaires + weekly_target = calculate_weekly_target( + all_daily_generation, + ) - # Vérification des valeurs trouvées - assert weekly_target == [0 for w in range(52)] + # Vérification des valeurs trouvées + assert weekly_target == [0 for w in range(52)] def test_complete_year_as_weekly_blocks_with_hydro_heuristic() -> None: diff --git a/tests/functional/test_hydro_without_rulecurves.py b/tests/functional/test_hydro_without_rulecurves.py index d3f8709f..ee0d7eed 100644 --- a/tests/functional/test_hydro_without_rulecurves.py +++ b/tests/functional/test_hydro_without_rulecurves.py @@ -19,85 +19,78 @@ get_number_of_days_in_month, update_generation_target, ) -from andromede.hydro_heuristic.problem import optimize_target from andromede.hydro_heuristic.heuristic_model import HeuristicHydroModelBuilder +from andromede.hydro_heuristic.problem import ( + DataAggregatorParameters, + HydroHeuristicParameters, + ReservoirParameters, + optimize_target, +) from tests.functional.libs.lib_hydro_heuristic import HYDRO_MODEL def test_hydro_heuristic() -> None: """ """ - scenarios = 1 - intermonthly_breakdown = 1 - interdaily_breakdown = 3 - folder_name = "hydro_without_rulecurves" - capacity = 1711510 - - for scenario in range(scenarios): - initial_level = 0.5 * capacity - - initial_level, status, _, monthly_generation = optimize_target( - intermonthly_breakdown, - folder_name, - capacity, - scenario, - initial_level, - hours_aggregated_time_steps=[ - 24 * get_number_of_days_in_month(m) for m in range(12) - ], - timesteps=list(range(12)), - total_target=None, + reservoir_data = ReservoirParameters( + capacity, + initial_level=0.5 * capacity, + folder_name="hydro_without_rulecurves", + scenario=0, + ) + + solving_output, monthly_output = optimize_target( + heuristic_parameters=HydroHeuristicParameters(1), + data_aggregator_parameters=DataAggregatorParameters( + [24 * get_number_of_days_in_month(m) for m in range(12)], + list(range(12)), + ), + reservoir_data=reservoir_data, + heuristic_model=HeuristicHydroModelBuilder(HYDRO_MODEL, "monthly").get_model(), + ) + + assert solving_output.status == pywraplp.Solver.OPTIMAL + + all_daily_generation: List[float] = [] + day_in_year = 0 + + for month in range(12): + number_day_month = get_number_of_days_in_month(month) + + solving_output, daily_output = optimize_target( + heuristic_parameters=HydroHeuristicParameters( + 3, monthly_output.generating[month] + ), + data_aggregator_parameters=DataAggregatorParameters( + [24 for d in range(365)], + list(range(day_in_year, day_in_year + number_day_month)), + ), + reservoir_data=reservoir_data, heuristic_model=HeuristicHydroModelBuilder( - HYDRO_MODEL, "monthly" + HYDRO_MODEL, "daily" ).get_model(), ) + reservoir_data.initial_level = daily_output.level - assert status == pywraplp.Solver.OPTIMAL - - all_daily_generation: List[float] = [] - day_in_year = 0 + assert solving_output.status == pywraplp.Solver.OPTIMAL - for month in range(12): - number_day_month = get_number_of_days_in_month(month) - - ( - initial_level, - status, - obj, - daily_generation, - ) = optimize_target( - interdaily_breakdown, - folder_name, - capacity, - scenario, - initial_level, - hours_aggregated_time_steps=[24 for d in range(365)], - timesteps=list(range(day_in_year, day_in_year + number_day_month)), - total_target=monthly_generation[month], - heuristic_model=HeuristicHydroModelBuilder( - HYDRO_MODEL, "daily" - ).get_model(), - ) - - assert status == pywraplp.Solver.OPTIMAL - - all_daily_generation = update_generation_target( - all_daily_generation, daily_generation - ) - day_in_year += number_day_month - - # Calcul des cibles hebdomadaires - weekly_target = calculate_weekly_target( - all_daily_generation, + all_daily_generation = update_generation_target( + all_daily_generation, daily_output.generating ) - - # Vérification des valeurs trouvées - expected_output_file = open( - "tests/functional/data/hydro_without_rulecurves/values-weekly.txt", - "r", + day_in_year += number_day_month + + # Calcul des cibles hebdomadaires + weekly_target = calculate_weekly_target( + all_daily_generation, + ) + + # Vérification des valeurs trouvées + expected_output_file = open( + "tests/functional/data/hydro_without_rulecurves/values-weekly.txt", + "r", + ) + expected_output = expected_output_file.readlines() + for week in range(52): + assert float(expected_output[week + 7].strip().split("\t")[9]) == round( + weekly_target[week] ) - expected_output = expected_output_file.readlines() - for week in range(52): - assert float(expected_output[week + 7].strip().split("\t")[9]) == round( - weekly_target[week] - ) diff --git a/tests/unittests/hydro_heuristic/test_data.py b/tests/unittests/hydro_heuristic/test_data.py index 2d4e9758..746e2183 100644 --- a/tests/unittests/hydro_heuristic/test_data.py +++ b/tests/unittests/hydro_heuristic/test_data.py @@ -10,15 +10,16 @@ # # This file is part of the Antares project. -import pytest from unittest.mock import Mock +import pytest + from andromede.hydro_heuristic.data import ( + DataAggregator, HydroHeuristicData, + RawHydroData, calculate_weekly_target, get_number_of_days_in_month, - DataAggregator, - RawHydroData, ) @@ -80,7 +81,6 @@ def test_compute_target() -> None: def test_data_aggregator() -> None: - mock_raw_data = Mock(spec=RawHydroData) mock_raw_data.time_series = list(range(10)) diff --git a/tests/unittests/hydro_heuristic/test_heuristic_model.py b/tests/unittests/hydro_heuristic/test_heuristic_model.py index 7f9c99cb..f0a48c26 100644 --- a/tests/unittests/hydro_heuristic/test_heuristic_model.py +++ b/tests/unittests/hydro_heuristic/test_heuristic_model.py @@ -12,16 +12,14 @@ import pytest -from andromede.hydro_heuristic.heuristic_model import HeuristicHydroModelBuilder, Model - from andromede.expression import literal, param, var from andromede.expression.indexing_structure import IndexingStructure +from andromede.hydro_heuristic.heuristic_model import HeuristicHydroModelBuilder, Model from andromede.model import float_parameter, float_variable, model from andromede.model.constraint import Constraint from andromede.model.parameter import float_parameter from andromede.model.variable import float_variable - CONSTANT = IndexingStructure(False, False) TIME_AND_SCENARIO_FREE = IndexingStructure(True, True) NON_ANTICIPATIVE_TIME_VARYING = IndexingStructure(True, False) @@ -84,7 +82,6 @@ def test_empty_model() -> None: - model_builder = HeuristicHydroModelBuilder(Model(id="empty"), "monthly") with pytest.raises(AssertionError): @@ -92,7 +89,6 @@ def test_empty_model() -> None: def test_minimal_model() -> None: - model_builder = HeuristicHydroModelBuilder(MINIMAL_HYDRO_MODEL, "monthly") heuristic_model = model_builder.get_model()