def _ensure_contingencies_monitored(options:Options, md:EgretModel, initial_ruc:bool = False) -> None:
    ''' Add contingency screening, if that option is enabled '''
    if initial_ruc:
        _ensure_contingencies_monitored.contingency_dicts = {}

    for bn, b in md.elements('branch'): 
        if not b.get('in_service', True):
            raise RuntimeError(f"Remove branches from service by setting the `planned_outage` attribute. "
                    f"Branch {bn} has `in_service`:False")
    for bn, b in md.elements('bus'): 
        if not b.get('in_service', True):
            raise RuntimeError(f"Buses cannot be removed from service in Prescient")

    if options.monitor_all_contingencies:
        key = []
        for bn, b in md.elements('branch'):
            if 'planned_outage' in b:
                if isinstance(b['planned_outage'], dict):
                    if any(b['planned_outage']['values']):
                        key.append(b)
                elif b['planned_outage']:
                    key.append(b)
        key = tuple(key)
        if key not in _ensure_contingencies_monitored.contingency_dicts:
            mapping_bus_to_idx = { k : i for i,k in enumerate(md.data['elements']['bus'].keys())}
            graph = construct_connection_graph(md.data['elements']['branch'], mapping_bus_to_idx)
            contingency_list = get_N_minus_1_branches(graph, md.data['elements']['branch'], mapping_bus_to_idx)
            contingency_dict = { cn : {'branch_contingency':cn} for cn in contingency_list} 
            _ensure_contingencies_monitored.contingency_dicts[key] = contingency_dict

        md.data['elements']['contingency'] = _ensure_contingencies_monitored.contingency_dicts[key]
示例#2
0
    def populate_initial_state_data(self, options: Options, day: date,
                                    model: EgretModel) -> None:
        ''' Populate an existing model with initial state data for the requested day

        Sets T0 information from actuals:
          * initial_state_of_charge for each storage element
          * initial_status for each generator
          * initial_p_output for each generator

        Arguments
        ---------
        options:
            Option values
        day:date
            The day whose initial state will be saved in the model
        model: EgretModel
            The model whose values will be modifed
        '''
        if day < self._first_day:
            day = self._first_day
        elif day > self._final_day:
            day = self._final_day

        actuals = self._get_actuals_by_date(day)

        for s, sdict in model.elements('storage'):
            soc = actuals.data['elements']['storage'][s][
                'initial_state_of_charge']
            sdict['initial_state_of_charge'] = soc

        for g, gdict in model.elements('generator', generator_type='thermal'):
            source = actuals.data['elements']['generator'][g]
            gdict['initial_status'] = source['initial_status']
            gdict['initial_p_output'] = source['initial_p_output']
def test_elements():
    md = ModelData(dict(testdata))

    for n, e in md.elements(element_type="generator"):
        assert n == 'G1' or n == 'G2'
        if n == 'G1':
            assert e["generator_type"] == 'thermal'
        if n == 'G2':
            assert e["generator_type"] == 'solar'

    buses = dict(md.elements(element_type='bus'))
    assert len(buses) == 4
    assert 'B1' in buses
    assert 'B2' in buses
    assert 'B3' in buses
    assert 'B4' in buses
    assert buses['B1']['bus_type'] == 'PV'

    buses = dict(md.elements(element_type='bus', bus_type='PQ'))
    assert len(buses) == 2
    assert 'B2' in buses
    assert 'B3' in buses

    buses = dict(md.elements(element_type='bus', bus_type=('PV', 'ref')))
    assert len(buses) == 2
    assert 'B1' in buses
    assert 'B4' in buses
def _copy_initial_state_into_model(options:Options, 
                                   current_state:SimulationState, 
                                   md:EgretModel):
    for g, g_dict in md.elements('generator', generator_type='thermal'):
        g_dict['initial_status'] = current_state.get_initial_generator_state(g)
        g_dict['initial_p_output']  = current_state.get_initial_power_generated(g)
    for s,s_dict in md.elements('storage'):
        s_dict['initial_state_of_charge'] = current_state.get_initial_state_of_charge(s)
    def _populate_with_forecastable_data(self, options:Options,
                                         start_time:datetime,
                                         num_time_periods: int,
                                         time_period_length_minutes: int,
                                         model: EgretModel,
                                         identify_dat: Callable[[date], EgretModel]
                                        ) -> None:
        # For now, require the time period to always be 60 minutes
        assert(time_period_length_minutes == 60.0)
        step_delta = timedelta(minutes=time_period_length_minutes)

        # See if we have space to store all the requested data.
        # If not, only supply what we have space for
        if len(model.data['system']['time_keys']) < num_time_periods:
            num_time_periods = len(model.data['system']['time_keys'])

        # Collect a list of non-dispatchable generators
        renewables = list(model.elements('generator', generator_type='renewable'))

        start_hour = start_time.hour
        start_day = start_time.date()

        # Loop through each time step
        for step_index in range(0, num_time_periods):
            step_time = start_time + step_delta*step_index
            day = step_time.date()

            # 0-based hour, useable as index into forecast arrays
            hour = step_time.hour

            # For data starting at time 0, we collect tomorrow's data
            # from today's dat file
            if start_hour == 0 and day != start_day:
                day = start_day
                hour += 24

            # If request is beyond the last day, just repeat the final day's values
            if day > self._final_day:
                day = self._final_day

            dat = identify_dat(day)

            # fill in renewables limits
            for gen, gdata in renewables:
                pmin = dat.data['elements']['generator'][gen]['p_min']['values'][hour]
                pmax = dat.data['elements']['generator'][gen]['p_max']['values'][hour]
                gdata['p_min']['values'][step_index] = pmin
                gdata['p_max']['values'][step_index] = pmax

            # Fill in load data
            for bus, bdata in model.elements('load'):
                load = dat.data['elements']['load'][bus]['p_load']['values'][hour]
                bdata['p_load']['values'][step_index] = load

            # Fill in reserve data
            reserve_req = dat.data['system']['reserve_requirement']['values'][hour]
            model.data['system']['reserve_requirement']['values'][step_index] = reserve_req
示例#6
0
def _ensure_reserve_factor_honored(options:Options, md:EgretModel, time_periods:Iterable[int]) -> None:
    ''' Adjust reserve requirements to satisfy the reserve factor.

    For each time period in time_periods, ensure that the reserve requirement is no less than
    the total load for that time period multiplied by the reserve factor.  If the reserve 
    requirement for a time is too low it is raised, otherwise it is left alone.

    '''
    if options.reserve_factor > 0:
        reserve_factor = options.reserve_factor
        reserve_reqs = md.data['system']['reserve_requirement']['values']
        for t in time_periods:
            total_load = sum(bdata['p_load']['values'][t]
                             for bus, bdata in md.elements('load'))
            min_reserve = reserve_factor*total_load
            if reserve_reqs[t] < min_reserve:
                reserve_reqs[t] = min_reserve