Ejemplo n.º 1
0
def retrofithub(Lin_cap_costs,Fixed_cap_costs,Lin_EE,Fixed_EE,CMatrix,STTech,PVTech,GSHPTech,htech,Horizon,Biomass_potential,Roof_area,Bldg_area,ExistingSystem,Retrofit_costs,Retrofit_EE,Loads,Days,PeakLoad,P_solar,inp,inp2,stor,ret,ex_tech,TechStor,TechInp,AnnuityRet,AnnuityStor,AnnuityInput,AnnuityUnderfloor,FIT,Cost_underfloor,Embodied_underfloor,Lifetime_underfloor,Embodied_boreholes,Lifetime_boreholes,gap):
    from docplex.mp.model import Model
    from docplex.util.environment import get_environment
    mdl = Model(name='LCA_retrofithub')
    ##VARIABLE DECLARATION
    mdl.Pin=mdl.continuous_var_matrix(Horizon,inp,lb=0,name='Pin') #Incoming power for conversion technologies
    mdl.P_export=mdl.continuous_var_matrix(Horizon,stor,lb=0,name='P_export') #Energy exported out of the building
    mdl.y=mdl.binary_var_list(inp2,name='y') #Binary value indicating whether or not a technology is installed
    mdl.Capacity=mdl.continuous_var_list(inp2,lb=0,name='Capacity') #Capacity of conversion technologies (in kW)
    mdl.y_retrofit=mdl.binary_var_list(ret,name='y_retrofit') #Binary indicating which retrofit option is installed (no retrofit, roof, facade, window, basement, window-facade, full retrofit). This variable decides which building demands are used.
    mdl.y_underfloor=mdl.binary_var(name='y_underfloor') #Binary indicating the installation of underfloor heating (required for installation of heat pumps in old buildings <1990)
    #Storage
    mdl.Qin=mdl.continuous_var_matrix(Horizon,stor,lb=0,name='Qin') #Hourly charging of energy storages
    mdl.Qout=mdl.continuous_var_matrix(Horizon,stor,lb=0,name='Qout') #Hourly discharging of energy storages
    mdl.E=mdl.continuous_var_matrix(Horizon,stor,lb=0,name='E') #Hour energy levels for energy storage
    mdl.Storage_cap=mdl.continuous_var_list(stor,lb=0,name='Storage_cap') #Capacity of energy storages (in kWh)
    mdl.y_stor=mdl.binary_var_list(stor,name='y_stor') #Binary variable indicating whether or not a storage system is installed
    #Dummy variables
    mdl.dummy=mdl.continuous_var_cube(Horizon,inp,ret,lb=0,name='dummy')#dummy for conversion tech (Represents mdl.Pin*mdl.y_retrofit). This is pushed with the constraints on lines 43-47
    mdl.dummer=mdl.continuous_var_cube(Horizon,stor,ret,lb=0,name='dummer')#dummy for storage (Represents mdl.P_export*mdl.y_retrofit). This is pushed with the constraints on lines 55-60
    mdl.dummy_pv=mdl.continuous_var_matrix(stor,ret,lb=0,name='dummy_pv')#dummy PV variable (Represents Capacity["PV"]*y_retrofit[r]). This is pushed with the constraints on lines 61-65
    mdl.dummy_st=mdl.continuous_var_matrix(stor,ret,lb=0,name='dummy_st')#dummy Storage variable (Represents Capacity["ST"]*y_retrofit[r]). This is pushed with the constraints on lines 66-70
    #Cost objective variables
    mdl.Operating_cost=mdl.continuous_var(lb=0,name='Operating_cost') #Total operating costs for energy carriers used in the building
    mdl.Income_via_exports=mdl.continuous_var(lb=0,name='Income_via_exports') #Profits from selling electricity (feed-in renumeration)
    mdl.Investment_cost_tech=mdl.continuous_var(lb=0,name='Investment_cost_tech') #Investment cost of conversion technologies (PV + heating system)
    mdl.Investment_cost_stor=mdl.continuous_var(lb=0,name='Investment_cost_stor') #Investment cost of storage technologies
    mdl.Investment_cost_ret=mdl.continuous_var(lb=0,name='Inveestment_cost_ret') #Investment cost of retrofit options
    mdl.Total_cost=mdl.continuous_var(lb=0,name='Total_cost') #Total costs to minimize
    #CO2 emissions objective variables
    mdl.Operating_emissions=mdl.continuous_var(lb=0,name='Operating_emissions') #Total CO2 emissions from energy carriers used within the building
    mdl.Embodied_system_emissions=mdl.continuous_var(lb=0,name='Embodied_system_emissions') #Embodied/grey CO2 emissions from conversion technologies (heating system + PV)
    mdl.Embodied_boreholes=mdl.continuous_var(lb=0,name='Embodied_boreholes') #Embodied/grey emissions from boreholes (Only for GSHP)
    mdl.Embodied_storage=mdl.continuous_var(lb=0,name='Embodied_storage') #Embodied/grey emissions from storages (Only if installed)
    mdl.Embodied_retrofit=mdl.continuous_var(lb=0,name='Embodied_retrofit') #Embodied/grey emissions from retrofit materials
    mdl.Embodied_underfloor=mdl.continuous_var(lb=0,name='Embodied_underfloor') #Embodied/grey emissions from underfloor heating (if used)
    mdl.Total_carbon = mdl.continuous_var(lb=0,name='Total_carbon') #Total CO2 emissions to minimize or used in the epsilon constraint
    ##CONSTRAINT DECLARATION
    #Dummy variable constraints (equates Pin[h,i]*y_retrofit[r])
    mdl.add_constraints(mdl.dummy[h,i,r]>=0 for h in Horizon for i in inp for r in ret)
    mdl.add_constraints(mdl.dummy[h,i,r]<=50000*mdl.y_retrofit[r] for h in Horizon for i in inp for r in ret)
    mdl.add_constraints(mdl.Pin[h,i]-mdl.dummy[h,i,r]>=0 for h in Horizon for i in inp for r in ret)
    mdl.add_constraints(mdl.Pin[h,i]-mdl.dummy[h,i,r]<=50000*(1-mdl.y_retrofit[r]) for h in Horizon for i in inp for r in ret)
    #Maximum allowable storage capacities based on available building area
    mdl.add_constraint(mdl.Storage_cap[0]<=Bldg_area/58*1.5)#Hot water storage
    mdl.add_constraint(mdl.Storage_cap[1]<=Bldg_area/122*1.5)#Cold water storage
    mdl.add_constraint(mdl.Storage_cap[2]<=Bldg_area*0.1)#Battery
    #Limit to one space heating system which can be installed
    mdl.add_constraint(mdl.sum(mdl.y[ht] for ht in htech)==1)
    #Dummer variable constraint (equates P_export[h,s]*y_retrofit[r])
    mdl.add_constraints(mdl.dummer[h,s,r]>=0 for h in Horizon for s in stor for r in ret)
    mdl.add_constraints(mdl.dummer[h,s,r]<=50000*mdl.y_retrofit[r] for h in Horizon for s in stor for r in ret)
    mdl.add_constraints(mdl.P_export[h,s]-mdl.dummer[h,s,r]>=0 for h in Horizon for s in stor for r in ret)
    mdl.add_constraints(mdl.P_export[h,s]-mdl.dummer[h,s,r]<=50000*(1-mdl.y_retrofit[r])for h in Horizon for s in stor for r in ret)
    mdl.add_constraints(mdl.P_export[h,s]==0 for h in Horizon for s in stor if s!=2) #Only the electrical energy carrier can be exported from building
    #Dummy PV variable constraints (equates Capacity["PV"]*y_retrofit[r])
    mdl.add_constraints(mdl.dummy_pv[s,r]>=0 for s in stor for r in ret)
    mdl.add_constraints(mdl.dummy_pv[s,r]<=50000*mdl.y_retrofit[r] for r in ret for s in stor)
    mdl.add_constraints(mdl.Capacity[PVTech]-mdl.dummy_pv[s,r]>=0 for r in ret for s in stor)
    mdl.add_constraints(mdl.Capacity[PVTech]-mdl.dummy_pv[s,r]<=50000*(1-mdl.y_retrofit[r])for r in ret for s in stor)
    #Dummy solar thermal variable constraints (equates Capacity["ST"]*y_retrofit[r])
    mdl.add_constraints(mdl.dummy_st[s,r]>=0 for r in ret for s in stor)
    mdl.add_constraints(mdl.dummy_st[s,r]<=50000*mdl.y_retrofit[r] for r in ret for s in stor)
    mdl.add_constraints(mdl.Capacity[STTech]-mdl.dummy_st[s,r]>=0 for r in ret for s in stor)
    mdl.add_constraints(mdl.Capacity[STTech]-mdl.dummy_st[s,r]<=50000*(1-mdl.y_retrofit[r])for r in ret for s in stor)
    #Fixed cost constraint (Binary must equal 1 if the capacity is >0)
    mdl.add_constraints(mdl.Capacity[i]<=50000*mdl.y[i] for i in inp2)
    #Load balance (Total conversion technology production + storage discharge - storage charge = Energy demand + exported energy)
    mdl.add_constraints(mdl.sum(mdl.Pin[h,i]*CMatrix[s,i] for i in inp)+mdl.Qout[h,s]-mdl.Qin[h,s]==mdl.sum(mdl.y_retrofit[r]*Loads[h,s,r] for r in ret)+mdl.P_export[h,s] for s in stor for h in Horizon)
    #Capacity constraint (Total power output of the conversion technology must be less than or equal to the capacity for dispatcable converstion tech, i.e. all except PV)
    mdl.add_constraints(mdl.Pin[h,i]*CMatrix[(s,i)]<=mdl.Capacity[i] for i in inp2 for s in stor for h in Horizon)
    #Solar PV constraint (PV production must equal the solar incidence times the efficiency)
    mdl.add_constraints(mdl.Pin[h,PVTech]==mdl.sum(P_solar[h,r]*mdl.dummy_pv[2,r] for r in ret) for h in Horizon)
    #Solar Storage constraint (Solar thermal production must equal the solar incidence times the efficiency)
    mdl.add_constraints(mdl.Pin[h,STTech]==mdl.sum(P_solar[h,r]*mdl.dummy_st[0,r]for r in ret)for h in Horizon)
    #Max elements (only one heating system can be installed)
    mdl.add_constraints(mdl.sum(mdl.y[d] for d in htech)<=1 for s in stor)
    #Roof area constraints (PV and Solar thermal install area must be less than max area)
    mdl.add_constraint(mdl.Capacity[PVTech]+mdl.Capacity[STTech]<=Roof_area)
    #Storage balance
    for h in Horizon:
        if (h==0) or (h==24) or (h==48) or (h==72) or (h==96) or (h==120) or (h==144) or (h==168) or (h==192) or (h==216): #First hour of the day
            mdl.add_constraints(mdl.E[h,s]==TechStor[s].decay*mdl.E[h+23,s]+TechStor[s].chg_eff*mdl.Qin[h,s]-(1/TechStor[s].dch_eff)*mdl.Qout[h,s] for s in stor)
        else: #All other hours of the day
            mdl.add_constraints(mdl.E[h,s]==TechStor[s].decay*mdl.E[h-1,s]+TechStor[s].chg_eff*mdl.Qin[h,s]-(1/TechStor[s].dch_eff)*mdl.Qout[h,s] for s in stor)
    #Storage charge limit
    mdl.add_constraints(mdl.Qin[h,s]<=TechStor[s].max_charge*mdl.Storage_cap[s] for h in Horizon for s in stor)
    #Storage discharge limit
    mdl.add_constraints(mdl.Qout[h,s]<=TechStor[s].max_discharge*mdl.Storage_cap[s] for h in Horizon for s in stor)
    #Storage capacity constraint
    mdl.add_constraints(mdl.E[h,s]<=mdl.Storage_cap[s] for h in Horizon for s in stor)
    #Fixed cost storage
    mdl.add_constraints(mdl.Storage_cap[s]<=100000*mdl.y_stor[s] for s in stor)
    #Only one retrofit state
    mdl.add_constraint(mdl.sum(mdl.y_retrofit[r] for r in ret)==1)
    #Need for underfloor if building is old and ASHP installed. Also ensure that windows are replace if the building is old for ASHP
    mdl.add_constraint(mdl.y_underfloor>=(mdl.sum(mdl.y_retrofit[r] for r in range(0,5))+mdl.y[6]+mdl.y[GSHPTech]-1.5)/2)
    #Existing system size
    mdl.add_constraints(mdl.Capacity[e]==PeakLoad[0,0]*mdl.y[e] for e in ex_tech)
    #Existing system install
    mdl.add_constraints(mdl.y[e]==0 for e in ex_tech if e!=ExistingSystem)
    #Restrict export of systems
    mdl.add_constraints(mdl.dummer[h,2,r]<=mdl.dummy[h,PVTech,r] for r in ret for h in Horizon)
    #Restriction of biomass
    mdl.add_constraints(mdl.sum((mdl.dummy[h,3,r]+mdl.dummy[h,10,r])*(Days[h,r]) for h in Horizon)<=Bldg_area*Biomass_potential for r in ret)
    ##Calculate objective function variables
    #Operating cost
    mdl.add_constraint(mdl.Operating_cost==mdl.sum(TechInp[i].operating_costs*Days[h,r]*mdl.dummy[h,i,r] for h in Horizon for i in inp for r in ret))
    # Income from selling PV at FIT
    mdl.add_constraint(mdl.Income_via_exports==mdl.sum(FIT*Days[h,r]*mdl.dummer[h,2,r] for h in Horizon for r in ret))
    #Calculate the total cost to be minimized
    mdl.add_constraint(mdl.Investment_cost_tech==mdl.sum((Fixed_cap_costs[(i)]*mdl.y[i]+Lin_cap_costs[(i)]*mdl.Capacity[i])*AnnuityInput[i] for i in inp2))
    mdl.add_constraint(mdl.Investment_cost_stor==mdl.sum((TechStor[s].fixed_cap_costs*mdl.y_stor[s]+TechStor[s].linear_cap_costs*mdl.Storage_cap[s])*AnnuityStor[s] for s in stor))
    mdl.add_constraint(mdl.Investment_cost_ret==mdl.sum((Retrofit_costs[r]*mdl.y_retrofit[r])*AnnuityRet[r] for r in ret)+(AnnuityUnderfloor*Cost_underfloor*mdl.y_underfloor*Bldg_area))
    mdl.add_constraint(mdl.Total_cost==mdl.Investment_cost_tech+mdl.Investment_cost_stor+mdl.Investment_cost_ret+mdl.Operating_cost-mdl.Income_via_exports)
    #Calculate the total CO2 emissions to be minimized constrained (epsilon constraint) for intermediate multi-objective solutions
    mdl.add_constraint(mdl.Embodied_system_emissions==mdl.sum((Lin_EE[(i)]*mdl.Capacity[i]+Fixed_EE[(i)]*mdl.y[i])/TechInp[i].lifetime for i in inp2))
    mdl.add_constraint(mdl.Embodied_storage==mdl.sum((TechStor[s].embodied_linear*mdl.Storage_cap[s]+TechStor[s].embodied_fixed*mdl.y_stor[s])/TechStor[s].lifetime for s in stor))
    mdl.add_constraint(mdl.Embodied_retrofit==mdl.sum(Retrofit_EE[r]*mdl.y_retrofit[r]/40 for r in ret))
    mdl.add_constraint(mdl.Embodied_underfloor==Embodied_underfloor*mdl.y_underfloor*Bldg_area/Lifetime_underfloor)
    mdl.add_constraint(mdl.Embodied_boreholes==mdl.Capacity[GSHPTech]/0.03*Embodied_boreholes/Lifetime_boreholes)
    mdl.add_constraint(mdl.Operating_emissions==mdl.sum(TechInp[i].carbon_factor*Days[h,r]*mdl.dummy[h,i,r] for h in Horizon for i in inp for r in ret))
    mdl.add_constraint(mdl.Total_carbon==mdl.Embodied_system_emissions+mdl.Embodied_storage+mdl.Embodied_retrofit+mdl.Embodied_underfloor+mdl.Embodied_boreholes+mdl.Operating_emissions)
    mdl.parameters.mip.tolerances.mipgap = gap
    return mdl