scenarios.py 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  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=8,
  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. self.multistorage["capacity"],
  52. self.multistorage["power"],
  53. self.multistorage["power"],
  54. self.multistorage["efficiency"],
  55. )
  56. storage, storage_impact = storage_model.run(power_delta)
  57. gap = load - power - storage_impact.sum(axis=0)
  58. # further adjust power to load with dispatchable power sources
  59. dispatchable_model = DispatchableArray(self.sources["dispatchable"])
  60. dp = dispatchable_model.power(gap)
  61. gap -= dp.sum(axis=0)
  62. S = np.maximum(gap, 0).mean()
  63. return S, load, power, gap, storage, dp