def getModelNormalResults(): # ============================================================================= # DESPACHO NORMAL # ============================================================================= DN = np.load('results\\EVALNOSIPS_D.npy') BN = np.load('results\\EVALNOSIPS_B.npy') LN = np.load('results\\EVALNOSIPS_L.npy') GN = np.load('results\\EVALNOSIPS_G.npy') NN = np.load('results\\EVALNOSIPS_N.npy') numHrs = range(24) numSce = range(7) realcost = 0 GENDATA, DEMDATA, LINDATA, STODATA = ld.loadsystemdata() genBar = GENDATA[:, 1] CV = GENDATA[:, 2] CRUP = GENDATA[:, 3] CRDOWN = GENDATA[:, 4] CENC = GENDATA[:, 5] CAPG = GENDATA[:, 6] RUPMAX = GENDATA[:, 7] RDOWNMAX = GENDATA[:, 8] PMAXGEN = GENDATA[:, 9] PMINGEN = GENDATA[:, 10] QMAXGEN = GENDATA[:, 11] QMINGEN = GENDATA[:, 12] AA, BB, PROB = ld.loadscendata() DEM = DEMDATA[:, 1] CDLS = DEMDATA[:, 3] PREAL = np.ndarray((3, 7, 24)) CBAT = abs(STODATA[:, 2]) CENS = 10000 for t in numHrs: for s in numSce: PG = GN[t, s, :, 0] DM = DN[t, s, :, 0] if s == 0: realcost = realcost + CV.dot(PG) else: crup = CRUP.dot(PG - PREAL[:, 0, t]) if (crup < 0): crup = 0 crdown = CRDOWN.dot(PREAL[:, 0, t] - PG) if (crdown < 0): crdown = 0 ens = sum(DM) - sum(PG) if (ens > 0): cdns = CENS * ens else: cdns = 0 realcost = realcost + PROB[s - 1] * ( CV.dot(PG + crup + crdown) + cdns) print('Costos Totales Reales modelo No relajado', realcost)
def relaxLine(lin, relaxcapacity, verbose=False): """ Realiza Optimización de Despacho con Seguridad para horizonte de tiempo con relajo de restricciones. """ # ============================================================================= # READ DATA # ============================================================================= M = 10000 NGen = 3 NLin = 3 NBar = 3 NHrs = 24 NEle = NGen + NLin NFal = NGen + NLin NSce = NFal + 1 numLin = range(NLin) numBar = range(NBar) numGen = range(NGen) numFal = range(NFal) numEle = range(NEle) numSce = range(NSce) numHrs = range(NHrs) numScF = range(1, NSce) GENDATA, DEMDATA, LINDATA, STODATA = ld.loadsystemdata() #Generator data genBar = GENDATA[:, 1] CV = GENDATA[:, 2] CRUP = GENDATA[:, 3] CRDOWN = GENDATA[:, 4] CENC = GENDATA[:, 5] CAPG = GENDATA[:, 6] RUPMAX = GENDATA[:, 7] RDOWNMAX = GENDATA[:, 8] PMAXGEN = GENDATA[:, 9] PMINGEN = GENDATA[:, 10] QMAXGEN = GENDATA[:, 11] QMINGEN = GENDATA[:, 12] #Demand data DPMAX = DEMDATA[:, 1] DQMAX = DEMDATA[:, 2] #Line data FMAX = LINDATA[:, 1] XL = LINDATA[:, 4] #Scenarios data A, B, PROB = ld.loadscendata() #Demand data DEMRES, DEMIND, DEMCOM = ld.loadcurvedata() D = np.array([DPMAX[0] * DEMRES, DPMAX[1] * DEMIND, DPMAX[2] * DEMCOM]) # ============================================================================= # COSTO ENERGIA NO SUMINISTRADA # ============================================================================= CENS = 10000 #Usd/MW # ============================================================================= # ADD MORE CAPACITY TO LINE TO RELAX CONSTRAINT # ============================================================================= FMAXP = FMAX.copy() if type(lin) is list: for (l, rc) in zip(lin, relaxcapacity): FMAXP[l] = rc * FMAXP[l] elif type(lin) is int: FMAXP[lin] = relaxcapacity * FMAXP[lin] # ============================================================================= # DEFINE VARIABLES # ============================================================================= #Define problem model = gp.Model("Model") if not verbose: model.setParam('OutputFlag', 0) else: model.setParam('OutputFlag', 1) #Variables p = model.addVars(NGen, NSce, NHrs, vtype=GRB.CONTINUOUS) x = model.addVars(NGen, NHrs, vtype=GRB.BINARY) e = model.addVars(NGen, NHrs, vtype=GRB.BINARY) a = model.addVars(NGen, NHrs, vtype=GRB.BINARY) f = model.addVars(NLin, NSce, NHrs, vtype=GRB.CONTINUOUS, lb=-GRB.INFINITY) theta = model.addVars(NBar, NSce, NHrs, vtype=GRB.CONTINUOUS, lb=-GRB.INFINITY) rup = model.addVars(NGen, NSce, NHrs, vtype=GRB.CONTINUOUS) rdown = model.addVars(NGen, NSce, NHrs, vtype=GRB.CONTINUOUS) xrup = model.addVars(NGen, NSce, NHrs, vtype=GRB.BINARY) xrdown = model.addVars(NGen, NSce, NHrs, vtype=GRB.BINARY) dns = model.addVars(NBar, NSce, NHrs, vtype=GRB.CONTINUOUS) #Objective Function Objective = quicksum( quicksum(CV[g] * p[g, 0, t] + CENC[g] * e[g, t] + CAPG[g] * a[g, t] + dns[g, 0, t] * CENS for g in numGen) + quicksum(PROB[s - 1] * quicksum(CV[g] * p[g, s, t] + CRUP[g] * rup[g, s, t] + CRDOWN[g] * rdown[g, s, t] + dns[g, s, t] * CENS for g in numGen) for s in numScF) for t in numHrs) #Contraints #Turn on and Turn Off machines for g in numGen: model.addConstr(x[g, 0] == e[g, 0] - a[g, 0]) for t in range(2, NHrs): for g in numGen: model.addConstr(x[g, t] == x[g, t - 1] + e[g, t] - a[g, t]) for t in range(3, NHrs): for g in numGen: model.addConstr(x[g, t] >= quicksum(e[g, k] for k in range(t - 3, t))) model.addConstr(1 - x[g, t] >= quicksum(a[g, k] for k in range(t - 3, t))) for g in numGen: model.addConstr(x[g, 0] >= e[g, 0]) model.addConstr(1 - x[g, 0] >= a[g, 0]) for g in numGen: model.addConstr(x[g, 1] >= quicksum(e[g, k] for k in range(2))) model.addConstr(1 - x[g, 1] >= quicksum(a[g, k] for k in range(2))) for g in numGen: model.addConstr(x[g, 2] >= quicksum(e[g, k] for k in range(3))) model.addConstr(1 - x[g, 2] >= quicksum(a[g, k] for k in range(3))) #Limits of Generators for t in numHrs: for s in numSce: for g in numGen: model.addConstr( p[g, 0, t] + rup[g, s, t] <= PMAXGEN[g] * x[g, t]) model.addConstr( p[g, 0, t] - rdown[g, s, t] >= PMINGEN[g] * x[g, t]) model.addConstr(rup[g, s, t] <= RUPMAX[g] * xrup[g, s, t]) model.addConstr( rdown[g, s, t] <= RDOWNMAX[g] * xrdown[g, s, t]) model.addConstr(xrup[g, s, t] + xrdown[g, s, t] <= 1) #Reserves are 0 for the base case scenario for t in numHrs: for g in numGen: model.addConstr(xrup[g, 0, t] + xrdown[g, 0, t] == 0) #Nodal Balancing por scenarios pre and post failure for t in numHrs: for s in numSce: model.addConstr(p[0, s, t] == D[0, t] + f[0, s, t] + f[2, s, t] - dns[0, s, t]) model.addConstr(p[1, s, t] + f[0, s, t] == D[1, t] + f[1, s, t] - dns[1, s, t]) model.addConstr(p[2, s, t] + f[2, s, t] + f[1, s, t] == D[2, t] - dns[2, s, t]) #Availability of elements for t in numHrs: for s in numSce: #Availability of generators for g in numGen: model.addConstr(p[g, s, t] <= A[g, s] * (p[g, 0, t] + rup[g, s, t])) model.addConstr(p[g, s, t] >= A[g, s] * (p[g, 0, t] - rdown[g, s, t])) model.addConstr(f[0, s, t] <= 1 / XL[0] * (theta[0, s, t] - theta[1, s, t]) + M * (1 - B[0, s])) model.addConstr(f[0, s, t] >= 1 / XL[0] * (theta[0, s, t] - theta[1, s, t]) - M * (1 - B[0, s])) model.addConstr(f[1, s, t] <= 1 / XL[1] * (theta[1, s, t] - theta[2, s, t]) + M * (1 - B[1, s])) model.addConstr(f[1, s, t] >= 1 / XL[1] * (theta[1, s, t] - theta[2, s, t]) - M * (1 - B[1, s])) model.addConstr(f[2, s, t] <= 1 / XL[2] * (theta[0, s, t] - theta[2, s, t]) + M * (1 - B[2, s])) model.addConstr(f[2, s, t] >= 1 / XL[2] * (theta[0, s, t] - theta[2, s, t]) - M * (1 - B[2, s])) #Capacity of lines in scenario base 0 for t in numHrs: for l in numLin: model.addConstr(f[l, 0, t] <= FMAX[l] * B[l, 0]) #scenario 0: must respect limits model.addConstr( f[l, 0, t] >= -1 * FMAX[l] * B[l, 0] ) #scenarios of contingencies can violate limits until a treshhold #Capacity of lines relaxed for scenarios of contingencies for t in numHrs: for s in numScF: for l in numLin: model.addConstr(f[l, s, t] <= FMAXP[l] * B[l, s]) model.addConstr(f[l, s, t] >= -1 * FMAXP[l] * B[l, s]) # ============================================================================= # RUN MODEL # ============================================================================= model.setObjective(Objective, GRB.MINIMIZE) model.optimize() print('Costos Totales modelo relajado', model.objVal) # ============================================================================= # SAVE RESULTS # ============================================================================= psol = np.array([[[p[g, s, t].X for t in numHrs] for s in numSce] for g in numGen]) xsol = np.array([[x[g, t].X for t in numHrs] for g in numGen]) esol = np.array([[e[g, t].X for t in numHrs] for g in numGen]) asol = np.array([[a[g, t].X for t in numHrs] for g in numGen]) fsol = np.array([[[f[l, s, t].X for t in numHrs] for s in numSce] for l in numLin]) thetasol = np.array([[[theta[n, s, t].X for t in numHrs] for s in numSce] for n in numBar]) rupsol = np.array([[[rup[g, s, t].X for t in numHrs] for s in numSce] for g in numGen]) rdownsol = np.array([[[rdown[g, s, t].X for t in numHrs] for s in numSce] for g in numGen]) xrupsol = np.array([[[xrup[g, s, t].X for t in numHrs] for s in numSce] for g in numGen]) xrdownsol = np.array([[[xrdown[g, s, t].X for t in numHrs] for s in numSce] for g in numGen]) dnssol = np.array([[[dns[g, s, t].X for t in numHrs] for s in numSce] for g in numGen]) # print(dnssol) np.save('results\\ECOPSOL', psol) np.save('results\\ECOXSOL', xsol) np.save('results\\ECOESOL', esol) np.save('results\\ECOASOL', asol) np.save('results\\ECOFSOL', fsol) np.save('results\\ECOTHETASOL', thetasol) np.save('results\\ECORUPSOL', rupsol) np.save('results\\ECORDOWNSOL', rdownsol) np.save('results\\ECOXRUPSOL', xrupsol) np.save('results\\ECOXRDOWNSOL', xrdownsol) np.save('results\\ECODEM', D) return model.objVal
def getModelRelaxResults(): mdr.relaxLine([1, 2], [1.4, 1.4]) datacont1 = cont.getInstancesLineLimitsViolations1(tolerance=1.1) datacont2 = cont.getInstancesLineLimitsViolations2(tolerance=1.05) datacont3 = cont.getInstancesLineLimitsViolations3(tolerance=1.1) # sm.despachonormal(datacont3,relax_vm=[0.95, 1.05]) # sm.redespacho(datacont2,relax_vm=[0.95, 1.05]) # sm.sips(datacont1,relax_vm=[0.95, 1.05],print_results = True, verbose=True) # SIMLIN = np.load('results\\SIMLIN.npy') # ============================================================================= # SOBRE 110 # ============================================================================= D = np.load('results\\EVALSIPSBATTERYLOADSHEDDING_D.npy') B = np.load('results\\EVALSIPSBATTERYLOADSHEDDING_B.npy') L = np.load('results\\EVALSIPSBATTERYLOADSHEDDING_L.npy') G = np.load('results\\EVALSIPSBATTERYLOADSHEDDING_G.npy') N = np.load('results\\EVALSIPSBATTERYLOADSHEDDING_N.npy') # ============================================================================= # ENTRE 100 Y 110 # ============================================================================= D2 = np.load('results\\EVALSIPSBATTERYLOADSHEDDING_D2.npy') B2 = np.load('results\\EVALSIPSBATTERYLOADSHEDDING_B2.npy') L2 = np.load('results\\EVALSIPSBATTERYLOADSHEDDING_L2.npy') G2 = np.load('results\\EVALSIPSBATTERYLOADSHEDDING_G2.npy') N2 = np.load('results\\EVALSIPSBATTERYLOADSHEDDING_N2.npy') # ============================================================================= # MENOR A 100 # ============================================================================= D3 = np.load('results\\EVALSIPSBATTERYLOADSHEDDING_D3.npy') B3 = np.load('results\\EVALSIPSBATTERYLOADSHEDDING_B3.npy') L3 = np.load('results\\EVALSIPSBATTERYLOADSHEDDING_L3.npy') G3 = np.load('results\\EVALSIPSBATTERYLOADSHEDDING_G3.npy') N3 = np.load('results\\EVALSIPSBATTERYLOADSHEDDING_N3.npy') numHrs = range(24) numSce = range(7) realcost = 0 GENDATA, DEMDATA, LINDATA, STODATA = ld.loadsystemdata() genBar = GENDATA[:, 1] CV = GENDATA[:, 2] CRUP = GENDATA[:, 3] CRDOWN = GENDATA[:, 4] CENC = GENDATA[:, 5] CAPG = GENDATA[:, 6] RUPMAX = GENDATA[:, 7] RDOWNMAX = GENDATA[:, 8] PMAXGEN = GENDATA[:, 9] PMINGEN = GENDATA[:, 10] QMAXGEN = GENDATA[:, 11] QMINGEN = GENDATA[:, 12] AA, BB, PROB = ld.loadscendata() DEM = DEMDATA[:, 1] CDLS = DEMDATA[:, 3] PREAL = np.ndarray((3, 7, 24)) CBAT = abs(STODATA[:, 2]) for t in numHrs: for s in numSce: z = (t, s) if z in datacont1: idx = datacont1.index(z) PG = G[idx, :, 0] DM = D[idx, :, 0] BM = B[idx, :, 0] PREAL[:, s, t] = PG elif z in datacont2: idx = datacont2.index(z) PG = G2[idx, :, 0] DM = D2[idx, :, 0] BM = B2[idx, :, 0] PREAL[:, s, t] = PG elif z in datacont3: idx = datacont3.index(z) PG = G3[idx, :, 0] DM = D3[idx, :, 0] BM = B3[idx, :, 0] PREAL[:, s, t] = PG else: print('Data not found!') if s == 0: realcost = realcost + CV.dot(PG) else: crup = CRUP.dot(PG - PREAL[:, 0, t]) if (crup < 0): crup = 0 crdown = CRDOWN.dot(PREAL[:, 0, t] - PG) if (crdown < 0): crdown = 0 deltadem = abs(DEM[:] - DM) cdls = CDLS.dot(deltadem) cbat = BM.dot(CBAT[:]) realcost = realcost + PROB[s - 1] * ( CV.dot(PG + crup + crdown + cdls + cbat)) print('Costos Totales reales modelo Relajado', realcost)
def run(verbose=False): """ Realiza Optimización de Despacho con Seguridad para horizonte de tiempo sin considerar relajo de restricciones. """ M = 10000 NGen = 3 NLin = 3 NBar = 3 NHrs = 24 NEle = NGen + NLin NFal = NGen + NLin NSce = NFal + 1 numLin = range(NLin) numBar = range(NBar) numGen = range(NGen) numFal = range(NFal) numEle = range(NEle) numSce = range(NSce) numHrs = range(NHrs) numScF = range(1,NSce) GENDATA,DEMDATA,LINDATA,STODATA = ld.loadsystemdata() #Generator data genBar = GENDATA[:,1] CV = GENDATA[:,2] CRUP = GENDATA[:,3] CRDOWN = GENDATA[:,4] CENC = GENDATA[:,5] CAPG = GENDATA[:,6] RUPMAX = GENDATA[:,7] RDOWNMAX = GENDATA[:,8] PMAXGEN = GENDATA[:,9] PMINGEN = GENDATA[:,10] QMAXGEN = GENDATA[:,11] QMINGEN = GENDATA[:,12] #Demand data DPMAX = DEMDATA[:,1] DQMAX = DEMDATA[:,2] #Line data FMAX = LINDATA[:,1] XL = LINDATA[:,4] # ============================================================================= # SIPS # ============================================================================= #Storage data CBAT = abs(STODATA[:,2]) PMAXBAT = abs(STODATA[:,8]) #Load Shedding DEMLSMAX = DEMDATA[:,4] CLS = DEMDATA[:,3] #Scenarios data A, B,PROB = ld.loadscendata() #Demand data DEMRES, DEMIND, DEMCOM = ld.loadcurvedata() D = np.array([DPMAX[0]*DEMRES,DPMAX[1]*DEMIND,DPMAX[2]*DEMCOM]) # ============================================================================= # DEFINE VARIABLES # ============================================================================= #Define problem model = gp.Model("Model") if not verbose: model.setParam('OutputFlag',0) else: model.setParam('OutputFlag',1) #Variables p = model.addVars(NGen,NSce,NHrs, vtype=GRB.CONTINUOUS) x = model.addVars(NGen,NHrs, vtype=GRB.BINARY) e = model.addVars(NGen,NHrs, vtype=GRB.BINARY) a = model.addVars(NGen,NHrs, vtype=GRB.BINARY) f = model.addVars(NLin,NSce,NHrs, vtype = GRB.CONTINUOUS, lb=-GRB.INFINITY) theta = model.addVars(NBar,NSce,NHrs, vtype = GRB.CONTINUOUS, lb=-GRB.INFINITY) rup = model.addVars(NGen,NSce,NHrs, vtype = GRB.CONTINUOUS) rdown = model.addVars(NGen,NSce,NHrs, vtype = GRB.CONTINUOUS) xrup = model.addVars(NGen,NSce,NHrs, vtype = GRB.BINARY) xrdown = model.addVars(NGen,NSce,NHrs, vtype = GRB.BINARY) #SIPS pbat = model.addVars(NGen, NSce, NHrs, vtype = GRB.CONTINUOUS) demls= model.addVars(NGen, NSce, NHrs, vtype = GRB.CONTINUOUS) #Objective Function Objective = quicksum(quicksum(CV[g]*p[g,0,t] + CENC[g]*e[g,t] + CAPG[g]*a[g,t] for g in numGen) + quicksum(PROB[s-1]*quicksum(CV[g]*p[g,s,t] + CRUP[g]*rup[g,s,t] + CRDOWN[g]* rdown[g,s,t] for g in numGen) for s in numScF) for t in numHrs) + \ quicksum(quicksum(PROB[s-1]*quicksum(CBAT[g]*pbat[g,s,t] + CLS[g]*demls[g,s,t] for g in numGen) for s in numScF) for t in numHrs) #Contraints #Turn on and Turn Off machines for g in numGen: model.addConstr(x[g,0] == e[g,0] - a[g,0]) for t in range(2,NHrs): for g in numGen: model.addConstr(x[g,t] == x[g,t-1] + e[g,t] - a[g,t]) for t in range(3,NHrs): for g in numGen: model.addConstr(x[g,t]>=quicksum(e[g,k] for k in range(t-3,t))) model.addConstr(1-x[g,t]>=quicksum(a[g,k] for k in range(t-3,t))) for g in numGen: model.addConstr(x[g,0] >= e[g,0]) model.addConstr(1 - x[g,0] >= a[g,0]) for g in numGen: model.addConstr(x[g,1] >= quicksum(e[g,k] for k in range(2))) model.addConstr(1 - x[g,1] >= quicksum(a[g,k] for k in range(2))) for g in numGen: model.addConstr(x[g,2] >= quicksum(e[g,k] for k in range(3))) model.addConstr(1 - x[g,2] >= quicksum(a[g,k] for k in range(3))) #Limits of Generators for t in numHrs: for s in numSce: for g in numGen: model.addConstr(p[g,0,t] + rup[g,s,t] <= PMAXGEN[g]*x[g,t]) model.addConstr(p[g,0,t] - rdown[g,s,t] >= PMINGEN[g]*x[g,t]) model.addConstr(rup[g,s,t] <= RUPMAX[g]*xrup[g,s,t]) model.addConstr(rdown[g,s,t] <= RDOWNMAX[g]*xrdown[g,s,t]) model.addConstr(xrup[g,s,t] + xrdown[g,s,t] <= 1) #Baterias model.addConstr(pbat[g,s,t]<=PMAXBAT[g]) #Loas shedding model.addConstr(demls[g,s,t]<=DEMLSMAX[g]) #Reserves are 0 for the base case scenario for t in numHrs: for g in numGen: model.addConstr(xrup[g,0,t] + xrdown[g,0,t] == 0) model.addConstr(demls[g,0,t] == 0) model.addConstr(pbat[g,0,t]==0) #Nodal Balancing por scenarios pre and post failure for t in numHrs: for s in numSce: model.addConstr(p[0,s,t] + pbat[0,s,t] == D[0,t] + f[0,s,t] + f[2,s,t] - demls[0,s,t]) model.addConstr(p[1,s,t] + pbat[1,s,t] + f[0,s,t] == D[1,t] + f[1,s,t] - demls[1,s,t]) model.addConstr(p[2,s,t] + pbat[2,s,t] + f[2,s,t] + f[1,s,t] == D[2,t] - demls[2,s,t]) #Availability of elements for t in numHrs: for s in numSce: #Availability of generators for g in numGen: model.addConstr(p[g,s,t] <= A[g,s]*(p[g,0,t] + rup[g,s,t])) model.addConstr(p[g,s,t] >= A[g,s]*(p[g,0,t] - rdown[g,s,t])) #Availability of lines for l in numLin: model.addConstr(f[l,s,t] <= FMAX[l]*B[l,s]) model.addConstr(f[l,s,t] >= -1*FMAX[l]*B[l,s]) model.addConstr(f[0,s,t] <= 1/XL[0]*(theta[0,s,t]-theta[1,s,t]) + M*(1-B[0,s])) model.addConstr(f[0,s,t] >= 1/XL[0]*(theta[0,s,t]-theta[1,s,t]) - M*(1-B[0,s])) model.addConstr(f[1,s,t] <= 1/XL[1]*(theta[1,s,t]-theta[2,s,t]) + M*(1-B[1,s])) model.addConstr(f[1,s,t] >= 1/XL[1]*(theta[1,s,t]-theta[2,s,t]) - M*(1-B[1,s])) model.addConstr(f[2,s,t] <= 1/XL[2]*(theta[0,s,t]-theta[2,s,t]) + M*(1-B[2,s])) model.addConstr(f[2,s,t] >= 1/XL[2]*(theta[0,s,t]-theta[2,s,t]) - M*(1-B[2,s])) # ============================================================================= # RUN MODEL # ============================================================================= model.setObjective(Objective, GRB.MINIMIZE) model.optimize() print('Costos Totales:',model.objVal) # ============================================================================= # SAVE RESULTS # ============================================================================= psol = np.array([[[p[g,s,t].X for t in numHrs] for s in numSce] for g in numGen]) xsol = np.array([[x[g,t].X for t in numHrs] for g in numGen]) esol = np.array([[e[g,t].X for t in numHrs] for g in numGen]) asol = np.array([[a[g,t].X for t in numHrs] for g in numGen]) fsol = np.array([[[f[l,s,t].X for t in numHrs] for s in numSce] for l in numLin]) thetasol = np.array([[[theta[n,s,t].X for t in numHrs] for s in numSce] for n in numBar]) rupsol = np.array([[[rup[g,s,t].X for t in numHrs] for s in numSce] for g in numGen]) rdownsol = np.array([[[rdown[g,s,t].X for t in numHrs] for s in numSce] for g in numGen]) xrupsol = np.array([[[xrup[g,s,t].X for t in numHrs] for s in numSce] for g in numGen]) xrdownsol = np.array([[[xrdown[g,s,t].X for t in numHrs] for s in numSce] for g in numGen]) demlssol = np.array([[[demls[g,s,t].X for t in numHrs] for s in numSce] for g in numGen]) pbatsol = np.array([[[pbat[g,s,t].X for t in numHrs] for s in numSce] for g in numGen]) # print(demlssol) np.save('results\\ECOPSOL_SIPS',psol) np.save('results\\ECOXSOL_SIPS',xsol) np.save('results\\ECOESOL_SIPS',esol) np.save('results\\ECOASOL_SIPS',asol) np.save('results\\ECOFSOL_SIPS',fsol) np.save('results\\ECOTHETASOL_SIPS',thetasol) np.save('results\\ECORUPSOL_SIPS',rupsol) np.save('results\\ECORDOWNSOL_SIPS',rdownsol) np.save('results\\ECOXRUPSOL_SIPS',xrupsol) np.save('results\\ECOXRDOWNSOL_SIPS',xrdownsol) np.save('results\\ECODEM_SIPS',D) np.save('results\\ECOPDEMLSSOL_SIPS',demlssol) np.save('results\\ECOPBATSOL_SIPS',pbatsol) return model.objVal
def run(lin,relaxcapacity,verbose=False): """ Realiza Optimización de Despacho con Seguridad para horizonte de tiempo sin considerar relajo de restricciones. """ M = 10000 NGen = 3 NLin = 3 NBar = 3 NHrs = 24 NEle = NGen + NLin NFal = NGen + NLin NSce = NFal + 1 numLin = range(NLin) numBar = range(NBar) numGen = range(NGen) numFal = range(NFal) numEle = range(NEle) numSce = range(NSce) numHrs = range(NHrs) numScF = range(1,NSce) GENDATA,DEMDATA,LINDATA,STODATA = ld.loadsystemdata() #Generator data genBar = GENDATA[:,1] CV = GENDATA[:,2] CRUP = GENDATA[:,3] CRDOWN = GENDATA[:,4] CENC = GENDATA[:,5] CAPG = GENDATA[:,6] RUPMAX = GENDATA[:,7] RDOWNMAX = GENDATA[:,8] PMAXGEN = GENDATA[:,9] PMINGEN = GENDATA[:,10] QMAXGEN = GENDATA[:,11] QMINGEN = GENDATA[:,12] #Demand data DPMAX = DEMDATA[:,1] DQMAX = DEMDATA[:,2] #Line data FMAX = LINDATA[:,1] XL = LINDATA[:,4] LENGTHLINE= LINDATA[:,6] #Demand data DEMRES, DEMIND, DEMCOM = ld.loadcurvedata() D = np.array([DPMAX[0]*DEMRES,DPMAX[1]*DEMIND,DPMAX[2]*DEMCOM]) #Scenarios data A, B,PROB = ld.loadscendata() # ============================================================================= # SIPS # ============================================================================= #Storage data CBAT = abs(STODATA[:,2]) PMAXBAT = abs(STODATA[:,8]) #Load Shedding DEMLSMAX = DEMDATA[:,4] CLS = DEMDATA[:,3] # ============================================================================= # ADD MORE CAPACITY TO LINE TO RELAX CONSTRAINT # ============================================================================= FMAXP = FMAX.copy() if type(lin) is list: for (l,rc) in zip(lin,relaxcapacity): FMAXP[l] = rc*FMAXP[l] elif type(lin) is int: FMAXP[lin] = relaxcapacity*FMAXP[lin] # ============================================================================= # FACTOR CRECIMIENTO GENERACIÓN, DEMANDA Y LINEAS # ============================================================================= #crecimiento demanda anual fdem = 1.05 #crecimiento capacidad en MW fcap = 100 #crecimiento generacion fgen = 1.07 # ============================================================================= # COSTOS DE INVERSION POR MW # ============================================================================= CINVLIN = 740*LENGTHLINE[0] CINVBAT = 400000 # ============================================================================= # HORIZONTE PLANIFICACION # ============================================================================= NYears = 20 numYears = range(NYears) DEMY = np.ndarray((NYears,NBar,NHrs)) RUPMAXY = np.ndarray((NYears,NGen)) RDOWNMAXY = np.ndarray((NYears,NGen)) PMAXGENY = np.ndarray((NYears,NGen)) PMINGENY = np.ndarray((NYears,NGen)) for y in numYears: DEMY[y,:] = (fdem**y)*D PMAXGENY[y,:] = (fgen**y)*PMAXGEN[:] RUPMAXY[y,:] = (fgen**y)*RUPMAX[:] RDOWNMAXY[y,:] = (fgen**y)*RDOWNMAX[:] PMINGENY[y,:] = PMINGEN[:] # ============================================================================= # DEFINE VARIABLES # ============================================================================= #Define problem model = gp.Model("Model") if not verbose: model.setParam('OutputFlag',0) else: model.setParam('OutputFlag',1) #Variables p = model.addVars(NYears,NGen,NSce,NHrs, vtype=GRB.CONTINUOUS) x = model.addVars(NYears,NGen,NHrs, vtype=GRB.BINARY) e = model.addVars(NYears,NGen,NHrs, vtype=GRB.BINARY) a = model.addVars(NYears,NGen,NHrs, vtype=GRB.BINARY) f = model.addVars(NYears,NLin,NSce,NHrs, vtype = GRB.CONTINUOUS, lb=-GRB.INFINITY) theta = model.addVars(NYears,NBar,NSce,NHrs, vtype = GRB.CONTINUOUS, lb=-GRB.INFINITY) rup = model.addVars(NYears,NGen,NSce,NHrs, vtype = GRB.CONTINUOUS) rdown = model.addVars(NYears,NGen,NSce,NHrs, vtype = GRB.CONTINUOUS) xrup = model.addVars(NYears,NGen,NSce,NHrs, vtype = GRB.BINARY) xrdown = model.addVars(NYears,NGen,NSce,NHrs, vtype = GRB.BINARY) #SIPS pbat = model.addVars(NYears,NGen, NSce, NHrs, vtype = GRB.CONTINUOUS) demls= model.addVars(NYears,NGen, NSce, NHrs, vtype = GRB.CONTINUOUS) #Investments Line xf50 = model.addVars(NLin, vtype=GRB.BINARY) #Battery xbat = model.addVars(NBar, vtype=GRB.BINARY) #Objective Function Objective = quicksum(quicksum(quicksum(CV[g]*p[y,g,0,t] + CENC[g]*e[y,g,t] + CAPG[g]*a[y,g,t] for g in numGen) + quicksum(PROB[s-1]*quicksum(CV[g]*p[y,g,s,t] + CRUP[g]*rup[y,g,s,t] + CRDOWN[g]* rdown[y,g,s,t] for g in numGen) for s in numScF) for t in numHrs) + quicksum(quicksum(PROB[s-1]*quicksum(CBAT[b]*pbat[y,b,s,t] + CLS[b]*demls[y,b,s,t] for b in numBar) for s in numScF) for t in numHrs)for y in numYears) + \ quicksum(fcap*xf50[l]*CINVLIN for l in numLin) + \ quicksum(PMAXBAT[b]*CINVBAT*xbat[b] for b in numBar) #Contraints #Turn on and Turn Off machines for y in numYears: for g in numGen: model.addConstr(x[y,g,0] == e[y,g,0] - a[y,g,0]) for t in range(2,NHrs): for g in numGen: model.addConstr(x[y,g,t] == x[y,g,t-1] + e[y,g,t] - a[y,g,t]) for t in range(3,NHrs): for g in numGen: model.addConstr(x[y,g,t]>=quicksum(e[y,g,k] for k in range(t-3,t))) model.addConstr(1-x[y,g,t]>=quicksum(a[y,g,k] for k in range(t-3,t))) for g in numGen: model.addConstr(x[y,g,0] >= e[y,g,0]) model.addConstr(1 - x[y,g,0] >= a[y,g,0]) for g in numGen: model.addConstr(x[y,g,1] >= quicksum(e[y,g,k] for k in range(2))) model.addConstr(1 - x[y,g,1] >= quicksum(a[y,g,k] for k in range(2))) for g in numGen: model.addConstr(x[y,g,2] >= quicksum(e[y,g,k] for k in range(3))) model.addConstr(1 - x[y,g,2] >= quicksum(a[y,g,k] for k in range(3))) #Limits of Generators for t in numHrs: for s in numSce: for g in numGen: model.addConstr(p[y,g,0,t] + rup[y,g,s,t] <= PMAXGENY[y,g]*x[y,g,t]) model.addConstr(p[y,g,0,t] - rdown[y,g,s,t] >= PMINGENY[y,g]*x[y,g,t]) model.addConstr(rup[y,g,s,t] <= RUPMAXY[y,g]*xrup[y,g,s,t]) model.addConstr(rdown[y,g,s,t] <= RDOWNMAXY[y,g]*xrdown[y,g,s,t]) model.addConstr(xrup[y,g,s,t] + xrdown[y,g,s,t] <= 1) #Baterias model.addConstr(pbat[y,g,s,t]<=PMAXBAT[g]*xbat[g]) #Loas shedding model.addConstr(demls[y,g,s,t]<=DEMLSMAX[g]) #Reserves are 0 for the base case scenario for t in numHrs: for g in numGen: model.addConstr(xrup[y,g,0,t] + xrdown[y,g,0,t] == 0) model.addConstr(demls[y,g,0,t] == 0) model.addConstr(pbat[y,g,0,t]==0) #Nodal Balancing por scenarios pre and post failure for t in numHrs: for s in numSce: model.addConstr(p[y,0,s,t] + pbat[y,0,s,t] == DEMY[y,0,t] + f[y,0,s,t] + f[y,2,s,t] - demls[y,0,s,t]) model.addConstr(p[y,1,s,t] + pbat[y,1,s,t] + f[y,0,s,t] == DEMY[y,1,t] + f[y,1,s,t] - demls[y,1,s,t]) model.addConstr(p[y,2,s,t] + pbat[y,2,s,t] + f[y,2,s,t] + f[y,1,s,t] == DEMY[y,2,t] - demls[y,2,s,t]) #Availability of elements for t in numHrs: for s in numSce: #Availability of generators for g in numGen: model.addConstr(p[y,g,s,t] <= A[g,s]*(p[y,g,0,t] + rup[y,g,s,t])) model.addConstr(p[y,g,s,t] >= A[g,s]*(p[y,g,0,t] - rdown[y,g,s,t])) #Availability of lines for l in numLin: model.addConstr(f[y,l,s,t] <= FMAX[l]*B[l,s] + fcap*xf50[l]*B[l,s]) model.addConstr(f[y,l,s,t] >= -1*FMAX[l]*B[l,s] - fcap*xf50[l]*B[l,s]) model.addConstr(f[y,0,s,t] <= 1/XL[0]*(theta[y,0,s,t]-theta[y,1,s,t]) + M*(1-B[0,s])) model.addConstr(f[y,0,s,t] >= 1/XL[0]*(theta[y,0,s,t]-theta[y,1,s,t]) - M*(1-B[0,s])) model.addConstr(f[y,1,s,t] <= 1/XL[1]*(theta[y,1,s,t]-theta[y,2,s,t]) + M*(1-B[1,s])) model.addConstr(f[y,1,s,t] >= 1/XL[1]*(theta[y,1,s,t]-theta[y,2,s,t]) - M*(1-B[1,s])) model.addConstr(f[y,2,s,t] <= 1/XL[2]*(theta[y,0,s,t]-theta[y,2,s,t]) + M*(1-B[2,s])) model.addConstr(f[y,2,s,t] >= 1/XL[2]*(theta[y,0,s,t]-theta[y,2,s,t]) - M*(1-B[2,s])) #Capacity of lines in scenario base 0 for t in numHrs: for l in numLin: model.addConstr(f[y,l,0,t] <= FMAX[l]*B[l,0] + fcap*xf50[l]*B[l,0]) #scenario 0: must respect limits model.addConstr(f[y,l,0,t] >= -1*FMAX[l]*B[l,0] - fcap*xf50[l]*B[l,0]) #scenarios of contingencies can violate limits until a treshhold #Capacity of lines relaxed for scenarios of contingencies for t in numHrs: for s in numScF: for l in numLin: model.addConstr(f[y,l,s,t] <= FMAXP[l]*B[l,s] + fcap*xf50[l]*B[l,s]) model.addConstr(f[y,l,s,t] >= -1*FMAXP[l]*B[l,s] - fcap*xf50[l]*B[l,s]) # ============================================================================= # RUN MODEL # ============================================================================= model.setObjective(Objective, GRB.MINIMIZE) model.optimize() print('Costos Totales:',model.objVal) # ============================================================================= # SAVE RESULTS # ============================================================================= psol = np.array([[[[p[y,g,s,t].X for t in numHrs] for s in numSce] for g in numGen] for y in numYears]) xsol = np.array([[[x[y,g,t].X for t in numHrs] for g in numGen]for y in numYears]) esol = np.array([[[e[y,g,t].X for t in numHrs] for g in numGen]for y in numYears]) asol = np.array([[[a[y,g,t].X for t in numHrs] for g in numGen]for y in numYears]) fsol = np.array([[[[f[y,l,s,t].X for t in numHrs] for s in numSce] for l in numLin]for y in numYears]) thetasol = np.array([[[[theta[y,n,s,t].X for t in numHrs] for s in numSce] for n in numBar]for y in numYears]) rupsol = np.array([[[[rup[y,g,s,t].X for t in numHrs] for s in numSce] for g in numGen]for y in numYears]) rdownsol = np.array([[[[rdown[y,g,s,t].X for t in numHrs] for s in numSce] for g in numGen]for y in numYears]) xrupsol = np.array([[[[xrup[y,g,s,t].X for t in numHrs] for s in numSce] for g in numGen]for y in numYears]) xrdownsol = np.array([[[[xrdown[y,g,s,t].X for t in numHrs] for s in numSce] for g in numGen]for y in numYears]) demlssol = np.array([[[[demls[y,g,s,t].X for t in numHrs] for s in numSce] for g in numGen]for y in numYears]) pbatsol = np.array([[[[pbat[y,g,s,t].X for t in numHrs] for s in numSce] for g in numGen]for y in numYears]) xf50sol = np.array([xf50[l].X for l in numLin]) xbatsol = np.array([xbat[b].X for b in numBar]) print('Inversion Lineas',xf50sol) print('Inversion Baterias', xbatsol) np.save('results\\ECOPSOL_SIPS_PLANIFICACION',psol) np.save('results\\ECOXSOL_SIPS_PLANIFICACION',xsol) np.save('results\\ECOESOL_SIPS_PLANIFICACION',esol) np.save('results\\ECOASOL_SIPS_PLANIFICACION',asol) np.save('results\\ECOFSOL_SIPS_PLANIFICACION',fsol) np.save('results\\ECOTHETASOL_SIPS_PLANIFICACION',thetasol) np.save('results\\ECORUPSOL_SIPS_PLANIFICACION',rupsol) np.save('results\\ECORDOWNSOL_SIPS_PLANIFICACION',rdownsol) np.save('results\\ECOXRUPSOL_SIPS_PLANIFICACION',xrupsol) np.save('results\\ECOXRDOWNSOL_SIPS_PLANIFICACION',xrdownsol) np.save('results\\ECODEM_SIPS_PLANIFICACION',D) np.save('results\\ECOPDEMLSSOL_SIPS_PLANIFICACION',demlssol) np.save('results\\ECOPBATSOL_SIPS_PLANIFICACION',pbatsol) return model.objVal
# -*- coding: utf-8 -*- """ Created on Sat Jan 4 14:55:03 2020 @author: ignac """ import loaddata as ld import math filename = 'data_3_bus.xlsx' GENDATA, DEMDATA, LINDATA, STODATA = ld.loadsystemdata(filename) X = LINDATA[:, 4] R = LINDATA[:, 5] BO = LINDATA[:, 2] BD = LINDATA[:, 3] LARGE = LINDATA[:, 6] """ x= [delta, \v\] """ # B = [[0,0,0],[0,0,0],[0,0,0]] # G = [[0.5,0.5,0.5],[0.5,0.5,0.5],[0.5,0.5,0.5]] numNodes = 3 def init_variables(): v = numNodes * [1] theta = numNodes * [0] return v, theta
def createnet(include_load_shedding=False, include_bat=False): GENDATA,DEMDATA,LINDATA,STODATA = ld.loadsystemdata() NUMNODES = 3 numgen = len(GENDATA) numlin = len(LINDATA) numdem = len(DEMDATA) numsto = len(STODATA) # ========================================================================= # CREATE EMPTY NET # ========================================================================= net = pp.create_empty_network(f_hz=50.0, sn_mva=100) # ========================================================================= # CREATE BUSES # ========================================================================= for i in range(numgen): pp.create_bus(net,vn_kv=220, index = i, max_vm_pu=1.05, min_vm_pu=0.95) cntidx = NUMNODES j=-1 for i in range(numgen): barcon = GENDATA[i][1] if(barcon>j): j=j+1 pp.create_bus(net, index = cntidx+j, vn_kv=13.8, max_vm_pu=1.05, min_vm_pu=0.95) # ========================================================================= # CREATE GENERATORS # ========================================================================= j=-1 indexgen=0 for i in range(numgen): pp.create_gen(net, vm_pu=1.02, index=indexgen, bus=GENDATA[i][1], p_mw = 0, sn_mva = GENDATA[i][13], max_p_mw = GENDATA[i][9], min_p_mw = GENDATA[i][10],max_q_mvar=GENDATA[i][11], min_q_mvar=GENDATA[i][12], controllable=True) indexgen = indexgen + 1 #create trafos barcon = GENDATA[i][1] if(barcon>j): j=j+1 pp.create_transformer(net, hv_bus=GENDATA[i][1], lv_bus=cntidx+j, std_type="500 MVA 220/13.8 kV") # ========================================================================= # CREATE LINES # ========================================================================= for i in range(numlin): fmax = LINDATA[i][1]/(3**0.5*220) ltype = {'typ'+str(i):{"r_ohm_per_km": LINDATA[i][5], "x_ohm_per_km": LINDATA[i][4], "c_nf_per_km": 10, "max_i_ka": fmax, "type": "ol", "qmm2":490, "alpha":4.03e-3}} pp.create_std_types(net,data=ltype,element='line') pp.create_line(net, from_bus=LINDATA[i][2], to_bus=LINDATA[i][3], length_km=LINDATA[i][6], std_type="typ"+str(i)) # ========================================================================= # CREATE LOADS # ========================================================================= for i in range(numdem): pp.create_load(net, index=i, bus=DEMDATA[i][0], p_mw = DEMDATA[i][1], q_mvar=DEMDATA[i][2], max_p_mw = DEMDATA[i][1], min_p_mw=DEMDATA[i][1], max_q_mvar = DEMDATA[i][2], min_q_mvar=DEMDATA[i][5], controllable = include_load_shedding) pp.create_poly_cost(net,i,'load',cp1_eur_per_mw=DEMDATA[i][3]) # ========================================================================= # CREATE STORAGE # ========================================================================= for i in range(numsto): pp.create_storage(net, index=i, bus=NUMNODES + i, p_mw = 0, q_mvar=0, max_e_mwh=100000, max_p_mw = STODATA[i][7], min_p_mw=STODATA[i][8], max_q_mvar=STODATA[i][9], min_q_mvar= STODATA[i][10], in_service=include_bat, controllable=include_bat) pp.create_poly_cost(net,i,'storage',cp1_eur_per_mw=STODATA[i][2]) return net