diff --git a/src/pymgrid/convert/to_nonmodular_ops.py b/src/pymgrid/convert/to_nonmodular_ops.py index f64173e4..9cb8603f 100644 --- a/src/pymgrid/convert/to_nonmodular_ops.py +++ b/src/pymgrid/convert/to_nonmodular_ops.py @@ -1,6 +1,4 @@ -from pymgrid.modules import ( - LoadModule, RenewableModule, BatteryModule, GridModule, GensetModule, UnbalancedEnergyModule, CurtailmentModule -) +from pymgrid.modules import LoadModule, RenewableModule, BatteryModule, GridModule, GensetModule, UnbalancedEnergyModule from copy import deepcopy import pandas as pd import numpy as np @@ -28,7 +26,7 @@ def get_empty_params(): def check_viability(modular): - classes = LoadModule, RenewableModule, BatteryModule, GridModule, GensetModule, UnbalancedEnergyModule, CurtailmentModule + classes = LoadModule, RenewableModule, BatteryModule, GridModule, GensetModule, UnbalancedEnergyModule classes_str = '\n'.join([str(x) for x in classes]) n_modules_by_cls = dict(zip(classes, [0]*len(classes))) @@ -74,8 +72,6 @@ def add_params_from_module(module, params_dict): add_genset_params(module, params_dict) elif isinstance(module, UnbalancedEnergyModule): add_unbalanced_energy_params(module, params_dict) - elif isinstance(module, CurtailmentModule): - check_curtailment_params(module) else: raise ValueError(f'Cannot parse module {module}.') @@ -182,11 +178,6 @@ def add_unbalanced_energy_params(unbalanced_energy_module, params_dict): _add_to_df_cost(params_dict, 'overgeneration') -def check_curtailment_params(curtailment_module): - if curtailment_module.curtailment_cost != 0: - warn(f'Curtailment cost {curtailment_module.curtailment_cost} will be ignored in conversion to nonmodular.') - - def _add_empty(params_dict, subdict_name, *keys): params_dict[subdict_name].update({k: [] for k in keys}) diff --git a/src/pymgrid/microgrid/microgrid.py b/src/pymgrid/microgrid/microgrid.py index 0c210b46..4bd30c0f 100644 --- a/src/pymgrid/microgrid/microgrid.py +++ b/src/pymgrid/microgrid/microgrid.py @@ -6,7 +6,7 @@ from warnings import warn from pymgrid.microgrid import DEFAULT_HORIZON -from pymgrid.modules import ModuleContainer, UnbalancedEnergyModule, CurtailmentModule +from pymgrid.modules import ModuleContainer, UnbalancedEnergyModule from pymgrid.microgrid.utils.step import MicrogridStep from pymgrid.utils.eq import verbose_eq from pymgrid.utils.logger import ModularLogger @@ -33,9 +33,7 @@ class Microgrid(yaml.YAMLObject): .. note:: The constructor copies modules passed to it. - add_curtailment_module : bool, default False - - add_unbalanced_module : bool, default True + add_unbalanced_module : bool, default True. Whether to add an unbalanced energy module to your microgrid. Such a module computes and attributes costs to any excess supply or demand. Set to True unless ``modules`` contains an ``UnbalancedEnergyModule``. @@ -103,18 +101,14 @@ class Microgrid(yaml.YAMLObject): def __init__(self, modules, - add_curtailment_module=False, add_unbalanced_module=True, - curtailment_cost=0.0, loss_load_cost=10., overgeneration_cost=2., reward_shaping_func=None, trajectory_func=None): self._modules = self._get_module_container(modules, - add_curtailment_module, add_unbalanced_module, - curtailment_cost, loss_load_cost, overgeneration_cost) @@ -143,13 +137,7 @@ def _get_unbalanced_energy_module(self, overgeneration_cost=overgeneration_cost ) - def _get_module_container(self, - modules, - add_curtailment_module, - add_unbalanced_module, - curtailment_cost, - loss_load_cost, - overgeneration_cost): + def _get_module_container(self, modules, add_unbalanced_module, loss_load_cost, overgeneration_cost): """ Types of _modules: Fixed source: provides energy to the microgrid. @@ -180,21 +168,10 @@ def _get_module_container(self, if not pd.api.types.is_list_like(modules): raise TypeError("modules must be list-like of modules.") - if add_curtailment_module: - curtailment_module = CurtailmentModule(curtailment_cost=curtailment_cost) - modules.append(curtailment_module) - else: - curtailment_module = None - if add_unbalanced_module: modules.append(self._get_unbalanced_energy_module(loss_load_cost, overgeneration_cost)) - container = ModuleContainer(modules) - - if curtailment_module: - curtailment_module.setup(container) - - return container + return ModuleContainer(modules) def _check_trajectory_func(self, trajectory_func): if trajectory_func is None: @@ -236,11 +213,8 @@ def reset(self): Observations from resetting the modules as well as the flushed balance log. """ self._set_trajectory() - def reset_args(module): return (self.modules,) if isinstance(module, CurtailmentModule) else () - return { - **{name: [module.reset(*reset_args(module)) for module in module_list] - for name, module_list in self.modules.iterdict()}, + **{name: [module.reset() for module in module_list] for name, module_list in self.modules.iterdict()}, **{"balance": self._balance_logger.flush(), "other": self._microgrid_logger.flush()} } diff --git a/src/pymgrid/modules/__init__.py b/src/pymgrid/modules/__init__.py index 8e284458..b262b248 100644 --- a/src/pymgrid/modules/__init__.py +++ b/src/pymgrid/modules/__init__.py @@ -1,5 +1,4 @@ from .battery.battery_module import BatteryModule -from .curtailment_module import CurtailmentModule from .genset_module import GensetModule from .grid_module import GridModule from .load_module import LoadModule diff --git a/src/pymgrid/modules/curtailment_module.py b/src/pymgrid/modules/curtailment_module.py deleted file mode 100644 index d77a19b6..00000000 --- a/src/pymgrid/modules/curtailment_module.py +++ /dev/null @@ -1,189 +0,0 @@ -import numpy as np - -import yaml - -from pymgrid.modules.base import BaseMicrogridModule, BaseTimeSeriesMicrogridModule -from pymgrid.modules.module_container import ModuleContainer - - -class CurtailmentModule(BaseMicrogridModule): - """ - A curtailment module for renewables. - - The classic examples of renewables are photovoltaics (PV) and wind turbines. This module allows for their - production to be curtailed without incurring costs (or incurring costs different from other overgeneration). - - Parameters - ---------- - modules_to_curtail : list-like or None, default None - List of modules to curtail or None, in which case all curtailment will apply to all fixed source modules, - of which renewables are by default. Can contain any of the following: - - * :class:`.BaseMicrogridModule` : - Specific modules to curtail: subclasses of the base module. - - * tuple, length two : - tuple of the form ``(module_name, module_number)`` pointing to a specific module, e.g. ``('renewable', 0)``. - - * str : - Name of a particular module type, e.g. ``'renewable'``. All modules in :class:`.Microgrid.modules```['renewable'] - will be included. - - * None : - Use all fixed source modules, of which renewables are. - - curtailment_cost : float, default 0.0 - Unit cost of curtailment. - - raise_errors : bool, default False - Whether to raise errors if bounds are exceeded in an action. - If False, actions are clipped to the limit possible. - - """ - module_type = ('curtailment', 'flex') - yaml_tag = u"!CurtailmentModule" - yaml_dumper = yaml.SafeDumper - yaml_loader = yaml.SafeLoader - - def __init__(self, - modules_to_curtail=None, - initial_step=0, - curtailment_cost=0.0, - normalized_action_bounds=(0, 1), - raise_errors=False): - - super().__init__(raise_errors, - initial_step=initial_step, - normalized_action_bounds=normalized_action_bounds, - provided_energy_name=None, - absorbed_energy_name='curtailment') - - self._modules_to_curtail = modules_to_curtail - self.curtailment_cost = curtailment_cost - - self._curtailment_modules = None - self._next_max_consumption = None - - def reset(self, module_container=None): - if module_container: - self.setup(module_container) - - return super().reset() - - def setup(self, module_container): - """ - - Parameters - ---------- - module_container : :class:`.ModuleContainer` - - Returns - ------- - - """ - if self._modules_to_curtail is None: - curtailment_modules = module_container.fixed.sources.to_list() - - else: - curtailment_modules = [] - - for module_ref in self._modules_to_curtail: - curtailment_modules.extend(self._get_modules_from_ref(module_container, module_ref)) - - self._curtailment_modules = ModuleContainer(curtailment_modules, set_names=False) - self._update_max_consumption() - - def _get_modules_from_ref(self, modules, ref): - if isinstance(ref, BaseMicrogridModule): # Module - referenced_modules = [ref] - - elif isinstance(ref, tuple): # Name of a module, e.g. ('renewable', 0) - if ref == self.name: - raise NameError('Cannot reference itself.') - - try: - referenced_modules = [modules[ref[0]][ref[1]]] - except (KeyError, IndexError): - raise NameError(f'Module {ref} not found.') - - elif isinstance(ref, str): # Name of a module type, e.g. 'renewable' - try: - referenced_modules = modules[ref] - except KeyError: - raise NameError(f'Module {ref} not found.') - else: - raise TypeError(f"Unrecognized module reference '{ref}'.") - - return referenced_modules - - def update(self, external_energy_change, as_source=False, as_sink=False): - assert as_sink - - if not self._curtailment_modules: - raise RuntimeError('Must call RenewableCurtailmentModule.setup before usage!') - - curtailment = min(external_energy_change, self.max_consumption) - info = {'absorbed_energy': curtailment, 'net_renewable_usage': self.max_consumption-curtailment} - reward = -1.0 * self.get_cost(curtailment) - - done = self._update_max_consumption() - - return reward, done, info - - def get_cost(self, curtailment): - return self.curtailment_cost * curtailment - - def _update_max_consumption(self): - try: - self._next_max_consumption = self._curtailment_modules.get_attrs('max_production').sum().item() - return False - except IndexError: - assert self._current_step == self._curtailment_modules.get_attrs('final_step', unique=True).item() - 1 - self._next_max_consumption = 0.0 - return True - - def _state_dict(self): - return dict() - - @property - def state(self): - return np.array([]) - - @property - def min_obs(self): - return np.array([]) - - @property - def max_obs(self): - return np.array([]) - - @property - def min_act(self): - # TODO (ahalev) find a better bound - return -np.inf - - @property - def max_act(self): - return 0.0 - - @property - def max_consumption(self): - module_current_step = self._curtailment_modules.get_attrs('current_step', unique=True).item() - if not self._current_step == module_current_step - 1: - raise RuntimeError(f'self.current_step={self._current_step} is not one less than curtailment module current' - f'step ({module_current_step}). This module should only be called after curtailment' - f'modules.') - - return self._next_max_consumption - - @property - def is_sink(self): - return True - - @property - def absorption_marginal_cost(self): - return self.curtailment_cost - - def __repr__(self): - return f'CurtailmentModule(' \ - f'modules={self._curtailment_modules.get_attrs("name").squeeze(axis=0).values.tolist()})' diff --git a/src/pymgrid/modules/unbalanced_energy_module.py b/src/pymgrid/modules/unbalanced_energy_module.py index bdfdd554..e69877ec 100644 --- a/src/pymgrid/modules/unbalanced_energy_module.py +++ b/src/pymgrid/modules/unbalanced_energy_module.py @@ -15,7 +15,7 @@ def __init__(self, initial_step=0, loss_load_cost=10, overgeneration_cost=2.0, - normalized_action_bounds=(0, 1) + normalized_action_bounds = (0, 1) ): super().__init__(raise_errors, diff --git a/tests/control/test_mpc.py b/tests/control/test_mpc.py index 142ca83a..d92d1adc 100644 --- a/tests/control/test_mpc.py +++ b/tests/control/test_mpc.py @@ -29,7 +29,7 @@ def test_run_with_load_pv_battery_grid(self): self.assertEqual(mpc_output.shape[0], max_steps) self.assertEqual(mpc_output[("grid", 0, "grid_import")].values + mpc_output[("battery", 0, "discharge_amount")].values + - mpc_output[("curtailment", 0, "net_renewable_usage")].values, + mpc_output[("renewable", 0, "renewable_used")].values, [load_const] * mpc_output.shape[0] ) @@ -128,7 +128,7 @@ def test_run_with_load_pv_battery_grid_different_names(self): self.assertEqual(mpc_output[("load_with_name", 0, "load_met")].values, [load_const]*mpc_output.shape[0]) self.assertEqual(mpc_output[("grid", 0, "grid_import")].values + mpc_output[("battery", 0, "discharge_amount")].values + - mpc_output[("curtailment", 0, "net_renewable_usage")].values, + mpc_output[("pv_with_name", 0, "renewable_used")].values, [load_const] * mpc_output.shape[0] ) self.assertEqual(mpc_output[("load_with_name", 0, "load_met")].values, [load_const]*mpc_output.shape[0]) diff --git a/tests/helpers/modular_microgrid.py b/tests/helpers/modular_microgrid.py index 1f1b22d7..542d9e61 100644 --- a/tests/helpers/modular_microgrid.py +++ b/tests/helpers/modular_microgrid.py @@ -15,7 +15,6 @@ def get_modular_microgrid(remove_modules=(), retain_only=None, additional_modules=None, add_unbalanced_module=True, - add_curtailment_module=True, timeseries_length=100, modules_only=False, normalized_action_bounds=(0, 1)): @@ -64,6 +63,4 @@ def get_modular_microgrid(remove_modules=(), if modules_only: return modules - return Microgrid(modules, - add_unbalanced_module=add_unbalanced_module, - add_curtailment_module=add_curtailment_module) + return Microgrid(modules, add_unbalanced_module=add_unbalanced_module) diff --git a/tests/helpers/test_case.py b/tests/helpers/test_case.py index cf9f1ab3..b7520e30 100644 --- a/tests/helpers/test_case.py +++ b/tests/helpers/test_case.py @@ -4,7 +4,6 @@ from unittest.util import safe_repr - class TestCase(unittest.TestCase): def assertEqual(self, first, second, msg=None) -> None: try: diff --git a/tests/microgrid/modules/module_tests/test_renewable_module.py b/tests/microgrid/modules/module_tests/test_renewable_module.py index 631e59d9..0bff0e10 100644 --- a/tests/microgrid/modules/module_tests/test_renewable_module.py +++ b/tests/microgrid/modules/module_tests/test_renewable_module.py @@ -1,4 +1,3 @@ -import numpy as np from pymgrid.modules import RenewableModule @@ -12,7 +11,7 @@ class TestRenewableModuleNoForecasting(TestTimeseriesModuleNoForecasting): __test__ = True - action_space_dim = 0 + action_space_dim = 1 def get_module(self): return RenewableModule(self.module_time_series) @@ -25,16 +24,20 @@ def test_step(self): renewable_module = self.get_module() self.assertEqual(renewable_module.current_renewable, self.time_series[0]) - obs, reward, done, info = renewable_module.step(np.array([])) + unnormalized_action = 1 + action = renewable_module.to_normalized(unnormalized_action, act=True) + obs, reward, done, info = renewable_module.step(action) obs = renewable_module.from_normalized(obs, obs=True) self.assertEqual(obs, self.time_series[1]) self.assertEqual(reward, 0) self.assertFalse(done) - self.assertEqual(info["provided_energy"], self.time_series[0]) + self.assertEqual(info["provided_energy"], unnormalized_action) + self.assertEqual(info["curtailment"], 0) + class TestRenewableModuleForecasting(TestTimeseriesModuleForecasting): __test__ = True - action_space_dim = 0 + action_space_dim = 1 def get_module(self): return RenewableModule(self.module_time_series, forecaster="oracle", forecast_horizon=self.forecast_horizon) @@ -43,13 +46,15 @@ def test_step(self): renewable_module = self.get_module() self.assertEqual(renewable_module.current_renewable, self.time_series[0]) - action = renewable_module.to_normalized(np.array([]), act=True) + unnormalized_action = 1 + action = renewable_module.to_normalized(unnormalized_action, act=True) obs, reward, done, info = renewable_module.step(action) obs = renewable_module.from_normalized(obs, obs=True) self.assertEqual(obs, self.time_series[1:self.forecast_horizon+2]) self.assertEqual(reward, 0) self.assertFalse(done) - self.assertEqual(info["provided_energy"], self.time_series[0]) + self.assertEqual(info["provided_energy"], unnormalized_action) + self.assertEqual(info["curtailment"], 0) class TestRenewableModuleForecastingNegativeVals(TestTimeSeriesModuleForecastingNegativeVals, diff --git a/tests/microgrid/serialize/test_microgrid_serialization.py b/tests/microgrid/serialize/test_microgrid_serialization.py index 52636ef9..4d6a961a 100644 --- a/tests/microgrid/serialize/test_microgrid_serialization.py +++ b/tests/microgrid/serialize/test_microgrid_serialization.py @@ -16,8 +16,7 @@ def test_serialize_no_modules(self): def test_serialize_with_renewable(self): microgrid = get_modular_microgrid(remove_modules=["genset", "battery", "load", "grid"], - add_unbalanced_module=False, - add_curtailment_module=False) + add_unbalanced_module=False) self.assertEqual(len(microgrid.modules), 1) self.assertEqual(microgrid, Microgrid.load(microgrid.dump())) diff --git a/tests/microgrid/test_microgrid.py b/tests/microgrid/test_microgrid.py index e16fa824..3b168e4c 100644 --- a/tests/microgrid/test_microgrid.py +++ b/tests/microgrid/test_microgrid.py @@ -310,11 +310,11 @@ def test_set_initial_step(self): self.assertEqual(initial_step, 1) -class TestMicrogridLoadPVWithCurtailment(TestCase): +class TestMicrogridLoadPV(TestCase): def setUp(self): self.load_ts, self.pv_ts = self.set_ts() self.microgrid, self.n_loads, self.n_pvs = self.set_microgrid() - self.n_modules = 2 + self.n_loads + self.n_pvs + self.n_modules = 1 + self.n_loads + self.n_pvs def set_ts(self): ts = 10 * np.random.rand(100) @@ -323,14 +323,11 @@ def set_ts(self): def set_microgrid(self): load = LoadModule(time_series=self.load_ts, raise_errors=True) pv = RenewableModule(time_series=self.pv_ts, raise_errors=True) - return Microgrid([load, pv], add_curtailment_module=True), 1, 1 + return Microgrid([load, pv]), 1, 1 def test_populated_correctly(self): self.assertTrue(hasattr(self.microgrid.modules, 'load')) self.assertTrue(hasattr(self.microgrid.modules, 'renewable')) - self.assertTrue(hasattr(self.microgrid.modules, 'curtailment')) - self.assertEqual(len(self.microgrid.modules.curtailment), 1) - self.assertEqual(len(self.microgrid.modules), self.n_modules) # load, pv, unbalanced def test_current_load_correct(self): @@ -355,7 +352,7 @@ def test_sample_action(self): def test_sample_action_with_flex(self): sampled_action = self.microgrid.sample_action(sample_flex_modules=True) - self.assertEqual(len(sampled_action), 2) + self.assertEqual(len(sampled_action), 1) self.assertIn('balancing', sampled_action) def test_state_dict(self): @@ -393,17 +390,19 @@ def check_step(self, microgrid, step_number=0): obs, reward, done, info = microgrid.run(control) loss_load = self.load_ts[step_number]-self.pv_ts[step_number] + overgeneration = -1 * loss_load loss_load_cost = self.microgrid.modules.balancing[0].loss_load_cost * max(loss_load, 0) + overgeneration_cost = self.microgrid.modules.balancing[0].overgeneration_cost * max(overgeneration, 0) - self.assertEqual(loss_load_cost, -1*reward) + self.assertEqual(loss_load_cost + overgeneration_cost, -1*reward) self.assertEqual(len(microgrid.log), step_number + 1) self.assertTrue(all(module in microgrid.log for module in microgrid.modules.names())) load_met = min(self.load_ts[step_number], self.pv_ts[step_number]) - loss_load = max(self.load_ts[step_number] - self.pv_ts[step_number], 0) - curtailment = max(self.pv_ts[step_number] - self.load_ts[step_number], 0) + loss_load = max(self.load_ts[step_number] - load_met, 0) + # Checking the log populated correctly. log_row = microgrid.log.iloc[step_number] @@ -419,16 +418,13 @@ def check_step(self, microgrid, step_number=0): self.assertEqual(log_entry('load', 'load_met'), load_met) self.assertEqual(log_entry('renewable', 'renewable_current'), self.pv_ts[step_number]) - self.assertEqual(log_entry('renewable', 'renewable_used')-log_entry('curtailment', 'curtailment'), load_met) + self.assertEqual(log_entry('renewable', 'renewable_used'), load_met) - self.assertEqual(log_entry('curtailment', 'curtailment'), curtailment) self.assertEqual(log_entry('balancing', 'loss_load'), loss_load) - overall_provided_absorbed = max(self.pv_ts[step_number], self.load_ts[step_number]) - self.assertEqual(log_entry('balance', 'overall_provided_to_microgrid'), overall_provided_absorbed) - self.assertEqual(log_entry('balance', 'overall_absorbed_from_microgrid'), overall_provided_absorbed) - self.assertEqual(log_entry('balance', 'reward'), -1 * loss_load_cost) + self.assertEqual(log_entry('balance', 'overall_provided_to_microgrid'), self.load_ts[step_number]) + self.assertEqual(log_entry('balance', 'overall_absorbed_from_microgrid'), self.load_ts[step_number]) self.assertEqual(log_entry('balance', 'fixed_provided_to_microgrid'), self.pv_ts[step_number]) self.assertEqual(log_entry('balance', 'fixed_absorbed_from_microgrid'), self.load_ts[step_number]) self.assertEqual(log_entry('balance', 'controllable_absorbed_from_microgrid'), 0.0) @@ -447,7 +443,7 @@ def test_run_n_steps(self): microgrid = self.check_step(microgrid=microgrid, step_number=step) -class TestMicrogridLoadExcessPVWithCurtailment(TestMicrogridLoadPVWithCurtailment): +class TestMicrogridLoadExcessPV(TestMicrogridLoadPV): # Same as above but pv is greater than load. def set_ts(self): load_ts = 10*np.random.rand(100) @@ -455,7 +451,7 @@ def set_ts(self): return load_ts, pv_ts -class TestMicrogridPVExcessLoadWithCurtailment(TestMicrogridLoadPVWithCurtailment): +class TestMicrogridPVExcessLoad(TestMicrogridLoadPV): # Load greater than PV. def set_ts(self): pv_ts = 10 * np.random.rand(100) @@ -463,7 +459,7 @@ def set_ts(self): return load_ts, pv_ts -class TestMicrogridTwoLoadsWithCurtailment(TestMicrogridLoadPVWithCurtailment): +class TestMicrogridTwoLoads(TestMicrogridLoadPV): def set_microgrid(self): load_1_ts = self.load_ts*(1-np.random.rand(*self.load_ts.shape)) load_2_ts = self.load_ts - load_1_ts @@ -474,10 +470,10 @@ def set_microgrid(self): load_1 = LoadModule(time_series=load_1_ts, raise_errors=True) load_2 = LoadModule(time_series=load_2_ts, raise_errors=True) pv = RenewableModule(time_series=self.pv_ts, raise_errors=True) - return Microgrid([load_1, load_2, pv], add_curtailment_module=True), 2, 1 + return Microgrid([load_1, load_2, pv]), 2, 1 -class TestMicrogridTwoPVWithCurtailment(TestMicrogridLoadPVWithCurtailment): +class TestMicrogridTwoPV(TestMicrogridLoadPV): def set_microgrid(self): pv_1_ts = self.pv_ts*(1-np.random.rand(*self.pv_ts.shape)) pv_2_ts = self.pv_ts - pv_1_ts @@ -488,10 +484,10 @@ def set_microgrid(self): load = LoadModule(time_series=self.load_ts, raise_errors=True) pv_1 = RenewableModule(time_series=pv_1_ts, raise_errors=True) pv_2 = RenewableModule(time_series=pv_2_ts) - return Microgrid([load, pv_1, pv_2], add_curtailment_module=True), 1, 2 + return Microgrid([load, pv_1, pv_2]), 1, 2 -class TestMicrogridTwoEachWithCurtailment(TestMicrogridLoadPVWithCurtailment): +class TestMicrogridTwoEach(TestMicrogridLoadPV): def set_microgrid(self): load_1_ts = self.load_ts*(1-np.random.rand(*self.load_ts.shape)) load_2_ts = self.load_ts - load_1_ts @@ -509,10 +505,10 @@ def set_microgrid(self): pv_1 = RenewableModule(time_series=pv_1_ts, raise_errors=True) pv_2 = RenewableModule(time_series=pv_2_ts) - return Microgrid([load_1, load_2, pv_1, pv_2], add_curtailment_module=True), 2, 2 + return Microgrid([load_1, load_2, pv_1, pv_2]), 2, 2 -class TestMicrogridManyEachWithCurtailment(TestMicrogridLoadPVWithCurtailment): +class TestMicrogridManyEach(TestMicrogridLoadPV): def set_microgrid(self): n_loads = np.random.randint(3, 10) n_pvs = np.random.randint(3, 10) @@ -538,28 +534,27 @@ def set_microgrid(self): load_modules = [LoadModule(time_series=ts) for ts in load_ts] pv_modules = [RenewableModule(time_series=ts) for ts in pv_ts] - return Microgrid([*load_modules, *pv_modules], add_curtailment_module=True), n_loads, n_pvs + return Microgrid([*load_modules, *pv_modules]), n_loads, n_pvs -class TestMicrogridManyEachExcessPV(TestMicrogridManyEachWithCurtailment): +class TestMicrogridManyEachExcessPV(TestMicrogridManyEach): def set_ts(self): load_ts = 10*np.random.rand(100) pv_ts = load_ts + 5*np.random.rand(100) return load_ts, pv_ts -class TestMicrogridManyEachExcessLoad(TestMicrogridManyEachWithCurtailment): +class TestMicrogridManyEachExcessLoad(TestMicrogridManyEach): def set_ts(self): pv_ts = 10*np.random.rand(100) load_ts = pv_ts + 5*np.random.rand(100) return load_ts, pv_ts -class TestMicrogridRewardShapingWithCurtailment(TestMicrogridLoadPVWithCurtailment): +class TestMicrogridRewardShaping(TestMicrogridLoadPV): def set_microgrid(self): original_microgrid, n_loads, n_pvs = super().set_microgrid() new_microgrid = Microgrid(original_microgrid.modules.to_tuples(), - add_curtailment_module=False, add_unbalanced_module=False, reward_shaping_func=self.reward_shaping_func)