| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685 |
- from __future__ import division
- import logging
- import traceback
- from os import path
- import sys
- import pyutilib.subprocess.GlobalData
- from numpy import array, zeros
- from pandas import DataFrame, ExcelWriter
- from pyomo.environ import *
- from pyomo.environ import SolverFactory
- from pyomo.kernel import value
- from common.data import APPDIRS
- from mct.makeMCT import linmct, readmct, set_dir_flujo
- from red.create import *
- from red.create1 import *
- from red.makeBdc import makeBdc
- from red.read import excel2net
- from utils.arr2dict import arr2dict
- pyutilib.subprocess.GlobalData.DEFINE_SIGNAL_HANDLERS_DEFAULT = False
- logger = logging.getLogger('spr.run.modelo')
- def setmodel(file, p_exec, all_day=True):
- # Determinar si se ejecuta todo el día o solo un período en específico
- if all_day:
- min = 0
- max = p_exec + 1
- logger.info("Se ejecuta el Modelo de Predespacho para las 24 horas")
- else:
- min = p_exec
- max = p_exec + 1
- logger.info(
- "Se ejecuta el Modelo de Predespacho para la hora {}".format(p_exec))
- logger.info("Modelo de Predespacho Regional")
- logger.info("Mercados Eléctricos de Centroamérica (c) 2020")
- # ============================================================================
- # Importación de datos desde archivo Excel
- # ============================================================================
- # Parametros de la linea
- logger.info("Inicio Predespacho Regional")
- logger.info("Leyendo información de RTR...")
- 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
- rc = branch[:, 4] # Resistencia 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
- # Lineas para límites de MCT
- br_t = brnames['Total'].to_numpy()
- lin_mct = linmct(br_t)
- dirf = set_dir_flujo()
- mct = readmct(file)
- # Informacion de los despachos nacionales
- dg_t = read_D_G(file)
- # Ofertas de todos los periodos
- ex_cnfff_t = readofertas_cnfffs(file)
- ex_ooi_t = readofertas_oois(file)
- ex_oor_t = readofertas_oors(file)
- ex_cf_t = readofertas_cfs(file)
- # Dataframe para almacenar la informacion de cada predespacho
- flujos_t = DataFrame()
- iep_t = DataFrame()
- pon_t = DataFrame()
- result_foo_i_t = DataFrame()
- result_foo_r_t = DataFrame()
- result_fof_t = DataFrame()
- result_foff_t = DataFrame()
- foo_ret_iny_t = DataFrame()
- # El range del for se modifica dependiendo los periodos que se quieren correr.
- for PERIODO in range(min, max):
- logger.info("Inicio de la ejecución para el periodo {}".format(PERIODO))
- logger.info("Leyendo información de los despacho nacionales.")
- # Dependiendo de los valores de la columna periodo del df son los valores que toma
- dg = dg_t[dg_t.periodo.isin([PERIODO])]
- # Resetea valores de ordenamiento del DF
- dg.reset_index(drop=True, inplace=True)
- # Ordena los valores que tiene segun los nodos de rtr
- dg_n = set_dgnacional(bus, dg)
- logger.info("Leyendo información de ofertas.")
- # Funcion leer contratos no firmes fisicos flexibles
- # Dependiendo de los valores de la columna periodo del df son los valores que toma
- ex_cnfff = ex_cnfff_t[ex_cnfff_t.periodo.isin([PERIODO])]
- # Resetea valores de ordenamiento del DF
- ex_cnfff.reset_index(drop=True, inplace=True)
- # Energia declarada con respecto al nodo
- vnfff_ed = setvariable(ex_cnfff['energía_dec'])
- # Magnitud de energia ofertada -flexibilizacion
- vnfff_m_i = setvariable_s(
- ex_cnfff[['magnitud_i1', 'magnitud_i2', 'magnitud_i3', 'magnitud_i4', 'magnitud_i5']])
- 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']])
- # Precio de la ofertas de inyeccion
- p_cnfffi = setvariable_s(
- ex_cnfff[['precio_i1', 'precio_i2', 'precio_i3', 'precio_i4', 'precio_i5']])
- # Precio de la ofertas de retiro
- p_cnfffr = setvariable_s(
- ex_cnfff[['precio_r1', 'precio_r2', 'precio_r3', 'precio_r4', 'precio_r5']])
- # Precio de la ofertas de inyeccion
- 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'])
- 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_n['Demanda'])
- gen = setvariable(dg_n['Generacion'])
- # Funcion leer parametros oferta de oportunidad inyeccion
- # Dependiendo de los valores de la columna periodo del df son los valores que toma
- ex_ooi = ex_ooi_t[ex_ooi_t.periodo.isin([PERIODO])]
- # Resetea valores de ordenamiento del DF
- ex_ooi.reset_index(drop=True, inplace=True)
- 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 = ex_oor_t[ex_oor_t.periodo.isin([PERIODO])]
- # Resetea valores de ordenamiento del DF
- ex_oor.reset_index(drop=True, inplace=True)
- voor_m = setvariable_s(ex_oor[['magnitud_oor1', 'magnitud_oor2', 'magnitud_oor3',
- 'magnitud_oor4', 'magnitud_oor5']]) # Ofertas con respecto al nodo
- # Precio de la ofertas - flexibilizacion
- p_oor = setvariable_s(
- ex_oor[['precio_oor1', 'precio_oor2', 'precio_oor3', 'precio_oor4', 'precio_oor5']])
- NOR = ex_oor.shape[0] # Numero de ofertas de retiro
- var_bin_oor = MATRIZ_OOR(bus, ex_oor)
- # Funcion leer parametros contratos firmes
- # Dependiendo de los valores de la columna periodo del df son los valores que toma
- ex_cf = ex_cf_t[ex_cf_t.periodo.isin([PERIODO])]
- # Resetea valores de ordenamiento del DF
- ex_cf.reset_index(drop=True, inplace=True)
- # Energia declarada con respecto al nodo
- vcf_ed = setvariable(ex_cf['energía_dec'])
- # Potencia requerida con respecto al nodo
- vcf_pr = setvariable(ex_cf['potencia_req'])
- # Magnitud de energia ofertada -flexibilizacion
- vcf_m = setvariable_s(
- ex_cf[['magnitu_cf1', 'magnitu_cf2', 'magnitu_cf3', 'magnitu_cf4', 'magnitu_cf5']])
- # Precio de la ofertas
- vcf_p = setvariable_s(
- ex_cf[['precio_cf1', 'precio_cf2', 'precio_cf3', 'precio_cf4', 'precio_cf5']])
- 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)
- # 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
- # numero de ofertas de oportuniddad retiro
- model.OR = Set(initialize=range(0, NOR))
- # numero de ofertas de oportunidad inyeccion
- model.OI = Set(initialize=range(0, NOI))
- # numero de ofertas de CNFFF
- model.CFF = Set(initialize=range(0, NCFF))
- # numero de ofertas de contratos firmes
- model.CF = Set(initialize=range(0, NCF))
- model.s = Set(initialize=range(0, 5)) # Numero de bloques
- model.inter = Set(initialize=lin_mct.keys()) # Interconexiones
- # Sentidos de interconexiones
- model.sen = Set(initialize=['sn', 'ns'])
- model.per = Set(initialize=range(0, 24)) # numero de periodos
- # 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)))
- model.Rc = Param(model.c, initialize=dict(enumerate(rc)))
- # 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
- # Oferta bloques 1
- model.fr = Param(model.OR, model.s, initialize=arr2dict(p_oor))
- 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
- # Precio de bloques - Oferta de oportunidad de inyeccion
- model.fi = Param(model.OI, model.s, initialize=arr2dict(p_ooi))
- 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
- # Potencia requerida - Si no se flexbiliza deberian de ser igual la energia y la potencia
- model.pf_req = Param(model.CF, initialize=dict(enumerate(vcf_pr)))
- # Precio de flexibilidad de contrato
- # Precio de bloques - Contrato firme - Oferta de flexibilidad
- model.ffi = Param(model.CF, model.s, initialize=arr2dict(vcf_p))
- # Magnitud de la oferta - tiene que ser igual a la suma de la energia declarada
- model.pfi_ofertado = Param(
- model.CF, model.s, initialize=arr2dict(vcf_m))
- 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
- # Precio de bloques - Contrato no firme fisico flexible
- model.fffr = Param(model.CFF, model.s, initialize=arr2dict(p_cnfffr))
- 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
- # Parte aceptada de cada bloques de las ofertas de oportunidad de retiro
- model.pr = Var(model.OR, model.s, domain=NonNegativeReals)
- # Parte aceptada de cada bloques de las ofertas de oportunidad de inyeccion
- model.pi = Var(model.OI, model.s, domain=NonNegativeReals)
- # Variables CF
- # Parte aceptada de cada bloques de las ofertas de flexibilidad de contratos firmes
- model.pfi = Var(model.CF, model.s, domain=NonNegativeReals)
- # Variables CNFFF
- # Parte aceptada de cada bloques de las oferta de flexibilidad de retiro
- model.pffr = 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.pffi = 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.pfft = Var(model.CFF, model.s, domain=NonNegativeReals)
- # Componente fisica de energia PERIODOria de inyeecion
- model.pff_iny_fisico = Var(model.CFF, domain=NonNegativeReals)
- # Componente fisica de energia PERIODOria de retiro
- model.pff_ret_fisico = Var(model.CFF, domain=NonNegativeReals)
- # Variables FOENS
- # Energia firme de lo CF
- model.pf_cortada = Var(model.CF, domain=NonNegativeReals)
- model.pf_pre_cortada = Var(model.CF, domain=NonNegativeReals)
- # Energia firme de los CNFFF
- model.pff_cortada = Var(model.CFF, domain=NonNegativeReals)
- model.fens = Var()
- # Variable problema de optimizacion
- # Inyeccion por nodo
- model.inyeccion = Var(model.i, domain=NonNegativeReals)
- 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
- # Máximas Capacidades de Trasferencia
- # Maxima transferenica(interconexion,sentido,periodo)
- model.Mct = Param(model.inter, model.sen, model.per,
- initialize=mct.mct.to_dict())
- model.DirF = Param(model.inter, initialize=dirf)
- logger.info("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) -
- # [ FOF
- sum(model.ffi[CF, s]*model.pfi[CF, s] for CF in model.CF for s in model.s) +
- # ┌
- sum(model.fffr[CFF, s]*model.pffr[CFF, s] for CFF in model.CFF for s in model.s) -
- # │ FOFF
- sum(model.fffi[CFF, s]*model.pffi[CFF, s] for CFF in model.CFF for s in model.s) +
- # └
- sum(model.ffft[CFF, s]*model.pfft[CFF, s]
- for CFF in model.CFF for s in model.s))) # -
- # ┌ FOENS
- # 0*model.fens*sum(model.pf_cortada[CF] for CF in model.CF) -
- # 0*model.fens*0.5*sum(model.pff_cortada[CFF] for CFF in model.CFF))) # └
- model.OBJ = Objective(rule=objfunc, sense=maximize)
- logger.info("Restricciones del Modelo de Optimización. ")
- # Esta restricción no es utilizada y se encarga de efectuar la reducción
- # de los contratos firmes (idem FOENS línea 327)
- # def fens_restriccion(model):
- # if NOR == 0 & NCF == 0 & NCFF > 0:
- # return model.fens == 3*max(model.fffr[CFF, s] for CFF in model.CFF for s in model.s)
- # elif NOR == 0 & NCF > 0 & NCFF == 0:
- # return model.fens == 3*max(model.ffi[CF, s] for CF in model.CF for s in model.s)
- # elif NOR == 0 & NCF > 0 & NCFF > 0:
- # return model.fens == 3*max(max(model.ffi[CF, s] for CF in model.CF for s in model.s),
- # max(model.fffr[CFF, s] for CFF in model.CFF for s in model.s))
- # elif NOR > 0 & NCF == 0 & NCFF == 0:
- # return model.fens == 3*max(model.fr[OR, s] for OR in model.OR for s in model.s)
- # elif NOR > 0 & NCF == 0 & NCFF > 0:
- # return model.fens == 3*max(max(model.fr[OR, s] for OR in model.OR for s in model.s),
- # max(model.fffr[CFF, s] for CFF in model.CFF for s in model.s))
- # elif NOR > 0 & NCF > 0 & NCFF == 0:
- # return model.fens == 3*max(max(model.fr[OR, s] for OR in model.OR for s in model.s),
- # max(model.ffi[CF, s] for CF in model.CF for s in model.s))
- # elif NOR > 0 & NCF > 0 & NCFF > 0:
- # return model.fens == 3*max(max(model.fr[OR, s] for OR in model.OR for s in model.s),
- # max(model.fffr[CFF, s]
- # for CFF in model.CFF for s in model.s),
- # max(model.ffi[CF, s] for CF in model.CF for s in model.s))
- # model.fens_constraint = Constraint(rule=fens_restriccion)
- # 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] - 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_cortada_constraint = Constraint(
- model.CF, rule=pf_cortada_restriccion)
- logger.info('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) -
- 0*sum(model.pf_cortada[CF]*model.bin_cfr[i, CF] for CF in model.CF) -
- 0*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) - # Al dividir entre 100 Rc
- # toda la ec. se pasa a p.u.
- 0.5*sum(((model.Inc[c, i]*model.rtmw_c[c])**2)
- * (model.Rc[c]/100) 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)
- 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)
- # Máximas capacidades de trasferencia entre áreas de control
- def eq_mct_ns_rule(model, inter):
- if inter == 'ES': # Maxima exportacion de El Salvador
- return (-(model.DirF[inter]*model.rtmw_c[lin_mct[inter][0]]+model.DirF[inter]*model.rtmw_c[lin_mct[inter][1]]) +
- (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
- elif inter == 'HON': # Maxima importacion de Honduras
- return (-(model.DirF[inter]*model.rtmw_c[lin_mct[inter][0]]+model.DirF[inter]*model.rtmw_c[lin_mct[inter][1]] +
- model.DirF[inter]*model.rtmw_c[lin_mct[inter][2]]) + (model.DirF[inter]*model.rtmw_c[lin_mct[inter][3]] +
- model.DirF[inter]*model.rtmw_c[lin_mct[inter][4]])) <= model.Mct[inter, 'sn', PERIODO] + 0.001
- else:
- return sum(model.DirF[inter]*model.rtmw_c[c] for c in lin_mct[inter]) <= model.Mct[inter, 'ns', PERIODO] + 0.001
- model.eq_mct_ns = Constraint(model.inter, rule=eq_mct_ns_rule)
- def eq_mct_sn_rule(model, inter):
- if inter == 'ES': # Maxima importacion de El Salvador
- return (-(model.DirF[inter]*model.rtmw_c[lin_mct[inter][0]]+model.DirF[inter]*model.rtmw_c[lin_mct[inter][1]]) +
- (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
- elif inter == 'HON': # Maxima importacion de Honduras
- return (-(model.DirF[inter]*model.rtmw_c[lin_mct[inter][0]]+model.DirF[inter]*model.rtmw_c[lin_mct[inter][1]] +
- model.DirF[inter]*model.rtmw_c[lin_mct[inter][2]]) + (model.DirF[inter]*model.rtmw_c[lin_mct[inter][3]] +
- model.DirF[inter]*model.rtmw_c[lin_mct[inter][4]])) >= -model.Mct[inter, 'ns', PERIODO] + 0.00001
- else:
- return sum(model.DirF[inter]*model.rtmw_c[c] for c in lin_mct[inter]) >= -model.Mct[inter, 'sn', PERIODO] + 0.00001
- model.eq_mct_sn = Constraint(model.inter, rule=eq_mct_sn_rule)
- model.dual = Suffix(direction=Suffix.IMPORT)
- logger.info("Construcción del modelo terminada.")
- ########################################### ORIGINAL #########
- # opt = SolverFactory('ipopt')
- # # opt.options['max_iter']= 10000
- # result = opt.solve(model)
- # model.solutions.store_to(result)
- ############################################ MODIFICADO POR OSCAR ############
- filename = path.basename(file).split('.')[0]
- filepath = path.dirname(file)
- try:
- opt = SolverFactory('ipopt') # TODO
- logger.info(
- "Inicio de la optimización para el periodo {}...".format(p_exec))
- result = opt.solve(
- model, logfile=f'log/solver_{filename}_{p_exec}.log', tee=True)
- model.solutions.store_to(result)
- result.write(
- filename=f"{APPDIRS['DATA']}/results_{filename}_periodo_{p_exec}.json",
- format='json')
- logger.info(
- "Solucion encontrada para el periodo{}...".format(p_exec))
- except Exception as e:
- logger.error("No se ejecutó el problema de optimización")
- logger.exception("Error: {}".format(e))
- return
- # Cálculo de Precios Nodales
- # =============================================================================
- logger.info("Calculando Precios Nodales. Periodo:" + str(PERIODO))
- 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()
- flujos['Periodo'] = set_periodo(nbr, PERIODO)
- flujos['BUS I'] = brnames['BUS I']
- flujos['BUS J'] = brnames['BUS J']
- flujos['CKT'] = brnames['CKT']
- f = array(list(model.rtmw_c.get_values().values()))
- perdidas = zeros(nbr)
- for c in model.c:
- perdidas[c] = (f[c]**2)*rc[c]/100
- flujos['Flujo'] = f
- flujos['Perdidas'] = perdidas
- # Guarda los resultados con los anteriores
- flujos_t = concat([flujos_t, flujos])
- pon = DataFrame()
- result_inyeccion = array(list(model.inyeccion.get_values().values()))
- result_retiro = array(list(model.retiro.get_values().values()))
- pon['Periodo'] = set_periodo(nb, PERIODO)
- pon['nodo'] = bus
- pon['Precio Exante'] = Sigma*-1
- # Guarda los resultados con los anteriores
- pon_t = concat([pon_t, pon])
- # print(pon)
- iep = DataFrame()
- iep['Periodo'] = set_periodo(nb, PERIODO)
- iep['nodo'] = bus
- iep['Inyeccion'] = result_inyeccion
- iep['Retiro'] = result_retiro
- # Guarda los resultados con los anteriores
- iep_t = concat([iep_t, iep])
- 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_pfi = setvariable_p(
- array(list(model.pfi.get_values().values())), NCF)
- 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_r = DataFrame()
- result_foo_r['Periodo'] = ex_oor['periodo']
- result_foo_r['N°'] = ex_oor['N°']
- result_foo_r['Pr Bloque 1'] = result_pr[:, 0]
- result_foo_r['Pr Bloque 2'] = result_pr[:, 1]
- result_foo_r['Pr Bloque 3'] = result_pr[:, 2]
- result_foo_r['Pr Bloque 4'] = result_pr[:, 3]
- result_foo_r['Pr Bloque 5'] = result_pr[:, 4]
- # Guarda los resultados con los anteriores
- result_foo_r_t = concat([result_foo_r_t, result_foo_r])
- result_foo_i = DataFrame()
- result_foo_i['Periodo'] = ex_ooi['periodo']
- result_foo_i['N°'] = ex_ooi['N°']
- result_foo_i['Pi Bloque 1'] = result_pi[:, 0]
- result_foo_i['Pi Bloque 2'] = result_pi[:, 1]
- result_foo_i['Pi Bloque 3'] = result_pi[:, 2]
- result_foo_i['Pi Bloque 4'] = result_pi[:, 3]
- result_foo_i['Pi Bloque 5'] = result_pi[:, 4]
- # Guarda los resultados con los anteriores
- result_foo_i_t = concat([result_foo_i_t, result_foo_i])
- result_fof = DataFrame()
- result_fof['Periodo'] = ex_cf['periodo']
- result_fof['N°'] = ex_cf['N°']
- result_fof['Pfi Bloque 1'] = result_pfi[:, 0]
- result_fof['Pfi Bloque 2'] = result_pfi[:, 1]
- result_fof['Pfi Bloque 3'] = result_pfi[:, 2]
- result_fof['Pfi Bloque 4'] = result_pfi[:, 3]
- result_fof['Pfi Bloque 5'] = result_pfi[:, 4]
- # Guarda los resultados con los anteriores
- result_fof_t = concat([result_fof_t, result_fof])
- result_foff = DataFrame()
- result_foff['Periodo'] = ex_cnfff['periodo']
- result_foff['N°'] = ex_cnfff['N°']
- 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]
- # Guarda los resultados con los anteriores
- result_foff_t = concat([result_foff_t, result_foff])
- foo_ret_iny = DataFrame()
- foo_ret_iny['Periodo'] = ex_cnfff['periodo']
- foo_ret_iny['N°'] = ex_cnfff['N°']
- foo_ret_iny['Inyeccion'] = result_pff_iny
- foo_ret_iny['Retiro'] = result_pff_ret
- # Guarda los resultados con los anteriores
- foo_ret_iny_t = concat([foo_ret_iny_t, foo_ret_iny])
- logger.info("Escribiendo resultados en carpeta.")
- filename = path.basename(file).split('.')
- filepath = path.dirname(file)
- if all_day:
- new_filename = filename[0]+'_results.'+filename[1]
- new_file = path.join(filepath, new_filename)
- else:
- new_filename = filename[0]+'_results_{}.'.format(p_exec)+filename[1]
- new_file = path.join(filepath, new_filename)
- writer = ExcelWriter(new_file)
- flujos_t.to_excel(writer, 'IEP-RTR', index=False)
- iep_t.to_excel(writer, 'IEP-TOTAL', index=False)
- pon_t.to_excel(writer, 'PEXANTES', index=False)
- result_foo_i_t.to_excel(writer, 'TOP-I', index=False)
- result_foo_r_t.to_excel(writer, 'TOP-R', index=False)
- result_fof_t.to_excel(writer, 'TCP-CF', index=False)
- result_foff_t.to_excel(writer, 'TCP-CNFFF-1', index=False)
- foo_ret_iny_t.to_excel(writer, 'TCP-CNFFF-2', index=False)
- writer.save()
- return 0
- if __name__ == "__main__":
- setmodel() # faltan argumentos
|