switch_model/balancing/planning_reserves.py
def define_components(model):
    """
    PLANNING_RESERVE_REQUIREMENTS is the set of planning reserve requirements.
    Each planning reserve requirement specifies a certain capacity reserve
    margin be enforced over a certain geographic area in either peak load
    conditions or in every timepoint. Where specified, planning reserve
    requirements are enforced in every investment period. The planning reserve
    area is specified as set of load zones. Typical use cases include
    specifying one planning reserve requirement per load zone, one aggregate
    requirement for the entire system, or a combination of a system-wide
    requirement and requirements for transmission-constrained "load pockets".
    This set is abbreviated as PRR / prr.

    prr_reserve_margin[prr] is the capacity reserve margin for each PRR which
    defaults to 0.15

    prr_enforcement_timescale[prr] Determines whether planning reserve
    requirements are enforced in each timepoint, or just timepoints with peak
    load (zone_demand_mw). Allowed values are 'all_timepoints' and 'peak_load'.

    PRR_ZONES is a set of (prr, zone) that describes which zones contribute to a
    given planning reserve requirement. Zones may belong to more than one PRR.

    PRR_TIMEPOINTS is a sparse set of (prr, t)

    gen_capacity_value[g, t] is a ratio of how much of a generator's installed
    capacity should be credited towards capacity reserve requirements. This
    defaults to gen_max_capacity_factor for renewable projects with variable
    output and 1.0 for other plants.

    AvailableReserveCapacity[prr,t] summarizes the available generation
    capacity across each planning reserve area, taking into account
    capacity_value. If storage projects are being modeled, they are credited
    with their scheduled net deliveries (dispatch - charging). This is added
    to the CAPACITY_FOR_RESERVES list.

    If TXPowerNet is defined in the model, it will be added to the
    CAPACITY_FOR_RESERVES list.

    CapacityRequirements[z,t] is an expression that defines capacity reserve
    requirements. This is set to (1+prr_reserve_margin) * load
    If the local_td module has been included, load will be set to
    WithdrawFromCentralGrid, which accounts for Distributed Energy Resources
    reducing (or increasing) net load to the central grid.
    If the local_td module is not include, load is set to zone_demand_mw and
    will not reflect any DER activities.
    """
    model.PLANNING_RESERVE_REQUIREMENTS = Set(
        doc="Areas and times where planning reserve margins are specified.",
        input_file='planning_reserve_requirements.csv',
        dimen=1
    )
    model.PRR_ZONES = Set(
        dimen=2,
        input_file='planning_reserve_requirement_zones.csv',
        doc=("A set of (prr, z) that describes which zones contribute to each "
             "Planning Reserve Requirement.")
    )
    model.prr_cap_reserve_margin = Param(
        model.PLANNING_RESERVE_REQUIREMENTS,
        within=PercentFraction,
        input_file='planning_reserve_requirements.csv',
        default=0.15
    )
    model.prr_enforcement_timescale = Param(
        model.PLANNING_RESERVE_REQUIREMENTS,
        default='period_peak_load',
        validate=lambda m, value, prr:
            value in ('all_timepoints', 'peak_load'),
        input_file='planning_reserve_requirements.csv',
        doc=("Determines whether planning reserve requirements are enforced in "
             "each timepoint, or just timepoints with peak load (zone_demand_mw)."),
        within=Any
    )
    def get_peak_timepoints(m, prr):
        """
        Return the set of timepoints with peak load within a planning reserve
        requirement area for each period. For this calculation, load is defined
        statically (zone_demand_mw), ignoring the impact of all distributed
        energy resources.
        """
        peak_timepoint_list = set()
        ZONES = [z for (_prr, z) in m.PRR_ZONES if _prr == prr]
        for p in m.PERIODS:
            peak_load = 0.0
            for t in m.TPS_IN_PERIOD[p]:
                load = sum(m.zone_demand_mw[z, t] for z in ZONES)
                if load > peak_load:
                    peak_timepoint = t
                    peak_load = load
            peak_timepoint_list.add(peak_timepoint)
        return peak_timepoint_list
    def PRR_TIMEPOINTS_init(m):
        PRR_TIMEPOINTS = []
        for prr in m.PLANNING_RESERVE_REQUIREMENTS:
            if m.prr_enforcement_timescale[prr] == 'all_timepoints':
                PRR_TIMEPOINTS.extend([(prr, t) for t in m.TIMEPOINTS])
            elif m.prr_enforcement_timescale[prr] == 'peak_load':
                PRR_TIMEPOINTS.extend([(prr, t) for t in get_peak_timepoints(m, prr)])
            else:
                raise ValueError("prr_enforcement_timescale not recognized: '{}'".format(
                    m.prr_enforcement_timescale[prr]))
        return PRR_TIMEPOINTS
    model.PRR_TIMEPOINTS = Set(
        dimen=2,
        within=model.PLANNING_RESERVE_REQUIREMENTS * model.TIMEPOINTS,
        initialize=PRR_TIMEPOINTS_init,
        doc=("The sparse set of (prr, t) for which planning reserve "
             "requirements are enforced.")
    )

    model.gen_can_provide_cap_reserves = Param(
        model.GENERATION_PROJECTS,
        within=Boolean,
        default=True,
        input_file='generation_projects_info.csv',
        doc="Indicates whether a generator can provide capacity reserves."
    )
    def gen_capacity_value_default(m, g, t):
        if not m.gen_can_provide_cap_reserves[g]:
            return 0.0
        elif g in m.VARIABLE_GENS:
            return m.gen_max_capacity_factor[g, t]
        else:
            return 1.0
    model.gen_capacity_value = Param(
        # Note we pass in the product of both sets rather than GEN_TPS
        # since GEN_TPS only includes timepoints in periods where the generation
        # is online (e.g. not retired). Passing in only capacity values
        # where the generation is online would complicate our get_inputs.py so instead we
        # accept all parameters and are ok if they are not all used.
        model.GENERATION_PROJECTS * model.TIMEPOINTS,
        # Previously domain was PercentFraction however we want to allow renewable factors greater than 1
        # or less than 0.
        within=Reals,
        input_file="reserve_capacity_value.csv",
        default=gen_capacity_value_default,
        validate=lambda m, value, g, t: (
            value == 0.0
            if not m.gen_can_provide_cap_reserves[g]
            else True)
    )

    def zones_for_prr(m, prr):
        return [z for (_prr, z) in m.PRR_ZONES if _prr == prr]

    def AvailableReserveCapacity_rule(m, prr, t):
        reserve_cap = 0.0
        ZONES = zones_for_prr(m, prr)
        GENS = [
            g
            for z in ZONES
            for g in m.GENS_IN_ZONE[z]
            if (g, t) in m.GEN_TPS and m.gen_can_provide_cap_reserves[g]
        ]
        for g in GENS:
            # Storage is only credited with its expected output
            # Note: this code appears to have no users, since it references
            # DispatchGen, which doesn't exist (should be m.DispatchGen).
            if g in getattr(m, 'STORAGE_GENS', set()):
                reserve_cap += m.DispatchGen[g, t] - m.ChargeStorage[g, t]
            # If local_td is included with DER modeling, avoid allocating
            # distributed generation to central grid capacity because it will
            # be credited with adjusting load at the distribution node.
            elif hasattr(m, 'Distributed_Power_Injections') and m.gen_is_distributed[g]:
                pass
            else:
                reserve_cap += m.gen_capacity_value[g, t] * m.GenCapacityInTP[g, t]
        return reserve_cap
    model.AvailableReserveCapacity = Expression(
        model.PRR_TIMEPOINTS, rule=AvailableReserveCapacity_rule
    )
    model.CAPACITY_FOR_RESERVES.append('AvailableReserveCapacity')

    if 'TXPowerNet' in model:
        model.CAPACITY_FOR_RESERVES.append('TXPowerNet')

    def CapacityRequirements_rule(m, prr, t):
        ZONES = zones_for_prr(m, prr)
        if hasattr(m, 'WithdrawFromCentralGrid'):
            return sum(
                (1 + m.prr_cap_reserve_margin[prr]) * m.WithdrawFromCentralGrid[z,t]
                for z in ZONES
            )
        else:
            return sum(
                (1 + m.prr_cap_reserve_margin[prr]) * m.zone_demand_mw[z,t]
                for z in ZONES
            )
    model.CapacityRequirements = Expression(
        model.PRR_TIMEPOINTS,
        rule=CapacityRequirements_rule
    )
    model.REQUIREMENTS_FOR_CAPACITY_RESERVES.append('CapacityRequirements')

    PLANNING_RESERVE_REQUIREMENTS is the set of planning reserve requirements.
    Each planning reserve requirement specifies a certain capacity reserve
    margin be enforced over a certain geographic area in either peak load
    conditions or in every timepoint. Where specified, planning reserve
    requirements are enforced in every investment period. The planning reserve
    area is specified as set of load zones. Typical use cases include
    specifying one planning reserve requirement per load zone, one aggregate
    requirement for the entire system, or a combination of a system-wide
    requirement and requirements for transmission-constrained "load pockets".
    This set is abbreviated as PRR / prr.

    prr_reserve_margin[prr] is the capacity reserve margin for each PRR which
    defaults to 0.15

    prr_enforcement_timescale[prr] Determines whether planning reserve
    requirements are enforced in each timepoint, or just timepoints with peak
    load (zone_demand_mw). Allowed values are 'all_timepoints' and 'peak_load'.

    PRR_ZONES is a set of (prr, zone) that describes which zones contribute to a
    given planning reserve requirement. Zones may belong to more than one PRR.

    PRR_TIMEPOINTS is a sparse set of (prr, t)

    gen_capacity_value[g, t] is a ratio of how much of a generator's installed
    capacity should be credited towards capacity reserve requirements. This
    defaults to gen_max_capacity_factor for renewable projects with variable
    output and 1.0 for other plants.

    AvailableReserveCapacity[prr,t] summarizes the available generation
    capacity across each planning reserve area, taking into account
    capacity_value. If storage projects are being modeled, they are credited
    with their scheduled net deliveries (dispatch - charging). This is added
    to the CAPACITY_FOR_RESERVES list.

    If TXPowerNet is defined in the model, it will be added to the
    CAPACITY_FOR_RESERVES list.

    CapacityRequirements[z,t] is an expression that defines capacity reserve
    requirements. This is set to (1+prr_reserve_margin) * load
    If the local_td module has been included, load will be set to
    WithdrawFromCentralGrid, which accounts for Distributed Energy Resources
    reducing (or increasing) net load to the central grid.
    If the local_td module is not include, load is set to zone_demand_mw and
    will not reflect any DER activities.
    
PLANNING_RESERVE_REQUIREMENTS is the set of planning reserve requirements.
Each planning reserve requirement specifies a certain capacity reserve
margin be enforced over a certain geographic area in either peak load
conditions or in every timepoint. Where specified, planning reserve
requirements are enforced in every investment period. The planning reserve
area is specified as set of load zones. Typical use cases include
specifying one planning reserve requirement per load zone, one aggregate
requirement for the entire system, or a combination of a system-wide
requirement and requirements for transmission-constrained "load pockets".
This set is abbreviated as PRR / prr.

prr_reserve_margin[prr] is the capacity reserve margin for each PRR which
defaults to 0.15

prr_enforcement_timescale[prr] Determines whether planning reserve
requirements are enforced in each timepoint, or just timepoints with peak
load (zone_demand_mw).

PRR_ZONES is a set of (prr, zone) that describes which zones contribute to a
given planning reserve requirement. Zones may belong to more than one PRR.

PRR_TIMEPOINTS is a sparse set of (prr, t)

gen_capacity_value[g, t] is a ratio of how much of a generator's installed
capacity should be credited towards capacity reserve requirements. This
defaults to gen_max_capacity_factor for renewable projects with variable
output and 1.0 for other plants.

AvailableReserveCapacity[prr,t] summarizes the available generation
capacity across each planning reserve area, taking into account
capacity_value. If storage projects are being modeled, they are credited
with their scheduled net deliveries (dispatch - charging). This is added
to the CAPACITY_FOR_RESERVES list.

If TXPowerNet is defined in the model, it will be added to the
CAPACITY_FOR_RESERVES list.

CapacityRequirements[z,t] is an expression that defines capacity reserve
requirements. This is set to (1+prr_reserve_margin) * load
If the local_td module has been included, load will be set to
WithdrawFromCentralGrid, which accounts for Distributed Energy Resources
reducing (or increasing) net load to the central grid.
If the local_td module is not include, load is set to zone_demand_mw and
will not reflect any DER activities.
PLANNING_RESERVE_REQUIREMENTS is the set of planning reserve requirements . Each planning reserve requirement specifies a certain capacity reserve margin be enforced over a certain geographic area in either peak load conditions or in every timepoint . Where specified planning reserve requirements are enforced in every investment period . The planning reserve area is specified as set of load zones . Typical use cases include specifying one planning reserve requirement per load zone one aggregate requirement for the entire system or a combination of a system - wide requirement and requirements for transmission - constrained " load pockets " . This set is abbreviated as PRR / prr . prr_reserve_margin [ prr ] is the capacity reserve margin for each PRR which defaults to 0 . 15 prr_enforcement_timescale [ prr ] Determines whether planning reserve requirements are enforced in each timepoint or just timepoints with peak load ( zone_demand_mw ) . PRR_ZONES is a set of ( prr zone ) that describes which zones contribute to a given planning reserve requirement . Zones may belong to more than one PRR . PRR_TIMEPOINTS is a sparse set of ( prr t ) gen_capacity_value [ g t ] is a ratio of how much of a generator ' s installed capacity should be credited towards capacity reserve requirements . This defaults to gen_max_capacity_factor for renewable projects with variable output and 1 . 0 for other plants . AvailableReserveCapacity [ prr t ] summarizes the available generation capacity across each planning reserve area taking into account capacity_value . If storage projects are being modeled they are credited with their scheduled net deliveries ( dispatch - charging ) . This is added to the CAPACITY_FOR_RESERVES list . If TXPowerNet is defined in the model it will be added to the CAPACITY_FOR_RESERVES list . CapacityRequirements [ z t ] is an expression that defines capacity reserve requirements . This is set to ( 1 + prr_reserve_margin ) * load If the local_td module has been included load will be set to WithdrawFromCentralGrid which accounts for Distributed Energy Resources reducing ( or increasing ) net load to the central grid . If the local_td module is not include load is set to zone_demand_mw and will not reflect any DER activities .
def define_components(model):
    model.PLANNING_RESERVE_REQUIREMENTS = Set(
        doc="Areas and times where planning reserve margins are specified.",
        input_file='planning_reserve_requirements.csv',
        dimen=1
    )
    model.PRR_ZONES = Set(
        dimen=2,
        input_file='planning_reserve_requirement_zones.csv',
        doc=("A set of (prr, z) that describes which zones contribute to each "
             "Planning Reserve Requirement.")
    )
    model.prr_cap_reserve_margin = Param(
        model.PLANNING_RESERVE_REQUIREMENTS,
        within=PercentFraction,
        input_file='planning_reserve_requirements.csv',
        default=0.15
    )
    model.prr_enforcement_timescale = Param(
        model.PLANNING_RESERVE_REQUIREMENTS,
        default='period_peak_load',
        validate=lambda m, value, prr:
            value in ('all_timepoints', 'peak_load'),
        input_file='planning_reserve_requirements.csv',
        doc=("Determines whether planning reserve requirements are enforced in "
             "each timepoint, or just timepoints with peak load (zone_demand_mw)."),
        within=Any
    )
    def get_peak_timepoints(m, prr):
        peak_timepoint_list = set()
        ZONES = [z for (_prr, z) in m.PRR_ZONES if _prr == prr]
        for p in m.PERIODS:
            peak_load = 0.0
            for t in m.TPS_IN_PERIOD[p]:
                load = sum(m.zone_demand_mw[z, t] for z in ZONES)
                if load > peak_load:
                    peak_timepoint = t
                    peak_load = load
            peak_timepoint_list.add(peak_timepoint)
        return peak_timepoint_list
    def PRR_TIMEPOINTS_init(m):
        PRR_TIMEPOINTS = []
        for prr in m.PLANNING_RESERVE_REQUIREMENTS:
            if m.prr_enforcement_timescale[prr] == 'all_timepoints':
                PRR_TIMEPOINTS.extend([(prr, t) for t in m.TIMEPOINTS])
            elif m.prr_enforcement_timescale[prr] == 'peak_load':
                PRR_TIMEPOINTS.extend([(prr, t) for t in get_peak_timepoints(m, prr)])
            else:
                raise ValueError("prr_enforcement_timescale not recognized: '{}'".format(
                    m.prr_enforcement_timescale[prr]))
        return PRR_TIMEPOINTS
    model.PRR_TIMEPOINTS = Set(
        dimen=2,
        within=model.PLANNING_RESERVE_REQUIREMENTS * model.TIMEPOINTS,
        initialize=PRR_TIMEPOINTS_init,
        doc=("The sparse set of (prr, t) for which planning reserve "
             "requirements are enforced.")
    )
    model.gen_can_provide_cap_reserves = Param(
        model.GENERATION_PROJECTS,
        within=Boolean,
        default=True,
        input_file='generation_projects_info.csv',
        doc="Indicates whether a generator can provide capacity reserves."
    )
    def gen_capacity_value_default(m, g, t):
        if not m.gen_can_provide_cap_reserves[g]:
            return 0.0
        elif g in m.VARIABLE_GENS:
            return m.gen_max_capacity_factor[g, t]
        else:
            return 1.0
    model.gen_capacity_value = Param(
        model.GENERATION_PROJECTS * model.TIMEPOINTS,
        within=Reals,
        input_file="reserve_capacity_value.csv",
        default=gen_capacity_value_default,
        validate=lambda m, value, g, t: (
            value == 0.0
            if not m.gen_can_provide_cap_reserves[g]
            else True)
    )
    def zones_for_prr(m, prr):
        return [z for (_prr, z) in m.PRR_ZONES if _prr == prr]
    def AvailableReserveCapacity_rule(m, prr, t):
        reserve_cap = 0.0
        ZONES = zones_for_prr(m, prr)
        GENS = [
            g
            for z in ZONES
            for g in m.GENS_IN_ZONE[z]
            if (g, t) in m.GEN_TPS and m.gen_can_provide_cap_reserves[g]
        ]
        for g in GENS:
            if g in getattr(m, 'STORAGE_GENS', set()):
                reserve_cap += m.DispatchGen[g, t] - m.ChargeStorage[g, t]
            elif hasattr(m, 'Distributed_Power_Injections') and m.gen_is_distributed[g]:
                pass
            else:
                reserve_cap += m.gen_capacity_value[g, t] * m.GenCapacityInTP[g, t]
        return reserve_cap
    model.AvailableReserveCapacity = Expression(
        model.PRR_TIMEPOINTS, rule=AvailableReserveCapacity_rule
    )
    model.CAPACITY_FOR_RESERVES.append('AvailableReserveCapacity')
    if 'TXPowerNet' in model:
        model.CAPACITY_FOR_RESERVES.append('TXPowerNet')
    def CapacityRequirements_rule(m, prr, t):
        ZONES = zones_for_prr(m, prr)
        if hasattr(m, 'WithdrawFromCentralGrid'):
            return sum(
                (1 + m.prr_cap_reserve_margin[prr]) * m.WithdrawFromCentralGrid[z,t]
                for z in ZONES
            )
        else:
            return sum(
                (1 + m.prr_cap_reserve_margin[prr]) * m.zone_demand_mw[z,t]
                for z in ZONES
            )
    model.CapacityRequirements = Expression(
        model.PRR_TIMEPOINTS,
        rule=CapacityRequirements_rule
    )
    model.REQUIREMENTS_FOR_CAPACITY_RESERVES.append('CapacityRequirements')
def define_components ( model ) : model . PLANNING_RESERVE_REQUIREMENTS = Set ( doc = "Areas and times where planning reserve margins are specified." , input_file = 'planning_reserve_requirements.csv' , dimen = 1 ) model . PRR_ZONES = Set ( dimen = 2 , input_file = 'planning_reserve_requirement_zones.csv' , doc = ( "A set of (prr, z) that describes which zones contribute to each " "Planning Reserve Requirement." ) ) model . prr_cap_reserve_margin = Param ( model . PLANNING_RESERVE_REQUIREMENTS , within = PercentFraction , input_file = 'planning_reserve_requirements.csv' , default = 0.15 ) model . prr_enforcement_timescale = Param ( model . PLANNING_RESERVE_REQUIREMENTS , default = 'period_peak_load' , validate = lambda m , value , prr : value in ( 'all_timepoints' , 'peak_load' ) , input_file = 'planning_reserve_requirements.csv' , doc = ( "Determines whether planning reserve requirements are enforced in " "each timepoint, or just timepoints with peak load (zone_demand_mw)." ) , within = Any ) def get_peak_timepoints ( m , prr ) : """
        Return the set of timepoints with peak load within a planning reserve
        requirement area for each period. For this calculation, load is defined
        statically (zone_demand_mw), ignoring the impact of all distributed
        energy resources.
        """ peak_timepoint_list = set ( ) ZONES = [ z for ( _prr , z ) in m . PRR_ZONES if _prr == prr ] for p in m . PERIODS : peak_load = 0.0 for t in m . TPS_IN_PERIOD [ p ] : load = sum ( m . zone_demand_mw [ z , t ] for z in ZONES ) if load > peak_load : peak_timepoint = t peak_load = load peak_timepoint_list . add ( peak_timepoint ) return peak_timepoint_list def PRR_TIMEPOINTS_init ( m ) : PRR_TIMEPOINTS = [ ] for prr in m . PLANNING_RESERVE_REQUIREMENTS : if m . prr_enforcement_timescale [ prr ] == 'all_timepoints' : PRR_TIMEPOINTS . extend ( [ ( prr , t ) for t in m . TIMEPOINTS ] ) elif m . prr_enforcement_timescale [ prr ] == 'peak_load' : PRR_TIMEPOINTS . extend ( [ ( prr , t ) for t in get_peak_timepoints ( m , prr ) ] ) else : raise ValueError ( "prr_enforcement_timescale not recognized: '{}'" . format ( m . prr_enforcement_timescale [ prr ] ) ) return PRR_TIMEPOINTS model . PRR_TIMEPOINTS = Set ( dimen = 2 , within = model . PLANNING_RESERVE_REQUIREMENTS * model . TIMEPOINTS , initialize = PRR_TIMEPOINTS_init , doc = ( "The sparse set of (prr, t) for which planning reserve " "requirements are enforced." ) ) model . gen_can_provide_cap_reserves = Param ( model . GENERATION_PROJECTS , within = Boolean , default = True , input_file = 'generation_projects_info.csv' , doc = "Indicates whether a generator can provide capacity reserves." ) def gen_capacity_value_default ( m , g , t ) : if not m . gen_can_provide_cap_reserves [ g ] : return 0.0 elif g in m . VARIABLE_GENS : return m . gen_max_capacity_factor [ g , t ] else : return 1.0 model . gen_capacity_value = Param ( model . GENERATION_PROJECTS * model . TIMEPOINTS , within = Reals , input_file = "reserve_capacity_value.csv" , default = gen_capacity_value_default , validate = lambda m , value , g , t : ( value == 0.0 if not m . gen_can_provide_cap_reserves [ g ] else True ) ) def zones_for_prr ( m , prr ) : return [ z for ( _prr , z ) in m . PRR_ZONES if _prr == prr ] def AvailableReserveCapacity_rule ( m , prr , t ) : reserve_cap = 0.0 ZONES = zones_for_prr ( m , prr ) GENS = [ g for z in ZONES for g in m . GENS_IN_ZONE [ z ] if ( g , t ) in m . GEN_TPS and m . gen_can_provide_cap_reserves [ g ] ] for g in GENS : if g in getattr ( m , 'STORAGE_GENS' , set ( ) ) : reserve_cap += m . DispatchGen [ g , t ] - m . ChargeStorage [ g , t ] elif hasattr ( m , 'Distributed_Power_Injections' ) and m . gen_is_distributed [ g ] : pass else : reserve_cap += m . gen_capacity_value [ g , t ] * m . GenCapacityInTP [ g , t ] return reserve_cap model . AvailableReserveCapacity = Expression ( model . PRR_TIMEPOINTS , rule = AvailableReserveCapacity_rule ) model . CAPACITY_FOR_RESERVES . append ( 'AvailableReserveCapacity' ) if 'TXPowerNet' in model : model . CAPACITY_FOR_RESERVES . append ( 'TXPowerNet' ) def CapacityRequirements_rule ( m , prr , t ) : ZONES = zones_for_prr ( m , prr ) if hasattr ( m , 'WithdrawFromCentralGrid' ) : return sum ( ( 1 + m . prr_cap_reserve_margin [ prr ] ) * m . WithdrawFromCentralGrid [ z , t ] for z in ZONES ) else : return sum ( ( 1 + m . prr_cap_reserve_margin [ prr ] ) * m . zone_demand_mw [ z , t ] for z in ZONES ) model . CapacityRequirements = Expression ( model . PRR_TIMEPOINTS , rule = CapacityRequirements_rule ) model . REQUIREMENTS_FOR_CAPACITY_RESERVES . append ( 'CapacityRequirements' )
PLANNING_RESERVE_REQUIREMENTS is the set of planning reserve requirements.
PLANNING_RESERVE_REQUIREMENTS is the set of planning reserve requirements .
"""
    PLANNING_RESERVE_REQUIREMENTS is the set of planning reserve requirements.
    Each planning reserve requirement specifies a certain capacity reserve
    margin be enforced over a certain geographic area in either peak load
    conditions or in every timepoint. Where specified, planning reserve
    requirements are enforced in every investment period. The planning reserve
    area is specified as set of load zones. Typical use cases include
    specifying one planning reserve requirement per load zone, one aggregate
    requirement for the entire system, or a combination of a system-wide
    requirement and requirements for transmission-constrained "load pockets".
    This set is abbreviated as PRR / prr.

    prr_reserve_margin[prr] is the capacity reserve margin for each PRR which
    defaults to 0.15

    prr_enforcement_timescale[prr] Determines whether planning reserve
    requirements are enforced in each timepoint, or just timepoints with peak
    load (zone_demand_mw). Allowed values are 'all_timepoints' and 'peak_load'.

    PRR_ZONES is a set of (prr, zone) that describes which zones contribute to a
    given planning reserve requirement. Zones may belong to more than one PRR.

    PRR_TIMEPOINTS is a sparse set of (prr, t)

    gen_capacity_value[g, t] is a ratio of how much of a generator's installed
    capacity should be credited towards capacity reserve requirements. This
    defaults to gen_max_capacity_factor for renewable projects with variable
    output and 1.0 for other plants.

    AvailableReserveCapacity[prr,t] summarizes the available generation
    capacity across each planning reserve area, taking into account
    capacity_value. If storage projects are being modeled, they are credited
    with their scheduled net deliveries (dispatch - charging). This is added
    to the CAPACITY_FOR_RESERVES list.

    If TXPowerNet is defined in the model, it will be added to the
    CAPACITY_FOR_RESERVES list.

    CapacityRequirements[z,t] is an expression that defines capacity reserve
    requirements. This is set to (1+prr_reserve_margin) * load
    If the local_td module has been included, load will be set to
    WithdrawFromCentralGrid, which accounts for Distributed Energy Resources
    reducing (or increasing) net load to the central grid.
    If the local_td module is not include, load is set to zone_demand_mw and
    will not reflect any DER activities.
    """ """
        Return the set of timepoints with peak load within a planning reserve
        requirement area for each period. For this calculation, load is defined
        statically (zone_demand_mw), ignoring the impact of all distributed
        energy resources.
        """ # Note we pass in the product of both sets rather than GEN_TPS # since GEN_TPS only includes timepoints in periods where the generation # is online (e.g. not retired). Passing in only capacity values # where the generation is online would complicate our get_inputs.py so instead we # accept all parameters and are ok if they are not all used. # Previously domain was PercentFraction however we want to allow renewable factors greater than 1 # or less than 0. # Storage is only credited with its expected output # Note: this code appears to have no users, since it references # DispatchGen, which doesn't exist (should be m.DispatchGen). # If local_td is included with DER modeling, avoid allocating # distributed generation to central grid capacity because it will # be credited with adjusting load at the distribution node.
model