scenarios.py 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. from .consumption import *
  2. from .production import *
  3. from .storage import *
  4. from typing import Tuple
  5. class Scenario:
  6. def __init__(
  7. self,
  8. yearly_total: float = None,
  9. sources: dict = {},
  10. multistorage: dict = {},
  11. flexibility_power=0,
  12. flexibility_time=4,
  13. ) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
  14. """Run a mix scenario.
  15. :param yearly_total: Annual consumption in GWh, for models with fixed annual consumption. defaults to None
  16. :type yearly_total: _type_, optional
  17. :param sources: float, defaults to {}
  18. :type sources: dict, optional
  19. :param multistorage: _description_, defaults to {}
  20. :type multistorage: dict, optional
  21. :param flexibility_power: _description_, defaults to 0
  22. :type flexibility_power: int, optional
  23. :param flexibility_time: _description_, defaults to 8
  24. :type flexibility_time: int, optional
  25. :return: Performance of the scenario.
  26. :rtype: Tuple[float, np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray]
  27. """
  28. self.yearly_total = yearly_total
  29. self.sources = sources
  30. self.multistorage = multistorage
  31. self.flexibility_power = flexibility_power
  32. self.flexibility_time = flexibility_time
  33. pass
  34. def run(self, times, intermittent_load_factors):
  35. # consumption
  36. consumption_model = FittedConsumptionModel(self.yearly_total)
  37. load = consumption_model.get(times)
  38. # intermittent sources (or sources with fixed load factors)
  39. intermittent_array = IntermittentArray(
  40. intermittent_load_factors, np.transpose([self.sources["intermittent"]])
  41. )
  42. power = intermittent_array.power()
  43. if self.flexibility_power > 0:
  44. flexibility_model = ConsumptionFlexibilityModel(
  45. self.flexibility_power, self.flexibility_time
  46. )
  47. load = flexibility_model.run(load, power)
  48. power_delta = power - load
  49. # adjust power to load with storage
  50. storage_model = MultiStorageModel(
  51. np.array(self.multistorage["capacity"])
  52. * np.array(self.multistorage["power"]),
  53. self.multistorage["power"],
  54. self.multistorage["power"],
  55. self.multistorage["efficiency"],
  56. )
  57. storage, storage_impact = storage_model.run(power_delta)
  58. gap = load - power - storage_impact.sum(axis=0)
  59. # further adjust power to load with dispatchable power sources
  60. dispatchable_model = DispatchableArray(self.sources["dispatchable"])
  61. dp = dispatchable_model.power(gap)
  62. gap -= dp.sum(axis=0)
  63. S = np.maximum(gap, 0).mean()
  64. return S, load, power, gap, storage, dp