Пример #1
0
    def f_optim(c):
        '''
        Objective function. Returns the profitability of the system.
        Note that some global variables are used.
        
        Global variables: Demand,eta_inv,eta_bat,CapacityFactorPV,coef,CountryData,
                          Inv, country    
        
        '''
        [r_PV, r_bat] = c
        # if the ratios are negative, set them to zero and add a penalty to the objective function
        penalty_PV = -1E10 * np.minimum(0, r_PV)
        penalty_bat = -1E10 * np.minimum(0, r_bat)
        r_PV = np.maximum(0, r_PV)
        r_bat = np.maximum(0, r_bat)

        E = EnergyFlows(r_PV, r_bat, Demand, eta_inv, eta_bat,
                        CapacityFactorPV, coef)
        F = FinancialAnalysis(E, CountryData, Inv)

        #print 'PV = ' + str(r_PV) + ', BAT = ' + str(r_bat) + ', PR = ' + str(PR) + ', LCOE = ' + str(LCOE)
        return F['LCOE'] + penalty_PV + penalty_bat
Пример #2
0
def SCoptim(CapacityFactorPV, CountryData, Inv, coef, max_RPV=10):
    '''
    Main optimization function
    
    :param CapacityFactorPV: Yearly capacity factor, kWh/kWp
    :param CountryData: Dictionary with the financial variables of the considered country   
    :param Inv: Investment data. Defined as a dictionary with the fields 'FixedPVCost','PVCost_kW','FixedBatteryCost','BatteryCost_kWh','PVLifetime','BatteryLifetime','OM'
    :param coef: Coefficient of the empirical SSR function the number of coefficients depends on the version of the function
    
    :return: list with the optimal values [r_pv, r_bat, LCOE]
    '''

    # Checking that country data is a dictionary:
    if not isinstance(CountryData, dict):
        sys.exit('CountryData must be a dictionnary in the SCoptim function')

    # Definition of the objective functionS of the optimization
    def f_optim(c):
        '''
        Objective function. Returns the profitability of the system.
        Note that some global variables are used.
        
        Global variables: Demand,eta_inv,eta_bat,CapacityFactorPV,coef,CountryData,
                          Inv, country    
        
        '''
        [r_PV, r_bat] = c
        # if the ratios are negative, set them to zero and add a penalty to the objective function
        penalty_PV = -1E10 * np.minimum(0, r_PV)
        penalty_bat = -1E10 * np.minimum(0, r_bat)
        r_PV = np.maximum(0, r_PV)
        r_bat = np.maximum(0, r_bat)

        E = EnergyFlows(r_PV, r_bat, Demand, eta_inv, eta_bat,
                        CapacityFactorPV, coef)
        F = FinancialAnalysis(E, CountryData, Inv)

        #print 'PV = ' + str(r_PV) + ', BAT = ' + str(r_bat) + ', PR = ' + str(PR) + ', LCOE = ' + str(LCOE)
        return F['LCOE'] + penalty_PV + penalty_bat

    def f_optim_0(c):
        '''
        Objective function. Returns the profitability of the system with r_bat = 0.
        Note that some global variables are used.
        
        Global variables: Demand,eta_inv,eta_bat,CapacityFactorPV,coef,CountryData,
                          Inv, country    
        
        '''
        [r_PV] = c
        r_bat = 0
        # if the ratios are negative, set them to zero and add a penalty to the objective function
        penalty_PV = -1E10 * np.minimum(0, r_PV)
        penalty_bat = -1E10 * np.minimum(0, r_bat)
        r_PV = np.maximum(0, r_PV)
        r_bat = np.maximum(0, r_bat)

        E = EnergyFlows(r_PV, r_bat, Demand, eta_inv, eta_bat,
                        CapacityFactorPV, coef)
        F = FinancialAnalysis(E, CountryData, Inv)

        #print 'PV = ' + str(r_PV) + ', BAT = ' + str(r_bat) + ', PR = ' + str(PR) + ', LCOE = ' + str(LCOE)
        return F['LCOE'] + penalty_PV + penalty_bat

    def f_optim_fixedPV(c):
        '''
        Objective function. Returns the profitability of the system with r_PV fixed.
        Note that some global variables are used.
        
        Global variables: Demand,eta_inv,eta_bat,CapacityFactorPV,coef,CountryData,
                          Inv, country    
        
        '''
        r_PV = max_RPV
        [r_bat] = c
        # if the ratios are negative, set them to zero and add a penalty to the objective function
        penalty_PV = -1E10 * np.minimum(0, r_PV)
        penalty_bat = -1E10 * np.minimum(0, r_bat)
        r_PV = np.maximum(0, r_PV)
        r_bat = np.maximum(0, r_bat)

        E = EnergyFlows(r_PV, r_bat, Demand, eta_inv, eta_bat,
                        CapacityFactorPV, coef)
        F = FinancialAnalysis(E, CountryData, Inv)

        #print 'PV = ' + str(r_PV) + ', BAT = ' + str(r_bat) + ', PR = ' + str(PR) + ', LCOE = ' + str(LCOE)
        return F['LCOE'] + penalty_PV + penalty_bat

    # Constraints:
    cons = ({
        'type': 'ineq',
        'fun': lambda x: x[0]
    }, {
        'type': 'ineq',
        'fun': lambda x: x[1]
    })
    bnds = ((0, max_RPV), (0, 10))

    # Hard coded system efficiencies:
    eta_inv = 0.96
    eta_bat = 0.92
    Demand = 3500

    # Since there are 3 discrete variants of the problem, the optimization is performed 3 times and the best one is selected
    # With PV and Battery:
    result = optimize.minimize(f_optim, [1.1, 1.1],
                               method='Nelder-Mead',
                               tol=1e-5,
                               constraints=cons,
                               bounds=bnds).values()
    # With PV, without Battery
    result2 = optimize.minimize(f_optim_0, [1.1],
                                method='Nelder-Mead',
                                tol=1e-5,
                                constraints=cons,
                                bounds=bnds).values()
    # Without PV, without battery:
    E_0 = EnergyFlows(0, 0, Demand, eta_inv, eta_bat, CapacityFactorPV, coef)
    F_0 = FinancialAnalysis(E_0, CountryData, Inv)
    # Selecting the best solution:
    if F_0 <= result2[4] and F_0 <= result[4]:
        r_PV = 0
        r_bat = 0
        LCOE = F_0
    elif result2[4] <= F_0 and result2[4] <= result[4]:
        r_PV = result2[5][0]
        r_bat = 0
        LCOE = result2[4]
    elif result[4] <= F_0 and result[4] <= result2[4]:
        r_PV = result[5][0]
        r_bat = result[5][1]
        LCOE = result[4]

    # if r_PV is unbounded, do the univariate optimization with its max value
    if r_PV > max_RPV:
        result_fixedPV = optimize.minimize(f_optim_fixedPV, [1.1],
                                           method='Nelder-Mead',
                                           tol=1e-5,
                                           constraints=cons,
                                           bounds=bnds).values()
        E_fixedPV = EnergyFlows(max_RPV, 0, Demand, eta_inv, eta_bat,
                                CapacityFactorPV, coef)
        F_fixedPV = FinancialAnalysis(E_fixedPV, CountryData, Inv)
        if F_fixedPV <= result_fixedPV[3]:
            r_PV = max_RPV
            r_bat = 0
            LCOE = F_fixedPV
        else:
            r_PV = max_RPV
            r_bat = result_fixedPV[5][0]
            LCOE = result_fixedPV[4]

    return [r_PV, r_bat, LCOE]
Пример #3
0
costs = np.arange(100,250,2)  
LCOEs = []
BAT = []
PV=[]
LCOE_stor = []    

for c in costs:
    # Optimisation
    Inv['BatteryCost_kWh'] = c
    [r_PV, r_bat, LCOE] = SCoptim(CapacityFactorPV,CountryData.loc[country,:].to_dict(),Inv,coef)
    BAT.append(r_bat)    
    LCOEs.append(LCOE)
    PV.append(r_PV)
    
    # Recalculating the whole set of values with the optimum inputs:
    E = EnergyFlows(r_PV,r_bat,Demand,eta_inv,eta_bat,CapacityFactorPV,coef)
    F = FinancialAnalysis(E,CountryData.loc[country,:].to_dict(),Inv)
    LCOE_stor.append(F['LCOE_stor'])


# Plotting:
fig4 = plt.figure(2,figsize=[7,5])
plt.subplot(211)
plt.plot(costs,BAT,linestyle='--',linewidth=2, marker='o',label='Battery')
plt.plot(costs,PV,label='PV', marker='o',linewidth=2)
plt.ylabel('Relative PV/Battery sizes [-]')
plt.ylim(0,2.5)
plt.legend(fontsize=16)
plt.grid()
#remove xaxis:
ax = plt.gca()