Leonel José Henriquez Orellana 5 éve
commit
2c9cf5e043
37 módosított fájl, 1073 hozzáadás és 0 törlés
  1. 375 0
      Predespacho.py
  2. BIN
      ieee6bus2s.xlsx
  3. 0 0
      red/__init__.py
  4. BIN
      red/__pycache__/__init__.cpython-36.pyc
  5. BIN
      red/__pycache__/__init__.cpython-37.pyc
  6. BIN
      red/__pycache__/create.cpython-36.pyc
  7. BIN
      red/__pycache__/create.cpython-37.pyc
  8. BIN
      red/__pycache__/create1.cpython-37.pyc
  9. BIN
      red/__pycache__/makeBdc.cpython-36.pyc
  10. BIN
      red/__pycache__/makeBdc.cpython-37.pyc
  11. BIN
      red/__pycache__/makePTDF.cpython-36.pyc
  12. BIN
      red/__pycache__/makePTDF.cpython-37.pyc
  13. BIN
      red/__pycache__/read.cpython-36.pyc
  14. BIN
      red/__pycache__/read.cpython-37.pyc
  15. 66 0
      red/create.py
  16. 359 0
      red/create1.py
  17. 61 0
      red/makeBdc.py
  18. 39 0
      red/makePTDF.py
  19. BIN
      red/prueba1.xlsx
  20. 50 0
      red/read.py
  21. 2 0
      red/utils/__init__.py
  22. BIN
      red/utils/__pycache__/__init__.cpython-36.pyc
  23. BIN
      red/utils/__pycache__/__init__.cpython-37.pyc
  24. BIN
      red/utils/__pycache__/arr2dict.cpython-36.pyc
  25. BIN
      red/utils/__pycache__/arr2dict.cpython-37.pyc
  26. BIN
      red/utils/__pycache__/idx_brch.cpython-36.pyc
  27. BIN
      red/utils/__pycache__/idx_brch.cpython-37.pyc
  28. 16 0
      red/utils/arr2dict.py
  29. 26 0
      red/utils/idx_brch.py
  30. 63 0
      red/utils/map.py
  31. BIN
      utils/__pycache__/__init__.cpython-36.pyc
  32. BIN
      utils/__pycache__/__init__.cpython-37.pyc
  33. BIN
      utils/__pycache__/arr2dict.cpython-36.pyc
  34. BIN
      utils/__pycache__/arr2dict.cpython-37.pyc
  35. BIN
      utils/__pycache__/idx_brch.cpython-36.pyc
  36. BIN
      utils/__pycache__/idx_brch.cpython-37.pyc
  37. 16 0
      utils/arr2dict.py

+ 375 - 0
Predespacho.py

@@ -0,0 +1,375 @@
+from __future__ import division
+from pyomo.environ import *
+from red.read import excel2net
+from red.create import *
+from red.create1 import *
+from red.makeBdc import makeBdc
+from utils.arr2dict import arr2dict
+from pyomo.environ import SolverFactory
+from pyomo.kernel import value
+from numpy import zeros, array
+from pandas import DataFrame, ExcelWriter
+import xlsxwriter
+
+def setmodel(file):
+        
+    print("{:=^100}".format(""))
+    print("{:^100}".format(" Modelo de Predespacho"))
+    print("{:^100}".format(" Mercados Eléctricos de Centroamérica (c) 2020 "))
+    print("{:=^100}".format(""))
+    # ============================================================================
+    # Importación de datos desde archivo Excel
+    # ============================================================================
+
+    #Parametros de la linea
+    print("Inicio del Script de Predespacho")
+    print("Leyendo información de red...")
+    net = excel2net(file)
+    bus = setbus(net)#Nodos
+    branch = setbranch(net, bus)#Set lineas
+    bu = branch[:, 5]#potenica max de la linea
+    bl = branch[:, 6]#potenica min de la linea
+    xc = branch[:,3]#Reactancia de la linea
+    nb = bus.shape[0] #Numero de nodos
+    nbr = branch.shape[0]#Numero de lineas
+    A = makeBdc(bus, branch)#Matriz incidente
+    brnames = branchnames(bus, branch)#Nombre de las lineas
+    inc = A.toarray()*-1
+    dg=read_D_G(file)
+    print("Leyendo información de ofertas")
+    #Funcion leer contratos no firmes fisicos flexibles
+    ex_cnfff = readofertas_cnfffs(file)
+    vnfff_ed= setvariable(ex_cnfff['energía_dec'])#Energia declarada con respecto al nodo
+    vnfff_m_i= setvariable_s(ex_cnfff[['magnitud_i1','magnitud_i2','magnitud_i3','magnitud_i4','magnitud_i5']])#Magnitud de energia ofertada -flexibilizacion
+    vnfff_m_r= setvariable_s(ex_cnfff[['magnitud_r1','magnitud_r2','magnitud_r3','magnitud_r4','magnitud_r5']])
+    vnfff_m_cvt=setvariable_s(ex_cnfff[['magnitud_cvt1','magnitud_cvt2','magnitud_cvt3','magnitud_cvt4','magnitud_cvt5']])
+    p_cnfffi= setvariable_s(ex_cnfff[['precio_i1','precio_i2','precio_i3','precio_i4','precio_i5']])#Precio de la ofertas de inyeccion
+    p_cnfffr= setvariable_s(ex_cnfff[['precio_r1','precio_r2','precio_r3','precio_r4','precio_r5']])#Precio de la ofertas de retiro
+    p_cnfffcvt= setvariable_s(ex_cnfff[['precio_cvt1','precio_cvt2','precio_cvt3','precio_cvt4','precio_cvt5']])#Precio de la ofertas de inyeccion
+    k_cnfffcvt= setvariable(ex_cnfff['k'])#Precio de la ofertas de inyeccion
+    NCFF = ex_cnfff.shape[0]#Numero de contratos firmes
+    var_bin_cnfffr=MATRIZ_VNFFF_R(bus,ex_cnfff)
+    var_bin_cnfffi=MATRIZ_VNFFF_I(bus,ex_cnfff)
+    dem=setvariable(dg['demanda'])
+    gen=setvariable(dg['generacion'])
+
+    #Funcion leer parametros oferta de oportunidad inyeccion
+    ex_ooi = readofertas_oois(file)
+    vooi_m=setvariable_s(ex_ooi[['magnitud_ooi1','magnitud_ooi2','magnitud_ooi3','magnitud_ooi4','magnitud_ooi5']])#Ofertas con respecto al nodo
+    p_ooi= setvariable_s(ex_ooi[['precio_ooi1','precio_ooi2','precio_ooi3','precio_ooi4','precio_ooi5']])#Precio de la ofertas
+    NOI = ex_ooi.shape[0]#Numero de ofertas de inyeccion
+    var_bin_ooi=MATRIZ_OOI(bus,ex_ooi)
+
+    #Funcion leer parametros oferta de oportunidad retiro
+    ex_oor = readofertas_oors(file)
+    voor_m=setvariable_s(ex_oor[['magnitud_oor1','magnitud_oor2','magnitud_oor3','magnitud_oor4','magnitud_oor5']])#Ofertas con respecto al nodo
+    p_oor= setvariable_s(ex_oor[['precio_oor1','precio_oor2','precio_oor3','precio_oor4','precio_oor5']])#Precio de la ofertas - flexibilizacion
+    NOR = ex_oor.shape[0]#Numero de ofertas de retiro
+    var_bin_oor=MATRIZ_OOR(bus,ex_oor)
+  
+    #Funcion leer parametros contratos firmes
+    ex_cf = readofertas_cfs(file)
+    vcf_ed=setvariable(ex_cf['energía_dec'])#Energia declarada con respecto al nodo
+    vcf_pr=setvariable(ex_cf['potencia_req'])#Potencia requerida con respecto al nodo
+    vcf_m=setvariable_s(ex_cf[['magnitu_cf1','magnitu_cf2','magnitu_cf3','magnitu_cf4','magnitu_cf5']])#Magnitud de energia ofertada -flexibilizacion
+    vcf_p= setvariable_s(ex_cf[['precio_cf1','precio_cf2','precio_cf3','precio_cf4','precio_cf5']])#Precio de la ofertas
+    NCF = ex_cf.shape[0]#Numero de contratos firmes
+    var_bin_cfr=MATRIZ_CFR(bus, ex_cf)
+    var_bin_cfi=MATRIZ_CFI(bus, ex_cf)
+
+    #Calculo de parametros
+    if NOR>0 & NCFF>0:
+        fens=3*max(max(ex_oor['precio_oor1']),max(ex_cnfff['precio_i1']))#Valor de los retiro firmes no suministrados
+    elif NOR>0 or NCFF==0:
+        fens=3*max(ex_oor['precio_oor1'])
+    elif NOR==0 or NCFF>0:
+        fens=3*max(ex_cnfff['precio_i1'])
+    ffenes=0.5*fens#Valor de la energía no flexible de los contratos físicos flexibles no suministrados 
+
+    # Inicio del modelo de optimización
+
+    model=ConcreteModel()
+
+    #sets
+    model.i=Set(initialize=range(0, nb))#numero de nodos
+    model.c=Set(initialize=range(0, nbr))#Numero de lineas
+    model.OR = Set(initialize=range(0, NOR))#numero de ofertas de oportuniddad retiro
+    model.OI = Set(initialize=range(0, NOI))#numero de ofertas de oportunidad inyeccion
+    model.CFF=Set(initialize=range(0, NCFF))#numero de ofertas de CNFFF
+    model.CF=Set(initialize=range(0, NCF))#numero de ofertas de contratos firmes
+    model.s=Set(initialize=range(0, 5))#Numero de bloques
+
+    #Parametros
+    #Parametros de la red
+    model.rtmw_min= Param(model.c, initialize=dict(enumerate(bl)))
+    model.rtmw_max= Param(model.c, initialize=dict(enumerate(bu)))
+    model.Inc = Param(model.c, model.i, initialize=arr2dict(inc))
+    model.xc = Param(model.c, initialize=dict(enumerate(xc)))
+    
+    #Parametros de los predespachos nacionales
+    model.D = Param(model.i, initialize=dict(enumerate(dem)))
+    model.G = Param(model.i, initialize=dict(enumerate(gen)))
+
+    #Ofertas de oportunidad
+    #Oferta de oportunidad de retiro
+    model.fr= Param(model.OR, model.s, initialize=arr2dict(p_oor))#Oferta bloques 1
+    model.pr_ofertado = Param(model.OR, model.s, initialize=arr2dict(voor_m))#Magnitud de la oferta MW-h
+    model.bin_pr = Param(model.i, model.OR, initialize=arr2dict(var_bin_oor))
+
+    #Oferta de oportunidad de inyeccion
+    model.fi= Param(model.OI, model.s, initialize=arr2dict(p_ooi))#Precio de bloques - Oferta de oportunidad de inyeccion
+    model.pi_ofertado= Param(model.OI, model.s, initialize=arr2dict(vooi_m))#Magnitud de la oferta MW-h
+    model.bin_pi = Param(model.i,model.OI,initialize=arr2dict(var_bin_ooi))
+
+    #Contratos firmes
+    model.pf_declarada=Param(model.CF, initialize=dict(enumerate(vcf_ed)))#Energia declarada
+    model.pf_req=Param(model.CF, initialize=dict(enumerate(vcf_pr)))# Potencia requerida - Si no se flexbiliza deberian de ser igual la energia y la potencia
+    #Precio de flexibilidad de contrato
+    model.ffi=Param(model.CF, model.s, initialize=arr2dict(vcf_p))#Precio de bloques - Contrato firme - Oferta de flexibilidad
+    model.pfi_ofertado=Param(model.CF, model.s, initialize=arr2dict(vcf_m))#Magnitud de la oferta - tiene que ser igual a la suma de la energia declarada 
+    model.bin_cfi=Param(model.i, model.CF,initialize=arr2dict(var_bin_cfi))
+    model.bin_cfr=Param(model.i, model.CF,initialize=arr2dict(var_bin_cfr))
+
+    #Ofertas de flexibilidad de contratos fisicos flexibles
+    #Ofertas de inyeccion
+    model.pff_declarada=Param(model.CFF, initialize=dict(enumerate(vnfff_ed)))
+    model.pffi_ofertado=Param(model.CFF, model.s, initialize=arr2dict(vnfff_m_i))#Magnitud del bloque
+    model.fffi=Param(model.CFF, model.s, initialize=arr2dict(p_cnfffi))#Precio de inyeccion
+    model.bin_pffi=Param(model.i,model.CFF, initialize=arr2dict(var_bin_cnfffi))
+
+    #Oferta de retiro
+    model.pffr_ofertado=Param(model.CFF, model.s, initialize=arr2dict(vnfff_m_r))#Magnitud de bloque de retiro ofertado
+    model.fffr=Param(model.CFF, model.s, initialize=arr2dict(p_cnfffr))#Precio de bloques - Contrato no firme fisico flexible
+    model.bin_pffr=Param(model.i,model.CFF, initialize=arr2dict(var_bin_cnfffr))
+
+    #Ofertad de pago maximo por CVT
+    model.k=Param(model.CFF, initialize=dict(enumerate(k_cnfffcvt)))#Indicador de oferta
+    model.pfft_ofertado=Param(model.CFF, model.s, initialize=arr2dict(vnfff_m_cvt))#Magnitud del bloque 
+    model.ffft=Param(model.CFF, model.s, initialize=arr2dict(p_cnfffcvt))#Precio de pago maximo CVT
+
+    #Variabeles
+    #Variable ofertas de oportunidad
+    model.pr= Var(model.OR, model.s, domain=NonNegativeReals)#Parte aceptada de cada bloques de las ofertas de oportunidad de retiro
+    model.pi= Var(model.OI, model.s, domain=NonNegativeReals)#Parte aceptada de cada bloques de las ofertas de oportunidad de inyeccion
+
+    #Variables CF
+    model.pfi=Var(model.CF, model.s, domain=NonNegativeReals)#Parte aceptada de cada bloques de las ofertas de flexibilidad de contratos firmes 
+
+    #Variables CNFFF
+    model.pffr=Var(model.CFF, model.s, domain=NonNegativeReals)#Parte aceptada de cada bloques de las oferta de flexibilidad de retiro
+    model.pffi=Var(model.CFF, model.s, domain=NonNegativeReals)#Parte aceptada de cada bloques de las ofertas de flexibilidad de inyección de los contratos físicos flexibles
+    model.pfft=Var(model.CFF, model.s, domain=NonNegativeReals)#Parte aceptada de cada bloques de las oferta de pago máximo de CVT de los contratos físicos flexibles
+    model.pff_iny_fisico=Var(model.CFF, domain=NonNegativeReals)#Componente fisica de energia horaria de inyeecion 
+    model.pff_ret_fisico=Var(model.CFF, domain=NonNegativeReals)#Componente fisica de energia horaria de retiro
+    
+    #Variables FOENS
+    model.pf_cortada=Var(model.CF, domain=NonNegativeReals)#Energia firme de lo CF 
+    model.pf_pre_cortada=Var(model.CF, domain=NonNegativeReals)
+    model.pff_cortada=Var(model.CFF, domain=NonNegativeReals)#Energia firme de los CNFFF
+    
+    #Variable problema de optimizacion
+    model.inyeccion= Var(model.i, domain=NonNegativeReals)#Inyeccion por nodo
+    model.retiro= Var(model.i, domain=NonNegativeReals)#Retiro por nodo
+    model.ref_angular= Var(model.i)#Fase del voltaje en el nodo
+    model.rtmw_c= Var(model.c)#Flujo de potencia actica por linea
+
+    print("Ecuación de Función Objetivo Max")
+
+    def objfunc(model):
+        return (sum(model.fr[OR,s]*model.pr[OR,s] for OR in model.OR for s in model.s) -  # ┌ FOO
+        sum(model.fi[OI,s]*model.pi[OI,s] for OI in model.OI for s in model.s) -          # └
+        sum(model.ffi[CF,s]*model.pfi[CF,s] for CF in model.CF for s in model.s) +        # [ FOF
+        sum(model.fffr[CFF,s]*model.pffr[CFF,s] for CFF in model.CFF for s in model.s) -  # ┌
+        sum(model.fffi[CFF,s]*model.pffi[CFF,s] for CFF in model.CFF for s in model.s) +  # │ FOFF
+        sum(model.ffft[CFF,s]*model.pfft[CFF,s] for CFF in model.CFF for s in model.s) -  # └
+        fens*sum(model.pf_cortada[CF] for CF in model.CF) -                               # ┌ FOENS
+        ffenes*sum(model.pff_cortada[CFF] for CFF in model.CFF))                          # └
+    model.OBJ= Objective(rule=objfunc, sense=maximize)
+
+    print("Restricciones del Modelo de Optimización")
+
+    #Restrecciones FOO
+    def pi_restriccion(model,OI,s):
+        return ((model.pi[OI,s] <=model.pi_ofertado[OI,s]))
+    model.pi_constraint= Constraint(model.OI, model.s, rule=pi_restriccion)
+
+    def pr_restriccion(model,OR,s):
+        return ((model.pr[OR,s]<=model.pr_ofertado[OR,s]))
+    model.pr_constraint= Constraint(model.OR, model.s, rule=pr_restriccion)
+
+    #Restricciones FOF
+    def pfi_restriccion(model,CF,s):
+        return (model.pfi[CF,s]<=model.pfi_ofertado[CF,s])
+    model.pfi_constraint= Constraint(model.CF, model.s, rule=pfi_restriccion)
+
+    #Restricciones FOFF
+    def pffr_restriccion(model,CFF,s):
+        return (model.pffr[CFF,s]<=model.pffr_ofertado[CFF,s])
+    model.pffr_constraint= Constraint(model.CFF, model.s, rule=pffr_restriccion)
+
+    def pffi_restriccion(model,CFF,s):
+        return (model.pffi[CFF,s]<=model.pffi_ofertado[CFF,s])
+    model.pffi_constraint= Constraint(model.CFF, model.s, rule=pffi_restriccion)
+
+    if  (model.k[CFF] ==0 for CFF in model.CFF):
+        def pfft_restriccion(model,CFF,s):
+            #if  model.k[CFF] ==0:
+            return (model.pfft[CFF,s]<=model.pfft_ofertado[CFF,s])
+        model.pfft_constraint= Constraint(model.CFF, model.s, rule=pfft_restriccion)
+
+    #K(cff) vale 0 si hay oferta de pago maximo por CVT
+    def pff_iny_fisico_restriccion(model,CFF):
+        if  model.k[CFF] ==0:
+            return (model.pff_iny_fisico[CFF]==sum(model.pfft[CFF,s] for s in model.s)- sum(model.pffr[CFF,s] for s in model.s))
+        elif model.k[CFF] ==1:
+            return (model.pff_iny_fisico[CFF]==model.pff_declarada[CFF] - model.pff_cortada[CFF]- sum(model.pffr[CFF,s] for s in model.s))
+    model.pff_iny_fisico_constraint=Constraint(model.CFF, rule=pff_iny_fisico_restriccion)
+        
+    def pff_ret_fisico_restriccion(model,CFF):
+        if  model.k[CFF] ==0:
+            return (model.pff_ret_fisico[CFF]==sum(model.pfft[CFF,s] for s in model.s) - sum(model.pffi[CFF,s] for s in model.s))
+        elif model.k[CFF] ==1:
+            return (model.pff_ret_fisico[CFF]==model.pff_declarada[CFF] - model.pff_cortada[CFF]- sum(model.pffi[CFF,s] for s in model.s))
+    model.pff_ret_fisico_constraint=Constraint(model.CFF, rule=pff_ret_fisico_restriccion)
+
+    #Restriccion FOENS
+    def pff_cortada_restriccion(model,CFF):
+        return (model.pff_cortada[CFF]<=model.pff_declarada[CFF])
+    model.pff_cortada_constraint=Constraint(model.CFF, rule=pff_cortada_restriccion)
+
+    def pf_cortada_restriccion(model,CF):
+        return (model.pf_cortada[CF]<=model.pf_req[CF] - model.pf_pre_cortada[CF])
+    model.pf_cortada_constraint=Constraint(model.CF, rule=pf_cortada_restriccion)
+
+    print('Restricciones de transmision')
+    #Restricciones de transmision
+    def inyec(model,i):
+        return (model.inyeccion[i]  == model.G[i] +
+        sum(model.pi[OI,s]*model.bin_pi[i,OI] for OI in model.OI for s in model.s) + 
+        sum(model.pfi[CF,s]*model.bin_cfi[i,CF] for CF in model.CF for s in model.s) +
+        sum(model.pff_iny_fisico[CFF]*model.bin_pffi[i,CFF] for CFF in model.CFF)) 
+    model.inyec_constraint= Constraint(model.i, rule=inyec)
+
+    def retiro(model,i):
+        return (model.retiro[i]  == model.D[i] +
+        sum(model.pr[OR,s]*model.bin_pr[i,OR] for OR in model.OR for s in model.s) + 
+        sum(model.pf_req[CF]*model.bin_cfr[i,CF] for CF in model.CF) +
+        sum(model.pff_ret_fisico[CFF]*model.bin_pffr[i,CFF] for CFF in model.CFF) - 
+        sum(model.pf_cortada[CF]*model.bin_cfr[i,CF] for CF in model.CF) -
+        sum(model.pf_pre_cortada[CF]*model.bin_cfr[i,CF] for CF in model.CF))
+    model.retiro_constraint= Constraint(model.i, rule=retiro)
+
+    #Los multiplicadore o variable duales de esta restriccion son los precios nodales
+    def balance_inyeccion_retiro(model,i):
+        return (model.inyeccion[i] +  sum(model.Inc[c,i]*model.rtmw_c[c] for c in model.c)== model.retiro[i])
+    model.balance_inyeccion_retiro_constraint= Constraint(model.i,rule=balance_inyeccion_retiro)
+
+    def rtmw_min_restriccion(model,c):
+        return (model.rtmw_c[c]>=-model.rtmw_min[c])
+    model.rtmw_min_constraint= Constraint(model.c, rule=rtmw_min_restriccion)
+
+    def rtmw_max_restriccion(model,c):
+        return (model.rtmw_c[c]<=model.rtmw_max[c])
+    model.rtmw_max_constraint= Constraint(model.c, rule=rtmw_max_restriccion)
+
+    #Referencia angular
+    #def ref_angular_restriccion(model,i):
+    #    return model.ref_angular[0]==0
+    #model.ref_angular_constraint =Constraint(model.i, rule=ref_angular_restriccion)
+
+    def flujo_potencia_actica(model,c):
+        return (model.xc[c]*model.rtmw_c[c]+sum(model.Inc[c,i]*model.ref_angular[i] for i in model.i)== 0)
+    model.flujo_potencia_actica_constraint= Constraint(model.c, rule=flujo_potencia_actica)
+
+    model.dual = Suffix(direction=Suffix.IMPORT)
+
+    print("Construcción del modelo terminada.")
+
+    opt = SolverFactory('cplex')
+    result = opt.solve(model)
+    model.solutions.store_to(result)
+    #print(result)
+
+    # Cálculo de Precios Nodales
+    # =============================================================================
+    print("Calculando Precios Nodales")
+    Sigma = zeros(nb)
+    for i in model.i:
+        Sigma[i] = model.dual[model.balance_inyeccion_retiro_constraint[i]]
+
+    # Construcción de array para grabar
+    # =============================================================================
+
+    flujos = DataFrame()
+    f = array(list(model.rtmw_c.get_values().values()))
+    flujos['linea'] = brnames
+    flujos['flujo'] = f
+    #print(flujos)
+
+    pon = DataFrame()
+    result_inyeccion = array(list(model.inyeccion.get_values().values()))
+    result_retiro = array(list(model.retiro.get_values().values()))
+    pon['nodo']= bus
+    pon['Inyeccion'] = result_inyeccion
+    pon['Retiro'] = result_retiro
+    pon['Ex-antes'] = Sigma*-1
+    #print(pon)
+    
+    result_pff_iny=array(list(model.pff_iny_fisico.get_values().values()))
+    result_pff_ret=array(list(model.pff_ret_fisico.get_values().values()))
+    result_pr = setvariable_p(array(list(model.pr.get_values().values())),NOR)
+    result_pi = setvariable_p(array(list(model.pi.get_values().values())),NOI)
+    result_pffr = setvariable_p(array(list(model.pffr.get_values().values())),NCFF)
+    result_pffi = setvariable_p(array(list(model.pffi.get_values().values())),NCFF)
+    result_pfft = setvariable_p(array(list(model.pfft.get_values().values())),NCFF)
+
+    result_foo=DataFrame()
+    result_foo['Pr Bloque 1']=result_pr[:,0]
+    result_foo['Pr Bloque 2']=result_pr[:,1]
+    result_foo['Pr Bloque 3']=result_pr[:,2]
+    result_foo['Pr Bloque 4']=result_pr[:,3]
+    result_foo['Pr Bloque 5']=result_pr[:,4]
+    result_foo['Pi Bloque 1']=result_pi[:,0]
+    result_foo['Pi Bloque 2']=result_pi[:,1]
+    result_foo['Pi Bloque 3']=result_pi[:,2]
+    result_foo['Pi Bloque 4']=result_pi[:,3]
+    result_foo['Pi Bloque 5']=result_pi[:,4]
+    #print(result_foo)
+    
+    result_foff=DataFrame()
+    result_foff['Pffr Bloque 1']=result_pffr[:,0]
+    result_foff['Pffr Bloque 2']=result_pffr[:,1]
+    result_foff['Pffr Bloque 3']=result_pffr[:,2]
+    result_foff['Pffr Bloque 4']=result_pffr[:,3]
+    result_foff['Pffr Bloque 5']=result_pffr[:,4]
+    result_foff['Pffi Bloque 1']=result_pffi[:,0]
+    result_foff['Pffi Bloque 2']=result_pffi[:,1]
+    result_foff['Pffi Bloque 3']=result_pffi[:,2]
+    result_foff['Pffi Bloque 4']=result_pffi[:,3]
+    result_foff['Pffi Bloque 5']=result_pffi[:,4]
+    result_foff['Pfft Bloque 1']=result_pfft[:,0]
+    result_foff['Pfft Bloque 2']=result_pfft[:,1]
+    result_foff['Pfft Bloque 3']=result_pfft[:,2]
+    result_foff['Pfft Bloque 4']=result_pfft[:,3]
+    result_foff['Pfft Bloque 5']=result_pfft[:,4]
+    #print(result_foff)
+
+    foo_ret_iny=DataFrame()
+    foo_ret_iny['Inyeccion']=result_pff_iny
+    foo_ret_iny['Retiro']=result_pff_ret
+
+    print("Escribiendo resultados en carpeta")
+    writer=ExcelWriter("Resultados_predespacho.xlsx")
+    flujos.to_excel(writer,'flujos',index=False)
+    pon.to_excel(writer,'pon',index=False)
+    result_foo.to_excel(writer,'result_foo',index=False)
+    result_foff.to_excel(writer,'result_foff',index=False)
+    foo_ret_iny.to_excel(writer,'result_foo_ret_iny',index=False)
+    writer.save()
+
+    print("{:=^100}".format(""))
+    print("{:^100}".format(" Script Finalizado "))
+    print("{:^100}".format(" Mercados Eléctricos de Centroamérica (c) 2020 "))
+    print("{:=^100}".format(""))
+    
+    return 0

BIN
ieee6bus2s.xlsx


+ 0 - 0
red/__init__.py


BIN
red/__pycache__/__init__.cpython-36.pyc


BIN
red/__pycache__/__init__.cpython-37.pyc


BIN
red/__pycache__/create.cpython-36.pyc


BIN
red/__pycache__/create.cpython-37.pyc


BIN
red/__pycache__/create1.cpython-37.pyc


BIN
red/__pycache__/makeBdc.cpython-36.pyc


BIN
red/__pycache__/makeBdc.cpython-37.pyc


BIN
red/__pycache__/makePTDF.cpython-36.pyc


BIN
red/__pycache__/makePTDF.cpython-37.pyc


BIN
red/__pycache__/read.cpython-36.pyc


BIN
red/__pycache__/read.cpython-37.pyc


+ 66 - 0
red/create.py

@@ -0,0 +1,66 @@
+# -*- coding: utf-8 -*-
+# =============================================================================
+#  Copyright (C) 2018 Mercados Electricos de Centroamérica. All rights reserved
+# =============================================================================
+
+"""Crea las estructuras con numeración secuencial de buses, circuitos y nombres de circuitos
+"""
+from numpy import array
+from numpy import zeros
+from utils.idx_brch import BUS_I, BUS_J, CKT
+
+def setbus(net):
+    """Lee la información de la red y crea una serie con los códigos de nodos y su numeración correlativa.
+    """
+    b = net['bus_i'].append(net['bus_j']).drop_duplicates().sort_values()
+    b = b.reset_index(drop=True)
+
+    return b
+
+
+def setbranch(net, b):
+    """Utiliza la información de la red, lod códigos de nodos y su numeración correlativa para generar un listado con
+    de los circuitos de acuerdo a la numeración correlativo del nodo.
+    """
+    br = net.copy()
+
+    for i in range(0, net.shape[0]):
+        br.loc[i, 'bus_i'] = b[b == br['bus_i'][i]].index[0]
+        br.loc[i, 'bus_j'] = b[b == br['bus_j'][i]].index[0]
+
+    br = br.sort_values(['bus_i', 'bus_j'])
+
+    return br.values
+
+def setvariable(variable):
+    l=variable.shape[0]
+    z=zeros(l)
+    for i in range(0,variable.shape[0]):
+        z[i]=variable[i]
+    return z
+
+def setvariable_s(variable):
+    (l,n)=variable.shape
+    z=zeros((l,n))
+    for i in range(0,l):
+        for j in range(0,n):
+            z[i,j]=variable.iloc[i,j]
+    return z
+
+def setvariable_p(variable, n):
+    z=zeros((n,5))
+    m=0
+    for j in range(0,n):
+        for i in range(0,5):
+            z[j,i]=variable[m]
+            m=m+1
+    return z
+
+def branchnames(b, br):
+    """Devuelve un array con los nombres de los circuitos.
+    """
+    brnames = []
+    for i in range(0, br.shape[0]):
+        brnames.append("-".join([str(b[br[i, BUS_I]]),str(b[br[i, BUS_J]])]))
+    brnames = array(brnames)
+    return brnames

+ 359 - 0
red/create1.py

@@ -0,0 +1,359 @@
+
+from pandas import read_excel, concat
+from numpy import zeros
+
+#Ofertas de oportunidad inyeccion
+def readofertas_ooi(predespacho_file):
+    """Lee del archivo Excel la información del Predespacho.
+    
+    Retorna un DataFrame con las columnas siguientes:
+        
+        1. nodo_io        : Nodo de inyección de la oferta
+        2. Generador	  : Potencia ofertada
+        3. Precio bloque 1: Oferta en dólares por la compra de DF
+        4. Magnitud bloque 1: Precio del MWh ofertado 
+    """
+
+    ofer_ooi = read_excel(predespacho_file,sheet_name='ooi')
+    ofer_ooi.columns = ['nodo_i','Generador','precio_ooi','magnitud_ooi']
+    
+    return ofer_ooi
+
+def readofertas_oois(predespacho_file):
+    """Lee del archivo Excel la información del Predespacho.
+    
+    Retorna un DataFrame con las columnas siguientes:
+        
+        1. nodo_io        : Nodo de inyección de la oferta
+        2. Generador	  : Potencia ofertada
+        3. Precio bloque 1: Oferta en dólares por la compra de DF
+        4. Magnitud bloque 1: Precio del MWh ofertado 
+    """
+
+    ofer_ooi = read_excel(predespacho_file,sheet_name='ooi')
+    ofer_ooi.columns = ['nodo_i','Generador','precio_ooi1','magnitud_ooi1','precio_ooi2','magnitud_ooi2','precio_ooi3','magnitud_ooi3','precio_ooi4','magnitud_ooi4','precio_ooi5','magnitud_ooi5']
+    
+    return ofer_ooi
+
+
+#Ofertas de oportunidad retiro
+def readofertas_oor(predespacho_file):
+    """Lee del archivo Excel la información del Predespacho.
+    
+    Retorna un DataFrame con las columnas siguientes:
+        
+        1. nodo_r        : Nodo de retiro de la oferta
+        2. Generador	  : Potencia ofertada
+        3. Precio bloque 1: Oferta en dólares por la compra de DF
+        4. Magnitud bloque 1: Precio del MWh ofertado 
+    """
+
+    ofer_oor = read_excel(predespacho_file,sheet_name='oor')
+    ofer_oor.columns = ['nodo_oor','generador', 'precio_oor','magnitud_oor']
+    
+    return ofer_oor
+
+def readofertas_oors(predespacho_file):
+    """Lee del archivo Excel la información del Predespacho.
+
+    Retorna un DataFrame con las columnas siguientes:
+        
+        1. nodo_io        : Nodo de inyección de la oferta
+        2. Generador	  : Potencia ofertada
+        3. Precio bloque 1: Oferta en dólares por la compra de DF
+        4. Magnitud bloque 1: Precio del MWh ofertado 
+        5. Precio bloque 2: Oferta en dólares por la compra de DF
+        6. Magnitud bloque 2: Precio del MWh ofertado 
+        7. Precio bloque 3: Oferta en dólares por la compra de DF
+        8. Magnitud bloque 3: Precio del MWh ofertado 
+        9. Precio bloque 4: Oferta en dólares por la compra de DF
+        10. Magnitud bloque 4: Precio del MWh ofertado 
+        11. Precio bloque 5: Oferta en dólares por la compra de DF
+        12. Magnitud bloque 5: Precio del MWh ofertado 
+    """
+
+    ofer_oor = read_excel(predespacho_file,sheet_name='oor')
+    ofer_oor.columns = ['nodo_oor','generador','precio_oor1','magnitud_oor1','precio_oor2','magnitud_oor2','precio_oor3','magnitud_oor3','precio_oor4','magnitud_oor4','precio_oor5','magnitud_oor5']
+
+    return ofer_oor
+
+#Ofertas de contrato firme
+def readofertas_cf(predespacho_file):
+    """Lee del archivo Excel la información del Predespacho.
+    
+    Retorna un DataFrame con las columnas siguientes:
+        
+        1. nodo_i        : Nodo de inyección de la oferta
+        2. Generador	  : Potencia ofertada
+	  3.Nodo_r:		    Nodo de retiro
+	  4. Energía Declarada: Ofertas en dólares de CF
+        5. Potencia requerida: Oferta en dólares por la compra de DF
+        6. Precio bloque 1: Precio del MWh ofertado 
+	  7. Magnitud bloque 1 : Cantidad de MW a flexibilizar	  
+    """
+
+    ofer_cf = read_excel(predespacho_file,sheet_name='cf')
+    ofer_cf.columns = ['nodo_cfi','generador','nodo_cfr','energía_dec','potencia_req','precio_cf','magnitu_cf']
+    
+    return ofer_cf
+
+def readofertas_cfs(predespacho_file):
+    """Lee del archivo Excel la información del Predespacho.
+    
+    Retorna un DataFrame con las columnas siguientes:
+        
+        1. nodo_i        : Nodo de inyección de la oferta
+        2. Generador	  : Potencia ofertada
+	    3.Nodo_r:		    Nodo de retiro
+	    4. Energía Declarada: Ofertas en dólares de CF
+        5. Potencia requerida: Oferta en dólares por la compra de DF
+        6. Precio bloque 1: Precio del MWh ofertado 
+	    7. Magnitud bloque 1 : Cantidad de MW a flexibilizar	
+        8. Precio bloque 2: Precio del MWh ofertado 
+	    9. Magnitud bloque 2 : Cantidad de MW a flexibilizar
+        10. Precio bloque 3: Precio del MWh ofertado 
+	    11. Magnitud bloque 3: Cantidad de MW a flexibilizar
+        12. Precio bloque 4: Precio del MWh ofertado 
+	    13. Magnitud bloque 4: Cantidad de MW a flexibilizar
+        14. Precio bloque 5: Precio del MWh ofertado 
+	    15. Magnitud bloque 5: Cantidad de MW a flexibilizar  
+    """
+
+    ofer_cf = read_excel(predespacho_file,sheet_name='cf')
+    ofer_cf.columns = ['nodo_cfi','generador','nodo_cfr','energía_dec','potencia_req','precio_cf1','magnitu_cf1','precio_cf2','magnitu_cf2','precio_cf3','magnitu_cf3','precio_cf4','magnitu_cf4','precio_cf5','magnitu_cf5']
+    
+    return ofer_cf
+
+
+def read_D_G(predespacho_file):
+    """Lee del archivo Excel la información del Predespacho.
+    
+    Retorna un DataFrame con la demanda y generacion en el nodo:
+        
+    1. nodo        : Nodo de inyección de la oferta
+    2. Generador	  : Potencia ofertada
+	3.Nodo_r:		    Nodo de retiro	  
+    """
+
+    nodos_d_m = read_excel(predespacho_file,sheet_name='g_m')
+    nodos_d_m.columns = ['nodo','generacion','demanda']
+    
+    return nodos_d_m
+
+#Ofertas contratos no firmes físicos flexible
+def readofertas_cnfff(predespacho_file):
+    """Lee del archivo Excel la información del Predespacho.
+    
+    Retorna un DataFrame con las columnas siguientes:
+        
+        1. nodo_i        : Nodo de inyección de la oferta
+        2. Generador	  : Potencia ofertada
+	    3.Nodo_r:		    Nodo de retiro
+	    4. Energía Declarada: Ofertas en dólares de CF
+        5. Potencia requerida: Oferta en dólares por la compra de DF
+        6. Precio bloque inyeccion 1: Precio del MWh ofertado 
+	    7. Magnitud bloque  inyeccion 1 : Cantidad de MW a flexibilizar
+        8. Precio bloque retiro 1: Precio del MWh ofertado 
+	    9. Magnitud bloque  retiro 1 : Cantidad de MW a flexibilizar
+        10. k(cff) sin hay ofertas de max CVT va le 0 sino 1
+        11. Precio bloque max CVT 1: Precio del MWh ofertado 
+	    12. Magnitud bloque MAX CVT 1 : Cantidad de MW a flexibilizar
+    """
+
+    ofer_cnfffi = read_excel(predespacho_file,sheet_name='cnfff')
+    ofer_cnfffi.columns = ['nodo_cnfffi','generador','nodo_cnfffr','energía_dec','precio_i','magnitud_i','precio_r','magnitud_r','k','precio_cvt','magnitud_cvt']
+    
+    return ofer_cnfffi
+
+def readofertas_cnfffs(predespacho_file):
+    """Lee del archivo Excel la información del Predespacho.
+    
+    Retorna un DataFrame con las columnas siguientes:
+        
+        1. nodo_i        : Nodo de inyección de la oferta
+        2. Generador	  : Potencia ofertada
+	    3.Nodo_r:		    Nodo de retiro
+	    4. Energía Declarada: Ofertas en dólares de CF
+        5. Precio bloque inyeccion 1: Precio del MWh ofertado 
+	    6. Magnitud bloque  inyeccion 1 : Cantidad de MW a flexibilizar
+        7. Precio bloque inyeccion 2: Precio del MWh ofertado 
+	    8. Magnitud bloque  inyeccion 2 : Cantidad de MW a flexibilizar
+        9. Precio bloque inyeccion 3: Precio del MWh ofertado 
+	    10. Magnitud bloque  inyeccion 3: Cantidad de MW a flexibilizar
+        11. Precio bloque inyeccion 4: Precio del MWh ofertado 
+	    12. Magnitud bloque  inyeccion 4: Cantidad de MW a flexibilizar
+        13. Precio bloque inyeccion 5: Precio del MWh ofertado 
+	    14. Magnitud bloque  inyeccion 5: Cantidad de MW a flexibilizar
+        15. Precio bloque retiro 1: Precio del MWh ofertado 
+	    16. Magnitud bloque  retiro 1 : Cantidad de MW a flexibilizar
+        17. Precio bloque retiro 2: Precio del MWh ofertado 
+	    18. Magnitud bloque  retiro 2: Cantidad de MW a flexibilizar
+        19. Precio bloque retiro 3: Precio del MWh ofertado 
+	    20. Magnitud bloque  retiro 3: Cantidad de MW a flexibilizar
+        21. Precio bloque retiro 4: Precio del MWh ofertado 
+	    22. Magnitud bloque  retiro 4: Cantidad de MW a flexibilizar
+        23. Precio bloque retiro 5: Precio del MWh ofertado 
+	    24. Magnitud bloque  retiro 5: Cantidad de MW a flexibilizar
+        25. k si hay ofertas de max CVT va le 0 sino 1
+        26. Precio bloque max CVT 1: Precio del MWh ofertado 
+	    27. Magnitud bloque MAX CVT 1 : Cantidad de MW a flexibilizar
+        28. Precio bloque max CVT 2: Precio del MWh ofertado 
+	    29. Magnitud bloque MAX CVT 2: Cantidad de MW a flexibilizar
+        30. Precio bloque max CVT 3: Precio del MWh ofertado 
+	    31. Magnitud bloque MAX CVT 3: Cantidad de MW a flexibilizar
+        32. Precio bloque max CVT 4: Precio del MWh ofertado 
+	    33. Magnitud bloque MAX CVT 4: Cantidad de MW a flexibilizar
+        34. Precio bloque max CVT 5: Precio del MWh ofertado 
+	    35. Magnitud bloque MAX CVT 5: Cantidad de MW a flexibilizar
+    """
+
+    ofer_cnfffi = read_excel(predespacho_file,sheet_name='cnfff')
+    ofer_cnfffi.columns = ['nodo_cnfffi','generador','nodo_cnfffr','energía_dec','precio_i1','magnitud_i1','precio_i2','magnitud_i2','precio_i3','magnitud_i3','precio_i4','magnitud_i4','precio_i5','magnitud_i5','precio_r1','magnitud_r1','precio_r2','magnitud_r2','precio_r3','magnitud_r3','precio_r4','magnitud_r4','precio_r5','magnitud_r5','k','precio_cvt1','magnitud_cvt1','precio_cvt2','magnitud_cvt2','precio_cvt3','magnitud_cvt3','precio_cvt4','magnitud_cvt4','precio_cvt5','magnitud_cvt5']
+    
+    return ofer_cnfffi
+
+def MATRIZ_OOI(bus, ex):
+    """Construye el vector de variables binareas de las  Ofertas de Oportunidad de Inyeccion existentes
+    
+    Vector cuya dimensión es C{nb}, en donde nb es el número de nodos, y cuyas
+    componentes son todas nulas, salvo la correspondiente al nodo de retiro
+    del derecho firme donde tiene el valor de 1
+    
+    La función regresa una matriz de dimensión C{nb x ne}, en donde C{nb} es el
+    número de nodos y C{ne} es el número de derechos firmes existentes. Cada
+    columna de la matriz es el vector VRTEe de cada derecho firme e.
+    
+    """
+    
+    _vooi = zeros((bus.shape[0], ex.shape[0]))
+    
+    for i in range(0, ex.shape[0]):
+        _vooi[bus[bus == ex.iloc[i].nodo_i].index[0],i] = 1
+        
+    return _vooi
+
+def MATRIZ_OOR(bus, ex):
+    """Construye el vector de variables binareas de las  Ofertas de Oportunidad de Retiro existentes
+    
+    Vector cuya dimensión es C{nb}, en donde nb es el número de nodos, y cuyas
+    componentes son todas nulas, salvo la correspondiente al nodo de retiro
+    del derecho firme donde tiene el valor de 1
+    
+    La función regresa una matriz de dimensión C{nb x ne}, en donde C{nb} es el
+    número de nodos y C{ne} es el número de derechos firmes existentes. Cada
+    columna de la matriz es el vector VRTEe de cada derecho firme e.
+    """
+    
+    _voor = zeros((bus.shape[0], ex.shape[0]))
+    
+    for i in range(0, ex.shape[0]):
+        _voor[bus[bus == ex.iloc[i].nodo_oor].index[0],i] = 1
+        
+    return _voor
+
+
+
+def MATRIZ_CFR(bus, ex):
+    """Construye el vector VCD de Potencia Requerida 
+    
+    Vector cuya dimensión es C{nb}, en donde nb es el número de nodos, y cuyas
+    componentes son todas nulas, salvo la correspondiente al nodo de retiro
+    del derecho firme donde tiene el valor correspondiene a la inyección
+    asociada al derecho
+    
+    La función regresa una matriz de dimensión C{nb x ne}, en donde C{nb} es el
+    número de nodos y C{ne} es el número de derechos firmes existentes. Cada
+    columna de la matriz es el vector VRTEe de cada derecho firme e.
+    
+    """
+    
+    _vcf_pr = zeros((bus.shape[0], ex.shape[0]))
+    
+    for i in range(0, ex.shape[0]):
+        _vcf_pr[bus[bus == ex.iloc[i].nodo_cfr].index[0],i] = 1
+        
+    return _vcf_pr
+
+def MATRIZ_CFI(bus, ex):
+    """Construye el vector VCD de Precio del bloque 1 Requerida 
+    
+    Vector cuya dimensión es C{nb}, en donde nb es el número de nodos, y cuyas
+    componentes son todas nulas, salvo la correspondiente al nodo de retiro
+    del derecho firme donde tiene el valor correspondiene a la inyección
+    asociada al derecho
+    
+    La función regresa una matriz de dimensión C{nb x ne}, en donde C{nb} es el
+    número de nodos y C{ne} es el número de derechos firmes existentes. Cada
+    columna de la matriz es el vector VRTEe de cada derecho firme e.
+    
+    """
+    
+    _vcf_p = zeros((bus.shape[0], ex.shape[0]))
+    
+    for i in range(0, ex.shape[0]):
+        _vcf_p[bus[bus == ex.iloc[i].nodo_cfi].index[0],i] = 1
+        
+    return _vcf_p
+
+def VCF_M(bus, ex):
+    """Construye el vector VCD de Magnitud en MW del bloque 1 Requerida 
+    
+    Vector cuya dimensión es C{nb}, en donde nb es el número de nodos, y cuyas
+    componentes son todas nulas, salvo la correspondiente al nodo de retiro
+    del derecho firme donde tiene el valor correspondiene a la inyección
+    asociada al derecho
+    
+    La función regresa una matriz de dimensión C{nb x ne}, en donde C{nb} es el
+    número de nodos y C{ne} es el número de derechos firmes existentes. Cada
+    columna de la matriz es el vector VRTEe de cada derecho firme e.
+    
+    """
+    
+    _vcf_m = zeros((bus.shape[0], ex.shape[0]))
+    
+    for i in range(0, ex.shape[0]):
+        _vcf_m[bus[bus == ex.iloc[i].nodo_cfi].index[0],i] = 1
+        
+    return _vcf_m
+
+def MATRIZ_VNFFF_I(bus, ex):
+    """Construye el vector VNFFF dela Magnitud del bloque declarada en MW del bloque 1 Requerida 
+    
+    Vector cuya dimensión es C{nb}, en donde nb es el número de nodos, y cuyas
+    componentes son todas nulas, salvo la correspondiente al nodo de retiro
+    del derecho firme donde tiene el valor correspondiene a la inyección
+    asociada al derecho
+    
+    La función regresa una matriz de dimensión C{nb x ne}, en donde C{nb} es el
+    número de nodos y C{ne} es el número de derechos firmes existentes. Cada
+    columna de la matriz es el vector VRTEe de cada derecho firme e.
+    
+    """
+    
+    _vnfff_m_i = zeros((bus.shape[0], ex.shape[0]))
+    
+    for i in range(0, ex.shape[0]):
+        _vnfff_m_i[bus[bus == ex.iloc[i].nodo_cnfffi].index[0],i] = 1
+        
+    return _vnfff_m_i
+
+def MATRIZ_VNFFF_R(bus, ex):
+    """Construye el vector VNFFF dela Magnitud del bloque declarada en MW del bloque 1 Requerida 
+    
+    Vector cuya dimensión es C{nb}, en donde nb es el número de nodos, y cuyas
+    componentes son todas nulas, salvo la correspondiente al nodo de retiro
+    del derecho firme donde tiene el valor correspondiene a la inyección
+    asociada al derecho
+    
+    La función regresa una matriz de dimensión C{nb x ne}, en donde C{nb} es el
+    número de nodos y C{ne} es el número de derechos firmes existentes. Cada
+    columna de la matriz es el vector VRTEe de cada derecho firme e.
+    
+    """
+    
+    _vnfff_m_r = zeros((bus.shape[0], ex.shape[0]))
+    
+    for i in range(0, ex.shape[0]):
+        _vnfff_m_r[bus[bus == ex.iloc[i].nodo_cnfffr].index[0],i] = 1
+        
+    return _vnfff_m_r

+ 61 - 0
red/makeBdc.py

@@ -0,0 +1,61 @@
+# -*- coding: utf-8 -*-
+# =============================================================================
+#  Copyright (C) 2018 Mercados Electricos de Centroamérica. All rights reserved
+# =============================================================================
+
+"""
+Construye las matrices B para el cálculo de flujos DC
+"""
+
+from numpy import ones, r_, zeros
+from scipy.sparse import csr_matrix as sparse
+from utils.idx_brch import BUS_I, BUS_J, X
+
+
+def makeBdc(bus, branch):
+    """Construye las matrices B para el cálculo de flujos DC.
+
+    Se construye primer la matriz de incidencia Cft (o matriz A, como se    denomina en la formulación de substas de
+    Derechos Firmes) y se define como:
+
+    El valor será uno (1) para las líneas ij donde su nodo inicial sea igual al nodo i y menos uno (-1) para las lineas
+    ij cuyo nodo final sea igual al nodo j.
+
+    La matriz de incidencias Cft tiene dimenciones C{nbr x nb}, en donde C{nbr}es el numero de líneas (branches) y
+    C{nb} el número de buses.
+
+    Luego se calcula la matriz Bf (ZZ) de dimensiones C{nbr x nb}, en donde C{nbr} es el numero de líneas (branches) y
+    C{nb} el número de buses, igual que la Matriz de Incidencias.
+
+    Contiene los mismos elementos nulos que la matriz Cft y cuyas componentes no nulas son:
+
+        1. Para la componente correspondiente a la fila de cada circuito br,y cuya columna corresponde al nodo de
+        llegada del circuito b
+
+            :math:`Bf[br,b] = 1/Xbr`
+
+        2. Para la componente correspondiente a la fila de cada circuito br, y cuya columna corresponde al nodo de
+        salida del circuito b
+
+            :math:`Bf[br,b] = -1/Xbr`
+
+    La matriz Bbus se calcula como la transpuesta de la matriz de incidencias Cft por la matriz Bf
+
+        :math:`Bbus = Cft.T * Bf`
+
+    .. codeauthor:: Oscar A. Leiva (MERELEC)
+    """
+    # constantes
+    nb = bus.shape[0]
+    nbr = branch.shape[0]
+
+    # construye la matriz de incidencia Cft
+    f = branch[:, BUS_I].astype(float)          # lista de buses de origen
+    t = branch[:, BUS_J].astype(float)          # lista de buses de destino
+    i = r_[range(nbr), range(nbr)]             # Set doble de indices de filas
+
+    # Matriz de incidencia
+    Cft = sparse((r_[ones(nbr), -ones(nbr)], (i, r_[f, t])), (nbr, nb))
+
+    #print(Cft)
+    return Cft

+ 39 - 0
red/makePTDF.py

@@ -0,0 +1,39 @@
+# -*- coding: utf-8 -*-
+# =============================================================================
+#  Copyright (C) 2018 Mercados Electricos de Centroamérica. All rights reserved
+# =============================================================================
+
+"""Construye las matrices PTDF (Matriz H) para el cálculo de flujos DC
+"""
+
+from numpy import zeros
+from numpy.linalg import solve
+from simsdt.red.makeBdc import makeBdc
+
+
+def makePTDF(bus, branch):
+    """Construye la matriz PTDF DC
+
+    Toma como nodo slack el primer nodo.
+
+    La matriz es de dimensiones C{nbr x nb}, en donde C{nbr} es el numero de
+    lineas y C{nb} es el numero de buses o nodos. El nodo slack siempre es el
+    primer nodo.
+
+    @author: Oscar A. Leiva (MERELEC)
+    """
+
+    # constantes
+    nb = bus.shape[0]
+    nbr = branch.shape[0]
+
+    Bbus, Bf, _ = makeBdc(bus, branch)
+
+    Bbus, Bf = Bbus.todense(), Bf.todense()
+
+    H = zeros((nbr, nb))
+
+    H[:, 1:] = solve(Bbus[1:, 1:].T, Bf[:, 1:].T).T
+    #       = Bf[:,1:] * inv(Bbus[1:,1:])
+
+    return H

BIN
red/prueba1.xlsx


+ 50 - 0
red/read.py

@@ -0,0 +1,50 @@
+# -*- coding: utf-8 -*-
+# =============================================================================
+#  Copyright (C) 2018 Mercados Electricos de Centroamérica. All rights reserved
+# =============================================================================
+
+"""Importa el archivo de red RTR a utilizar para el cálculo 
+"""
+
+from pandas import read_sql, read_csv, read_excel
+
+# SERVER = "192.168.98.134"
+# DB = "MEIntegrado"
+# conn = pyodbc.connect('DRIVER={SQL Server};SERVER=' + SERVER + ';DATABASE=' + DB)
+# query = "SELECT BUS_I, BUS_J, ID_CKT, X, R, CTOIJ, CTOJI  FROM MATRIZ_RTR WHERE FECHA = '{f}'"
+
+
+def sql2net(fecha):
+    """Lee la información de  la red desde una base de datos
+
+    .. warning::
+
+        Función no implementada.
+    """
+    q = query.format(f=fecha)
+    df = read_sql(q, conn)
+    df.columns = ['bus_i', 'bus_j', 'ckt', 'x', 'r', 'max', 'min']
+    
+    return df
+
+
+def csv2net(file):
+    """Lee la información de  la red desde un archivo csv
+    """
+    df = read_csv(file)
+    df.columns = ['bus_i', 'bus_j', 'ckt', 'x', 'r', 'max', 'min']
+    
+    return df
+
+
+def excel2net(file):
+    """Lee la información de  la red desde un archivo de excel.
+
+    .. note::
+
+        La información debe de estar en una hoja del archivo llamada 'rtr'.
+    """
+    df = read_excel(file, sheet_name='rtr')
+    df.columns = ['bus_i', 'bus_j', 'ckt', 'x', 'r', 'max', 'min']
+    
+    return df

+ 2 - 0
red/utils/__init__.py

@@ -0,0 +1,2 @@
+"""Funciones varias para la ejecución del modelo
+"""

BIN
red/utils/__pycache__/__init__.cpython-36.pyc


BIN
red/utils/__pycache__/__init__.cpython-37.pyc


BIN
red/utils/__pycache__/arr2dict.cpython-36.pyc


BIN
red/utils/__pycache__/arr2dict.cpython-37.pyc


BIN
red/utils/__pycache__/idx_brch.cpython-36.pyc


BIN
red/utils/__pycache__/idx_brch.cpython-37.pyc


+ 16 - 0
red/utils/arr2dict.py

@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Thu Jul  5 16:01:56 2018
+
+@author: BI4
+"""
+
+
+def arr2dict(x):
+    """Convierte un array en diccionario."""
+    d = {}
+    for i in range(0, x.shape[0]):
+        for j in range(0, x.shape[1]):
+            d[i, j] = x[i, j]
+            
+    return d

+ 26 - 0
red/utils/idx_brch.py

@@ -0,0 +1,26 @@
+# -*- coding: utf-8 -*-
+# =============================================================================
+#  Copyright (C) 2018 Mercados Electricos de Centroamérica. All rights reserved
+# =============================================================================
+
+"""Define constantes para nombres de las columnas del dataframe de lineas
+
+El indice, nombre y descripción de cada columna es el siguiente:
+
+Columnas 0-5 incluidas en la definición de la red
+    0. C{BUS_I}     Bus de origen
+    1. C{BUS_J}     Bus de destino
+    2. C{X}         Reactancia (p.u)
+    3. C{R}         Resistencia (p.u)
+    4. C{RT_MAX}    Limite superior de transferencia en MW ij
+    5. C{RT_MIN}    Limite inferior de transferencia en MW ji
+"""
+
+# definición de indices
+BUS_I    = 0
+BUS_J    = 1
+CKT      = 2
+X        = 3
+R        = 4
+RT_MAX   = 5
+RT_MIN   = 6

+ 63 - 0
red/utils/map.py

@@ -0,0 +1,63 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Wed Jul 11 09:28:46 2018
+
+@author: BI4
+"""
+
+from mpl_toolkits.basemap import Basemap
+import matplotlib.pyplot as plt
+import matplotlib.patches as mpatches
+
+def plotMCT(MCT):
+    
+    plt.figure(figsize=(24,12))
+    _map = Basemap(projection='merc',
+                  resolution='l',
+                  llcrnrlon=-93, llcrnrlat=7,
+                  urcrnrlon=-75, urcrnrlat=19)
+    
+    _map.drawcoastlines()
+    _map.drawcountries(linewidth=1)
+    _map.drawmapboundary(fill_color='#99ffff')
+    _map.fillcontinents(color='#cc9966',lake_color='#99ffff')
+    
+    
+    _lons = [-90.25,-88.9167,-86.5,-85,-84,-81]
+    _lats = [15.5,13.7,15,13,10,8.2]
+    _inter = {'GUAESA':[0,1,'{0} MW'],
+              'GUAHON':[0,2,'{0} MW'],
+              'ESAHON':[1,2,'{0} MW'],
+              'HONNIC':[2,3,'{0} MW'],
+              'NICCRC':[3,4,'{0} MW'],
+              'CRCPAN':[4,5,'{0} MW']}
+    
+    _x,_y = _map(_lons,_lats)
+    
+    for i in _inter:
+        a = [_x[_inter[i][0]],_x[_inter[i][1]]]
+        b = [_y[_inter[i][0]],_y[_inter[i][1]]]
+        
+        if MCT[i][1] >= MCT[i][2] or MCT[i][1] <= MCT[i][0]:
+            color = 'orangered'
+        elif MCT[i][1] >= 0.8*MCT[i][2] or MCT[i][1] <= 0.8*MCT[i][0]:
+            color = 'yellow'
+        else:
+            color = 'green'
+        
+        plt.plot(a,b,'-',color=color,linewidth=3, label=_inter[i][2])
+    
+        plt.text(sum(a)/2,sum(b)/2,'{:.2f} MW'.format(MCT[i][1]*100), 
+                 fontdict={'fontsize': 12, 'backgroundcolor':'#cc9966', 'fontweight':'bold'},
+                 horizontalalignment='center',
+                 verticalalignment='center',)
+    
+    _map.plot(_x,_y,'o', color='navy',markersize=18)
+    
+    red_patch = mpatches.Patch(color='red', label='Interconexión al 100% de capacidad')
+    yellow_patch = mpatches.Patch(color='yellow', label='Interconexión a mas del 80% de capacidad')
+    green_patch = mpatches.Patch(color='green',label='Interconexión a menos del 80% de capacidad')
+    plt.legend(handles=[red_patch,yellow_patch,green_patch], loc=3, fontsize=16)
+    
+    plt.suptitle('Flujos entre Áreas de Control', fontsize =18, fontweight='bold')
+    plt.show()

BIN
utils/__pycache__/__init__.cpython-36.pyc


BIN
utils/__pycache__/__init__.cpython-37.pyc


BIN
utils/__pycache__/arr2dict.cpython-36.pyc


BIN
utils/__pycache__/arr2dict.cpython-37.pyc


BIN
utils/__pycache__/idx_brch.cpython-36.pyc


BIN
utils/__pycache__/idx_brch.cpython-37.pyc


+ 16 - 0
utils/arr2dict.py

@@ -0,0 +1,16 @@
+# -*- coding: utf-8 -*-
+"""
+Created on Thu Jul  5 16:01:56 2018
+
+@author: BI4
+"""
+
+
+def arr2dict(x):
+    """Convierte un array en diccionario."""
+    d = {}
+    for i in range(0, x.shape[0]):
+        for j in range(0, x.shape[1]):
+            d[i, j] = x[i, j]
+            
+    return d