Source code for monee.problem.load_shedding

import math

from monee.model.branch import (
    GenericPowerBranch,
    HeatExchanger,
    HeatExchangerGenerator,
    HeatExchangerLoad,
    PowerLine,
)
from monee.model.child import (
    ExtHydrGrid,
    ExtPowerGrid,
    PowerGenerator,
    PowerLoad,
    Sink,
    Source,
)
from monee.model.core import Var
from monee.model.grid import GasGrid, WaterGrid
from monee.model.multi import CHPControlNode, PowerToGas, PowerToHeat
from monee.model.node import Bus, Junction
from monee.problem.core import (
    AttributeParameter,
    Constraints,
    Objectives,
    OptimizationProblem,
)

CONTROLLABLE_ATTRIBUTES = [
    (
        "regulation",
        AttributeParameter(
            min=lambda attr, val: 0, max=lambda attr, val: 1, val=lambda attr, val: 1
        ),
    )
]
CONTROLLABLE_ATTRIBUTES_CP = [
    (
        "regulation",
        AttributeParameter(
            min=lambda attr, val: 0, max=lambda attr, val: 1, val=lambda attr, val: 1
        ),
    )
]


def _or_zero(var):
    """
    No docstring provided.
    """
    if type(var) is Var and math.isnan(var.value):
        return 0
    if (
        hasattr(var, "value")
        and hasattr(var.value, "value")
        and math.isnan(var.value.value)
    ):
        return 0
    return var


HHV = 15.3


def retrieve_power_uniform(model):
    """
    No docstring provided.
    """

    if isinstance(model, HeatExchangerLoad | HeatExchangerGenerator | HeatExchanger):
        return (model.q_w_set / 1000000.0 * model.regulation, model.q_w_set / 1000000.0)
    elif isinstance(model, PowerLoad | PowerGenerator):
        return (_or_zero(model.p_mw) * model.regulation, model.p_mw)
    elif isinstance(model, ExtPowerGrid):
        return model.p_mw, 0
    elif isinstance(model, ExtHydrGrid):
        return model.mass_flow * 3.6 * HHV, 0
    elif isinstance(model, Sink | Source):
        return (
            _or_zero(model.mass_flow) * 3.6 * HHV * model.regulation,
            model.mass_flow * 3.6 * HHV,
        )
    elif isinstance(model, CHPControlNode):
        return (0, 0)
    elif isinstance(model, PowerToHeat):
        return (0, 0)
    elif isinstance(model, PowerToGas):
        return (0, 0)
    elif isinstance(model, PowerLine):
        if model.backup:
            return (0, model.on_off * 0.1)
        return (0, 0)
    raise ValueError(f"The model {type(model)} is not a known load.")


def calculate_objective(model_to_data):
    """
    No docstring provided.
    """
    power_coeff = [
        (
            model,
            (retrieve_power_uniform(model)[1] - retrieve_power_uniform(model)[0])
            * data,
        )
        for model, data in model_to_data.items()
    ]
    return sum([t[1] for t in power_coeff])


[docs] def create_load_shedding_optimization_problem( load_weight=10, bounds_el=(0.9, 1.1), bounds_heat=(0.9, 1.1), bounds_gas=(0.9, 1.1), bounds_lp=(0, 1.5), ext_grid_el_bounds=(-0.25, 0.25), ext_grid_gas_bounds=(-1.5, 1.5), use_ext_grid_bounds=True, use_ext_grid_objective=True, check_lp=True, check_vm=True, check_pressure=True, check_t=True, debug=False, ): """ No docstring provided. """ problem = OptimizationProblem(debug=debug) problem.controllable_demands(CONTROLLABLE_ATTRIBUTES) problem.controllable_generators(CONTROLLABLE_ATTRIBUTES) problem.controllable_cps(CONTROLLABLE_ATTRIBUTES_CP) if use_ext_grid_objective: problem.controllable_ext() problem.controllable( component_condition=lambda component: "backup" in component.model.vars and component.model.backup, attributes=[ ( "on_off", AttributeParameter( min=lambda attr, val: 0, max=lambda attr, val: 1, val=lambda attr, val: 1, integer=True, ), ) ], ) if check_vm: problem.bounds(bounds_el, lambda m, _: type(m) is Bus, ["vm_pu"]) if check_t: problem.bounds( bounds_heat, lambda m, g: type(m) is Junction and type(g) is WaterGrid, ["t_pu"], ) if check_pressure: problem.bounds(bounds_gas, lambda m, _: type(m) is Junction, ["pressure_pu"]) objectives = Objectives() def calc_weight(model): weight = 1 if isinstance(model, HeatExchangerLoad | Sink | PowerLoad): weight = load_weight elif isinstance(model, CHPControlNode | PowerToGas | PowerToHeat): weight = load_weight - 1 elif isinstance(model, ExtPowerGrid | ExtHydrGrid): weight = 5 return weight objectives.with_models(problem.controllables_link).data(calc_weight).calculate( calculate_objective ) constraints = Constraints() if use_ext_grid_bounds: constraints.select_types(ExtPowerGrid).equation( lambda model: model.p_mw >= ext_grid_el_bounds[0] ).equation(lambda model: model.p_mw <= ext_grid_el_bounds[1]) constraints.select( lambda comp: type(comp.grid) is GasGrid and type(comp.model) is ExtHydrGrid ).equation(lambda model: model.mass_flow >= ext_grid_gas_bounds[0]).equation( lambda model: model.mass_flow <= ext_grid_gas_bounds[1] ) if check_lp: constraints.select_types(GenericPowerBranch).equation( lambda model: model.loading_from_percent <= bounds_lp[1] ).equation(lambda model: model.loading_to_percent <= bounds_lp[1]) problem.constraints = constraints problem.objectives = objectives return problem