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()
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)
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)
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())
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)
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))
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)
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)
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))
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))
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))
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))
def testNegative(self): """Test Negative is caught.""" self.df -= 4 with self.assertRaises(ValueError): LinearProgramContainer(self.df)
def testNan(self): """Test Nan is caught.""" self.df[self.df > 8] = np.nan with self.assertRaises(ValueError): LinearProgramContainer(self.df)
def testOk(self): """Test an okay profile is passed without error.""" LinearProgramContainer(self.df)