Exemplo n.º 1
0
def distribuition_costs(pixT,
                        DH_threshold,
                        dist_grid_cost,
                        out_raster_hdm_last_year,
                        out_raster_maxDHdem,
                        out_raster_invest_Euro,
                        out_raster_coh_area_bool,
                        out_raster_labels,
                        struct=np.ones((3, 3))):
    rm_file(out_raster_coh_area_bool, out_raster_labels)
    invest_Euro_arr = raster_array(out_raster_invest_Euro)
    maxDHdem_arr = raster_array(out_raster_maxDHdem)
    heat_density_map_last_year, geo_transform = raster_array(
        out_raster_hdm_last_year, return_gt=True)
    rast_origin = geo_transform[0], geo_transform[3]
    coh_areas = np.zeros_like(maxDHdem_arr, 'int8')
    reg_filter = maxDHdem_arr.astype(bool).astype('int8')
    # DH_threshold in MWH
    DH_threshold_MWh = DH_threshold * 1000
    for pix_threshold in pixT:
        # calculate coherent regions with given thresholds and cut them to
        # LAU2 levels
        # DH_Regions: boolean array showing DH regions
        DH_Regions, gt = DHP.DHReg(heat_density_map_last_year, pix_threshold,
                                   DH_threshold, rast_origin)
        # multiplication with reg_filter required to follow out_raster_maxDHdem
        # pattern and separate connection of regions with pixels that have
        # value of zero in out_raster_maxDHdem
        result = DH_Regions.astype(int) * reg_filter
        labels, nr_coherent = measurements.label(result, structure=struct)
        if nr_coherent == 0:
            break
        for i in range(1, nr_coherent + 1):
            temp = labels == i
            q = np.sum(maxDHdem_arr[temp])
            q_inv = np.sum(invest_Euro_arr[temp])
            q_spec_cost = q_inv / q
            if q_spec_cost <= dist_grid_cost and q >= DH_threshold_MWh:
                coh_areas[temp] = 1
                heat_density_map_last_year[temp] = 0
        labels = None
        nr_coherent = None
    labels, numLabels = measurements.label(coh_areas, structure=struct)
    CM19.main(out_raster_coh_area_bool, geo_transform, 'int8', coh_areas)
    CM19.main(out_raster_labels, geo_transform, "int16", labels)
    return numLabels
Exemplo n.º 2
0
def distribuition_costs(invest_Euro,
                        maxDHdem,
                        features_path,
                        hdm_1st,
                        hdm_last,
                        MS_1st,
                        pixT,
                        DHT,
                        costT,
                        coh_area_raster,
                        hdm_dh_reg_last_year,
                        label_raster,
                        struct=np.ones((3, 3))):
    rm_file(coh_area_raster, hdm_dh_reg_last_year, label_raster)
    invest_Euro_arr = raster_array(invest_Euro)
    maxDHdem_arr = raster_array(maxDHdem)
    hdm_arr, geo_transform = raster_array(hdm_last, return_gt=True)
    rast_origin = geo_transform[0], geo_transform[3]
    coh_areas = np.zeros_like(maxDHdem_arr, 'int8')
    reg_filter = maxDHdem_arr.astype(bool).astype('int8')
    for pix_threshold in pixT:
        # calculate coherent regions with given thresholds and cut them to
        # LAU2 levels
        DH_Regions = CM4.main(hdm_arr,
                              features_path,
                              pix_threshold,
                              DHT,
                              None,
                              rast_origin,
                              only_return_areas=True)
        # multiplication with reg_filter required to follow maxDHdem
        # pattern and separate connection of regions with pixels that have
        # value of zero in maxDHdem
        result = DH_Regions.astype(int) * reg_filter
        labels, nr_coherent = measurements.label(result, structure=struct)
        if nr_coherent == 0:
            break
        for i in range(1, nr_coherent + 1):
            temp = labels == i
            q = np.sum(maxDHdem_arr[temp])
            q_inv = np.sum(invest_Euro_arr[temp])
            q_spec_cost = q_inv / q
            if q_spec_cost <= costT and q >= DHT:
                coh_areas[temp] = 1
                hdm_arr[temp] = 0
        labels = None
        nr_coherent = None
    hdm_last_arr = raster_array(hdm_last)
    hdm_1st_arr = raster_array(hdm_1st)
    labels, numLabels = measurements.label(coh_areas, structure=struct)
    if numLabels == 0:
        raise ValueError('For the provided grid cost ceiling, no district '
                         'heating potential area can be realized!')
    if numLabels > 100:
        raise ValueError('For the given scenario, we found more than 100 '
                         'coherent areas. Please reduce the size of your '
                         'selection and run the scenario again!')
    hdm_in_dh_reg = hdm_last_arr * coh_areas
    CM19.main(coh_area_raster, geo_transform, 'int8', coh_areas)
    CM19.main(hdm_dh_reg_last_year, geo_transform, "float64", hdm_in_dh_reg)
    CM19.main(label_raster, geo_transform, "int16", labels)
    # average demand in dh regions: sum_demand/sum_area_of_dhReg
    # MWh/ha
    ave_dem_dh_reg = np.sum(hdm_in_dh_reg) / np.sum(coh_areas)
def main(investment_start_year, investment_last_year, depreciation_time,
         accumulated_energy_saving, dh_connection_rate_first_year,
         dh_connection_rate_last_year, interest_rate, grid_cost_ceiling, c1,
         c2, full_load_hours, mip_gap, in_raster_gfa, in_raster_hdm,
         out_raster_maxDHdem, out_raster_economic_maxDHdem,
         out_raster_invest_Euro, out_raster_hdm_last_year,
         out_raster_dist_pipe_length, out_raster_coh_area_bool,
         out_raster_labels, out_shp_prelabel, out_shp_label, out_shp_edges,
         out_shp_nodes, out_csv_solution, output_directory):
    """
    Default parameters:
        grid_factor: grid factor of 1.05 shows the ratio of total grid costs to
            distribtion grid costs and is set based on previously run
            sensitivity analyses as well as other studies in the literature.
        pixT: pixel threshold in MWh/ha
        DH_threshold: DH area threshold in GWh/year just for filtering all the low demand
            pixels.
        trans_line_cap_cost: transmission line cost: power[MW], transmission
            line cost[EUR/m]
    """
    # test input raster
    in_raster_hdm_arr = raster_array(in_raster_hdm)
    if len(np.nonzero(in_raster_hdm_arr)[0]) == 0:
        in_raster_hdm_arr = None
        covered_demand, dist_inv, dist_spec_cost, trans_inv, \
        trans_spec_cost, trans_line_length, dist_pipe_len, \
        heat_dem_1st, heat_dem_last, n_coh_areas, \
        n_coh_areas_selected = np.zeros(11)
        opt_term_cond = False
        numLabels = 0
        output_summary = summary(covered_demand, dist_inv, dist_spec_cost,
                                 trans_inv, trans_spec_cost, trans_line_length,
                                 dist_pipe_len, heat_dem_1st, heat_dem_last,
                                 n_coh_areas, n_coh_areas_selected,
                                 opt_term_cond, numLabels)

        return output_summary, opt_term_cond, edge_list
    in_raster_hdm_arr = None
    grid_factor = 1.05
    pixT = 10 * np.arange(1, 135, 0.1)
    # DH Threshold in GWh/year
    DH_threshold = 1
    trans_line_cap_cost = np.array([[0, 0], [0.2, 195], [0.3, 206], [0.6, 220],
                                    [1.2, 240], [1.9, 261], [3.6, 288],
                                    [6.1, 323], [9.8, 357], [20,
                                                             426], [45, 564],
                                    [75, 701], [125, 839], [190, 976],
                                    [400, 1418], [700, 2050], [1000, 2683]])
    '''
    trans_line_cap_cost = np.array([[0, 0], [0.2, 195], [0.3, 206], [0.6, 220], [1.2, 240],
                        [1.9, 261], [3.6, 288], [6.1, 323], [9.8, 357],
                        [20,  426], [45,  564], [75,  701], [125, 839],
                        [190, 976], [19000, 97600]])
    '''
    dist_grid_cost = float(grid_cost_ceiling) / float(grid_factor)

    # f2: calculate pixel based values
    f2_output_layers = [
        out_raster_maxDHdem, out_raster_invest_Euro, out_raster_hdm_last_year,
        out_raster_dist_pipe_length
    ]
    dh_demand(c1, c2, in_raster_gfa, in_raster_hdm, investment_start_year,
              investment_last_year, accumulated_energy_saving,
              dh_connection_rate_first_year, dh_connection_rate_last_year,
              depreciation_time, interest_rate, f2_output_layers)
    # f3: Determination of coherent areas based on the grid cost threshold.
    numLabels = distribuition_costs(pixT, DH_threshold, dist_grid_cost,
                                    out_raster_hdm_last_year,
                                    out_raster_maxDHdem,
                                    out_raster_invest_Euro,
                                    out_raster_coh_area_bool,
                                    out_raster_labels)
    edge_list = []
    if numLabels > 0 and numLabels < 70:
        # numLabels = 0 : the grid cost ceiling is too low.
        # numLabels > 100: too many coherent areas were detected!
        # f4: pre-steps for providing input to the optimization function including
        # calling various functions for calculating distance between coherent
        # areas, optimization module, illustrating the transmission lines,
        # polygonize the coherent areas.
        (covered_demand, dist_inv, dist_spec_cost, trans_inv, trans_spec_cost,
         trans_line_length), dist_pipe_len, heat_dem_1st, \
         heat_dem_last, n_coh_areas, \
         n_coh_areas_selected, \
         opt_term_cond, edge_list    = pre_opt(depreciation_time, interest_rate,
                                        grid_cost_ceiling, trans_line_cap_cost,
                                        full_load_hours, mip_gap,
                                        in_raster_hdm,
                                        out_raster_coh_area_bool,
                                        out_raster_hdm_last_year,
                                        out_raster_dist_pipe_length,
                                        out_raster_maxDHdem,
                                        out_raster_economic_maxDHdem,
                                        out_raster_labels,
                                        out_raster_invest_Euro, out_shp_prelabel,
                                        out_shp_label, out_shp_edges,
                                        out_shp_nodes, out_csv_solution,
                                        output_directory, polygonize_region=True)
        print("pre_opt")
    else:
        covered_demand, dist_inv, dist_spec_cost, trans_inv, \
        trans_spec_cost, trans_line_length, dist_pipe_len, \
        heat_dem_1st, heat_dem_last, n_coh_areas, \
        n_coh_areas_selected = np.zeros(11)
        opt_term_cond = False
    # f9: returns the summary of results in a dictionary format
    output_summary = summary(covered_demand, dist_inv, dist_spec_cost,
                             trans_inv, trans_spec_cost, trans_line_length,
                             dist_pipe_len, heat_dem_1st, heat_dem_last,
                             n_coh_areas, n_coh_areas_selected, opt_term_cond,
                             numLabels)
    return output_summary, opt_term_cond, edge_list
def pre_opt(depreciation_time,
            interest_rate,
            grid_cost_ceiling,
            trans_line_cap_cost,
            full_load_hours,
            mip_gap,
            in_raster_hdm,
            out_raster_coh_area_bool,
            out_raster_hdm_last_year,
            out_raster_dist_pipe_length,
            out_raster_maxDHdem,
            out_raster_economic_maxDHdem,
            out_raster_labels,
            out_raster_invest_Euro,
            out_shp_prelabel,
            out_shp_label,
            out_shp_edges,
            out_shp_nodes,
            out_csv_solution,
            output_directory,
            polygonize_region=False):
    hdm_arr, geoTrans = raster_array(out_raster_hdm_last_year, return_gt=True)
    labels = raster_array(out_raster_labels, 'int16')
    nr_coherent = np.max(labels)
    labels_copy = np.copy(labels)
    distance_matrix, row_from_label, col_from_label, \
        row_to_label, col_to_label = feature_dist(labels)

    total_pipe_length_arr = raster_array(out_raster_dist_pipe_length)
    hdm_1st_arr = raster_array(in_raster_hdm)
    dist_invest_arr = raster_array(out_raster_invest_Euro)
    maxDHdem_arr = raster_array(out_raster_maxDHdem)
    # prepare dataframe for final answers.
    heat_dem_coh_1st = np.zeros((nr_coherent))
    heat_dem_coh_last = np.zeros((nr_coherent))
    heat_dem_spec_area = np.zeros((nr_coherent))
    dist_pipe_len = np.zeros((nr_coherent))
    q = np.zeros((nr_coherent))
    q_inv = np.zeros((nr_coherent))
    q_spec_cost = np.zeros((nr_coherent))
    area_coh_area = np.zeros((nr_coherent))
    for i in range(1, nr_coherent + 1):
        j = i - 1
        temp = labels_copy == i
        # in hectare
        area_coh_area[j] = np.sum(temp)
        heat_dem_coh_1st[j] = np.sum(hdm_1st_arr[temp])
        heat_dem_coh_last[j] = np.sum(hdm_arr[temp])
        # pipe length raster is in m/m2 and for each pixel needs a factor 10000
        # for meter and factor 1e-3 for km. Overal factor 10 to get it in km
        dist_pipe_len[j] = np.sum(total_pipe_length_arr[temp]) * 10
        q[j] = np.sum(maxDHdem_arr[temp])
        q_inv[j] = np.sum(dist_invest_arr[temp])
        q_spec_cost[j] = q_inv[j] / q[j]
        # MWh/km2
        heat_dem_spec_area[j] = heat_dem_coh_last[j] / area_coh_area[j]
    df = pd.DataFrame({
        'heat demand total 1st year [MWh]':
        heat_dem_coh_1st,
        'heat demand total last year [MWh]':
        heat_dem_coh_last,
        'max potential district heating through investment period [MWh]':
        q,
        'specific heat demand total 1st year [MWh/ha]':
        heat_dem_spec_area,
        'distribution line length [km]':
        dist_pipe_len,
        'distribution costs - annualized [EUR]':
        q_inv,
        'distribution costs [EUR/MWh]':
        q_spec_cost,
        'area [ha]':
        area_coh_area
    })
    '''
    Dimension DN Water flow m/s Capacity MW Cost EUR/m
    Reference: GIS based analysis of future district heating in Denmark
    Author: Steffan Nielsen, Bernd Moeller
    '''
    if interest_rate > 0:
        annuity_factor = (interest_rate *
                          (1 + interest_rate)**depreciation_time) / (
                              (1 + interest_rate)**depreciation_time - 1)
    else:
        annuity_factor = 1
    '''
    tl_cost_copy = np.copy(trans_line_cap_cost)
    temp_q = np.copy(q)
    power_to_add = temp_q[temp_q/full_load_hours > 190]/full_load_hours
    for item in power_to_add:
        for i in range(1, 5):
            temp_price = i * item / 190 * 976
            tl_cost_copy = np.concatenate((tl_cost_copy, [[i * item, temp_price]]))
    tl_cost_copy = tl_cost_copy[tl_cost_copy[:, 0].argsort()]
    trans_line_cap_cost = np.copy(tl_cost_copy)
    '''
    # consideration of annuity factor
    trans_line_cap_cost[:, 1] = trans_line_cap_cost[:, 1] * annuity_factor
    cost_matrix = trans_line_cap_cost[:, 1]
    pow_range_matrix = trans_line_cap_cost[:, 0]
    term_cond, dh, edge_list = optimize_dist(grid_cost_ceiling, cost_matrix,
                                             pow_range_matrix, distance_matrix,
                                             q, q_spec_cost, mip_gap)
    grid_cost_header = 'Connected at %0.2f EUR/MWh' % grid_cost_ceiling
    df[grid_cost_header] = dh[:-6]
    df['label'] = df.index + 1
    headers = [
        'label', 'heat demand total 1st year [MWh]',
        'heat demand total last year [MWh]', 'distribution costs [EUR/MWh]',
        'specific heat demand total 1st year [MWh/ha]',
        'distribution costs - annualized [EUR]', 'area [ha]',
        'distribution line length [km]', grid_cost_header
    ]
    df = df[headers]

    df.to_csv(out_csv_solution)
    if polygonize_region and term_cond == True:
        economic_bool = dh[:-6]
        poly(heat_dem_coh_last, heat_dem_spec_area, q, q_spec_cost,
             economic_bool, area_coh_area, out_raster_coh_area_bool,
             out_raster_labels, out_raster_maxDHdem,
             out_raster_economic_maxDHdem, out_shp_prelabel, out_shp_label)
    node_label_list = np.arange(1, nr_coherent + 1) * dh[0:-6]
    if term_cond == True:
        if len(edge_list) > 0:
            edge_representation(row_from_label, col_from_label, row_to_label,
                                col_to_label, distance_matrix, node_label_list,
                                edge_list, geoTrans, out_shp_edges,
                                out_shp_nodes, output_directory)
    sum_dist_pipeline = np.sum(dist_pipe_len * dh[:-6])
    return dh[-6:], sum_dist_pipeline, np.sum(hdm_1st_arr), np.sum(
        hdm_arr), nr_coherent, np.sum(dh[:-6]), term_cond, edge_list
Exemplo n.º 5
0
def pre_opt(coh_area_raster,
            grid_cost,
            output_dir,
            hdm_1st,
            hdm_last,
            total_pipe_length,
            maxDHdem_path,
            inShapefile,
            label_raster,
            invest_Euro,
            outPolygon,
            depr_time,
            r,
            sol_csv,
            epsg=3035,
            struct=np.ones((3, 3)),
            polygonize_region=False,
            full_load_hours=3000):
    '''
    ########################################################
    edge_folder_name = inShapefile.split('/')[-1][:-4]
    edge_folder_name = 'edges'
    edge_folder = output_dir + os.sep + edge_folder_name
    rm_mk_dir(edge_folder)
    ########################################################
    '''
    hdm_arr, geoTrans = raster_array(hdm_last, return_gt=True)
    labels = raster_array(label_raster, 'int16')
    nr_coherent = np.max(labels)
    labels_copy = np.copy(labels)
    distance_matrix, row_from_label, col_from_label, \
        row_to_label, col_to_label = feature_dist(labels)
    '''
    # in case of center-to-center distance use the following:
    distance_matrix = 100 * cdist(coords, coords, 'euclidean')
    '''
    ###########################################################################
    ###########################################################################
    total_pipe_length_arr = raster_array(total_pipe_length)
    hdm_1st_arr = raster_array(hdm_1st)
    dist_invest_arr = raster_array(invest_Euro)
    maxDHdem_arr = raster_array(maxDHdem_path)
    # prepare dataframe for final answers
    heat_dem_coh_1st = np.zeros((nr_coherent))
    heat_dem_coh_last = np.zeros((nr_coherent))
    heat_dem_spec_area = np.zeros((nr_coherent))
    dist_pipe_len = np.zeros((nr_coherent))
    q = np.zeros((nr_coherent))
    q_inv = np.zeros((nr_coherent))
    q_spec_cost = np.zeros((nr_coherent))
    area_coh_area = np.zeros((nr_coherent))
    for i in range(1, nr_coherent + 1):
        j = i - 1
        temp = labels_copy == i
        # in hectare
        area_coh_area[j] = np.sum(temp)
        heat_dem_coh_1st[j] = np.sum(hdm_1st_arr[temp])
        heat_dem_coh_last[j] = np.sum(hdm_arr[temp])
        # pipe length raster is in m/m2 and for each pixel needs a factor 10000
        # for meter and factor 1e-3 for km. Overal factor 10 to get it in km
        dist_pipe_len[j] = np.sum(total_pipe_length_arr[temp]) * 10
        q[j] = np.sum(maxDHdem_arr[temp])
        q_inv[j] = np.sum(dist_invest_arr[temp])
        q_spec_cost[j] = q_inv[j] / q[j]
        # MWh/km2
        heat_dem_spec_area[j] = heat_dem_coh_last[j] / area_coh_area[j]
    df = pd.DataFrame({
        'heat demand total 1st year [MWh]': heat_dem_coh_1st,
        'heat demand total last year [MWh]': heat_dem_coh_last,
        'potential heat demand district heating [MWh]': q,
        'specific heat demand total 1st year [MWh/km2]': heat_dem_spec_area,
        'distribution line length [km]': dist_pipe_len,
        'distribution costs [EUR]': q_inv,
        'distribution costs [EUR/MWh]': q_spec_cost,
        'area [km2]': area_coh_area
    })
    '''
    Dimension DN Water flow m/s Capacity MW Cost EUR/m
    Reference: GIS based analysis of future district heating in Denmark
    Author: Steffan Nielsen, Bernd Moeller

    Important Note: this is a simplified method for finding the diameter of the
    transmission lines. The capacity and therefore, the cost of a transmission
    line is set only considering two coherent areas.
    for calculation of the cost, 3000h of full load hours has been considered.
    '''
    annuity_factor = (r * (1 + r)**depr_time) / ((1 + r)**depr_time - 1)
    # power[MW], transmission line cost[EUR/m]
    tl_cost = np.array([[0, 0], [0.2, 195], [0.3, 206], [0.6, 220], [1.2, 240],
                        [1.9, 261], [3.6, 288], [6.1, 323], [9.8, 357],
                        [20, 426], [45, 564], [75, 701], [125, 839],
                        [190, 976], [19000, 97600]])

    tl_cost_copy = np.copy(tl_cost)
    temp_q = np.copy(q)
    power_to_add = temp_q[temp_q / full_load_hours > 190] / full_load_hours
    for item in power_to_add:
        for i in range(1, 5):
            temp_price = i * item / 190 * 976
            tl_cost_copy = np.concatenate(
                (tl_cost_copy, [[i * item, temp_price]]))
        '''
        for i in range(tl_cost.shape[0]):
            temp_pow = (item + tl_cost[i, 0])/2
            temp_price = temp_pow / 190 * 976
            tl_cost_copy = np.concatenate((tl_cost_copy, [[temp_pow, temp_price]]))
        '''
    tl_cost_copy = tl_cost_copy[tl_cost_copy[:, 0].argsort()]
    tl_cost = np.copy(tl_cost_copy)

    # consideration of annuity factor
    tl_cost[:, 1] = tl_cost[:, 1] * annuity_factor

    # term_cond, dh_filtered, edge_list_filtered = optimize_dist(grid_cost, distance_matrix_filtered, trans_line_cost_filtered, q_filtered, q_spec_cost_filtered)
    cost_matrix = tl_cost[:, 1]
    pow_range_matrix = tl_cost[:, 0]
    term_cond, dh, edge_list = optimize_dist(grid_cost, cost_matrix,
                                             pow_range_matrix, distance_matrix,
                                             q, q_spec_cost)
    grid_cost_header = 'Connected at %0.2f EUR/MWh' % grid_cost
    df[grid_cost_header] = dh[:-6]
    df['label'] = df.index + 1
    headers = [
        'label', 'heat demand total 1st year [MWh]',
        'heat demand total last year [MWh]',
        'potential heat demand district heating [MWh]',
        'distribution costs [EUR/MWh]',
        'specific heat demand total 1st year [MWh/km2]',
        'distribution costs [EUR]', 'area [km2]',
        'distribution line length [km]', grid_cost_header
    ]
    df = df[headers]
    df.to_csv(sol_csv)
    if polygonize_region and term_cond:
        economic = dh[:-6]
        poly(coh_area_raster, label_raster, outPolygon, economic,
             heat_dem_coh_last, heat_dem_spec_area, q, q_spec_cost,
             area_coh_area)
    node_label_list = np.arange(1, nr_coherent + 1) * dh[0:-6]
    if term_cond:
        if len(edge_list) > 0:
            edge_folder = output_dir + os.sep + 'edges'
            edge_representation(row_from_label, col_from_label, row_to_label,
                                col_to_label, distance_matrix, node_label_list,
                                edge_list, geoTrans, edge_folder)
            # for the case center-to-center use the follwoing line instead!
            # edge_representation(label_raster, coords, distance_matrix,
            #                     node_label_list, edge_list,
            #                     edge_folder + os.sep + str(grid_cost))
    '''
    #########################################################################
    #########################################################################
    node_label_list = np.arange(1, nr_coherent+1) * dh[0: -6]
    if term_cond:
        if len(edge_list) > 0:
            edge_folder = output_dir + os.sep + 'edges'
            edge_representation_old(label_raster, coh_area_raster, distance_matrix,
                                node_label_list, edge_list, edge_folder)
            # for the case center-to-center use the follwoing line instead!
            # edge_representation(label_raster, coords, distance_matrix,
            #                     node_label_list, edge_list,
            #                     edge_folder + os.sep + str(grid_cost))
    #########################################################################
    #########################################################################
    '''
    sum_dist_pipeline = np.sum(dist_pipe_len * dh[:-6])
    calculated_total_trans_cost = 0
    return dh[-6:], sum_dist_pipeline, np.sum(hdm_1st_arr), np.sum(
        hdm_arr), nr_coherent, np.sum(dh[:-6])