示例#1
0
  def testSimpleStorageWithStorageEfficiency(self):
    """Free Storage should backup Solar."""
    solar = GridSource(SOLAR, 2.0e6, 0)
    wind = GridSource(WIND, 5.0e6, 0)
    ng = GridSource(NG, 1.0e10, 0)

    se = math.pow(0.5, 1.0 / 3)
    storage = GridRecStorage(STORAGE, 0, storage_efficiency=se)

    lp = self.lp
    lp.add_nondispatchable_sources(solar, wind)
    lp.add_dispatchable_sources(ng)
    lp.add_storage(storage)
    self.assertTrue(lp.solve())

    npt.assert_almost_equal(solar.get_solution_values(),
                            np.array([4.5, 0, 0, 2.25]))

    npt.assert_almost_equal(wind.get_solution_values(),
                            np.zeros(4))

    npt.assert_almost_equal(ng.get_solution_values(),
                            np.zeros(4))

    npt.assert_almost_equal(storage.get_solution_values(),
                            np.array([0, 1.5, 1.5 * se, 1.5 * se * se]))

    npt.assert_almost_equal(storage.get_source_solution_values(),
                            np.array([-1.5, 0, 0, 0.75]))
示例#2
0
  def testSimpleStorageWithSourceLimit(self):
    """Tests Solar, Wind, Storage.  Solar limited so wind makes up the rest."""
    solar = GridSource(SOLAR, 2.0e6, 0, max_energy=3)
    wind = GridSource(WIND, 5.0e6, 0)
    ng = GridSource(NG, 1.0e10, 0)
    storage = GridRecStorage(STORAGE, 0)

    lp = self.lp
    lp.add_nondispatchable_sources(solar, wind)
    lp.add_dispatchable_sources(ng)
    lp.add_storage(storage)
    self.assertTrue(lp.solve())

    npt.assert_almost_equal(solar.get_solution_values(),
                            np.array([2.0, 0, 0, 1.0]))

    npt.assert_almost_equal(wind.get_solution_values(),
                            np.array([3.0, 0, 0, 0.0]))

    npt.assert_almost_equal(ng.get_solution_values(),
                            np.zeros(4))

    npt.assert_almost_equal(storage.get_solution_values(),
                            np.array([0, 2.0, 2.0, 2.0]))

    npt.assert_almost_equal(storage.get_source_solution_values(),
                            np.array([-2.0, 0, 0, 2.0]))
示例#3
0
  def testSimpleStorageWithStorageLimit(self):
    """Free Storage should backup Solar."""
    solar = GridSource(SOLAR, 2.0e6, 0)
    wind = GridSource(WIND, 5.0e6, 0)
    ng = GridSource(NG, 1.0e10, 0)
    storage = GridRecStorage(STORAGE, 0, max_storage=0.5)

    lp = self.lp
    lp.add_nondispatchable_sources(solar, wind)
    lp.add_dispatchable_sources(ng)
    lp.add_storage(storage)
    self.assertTrue(lp.solve())

    npt.assert_almost_equal(solar.get_solution_values(),
                            np.array([5.0, 0, 0, 2.5]))

    npt.assert_almost_equal(wind.get_solution_values(),
                            np.zeros(4))

    npt.assert_almost_equal(ng.get_solution_values(),
                            np.zeros(4))

    npt.assert_almost_equal(storage.get_solution_values(),
                            np.array([0, 0.5, 0.5, 0.5]))

    npt.assert_almost_equal(storage.get_source_solution_values(),
                            np.array([-0.5, 0, 0, 0.5]))
示例#4
0
  def testRandomSawToothRecStorage(self):
    lp = self.lp
    solar = self.solar
    lp.add_nondispatchable_sources(solar)
    storage = GridRecStorage(STORAGE, 0)
    lp.add_storage(storage)

    for storage_efficiency in np.linspace(0.1, 1.0, 4):
      storage.storage_efficiency = storage_efficiency
      self.assertTrue(lp.solve())

      # build up storage profile
      demand_profile = self.demand_profile
      golden_storage_profile = []
      last_storage_value = 0.0
      for d in reversed(demand_profile):
        next_storage_value = (last_storage_value + d) / storage_efficiency
        golden_storage_profile.append(next_storage_value)
        last_storage_value = next_storage_value

      golden_storage_profile.reverse()
      # First generation comes from solar, so set golden_storage[0] = 0.
      golden_storage_profile[0] = 0
      golden_solar_profile = self.impulse * golden_storage_profile[1]

      npt.assert_allclose(solar.get_solution_values(),
                          golden_solar_profile)

      npt.assert_allclose(storage.get_solution_values(),
                          golden_storage_profile,
                          atol=1e-7)
示例#5
0
  def testRpsStorage(self):
    """Storage credits rps if timeslice exceeds demand."""

    lp = self.lp
    wind = GridSource(WIND, 2.0e6, 0, is_rps_source=True)
    ng = GridSource(NG, 0, 1.0e6)
    storage = GridRecStorage(STORAGE, 1, 1, 1)

    lp.add_nondispatchable_sources(wind)
    lp.add_dispatchable_sources(ng)
    lp.add_storage(storage)

    demand_at_0 = self.profiles[DEMAND][0]
    demand_at_1 = self.profiles[DEMAND][1]

    total = sum(self.profiles[DEMAND])
    for rps in range(0, 120, 10):
      lp.rps_percent = rps

      rps_total = total * rps / 100.0

      # Wind is only on for one time-slice.
      wind_at_0 = rps_total
      wind_nameplate = wind_at_0
      golden_wind = wind_nameplate * self.profiles[WIND]

      # Either we charge at 0, or ng fills remaining.
      if wind_at_0 >= demand_at_0:
        storage_at_0 = wind_at_0 - demand_at_0
        ng_at_0 = 0
      else:
        storage_at_0 = 0
        ng_at_0 = demand_at_0 - wind_at_0

      # Discharge everything at 1.
      storage_discharge_power = storage_at_0
      ng_at_1 = demand_at_1 - storage_discharge_power

      if lp.solve():
        self.assertTrue(rps <= 100)
        npt.assert_almost_equal(wind.get_solution_values(),
                                golden_wind)

        npt.assert_almost_equal(ng.get_solution_values(),
                                np.array([ng_at_0, ng_at_1]))

        # Storage at t=1 shows what charged at t=0.
        npt.assert_almost_equal(storage.get_solution_values(),
                                np.array([0.0, storage_at_0]))
      else:
        # Verify no convergence because we asked for a ridiculous rps number.
        self.assertTrue(rps > 100)
示例#6
0
  def testStorageNameplateCost(self):
    """Keep increasing storage costs until ng finally wins out."""
    wind = GridSource(WIND, 1.0e6, 0)
    storage = GridRecStorage(STORAGE, 0)
    ng = GridSource(NG, 4.6e6, 0)
    lp = self.lp
    lp.add_nondispatchable_sources(wind)
    lp.add_dispatchable_sources(ng)
    lp.add_storage(storage)

    self.assertTrue(lp.solve())

    npt.assert_almost_equal(wind.get_solution_values(),
                            np.array([2.0, 0.0]))

    npt.assert_almost_equal(ng.get_solution_values(),
                            np.zeros(2))

    # Change costs.  Total wind + storage cost is now (2 + 1)E6.
    # Still less than ng costs.
    storage.charge_nameplate_cost = 1.0e6
    self.assertTrue(lp.solve())

    npt.assert_almost_equal(wind.get_solution_values(),
                            np.array([2.0, 0.0]))

    npt.assert_almost_equal(ng.get_solution_values(),
                            np.zeros(2))

    # Change Costs. Total wind + storage cost is now (2 + 1 + 1)E6.
    # Still less than ng costs.
    storage.storage_nameplate_cost = 1.0e6
    self.assertTrue(lp.solve())

    npt.assert_almost_equal(wind.get_solution_values(),
                            np.array([2.0, 0.0]))

    npt.assert_almost_equal(ng.get_solution_values(),
                            np.zeros(2))

    # Change costs.  Total wind + storage cost is now
    # (2 + 1 + 1 + 1)E6.  Now more than ng costs.
    storage.discharge_nameplate_cost = 1.0e6
    self.assertTrue(lp.solve())

    npt.assert_almost_equal(wind.get_solution_values(),
                            np.zeros(2))

    npt.assert_almost_equal(ng.get_solution_values(),
                            np.array([1.0, 1.0]))
示例#7
0
  def testCircularRecStorageFirstHourSource(self):
    """Verify that storage from first hour affects last hour."""
    wind = GridSource(WIND, 2.0e6, 0)
    storage = GridRecStorage(STORAGE, 0)

    lp = self.lp
    lp.add_nondispatchable_sources(wind)
    lp.add_storage(storage)
    self.assertTrue(lp.solve())

    npt.assert_almost_equal(wind.get_solution_values(),
                            np.array([2.0, 0.0]))

    npt.assert_almost_equal(storage.get_solution_values(),
                            np.array([0.0, 1.0]))

    npt.assert_almost_equal(storage.get_source_solution_values(),
                            np.array([-1.0, 1.0]))
示例#8
0
  def testCircularRecStorageLastHourSource(self):
    """Verify that storage from last hour affects first hour."""
    solar = GridSource(SOLAR, 2.0e6, 0)
    storage = GridRecStorage(STORAGE, 0)

    lp = self.lp
    lp.add_nondispatchable_sources(solar)
    lp.add_storage(storage)
    self.assertTrue(lp.solve())

    npt.assert_almost_equal(solar.get_solution_values(),
                            np.array([0.0, 2.0]))

    npt.assert_almost_equal(storage.get_solution_values(),
                            np.array([1.0, 0.0]))

    npt.assert_almost_equal(storage.get_source_solution_values(),
                            np.array([1.0, -1.0]))
示例#9
0
  def testFreeRecStorageMeansCheapestSource(self):
    """Verify that free storage selects the cheapest energy supply."""
    solar = GridSource(SOLAR, 2.0e6, 0)
    wind = GridSource(WIND, 2.2e6, 0)
    storage = GridRecStorage(STORAGE, 0)

    lp = self.lp
    lp.add_nondispatchable_sources(solar, wind)
    lp.add_storage(storage)
    self.assertTrue(lp.solve())

    npt.assert_almost_equal(wind.get_solution_values(),
                            np.zeros(2))

    npt.assert_almost_equal(solar.get_solution_values(),
                            np.array([0.0, 2.0]))

    npt.assert_almost_equal(storage.get_solution_values(),
                            np.array([1.0, 0.0]))

    npt.assert_almost_equal(storage.get_source_solution_values(),
                            np.array([1.0, -1.0]))
示例#10
0
  def testCircularRecAccounting(self):
    """Verify that RECs get stored and accounted for properly."""
    lp = self.lp
    solar = GridSource(SOLAR, 2e6, 2e6, is_rps_source=True)
    wind = GridSource(WIND, 1e6, 1e6)
    storage = GridRecStorage(STORAGE, 1, 1, 1, discharge_efficiency=0.5)

    lp.add_nondispatchable_sources(solar, wind)
    lp.add_storage(storage)

    for rps in np.arange(0, 110, 10):
      lp.rps_percent = rps
      self.assertTrue(lp.solve())

      npt.assert_almost_equal(solar.get_solution_values(),
                              self.profiles[SOLAR].values *
                              rps / storage.discharge_efficiency)

      npt.assert_almost_equal(wind.get_solution_values(),
                              self.profiles[WIND] *
                              (100 - rps) / storage.discharge_efficiency)

      rps_credit = np.array([v.solution_value()
                             for v in lp.rps_credit_variables[0]])
      self.assertAlmostEqual(sum(rps_credit), rps)

      rec_storage = storage.rec_storage
      no_rec_storage = storage.no_rec_storage

      npt.assert_almost_equal(rps_credit,
                              rec_storage.source.get_solution_values() *
                              storage.discharge_efficiency)

      npt.assert_almost_equal(self.profiles[DEMAND] - rps_credit,
                              no_rec_storage.source.get_solution_values() *
                              storage.discharge_efficiency)