예제 #1
0
 def test_approx_equal(self):
     assert not utilities.approx_equal(1, 2)
     assert not utilities.approx_equal(1, 1.02)
     assert utilities.approx_equal(1, 1.01)
     assert utilities.approx_equal(1, 1)
예제 #2
0
 def test_approx_equal(self):
     assert not utilities.approx_equal(1, 2)
     assert not utilities.approx_equal(1, 1.02)
     assert utilities.approx_equal(1, 1.01)
     assert utilities.approx_equal(1, 1)
예제 #3
0
def load_inputs(mod, switch_data, inputs_dir):
    """

    Import data to support modeling fuel use under partial loading
    conditions with piecewise linear incremental heat rates.

    These files are formatted differently than most to match the
    standard format of incremental heat rates. This format is peculiar
    because it formats data records that describes a fuel use curve in
    two disticnt ways. The first record is the first point on the curve,
    but all subsequent records are slopes and x-domain for each line
    segment. For a given generation technology or project, the relevant
    data should be formatted like so:

    power_start_mw  power_end_mw   ihr   fuel_use_rate
    min_load             .          .       value
    min_load          mid_load1   value       .
    mid_load1         max_load    value       .

    The first row provides the first point on the input/output curve.
    Literal dots should be included to indicate blanks.
    The column fuel_use_rate is in units of MMBTU/h.
    Subsequent rows provide the domain and slope of each line segement.
    The column ihr indicates incremental heat rate in MMBTU/MWh.
    Any number of line segments will be accepted.
    All text should be replaced with actual numerical values.

    I chose this format to a) be relatively consistent with standard
    data that is easiest to find, b) make it difficult to misinterpret
    the meaning of the data, and c) allow all of the standard data to be
    included in a single file.

    The following files are optional. If no representative data is
    provided for a generation technology, it will default to a single
    line segment with an intercept of 0 and a slope equal to the full
    load heat rate. If no specific data is provided for a project, it
    will default to its generation technology.

    gen_inc_heat_rates.tab
        generation_technology, power_start_mw, power_end_mw,
        incremental_heat_rate_mbtu_per_mwhr, fuel_use_rate_mmbtu_per_h

    proj_inc_heat_rates.tab
        project, power_start_mw, power_end_mw,
        incremental_heat_rate_mbtu_per_mwhr, fuel_use_rate_mmbtu_per_h

    """
    path = os.path.join(inputs_dir, 'gen_inc_heat_rates.tab')
    if os.path.isfile(path):
        (fuel_rate_segments, min_load, full_hr) = _parse_inc_heat_rate_file(
            path, id_column="generation_technology")
        # Check implied minimum loading level for consistency with
        # g_min_load_fraction if g_min_load_fraction was provided. If
        # g_min_load_fraction wasn't provided, set it to implied minimum
        # loading level.
        for g in min_load:
            if 'g_min_load_fraction' not in switch_data.data():
                switch_data.data()['g_min_load_fraction'] = {}
            if g in switch_data.data(name='g_min_load_fraction'):
                min_load_dat = switch_data.data(name='g_min_load_fraction')[g]
                if not approx_equal(min_load[g], min_load_dat):
                    raise ValueError((
                        "g_min_load_fraction is inconsistant with " +
                        "incremental heat rate data for generation " +
                        "technology {}.").format(g))
            else:
                switch_data.data(name='g_min_load_fraction')[g] = min_load[g]
        # Same thing, but for full load heat rate.
        for g in full_hr:
            if 'g_full_load_heat_rate' not in switch_data.data():
                switch_data.data()['g_full_load_heat_rate'] = {}
            if g in switch_data.data(name='g_full_load_heat_rate'):
                full_hr_dat = switch_data.data(name='g_full_load_heat_rate')[g]
                if abs((full_hr[g] - full_hr_dat) / full_hr_dat) > 0.01:
                    raise ValueError((
                        "g_full_load_heat_rate is inconsistant with " +
                        "incremental heat rate data for generation " +
                        "technology {}.").format(g))
            else:
                switch_data.data(name='g_full_load_heat_rate')[g] = full_hr[g]
        # Copy parsed data into the data portal.
        switch_data.data()['GEN_FUEL_USE_SEGMENTS'] = fuel_rate_segments

    path = os.path.join(inputs_dir, 'proj_inc_heat_rates.tab')
    if os.path.isfile(path):
        (fuel_rate_segments, min_load, full_hr) = _parse_inc_heat_rate_file(
            path, id_column="project")
        # Check implied minimum loading level for consistency with
        # proj_min_load_fraction if proj_min_load_fraction was provided. If
        # proj_min_load_fraction wasn't provided, set it to implied minimum
        # loading level.
        for pr in min_load:
            if 'proj_min_load_fraction' not in switch_data.data():
                switch_data.data()['proj_min_load_fraction'] = {}
            dp_dict = switch_data.data(name='proj_min_load_fraction')
            if pr in dp_dict:
                min_load_dat = dp_dict[pr]
                if abs((min_load[pr] - min_load_dat) / min_load_dat) > 0.01:
                    raise ValueError((
                        "proj_min_load_fraction is inconsistant with " +
                        "incremental heat rate data for project " +
                        "{}.").format(pr))
            else:
                dp_dict[pr] = min_load[pr]
        # Same thing, but for full load heat rate.
        for pr in full_hr:
            if 'proj_full_load_heat_rate' not in switch_data.data():
                switch_data.data()['proj_full_load_heat_rate'] = {}
            dp_dict = switch_data.data(name='proj_full_load_heat_rate')
            if pr in dp_dict:
                full_hr_dat = dp_dict[pr]
                if abs((full_hr[pr] - full_hr_dat) / full_hr_dat) > 0.01:
                    raise ValueError((
                        "proj_full_load_heat_rate is inconsistant with " +
                        "incremental heat rate data for project " +
                        "{}.").format(pr))
            else:
                dp_dict[pr] = full_hr[pr]
        # Copy parsed data into the data portal.
        switch_data.data()['PROJ_FUEL_USE_SEGMENTS'] = fuel_rate_segments
예제 #4
0
def load_inputs(mod, switch_data, inputs_dir):
    """

    Import data to support modeling fuel use under partial loading
    conditions with piecewise linear incremental heat rates.

    These files are formatted differently than most to match the
    standard format of incremental heat rates. This format is peculiar
    because it formats data records that describes a fuel use curve in
    two disticnt ways. The first record is the first point on the curve,
    but all subsequent records are slopes and x-domain for each line
    segment. For a given generation technology or project, the relevant
    data should be formatted like so:

    power_start_mw  power_end_mw   ihr   fuel_use_rate
    min_load             .          .       value
    min_load          mid_load1   value       .
    mid_load1         max_load    value       .

    The first row provides the first point on the input/output curve.
    Literal dots should be included to indicate blanks.
    The column fuel_use_rate is in units of MMBTU/h.
    Subsequent rows provide the domain and slope of each line segement.
    The column ihr indicates incremental heat rate in MMBTU/MWh.
    Any number of line segments will be accepted.
    All text should be replaced with actual numerical values.

    I chose this format to a) be relatively consistent with standard
    data that is easiest to find, b) make it difficult to misinterpret
    the meaning of the data, and c) allow all of the standard data to be
    included in a single file.

    The following files are optional. If no representative data is
    provided for a generation technology, it will default to a single
    line segment with an intercept of 0 and a slope equal to the full
    load heat rate. If no specific data is provided for a project, it
    will default to its generation technology.

    gen_inc_heat_rates.tab
        generation_technology, power_start_mw, power_end_mw,
        incremental_heat_rate_mbtu_per_mwhr, fuel_use_rate_mmbtu_per_h

    proj_inc_heat_rates.tab
        project, power_start_mw, power_end_mw,
        incremental_heat_rate_mbtu_per_mwhr, fuel_use_rate_mmbtu_per_h

    """
    path = os.path.join(inputs_dir, 'gen_inc_heat_rates.tab')
    if os.path.isfile(path):
        (fuel_rate_segments, min_load, full_hr) = _parse_inc_heat_rate_file(
            path, id_column="generation_technology")
        # Check implied minimum loading level for consistency with
        # g_min_load_fraction if g_min_load_fraction was provided. If
        # g_min_load_fraction wasn't provided, set it to implied minimum
        # loading level.
        for g in min_load:
            if 'g_min_load_fraction' not in switch_data.data():
                switch_data.data()['g_min_load_fraction'] = {}
            if g in switch_data.data(name='g_min_load_fraction'):
                min_load_dat = switch_data.data(name='g_min_load_fraction')[g]
                if not approx_equal(min_load[g], min_load_dat):
                    raise ValueError(
                        ("g_min_load_fraction is inconsistant with " +
                         "incremental heat rate data for generation " +
                         "technology {}.").format(g))
            else:
                switch_data.data(name='g_min_load_fraction')[g] = min_load[g]
        # Same thing, but for full load heat rate.
        for g in full_hr:
            if 'g_full_load_heat_rate' not in switch_data.data():
                switch_data.data()['g_full_load_heat_rate'] = {}
            if g in switch_data.data(name='g_full_load_heat_rate'):
                full_hr_dat = switch_data.data(name='g_full_load_heat_rate')[g]
                if abs((full_hr[g] - full_hr_dat) / full_hr_dat) > 0.01:
                    raise ValueError(
                        ("g_full_load_heat_rate is inconsistant with " +
                         "incremental heat rate data for generation " +
                         "technology {}.").format(g))
            else:
                switch_data.data(name='g_full_load_heat_rate')[g] = full_hr[g]
        # Copy parsed data into the data portal.
        switch_data.data()['GEN_FUEL_USE_SEGMENTS'] = fuel_rate_segments

    path = os.path.join(inputs_dir, 'proj_inc_heat_rates.tab')
    if os.path.isfile(path):
        (fuel_rate_segments, min_load,
         full_hr) = _parse_inc_heat_rate_file(path, id_column="project")
        # Check implied minimum loading level for consistency with
        # proj_min_load_fraction if proj_min_load_fraction was provided. If
        # proj_min_load_fraction wasn't provided, set it to implied minimum
        # loading level.
        for pr in min_load:
            if 'proj_min_load_fraction' not in switch_data.data():
                switch_data.data()['proj_min_load_fraction'] = {}
            dp_dict = switch_data.data(name='proj_min_load_fraction')
            if pr in dp_dict:
                min_load_dat = dp_dict[pr]
                if abs((min_load[pr] - min_load_dat) / min_load_dat) > 0.01:
                    raise ValueError(
                        ("proj_min_load_fraction is inconsistant with " +
                         "incremental heat rate data for project " +
                         "{}.").format(pr))
            else:
                dp_dict[pr] = min_load[pr]
        # Same thing, but for full load heat rate.
        for pr in full_hr:
            if 'proj_full_load_heat_rate' not in switch_data.data():
                switch_data.data()['proj_full_load_heat_rate'] = {}
            dp_dict = switch_data.data(name='proj_full_load_heat_rate')
            if pr in dp_dict:
                full_hr_dat = dp_dict[pr]
                if abs((full_hr[pr] - full_hr_dat) / full_hr_dat) > 0.01:
                    raise ValueError(
                        ("proj_full_load_heat_rate is inconsistant with " +
                         "incremental heat rate data for project " +
                         "{}.").format(pr))
            else:
                dp_dict[pr] = full_hr[pr]
        # Copy parsed data into the data portal.
        switch_data.data()['PROJ_FUEL_USE_SEGMENTS'] = fuel_rate_segments