def run_esM_with_DSM(timeSeriesAggregation, tBwd, tFwd, numberOfTypicalPeriods=25, numberOfTimeStepsPerPeriod=1): # add DSM dsm_test_esM_ = dsm_test_esM() esM_with = dsm_test_esM_[0] load_without_dsm = dsm_test_esM_[1] shiftMax = 10 esM_with.add( fn.DemandSideManagementBETA(esM=esM_with, name='flexible demand', commodity='electricity', hasCapacityVariable=False, tFwd=tFwd, tBwd=tBwd, operationRateFix=load_without_dsm, opexShift=1, shiftDownMax=shiftMax, shiftUpMax=shiftMax, socOffsetDown=-1, socOffsetUp=-1)) if timeSeriesAggregation: esM_with.cluster(numberOfTimeStepsPerPeriod=numberOfTimeStepsPerPeriod, numberOfTypicalPeriods=numberOfTypicalPeriods) esM_with.optimize(timeSeriesAggregation=True, solver='gurobi', optimizationSpecs='LogToConsole=0') if esM_with.solverSpecs['status'] != 'ok': print(esM_with.solverSpecs['status'], esM_with.solverSpecs['terminationCondition']) print( '\n\nOptimization failed. Try againg with relaxed state of charge formulation (socOffsetDown=socOffsetDown=200)\n\n' ) esM_with.add( fn.DemandSideManagementBETA(esM=esM_with, name='flexible demand', commodity='electricity', hasCapacityVariable=False, tFwd=tFwd, tBwd=tBwd, operationRateFix=load_without_dsm, opexShift=1, shiftDownMax=shiftMax, shiftUpMax=shiftMax, socOffsetDown=200, socOffsetUp=200)) esM_with.optimize(timeSeriesAggregation=True, solver='gurobi', optimizationSpecs='LogToConsole=0') else: esM_with.optimize(timeSeriesAggregation=False, solver='gurobi', optimizationSpecs='LogToConsole=0') if esM_with.solverSpecs['status'] != 'ok': print(esM_with.solverSpecs['status'], esM_with.solverSpecs['terminationCondition']) print( '\n\nOptimization failed. Try againg with relaxed state of charge formulation (socOffsetDown=socOffsetDown=200)\n\n' ) esM_with.add( fn.DemandSideManagementBETA(esM=esM_with, name='flexible demand', commodity='electricity', hasCapacityVariable=False, tFwd=tFwd, tBwd=tBwd, operationRateFix=load_without_dsm, opexShift=1, shiftDownMax=shiftMax, shiftUpMax=shiftMax, socOffsetDown=200, socOffsetUp=200)) esM_with.optimize(timeSeriesAggregation=False, solver='gurobi', optimizationSpecs='LogToConsole=0') generator_outputs = esM_with.componentModelingDict[ "SourceSinkModel"].operationVariablesOptimum esM_load_with_DSM = esM_with.componentModelingDict[ 'DSMModel'].operationVariablesOptimum fig, ax = fn.plotOperation(esM_with, 'cheap', 'location', figsize=(4, 2), fontsize=10) ax.set_title('Cheap generator') fig, ax = fn.plotOperation(esM_with, 'expensive', 'location', figsize=(4, 2), fontsize=10) ax.set_title('Expensive generator') fig, ax = fn.plotOperation(esM_with, 'flexible demand', 'location', figsize=(4, 2), fontsize=10) ax.set_title('Flexible demand') plt.show() c = esM_with.componentModelingDict[ 'StorageExtModel'].chargeOperationVariablesOptimum chargeMax = (pd.concat( [ esM_with.getComponent('flexible demand_' + str(i)).fullChargeOpRateMax.loc[0] for i in range(tBwd + tFwd + 1) ], axis=1, keys=['flexible demand_' + str(i) for i in range(tBwd + tFwd + 1)]).T) plotShift(0, len(c.T), 'Shift profile', timeSeriesAggregation, esM_with, shiftMax=shiftMax, numberOfTimeStepsPerPeriod=numberOfTimeStepsPerPeriod, tBwd=tBwd, tFwd=tFwd)
def test_DSM(dsm_test_esM): """ Given a one-node system with two generators, check whether the load and generation is shifted correctly in both directions with and without demand side management. """ esM_without, load_without_dsm, timestep_up, timestep_down, time_shift, cheap_capacity = dsm_test_esM esM_without.add( fn.Sink(esM=esM_without, name='load', commodity='electricity', hasCapacityVariable=False, operationRateFix=load_without_dsm)) esM_without.optimize(timeSeriesAggregation=False, solver='glpk') # without dsm generator_outputs = esM_without.componentModelingDict[ 'SourceSinkModel'].operationVariablesOptimum # benchmark generation without dsm cheap_without_dsm = load_without_dsm.clip(0, cheap_capacity).copy() cheap_without_dsm.name = ('cheap', 'location') expensive_without_dsm = load_without_dsm - cheap_without_dsm expensive_without_dsm.name = ('expensive', 'location') # test without dsm pd.testing.assert_series_equal( generator_outputs.loc[('cheap', 'location')], cheap_without_dsm) pd.testing.assert_series_equal( generator_outputs.loc[('expensive', 'location')], expensive_without_dsm) # add DSM tFwd = 3 tBwd = 3 esM_with = dsm_test_esM[0] esM_with.removeComponent('load') shiftMax = 10 esM_with.add( fn.DemandSideManagementBETA(esM=esM_with, name='flexible demand', commodity='electricity', hasCapacityVariable=False, tFwd=tFwd, tBwd=tBwd, operationRateFix=load_without_dsm, opexShift=1, shiftDownMax=shiftMax, shiftUpMax=shiftMax, socOffsetDown=-1, socOffsetUp=-1)) esM_with.optimize(timeSeriesAggregation=False, solver='glpk', optimizationSpecs='LogToConsole=0') generator_outputs = esM_with.componentModelingDict[ "SourceSinkModel"].operationVariablesOptimum esM_load_with_DSM = esM_with.componentModelingDict[ 'DSMModel'].operationVariablesOptimum # benchmark generation and load with dsm expensive_with_dsm = expensive_without_dsm.copy() expensive_with_dsm[timestep_up:timestep_up + time_shift] -= 10 expensive_with_dsm[timestep_down - time_shift:timestep_down] -= 10 expensive_with_dsm.name = ('expensive', 'location') cheap_with_dsm = cheap_without_dsm.copy() cheap_with_dsm[timestep_up - time_shift:timestep_up] += 10 cheap_with_dsm[timestep_down:timestep_down + time_shift] += 10 cheap_with_dsm.name = ('cheap', 'location') load_with_dsm = load_without_dsm.copy() load_with_dsm[timestep_up - time_shift:timestep_up] += 10 load_with_dsm[timestep_up:timestep_up + time_shift] -= 10 load_with_dsm[timestep_down - time_shift:timestep_down] -= 10 load_with_dsm[timestep_down:timestep_down + time_shift] += 10 load_with_dsm.name = ('flexible demand', 'location') # test with dsm pd.testing.assert_series_equal( generator_outputs.loc[('cheap', 'location')], cheap_with_dsm) pd.testing.assert_series_equal( generator_outputs.loc[('expensive', 'location')], expensive_with_dsm) pd.testing.assert_series_equal( esM_load_with_DSM.loc[('flexible demand', 'location')], load_with_dsm) esM_with.cluster(numberOfTimeStepsPerPeriod=1, numberOfTypicalPeriods=25) esM_with.optimize(timeSeriesAggregation=True, solver='glpk', optimizationSpecs='LogToConsole=0') # benchmark generation and load with dsm expensive_with_dsm = expensive_without_dsm.copy() expensive_with_dsm[timestep_up:timestep_up + time_shift] -= 10 expensive_with_dsm[timestep_down - time_shift:timestep_down] -= 10 expensive_with_dsm.name = ('expensive', 'location') cheap_with_dsm = cheap_without_dsm.copy() cheap_with_dsm[timestep_up - time_shift:timestep_up] += 10 cheap_with_dsm[timestep_down:timestep_down + time_shift] += 10 cheap_with_dsm.name = ('cheap', 'location') load_with_dsm = load_without_dsm.copy() load_with_dsm[timestep_up - time_shift:timestep_up] += 10 load_with_dsm[timestep_up:timestep_up + time_shift] -= 10 load_with_dsm[timestep_down - time_shift:timestep_down] -= 10 load_with_dsm[timestep_down:timestep_down + time_shift] += 10 load_with_dsm.name = ('flexible demand', 'location') # test with dsm pd.testing.assert_series_equal( generator_outputs.loc[('cheap', 'location')], cheap_with_dsm) pd.testing.assert_series_equal( generator_outputs.loc[('expensive', 'location')], expensive_with_dsm) pd.testing.assert_series_equal( esM_load_with_DSM.loc[('flexible demand', 'location')], load_with_dsm) esM_with.cluster(numberOfTimeStepsPerPeriod=1, numberOfTypicalPeriods=25) esM_with.optimize(timeSeriesAggregation=True, solver='glpk', optimizationSpecs='LogToConsole=0') # benchmark generation and load with dsm expensive_with_dsm = expensive_without_dsm.copy() expensive_with_dsm[timestep_up:timestep_up + time_shift] -= 10 expensive_with_dsm[timestep_down - time_shift:timestep_down] -= 10 expensive_with_dsm.name = ('expensive', 'location') cheap_with_dsm = cheap_without_dsm.copy() cheap_with_dsm[timestep_up - time_shift:timestep_up] += 10 cheap_with_dsm[timestep_down:timestep_down + time_shift] += 10 cheap_with_dsm.name = ('cheap', 'location') load_with_dsm = load_without_dsm.copy() load_with_dsm[timestep_up - time_shift:timestep_up] += 10 load_with_dsm[timestep_up:timestep_up + time_shift] -= 10 load_with_dsm[timestep_down - time_shift:timestep_down] -= 10 load_with_dsm[timestep_down:timestep_down + time_shift] += 10 load_with_dsm.name = ('flexible demand', 'location') # test with dsm pd.testing.assert_series_equal( generator_outputs.loc[('cheap', 'location')], cheap_with_dsm) pd.testing.assert_series_equal( generator_outputs.loc[('expensive', 'location')], expensive_with_dsm) pd.testing.assert_series_equal( esM_load_with_DSM.loc[('flexible demand', 'location')], load_with_dsm)
def run_esM_with_DSM( timeSeriesAggregation, tBwd, tFwd, numberOfTypicalPeriods=25, numberOfTimeStepsPerPeriod=1, ): # add DSM dsm_test_esM_ = dsm_test_esM() esM_with = dsm_test_esM_[0] load_without_dsm = dsm_test_esM_[1] shiftMax = 10 esM_with.add( fn.DemandSideManagementBETA( esM=esM_with, name="flexible demand", commodity="electricity", hasCapacityVariable=False, tFwd=tFwd, tBwd=tBwd, operationRateFix=load_without_dsm, opexShift=1, shiftDownMax=shiftMax, shiftUpMax=shiftMax, socOffsetDown=-1, socOffsetUp=-1, ) ) if timeSeriesAggregation: esM_with.cluster( numberOfTimeStepsPerPeriod=numberOfTimeStepsPerPeriod, numberOfTypicalPeriods=numberOfTypicalPeriods, ) esM_with.optimize(timeSeriesAggregation=True) if esM_with.solverSpecs["status"] != "ok": print( esM_with.solverSpecs["status"], esM_with.solverSpecs["terminationCondition"], ) print( "\n\nOptimization failed. Try againg with relaxed state of charge formulation (socOffsetDown=socOffsetDown=200)\n\n" ) esM_with.add( fn.DemandSideManagementBETA( esM=esM_with, name="flexible demand", commodity="electricity", hasCapacityVariable=False, tFwd=tFwd, tBwd=tBwd, operationRateFix=load_without_dsm, opexShift=1, shiftDownMax=shiftMax, shiftUpMax=shiftMax, socOffsetDown=200, socOffsetUp=200, ) ) esM_with.optimize(timeSeriesAggregation=True) else: esM_with.optimize( timeSeriesAggregation=False, ) if esM_with.solverSpecs["status"] != "ok": print( esM_with.solverSpecs["status"], esM_with.solverSpecs["terminationCondition"], ) print( "\n\nOptimization failed. Try againg with relaxed state of charge formulation (socOffsetDown=socOffsetDown=200)\n\n" ) esM_with.add( fn.DemandSideManagementBETA( esM=esM_with, name="flexible demand", commodity="electricity", hasCapacityVariable=False, tFwd=tFwd, tBwd=tBwd, operationRateFix=load_without_dsm, opexShift=1, shiftDownMax=shiftMax, shiftUpMax=shiftMax, socOffsetDown=200, socOffsetUp=200, ) ) esM_with.optimize( timeSeriesAggregation=False, ) generator_outputs = esM_with.componentModelingDict[ "SourceSinkModel" ].operationVariablesOptimum esM_load_with_DSM = esM_with.componentModelingDict[ "DSMModel" ].operationVariablesOptimum fig, ax = fn.plotOperation( esM_with, "cheap", "location", figsize=(4, 2), fontsize=10 ) ax.set_title("Cheap generator") fig, ax = fn.plotOperation( esM_with, "expensive", "location", figsize=(4, 2), fontsize=10 ) ax.set_title("Expensive generator") fig, ax = fn.plotOperation( esM_with, "flexible demand", "location", figsize=(4, 2), fontsize=10 ) ax.set_title("Flexible demand") plt.show() c = esM_with.componentModelingDict[ "StorageExtModel" ].chargeOperationVariablesOptimum chargeMax = pd.concat( [ esM_with.getComponent("flexible demand_" + str(i)).fullChargeOpRateMax.loc[ 0 ] for i in range(tBwd + tFwd + 1) ], axis=1, keys=["flexible demand_" + str(i) for i in range(tBwd + tFwd + 1)], ).T plotShift( 0, len(c.T), "Shift profile", timeSeriesAggregation, esM_with, shiftMax=shiftMax, numberOfTimeStepsPerPeriod=numberOfTimeStepsPerPeriod, tBwd=tBwd, tFwd=tFwd, )