def simulate( variables, # planted corn stover in hectares LC = land_costs, # land costs per county C_Y = bu_per_acre_C_yield, # corn yield per acre LL = land_limits, # land limits DM = dist_map, # distance mapping R_idx = refinery_idx # location of refinery in simple case ): # Empty variables CS_farm_kg = 0 # corn stover production in kg CS_cultivation_capex = 0 # total costs CS_cultivation_opex = 0 CS_travel_opex = 0 CS_flow_matrix = np.zeros((len(counties),len(counties))) CS_flow = 0 CS_refinery_kg = 0 CS_ethanol = np.zeros((len(counties),1)) CS_refinery_opex = 0 CS_refinery_capex = 0 Constraints = [] # constraints ############################## # Cultivation and Harvesting for i in range(0,len(counties)): # Per ha values (need to expand) (CS_per_ha, seeds_per_ha, fertilization_per_ha, lime_per_ha) = CS_cultivation.sim(C_Y[i]) # kg CS produced in given county 'i' CS_farm_kg += CS_per_ha*variables[i] # Capital costs (need to expand) CS_cultivation_capex += variables[i]*LC[i] # Operating costs (need to expand) harvesting = 38.31*ha_to_acre # $ per ha CS_cultivation_opex += variables[i]*(seeds_per_ha*.00185 + fertilization_per_ha[0]*0.55 + fertilization_per_ha[1]*0.46 + fertilization_per_ha[2]*0.50 + lime_per_ha*0.01 + harvesting) #herbicide in per ha?? ################################ # Flow to refinery for j in range(0,len(counties)): # County to county mass transfer (kg of CS) (from county 'i' to county 'j') CS_flow_matrix[i,j] += variables[(i+1)*len(counties) + j] # Travel costs in bale-miles CS_travel_opex += DM[i,j]*CS_flow_matrix[i,j]*(lb_to_kg)*(1/1500)*0.50 # Transportation constraints (flow from county 'i' must be <= mass produced) CS_flow = sum(CS_flow_matrix[i,:]) Constraints.append(CS_flow - CS_farm_kg) # Cultivation constraints (land limits) Constraints.append(variables[i] - LL[i]) ################################ # Refinery for j in range(0,len(counties)): # Find total mass sent to refinery in county 'j' CS_refinery_kg = sum(CS_flow_matrix[:,j]) # Ethanol produced at refinery in county 'j' CS_ethanol[j] = CS_processing.sim(CS_refinery_kg) # Refinery opex #ADD THIS # Refinery capex if CS_refinery_kg > 0: scale = CS_refinery_kg/(5563*142) # Based on kg per ha and ha scaling in Jack's TEA file CS_refinery_capex+= 400000000*(scale)**.6 Constraints.append(1990000-sum(CS_ethanol)) Constraints.append(sum(CS_ethanol) - 2010000) Constraints = list(Constraints) return [CS_refinery_capex, CS_travel_opex], Constraints
def simulate( vars, # cultivation hectares per county, hub-to-hub biomass flows LC=reduced_land_costs, # land costs per county C_Y=reduced_C_yield, # corn yield per acre LL=reduced_land_limits, # land limits DM=dist_map, # hub to hub distances C2H_map=map_C2H, # binary matrix mapping counties (rows) to hubs (columns) C2H=dist_C2H, # county to hub distances locations=locations, #possible location of biorefineries, hubs=hubs, Q=quota): # Empty parameters CS_cultivation_capex = 0 CS_cultivation_opex = 0 CS_travel_opex = 0 CS_flow_matrix = np.zeros((len(hubs), len(locations))) CS_C2H_prod = np.zeros((len(LC), len(hubs))) CS_flow = 0 CS_refinery_kg = 0 CS_ethanol = np.zeros((len(locations), 1)) CS_refinery_capex = 0 Constraints = [] # constraints # Per ha values (need to expand) (CS_per_ha, seeds_per_ha, fertilization_per_ha, lime_per_ha) = CS_cultivation.sim(C_Y) # Capital costs (need to expand) L = np.array(LC) v = np.array(vars) CS_cultivation_capex = np.dot(v[0:len(LC)], L) ############################## # Cultivation and Harvesting # Operating costs (need to expand) harvesting = 38.31 * ha_to_acre # $ per ha CS_cultivation_opex = np.dot( v[0:len(LC)], (seeds_per_ha * .00185 + fertilization_per_ha[0] * 0.55 + fertilization_per_ha[1] * 0.46 + fertilization_per_ha[2] * 0.50 + lime_per_ha * 0.01 + harvesting)) #herbicide in per ha?? # Automatic flow to pre-processing hub CS_C2H_prod = C2H_map * CS_per_ha * v[0:len(LC)] CS_cultivation_opex = sum(CS_per_ha * vars[0:len(LC)] * (lb_to_kg) * (1 / 1500) * 0.50 * C2H) # Cultivation constraints (land limits) for i in range(0, len(LC)): Constraints.append(vars[i] - LL[i] - 5) #allow some slack in DVs ################################ # Flow to refinery for j in range(0, len(hubs)): for k in range(0, len(locations)): # Mass transfer (1Ms kg of CS) from hub 'j' to hub 'k' CS_flow_matrix[j, k] = CS_flow_matrix[j, k] + vars[i + 1 + j * len(locations) + k] # Travel costs in bale-miles CS_travel_opex += DM[j, k] * CS_flow_matrix[j, k] * (lb_to_kg) * ( 1 / 1500) * 0.50 for j in range(0, len(hubs)): # Hubs collect biomass from counties CS_hub_kg = sum(CS_C2H_prod[:, j]) # Transportation constraints (all delivery from hub 'j' must be <= mass produced) CS_flow = sum(CS_flow_matrix[j, :]) Constraints.append(CS_flow - CS_hub_kg - 5) #allow some slack in DVs ############################### # Refinery for k in range(0, len(locations)): # Find total mass received at hub 'l' CS_refinery_kg = sum(CS_flow_matrix[:, k]) # Ethanol produced at refinery at hub 'l' CS_ethanol[k] = CS_processing.sim(CS_refinery_kg) # Refinery capex if CS_refinery_kg > 5: scale = CS_refinery_kg / ( 5563 * 142 ) # Based on kg per ha and ha scaling in Jack's TEA file CS_refinery_capex += 400000000 * (scale)**.6 # Sets ethanol production quota (L) Constraints.append(Q * 0.95 - sum(CS_ethanol)[0]) Constraints.append(sum(CS_ethanol)[0] - Q * 1.05) Constraints = list(Constraints) # Returns list of objectives, Constraints return [CS_refinery_capex, CS_travel_opex], Constraints
def test(DV, LC, C_Y, LL, DM, C2H_map, C2H, locations, hubs, Q): # Empty parameters CS_cultivation_capex = 0 CS_cultivation_opex = 0 CS_travel_opex = 0 CS_flow_matrix = np.zeros((len(hubs), len(locations))) CS_C2H_prod = np.zeros((len(LC), len(hubs))) CS_flow = 0 CS_refinery_kg = 0 CS_ethanol = np.zeros((len(locations), 1)) CS_refinery_capex = 0 Constraints = [] # constraints ############################## # Cultivation and Harvesting for i in range(0, len(LC)): # Per ha values (need to expand) (CS_per_ha, seeds_per_ha, fertilization_per_ha, lime_per_ha) = CS_cultivation.sim(C_Y[i]) # Capital costs (need to expand) CS_cultivation_capex += DV[i] * LC[i] # Operating costs (need to expand) harvesting = 38.31 * ha_to_acre # $ per ha CS_cultivation_opex += DV[i] * ( seeds_per_ha * .00185 + fertilization_per_ha[0] * 0.55 + fertilization_per_ha[1] * 0.46 + fertilization_per_ha[2] * 0.50 + lime_per_ha * 0.01 + harvesting) #herbicide in per ha?? # Automatic flow to pre-processing hub CS_C2H_prod[i, :] = C2H_map[i, :] * CS_per_ha * DV[i] CS_cultivation_opex += CS_per_ha * DV[i] * (lb_to_kg) * ( 1 / 1500) * 0.50 * C2H[i] # Cultivation constraints (land limits) Constraints.append(DV[i] - LL[i] - 5) #allow some slack in DVs ################################ # Flow to refinery for j in range(0, len(hubs)): for k in range(0, len(locations)): # Mass transfer (1Ms kg of CS) from hub 'j' to hub 'k' CS_flow_matrix[ j, k] = CS_flow_matrix[j, k] + DV[i + 1 + j * len(locations) + k] # Travel costs in bale-miles CS_travel_opex += DM[j, k] * CS_flow_matrix[j, k] * (lb_to_kg) * ( 1 / 1500) * 0.50 for j in range(0, len(hubs)): # Hubs collect biomass from counties CS_hub_kg = sum(CS_C2H_prod[:, j]) # Transportation constraints (all delivery from hub 'j' must be <= mass produced) CS_flow = sum(CS_flow_matrix[j, :]) Constraints.append(CS_flow - CS_hub_kg - 5) #allow some slack in DVs ############################### # Refinery for k in range(0, len(locations)): # Find total mass received at hub 'l' CS_refinery_kg = sum(CS_flow_matrix[:, k]) # Ethanol produced at refinery at hub 'l' CS_ethanol[k] = CS_processing.sim(CS_refinery_kg) # Refinery capex if CS_refinery_kg > 5: scale = CS_refinery_kg / ( 5563 * 142 ) # Based on kg per ha and ha scaling in Jack's TEA file CS_refinery_capex += 400000000 * (scale)**.6 # Sets ethanol production quota (L) Constraints.append(Q * 0.95 - sum(CS_ethanol)[0]) Constraints.append(sum(CS_ethanol)[0] - Q * 1.05) Constraints = list(Constraints) # Returns list of objectives, Constraints return [CS_refinery_capex, CS_travel_opex], Constraints
def QD(groups, reduced_counties, locations): ##################################################################### ########## IMPORT DATA ########################## ##################################################################### # import county level data df_geo = pd.read_excel('geodata_total.xlsx', header=0) counties = list(df_geo['co_state']) #county-to-hub data filename = 'C2H_' + str(groups) + '.xlsx' df_C2H = pd.read_excel(filename, header=0) c = list(df_C2H['co_state']) #eliminate and counties that don't appear in both lists for i in counties: idx = counties.index(i) if i in c: pass else: df_geo = df_geo.drop(index=idx) df_geo = df_geo.reset_index(drop=True) counties = list(df_geo['co_state']) land_costs = df_geo.loc[:, 'land_cost_dpa'].values # $ per acre land_limits = df_geo[ 'land_limits_acre'].values # county ag production area in acres # Corn Stover bu_per_acre_C_yield = df_geo[ 'yield_bpa'].values #yield in bushels per acre ################################ # Convert to function inputs reduced_land_costs = [] reduced_land_limits = [] reduced_C_yield = [] # Hub grouping information, distance look-up tables dist_C2H = [] county_hubs = [] for county in reduced_counties: idx = counties.index(county) reduced_land_costs.append(land_costs[idx]) reduced_land_limits.append(land_limits[idx]) reduced_C_yield.append(bu_per_acre_C_yield[idx]) # distance from each county to pre-defined hub dist_C2H.append(df_C2H.loc[df_C2H['co_state'] == county, 'travel_dist_km'].values[0]) # list of hubs assigned to each county county_hubs.append(df_C2H.loc[df_C2H['co_state'] == county, 'destinationID'].values[0]) # Pre-define location of refineries # put a number > 0 and < number of hubs if desired; if not, problem defaults to full list of hubs #hub-to-hub data filename = 'H2H_' + str(groups) + '.xlsx' df_H2H = pd.read_excel(filename, header=0) hubs = list(df_H2H['OriginID'].unique()) ################################ # Convert to function inputs dist_map = np.zeros((len(hubs), len(locations))) # convert look-up table to distance matrix for i in range(0, len(hubs)): c1 = hubs[i] for j in range(0, len(locations)): c2 = hubs[locations[j] - 1] dist_map[i, j] = df_H2H.loc[(df_H2H['OriginID'] == c1) & (df_H2H['DestinationID'] == c2), 'Total_Kilometers'] map_C2H = np.zeros((len(reduced_counties), len(hubs))) # convert look-up table to distance matrix for i in range(0, len(reduced_counties)): h = int(county_hubs[i]) - 1 map_C2H[i, h] = 1 ##################################################################### ########## FUNCTION DEFINITION ######################## ##################################################################### ################################### #pre-load test decision variables V = [] for i in range(0, len(reduced_counties)): V.append(reduced_land_limits[i] * 0.50) #50% of theoretical capacity LC = reduced_land_costs # land costs per county C_Y = reduced_C_yield # corn yield per acre C2H_map = map_C2H # binary matrix mapping counties (rows) to hubs (columns) locations = locations #possible location of biorefineries, hubs = hubs # Empty parameters CS_flow_matrix = np.zeros((len(hubs), len(locations))) CS_C2H_prod = np.zeros((len(LC), len(hubs))) CS_refinery_kg = 0 CS_ethanol = np.zeros((len(locations), 1)) ############################## # Cultivation and Harvesting for i in range(0, len(LC)): # Per ha values (need to expand) (CS_per_ha, seeds_per_ha, fertilization_per_ha, lime_per_ha) = CS_cultivation.sim(C_Y[i]) # Automatic flow to pre-processing hub CS_C2H_prod[i, :] = C2H_map[i, :] * CS_per_ha * V[i] ################################ # Flow to refinery for j in range(0, len(hubs)): for k in range(0, len(locations)): V.append(sum(CS_C2H_prod[:, j]) * (1 / len(locations))) # Mass transfer (kg of CS) from hub 'j' to hub 'k' CS_flow_matrix[ j, k] = CS_flow_matrix[j, k] + V[i + 1 + j * len(locations) + k] ############################### # Refinery for k in range(0, len(locations)): # Find total mass received at hub 'l' CS_refinery_kg = sum(CS_flow_matrix[:, k]) # Ethanol produced at refinery at hub 'l' CS_ethanol[k] = CS_processing.sim(CS_refinery_kg) ############################### # Upper bound hub 1Ms kgs UB = 0 for j in range(0, len(hubs)): UB = max(UB, sum(CS_C2H_prod[:, j])) return [sum(CS_ethanol[:]), UB]
# Hubs collect biomass from counties CS_hub_kg = sum(CS_C2H_prod[:, j]) # Transportation constraints (all delivery from hub 'j' must be <= mass produced) CS_flow = sum(CS_flow_matrix[j, :]) Constraints.append(CS_flow - CS_hub_kg) ############################### # Refinery for k in range(0, len(locations)): # Find total mass received at hub 'l' CS_refinery_kg = sum(CS_flow_matrix[:, k]) # Ethanol produced at refinery at hub 'l' CS_ethanol[k] = CS_processing.sim(CS_refinery_kg) # Refinery opex # ADD THIS # Refinery capex if CS_refinery_kg > 0: scale = CS_refinery_kg / ( 5563 * 142 ) # Based on kg per ha and ha scaling in Jack's TEA file CS_refinery_capex += 400000000 * (scale)**.6 # Sets ethanol production quota (L) Constraints.append(1100000 - sum(CS_ethanol)) # Constraints.append(sum(CS_ethanol) - 1300000) # Constraints.append(11900000-sum(CS_farm_kg))
def simulate( vars, # cultivation hectares per county, hub-to-hub biomass flows LC = land_costs, # land costs per county C_Y = bu_per_acre_C_yield, # corn yield per acre LL = land_limits, # land limits DM = dist_map, # hub to hub distances C2H_map = map_C2H, # binary matrix mapping counties (rows) to hubs (columns) C2H = dist_C2H # county to hub distances ): # Empty parameters CS_farm_kg = 0 # corn stover production in kg CS_cultivation_capex = 0 CS_cultivation_opex = 0 CS_travel_opex = 0 CS_flow_matrix = np.zeros((len(hubs),len(hubs))) CS_C2H_prod = np.zeros((len(counties),len(hubs))) CS_flow = 0 CS_refinery_kg = 0 CS_ethanol = np.zeros((len(hubs),1)) CS_refinery_opex = 0 CS_refinery_capex = 0 Constraints = [] # constraints ############################## # Cultivation and Harvesting for i in range(0,len(counties)): # Per ha values (need to expand) (CS_per_ha, seeds_per_ha, fertilization_per_ha, lime_per_ha) = CS_cultivation.sim(C_Y[i]) # kg CS produced in given county 'i' CS_farm_kg += CS_per_ha*vars[i] # Capital costs (need to expand) CS_cultivation_capex += vars[i]*LC[i] # Operating costs (need to expand) harvesting = 38.31*ha_to_acre # $ per ha CS_cultivation_opex += vars[i]*(seeds_per_ha*.00185 + fertilization_per_ha[0]*0.55 + fertilization_per_ha[1]*0.46 + fertilization_per_ha[2]*0.50 + lime_per_ha*0.01 + harvesting) #herbicide in per ha?? # Automatic flow to pre-processing hub CS_C2H_prod[i,:] = C2H_map[i,:]*CS_per_ha*vars[i] CS_cultivation_opex += CS_per_ha*vars[i]*(lb_to_kg)*(1/1500)*0.50*C2H[i] # Cultivation constraints (land limits) Constraints.append(vars[i] - LL[i]) ################################ # Flow to refinery for j in range(0,len(hubs)): for k in range(0,len(hubs)): # Mass transfer (kg of CS) from hub 'j' to hub 'k' CS_flow_matrix[j,k] = CS_flow_matrix[j,k] + vars[i + 1 + j*len(hubs) + k] # Travel costs in bale-miles CS_travel_opex += DM[j,k]*CS_flow_matrix[j,k]*(lb_to_kg)*(1/1500)*0.50 for j in range(0,len(hubs)): # Hubs collect biomass from counties CS_hub_kg = sum(CS_C2H_prod[:,j]) # Transportation constraints (all delivery from hub 'j' must be <= mass produced) CS_flow = sum(CS_flow_matrix[j,:]) Constraints.append(CS_flow - CS_hub_kg) DISTANCE VARIABLES ################################ # Refinery for j in range(0,len(hubs)): # Find total mass received at hub 'j' CS_refinery_kg = sum(CS_flow_matrix[:,j]) # Ethanol produced at refinery at hub 'j' CS_ethanol[j] = CS_processing.sim(CS_refinery_kg) # Refinery opex # ADD THIS # Refinery capex ADJUST TO MAKE NON-ZERO if CS_refinery_kg > 0: scale = CS_refinery_kg/(5563*142) # Based on kg per ha and ha scaling in Jack's TEA file CS_refinery_capex+= 400000000*(scale)**.6 # Sets ethanol production quota (L) Constraints.append(11900000-sum(CS_ethanol)) Constraints.append(sum(CS_ethanol) - 12100000) Constraints = list(Constraints) # Returns list of objectives, Constraints return [CS_refinery_capex, CS_travel_opex], Constraints