Exemple #1
0
def test_order_vertices():
    try:
        from vertex import Vertex
    except (SystemError, ImportError):
        from code.vertex import Vertex

    p = [-100, 0, 100, 0]  # power vector
    c = [0.4, 0.3, 0.3, 0.2]  # marginal price vector
    uv = []
    for i in range(len(p)):
        uv.append(Vertex(c[i], 0, p[i]))

    ov = order_vertices(uv)
    print (uv)
    print (ov)
Exemple #2
0
def test_prod_cost_from_vertices():
    from code.local_asset_model import LocalAsset
    from code.market import Market

    # TEST_PROD_COST_FROM_VERTICES - tests function prod_cost_from_vertices()
    print('Running test_prod_cost_from_vertices()')
    pf = 'pass'

    # Create a test object
    test_object = LocalAsset

    # Create a test market
    test_market = Market()

    # Create several active vertices av
    av = [Vertex(0.02, 5, 0),
          Vertex(0.02, 7, 100),
          Vertex(0.025, 9.25, 200)]

    # Create a time interval
    dt = datetime.now()
    at = dt
    #   NOTE: Function Hours() corrects behavior of Matlab function hours().
    dur = timedelta(hours=1)
    mkt = test_market
    mct = dt
    st = dt
    ti = TimeInterval(at, dur, mkt, mct, st)

    # Create and store the activeVertices, which are IntervalValues
    test_object.activeVertices = [IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[0]),
                                  IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[1]),
                                  IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[2])]

    # CASE: Various signed powers when there is more than one vertex
    test_powers = [-50, 0, 50, 150, 250]
    pc = []
    for p in test_powers:
        pc.append(prod_cost_from_vertices(test_object, ti, p))

    # pc(1) = 0: value is always 0 for power < 0
    # pc(2) = 5.0: assign cost from first vertex
    # pc(3) = 6.0: interpolate between vertices
    # pc(4) = 8.125: interpolate between vertices
    # pc(5) = 9.25: use last vertex cost if power > last vertex power

    # if ~all(pc == [0, 5.0, 6.0, 8.125, 9.25])
    expected = [0, 5.0, 6.0, 8.125, 9.25]
    if not all([pc[i] == expected[i] for i in range(len(pc))]):
        pf = 'fail'
        raise Exception('- the production cost was incorrectly calculated')
    else:
        print('- the production cost was correctly calculated')

    # CASE: One vertex (inelastic case, a constant)
    test_object.activeVertices = [
        IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[0])]

    # pc[i] = prod_cost_from_vertices(test_object, ti, test_powers[i])
    pc = []
    for p in test_powers:
        pc.append(prod_cost_from_vertices(test_object, ti, p))

    expected = [0.0, 5.0, 5.0, 5.0, 5.0]
    # if ~all(pc == [0.0, 5.0, 5.0, 5.0, 5.0])
    if not all([pc[i] == expected[i] for i in range(len(pc))]):
        pf = 'fail'
        raise Exception('- made an incorrect assignment when there is one vertex')
    else:
        print('- made a correct assignment when there is one vertex')

    # CASE: No active vertices (error case):
    test_object.activeVertices = []

    # print('off', 'all')
    try:
        pc = prod_cost_from_vertices(test_object, ti, test_powers[4])
        pf = 'fail'
        # print('on', 'all')
        raise Exception('- the function should have warned and continued when there were no active vertices')
    except:
        print('- the function returned gracefully when there were no active vertices')
        # print('on', 'all')

    #   Success
    print('- the test function ran to completion')
    print('Result: #s\n\n', pf)
Exemple #3
0
def test_production():
    from code.local_asset_model import LocalAsset
    from code.market import Market

    print('Running test_production()')
    pf = 'pass'

    #   Create a test object
    test_object = LocalAsset()

    #   Create a test market
    test_market = Market()

    #   Create several active vertices av
    av = [Vertex(0.0200, 5.00, 0.0),
          Vertex(0.0200, 7.00, 100.0),
          Vertex(0.0250, 9.25, 200.0)]

    # Create a time interval ti
    dt = datetime.now()
    at = dt
    #   NOTE: Function Hours() corrects the behavior of Matlab hours().
    dur = timedelta(hours=1)
    mkt = test_market
    mct = dt
    st = dt
    ti = TimeInterval(at, dur, mkt, mct, st)

    # Assign activeVertices, which are IntervalValues
    test_object.activeVertices = [
        IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[0]),
        IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[1]),
        IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[2])]

    # CASE: Various marginal prices when there is more than one vertex
    test_prices = [-0.010, 0.000, 0.020, 0.0225, 0.030]

    p = [0] * len(test_prices)  # zeros(1, length(test_prices))
    for i in range(len(test_prices)):  # for i = 1:length(test_prices)
        p[i] = production(test_object, test_prices[i], ti)

    print('- the function ran without errors')

    # p(1) = 0: below first vertex
    # p(2) = 0: below first vertex
    # p(3) = 100: at first vertex, which has identical marginal price as second
    # p(4) = 150: interpolate between vertices
    # p(5) = 200: exceeds last vertex

    # if ~all(abs(p - [0, 0, 100, 150, 200]) < 0.001):
    expected = [0, 0, 100, 150, 200]
    if not all([p[i] - expected[i] < 0.001 for i in range(len(p))]):
        pf = 'fail'
        raise Exception('- the production cost was incorrectly calculated')
    else:
        print('- the production cost was correctly calculated')

    # CASE: One vertex (inelastic case, a constant)
    test_object.activeVertices = [IntervalValue(test_object, ti, test_market, MeasurementType.ActiveVertex, av[2])]

    for i in range(5):
        p[i] = production(test_object, test_prices[i], ti)

    # if ~all(p == 200 * ones(1, length(p))):
    if not all(x == 200 for x in p):
        pf = 'fail'
        raise Exception('the vertex power should be assigned when there is one vertex')
    else:
        print('- the correct power was assigned when there is one vertex')

    # CASE: No active vertices (error case):
    test_object.activeVertices = []

    try:
        p = production(test_object, test_prices[4], ti)
        pf = 'fail'
        raise Exception('- an error should have occurred with no active vertices')
    except:
        print('- with no vertices, system returned with warnings, as expected')

    #   Success
    print('- the test function ran to completion')
    print('Result: #s\n\n', pf)
Exemple #4
0
city_market.meterPoints.append(meter)

# Add weather forecast service
config = {'weather_file': city_config['weather_forecast']['weather_file']}
weather_service = TemperatureForecastModel(config)
city_market.informationServiceModels.append(weather_service)

# Add uncontrollable model
inelastive_load = LocalAsset()
inelastive_load.name = 'InelasticLoad'
inelastive_load.maximumPower = -50000  # Remember that a load is a negative power [kW]
inelastive_load.minimumPower = -200000  # Assume twice the average PNNL load [kW]
inelastive_load_model = OpenLoopRichlandLoadPredictor(weather_service)
inelastive_load_model.name = 'InelasticLoadModel'
inelastive_load_model.defaultPower = -100420  # [kW]
inelastive_load_model.defaultVertices = [Vertex(float("inf"), 0.0, -100420.0)]
inelastive_load_model.object = inelastive_load
inelastive_load.model = inelastive_load_model
city_market.localAssets.extend([inelastive_load])

# Add Market
market = Market()
market.name = 'dayAhead'
market.commitment = False
market.converged = False
market.defaultPrice = 0.0428  # [$/kWh]
market.dualityGapThreshold = duality_gap_threshold  # [0.02 = 2#]
market.initialMarketState = MarketState.Inactive
market.marketOrder = 1  # This is first and only market
market.intervalsToClear = 1  # Only one interval at a time
market.futureHorizon = timedelta(
Exemple #5
0
def test_update_costs():
    print('Running AbstractModel.test_update_costs()')

    test_mtn = TransactiveNode()

    #   Create a test market test_mkt
    test_mkt = Market()

    #   Create a sample time interval ti
    dt = datetime.now()
    at = dt
    #   NOTE: Function Hours() corrects behavior of Matlab hours().
    dur = timedelta(hours=1)
    mkt = test_mkt
    mct = dt
    st = datetime.combine(date.today(), time()) + timedelta(hours=20)
    ti = TimeInterval(at, dur, mkt, mct, st)

    #   Save the time interval
    test_mkt.timeIntervals = [ti]

    #   Assign a marginal price in the time interval
    test_mkt.check_marginal_prices(test_mtn)

    #   Create a Neighbor test object and give it a default maximum power value
    # test_obj = Neighbor()
    #     test_obj.maximumPower = 100

    #   Create a corresponding Neighbor.
    test_mdl = Neighbor()

    #   Make sure that the model and object cross-reference one another
    # test_obj.model = test_mdl
    # test_mdl.object = test_obj

    test_mdl.scheduledPowers = [
        IntervalValue(test_mdl, ti, test_mkt, MeasurementType.ScheduledPower,
                      100)
    ]
    test_mdl.activeVertices = [
        IntervalValue(test_mdl, ti, test_mkt, MeasurementType.ActiveVertex,
                      Vertex(0.05, 0, 100))
    ]

    #   Run a test with a Neighbor object
    print('- running test with a Neighbor:')
    try:
        test_mdl.update_costs(test_mkt)
        print('  - the method encountered no errors')
    except RuntimeWarning:
        print('  - ERRORS ENCOUNTERED')

    assert len(test_mdl.productionCosts
               ) == 1, '  - the method did not store a production cost'
    assert len(
        test_mdl.dualCosts) == 1, '  - the method did not store a dual cost'
    assert test_mdl.totalProductionCost == sum([x.value for x in test_mdl.productionCosts]), \
            '  - the method did not store a total production cost'
    assert test_mdl.totalDualCost == sum([x.value for x in test_mdl.dualCosts]), \
            '  - the method did not store a total dual cost'

    # Run a test again with a LocalAsset.
    # test_obj = LocalAsset()
    test_mdl = LocalAsset()
    # test_obj.model = test_mdl
    # test_mdl.object = test_obj
    test_mdl.maximumPower = 100

    test_mdl.scheduledPowers = [
        IntervalValue(test_mdl, ti, test_mkt, MeasurementType.ScheduledPower,
                      100)
    ]
    test_mdl.activeVertices = [
        IntervalValue(test_mdl, ti, test_mkt, MeasurementType.ActiveVertex,
                      Vertex(0.05, 0, 100))
    ]

    print('- running test with a LocalAsset:')

    try:
        test_mdl.update_costs(test_mkt)
        print('  - the method encountered no errors')
    except RuntimeWarning:
        print('  - ERRORS ENCOUNTERED')

    assert len(test_mdl.productionCosts
               ) == 1, '  - the method did not store a production cost'
    assert len(
        test_mdl.dualCosts) == 1, '  - the method did not store a dual cost'
    assert test_mdl.totalProductionCost == sum([x.value for x in test_mdl.productionCosts]), \
            '  - the method did not store a total production cost'
    assert test_mdl.totalDualCost == sum([x.value for x in test_mdl.dualCosts]), \
            '  - the method did not store a total dual cost'

    # Success
    print('test_update_costs() ran to completion.\n')
def test_calculate_reserve_margin():
    # TEST_LAM_CALCULATE_RESERVE_MARGIN() - a LocalAsset ("LAM") class
    # method NOTE: Reserve margins are introduced but not fully integrated into
    # code in early template versions.
    # CASES:
    # 1. uses hard maximum if no active vertices exist
    # 2. vertices exist
    # 2.1 uses maximum vertex power if it is less than hard power constraint
    # 2.2 uses hard constraint if it is less than maximum vertex power
    # 2.3 upper flex power is greater than scheduled power assigns correct
    # positive reserve margin
    # 2.4 upperflex power less than scheduled power assigns zero value to
    # reserve margin.
    print('Running LocalAsset.test_calculate_reserve_margin()')

    # Establish test market
    test_mkt = Market()

    # Establish test market with an active time interval
    # Note: modified 1/29/18 due to new TimeInterval constructor
    dt = datetime.now()
    at = dt
    # NOTE: def Hours() corrects behavior of Matlab hours().
    dur = timedelta(hours=1)
    mkt = test_mkt
    mct = dt
    # st = datetime(date)
    st = datetime.combine(date.today(), time())

    ti = TimeInterval(at, dur, mkt, mct, st)

    # Store time interval
    test_mkt.timeIntervals = [ti]

    # Establish test object that is a LocalAsset.
    test_model = LocalAsset()
    test_model.scheduledPowers = [
        IntervalValue(test_model, ti, test_mkt, MeasurementType.ScheduledPower,
                      0.0)
    ]
    test_model.maximumPower = 100

    # Run the first test case.
    print("  Case 1:")
    try:
        test_model.calculate_reserve_margin(test_mkt)
        print('  The test ran without errors')
    except RuntimeWarning as cause:
        print('  The test encountered errors', cause)

    print(test_model.reserveMargins[0].value)

    assert len(test_model.reserveMargins
               ) == 1, 'An unexpected number of results were stored'

    assert test_model.reserveMargins[0].value == test_model.maximumPower, \
                                                                'The method did not use the available maximum power'

    # create some vertices and store them
    iv = [
        IntervalValue(test_model, ti, test_mkt, MeasurementType.Vertex,
                      Vertex(0, 0, -10)),
        IntervalValue(test_model, ti, test_mkt, MeasurementType.Vertex,
                      Vertex(0, 0, 10))
    ]
    test_model.activeVertices = iv

    print("  Case 2: test with maximum power greater than maximum vertex")
    test_model.maximumPower = 100
    try:
        test_model.calculate_reserve_margin(test_mkt)
        print('  The test ran without errors')
    except RuntimeWarning as cause:
        print('  The test encountered errors', cause)

    assert test_model.reserveMargins[
        0].value == 10, 'The method should have used vertex for comparison'

    print("  Case 3: test with maximum power less than maximum vertex")
    test_model.maximumPower = 5
    try:
        test_model.calculate_reserve_margin(test_mkt)
        print('  The test ran without errors')
    except RuntimeWarning as cause:
        print('  The test encountered errors', cause)

    assert test_model.reserveMargins[
        0].value == 5, 'The method should have used maximum power for comparison'

    print("  Case 4: test with scheduled power greater than maximum vertex")
    test_model.scheduledPowers[0].value = 20
    test_model.maximumPower = 500
    try:
        test_model.calculate_reserve_margin(test_mkt)
        print('  The test ran without errors')
    except RuntimeWarning as cause:
        print('  The test encountered errors', cause)
    print(test_model.reserveMargins[0].value)
    assert test_model.reserveMargins[
        0].value == 0, 'The method should have assigned zero for a neg. result'

    # Success.
    print('Method test_calculate_reserve_margin() ran to completion.\n')
def test_update_production_costs():
    # TEST_UPDATE_PRODUCTION_COSTS() - test method update_production_costs() that calculates production costs from
    # active vertices and scheduled powers.
    # NOTE: This test is virtually identical to the Neighbor test of the same name.
    print('Running LocalAsset.test_update_production_costs()')

    #   Create a test Market.
    test_market = Market()

    #   Create and store a TimeInterval.
    dt = datetime.now(
    )  # datetime that may be used for most datetime arguments
    time_interval = TimeInterval(dt, timedelta(hours=1), test_market, dt, dt)
    test_market.timeIntervals = [time_interval]

    #   Create a test LocalAsset.
    test_model = LocalAsset()

    #   Create and store a scheduled power IntervalValue in the active time interval.
    test_model.scheduledPowers = [
        IntervalValue(test_model, time_interval, test_market,
                      MeasurementType.ScheduledPower, 50)
    ]

    #   Create and store some active vertices IntervalValues in the active time interval.
    vertices = [Vertex(0.1, 1000, 0), Vertex(0.2, 1015, 100)]
    interval_values = [
        IntervalValue(test_model, time_interval, test_market,
                      MeasurementType.ActiveVertex, vertices[0]),
        IntervalValue(test_model, time_interval, test_market,
                      MeasurementType.ActiveVertex, vertices[1])
    ]
    test_model.activeVertices = interval_values

    # TEST 1
    print('- Test 1: First calculation of a production cost')

    try:
        test_model.update_production_costs(test_market)
        print('  - the method ran without errors')
    except RuntimeWarning as cause:
        print('  - the method encountered errors', cause)

    assert len(test_model.productionCosts
               ) == 1, 'The wrong number of production costs was created'

    production_cost = test_model.productionCosts[0].value
    assert production_cost == 1007.5, 'An unexpected production cost value was found'

    # TEST 2
    print('- Test 2: Reassignment of an existing production cost')

    #   Configure the test by modifying the scheduled power value.
    test_model.scheduledPowers[0].value = 150

    try:
        test_model.update_production_costs(test_market)
        print('  - the method ran without errors')
    except RuntimeWarning as cause:
        print('  - the method encountered errors', cause)

    assert len(test_model.productionCosts
               ) == 1, 'The wrong number of productions was created'

    production_cost = test_model.productionCosts[0].value

    assert production_cost == 1015, 'An unexpected dual cost value was found'

    # Success.
    print('Method test_update_production_costs() ran to completion.\n')