Assigns an MV feeder to every generator, LV station, load, and branch tee

    Parameters
    -----------
    mv_grid : :class:`~.grid.grids.MVGrid`
773162
def assign_mv_feeder_to_nodes(mv_grid):
    
    mv_station_neighbors = mv_grid.graph.neighbors(mv_grid.station)
    # get all nodes in MV grid and remove MV station to get separate subgraphs
    mv_graph_nodes = mv_grid.graph.nodes()
    mv_graph_nodes.remove(mv_grid.station)
    subgraph = mv_grid.graph.subgraph(mv_graph_nodes)

    for neighbor in mv_station_neighbors:
        # determine feeder
        mv_feeder = mv_grid.graph.line_from_nodes(mv_grid.station, neighbor)
        # get all nodes in that feeder by doing a DFS in the disconnected
        # subgraph starting from the node adjacent to the MVStation `neighbor`
        subgraph_neighbor = nx.dfs_tree(subgraph, source=neighbor)
        for node in subgraph_neighbor.nodes():
            # in case of an LV station assign feeder to all nodes in that LV
            # grid
            if isinstance(node, LVStation):
                for lv_node in node.grid.graph.nodes():
                    lv_node.mv_feeder = mv_feeder
            else:
                node.mv_feeder = mv_feeder
845083
def _run_power_flow(self, Ybus, Sbus, V, pv, pq, pvpq, **kw_args):
        
        Va = angle(V)
        Vm = abs(V)

        # Initial evaluation of F(x0)...
        F = self._evaluate_function(Ybus, V, Sbus, pv, pq)
        # ...and convergency check.
        converged = self._check_convergence(F)

        # Perform Newton iterations.
        i = 0
        while (not converged) and (i < self.iter_max):
            V, Vm, Va = self._one_iteration(F, Ybus, V, Vm, Va, pv, pq, pvpq)
            F = self._evaluate_function(Ybus, V, Sbus, pv, pq)
            converged = self._check_convergence(F)
            i += 1

        if converged:
            if self.verbose:
                logger.info("Newton's method power flow converged in %d "
                            "iterations." % i)
        else:
            logger.error("Newton's method power flow did not converge in %d "
                         "iterations." % i)

        return V, converged, i
89631
def lv_grid_districts(self):
        
        for lv_grid_district in sorted(self._lv_grid_districts, key=lambda _: repr(_)):
            yield lv_grid_district
975650
def set_defaults(self):
        
        self['mswitch'] = 1
        self['elem'] = '../grid/elem.dat'
        self['elec'] = '../grid/elec.dat'
        self['volt'] = '../mod/volt.dat'
        self['inv_dir'] = '../inv'
        self['diff_inv'] = 'F ! difference inversion?'
        self['iseed_var'] = 'iseed variance'
        self['cells_x'] = '0    ! # cells in x-direction'
        self['cells_z'] = '-1    ! # cells in z-direction'
        self['ani_x'] = '1.000  ! smoothing parameter in x-direction'
        self['ani_z'] = '1.000  ! smoothing parameter in z-direction'
        self['max_it'] = '20    ! max. nr of iterations'
        self['dc_inv'] = 'F     ! DC inversion?'
        self['robust_inv'] = 'T     ! robust inversion?'
        self['fpi_inv'] = 'F     ! final phase improvement?'
        self['mag_rel'] = '5'
        self['mag_abs'] = '1e-3'
        self['pha_a1'] = 0
        self['pha_b'] = 0
        self['pha_rel'] = 0
        self['pha_abs'] = 0
        self['hom_bg'] = 'F'
        self['hom_mag'] = '10.00'
        self['hom_pha'] = '0.00'
        self['another_ds'] = 'F'
        self['d2_5'] = '1'
        self['fic_sink'] = 'F'
        self['fic_sink_node'] = '10000'
        self['boundaries'] = 'F'
        self['boundaries_file'] = 'boundary.dat'
        self['mswitch2'] = '1'
        self['lambda'] = 'lambda'
899011
def build_iters(data_dir, max_records, q, horizon, splits, batch_size):
    
    # Read in data as numpy array
    df = pd.read_csv(os.path.join(data_dir, "electricity.txt"), sep=",", header=None)
    feature_df = df.iloc[:, :].astype(float)
    x = feature_df.as_matrix()
    x = x[:max_records] if max_records else x

    # Construct training examples based on horizon and window
    x_ts = np.zeros((x.shape[0] - q, q, x.shape[1]))
    y_ts = np.zeros((x.shape[0] - q, x.shape[1]))
    for n in range(x.shape[0]):
        if n + 1 < q:
            continue
        elif n + 1 + horizon > x.shape[0]:
            continue
        else:
            y_n = x[n + horizon, :]
            x_n = x[n + 1 - q:n + 1, :]
        x_ts[n-q] = x_n
        y_ts[n-q] = y_n

    # Split into training and testing data
    training_examples = int(x_ts.shape[0] * splits[0])
    valid_examples = int(x_ts.shape[0] * splits[1])
    x_train, y_train = x_ts[:training_examples], \
                       y_ts[:training_examples]
    x_valid, y_valid = x_ts[training_examples:training_examples + valid_examples], \
                       y_ts[training_examples:training_examples + valid_examples]
    x_test, y_test = x_ts[training_examples + valid_examples:], \
                     y_ts[training_examples + valid_examples:]

    #build iterators to feed batches to network
    train_iter = mx.io.NDArrayIter(data=x_train,
                                   label=y_train,
                                   batch_size=batch_size)
    val_iter = mx.io.NDArrayIter(data=x_valid,
                                 label=y_valid,
                                 batch_size=batch_size)
    test_iter = mx.io.NDArrayIter(data=x_test,
                                  label=y_test,
                                  batch_size=batch_size)
    return train_iter, val_iter, test_iter
1357355
def reset(self):
        
        logger.info("Reseting environment.")

        self._step = 0

        # Reset the set-point of each generator to its original value.
        gs = [g for g in self.case.online_generators if g.bus.type !=REFERENCE]
        for i, g in enumerate(gs):
            g.p = self._Pg0[i]

        # Apply load profile to the original demand at each bus.
        for i, b in enumerate([b for b in self.case.buses if b.type == PQ]):
            b.p_demand = self._Pd0[i] * self.profile[self._step]

        # Initialise the record of generator set-points.
        self._Pg = zeros((len(self.case.online_generators), len(self.profile)))

        # Apply the first load profile value.
#        self.step()

        self.case.reset()
259140
def _update_model(self, case, B, Bsrc, v_angle, p_srcinj, p_ref, ref_idx):
        
        iref = ref_idx
        base_mva = case.base_mva
        buses = case.connected_buses
        branches = case.online_branches

        p_from = (Bsrc * v_angle + p_srcinj) * base_mva
        p_to = -p_from

        for i, branch in enumerate(branches):
            branch.p_from = p_from[i]
            branch.p_to = p_to[i]
            branch.q_from = 0.0
            branch.q_to = 0.0

        for j, bus in enumerate(buses):
            bus.v_angle = v_angle[j] * (180 / pi)
            bus.v_magnitude = 1.0

        # Update Pg for swing generator.
        g_ref = [g for g in case.generators if g.bus == buses[iref]][0]
        # Pg = Pinj + Pload + Gs
        # newPg = oldPg + newPinj - oldPinj
        p_inj = (B[iref, :] * v_angle - p_ref) * base_mva
        g_ref.p += p_inj[0]
621502
def generator(self, Xgen, Xexc, Xgov, Vgen):
        
        generators = self.dyn_generators
        omegas = 2 * pi * self.freq

        F = zeros(Xgen.shape)

        typ1 = [g._i for g in generators if g.model == CLASSICAL]
        typ2 = [g._i for g in generators if g.model == FOURTH_ORDER]

        # Generator type 1: classical model
        omega = Xgen[typ1, 1]
        Pm0 = Xgov[typ1, 0]

        H = array([g.h for g in generators])[typ1]
        D = array([g.d for g in generators])[typ1]

        Pe = Vgen[typ1, 2]

        ddelta = omega = omegas
        domega = pi * self.freq / H * (-D * (omega - omegas) + Pm0 - Pe)
        dEq = zeros(len(typ1))

        F[typ1, :] = c_[ddelta, domega, dEq]

        # Generator type 2: 4th order model
        omega = Xgen[typ2, 1]
        Eq_tr = Xgen[typ2, 2]
        Ed_tr = Xgen[typ2, 3]

        H = array([g.h for g in generators])
        D = array([g.d for g in generators])
        xd = array([g.xd for g in generators])
        xq = array([g.xq for g in generators])
        xd_tr = array([g.xd_tr for g in generators])
        xq_tr = array([g.xq_tr for g in generators])
        Td0_tr = array([g.td for g in generators])
        Tq0_tr = array([g.tq for g in generators])

        Id = Vgen[typ2, 0]
        Iq = Vgen[typ2, 1]
        Pe = Vgen[typ2, 2]

        Efd = Xexc[typ2, 0]
        Pm = Xgov[typ2, 0]

        ddelta = omega - omegas
        domega = pi * self.freq / H * (-D * (omega - omegas) + Pm - Pe)
        dEq = 1 / Td0_tr * (Efd - Eq_tr + (xd - xd_tr) * Id)
        dEd = 1 / Tq0_tr * (-Ed_tr - (xq - xq_tr) * Iq)

        F[typ2, :] = c_[ddelta, domega, dEq, dEd]

        # Generator type 3:

        # Generator type 4:

        return F
90829
def _get_voltage_magnitude_var(self, buses, generators):
        
        Vm = array([b.v_magnitude for b in buses])

        # For buses with generators initialise Vm from gen data.
        for g in generators:
            Vm[g.bus._i] = g.v_magnitude

        Vmin = array([b.v_min for b in buses])
        Vmax = array([b.v_max for b in buses])

        return Variable("Vm", len(buses), Vm, Vmin, Vmax)
209491
def add_load(self, lv_load):
        
        if lv_load not in self._loads and isinstance(lv_load,
                                                     LVLoadDing0):
            self._loads.append(lv_load)
            self.graph_add_node(lv_load)
54296
def _run_power_flow(self, Ybus, Sbus, V, pv, pq, pvpq):
        
        i = 0
        Va = angle(V)
        Vm = abs(V)

        # FIXME: Do not repeat build for each Q limit loop.
        Bp, Bpp = self.case.makeB(method=self.method)

        # Evaluate initial mismatch.
        P, Q = self._evaluate_mismatch(Ybus, V, Sbus, pq, pvpq)

        if self.verbose:
            logger.info("iteration     max mismatch (p.u.)  \n")
            logger.info("type   #        P            Q     \n")
            logger.info("---- ----  -----------  -----------\n")

        # Check tolerance.
        converged = self._check_convergence(P, Q, i, "P")

        if converged and self.verbose:
            logger.info("Converged!")

        # Reduce B matrices.
        pq_col = [[k] for k in pq]
        pvpq_col = [[k] for k in pvpq]
        Bp = Bp[pvpq_col, pvpq].tocsc() # splu requires a CSC matrix
        Bpp = Bpp[pq_col, pq].tocsc()

        # Factor B matrices.
        Bp_solver = splu(Bp)
        Bpp_solver = splu(Bpp)
#        L = decomp.lu(Bp.todense())
#        LU, P = decomp.lu_factor(Bp.todense())

        # Perform Newton iterations.
        while (not converged) and (i < self.iter_max):
            i += 1
            # Perform P iteration, update Va.
            V, Vm, Va = self._p_iteration(P, Bp_solver, Vm, Va, pvpq)

            # Evalute mismatch.
            P, Q = self._evaluate_mismatch(Ybus, V, Sbus, pq, pvpq)
            # Check tolerance.
            converged = self._check_convergence(P, Q, i, "P")

            if self.verbose and converged:
                logger.info("Fast-decoupled power flow converged in %d "
                    "P-iterations and %d Q-iterations." % (i, i - 1))
                break

            # Perform Q iteration, update Vm.
            V, Vm, Va = self._q_iteration(Q, Bpp_solver, Vm, Va, pq)

            # Evalute mismatch.
            P, Q = self._evaluate_mismatch(Ybus, V, Sbus, pq, pvpq)
            # Check tolerance.
            converged = self._check_convergence(P, Q, i, "Q")

            if self.verbose and converged:
                logger.info("Fast-decoupled power flow converged in %d "
                    "P-iterations and %d Q-iterations." % (i, i))
                break

        if self.verbose and not converged:
            logger.error("FDPF did not converge in %d iterations." % i)

        return V, converged, i
338658
def setup(delta_x, delta_y, delta_z, pos)
      # Set up the provided parameters:
      @delta_x = delta_x
      @delta_y = delta_y
      @delta_z = delta_z
      self.pos = pos
      # Set up the dimensional parameters:
      @nx, @ny, @nz = self.shape
    end
155316
def set_power_supplies(self, power_supplies):
        

        power_supply_id = 0
        for power_supply in power_supplies:
            yield from self._hypervisor.send('c7200 set_power_supply "{name}" {power_supply_id} {powered_on}'.format(name=self._name,
                                                                                                                     power_supply_id=power_supply_id,
                                                                                                                     powered_on=power_supply))

            log.info('Router "{name}" [{id}]: power supply {power_supply_id} state updated to {powered_on}'.format(name=self._name,
                                                                                                                   id=self._id,
                                                                                                                   power_supply_id=power_supply_id,
                                                                                                                   powered_on=power_supply))
            power_supply_id += 1

        self._power_supplies = power_supplies
701805
def add_station(self, mv_station, force=False):
        
        if not isinstance(mv_station, MVStationDing0):
            raise Exception('Given MV station is not a MVStationDing0 object.')
        if self._station is None:
            self._station = mv_station
            self.graph_add_node(mv_station)
        else:
            if force:
                self._station = mv_station
            else:
                raise Exception('MV Station already set, use argument `force=True` to override.')
324043
def set_operation_voltage_level(self):
        

        mv_station_v_level_operation = float(cfg_ding0.get('mv_routing_tech_constraints',
                                                           'mv_station_v_level_operation'))

        self.v_level_operation = mv_station_v_level_operation * self.grid.v_level
188741
def write_bus_data(self, file):
        
        # I, 'NAME', BASKV, IDE, GL, BL, AREA, ZONE, VM, VA, OWNER
        bus_attrs = ["_i", "name", "v_base", "type", "g_shunt", "b_shunt",
                     "area", "zone",
                     "v_magnitude", "v_angle"]

        for bus in self.case.buses:
            vals = [getattr(bus, a) for a in bus_attrs]
            if float(vals[6]) == 0.0:
                vals[6] = 1  # default AREA: 1
            if float(vals[7])==0.0:
                vals[7] = 1  # default ZONE: 1
            d = {PQ: 1, PV: 2, REFERENCE: 3, ISOLATED: 4}
            vals[3] = d[vals[3]]
            vals.append(1)

#            print len(vals), vals

            file.write("%6d,'%-10s',%10.4f,%d,%10.3f,%10.3f,%4d,%4d,%10.3f,"
                       "%10.3f%4d\n" % tuple(vals))
        file.write(" 0 / END OF BUS DATA, BEGIN LOAD DATA\n")


        # I, ID, STATUS, AREA, ZONE, PL, QL, IP, IQ, YP, YQ, OWNER
        load_attrs = ["_i", "area", "zone", "p_demand", "q_demand"]

        for bus in self.case.buses:
            if bus.p_demand > 0.0 or bus.q_demand > 0.0:
                vals = [getattr(bus, a) for a in load_attrs]
                if float(vals[1])==0.0:
                    vals[1] = 1  # default AREA: 1
                if float(vals[2])==0.0:
                    vals[2] = 1  # default ZONE: 1
                vals.insert(1, 1) # STATUS
                vals.insert(1, "1 ") # ID
                vals.extend([0., 0., 0., 0.])
                vals.append(1) # OWNER

                file.write("%6d,'%s',%2d,%2d,%2d,%10.3f,%10.3f,%10.3f,%10.3f,"
                           "%10.3f,%10.3f,%4d\n" % tuple(vals))

        file.write(" 0 / END OF LOAD DATA, BEGIN GENERATOR DATA\n")
879908
def write_generator_data(self, file):
        
        writer = self._get_writer(file)
        writer.writerow(["bus"] + GENERATOR_ATTRS)

        for g in self.case.generators:
            i = g.bus._i
            writer.writerow([i] + [getattr(g,a) for a in GENERATOR_ATTRS])