predespacho_24h.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500
  1. from __future__ import division
  2. from pyomo.environ import *
  3. from red.read import excel2net
  4. from red.create import *
  5. from red.create1 import *
  6. from red.makeBdc import makeBdc
  7. from utils.arr2dict import arr2dict
  8. from pyomo.environ import SolverFactory
  9. from pyomo.kernel import value
  10. from numpy import zeros, array
  11. from pandas import DataFrame, ExcelWriter
  12. from mct.makeMCT import linmct, readmct, set_dir_flujo
  13. from os import path
  14. def setmodel(file):
  15. print("{:=^100}".format(""))
  16. print("{:^100}".format(" Modelo de Predespacho Regional"))
  17. print("{:^100}".format(" Mercados Eléctricos de Centroamérica (c) 2020 "))
  18. print("{:=^100}".format(""))
  19. # ============================================================================
  20. # Importación de datos desde archivo Excel
  21. # ============================================================================
  22. #Parametros de la linea
  23. print("Inicio del Script de Predespacho")
  24. print("Leyendo información de red...")
  25. net = excel2net(file)
  26. bus = setbus(net)#Nodos
  27. branch = setbranch(net, bus)#Set lineas
  28. bu = branch[:, 5]#potenica max de la linea
  29. bl = branch[:, 6]#potenica min de la linea
  30. xc = branch[:,3]#Reactancia de la linea
  31. rc = branch[:,4]#Resistencia de la linea
  32. nb = bus.shape[0] #Numero de nodos
  33. nbr = branch.shape[0]#Numero de lineas
  34. A = makeBdc(bus, branch)#Matriz incidente
  35. brnames = branchnames(bus, branch)#Nombre de las lineas
  36. inc = A.toarray()*-1
  37. # Lineas para límites de MCT
  38. br_t = brnames['Total'].to_numpy()
  39. lin_mct = linmct(br_t)
  40. dirf = set_dir_flujo()
  41. mct = readmct(file)
  42. #Informacion de los despachos nacionales
  43. dg_t =read_D_G(file)
  44. #Ofertas de todos los periodos
  45. ex_cnfff_t = readofertas_cnfffs(file)
  46. ex_ooi_t = readofertas_oois(file)
  47. ex_oor_t = readofertas_oors(file)
  48. ex_cf_t = readofertas_cfs(file)
  49. #Dataframe para almacenar la informacion de cada predespacho
  50. flujos_t=DataFrame()
  51. iep_t=DataFrame()
  52. pon_t = DataFrame()
  53. result_foo_i_t = DataFrame()
  54. result_foo_r_t = DataFrame()
  55. result_fof_t = DataFrame()
  56. result_foff_t = DataFrame()
  57. foo_ret_iny_t = DataFrame()
  58. for PERIODO in range(0,1):
  59. print("Leyendo información de los despacho nacionales. Periodo: " + str(PERIODO))
  60. dg=dg_t[dg_t.periodo.isin([PERIODO])]#Dependiendo de los valores de la columna periodo del df son los valores que toma
  61. dg.reset_index(drop=True, inplace=True)#Resetea valores de ordenamiento del DF
  62. dg_n=set_dgnacional(bus,dg)#Ordena los valores que tiene segun los nodos de rtr
  63. print("Leyendo información de ofertas. Periodo: " + str(PERIODO))
  64. #Funcion leer contratos no firmes fisicos flexibles
  65. ex_cnfff=ex_cnfff_t[ex_cnfff_t.periodo.isin([PERIODO])]#Dependiendo de los valores de la columna periodo del df son los valores que toma
  66. ex_cnfff.reset_index(drop=True, inplace=True)#Resetea valores de ordenamiento del DF
  67. vnfff_ed= setvariable(ex_cnfff['energía_dec'])#Energia declarada con respecto al nodo
  68. vnfff_m_i= setvariable_s(ex_cnfff[['magnitud_i1','magnitud_i2','magnitud_i3','magnitud_i4','magnitud_i5']])#Magnitud de energia ofertada -flexibilizacion
  69. vnfff_m_r= setvariable_s(ex_cnfff[['magnitud_r1','magnitud_r2','magnitud_r3','magnitud_r4','magnitud_r5']])
  70. vnfff_m_cvt=setvariable_s(ex_cnfff[['magnitud_cvt1','magnitud_cvt2','magnitud_cvt3','magnitud_cvt4','magnitud_cvt5']])
  71. p_cnfffi= setvariable_s(ex_cnfff[['precio_i1','precio_i2','precio_i3','precio_i4','precio_i5']])#Precio de la ofertas de inyeccion
  72. p_cnfffr= setvariable_s(ex_cnfff[['precio_r1','precio_r2','precio_r3','precio_r4','precio_r5']])#Precio de la ofertas de retiro
  73. p_cnfffcvt= setvariable_s(ex_cnfff[['precio_cvt1','precio_cvt2','precio_cvt3','precio_cvt4','precio_cvt5']])#Precio de la ofertas de inyeccion
  74. k_cnfffcvt= setvariable(ex_cnfff['k'])#Precio de la ofertas de inyeccion
  75. NCFF = ex_cnfff.shape[0]#Numero de contratos firmes
  76. var_bin_cnfffr=MATRIZ_VNFFF_R(bus,ex_cnfff)
  77. var_bin_cnfffi=MATRIZ_VNFFF_I(bus,ex_cnfff)
  78. dem=setvariable(dg_n['Demanda'])
  79. gen=setvariable(dg_n['Generacion'])
  80. #Funcion leer parametros oferta de oportunidad inyeccion
  81. ex_ooi = ex_ooi_t[ex_ooi_t.periodo.isin([PERIODO])]#Dependiendo de los valores de la columna periodo del df son los valores que toma
  82. ex_ooi.reset_index(drop=True, inplace=True)#Resetea valores de ordenamiento del DF
  83. vooi_m=setvariable_s(ex_ooi[['magnitud_ooi1','magnitud_ooi2','magnitud_ooi3','magnitud_ooi4','magnitud_ooi5']])#Ofertas con respecto al nodo
  84. p_ooi= setvariable_s(ex_ooi[['precio_ooi1','precio_ooi2','precio_ooi3','precio_ooi4','precio_ooi5']])#Precio de la ofertas
  85. NOI = ex_ooi.shape[0]#Numero de ofertas de inyeccion
  86. var_bin_ooi=MATRIZ_OOI(bus,ex_ooi)
  87. #Funcion leer parametros oferta de oportunidad retiro
  88. ex_oor=ex_oor_t[ex_oor_t.periodo.isin([PERIODO])]
  89. ex_oor.reset_index(drop=True, inplace=True)#Resetea valores de ordenamiento del DF
  90. voor_m=setvariable_s(ex_oor[['magnitud_oor1','magnitud_oor2','magnitud_oor3','magnitud_oor4','magnitud_oor5']])#Ofertas con respecto al nodo
  91. p_oor= setvariable_s(ex_oor[['precio_oor1','precio_oor2','precio_oor3','precio_oor4','precio_oor5']])#Precio de la ofertas - flexibilizacion
  92. NOR = ex_oor.shape[0]#Numero de ofertas de retiro
  93. var_bin_oor=MATRIZ_OOR(bus,ex_oor)
  94. #Funcion leer parametros contratos firmes
  95. ex_cf=ex_cf_t[ex_cf_t.periodo.isin([PERIODO])]#Dependiendo de los valores de la columna periodo del df son los valores que toma
  96. ex_cf.reset_index(drop=True, inplace=True)#Resetea valores de ordenamiento del DF
  97. vcf_ed=setvariable(ex_cf['energía_dec'])#Energia declarada con respecto al nodo
  98. vcf_pr=setvariable(ex_cf['potencia_req'])#Potencia requerida con respecto al nodo
  99. vcf_m=setvariable_s(ex_cf[['magnitu_cf1','magnitu_cf2','magnitu_cf3','magnitu_cf4','magnitu_cf5']])#Magnitud de energia ofertada -flexibilizacion
  100. vcf_p= setvariable_s(ex_cf[['precio_cf1','precio_cf2','precio_cf3','precio_cf4','precio_cf5']])#Precio de la ofertas
  101. NCF = ex_cf.shape[0]#Numero de contratos firmes
  102. var_bin_cfr=MATRIZ_CFR(bus, ex_cf)
  103. var_bin_cfi=MATRIZ_CFI(bus, ex_cf)
  104. # Inicio del modelo de optimización
  105. model=ConcreteModel()
  106. #sets
  107. model.i=Set(initialize=range(0, nb))#numero de nodos
  108. model.c=Set(initialize=range(0, nbr))#Numero de lineas
  109. model.OR = Set(initialize=range(0, NOR))#numero de ofertas de oportuniddad retiro
  110. model.OI = Set(initialize=range(0, NOI))#numero de ofertas de oportunidad inyeccion
  111. model.CFF=Set(initialize=range(0, NCFF))#numero de ofertas de CNFFF
  112. model.CF=Set(initialize=range(0, NCF))#numero de ofertas de contratos firmes
  113. model.s=Set(initialize=range(0, 5))#Numero de bloques
  114. model.inter = Set(initialize=lin_mct.keys()) # Interconexiones
  115. model.sen = Set(initialize=['sn', 'ns']) # Sentidos de interconexiones
  116. model.per=Set(initialize=range(0, 24))#numero de periodos
  117. #Parametros
  118. #Parametros de la red
  119. model.rtmw_min= Param(model.c, initialize=dict(enumerate(bl)))
  120. model.rtmw_max= Param(model.c, initialize=dict(enumerate(bu)))
  121. model.Inc = Param(model.c, model.i, initialize=arr2dict(inc))
  122. model.Xc = Param(model.c, initialize=dict(enumerate(xc)))
  123. model.Rc = Param(model.c, initialize=dict(enumerate(rc)))
  124. #Parametros de los predespachos nacionales
  125. model.D = Param(model.i, initialize=dict(enumerate(dem)))
  126. model.G = Param(model.i, initialize=dict(enumerate(gen)))
  127. #Ofertas de oportunidad
  128. #Oferta de oportunidad de retiro
  129. model.fr= Param(model.OR, model.s, initialize=arr2dict(p_oor))#Oferta bloques 1
  130. model.pr_ofertado = Param(model.OR, model.s, initialize=arr2dict(voor_m))#Magnitud de la oferta MW-h
  131. model.bin_pr = Param(model.i, model.OR, initialize=arr2dict(var_bin_oor))
  132. #Oferta de oportunidad de inyeccion
  133. model.fi= Param(model.OI, model.s, initialize=arr2dict(p_ooi))#Precio de bloques - Oferta de oportunidad de inyeccion
  134. model.pi_ofertado= Param(model.OI, model.s, initialize=arr2dict(vooi_m))#Magnitud de la oferta MW-h
  135. model.bin_pi = Param(model.i,model.OI,initialize=arr2dict(var_bin_ooi))
  136. #Contratos firmes
  137. model.pf_declarada=Param(model.CF, initialize=dict(enumerate(vcf_ed)))#Energia declarada
  138. 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
  139. #Precio de flexibilidad de contrato
  140. model.ffi=Param(model.CF, model.s, initialize=arr2dict(vcf_p))#Precio de bloques - Contrato firme - Oferta de flexibilidad
  141. 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
  142. model.bin_cfi=Param(model.i, model.CF,initialize=arr2dict(var_bin_cfi))
  143. model.bin_cfr=Param(model.i, model.CF,initialize=arr2dict(var_bin_cfr))
  144. #Ofertas de flexibilidad de contratos fisicos flexibles
  145. #Ofertas de inyeccion
  146. model.pff_declarada=Param(model.CFF, initialize=dict(enumerate(vnfff_ed)))
  147. model.pffi_ofertado=Param(model.CFF, model.s, initialize=arr2dict(vnfff_m_i))#Magnitud del bloque
  148. model.fffi=Param(model.CFF, model.s, initialize=arr2dict(p_cnfffi))#Precio de inyeccion
  149. model.bin_pffi=Param(model.i,model.CFF, initialize=arr2dict(var_bin_cnfffi))
  150. #Oferta de retiro
  151. model.pffr_ofertado=Param(model.CFF, model.s, initialize=arr2dict(vnfff_m_r))#Magnitud de bloque de retiro ofertado
  152. model.fffr=Param(model.CFF, model.s, initialize=arr2dict(p_cnfffr))#Precio de bloques - Contrato no firme fisico flexible
  153. model.bin_pffr=Param(model.i,model.CFF, initialize=arr2dict(var_bin_cnfffr))
  154. #Ofertad de pago maximo por CVT
  155. model.k=Param(model.CFF, initialize=dict(enumerate(k_cnfffcvt)))#Indicador de oferta
  156. model.pfft_ofertado=Param(model.CFF, model.s, initialize=arr2dict(vnfff_m_cvt))#Magnitud del bloque
  157. model.ffft=Param(model.CFF, model.s, initialize=arr2dict(p_cnfffcvt))#Precio de pago maximo CVT
  158. #Variabeles
  159. #Variable ofertas de oportunidad
  160. model.pr= Var(model.OR, model.s, domain=NonNegativeReals)#Parte aceptada de cada bloques de las ofertas de oportunidad de retiro
  161. model.pi= Var(model.OI, model.s, domain=NonNegativeReals)#Parte aceptada de cada bloques de las ofertas de oportunidad de inyeccion
  162. #Variables CF
  163. model.pfi=Var(model.CF, model.s, domain=NonNegativeReals)#Parte aceptada de cada bloques de las ofertas de flexibilidad de contratos firmes
  164. #Variables CNFFF
  165. model.pffr=Var(model.CFF, model.s, domain=NonNegativeReals)#Parte aceptada de cada bloques de las oferta de flexibilidad de retiro
  166. 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
  167. 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
  168. model.pff_iny_fisico=Var(model.CFF, domain=NonNegativeReals)#Componente fisica de energia PERIODOria de inyeecion
  169. model.pff_ret_fisico=Var(model.CFF, domain=NonNegativeReals)#Componente fisica de energia PERIODOria de retiro
  170. #Variables FOENS
  171. model.pf_cortada=Var(model.CF, domain=NonNegativeReals)#Energia firme de lo CF
  172. model.pf_pre_cortada=Var(model.CF, domain=NonNegativeReals)
  173. model.pff_cortada=Var(model.CFF, domain=NonNegativeReals)#Energia firme de los CNFFF
  174. model.fens=Var()
  175. #Variable problema de optimizacion
  176. model.inyeccion= Var(model.i, domain=NonNegativeReals)#Inyeccion por nodo
  177. model.retiro= Var(model.i, domain=NonNegativeReals)#Retiro por nodo
  178. model.ref_angular= Var(model.i)#Fase del voltaje en el nodo
  179. model.rtmw_c= Var(model.c)#Flujo de potencia actica por linea
  180. # Máximas Capacidades de Trasferencia
  181. model.Mct = Param(model.inter, model.sen, model.per, initialize=mct.mct.to_dict())#Maxima transferenica(interconexion,sentido,periodo)
  182. model.DirF = Param(model.inter, initialize=dirf)
  183. print("Ecuación de Función Objetivo Max. Periodo: " + str(PERIODO))
  184. def objfunc(model):
  185. return ((sum(model.fr[OR,s]*model.pr[OR,s] for OR in model.OR for s in model.s) - # ┌ FOO
  186. sum(model.fi[OI,s]*model.pi[OI,s] for OI in model.OI for s in model.s) - # └
  187. sum(model.ffi[CF,s]*model.pfi[CF,s] for CF in model.CF for s in model.s) + # [ FOF
  188. sum(model.fffr[CFF,s]*model.pffr[CFF,s] for CFF in model.CFF for s in model.s) - # ┌
  189. sum(model.fffi[CFF,s]*model.pffi[CFF,s] for CFF in model.CFF for s in model.s) + # │ FOFF
  190. sum(model.ffft[CFF,s]*model.pfft[CFF,s] for CFF in model.CFF for s in model.s) - # └
  191. 0*model.fens*sum(model.pf_cortada[CF] for CF in model.CF) - # ┌ FOENS
  192. 0*model.fens*0.5*sum(model.pff_cortada[CFF] for CFF in model.CFF))) # └
  193. model.OBJ= Objective(rule=objfunc, sense=maximize)
  194. print("Restricciones del Modelo de Optimización. Periodo: "+str(PERIODO))
  195. def fens_restriccion(model):
  196. if NOR==0 & NCF==0 & NCFF>0:
  197. return model.fens == 3*max(model.fffr[CFF,s] for CFF in model.CFF for s in model.s)
  198. elif NOR==0 & NCF>0 & NCFF==0:
  199. return model.fens == 3*max(model.ffi[CF,s] for CF in model.CF for s in model.s)
  200. elif NOR==0 & NCF>0 & NCFF>0:
  201. return model.fens == 3*max(max(model.ffi[CF,s] for CF in model.CF for s in model.s),
  202. max(model.fffr[CFF,s] for CFF in model.CFF for s in model.s))
  203. elif NOR>0 & NCF==0 & NCFF==0:
  204. return model.fens == 3*max(model.fr[OR,s] for OR in model.OR for s in model.s)
  205. elif NOR>0 & NCF==0 & NCFF>0:
  206. return model.fens == 3*max(max(model.fr[OR,s] for OR in model.OR for s in model.s),
  207. max(model.fffr[CFF,s] for CFF in model.CFF for s in model.s))
  208. elif NOR>0 & NCF>0 & NCFF==0:
  209. return model.fens == 3*max(max(model.fr[OR,s] for OR in model.OR for s in model.s),
  210. max(model.ffi[CF,s] for CF in model.CF for s in model.s))
  211. elif NOR>0 & NCF>0 & NCFF>0:
  212. return model.fens == 3*max(max(model.fr[OR,s] for OR in model.OR for s in model.s),
  213. max(model.fffr[CFF,s] for CFF in model.CFF for s in model.s),
  214. max(model.ffi[CF,s] for CF in model.CF for s in model.s))
  215. model.fens_constraint= Constraint(rule=fens_restriccion)
  216. #Restrecciones FOO
  217. def pi_restriccion(model,OI,s):
  218. return ((model.pi[OI,s] <=model.pi_ofertado[OI,s]))
  219. model.pi_constraint= Constraint(model.OI, model.s, rule=pi_restriccion)
  220. def pr_restriccion(model,OR,s):
  221. return ((model.pr[OR,s]<=model.pr_ofertado[OR,s]))
  222. model.pr_constraint= Constraint(model.OR, model.s, rule=pr_restriccion)
  223. #Restricciones FOF
  224. def pfi_restriccion(model,CF,s):
  225. return (model.pfi[CF,s]<=model.pfi_ofertado[CF,s])
  226. model.pfi_constraint= Constraint(model.CF, model.s, rule=pfi_restriccion)
  227. #Restricciones FOFF
  228. def pffr_restriccion(model,CFF,s):
  229. return (model.pffr[CFF,s]<=model.pffr_ofertado[CFF,s])
  230. model.pffr_constraint= Constraint(model.CFF, model.s, rule=pffr_restriccion)
  231. def pffi_restriccion(model,CFF,s):
  232. return (model.pffi[CFF,s]<=model.pffi_ofertado[CFF,s])
  233. model.pffi_constraint= Constraint(model.CFF, model.s, rule=pffi_restriccion)
  234. if (model.k[CFF] ==0 for CFF in model.CFF):
  235. def pfft_restriccion(model,CFF,s):
  236. #if model.k[CFF] ==0:
  237. return (model.pfft[CFF,s]<=model.pfft_ofertado[CFF,s])
  238. model.pfft_constraint= Constraint(model.CFF, model.s, rule=pfft_restriccion)
  239. #K(cff) vale 0 si hay oferta de pago maximo por CVT
  240. def pff_iny_fisico_restriccion(model,CFF):
  241. if model.k[CFF] ==0:
  242. 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))
  243. elif model.k[CFF] ==1:
  244. return (model.pff_iny_fisico[CFF]==model.pff_declarada[CFF] - sum(model.pffr[CFF,s] for s in model.s))
  245. model.pff_iny_fisico_constraint=Constraint(model.CFF, rule=pff_iny_fisico_restriccion)
  246. def pff_ret_fisico_restriccion(model,CFF):
  247. if model.k[CFF] ==0:
  248. 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))
  249. elif model.k[CFF] ==1:
  250. return (model.pff_ret_fisico[CFF]==model.pff_declarada[CFF] - model.pff_cortada[CFF]- sum(model.pffi[CFF,s] for s in model.s))
  251. model.pff_ret_fisico_constraint=Constraint(model.CFF, rule=pff_ret_fisico_restriccion)
  252. #Restriccion FOENS
  253. def pff_cortada_restriccion(model,CFF):
  254. return (model.pff_cortada[CFF]<=model.pff_declarada[CFF])
  255. model.pff_cortada_constraint=Constraint(model.CFF, rule=pff_cortada_restriccion)
  256. def pf_cortada_restriccion(model,CF):
  257. return (model.pf_cortada[CF]<=model.pf_req[CF])
  258. model.pf_cortada_constraint=Constraint(model.CF, rule=pf_cortada_restriccion)
  259. print('Restricciones de transmision. Periodo: ' + str(PERIODO))
  260. #Restricciones de transmision
  261. def inyec(model,i):
  262. return (model.inyeccion[i] == model.G[i] +
  263. sum(model.pi[OI,s]*model.bin_pi[i,OI] for OI in model.OI for s in model.s) +
  264. sum(model.pfi[CF,s]*model.bin_cfi[i,CF] for CF in model.CF for s in model.s) +
  265. sum(model.pff_iny_fisico[CFF]*model.bin_pffi[i,CFF] for CFF in model.CFF))
  266. model.inyec_constraint= Constraint(model.i, rule=inyec)
  267. def retiro(model,i):
  268. return (model.retiro[i] == model.D[i] +
  269. sum(model.pr[OR,s]*model.bin_pr[i,OR] for OR in model.OR for s in model.s) +
  270. sum(model.pf_req[CF]*model.bin_cfr[i,CF] for CF in model.CF) +
  271. sum(model.pff_ret_fisico[CFF]*model.bin_pffr[i,CFF] for CFF in model.CFF) -
  272. 0*sum(model.pf_cortada[CF]*model.bin_cfr[i,CF] for CF in model.CF) -
  273. 0*sum(model.pf_pre_cortada[CF]*model.bin_cfr[i,CF] for CF in model.CF))
  274. model.retiro_constraint= Constraint(model.i, rule=retiro)
  275. #Los multiplicadore o variable duales de esta restriccion son los precios nodales
  276. def balance_inyeccion_retiro(model,i):
  277. return (model.inyeccion[i] + sum(model.Inc[c,i]*model.rtmw_c[c] for c in model.c) - # Al dividir entre 100 Rc
  278. 0.5*sum(((model.Inc[c,i]*model.rtmw_c[c])**2)*(model.Rc[c]/100) for c in model.c) # toda la ec. se pasa a p.u.
  279. == model.retiro[i])
  280. model.balance_inyeccion_retiro_constraint= Constraint(model.i,rule=balance_inyeccion_retiro)
  281. def rtmw_min_restriccion(model,c):
  282. return (model.rtmw_c[c] >=-model.rtmw_min[c])
  283. model.rtmw_min_constraint= Constraint(model.c, rule=rtmw_min_restriccion)
  284. def rtmw_max_restriccion(model,c):
  285. return (model.rtmw_c[c] <=model.rtmw_max[c])
  286. model.rtmw_max_constraint= Constraint(model.c, rule=rtmw_max_restriccion)
  287. def flujo_potencia_actica(model,c):
  288. return ((model.Xc[c])*model.rtmw_c[c]+sum(model.Inc[c,i]*model.ref_angular[i] for i in model.i)== 0)
  289. model.flujo_potencia_actica_constraint= Constraint(model.c, rule=flujo_potencia_actica)
  290. # Máximas capacidades de trasferencia entre áreas de control
  291. def eq_mct_ns_rule(model, inter):
  292. if inter=='ES':#Maxima exportacion de El Salvador
  293. return (-(model.DirF[inter]*model.rtmw_c[lin_mct[inter][0]]+model.DirF[inter]*model.rtmw_c[lin_mct[inter][1]]) +
  294. (model.DirF[inter]*model.rtmw_c[lin_mct[inter][2]]+model.DirF[inter]*model.rtmw_c[lin_mct[inter][3]])) <= model.Mct[inter, 'ns', PERIODO] + 0.001
  295. elif inter=='HON':#Maxima importacion de Honduras
  296. return (-(model.DirF[inter]*model.rtmw_c[lin_mct[inter][0]]+model.DirF[inter]*model.rtmw_c[lin_mct[inter][1]] +
  297. model.DirF[inter]*model.rtmw_c[lin_mct[inter][2]]) + (model.DirF[inter]*model.rtmw_c[lin_mct[inter][3]]+
  298. model.DirF[inter]*model.rtmw_c[lin_mct[inter][4]])) <= model.Mct[inter, 'sn', PERIODO] + 0.001
  299. else:
  300. return sum(model.DirF[inter]*model.rtmw_c[c] for c in lin_mct[inter]) <= model.Mct[inter, 'ns', PERIODO] + 0.001
  301. model.eq_mct_ns = Constraint(model.inter, rule=eq_mct_ns_rule)
  302. def eq_mct_sn_rule(model, inter):
  303. if inter=='ES':#Maxima importacion de El Salvador
  304. return (-(model.DirF[inter]*model.rtmw_c[lin_mct[inter][0]]+model.DirF[inter]*model.rtmw_c[lin_mct[inter][1]]) +
  305. (model.DirF[inter]*model.rtmw_c[lin_mct[inter][2]]+model.DirF[inter]*model.rtmw_c[lin_mct[inter][3]])) >= -model.Mct[inter, 'sn', PERIODO] + 0.00001
  306. elif inter=='HON':#Maxima importacion de Honduras
  307. return (-(model.DirF[inter]*model.rtmw_c[lin_mct[inter][0]]+model.DirF[inter]*model.rtmw_c[lin_mct[inter][1]] +
  308. model.DirF[inter]*model.rtmw_c[lin_mct[inter][2]]) + (model.DirF[inter]*model.rtmw_c[lin_mct[inter][3]]+
  309. model.DirF[inter]*model.rtmw_c[lin_mct[inter][4]])) >= -model.Mct[inter, 'ns', PERIODO] + 0.00001
  310. else:
  311. return sum(model.DirF[inter]*model.rtmw_c[c] for c in lin_mct[inter]) >= -model.Mct[inter, 'sn', PERIODO] + 0.00001
  312. model.eq_mct_sn = Constraint(model.inter, rule=eq_mct_sn_rule)
  313. model.dual = Suffix(direction=Suffix.IMPORT)
  314. print("Construcción del modelo terminada. Periodo: "+str(PERIODO))
  315. opt = SolverFactory('ipopt')
  316. #opt.options['max_iter']= 10000
  317. result = opt.solve(model)
  318. model.solutions.store_to(result)
  319. # Cálculo de Precios Nodales
  320. # =============================================================================
  321. print("Calculando Precios Nodales. Periodo:" + str(PERIODO))
  322. Sigma = zeros(nb)
  323. for i in model.i:
  324. Sigma[i] = model.dual[model.balance_inyeccion_retiro_constraint[i]]
  325. # Construcción de array para grabar
  326. # =============================================================================
  327. flujos=DataFrame()
  328. flujos['Periodo']=set_periodo(nbr,PERIODO)
  329. flujos['BUS I'] = brnames['BUS I']
  330. flujos['BUS J'] = brnames['BUS J']
  331. flujos['CKT'] = brnames['CKT']
  332. f = array(list(model.rtmw_c.get_values().values()))
  333. perdidas=zeros(nbr)
  334. for c in model.c:
  335. perdidas[c]=(f[c]**2)*rc[c]/100
  336. flujos['Flujo'] = f
  337. flujos['Perdidas'] = perdidas
  338. flujos_t=concat([flujos_t,flujos])#Guarda los resultados con los anteriores
  339. pon = DataFrame()
  340. result_inyeccion = array(list(model.inyeccion.get_values().values()))
  341. result_retiro = array(list(model.retiro.get_values().values()))
  342. pon['Periodo']=set_periodo(nb,PERIODO)
  343. pon['nodo']= bus
  344. pon['Precio Exante'] = Sigma*-1
  345. pon_t=concat([pon_t,pon])#Guarda los resultados con los anteriores
  346. #print(pon)
  347. iep=DataFrame()
  348. iep['Periodo']=set_periodo(nb,PERIODO)
  349. iep['nodo']= bus
  350. iep['Inyeccion'] = result_inyeccion
  351. iep['Retiro'] = result_retiro
  352. iep_t=concat([iep_t,iep])#Guarda los resultados con los anteriores
  353. result_pff_iny=array(list(model.pff_iny_fisico.get_values().values()))
  354. result_pff_ret=array(list(model.pff_ret_fisico.get_values().values()))
  355. result_pr = setvariable_p(array(list(model.pr.get_values().values())),NOR)
  356. result_pi = setvariable_p(array(list(model.pi.get_values().values())),NOI)
  357. result_pfi = setvariable_p(array(list(model.pfi.get_values().values())),NCF)
  358. result_pffr = setvariable_p(array(list(model.pffr.get_values().values())),NCFF)
  359. result_pffi = setvariable_p(array(list(model.pffi.get_values().values())),NCFF)
  360. result_pfft = setvariable_p(array(list(model.pfft.get_values().values())),NCFF)
  361. result_foo_r=DataFrame()
  362. result_foo_r['Periodo']=ex_oor['periodo']
  363. result_foo_r['N°']=ex_oor['N°']
  364. result_foo_r['Pr Bloque 1']=result_pr[:,0]
  365. result_foo_r['Pr Bloque 2']=result_pr[:,1]
  366. result_foo_r['Pr Bloque 3']=result_pr[:,2]
  367. result_foo_r['Pr Bloque 4']=result_pr[:,3]
  368. result_foo_r['Pr Bloque 5']=result_pr[:,4]
  369. result_foo_r_t=concat([result_foo_r_t,result_foo_r])#Guarda los resultados con los anteriores
  370. result_foo_i=DataFrame()
  371. result_foo_i['Periodo']=ex_ooi['periodo']
  372. result_foo_i['N°']=ex_ooi['N°']
  373. result_foo_i['Pi Bloque 1']=result_pi[:,0]
  374. result_foo_i['Pi Bloque 2']=result_pi[:,1]
  375. result_foo_i['Pi Bloque 3']=result_pi[:,2]
  376. result_foo_i['Pi Bloque 4']=result_pi[:,3]
  377. result_foo_i['Pi Bloque 5']=result_pi[:,4]
  378. result_foo_i_t=concat([result_foo_i_t,result_foo_i])#Guarda los resultados con los anteriores
  379. result_fof=DataFrame()
  380. result_fof['Periodo']=ex_cf['periodo']
  381. result_fof['N°']=ex_cf['N°']
  382. result_fof['Pfi Bloque 1']=result_pfi[:,0]
  383. result_fof['Pfi Bloque 2']=result_pfi[:,1]
  384. result_fof['Pfi Bloque 3']=result_pfi[:,2]
  385. result_fof['Pfi Bloque 4']=result_pfi[:,3]
  386. result_fof['Pfi Bloque 5']=result_pfi[:,4]
  387. result_fof_t=concat([result_fof_t,result_fof])#Guarda los resultados con los anteriores
  388. result_foff=DataFrame()
  389. result_foff['Periodo']=ex_cnfff['periodo']
  390. result_foff['N°']=ex_cnfff['N°']
  391. result_foff['Pffr Bloque 1']=result_pffr[:,0]
  392. result_foff['Pffr Bloque 2']=result_pffr[:,1]
  393. result_foff['Pffr Bloque 3']=result_pffr[:,2]
  394. result_foff['Pffr Bloque 4']=result_pffr[:,3]
  395. result_foff['Pffr Bloque 5']=result_pffr[:,4]
  396. result_foff['Pffi Bloque 1']=result_pffi[:,0]
  397. result_foff['Pffi Bloque 2']=result_pffi[:,1]
  398. result_foff['Pffi Bloque 3']=result_pffi[:,2]
  399. result_foff['Pffi Bloque 4']=result_pffi[:,3]
  400. result_foff['Pffi Bloque 5']=result_pffi[:,4]
  401. result_foff['Pfft Bloque 1']=result_pfft[:,0]
  402. result_foff['Pfft Bloque 2']=result_pfft[:,1]
  403. result_foff['Pfft Bloque 3']=result_pfft[:,2]
  404. result_foff['Pfft Bloque 4']=result_pfft[:,3]
  405. result_foff['Pfft Bloque 5']=result_pfft[:,4]
  406. result_foff_t=concat([result_foff_t,result_foff])#Guarda los resultados con los anteriores
  407. foo_ret_iny=DataFrame()
  408. foo_ret_iny['Periodo']=ex_cnfff['periodo']
  409. foo_ret_iny['N°']=ex_cnfff['N°']
  410. foo_ret_iny['Inyeccion']=result_pff_iny
  411. foo_ret_iny['Retiro']=result_pff_ret
  412. foo_ret_iny_t=concat([foo_ret_iny_t,foo_ret_iny])#Guarda los resultados con los anteriores
  413. print("Escribiendo resultados en carpeta.")
  414. filename = path.basename(file).split('.')
  415. filepath = path.dirname(file)
  416. new_filename = filename[0]+'_results.'+filename[1]
  417. new_file = path.join(filepath, new_filename)
  418. writer=ExcelWriter(new_file)
  419. flujos_t.to_excel(writer,'IEP-RTR',index=False)
  420. iep_t.to_excel(writer,'IEP-TOTAL',index=False)
  421. pon_t.to_excel(writer,'PEXANTES',index=False)
  422. result_foo_i_t.to_excel(writer,'TOP-I',index=False)
  423. result_foo_r_t.to_excel(writer,'TOP-R',index=False)
  424. result_fof_t.to_excel(writer,'TCP-CF',index=False)
  425. result_foff_t.to_excel(writer,'TCP-CNFFF-1',index=False)
  426. foo_ret_iny_t.to_excel(writer,'TCP-CNFFF-2',index=False)
  427. writer.save()
  428. print("{:=^100}".format(""))
  429. print("{:^100}".format(" Script Finalizado "))
  430. print("{:^100}".format(" Mercados Eléctricos de Centroamérica (c) 2020 "))
  431. print("{:=^100}".format(""))
  432. return 0