<jupyter_start><jupyter_text>Agregamos los parámetros del modelo a los elementos de la red.<jupyter_code>def net_add_optfw(net):
    #agregamos parámetros para el costo inicial en forma de un valor constante ic_0 y un valor función lineal de la potencia ic_1
    net.ext_grid['ic_0_mu'] = 0.0
    net.ext_grid['ic_1_mu'] = 0.0

    #idem para costo operativo
    net.ext_grid['oc_0_mu'] = 0.0
    net.ext_grid['oc_1_mu'] = 0.0

    #potencia disponible
    net.ext_grid['ap_mw'] = 0.5
    
    #potencia entregada
    net.ext_grid['op_mw'] = 0.0
    
    #las restricciones pueden ser ninguna, o una lista de restricciones tipo pyomo
    net.ext_grid['constraints'] = None

    #se repite para la carga y los generadores estáticos
    net.load['ic_0_mu'] = 0.0
    net.load['ic_1_mu'] = 0.0
    net.load['oc_0_mu'] = 0.0
    net.load['oc_1_mu'] = 0.0
    net.load['ap_mw'] = 0.5
    net.load['op_mw'] = 0.0
    net.load['constraints'] = None

    net.sgen['ic_0_mu'] = 0.0
    net.sgen['ic_1_mu'] = 0.0
    net.sgen['oc_0_mu'] = 0.0
    net.sgen['oc_1_mu'] = 0.0
    net.sgen['ap_mw'] = 0.5
    net.sgen['op_mw'] = 0.0
    net.sgen['constraints'] = None
net_add_optfw(net)<jupyter_output><empty_output><jupyter_text>Vemos como queda por ejemplo el elemento de red externa:<jupyter_code>net.ext_grid<jupyter_output><empty_output><jupyter_text>Defino una función normal de Python para que nos va a dar la componente lineal del costo de la energía Variables que define el modelo:y para el añod para el día del añoh para la hora del díadt la granularidad del modelo, en horastemp la temperaturawv la velocidad del vientoI la irradiación solareg el crecimiento económico en pu respecto al año 0Estas variables llegan como parámetros en forma de diccionario en el argumento 'model_status' (ver este nombre)Todas las funciones reciben este argumento, la lógica de la función indica que valor retorna. Pr ejemplo, si la granularidad es 24 h, debe retornar el valor medio del parámetro producido.<jupyter_code>def oc_1_ext_grid(model_status={}):
    #modelo sencillo con dos precios, uno entre 0 a 18 y otro de 18 a 24
    res = 0.0
    sx = 1e-6
    if 'h' in model_status:
        h = model_status['h']
        if 0.0 <= h and h < 18.0:
            res = 3600.0*sx
        elif 18 <= h and h < 24.0:
            res = 5400.0*sx
        else:
            raise ValueError("Hour outside model range")
    else:
        raise ValueError("Hour not defined")
    
    return res
#test:
#m_s = {'y': 0, 'd': 180, 'h': 14.0, 'dt': 1.0, 'temp': 12.0, 'wv': 10.0, 'eg': 1.0}

#oc_1_ext_grid(m_s)
#20 hs: 5400
#m_s['h'] = 20.5
#oc_1_ext_grid(m_s)
#25 hs: error
#m_s['h'] = 25
#oc_1_ext_grid(m_s)
net.ext_grid['oc_1_mu'][0] = oc_1_ext_grid
net.ext_grid
def demand(model_status={}):
    #modelo sencillo en forma de escalones
    #devuelvr la fracción de la carga empleada
    res = 0.0
    if 'h' in model_status:
        h = model_status['h']
        if 0.0 <= h and h < 6.0:
            res = 0.2
        elif 6.0 <= h and h < 8.0:
            res = 0.4
        elif 8.0 <= h and h < 18.0:
            res = 0.5
        elif 18.0 <= h and h < 22.0:
            res = 1.0
        elif 22.0 <= h and h < 24.0:
            res = 0.3            
        else:
            raise ValueError("Hour outside model range")
    else:
        raise ValueError("Hour not defined")
    
    return res
net.load['op_mw'][0] = demand
net.load
def solar_output(model_status={}):
    #modelo sencillo
    #devuelvr la fracción de la potencia entregada en función del tiempo
    #no toma en cuenta la radicación solar ni la temperatura
    res = 0.0
    if 'h' in model_status:
        h = model_status['h']
        if 0.0 <= h and h < 8.0:
            res = 0.0
        elif 8.0 <= h and h < 18.0:
            res = math.exp(-(h-13.0)**2/8)
        elif 18.0 <= h and h < 24.0:
            res = 0.0
        else:
            raise ValueError("Hour outside model range")
    else:
        raise ValueError("Hour not defined")
    
    return res
#test:
#m_s = {'y': 0, 'd': 180, 'h': 43.0, 'dt': 1.0, 'temp': 12.0, 'wv': 10.0, 'eg': 1.0}
#solar_output(m_s)
net.sgen['name'][0] = 'PV1'
net.sgen['ap_mw'][0] = solar_output
net.sgen['ic_0_mu'][0] = 2
net.sgen['ic_1_mu'][0] = 3*0.75
net.sgen['oc_0_mu'][0] = 0.0
net.sgen['oc_1_mu'][0] = 500e-6

def wind_output(model_status={}):
    #modelo sencillo
    #devuelvr la fracción de la potencia entregada en función del tiempo
    #no toma en cuenta la radicación solar ni la temperatura
    res = 0.0
    if 'wv' in model_status:
        wv = model_status['wv']
        if 0.0 <= wv and wv < 3.0:
            res = 0.0
        elif 3.0 <= wv and wv < 15.0:
            res = (wv-3.0)/(15.0-3.0)
        elif 15.0 <= wv and wv < 25.0:
            res = 1.0
        else:
            res = 0.0
    else:
        raise ValueError("Wind Velocity not defined")
    
    return res
net.sgen['name'][1] = 'WT1'
net.sgen['ap_mw'][1] = wind_output
net.sgen['ic_0_mu'][1] = 100.0
net.sgen['ic_1_mu'][1] = 3.0
net.sgen['oc_0_mu'][1] = 0.0
net.sgen['oc_1_mu'][1] = 700e-6
net.sgen<jupyter_output><empty_output><jupyter_text>Primero construyo un modelo manualmente:Es un modelo de dimensionamiento de 2 DERs (WT+PV)<jupyter_code>m = pe.ConcreteModel()
dias = 365
años = 5
M = 1e3
#el rango de horas:
T_i = range(24)
#las variables que definien si construir y que potencia
m.ap_mw_PV = pe.Var(within = pe.NonNegativeReals)  #Tamano PV
m.ap_mw_WT = pe.Var(within = pe.NonNegativeReals)  #Tamano WT

m.sgen_PV = pe.Var(within = pe.Binary)
m.sgen_WT = pe.Var(within = pe.Binary) 
#despacho de solar y WT disponible
m.p_mw_PV = pe.Var(T_i, within = pe.NonNegativeReals)
m.p_mw_WT = pe.Var(T_i, within = pe.NonNegativeReals)
#energia comprada a la red
m.p_mw_Ext = pe.Var(T_i, within = pe.NonNegativeReals, bounds = (0, net.ext_grid['ap_mw'][0]))
#si puedo exportar:
##m.p_mw_Ext = pe.Var(T_i, bounds = (-net.ext_grid['ap_mw'][0], net.ext_grid['ap_mw'][0]))
#el rango de condiciones:
m_s = {'y': 0, 'd': 180, 'h': 43.0, 'dt': 1.0, 'temp': 12.0, 'wv': 10.0, 'eg': 1.0}

Escenarios_i = []
for t in T_i:
    Escenarios_i.append({'y': 0, 'd': 180, 'h': 1.0*t, 'dt': 1.0, 'temp': 12.0, 'wv': random.uniform(1.0, 20.0), 'eg': 1.0})

#Escenarios_i
#los costos iniciales:
costos_iniciales = net.ext_grid['ic_0_mu'][0] + net.load['ic_0_mu'][0] + m.sgen_PV*net.sgen['ic_0_mu'][0] + m.sgen_WT*net.sgen['ic_0_mu'][1] +  \
                   net.ext_grid['ic_1_mu'][0]*0 + net.load['ic_1_mu'][0]*0 + m.ap_mw_PV * net.sgen['ic_1_mu'][0] + m.ap_mw_WT * net.sgen['ic_1_mu'][1]
print(costos_iniciales)
costos_variables = sum(m.p_mw_PV[t]*net.sgen['oc_1_mu'][0]*dias*años+ m.p_mw_WT[t]*net.sgen['oc_1_mu'][1]*dias*años + m.p_mw_Ext[t]*net.ext_grid['oc_1_mu'][0](Escenarios_i[t])*dias*años for t in T_i)
print(costos_variables)
costos = costos_iniciales + costos_variables
print(costos)
m.value = pe.Objective(
expr = costos_iniciales + costos_variables,
sense = pe.minimize )
def hourly_power_balance(m, t):
    return m.p_mw_Ext[t] + m.p_mw_PV[t] + m.p_mw_WT[t] - net.load['op_mw'][0](Escenarios_i[t])*net.load['p_mw'][0] == 0
m.hourly_power_balance = pe.Constraint(T_i, rule = hourly_power_balance)
#dimensionamiento solar:
m.PV_dim = pe.Constraint(T_i, rule = (lambda m, t : m.p_mw_PV[t] <= m.ap_mw_PV*net.sgen['ap_mw'][0](Escenarios_i[t])))
m.PV_build = pe.Constraint( expr = m.ap_mw_PV <= m.sgen_PV*M)
#dimensionamiento WT:
m.WT_dim = pe.Constraint(T_i, rule = (lambda m, t : m.p_mw_WT[t] <= m.ap_mw_WT*net.sgen['ap_mw'][1](Escenarios_i[t])))
m.WT_build = pe.Constraint( expr = m.ap_mw_WT <= m.sgen_WT*M)
opt = pe.SolverFactory('glpk')

result_obj= opt.solve(m, tee=True)
m.pprint()<jupyter_output>6 Set Declarations
    PV_dim_index : Size=1, Index=None, Ordered=False
        Key  : Dimen : Domain : Size : Members
        None :     1 :    Any :   24 : {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}
    WT_dim_index : Size=1, Index=None, Ordered=False
        Key  : Dimen : Domain : Size : Members
        None :     1 :    Any :   24 : {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}
    hourly_power_balance_index : Size=1, Index=None, Ordered=False
        Key  : Dimen : Domain : Size : Members
        None :     1 :    Any :   24 : {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}
    p_mw_Ext_index : Size=1, Index=None, Ordered=False
        Key  : Dimen : Domain : Size : Members
        None :     1 :    Any :   24 : {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23}
    p_mw_PV_index : Size=1, Index=None, Ordered=False
       [...]
{'fraction_non_alphanumeric': 0.15251699113005415, 'fraction_numerical': 0.0603617094804746, 'mean_word_length': 2.9862258953168044, 'pattern_counts': {'":': 0, '<': 46, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '357951', 'license': 'MIT', 'n_tokens_mistral': 4058, 'n_tokens_neox': 3674, 'n_words': 930, 'path': 'Notebooks/Prueba PP-Pyomo-2.ipynb', 'repo_name': 'ExoticAnt/MMGO', 'size': '8681'}