def test_price_duality(test_mp): years = [2020, 2025, 2030, 2040, 2050] for c in [0.25, 0.5, 0.75]: # set up a scenario for cumulative constraints scen = Scenario(test_mp, MODEL, "cum_many_tecs", version="new") model_setup(scen, years, simple_tecs=False) scen.add_cat("year", "cumulative", years) scen.add_par("bound_emission", ["World", "ghg", "all", "cumulative"], 0.5, "tCO2") scen.commit("initialize test scenario") scen.solve() # set up a new scenario with emissions taxes tax_scen = Scenario(test_mp, MODEL, "tax_many_tecs", version="new") model_setup(tax_scen, years, simple_tecs=False) for y in years: tax_scen.add_cat("year", y, y) # use emission prices from cumulative-constraint scenario as taxes taxes = scen.var("PRICE_EMISSION").rename(columns={ "year": "type_year", "lvl": "value" }) taxes["unit"] = "USD/tCO2" tax_scen.add_par("tax_emission", taxes) tax_scen.commit("initialize test scenario for taxes") tax_scen.solve() # check that emissions are close between cumulative and tax scenario filters = {"node": "World"} emiss = scen.var("EMISS", filters).set_index("year").lvl emiss_tax = tax_scen.var("EMISS", filters).set_index("year").lvl npt.assert_allclose(emiss, emiss_tax, rtol=0.20)
def base_scen_mp(test_mp): scen = Scenario(test_mp, 'model', 'standard', version='new') data = {2020: 1, 2030: 2, 2040: 3} years = sorted(list(set(data.keys()))) scen.add_set('node', 'node') scen.add_set('commodity', 'comm') scen.add_set('level', 'level') scen.add_set('year', years) scen.add_set('technology', 'tec') scen.add_set('mode', 'mode') output_specs = ['node', 'comm', 'level', 'year', 'year'] for (yr, value) in data.items(): scen.add_par('demand', ['node', 'comm', 'level', yr, 'year'], 1, 'GWa') scen.add_par('technical_lifetime', ['node', 'tec', yr], 10, 'y') tec_specs = ['node', 'tec', yr, yr, 'mode'] scen.add_par('output', tec_specs + output_specs, 1, '-') scen.add_par('var_cost', tec_specs + ['year'], value, 'USD/GWa') scen.commit('initialize test model') scen.solve(case='original_years') yield scen, test_mp
def test_new_timeseries_long_name64plus(message_test_mp): scen = Scenario(message_test_mp, **SCENARIO["dantzig multi-year"]) scen = scen.clone(keep_solution=False) scen.check_out(timeseries_only=True) df = pd.DataFrame( { "region": [ "India", ], "variable": [ ( "Emissions|CO2|Energy|Demand|Transportation|Aviation|" "Domestic|Freight|Oil" ), ], "unit": [ "Mt CO2/yr", ], "2012": [ 0.257009, ], } ) scen.add_timeseries(df) scen.commit("importing a testing timeseries")
def base_scen_mp(test_mp): scen = Scenario(test_mp, "model", "standard", version="new") data = {2020: 1, 2030: 2, 2040: 3} years = sorted(list(set(data.keys()))) scen.add_set("node", "node") scen.add_set("commodity", "comm") scen.add_set("level", "level") scen.add_set("year", years) scen.add_set("technology", "tec") scen.add_set("mode", "mode") output_specs = ["node", "comm", "level", "year", "year"] for (yr, value) in data.items(): scen.add_par("demand", ["node", "comm", "level", yr, "year"], 1, "GWa") scen.add_par("technical_lifetime", ["node", "tec", yr], 10, "y") tec_specs = ["node", "tec", yr, yr, "mode"] scen.add_par("output", tec_specs + output_specs, 1, "-") scen.add_par("var_cost", tec_specs + ["year"], value, "USD/GWa") scen.commit("initialize test model") scen.solve(case="original_years", quiet=True) yield scen, test_mp
def test_bound_emission_year(test_mp): scen = Scenario(test_mp, "test_bound_emission", "standard", version="new") model_setup(scen, [2020, 2030]) scen.commit("initialize test model") add_bound_emission(scen, bound=1.250, year=2020) scen.solve(case="bound_emission_year") assert_function(scen, year=2020)
def test_price_duality(test_mp): years = [2020, 2025, 2030, 2040, 2050] for c in [0.25, 0.5, 0.75]: # set up a scenario for cumulative constraints scen = Scenario(test_mp, MODEL, 'cum_many_tecs', version='new') model_setup(scen, years, simple_tecs=False) scen.add_cat('year', 'cumulative', years) scen.add_par('bound_emission', ['World', 'ghg', 'all', 'cumulative'], 0.5, 'tCO2') scen.commit('initialize test scenario') scen.solve() # set up a new scenario with emissions taxes tax_scen = Scenario(test_mp, MODEL, 'tax_many_tecs', version='new') model_setup(tax_scen, years, simple_tecs=False) for y in years: tax_scen.add_cat('year', y, y) # use emission prices from cumulative-constraint scenario as taxes taxes = scen.var('PRICE_EMISSION')\ .rename(columns={'year': 'type_year', 'lvl': 'value'}) taxes['unit'] = 'USD/tCO2' tax_scen.add_par('tax_emission', taxes) tax_scen.commit('initialize test scenario for taxes') tax_scen.solve() # check that emissions are close between cumulative and tax scenario filters = {'node': 'World'} emiss = scen.var('EMISS', filters).set_index('year').lvl emiss_tax = tax_scen.var('EMISS', filters).set_index('year').lvl npt.assert_allclose(emiss, emiss_tax, rtol=0.20)
def test_bound_emission_5y(test_mp): scen = Scenario(test_mp, "test_bound_emission", "standard", version="new") model_setup(scen, [2020, 2025, 2030, 2040]) scen.commit("initialize test model") add_bound_emission(scen, bound=1.250) scen.solve(case="bound_emission_5y", quiet=True) assert_function(scen, year="cumulative")
def test_bound_emission_5y(test_mp): scen = Scenario(test_mp, 'test_bound_emission', 'standard', version='new') model_setup(scen, [2020, 2025, 2030, 2040]) scen.commit('initialize test model') add_bound_emission(scen, bound=1.250) scen.solve(case='bound_emission_5y') assert_function(scen, year='cumulative')
def test_commodity_price(test_mp): scen = Scenario(test_mp, 'test_commodity_price', 'standard', version='new') model_setup(scen) scen.commit('initialize test model') scen.solve(case='price_commodity_standard') assert scen.var('OBJ')['lvl'] == 1 assert scen.var('PRICE_COMMODITY')['lvl'][0] == 1
def test_commodity_price(test_mp): scen = Scenario(test_mp, "test_commodity_price", "standard", version="new") model_setup(scen) scen.commit("initialize test model") scen.solve(case="price_commodity_standard") assert scen.var("OBJ")["lvl"] == 1 assert scen.var("PRICE_COMMODITY")["lvl"][0] == 1
def test_init(test_mp): scen = Scenario(test_mp, *msg_args) scen = scen.clone('foo', 'bar') scen.check_out() macro.init(scen) scen.commit('foo') scen.solve() assert np.isclose(scen.var('OBJ')['lvl'], 153.675)
def test_no_constraint(test_mp): scen = Scenario(test_mp, MODEL, 'no_constraint', version='new') model_setup(scen, [2020, 2030]) scen.commit('initialize test scenario') scen.solve() # without emissions constraint, the zero-cost technology satisfies demand assert scen.var('OBJ')['lvl'] == 0 # without emissions constraint, there are no emission prices assert scen.var('PRICE_EMISSION').empty
def test_no_constraint(test_mp): scen = Scenario(test_mp, MODEL, "no_constraint", version="new") model_setup(scen, [2020, 2030]) scen.commit("initialize test scenario") scen.solve(quiet=True) # without emissions constraint, the zero-cost technology satisfies demand assert scen.var("OBJ")["lvl"] == 0 # without emissions constraint, there are no emission prices assert scen.var("PRICE_EMISSION").empty
def test_init(test_mp): scen = Scenario(test_mp, *msg_args) obs = scen.var('OBJ')['lvl'] scen = scen.clone('foo', 'bar', keep_solution=False) scen.check_out() macro.init(scen) scen.commit('foo') scen.solve() exp = scen.var('OBJ')['lvl'] assert np.isclose(obs, exp)
def test_new_timeseries_long_name64plus(test_mp): scen = Scenario(test_mp, *msg_multiyear_args) scen = scen.clone(keep_solution=False) scen.check_out(timeseries_only=True) df = pd.DataFrame({ 'region': ['India', ], 'variable': [('Emissions|CO2|Energy|Demand|Transportation|Aviation|' 'Domestic|Freight|Oil'), ], 'unit': ['Mt CO2/yr', ], '2012': [0.257009, ] }) scen.add_timeseries(df) scen.commit('importing a testing timeseries')
def test_add_year(test_mp): scen_ref = Scenario(test_mp, 'model', 'standard', version='new') model_setup(scen_ref, {2020: 1, 2030: 2, 2040: 3}) scen_ref.commit('initialize test model') scen_ref.solve(case='original_years') # Adding new years years_new = [2025, 2035] scen_new = adding_years(test_mp, scen_ref, years_new) scen_new.solve(case='new_years') # Running the tests assert_function(scen_ref, scen_new, years_new, yr_test=2025)
def test_addon_up(test_mp): scen = Scenario(test_mp, *msg_args).clone(scenario='addon_up', keep_solution=False) add_addon(scen, costs=-1, zero_output=True) scen.check_out() scen.add_par('addon_up', addon_share) scen.commit('adding upper bound on addon technology') scen.solve() exp = scen.var('ACT', f)['lvl'] * 0.5 obs = scen.var('ACT', g)['lvl'] assert np.isclose(exp, obs)
def test_init(message_test_mp): scen = Scenario(message_test_mp, **SCENARIO["dantzig"]) scen = scen.clone("foo", "bar") scen.check_out() MACRO.initialize(scen) scen.commit("foo") scen.solve(quiet=True) assert np.isclose(scen.var("OBJ")["lvl"], 153.675) assert "mapping_macro_sector" in scen.set_list() assert "aeei" in scen.par_list() assert "DEMAND" in scen.var_list() assert "COST_ACCOUNTING_NODAL" in scen.equ_list()
def test_init(message_test_mp): scen = Scenario(message_test_mp, **SCENARIO['dantzig']) scen = scen.clone('foo', 'bar') scen.check_out() MACRO.initialize(scen) scen.commit('foo') scen.solve() assert np.isclose(scen.var('OBJ')['lvl'], 153.675) assert 'mapping_macro_sector' in scen.set_list() assert 'aeei' in scen.par_list() assert 'DEMAND' in scen.var_list() assert 'COST_ACCOUNTING_NODAL' in scen.equ_list()
def test_addon_lo(message_test_mp): scen = Scenario(message_test_mp, **SCENARIO['dantzig']) \ .clone(scenario='addon_lo', keep_solution=False) add_addon(scen, costs=1, zero_output=True) scen.check_out() scen.add_par('addon_lo', addon_share) scen.commit('adding lower bound on addon technology') scen.solve() exp = scen.var('ACT', f)['lvl'] * 0.5 obs = scen.var('ACT', g)['lvl'] assert np.isclose(exp, obs)
def test_addon_up(message_test_mp): scen = Scenario(message_test_mp, **SCENARIO["dantzig"]).clone(scenario="addon_up", keep_solution=False) add_addon(scen, costs=-1, zero_output=True) scen.check_out() scen.add_par("addon_up", addon_share) scen.commit("adding upper bound on addon technology") scen.solve() exp = scen.var("ACT", f)["lvl"] * 0.5 obs = scen.var("ACT", g)["lvl"] assert np.isclose(exp, obs)
def test_per_period_equidistant(test_mp): scen = Scenario(test_mp, MODEL, 'per_period_equidistant', version='new') years = [2020, 2030, 2040] model_setup(scen, years) for y in years: scen.add_cat('year', y, y) scen.add_par('bound_emission', ['World', 'ghg', 'all', y], 0, 'tCO2') scen.commit('initialize test scenario') scen.solve() # with emissions constraint, the technology with costs satisfies demand assert scen.var('OBJ')['lvl'] > 0 # under per-year emissions constraints, the emission price must be equal to # the marginal relaxation, ie. the difference in costs between technologies npt.assert_allclose(scen.var('PRICE_EMISSION')['lvl'], [1] * 3)
def test_per_period_equidistant(test_mp): scen = Scenario(test_mp, MODEL, "per_period_equidistant", version="new") years = [2020, 2030, 2040] model_setup(scen, years) for y in years: scen.add_cat("year", y, y) scen.add_par("bound_emission", ["World", "ghg", "all", y], 0, "tCO2") scen.commit("initialize test scenario") scen.solve() # with emissions constraint, the technology with costs satisfies demand assert scen.var("OBJ")["lvl"] > 0 # under per-year emissions constraints, the emission price must be equal to # the marginal relaxation, ie. the difference in costs between technologies npt.assert_allclose(scen.var("PRICE_EMISSION")["lvl"], [1] * 3)
def test_commodity_price_equality(test_mp): scen = Scenario(test_mp, "test_commodity_price", "equality", version="new") model_setup(scen, var_cost=-1) scen.commit("initialize test model with negative variable costs") # negative variable costs and supply >= demand causes an unbounded ray pytest.raises(CalledProcessError, scen.solve) # use the commodity-balance equality feature scen.check_out() scen.add_set("balance_equality", ["comm", "level"]) scen.commit("set commodity-balance for `[comm, level]` as equality") scen.solve(case="price_commodity_equality") assert scen.var("OBJ")["lvl"] == -1 assert scen.var("PRICE_COMMODITY")["lvl"][0] == -1
def test_commodity_price_equality(test_mp): scen = Scenario(test_mp, 'test_commodity_price', 'equality', version='new') model_setup(scen, var_cost=-1) scen.commit('initialize test model with negative variable costs') # negative variable costs and supply >= demand causes an unbounded ray pytest.raises(CalledProcessError, scen.solve) # use the commodity-balance equality feature scen.check_out() scen.add_set('balance_equality', ['comm', 'level']) scen.commit('set commodity-balance for `[comm, level]` as equality') scen.solve(case='price_commodity_equality') assert scen.var('OBJ')['lvl'] == -1 assert scen.var('PRICE_COMMODITY')['lvl'][0] == -1
def test_cumulative_equidistant(test_mp): scen = Scenario(test_mp, MODEL, "cum_equidistant", version="new") years = [2020, 2030, 2040] model_setup(scen, years) scen.add_cat("year", "cumulative", years) scen.add_par("bound_emission", ["World", "ghg", "all", "cumulative"], 0, "tCO2") scen.commit("initialize test scenario") scen.solve(quiet=True) # with emissions constraint, the technology with costs satisfies demand assert scen.var("OBJ")["lvl"] > 0 # under a cumulative constraint, the price must increase with the discount # rate starting from the marginal relaxation in the first year obs = scen.var("PRICE_EMISSION")["lvl"].values npt.assert_allclose(obs, [1.05 ** (y - years[0]) for y in years])
def test_cumulative_equidistant(test_mp): scen = Scenario(test_mp, MODEL, 'cum_equidistant', version='new') years = [2020, 2030, 2040] model_setup(scen, years) scen.add_cat('year', 'cumulative', years) scen.add_par('bound_emission', ['World', 'ghg', 'all', 'cumulative'], 0, 'tCO2') scen.commit('initialize test scenario') scen.solve() # with emissions constraint, the technology with costs satisfies demand assert scen.var('OBJ')['lvl'] > 0 # under a cumulative constraint, the price must increase with the discount # rate starting from the marginal relaxation in the first year obs = scen.var('PRICE_EMISSION')['lvl'].values npt.assert_allclose(obs, [1.05**(y - years[0]) for y in years])
def test_addon_tec(test_mp): scen = Scenario(test_mp, *msg_args).clone(scenario='addon', keep_solution=False) add_addon(scen, costs=-1) scen.check_out() bda = scen.par('bound_activity_up', f) bda['value'] = bda['value'] / 2 scen.add_par('bound_activity_up', bda) scen.commit('changing output and bounds') scen.solve() exp = scen.var('ACT', f)['lvl'] obs = scen.var('ACT', g)['lvl'] assert np.isclose(exp, obs)
def test_excel_read_write(test_mp): fname = 'test_excel_read_write.xlsx' scen1 = Scenario(test_mp, *msg_args) scen1.to_excel(fname) scen2 = Scenario(test_mp, model='foo', scenario='bar', version='new') scen2.read_excel(fname) exp = scen1.par('input') obs = scen2.par('input') pdt.assert_frame_equal(exp, obs) scen2.commit('foo') # must be checked in scen2.solve() assert np.isclose(scen2.var('OBJ')['lvl'], 153.675) os.remove(fname)
def test_addon_tec(message_test_mp): scen = Scenario(message_test_mp, **SCENARIO["dantzig"]).clone(scenario="addon", keep_solution=False) add_addon(scen, costs=-1) scen.check_out() bda = scen.par("bound_activity_up", f) bda["value"] = bda["value"] / 2 scen.add_par("bound_activity_up", bda) scen.commit("changing output and bounds") scen.solve() exp = scen.var("ACT", f)["lvl"] obs = scen.var("ACT", g)["lvl"] assert np.isclose(exp, obs)