Example #1
0
  def testSolutionValuesCalledBeforeSolve(self):
    lp = LinearProgramContainer(self.dummy_profile)
    ng = GridSource(NG, 1e6, 1e6)
    lp.add_dispatchable_sources(ng)
    with self.assertRaises(RuntimeError):
      ng.get_solution_values()

    with self.assertRaises(RuntimeError):
      ng.get_nameplate_solution_value()
Example #2
0
class StorageStepTest(unittest.TestCase):

  def setUp(self):
    self.demand_profile = np.array(
        [0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0])

    impulse_profile = np.zeros(len(self.demand_profile))
    impulse_profile[0] = 1.0
    self.impulse = impulse_profile

    rng = pd.date_range('1/1/2011', periods=len(self.demand_profile), freq='H')

    df = pd.DataFrame.from_dict(
        {DEMAND: self.demand_profile,
         SOLAR: impulse_profile,
         TIME: rng}
    )

    self.profiles = df.set_index(TIME,
                                 verify_integrity=True)

    self.lp = LinearProgramContainer(self.profiles)
    self.lp.add_demands(GridDemand(DEMAND))

    self.solar = GridSource(SOLAR, 1e6, 1e6)

  def testRandomSawToothStorage(self):
    lp = self.lp
    solar = self.solar
    lp.add_nondispatchable_sources(solar)
    storage = GridStorage(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)
Example #3
0
class FourTimeSliceRpsTest(unittest.TestCase):

  def setUp(self):
    self.demand_profile = np.array([0.0, 50, 50, 0.0])

    rng = pd.date_range('1/1/2011', periods=len(self.demand_profile), freq='H')

    df = pd.DataFrame.from_dict(
        {DEMAND: self.demand_profile,
         SOLAR: np.array([0.0, 0.0, 0.0, 1.0]),
         WIND: np.array([1.0, 0.0, 0.0, 0.0]),
         TIME: rng}
    )

    self.profiles = df.set_index(TIME,
                                 verify_integrity=True)

    self.lp = LinearProgramContainer(self.profiles)
    self.lp.add_demands(GridDemand(DEMAND))

  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)
Example #4
0
  def testDemandMatchesProfile(self):
    """Verify lp checks for demand profiles."""

    with self.assertRaises(KeyError):
      lp = LinearProgramContainer(self.dummy_profile)
      lp.add_demands(
          GridDemand('Some Demand', 0),
          GridDemand('Other Demand', 1)
      )
      self.assertTrue(lp.solve())
Example #5
0
  def testUnreasonableProfileRejected(self):
    """Verify profile exists."""

    # Test len(profile) == 0 handled properly.
    with self.assertRaises(ValueError):
      unused_lp = LinearProgramContainer(pd.DataFrame())

    # Test profile is None case handled properly.
    with self.assertRaises(ValueError):
      unused_lp = LinearProgramContainer(None)
Example #6
0
  def setUp(self):
    self.demand_profile = np.array([0.0, 50, 50, 0.0])

    rng = pd.date_range('1/1/2011', periods=len(self.demand_profile), freq='H')

    df = pd.DataFrame.from_dict(
        {DEMAND: self.demand_profile,
         SOLAR: np.array([0.0, 0.0, 0.0, 1.0]),
         WIND: np.array([1.0, 0.0, 0.0, 0.0]),
         TIME: rng}
    )

    self.profiles = df.set_index(TIME,
                                 verify_integrity=True)

    self.lp = LinearProgramContainer(self.profiles)
    self.lp.add_demands(GridDemand(DEMAND))
Example #7
0
class FourTimeSliceTest(unittest.TestCase):

  def setUp(self):
    self.demand_profile = np.array([3.0, 0.0, 0.0, 3.0])

    rng = pd.date_range('1/1/2011', periods=len(self.demand_profile), freq='H')

    df = pd.DataFrame.from_dict(
        {DEMAND: self.demand_profile,
         SOLAR: np.array([2.0, 0.0, 0.0, 1.0]),
         WIND: np.array([1.0, 0.0, 0.0, 0.0]),
         TIME: rng}
    )

    self.profiles = df.set_index(TIME,
                                 verify_integrity=True)

    self.lp = LinearProgramContainer(self.profiles)
    self.lp.add_demands(GridDemand(DEMAND))

    self.solar = GridSource(SOLAR, 1e6, 1e6)
    self.ng = GridSource(NG, 1e6, 1e6)
Example #8
0
  def setUp(self):
    self.demand_profile = np.array(
        [0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0])

    impulse_profile = np.zeros(len(self.demand_profile))
    impulse_profile[0] = 1.0
    self.impulse = impulse_profile

    rng = pd.date_range('1/1/2011', periods=len(self.demand_profile), freq='H')

    df = pd.DataFrame.from_dict(
        {DEMAND: self.demand_profile,
         SOLAR: impulse_profile,
         TIME: rng}
    )

    self.profiles = df.set_index(TIME,
                                 verify_integrity=True)

    self.lp = LinearProgramContainer(self.profiles)
    self.lp.add_demands(GridDemand(DEMAND))

    self.solar = GridSource(SOLAR, 1e6, 1e6)
Example #9
0
class TwoTimeSliceTest(unittest.TestCase):
  """Tests with only two time slices."""

  def setUp(self):
    solar_profile = np.array([0.0, 1.0])
    wind_profile = np.array([1.0, 0.0])
    demand_profile = np.array([1.0, 1.0])
    self.demand_profile = demand_profile

    rng = pd.date_range('1/1/2011', periods=len(solar_profile), freq='H')
    df = pd.DataFrame.from_dict(
        {
            SOLAR: solar_profile,
            WIND: wind_profile,
            DEMAND: demand_profile,
            TIME: rng
        }
    )

    self.profiles = df.set_index(TIME,
                                 verify_integrity=True)

    self.lp = LinearProgramContainer(self.profiles)
    self.lp.add_demands(GridDemand(DEMAND))
Example #10
0
  def testDispatchableOnly(self):
    """One Dispatchable Source should fill demand."""

    # Test over a few different profiles
    offset_sin_wave = np.sin(np.linspace(0, 2 * math.pi, 4)) + 2
    profiles = [self.demand_profile,
                np.zeros(4),
                np.ones(4),
                np.arange(4) % 2,  # 0,1,0,1
                offset_sin_wave]

    for profile in profiles:
      lp = LinearProgramContainer(pd.DataFrame({DEMAND: profile}))
      lp.add_demands(GridDemand(DEMAND))

      ng = self.ng
      lp.add_dispatchable_sources(ng)
      self.assertTrue(lp.solve())
      npt.assert_almost_equal(ng.get_solution_values(), profile)

      self.assertAlmostEqual(ng.get_nameplate_solution_value(),
                             max(profile))
Example #11
0
  def testAddNonDispatchableSourceWithoutProfile(self):
    """Ensure NonDispatchable Source without profile gets error."""

    with self.assertRaises(KeyError):
      lp = LinearProgramContainer(self.dummy_profile)
      lp.add_nondispatchable_sources(GridSource(NG, 1e6, 1e6))
Example #12
0
  def testAddDispatchableSourceWithProfile(self):
    """Ensure Dispatchable Source with profile gets error."""

    with self.assertRaises(KeyError):
      lp = LinearProgramContainer(pd.DataFrame({NG: np.ones(4)}))
      lp.add_dispatchable_sources(GridSource(NG, 1e6, 1e6))
Example #13
0
  def testNegative(self):
    """Test Negative is caught."""

    self.df -= 4
    with self.assertRaises(ValueError):
      LinearProgramContainer(self.df)
Example #14
0
  def testNan(self):
    """Test Nan is caught."""

    self.df[self.df > 8] = np.nan
    with self.assertRaises(ValueError):
      LinearProgramContainer(self.df)
Example #15
0
  def testOk(self):
    """Test an okay profile is passed without error."""

    LinearProgramContainer(self.df)