Beispiel #1
0
def test_add_bound_activity_up(test_mp):
    scen = Scenario(test_mp, *msg_args)
    scen.solve()

    # data for act bound
    exp = 0.5 * calculate_activity(scen).sum()
    data = pd.DataFrame({
        'node_loc': 'seattle',
        'technology': 'transport_from_seattle',
        'year_act': 2010,
        'time': 'year',
        'unit': 'cases',
        'mode': 'to_chicago',
        'value': exp,
    }, index=[0])

    # test limiting one mode
    clone = scen.clone('foo', 'bar', keep_solution=False)
    clone.check_out()
    clone.add_par('bound_activity_up', data)
    clone.commit('foo')
    clone.solve()
    obs = calculate_activity(clone).loc['to_chicago']
    assert np.isclose(obs, exp)

    orig_obj = scen.var('OBJ')['lvl']
    new_obj = clone.var('OBJ')['lvl']
    assert new_obj >= orig_obj
Beispiel #2
0
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)
Beispiel #3
0
def test_solve_modified(caplog, message_test_mp):
    base = Scenario(message_test_mp, **SCENARIO["dantzig"])

    # Base objective value
    base.solve()
    base_obj = base.var("OBJ")["lvl"]

    with solve_modified(base, "new scenario name") as scenario:
        # Scenario is not yet solved
        assert not scenario.has_solution()

        # Scenario has the indicated new name
        assert "new scenario name" == scenario.scenario

        # Change one demand parameter from 325 to 326
        scenario.add_par(
            "demand",
            make_df(
                "demand",
                node=["new-york"],
                commodity=["cases"],
                level="consumption",
                year=1963,
                time="year",
                value=326,
                unit="case",
            ),
        )

    # Scenario is solved at the end of the with: statement
    assert scenario.has_solution()

    assert scenario.var("OBJ")["lvl"] != base_obj
Beispiel #4
0
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_add_bound_activity_up_all_modes(message_test_mp):
    scen = Scenario(message_test_mp, **SCENARIO["dantzig"]).clone()
    scen.solve(quiet=True)

    # data for act bound
    exp = 0.95 * calculate_activity(scen).sum()
    data = pd.DataFrame(
        {
            "node_loc": "seattle",
            "technology": "transport_from_seattle",
            "year_act": _year,
            "time": "year",
            "unit": "cases",
            "mode": "all",
            "value": exp,
        },
        index=[0],
    )

    # test limiting all modes
    clone = scen.clone("foo", "baz", keep_solution=False)
    clone.check_out()
    clone.add_par("bound_activity_up", data)
    clone.commit("foo")
    clone.solve()
    obs = calculate_activity(clone).sum()
    assert np.isclose(obs, exp)

    orig_obj = scen.var("OBJ")["lvl"]
    new_obj = clone.var("OBJ")["lvl"]
    assert new_obj >= orig_obj
Beispiel #6
0
def test_add_bound_activity_up_all_modes(message_test_mp):
    scen = Scenario(message_test_mp, **SCENARIO['dantzig']).clone()
    scen.solve()

    # data for act bound
    exp = 0.95 * calculate_activity(scen).sum()
    data = pd.DataFrame(
        {
            'node_loc': 'seattle',
            'technology': 'transport_from_seattle',
            'year_act': _year,
            'time': 'year',
            'unit': 'cases',
            'mode': 'all',
            'value': exp,
        },
        index=[0])

    # test limiting all modes
    clone = scen.clone('foo', 'baz', keep_solution=False)
    clone.check_out()
    clone.add_par('bound_activity_up', data)
    clone.commit('foo')
    clone.solve()
    obs = calculate_activity(clone).sum()
    assert np.isclose(obs, exp)

    orig_obj = scen.var('OBJ')['lvl']
    new_obj = clone.var('OBJ')['lvl']
    assert new_obj >= orig_obj
def test_solve_legacy_scenario(test_legacy_mp):
    scen = Scenario(test_legacy_mp, *msg_args)
    exp = scen.var('OBJ')['lvl']

    # solve scenario, assert that the new objective value is close to previous
    scen.remove_solution()
    scen.solve()
    assert np.isclose(exp, scen.var('OBJ')['lvl'])
Beispiel #8
0
def test_share_commodity_lo(test_mp):
    scen = Scenario(test_mp, *msg_args)
    scen.solve()

    # data for share bound
    def calc_share(s):
        a = calculate_activity(
            s, tec='transport_from_seattle').loc['to_new-york']
        b = calculate_activity(
            s, tec='transport_from_san-diego').loc['to_new-york']
        return a / (a + b)

    exp = 1. * calc_share(scen)

    # add share constraints
    clone = scen.clone(scenario='share_commodity_lo', keep_solution=False)
    clone.check_out()
    clone.add_cat('technology', 'share', 'transport_from_seattle')
    clone.add_cat('technology', 'total', ['transport_from_seattle',
                                          'transport_from_san-diego'])
    clone.add_set('shares', 'test-share')
    clone.add_set('map_shares_commodity_share',
                  pd.DataFrame({
                      'shares': 'test-share',
                      'node_share': 'new-york',
                      'node': 'new-york',
                      'type_tec': 'share',
                      'mode': 'all',
                      'commodity': 'cases',
                      'level': 'consumption',
                  }, index=[0]))
    clone.add_set('map_shares_commodity_total',
                  pd.DataFrame({
                      'shares': 'test-share',
                      'node_share': 'new-york',
                      'node': 'new-york',
                      'type_tec': 'total',
                      'mode': 'all',
                      'commodity': 'cases',
                      'level': 'consumption',
                  }, index=[0]))
    clone.add_par('share_commodity_lo',
                  pd.DataFrame({
                      'shares': 'test-share',
                      'node_share': 'new-york',
                      'year_act': 2010,
                      'time': 'year',
                      'unit': 'cases',
                      'value': exp,
                  }, index=[0]))
    clone.commit('foo')
    clone.solve()
    obs = calc_share(clone)
    assert np.isclose(obs, exp)

    orig_obj = scen.var('OBJ')['lvl']
    new_obj = clone.var('OBJ')['lvl']
    assert new_obj >= orig_obj
Beispiel #9
0
def test_reporter(test_mp):
    scen = Scenario(test_mp,
                    'canning problem (MESSAGE scheme)',
                    'standard')

    # Varies between local & CI contexts
    # DEBUG may be due to reuse of test_mp in a non-deterministic order
    if not scen.has_solution():
        scen.solve()

    # IXMPReporter can be initialized on a MESSAGE Scenario
    rep_ix = ixmp_Reporter.from_scenario(scen)

    # message_ix.Reporter can also be initialized
    rep = Reporter.from_scenario(scen)

    # Number of quantities available in a rudimentary MESSAGEix Scenario
    assert len(rep.graph['all']) == 120

    # Quantities have short dimension names
    assert 'demand:n-c-l-y-h' in rep.graph

    # Aggregates are available
    assert 'demand:n-l-h' in rep.graph

    # Quantities contain expected data
    dims = dict(coords=['chicago new-york topeka'.split()], dims=['n'])
    demand = xr.DataArray([300, 325, 275], **dims)

    # NB the call to squeeze() drops the length-1 dimensions c-l-y-h
    obs = rep.get('demand:n-c-l-y-h').squeeze(drop=True)
    # TODO: Squeeze on AttrSeries still returns full index, whereas xarray
    # drops everything except node
    obs = obs.reset_index(['c', 'l', 'y', 'h'], drop=True)
    # check_dtype is false because of casting in pd.Series to float
    # check_attrsis false because we don't get the unit addition in bare xarray
    assert_qty_equal(obs.sort_index(), demand,
                     check_attrs=False, check_dtype=False)

    # ixmp.Reporter pre-populated with only model quantities and aggregates
    assert len(rep_ix.graph) == 5088

    # message_ix.Reporter pre-populated with additional, derived quantities
    assert len(rep.graph) == 7975

    # Derived quantities have expected dimensions
    vom_key = rep.full_key('vom')
    assert vom_key not in rep_ix
    assert vom_key == 'vom:nl-t-yv-ya-m-h'

    # …and expected values
    vom = (
        rep.get(rep.full_key('ACT')) * rep.get(rep.full_key('var_cost'))
    ).dropna()
    # check_attrs false because `vom` multiply above does not add units
    assert_qty_equal(vom, rep.get(vom_key), check_attrs=False)
Beispiel #10
0
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
Beispiel #11
0
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
Beispiel #12
0
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)
Beispiel #13
0
def test_solve_legacy_scenario(tmp_path, test_data_path):
    db_path = create_test_platform(tmp_path, test_data_path, "legacy")
    mp = Platform(backend="jdbc", driver="hsqldb", path=db_path)
    scen = Scenario(mp,
                    model="canning problem (MESSAGE scheme)",
                    scenario="standard")
    exp = scen.var("OBJ")["lvl"]

    # solve scenario, assert that the new objective value is close to previous
    scen = scen.clone(keep_solution=False)
    scen.solve()
    assert np.isclose(exp, scen.var("OBJ")["lvl"])
Beispiel #14
0
def test_solve_legacy_scenario(tmp_path, test_data_path):
    db_path = create_test_platform(tmp_path, test_data_path, 'legacy')
    mp = Platform(backend='jdbc', driver='hsqldb', path=db_path)
    scen = Scenario(mp,
                    model='canning problem (MESSAGE scheme)',
                    scenario='standard')
    exp = scen.var('OBJ')['lvl']

    # solve scenario, assert that the new objective value is close to previous
    scen.remove_solution()
    scen.solve()
    assert np.isclose(exp, scen.var('OBJ')['lvl'])
Beispiel #15
0
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)
Beispiel #16
0
def test_rename_technology_no_rm(test_mp):
    scen = Scenario(test_mp, *msg_args)
    scen.solve()
    assert scen.par('output')['technology'].isin(['canning_plant']).any()

    clone = scen.clone('foo', 'bar', keep_solution=False)
    # also test if already checked out
    clone.check_out()

    clone.rename('technology', {'canning_plant': 'foo_bar'}, keep=True)
    assert clone.par('output')['technology'].isin(['canning_plant']).any()
    assert clone.par('output')['technology'].isin(['foo_bar']).any()
Beispiel #17
0
def test_as_pyam(message_test_mp):
    scen = Scenario(message_test_mp, **SCENARIO['dantzig'])
    if not scen.has_solution():
        scen.solve()
    rep = Reporter.from_scenario(scen)

    # Quantities for 'ACT' variable at full resolution
    qty = rep.get(rep.full_key('ACT'))

    # Call as_pyam() with an empty quantity
    p = computations.as_pyam(scen, qty[0:0], year_time_dim='ya')
    assert isinstance(p, pyam.IamDataFrame)
def test_as_pyam(message_test_mp):
    scen = Scenario(message_test_mp, **SCENARIO["dantzig"])
    if not scen.has_solution():
        scen.solve()
    rep = Reporter.from_scenario(scen)

    # Quantities for 'ACT' variable at full resolution
    qty = rep.get(rep.full_key("ACT"))

    # Call as_pyam() with an empty quantity
    as_pyam = rep.get_comp("as_pyam")
    p = as_pyam(scen, qty[0:0], rename=dict(nl="region", ya="year"))
    assert isinstance(p, pyam.IamDataFrame)
Beispiel #19
0
def test_rename_technology(test_mp):
    scen = Scenario(test_mp, *msg_args)
    scen.solve()
    assert scen.par('output')['technology'].isin(['canning_plant']).any()
    exp_obj = scen.var('OBJ')['lvl']

    clone = scen.clone('foo', 'bar', keep_solution=False)
    clone.rename('technology', {'canning_plant': 'foo_bar'})
    assert not clone.par('output')['technology'].isin(['canning_plant']).any()
    assert clone.par('output')['technology'].isin(['foo_bar']).any()
    clone.solve()
    obs_obj = clone.var('OBJ')['lvl']
    assert obs_obj == exp_obj
Beispiel #20
0
def test_reporter_from_scenario(message_test_mp):
    scen = Scenario(message_test_mp, **SCENARIO["dantzig"])

    # Varies between local & CI contexts
    # DEBUG may be due to reuse of test_mp in a non-deterministic order
    if not scen.has_solution():
        scen.solve(quiet=True)

    # IXMPReporter can be initialized on a MESSAGE Scenario
    rep_ix = ixmp_Reporter.from_scenario(scen)

    # message_ix.Reporter can also be initialized
    rep = Reporter.from_scenario(scen)

    # Number of quantities available in a rudimentary MESSAGEix Scenario
    assert len(rep.graph["all"]) == 123

    # Quantities have short dimension names
    assert "demand:n-c-l-y-h" in rep

    # Aggregates are available
    assert "demand:n-l-h" in rep

    # Quantities contain expected data
    dims = dict(coords=["chicago new-york topeka".split()], dims=["n"])
    demand = Quantity(xr.DataArray([300, 325, 275], **dims), name="demand")

    # NB the call to squeeze() drops the length-1 dimensions c-l-y-h
    obs = rep.get("demand:n-c-l-y-h").squeeze(drop=True)
    # check_attrs False because we don't get the unit addition in bare xarray
    assert_qty_equal(obs, demand, check_attrs=False)

    # ixmp.Reporter pre-populated with only model quantities and aggregates
    assert len(rep_ix.graph) == 5225

    # message_ix.Reporter pre-populated with additional, derived quantities
    # This is the same value as in test_tutorials.py
    assert len(rep.graph) == 12690

    # Derived quantities have expected dimensions
    vom_key = rep.full_key("vom")
    assert vom_key not in rep_ix
    assert vom_key == "vom:nl-t-yv-ya-m-h"

    # …and expected values
    var_cost = rep.get(rep.full_key("var_cost"))
    ACT = rep.get(rep.full_key("ACT"))
    product = rep.get_comp("product")
    vom = product(var_cost, ACT)
    # check_attrs false because `vom` multiply above does not add units
    assert_qty_equal(vom, rep.get(vom_key))
Beispiel #21
0
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)
Beispiel #22
0
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()
Beispiel #23
0
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_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])
Beispiel #27
0
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)
Beispiel #28
0
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
    with pytest.raises(ModelError, match="GAMS errored with return code 3"):
        scen.solve(quiet=True)

    # 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
Beispiel #30
0
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)