From 40a3ca8d61863476ef71d4f276a71609dc5e0d3b Mon Sep 17 00:00:00 2001 From: Will Usher Date: Tue, 13 Feb 2024 15:27:36 +0100 Subject: [PATCH 1/2] Allow negative emissions, but don't include them in emissions penalty --- src/osemosys.txt | 213 +++++------------------------- tests/test_negative_emissions.txt | 169 ++++++++++++++++++++++++ 2 files changed, 201 insertions(+), 181 deletions(-) create mode 100644 tests/test_negative_emissions.txt diff --git a/src/osemosys.txt b/src/osemosys.txt index 7a13b0b..249f7ac 100644 --- a/src/osemosys.txt +++ b/src/osemosys.txt @@ -23,12 +23,12 @@ # limitations under the License. # ============================================================================ # - - + + # To run OSeMOSYS, enter the following line into your command prompt: # # glpsol -m osemosys.txt -d datafile.txt -o results.txt - + # # ######################################### ###################### Model Definition ############# @@ -78,8 +78,8 @@ param DiscountRateStorage{r in REGION, s in STORAGE}; param DiscountFactorStorage{r in REGION, s in STORAGE, y in YEAR} := (1 + DiscountRateStorage[r, s]) ^ (y - min{yy in YEAR} min(yy) + 0.0); param DiscountFactorMidStorage{r in REGION, s in STORAGE, y in YEAR} := - (1 + DiscountRateStorage[r, s]) ^ (y - min{yy in YEAR} min(yy) + 0.5); - + (1 + DiscountRateStorage[r, s]) ^ (y - min{yy in YEAR} min(yy) + 0.5); + param DaySplit{lh in DAILYTIMEBRACKET, y in YEAR}; param Conversionls{l in TIMESLICE, ls in SEASON} binary; param Conversionld{l in TIMESLICE, ld in DAYTYPE} binary; @@ -156,13 +156,12 @@ param REMinProductionTarget{r in REGION, y in YEAR}; ######### Emissions & Penalties ############# # param EmissionActivityRatio{r in REGION, t in TECHNOLOGY, e in EMISSION, m in MODE_OF_OPERATION, y in YEAR}; -param EmissionsPenalty{r in REGION, e in EMISSION, y in YEAR}; +param EmissionsPenalty{r in REGION, e in EMISSION, y in YEAR} >=0; param AnnualExogenousEmission{r in REGION, e in EMISSION, y in YEAR}; param AnnualEmissionLimit{r in REGION, e in EMISSION, y in YEAR}; param ModelPeriodExogenousEmission{r in REGION, e in EMISSION}; param ModelPeriodEmissionLimit{r in REGION, e in EMISSION}; # - ############## ## ######################################################################## @@ -172,7 +171,7 @@ param ModelPeriodEmissionLimit{r in REGION, e in EMISSION}; ##### 'Capacity investment' check ##### printf "Checking Max and Min capcity-investment bounds for r in REGION, t in TECHNOLOGY, y in YEAR \n"; # -check{r in REGION, t in TECHNOLOGY, y in YEAR:TotalAnnualMaxCapacityInvestment[r, t, y]<>-1 && TotalAnnualMinCapacityInvestment[r, t, y]<>0}: TotalAnnualMaxCapacityInvestment[r, t, y]>=TotalAnnualMinCapacityInvestment[r, t, y]; +check{r in REGION, t in TECHNOLOGY, y in YEAR: TotalAnnualMaxCapacityInvestment[r, t, y]<>-1 && TotalAnnualMinCapacityInvestment[r, t, y]<>0}: TotalAnnualMaxCapacityInvestment[r, t, y]>=TotalAnnualMinCapacityInvestment[r, t, y]; # ##### 'Annual Activity' check ##### printf "Checking Annual activity limits for r in REGION, t in TECHNOLOGY, y in YEAR \n"; @@ -229,10 +228,10 @@ var StorageLevelDayTypeStart{r in REGION, s in STORAGE, ls in SEASON, ld in DAYT var StorageLevelDayTypeFinish{r in REGION, s in STORAGE, ls in SEASON, ld in DAYTYPE, y in YEAR} >=0; var StorageLowerLimit{r in REGION, s in STORAGE, y in YEAR}>=0; var StorageUpperLimit{r in REGION, s in STORAGE, y in YEAR} >=0; - + var AccumulatedNewStorageCapacity{r in REGION, s in STORAGE, y in YEAR} >=0; var NewStorageCapacity{r in REGION, s in STORAGE, y in YEAR} >=0; - + var CapitalInvestmentStorage{r in REGION, s in STORAGE, y in YEAR} >=0; var DiscountedCapitalInvestmentStorage{r in REGION, s in STORAGE, y in YEAR} >=0; var SalvageValueStorage{r in REGION, s in STORAGE, y in YEAR} >=0; @@ -270,23 +269,6 @@ var TradeAnnual{r in REGION, rr in REGION, f in FUEL, y in YEAR}; # var ProductionAnnual{r in REGION, f in FUEL, y in YEAR}>= 0; var UseAnnual{r in REGION, f in FUEL, y in YEAR}>= 0; - - - - - - - - - - - - - - - - - # ######### Costing Variables ############# # @@ -296,12 +278,12 @@ var DiscountedCapitalInvestment{r in REGION, t in TECHNOLOGY, y in YEAR}>= 0; var SalvageValue{r in REGION, t in TECHNOLOGY, y in YEAR}>= 0; var DiscountedSalvageValue{r in REGION, t in TECHNOLOGY, y in YEAR}>= 0; var OperatingCost{r in REGION, t in TECHNOLOGY, y in YEAR}>= 0; - - - + + + var DiscountedOperatingCost{r in REGION, t in TECHNOLOGY, y in YEAR}>= 0; - - + + # var AnnualVariableOperatingCost{r in REGION, t in TECHNOLOGY, y in YEAR}>= 0; var AnnualFixedOperatingCost{r in REGION, t in TECHNOLOGY, y in YEAR}>= 0; @@ -312,7 +294,7 @@ var TotalDiscountedCost{r in REGION, y in YEAR}>= 0; var ModelPeriodCostByRegion{r in REGION} >= 0; # ######### Reserve Margin ############# - + # var TotalCapacityInReserveMargin{r in REGION, y in YEAR}>= 0; var DemandNeedingReserveMargin{r in REGION,l in TIMESLICE, y in YEAR}>= 0; @@ -324,43 +306,20 @@ var RETotalProductionOfTargetFuelAnnual{r in REGION, y in YEAR}; # ######### Emissions ############# # -var AnnualTechnologyEmissionByMode{r in REGION, t in TECHNOLOGY, e in EMISSION, m in MODE_OF_OPERATION, y in YEAR}>=0; -var AnnualTechnologyEmission{r in REGION, t in TECHNOLOGY, e in EMISSION, y in YEAR}>=0; +var AnnualTechnologyEmissionByMode{r in REGION, t in TECHNOLOGY, e in EMISSION, m in MODE_OF_OPERATION, y in YEAR}; +var AnnualTechnologyEmission{r in REGION, t in TECHNOLOGY, e in EMISSION, y in YEAR}; var AnnualTechnologyEmissionPenaltyByEmission{r in REGION, t in TECHNOLOGY, e in EMISSION, y in YEAR}>=0; var AnnualTechnologyEmissionsPenalty{r in REGION, t in TECHNOLOGY, y in YEAR}>=0; var DiscountedTechnologyEmissionsPenalty{r in REGION, t in TECHNOLOGY, y in YEAR}>=0; -var AnnualEmissions{r in REGION, e in EMISSION, y in YEAR}>=0; -var ModelPeriodEmissions{r in REGION, e in EMISSION}>=0; - - - - - -# - - - +var AnnualEmissions{r in REGION, e in EMISSION, y in YEAR}; +var ModelPeriodEmissions{r in REGION, e in EMISSION}; + ###################### # Objective Function # ###################### -# + minimize cost: sum{r in REGION, y in YEAR} TotalDiscountedCost[r,y]; - - - - - - - - - - - - - - - -# + ##################### # Constraints # ##################### @@ -618,21 +577,13 @@ s.t. SI5_DiscountingCapitalInvestmentStorage{r in REGION, s in STORAGE, y in YEA s.t. SI6_SalvageValueStorageAtEndOfPeriod1{r in REGION, s in STORAGE, y in YEAR: (y+OperationalLifeStorage[r,s]-1) <= (max{yy in YEAR} max(yy))}: 0 = SalvageValueStorage[r,s,y]; s.t. SI7_SalvageValueStorageAtEndOfPeriod2{r in REGION, s in STORAGE, y in YEAR: (DepreciationMethod[r]=1 && (y+OperationalLifeStorage[r,s]-1) > (max{yy in YEAR} max(yy)) && DiscountRateStorage[r,s]=0) || (DepreciationMethod[r]=2 && (y+OperationalLifeStorage[r,s]-1) > (max{yy in YEAR} max(yy)))}: CapitalInvestmentStorage[r,s,y]*(1-(max{yy in YEAR} max(yy) - y+1)/OperationalLifeStorage[r,s]) = SalvageValueStorage[r,s,y]; s.t. SI8_SalvageValueStorageAtEndOfPeriod3{r in REGION, s in STORAGE, y in YEAR: DepreciationMethod[r]=1 && (y+OperationalLifeStorage[r,s]-1) > (max{yy in YEAR} max(yy)) && DiscountRateStorage[r,s]>0}: CapitalInvestmentStorage[r,s,y]*(1-(((1+DiscountRateStorage[r,s])^(max{yy in YEAR} max(yy) - y+1)-1)/((1+DiscountRateStorage[r,s])^OperationalLifeStorage[r,s]-1))) = SalvageValueStorage[r,s,y]; - - - - - s.t. SI9_SalvageValueStorageDiscountedToStartYear{r in REGION, s in STORAGE, y in YEAR}: SalvageValueStorage[r,s,y]/((1+DiscountRateStorage[r,s])^(max{yy in YEAR} max(yy)-min{yy in YEAR} min(yy)+1)) = DiscountedSalvageValueStorage[r,s,y]; s.t. SI10_TotalDiscountedCostByStorage{r in REGION, s in STORAGE, y in YEAR}: DiscountedCapitalInvestmentStorage[r,s,y]-DiscountedSalvageValueStorage[r,s,y] = TotalDiscountedStorageCost[r,s,y]; # ######### Capital Costs ############# # s.t. CC1_UndiscountedCapitalInvestment{r in REGION, t in TECHNOLOGY, y in YEAR}: CapitalCost[r,t,y] * NewCapacity[r,t,y] * CapitalRecoveryFactor[r,t] * PvAnnuity[r,t] = CapitalInvestment[r,t,y]; - s.t. CC2_DiscountingCapitalInvestment{r in REGION, t in TECHNOLOGY, y in YEAR}: CapitalInvestment[r,t,y] / DiscountFactor[r,y] = DiscountedCapitalInvestment[r,t,y]; - - # ######### Salvage Value ############# # @@ -664,58 +615,37 @@ s.t. OC4_DiscountedOperatingCostsTotalAnnual{r in REGION, t in TECHNOLOGY, y in OperatingCost[r,t,y] / DiscountFactorMid[r, y] = DiscountedOperatingCost[r,t,y]; - + # ######### Total Discounted Costs ############# # s.t. TDC1_TotalDiscountedCostByTechnology{r in REGION, t in TECHNOLOGY, y in YEAR}: DiscountedOperatingCost[r,t,y]+DiscountedCapitalInvestment[r,t,y]+DiscountedTechnologyEmissionsPenalty[r,t,y]-DiscountedSalvageValue[r,t,y] = TotalDiscountedCostByTechnology[r,t,y]; s.t. TDC2_TotalDiscountedCost{r in REGION, y in YEAR}: sum{t in TECHNOLOGY} TotalDiscountedCostByTechnology[r,t,y]+sum{s in STORAGE} TotalDiscountedStorageCost[r,s,y] = TotalDiscountedCost[r,y]; - + # ######### Total Capacity Constraints ############## # s.t. TCC1_TotalAnnualMaxCapacityConstraint{r in REGION, t in TECHNOLOGY, y in YEAR: TotalAnnualMaxCapacity[r,t,y] <> -1}: TotalCapacityAnnual[r,t,y] <= TotalAnnualMaxCapacity[r,t,y]; - - - - s.t. TCC2_TotalAnnualMinCapacityConstraint{r in REGION, t in TECHNOLOGY, y in YEAR: TotalAnnualMinCapacity[r,t,y]>0}: TotalCapacityAnnual[r,t,y] >= TotalAnnualMinCapacity[r,t,y]; # ######### New Capacity Constraints ############## # s.t. NCC1_TotalAnnualMaxNewCapacityConstraint{r in REGION, t in TECHNOLOGY, y in YEAR: TotalAnnualMaxCapacityInvestment[r,t,y] <> -1}: NewCapacity[r,t,y] <= TotalAnnualMaxCapacityInvestment[r,t,y]; - - - s.t. NCC2_TotalAnnualMinNewCapacityConstraint{r in REGION, t in TECHNOLOGY, y in YEAR: TotalAnnualMinCapacityInvestment[r,t,y]>0}: NewCapacity[r,t,y] >= TotalAnnualMinCapacityInvestment[r,t,y]; # ######### Annual Activity Constraints ############## - - - - - - - - - - # s.t. AAC1_TotalAnnualTechnologyActivity{r in REGION, t in TECHNOLOGY, y in YEAR}: sum{l in TIMESLICE} RateOfTotalActivity[r,t,l,y]*YearSplit[l,y] = TotalTechnologyAnnualActivity[r,t,y]; s.t. AAC2_TotalAnnualTechnologyActivityUpperLimit{r in REGION, t in TECHNOLOGY, y in YEAR: TotalTechnologyAnnualActivityUpperLimit[r,t,y] <> -1}: TotalTechnologyAnnualActivity[r,t,y] <= TotalTechnologyAnnualActivityUpperLimit[r,t,y] ; s.t. AAC3_TotalAnnualTechnologyActivityLowerLimit{r in REGION, t in TECHNOLOGY, y in YEAR: TotalTechnologyAnnualActivityLowerLimit[r,t,y]>0}: TotalTechnologyAnnualActivity[r,t,y] >= TotalTechnologyAnnualActivityLowerLimit[r,t,y] ; # ######### Total Activity Constraints ############## - - # s.t. TAC1_TotalModelHorizonTechnologyActivity{r in REGION, t in TECHNOLOGY}: sum{y in YEAR} TotalTechnologyAnnualActivity[r,t,y] = TotalTechnologyModelPeriodActivity[r,t]; s.t. TAC2_TotalModelHorizonTechnologyActivityUpperLimit{r in REGION, t in TECHNOLOGY: TotalTechnologyModelPeriodActivityUpperLimit[r,t]<>-1}: TotalTechnologyModelPeriodActivity[r,t] <= TotalTechnologyModelPeriodActivityUpperLimit[r,t] ; s.t. TAC3_TotalModelHorizenTechnologyActivityLowerLimit{r in REGION, t in TECHNOLOGY: TotalTechnologyModelPeriodActivityLowerLimit[r,t]>0}: TotalTechnologyModelPeriodActivity[r,t] >= TotalTechnologyModelPeriodActivityLowerLimit[r,t] ; # ######### Reserve Margin Constraint ############## NTS: Should change demand for production - - # s.t. RM1_ReserveMargin_TechnologiesIncluded_In_Activity_Units{r in REGION, l in TIMESLICE, y in YEAR: ReserveMargin[r,y] > 0}: sum {t in TECHNOLOGY} @@ -736,10 +666,6 @@ s.t. RM3_ReserveMargin_Constraint{r in REGION, l in TIMESLICE, y in YEAR: Reserv # ######### RE Production Target ############## NTS: Should change demand for production - - - - # s.t. RE1_FuelProductionByTechnologyAnnual{r in REGION, t in TECHNOLOGY, f in FUEL, y in YEAR}: sum{l in TIMESLICE} ProductionByTechnology[r,l,t,f,y] = ProductionByTechnologyAnnual[r,t,f,y]; s.t. RE2_TechIncluded{r in REGION, y in YEAR}: sum{t in TECHNOLOGY, f in FUEL} ProductionByTechnologyAnnual[r,t,f,y]*RETagTechnology[r,t,y] = TotalREProductionAnnual[r,y]; @@ -748,18 +674,6 @@ s.t. RE4_EnergyConstraint{r in REGION, y in YEAR}:REMinProductionTarget[r,y]*RET s.t. RE5_FuelUseByTechnologyAnnual{r in REGION, t in TECHNOLOGY, f in FUEL, y in YEAR}: sum{l in TIMESLICE} RateOfUseByTechnology[r,l,t,f,y]*YearSplit[l,y] = UseByTechnologyAnnual[r,t,f,y]; # ######### Emissions Accounting ############## - - - - - - - - - - - - # s.t. E1_AnnualEmissionProductionByMode{r in REGION, t in TECHNOLOGY, e in EMISSION, m in MODE_OF_OPERATION, y in YEAR: EmissionActivityRatio[r,t,e,m,y] <> 0}: @@ -773,8 +687,9 @@ s.t. E2_AnnualEmissionProduction{r in REGION, t in TECHNOLOGY, e in EMISSION, y = AnnualTechnologyEmission[r,t,e,y]; -s.t. E3_EmissionsPenaltyByTechAndEmission{r in REGION, t in TECHNOLOGY, e in EMISSION, y in YEAR: EmissionsPenalty[r,e,y] <> 0}: - AnnualTechnologyEmission[r,t,e,y] * EmissionsPenalty[r,e,y] +s.t. E3_EmissionsPenaltyByTechAndEmission{r in REGION, t in TECHNOLOGY, e in EMISSION, y in YEAR}: + sum{m in MODE_OF_OPERATION: EmissionActivityRatio[r,t,e,m,y] > 0} EmissionActivityRatio[r,t,e,m,y] * TotalAnnualTechnologyActivityByMode[r,t,m,y] + * EmissionsPenalty[r,e,y] = AnnualTechnologyEmissionPenaltyByEmission[r,t,e,y]; @@ -811,7 +726,7 @@ s.t. E9_ModelPeriodEmissionsLimit{r in REGION, e in EMISSION: ModelPeriodEmissio # ########################################################################################### # - + # Solve the problem solve; # @@ -823,7 +738,7 @@ solve; # # ######################################################################################################### # - + #### Summary results ### # ### Total costs and emissions by region ### @@ -1140,8 +1055,6 @@ table AccumulatedNewCapacityResults OUT "CSV" ResultsPath & "/AccumulatedNewCapacity.csv" : r~REGION, t~TECHNOLOGY, y~YEAR, AccumulatedNewCapacity[r, t, y]~VALUE; - - table AnnualEmissionsResults {r in REGION, e in EMISSION, y in YEAR: @@ -1150,31 +1063,20 @@ table AnnualEmissionsResults OUT "CSV" ResultsPath & "/AnnualEmissions.csv" : r~REGION, e~EMISSION, y~YEAR, AnnualEmissions[r, e, y]~VALUE; - - table AnnualFixedOperatingCostResults {r in REGION, t in TECHNOLOGY, y in YEAR: AnnualFixedOperatingCost[r, t, y] > 0} - - - OUT "CSV" ResultsPath & "/AnnualFixedOperatingCost.csv" : r~REGION, t~TECHNOLOGY, y~YEAR, AnnualFixedOperatingCost[r, t, y]~VALUE; - - - table AnnualTechnologyEmissionResults {r in REGION, t in TECHNOLOGY, e in EMISSION, y in YEAR: AnnualTechnologyEmission[r, t, e, y] > 0} - OUT "CSV" ResultsPath & "/AnnualTechnologyEmission.csv" : r~REGION, t~TECHNOLOGY, e~EMISSION, y~YEAR, AnnualTechnologyEmission[r, t, e, y]~VALUE; - - table AnnualTechnologyEmissionByModeResults {r in REGION, t in TECHNOLOGY, e in EMISSION, m in MODE_OF_OPERATION, y in YEAR: @@ -1182,18 +1084,13 @@ table AnnualTechnologyEmissionByModeResults OUT "CSV" ResultsPath & "/AnnualTechnologyEmissionByMode.csv" : r~REGION, t~TECHNOLOGY, e~EMISSION, m~MODE_OF_OPERATION, y~YEAR, AnnualTechnologyEmissionByMode[r, t, e, m, y]~VALUE; - - table AnnualVariableOperatingCostResults {r in REGION, t in TECHNOLOGY, y in YEAR: AnnualVariableOperatingCost[r, t, y] > 0} - OUT "CSV" ResultsPath & "/AnnualVariableOperatingCost.csv" : r~REGION, t~TECHNOLOGY, y~YEAR, AnnualVariableOperatingCost[r, t, y]~VALUE; - - table CapitalInvestmentResults {r in REGION, t in TECHNOLOGY, y in YEAR: @@ -1254,22 +1151,18 @@ table NumberOfNewTechnologyUnitsResults table ProductionByTechnologyResults {r in REGION, l in TIMESLICE, t in TECHNOLOGY, f in FUEL, y in YEAR: ProductionByTechnology[r, l, t, f, y] > 0} - OUT "CSV" ResultsPath & "/ProductionByTechnology.csv" : r~REGION, l~TIMESLICE, t~TECHNOLOGY, f~FUEL, y~YEAR, ProductionByTechnology[r, l, t, f, y]~VALUE; - table ProductionByTechnologyAnnualResults {r in REGION, t in TECHNOLOGY, f in FUEL, y in YEAR: ProductionByTechnologyAnnual[r, t, f, y] > 0} - OUT "CSV" ResultsPath & "/ProductionByTechnologyAnnual.csv" : r~REGION, t~TECHNOLOGY, f~FUEL, y~YEAR, ProductionByTechnologyAnnual[r, t, f, y]~VALUE; - table RateOfActivityResults {r in REGION, l in TIMESLICE, t in TECHNOLOGY, m in MODE_OF_OPERATION, y in YEAR: @@ -1277,17 +1170,14 @@ table RateOfActivityResults OUT "CSV" ResultsPath & "/RateOfActivity.csv" : r~REGION, l~TIMESLICE, t~TECHNOLOGY, m~MODE_OF_OPERATION, y~YEAR, RateOfActivity[r, l, t, m, y]~VALUE; - table RateOfProductionByTechnologyResults {r in REGION, l in TIMESLICE, t in TECHNOLOGY, f in FUEL, y in YEAR: RateOfProductionByTechnology[r, l, t, f, y] > 0} - OUT "CSV" ResultsPath & "/RateOfProductionByTechnology.csv" : r~REGION, l~TIMESLICE, t~TECHNOLOGY, f~FUEL, y~YEAR, RateOfProductionByTechnology[r, l, t, f, y]~VALUE; - table RateOfProductionByTechnologyByModeResults {r in REGION, l in TIMESLICE, t in TECHNOLOGY, m in MODE_OF_OPERATION, f in FUEL, y in YEAR: @@ -1300,11 +1190,9 @@ table RateOfProductionByTechnologyByModeResults table RateOfUseByTechnologyResults {r in REGION, l in TIMESLICE, t in TECHNOLOGY, f in FUEL, y in YEAR: RateOfUseByTechnology[r, l, t, f, y] > 0} - OUT "CSV" ResultsPath & "/RateOfUseByTechnology.csv" : r~REGION, l~TIMESLICE, t~TECHNOLOGY, f~FUEL, y~YEAR, - RateOfUseByTechnology[r, l, t, f, y]~VALUE; table RateOfUseByTechnologyByModeResults @@ -1321,7 +1209,6 @@ table SalvageValueResults OUT "CSV" ResultsPath & "/SalvageValue.csv" : r~REGION, t~TECHNOLOGY, y~YEAR, SalvageValue[r, t, y]~VALUE; - table SalvageValueStorageResults {r in REGION, s in STORAGE, y in YEAR: @@ -1329,30 +1216,14 @@ table SalvageValueStorageResults OUT "CSV" ResultsPath & "/SalvageValueStorage.csv" : r~REGION, s~STORAGE, y~YEAR, SalvageValueStorage[r, s, y]~VALUE; - - - - - - - - - - - table TotalAnnualTechnologyActivityByModeResults {r in REGION, t in TECHNOLOGY, m in MODE_OF_OPERATION, y in YEAR: TotalAnnualTechnologyActivityByMode[r, t, m, y] > 0} - - - OUT "CSV" ResultsPath & "/TotalAnnualTechnologyActivityByMode.csv" : r~REGION, t~TECHNOLOGY, m~MODE_OF_OPERATION, y~YEAR, TotalAnnualTechnologyActivityByMode[r, t, m, y]~VALUE; - - table TotalCapacityAnnualResults {r in REGION, t in TECHNOLOGY, y in YEAR: @@ -1368,58 +1239,38 @@ table TotalDiscountedCostResults ResultsPath & "/TotalDiscountedCost.csv" : r~REGION, y~YEAR, TotalDiscountedCost[r, y]~VALUE; - - - - - - - - - - - table TotalTechnologyAnnualActivityResults {r in REGION, t in TECHNOLOGY, y in YEAR: TotalTechnologyAnnualActivity[r, t, y] > 0} - - OUT "CSV" ResultsPath & "/TotalTechnologyAnnualActivity.csv" : r~REGION, t~TECHNOLOGY, y~YEAR, TotalTechnologyAnnualActivity[r, t, y]~VALUE; - + table TotalTechnologyModelPeriodActivityResults {r in REGION, t in TECHNOLOGY: TotalTechnologyModelPeriodActivity[r, t] > 0} - - OUT "CSV" ResultsPath & "/TotalTechnologyModelPeriodActivity.csv" : r~REGION, t~TECHNOLOGY, TotalTechnologyModelPeriodActivity[r, t]~VALUE; - + table TradeResults {r in REGION, rr in REGION, l in TIMESLICE, f in FUEL, y in YEAR: Trade[r, rr, l, f, y] <> 0} - OUT "CSV" ResultsPath & "/Trade.csv" : r~REGION, rr~REGION, l~TIMESLICE, f~FUEL, y~YEAR, Trade[r, rr, l, f, y]~VALUE; - + table UseByTechnologyResults {r in REGION, l in TIMESLICE, t in TECHNOLOGY, f in FUEL, y in YEAR: - UseByTechnology[r, l, t, f, y] > 0} - OUT "CSV" ResultsPath & "/UseByTechnology.csv" : r~REGION, l~TIMESLICE, t~TECHNOLOGY, f~FUEL, y~YEAR, UseByTechnology[r, l, t, f, y]~VALUE; - - end; diff --git a/tests/test_negative_emissions.txt b/tests/test_negative_emissions.txt new file mode 100644 index 0000000..343a60f --- /dev/null +++ b/tests/test_negative_emissions.txt @@ -0,0 +1,169 @@ +set MODE_OF_OPERATION := +1 + +; +param default 0 : AnnualExogenousEmission := +; +param default 0 : AccumulatedAnnualDemand := +; +param default 99999 : TotalAnnualMaxCapacity := +; +param default 1 : CapacityToActivityUnit := +BB gas_plant 1.00 + +; +param default 0 : StorageMaxChargeRate := +; +param default 0.05 : DiscountRate := +; + +param default 0.05 : DiscountRateStorage := +; + +param default 0 : TotalTechnologyAnnualActivityLowerLimit := +; +param default 999 : ResidualStorageCapacity := +; +param default 0 : OutputActivityRatio := +BB gas_import natural_gas 1 2016 1 +BB gas_plant electricity 1 2016 1 + +; +set EMISSION := +CO2 +; +param default 0 : RETagFuel := +; +param default 0 : FixedCost := +BB gas_plant 2016 9.1101 + +; +param default 0 : EmissionActivityRatio := +BB gas_plant CO2 1 2016 -0.516 +; +param default 0 : RETagTechnology := +; +param default 0 : YearSplit := +x 2016 1 + +; +param default 0 : Conversionlh := +; +param default 0.00137 : DaySplit := +; +param default 0 : MinStorageCharge := +; +param default 0 : VariableCost := +BB gas_plant 1 2016 9.1202 + +; +param default 0 : CapitalCostStorage := +; +param default 0 : ResidualCapacity := +BB gas_plant 2016 3.1101 + +; +set DAYTYPE := +; +param default 0 : StorageLevelStart := +; +set TECHNOLOGY := +gas_import + +gas_plant + +; +param default 0 : InputActivityRatio := +BB gas_plant natural_gas 1 2016 1.1101 + +; +param default 1 : OperationalLife := +; +param default 99999 : AnnualEmissionLimit := +; +param default 99999 : ModelPeriodEmissionLimit := +; +param default 99999 : TotalTechnologyAnnualActivityUpperLimit := +; +param default 0 : TechnologyToStorage := +; +param default 0 : ReserveMarginTagFuel := +; +param default 0 : OperationalLifeStorage := +; +set STORAGE := +; +param default 0 : ModelPeriodExogenousEmission := +; +param default 99999 : TotalAnnualMaxCapacityInvestment := +; +param default 0 : SpecifiedDemandProfile := +BB electricity x 2016 1 + +; +param default 0 : TotalAnnualMinCapacity := +; +set YEAR := +2016 + +; +set FUEL := +natural_gas + +electricity + +; +param default 0 : TotalTechnologyModelPeriodActivityLowerLimit := +; +param default 0 : ReserveMarginTagTechnology := +; +param default 0 : StorageMaxDischargeRate := +; +param default 0 : TradeRoute := +; +param default 1 : CapacityFactor := +; +param default 1 : DepreciationMethod := +; +param default 7 : DaysInDayType := +; +param default 0 : Conversionld := +; +param default 0 : Conversionls := +; +set SEASON := +; +set DAILYTIMEBRACKET := +; +param default 1 : AvailabilityFactor := +; +param default 0 : SpecifiedAnnualDemand := +BB electricity 2016 2.1101 + +; +set TIMESLICE := +x + +; +param default 0 : CapitalCost := +; +set REGION := +BB + +; +param default 1 : ReserveMargin := +; +param default 0 : TotalAnnualMinCapacityInvestment := +; +param default 99999 : TotalTechnologyModelPeriodActivityUpperLimit := +; +param default 0 : REMinProductionTarget := +; +param default 0 : CapacityOfOneTechnologyUnit := +; +param default 0 : EmissionsPenalty := +BB CO2 2016 20 +; +param default 0 : TechnologyFromStorage := +; +end; From 2ef9c86eb9203aecddfb142f38b9eb0e2244ece2 Mon Sep 17 00:00:00 2001 From: Will Usher Date: Tue, 13 Feb 2024 15:34:47 +0100 Subject: [PATCH 2/2] Do not count negative emissions for emission penalty --- src/osemosys_fast.txt | 43 +++++++++++++++++++++++------------------- src/osemosys_short.txt | 24 ++++++++++++++--------- 2 files changed, 39 insertions(+), 28 deletions(-) diff --git a/src/osemosys_fast.txt b/src/osemosys_fast.txt index 73d598b..3d36455 100644 --- a/src/osemosys_fast.txt +++ b/src/osemosys_fast.txt @@ -333,14 +333,14 @@ var ModelPeriodEmissions{r in REGION, e in EMISSION}>= 0; ###################### # -minimize cost: sum{r in REGION, t in TECHNOLOGY, y in YEAR} - ((((sum{yy in YEAR: y-yy < OperationalLife[r,t] && y-yy>=0} - NewCapacity[r,t,yy])+ ResidualCapacity[r,t,y])*FixedCost[r,t,y] + - sum{m in MODEperTECHNOLOGY[t], l in TIMESLICE} - RateOfActivity[r,l,t,m,y]*YearSplit[l,y]*VariableCost[r,t,m,y]) / DiscountFactorMid[r,y] + - CapitalCost[r,t,y] * NewCapacity[r,t,y] * CapitalRecoveryFactor[r,t] * PvAnnuity[r,t] / DiscountFactor[r,y] + - DiscountedTechnologyEmissionsPenalty[r,t,y] - DiscountedSalvageValue[r,t,y]) + - sum{r in REGION, s in STORAGE, y in YEAR} (CapitalCostStorage[r,s,y] * NewStorageCapacity[r,s,y] / DiscountFactorStorage[r,s,y] - +minimize cost: sum{r in REGION, t in TECHNOLOGY, y in YEAR} + ((((sum{yy in YEAR: y-yy < OperationalLife[r,t] && y-yy>=0} + NewCapacity[r,t,yy])+ ResidualCapacity[r,t,y])*FixedCost[r,t,y] + + sum{m in MODEperTECHNOLOGY[t], l in TIMESLICE} + RateOfActivity[r,l,t,m,y]*YearSplit[l,y]*VariableCost[r,t,m,y]) / DiscountFactorMid[r,y] + + CapitalCost[r,t,y] * NewCapacity[r,t,y] * CapitalRecoveryFactor[r,t] * PvAnnuity[r,t] / DiscountFactor[r,y] + + DiscountedTechnologyEmissionsPenalty[r,t,y] - DiscountedSalvageValue[r,t,y]) + + sum{r in REGION, s in STORAGE, y in YEAR} (CapitalCostStorage[r,s,y] * NewStorageCapacity[r,s,y] / DiscountFactorStorage[r,s,y] - - SalvageValueStorage[r,s,y] / ((1+DiscountRateStorage[r,s])^(max{yy in YEAR} max(yy)-min{yy in YEAR} min(yy)+1))); # @@ -535,7 +535,12 @@ s.t. RE4_EnergyConstraint{r in REGION, y in YEAR}:REMinProductionTarget[r,y]*sum # ######### Emissions Accounting ############## # -s.t. E5_DiscountedEmissionsPenaltyByTechnology{r in REGION, t in TECHNOLOGY, y in YEAR}: sum{e in EMISSION, l in TIMESLICE, (m,tt) in MODExTECHNOLOGYperEMISSION[e]: t=tt} EmissionActivityRatio[r,t,e,m,y]*RateOfActivity[r,l,t,m,y]*YearSplit[l,y]*EmissionsPenalty[r,e,y]/DiscountFactorMid[r,y] = DiscountedTechnologyEmissionsPenalty[r,t,y]; +s.t. E5_DiscountedEmissionsPenaltyByTechnology +{r in REGION, t in TECHNOLOGY, y in YEAR}: +sum{e in EMISSION, l in TIMESLICE, (m,tt) in MODExTECHNOLOGYperEMISSION[e]: t=tt and EmissionActivityRatio[r,t,e,m,y]>0} +EmissionActivityRatio[r,t,e,m,y] * RateOfActivity[r,l,t,m,y] * YearSplit[l,y] * EmissionsPenalty[r,e,y] / DiscountFactorMid[r,y] += +DiscountedTechnologyEmissionsPenalty[r,t,y]; s.t. E8_AnnualEmissionsLimit{r in REGION, e in EMISSION, y in YEAR: AnnualEmissionLimit[r,e,y] <> -1}: sum{l in TIMESLICE, (m,t) in MODExTECHNOLOGYperEMISSION[e]} EmissionActivityRatio[r,t,e,m,y]*RateOfActivity[r,l,t,m,y]*YearSplit[l,y]+AnnualExogenousEmission[r,e,y] <= AnnualEmissionLimit[r,e,y]; s.t. E9_ModelPeriodEmissionsLimit{r in REGION, e in EMISSION: ModelPeriodEmissionLimit[r,e] <> -1}: sum{l in TIMESLICE, (m,t) in MODExTECHNOLOGYperEMISSION[e], y in YEAR} EmissionActivityRatio[r,t,e,m,y]*RateOfActivity[r,l,t,m,y]*YearSplit[l,y] + ModelPeriodExogenousEmission[r,e] <= ModelPeriodEmissionLimit[r,e] ; #s.t. E1_AnnualEmissionProductionByMode{r in REGION, t in TECHNOLOGY, e in EMISSION, m in MODEperTECHNOLOGY[t], y in YEAR}: EmissionActivityRatio[r,t,e,m,y]*sum{l in TIMESLICE} RateOfActivity[r,l,t,m,y]*YearSplit[l,y]=AnnualTechnologyEmissionByMode[r,t,e,m,y]; @@ -582,22 +587,22 @@ for {r in REGION} { } printf "\n" >> ResultsPath & "/SelectedResults.csv"; printf "Cost" >> ResultsPath & "/SelectedResults.csv"; -for {r in REGION} - {printf ",%g", +for {r in REGION} + {printf ",%g", sum{t in TECHNOLOGY, y in YEAR} ( ( ( ( - (sum{yy in YEAR: y-yy < OperationalLife[r,t] && y-yy>=0} - NewCapacity[r,t,yy]) + ResidualCapacity[r,t,y]) - * FixedCost[r,t,y] + sum{m in MODEperTECHNOLOGY[t], l in TIMESLICE} + (sum{yy in YEAR: y-yy < OperationalLife[r,t] && y-yy>=0} + NewCapacity[r,t,yy]) + ResidualCapacity[r,t,y]) + * FixedCost[r,t,y] + sum{m in MODEperTECHNOLOGY[t], l in TIMESLICE} RateOfActivity[r,l,t,m,y] * YearSplit[l,y] * VariableCost[r,t,m,y]) - / DiscountFactorMid[r,y] - + CapitalCost[r,t,y] * NewCapacity[r,t,y] * CapitalRecoveryFactor[r,t] * PvAnnuity[r,t] / DiscountFactor[r,y] - + DiscountedTechnologyEmissionsPenalty[r,t,y] - DiscountedSalvageValue[r,t,y]) - + sum{s in STORAGE} - (CapitalCostStorage[r,s,y] * NewStorageCapacity[r,s,y] / DiscountFactorStorage[r,s,y] + / DiscountFactorMid[r,y] + + CapitalCost[r,t,y] * NewCapacity[r,t,y] * CapitalRecoveryFactor[r,t] * PvAnnuity[r,t] / DiscountFactor[r,y] + + DiscountedTechnologyEmissionsPenalty[r,t,y] - DiscountedSalvageValue[r,t,y]) + + sum{s in STORAGE} + (CapitalCostStorage[r,s,y] * NewStorageCapacity[r,s,y] / DiscountFactorStorage[r,s,y] - SalvageValueStorage[r,s,y] / ((1+DiscountRateStorage[r,s])^(max{yy in YEAR} max(yy)-min{yy in YEAR} min(yy)+1)))) >> ResultsPath & "/SelectedResults.csv"; } printf "\n" >> ResultsPath & "/SelectedResults.csv"; diff --git a/src/osemosys_short.txt b/src/osemosys_short.txt index 68259f6..34aaab6 100644 --- a/src/osemosys_short.txt +++ b/src/osemosys_short.txt @@ -148,7 +148,7 @@ param REMinProductionTarget{r in REGION, y in YEAR}; ######### Emissions & Penalties ############# # param EmissionActivityRatio{r in REGION, t in TECHNOLOGY, e in EMISSION, m in MODE_OF_OPERATION, y in YEAR}; -param EmissionsPenalty{r in REGION, e in EMISSION, y in YEAR}; +param EmissionsPenalty{r in REGION, e in EMISSION, y in YEAR} >=0; param AnnualExogenousEmission{r in REGION, e in EMISSION, y in YEAR}; param AnnualEmissionLimit{r in REGION, e in EMISSION, y in YEAR}; param ModelPeriodExogenousEmission{r in REGION, e in EMISSION}; @@ -307,15 +307,15 @@ minimize cost: sum{r in REGION, t in TECHNOLOGY, y in YEAR} ( ( (sum{yy in YEAR: y-yy < OperationalLife[r,t] && y-yy>=0} - NewCapacity[r,t,yy]) - + ResidualCapacity[r,t,y]) * FixedCost[r,t,y] + + NewCapacity[r,t,yy]) + + ResidualCapacity[r,t,y]) * FixedCost[r,t,y] + sum{m in MODE_OF_OPERATION, l in TIMESLICE} - RateOfActivity[r,l,t,m,y] * YearSplit[l,y] * VariableCost[r,t,m,y]) + RateOfActivity[r,l,t,m,y] * YearSplit[l,y] * VariableCost[r,t,m,y]) / DiscountFactorMid[r,y] + CapitalCost[r,t,y] * NewCapacity[r,t,y] * CapitalRecoveryFactor[r,t] * PvAnnuity[r,t] / DiscountFactor[r,y] + DiscountedTechnologyEmissionsPenalty[r,t,y] - DiscountedSalvageValue[r,t,y])) + sum{r in REGION, s in STORAGE, y in YEAR} - (CapitalCostStorage[r,s,y] * NewStorageCapacity[r,s,y] / DiscountFactorStorage[r,s,y] + (CapitalCostStorage[r,s,y] * NewStorageCapacity[r,s,y] / DiscountFactorStorage[r,s,y] - SalvageValueStorage[r,s,y] / ((1+DiscountRateStorage[r,s])^(max{yy in YEAR} max(yy)-min{yy in YEAR} min(yy)+1))); # ##################### @@ -368,8 +368,8 @@ s.t. EBb4_EnergyBalanceEachYear4{r in REGION, f in FUEL, y in YEAR}: sum{m in MO #s.t. Acc1_FuelProductionByTechnology{r in REGION, l in TIMESLICE, t in TECHNOLOGY, f in FUEL, y in YEAR}: sum{m in MODE_OF_OPERATION: OutputActivityRatio[r,t,f,m,y] <>0} RateOfActivity[r,l,t,m,y]*OutputActivityRatio[r,t,f,m,y] * YearSplit[l,y] = ProductionByTechnology[r,l,t,f,y]; #s.t. Acc2_FuelUseByTechnology{r in REGION, l in TIMESLICE, t in TECHNOLOGY, f in FUEL, y in YEAR}: sum{m in MODE_OF_OPERATION: InputActivityRatio[r,t,f,m,y]<>0} RateOfActivity[r,l,t,m,y]*InputActivityRatio[r,t,f,m,y] * YearSplit[l,y] = UseByTechnology[r,l,t,f,y]; #s.t. Acc3_AverageAnnualRateOfActivity{r in REGION, t in TECHNOLOGY, m in MODE_OF_OPERATION, y in YEAR}: sum{l in TIMESLICE} RateOfActivity[r,l,t,m,y]*YearSplit[l,y] = TotalAnnualTechnologyActivityByMode[r,t,m,y]; -####s.t. Acc4_ModelPeriodCostByRegion{r in REGION}:sum{t in TECHNOLOGY, y in YEAR}(((((sum{yy in YEAR: y-yy < OperationalLife[r,t] && y-yy>=0} NewCapacity[r,t,yy])+ ResidualCapacity[r,t,y])*FixedCost[r,t,y] + sum{m in MODE_OF_OPERATION, l in TIMESLICE} RateOfActivity[r,l,t,m,y]*YearSplit[l,y]*VariableCost[r,t,m,y])/((DiscountFactorMid[r,y]))+CapitalCost[r,t,y] * NewCapacity[r,t,y]/((DiscountFactor[r,y]))+DiscountedTechnologyEmissionsPenalty[r,t,y]-DiscountedSalvageValue[r,t,y]) + sum{s in STORAGE} (CapitalCostStorage[r,s,y] * NewStorageCapacity[r,s,y] / DiscountFactorStorage[r,s,y] - - SalvageValueStorage[r,s,y] / ((1+DiscountRateStorage[r,s])^(max{yy in YEAR} max(yy)-min{yy in YEAR} min(yy)+1))))= ModelPeriodCostByRegion[r]; +#s.t. Acc4_ModelPeriodCostByRegion{r in REGION}:sum{t in TECHNOLOGY, y in YEAR}(((((sum{yy in YEAR: y-yy < OperationalLife[r,t] && y-yy>=0} NewCapacity[r,t,yy])+ ResidualCapacity[r,t,y])*FixedCost[r,t,y] + sum{m in MODE_OF_OPERATION, l in TIMESLICE} RateOfActivity[r,l,t,m,y]*YearSplit[l,y]*VariableCost[r,t,m,y])/((DiscountFactorMid[r,y]))+CapitalCost[r,t,y] * NewCapacity[r,t,y]/((DiscountFactor[r,y]))+DiscountedTechnologyEmissionsPenalty[r,t,y]-DiscountedSalvageValue[r,t,y]) + sum{s in STORAGE} (CapitalCostStorage[r,s,y] * NewStorageCapacity[r,s,y] / DiscountFactorStorage[r,s,y] +# - SalvageValueStorage[r,s,y] / ((1+DiscountRateStorage[r,s])^(max{yy in YEAR} max(yy)-min{yy in YEAR} min(yy)+1))))= ModelPeriodCostByRegion[r]; # ######### Storage Equations ############# # @@ -496,11 +496,17 @@ s.t. RE4_EnergyConstraint{r in REGION, y in YEAR}:REMinProductionTarget[r,y]*sum # ######### Emissions Accounting ############## # -s.t. E5_DiscountedEmissionsPenaltyByTechnology{r in REGION, t in TECHNOLOGY, y in YEAR}: sum{e in EMISSION, l in TIMESLICE, m in MODE_OF_OPERATION} EmissionActivityRatio[r,t,e,m,y]*RateOfActivity[r,l,t,m,y]*YearSplit[l,y]*EmissionsPenalty[r,e,y]/DiscountFactorMid[r,y] = DiscountedTechnologyEmissionsPenalty[r,t,y]; +s.t. E5_DiscountedEmissionsPenaltyByTechnology + {r in REGION, t in TECHNOLOGY, y in YEAR}: + sum{e in EMISSION, l in TIMESLICE, m in MODE_OF_OPERATION: EmissionActivityRatio[r,t,e,m,y]>0} + EmissionActivityRatio[r,t,e,m,y] * RateOfActivity[r,l,t,m,y] * YearSplit[l,y] * EmissionsPenalty[r,e,y] / DiscountFactorMid[r,y] + = + DiscountedTechnologyEmissionsPenalty[r,t,y]; + s.t. E8_AnnualEmissionsLimit{r in REGION, e in EMISSION, y in YEAR: AnnualEmissionLimit[r,e,y] <> -1}: sum{l in TIMESLICE, t in TECHNOLOGY, m in MODE_OF_OPERATION} EmissionActivityRatio[r,t,e,m,y]*RateOfActivity[r,l,t,m,y]*YearSplit[l,y]+AnnualExogenousEmission[r,e,y] <= AnnualEmissionLimit[r,e,y]; s.t. E9_ModelPeriodEmissionsLimit{r in REGION, e in EMISSION: ModelPeriodEmissionLimit[r,e] <> -1}: sum{l in TIMESLICE, t in TECHNOLOGY, m in MODE_OF_OPERATION, y in YEAR} EmissionActivityRatio[r,t,e,m,y]*RateOfActivity[r,l,t,m,y]*YearSplit[l,y] + ModelPeriodExogenousEmission[r,e] <= ModelPeriodEmissionLimit[r,e] ; #s.t. E1_AnnualEmissionProductionByMode{r in REGION, t in TECHNOLOGY, e in EMISSION, m in MODE_OF_OPERATION, y in YEAR}: EmissionActivityRatio[r,t,e,m,y]*sum{l in TIMESLICE} RateOfActivity[r,l,t,m,y]*YearSplit[l,y]=AnnualTechnologyEmissionByMode[r,t,e,m,y]; -#s.t. E2_AnnualEmissionProduction{r in REGION, t in TECHNOLOGY, e in EMISSION, m in MODE_OF_OPERATION, y in YEAR}: +#s.t. E2_AnnualEmissionProduction{r in REGION, t in TECHNOLOGY, e in EMISSION, m in MODE_OF_OPERATION, y in YEAR}: # sum{l in TIMESLICE, m in MODE_OF_OPERATION: EmissionActivityRatio[r,t,e,m,y]<>0} # EmissionActivityRatio[r,t,e,m,y] * RateOfActivity[r,l,t,m,y]*YearSplit[l,y] # =