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