Beispiel #1
0
 def __init__(self):
     self.action_space = []
     self.ppopt = ppoption(VERBOSE=0,
                           OUT_ALL=0,
                           OUT_SYS_SUM=False,
                           OUT_BUS=False,
                           OUT_BRANCH=False)  #output format control
     self.state = {'loss': None, 'Vmin': None, 'Vmax': None}
     self.bus_list = []
     self.genmap = {}  #{bus number: gen number}
     self.actmap = {}  #{0~n_actions: act number}
     # assign case
     self.ppc = case()
     g = nx.Graph()
     for bus in self.ppc['bus']:
         self.bus_list.append(int(bus[0]))
         g.add_node(int(bus[0]))
     for brch in self.ppc['branch']:
         g.add_edge(int(brch[0]), int(brch[1]))
     self.pos = nx.kamada_kawai_layout(g)
     red = '#ff0000'  #red
     green = '#00ff00'  #green
     blue = '#0000ff'  #blue
     self.cmap = col.LinearSegmentedColormap.from_list(
         'cmap', [blue, green, red])
Beispiel #2
0
def PF_Sim(ppc, pDemand, rDemand, nodesStorage, U, rootV2):
    """
	Uses PyPower to calculate PF to simulate node voltages after storage action
	Inputs: ppc - PyPower case dictionary
		pDemand/rDemand - true values of real and reactive power demanded
		nodesStorage - list of storage nodes indexes
		U - storage control action
		rootV2 - voltage of the substation node
	Outputs: runVoltage - (buses X time) array of voltages
	"""

    nodesNum = 7  #pDemand.shape tuple doesnt work...
    runVoltage = np.zeros((nodesNum, 1))

    pLoad = np.copy(pDemand)
    pLoad[nodesStorage] = pLoad[nodesStorage] + U
    rLoad = rDemand
    rootVoltage = np.sqrt(rootV2)
    ppc['bus'][:, 2] = pLoad.flatten()
    ppc['bus'][:, 3] = rLoad.flatten()
    #ppc['bus'][rootIdx,7] = rootVoltage # Doesnt actually set PF root voltage

    ppopt = ppoption(VERBOSE=0, OUT_ALL=0)
    ppc_out = runpf(ppc, ppopt)

    rootVdiff = rootVoltage - 1
    runVoltage = ppc_out[0]['bus'][:, 7] + rootVdiff

    return runVoltage
def case_iteration():
    ppc = mycase()
    ppopt = ppoption(PF_ALG=2)

    r = runopf(ppc, ppopt)

    myprintpf(r)
Beispiel #4
0
def PF_Sim(ppc, GCtime, pDemand, rDemand, nodesStorage, U, rootV2):
    """
    Uses PyPower to calculate PF to simulate node voltages after storage control
    Inputs: ppc - PyPower case dictionary
        GCtime - number of time steps between GC runs
        pDemand/rDemand - true values of real and reactive power demanded
        nodesStorage - list of storage nodes indexes
        U - storage control action
        rootV2 - voltage of the substation node
    Outputs: runVoltage - (buses X time) array of voltages
    """
    nodesNum, T = pDemand.shape
    runVoltage = np.zeros((nodesNum, GCtime))
    for t in range(GCtime):
        pLoad = pDemand[:, t]
        pLoad[nodesStorage] = pLoad[nodesStorage] + U[:, t]
        rLoad = rDemand[:, t]
        rootVoltage = np.sqrt(rootV2[:, t])
        ppc['bus'][:, 2] = pLoad.flatten()
        ppc['bus'][:, 3] = rLoad.flatten()
        # ppc['bus'][rootIdx,7] = rootVoltage # Doesnt actually set PF root voltage

        # for surpressing runpf output
        ppopt = ppoption(VERBOSE=0, OUT_ALL=0)
        ppc_out = runpf(ppc, ppopt)

        rootVdiff = rootVoltage - 1
        runVoltage[:, t] = ppc_out[0]['bus'][:, 7] + rootVdiff

    return runVoltage
Beispiel #5
0
def adapt_case(node, power, time):
    #input node is the node that the agent accesses, the power is in kW , the time is the timestep [0,96]
    time = time % 96  # if the time interval exceeds the number of elements in the load profile
    loadprofile = 0.001 * array([
        2.1632, 1.9456, 1.7568, 1.5968, 1.4784, 1.3952, 1.3408, 1.3056, 1.2832,
        1.2672, 1.2608, 1.2512, 1.2416, 1.2352, 1.2256, 1.2256, 1.2288, 1.2416,
        1.2576, 1.28, 1.3088, 1.3792, 1.5264, 1.7856, 2.176, 2.6496, 3.136,
        3.568, 3.8912, 4.112, 4.2464, 4.3136, 4.3328, 4.3136, 4.2592, 4.1824,
        4.0864, 3.9872, 3.888, 3.808, 3.7536, 3.7184, 3.7024, 3.7024, 3.7152,
        3.744, 3.7984, 3.888, 4.0128, 4.1472, 4.256, 4.3136, 4.2944, 4.2144,
        4.096, 3.968, 3.8464, 3.7376, 3.6384, 3.5424, 3.4528, 3.376, 3.312,
        3.2768, 3.2704, 3.3024, 3.3792, 3.5168, 3.712, 3.9584, 4.2432, 4.5536,
        4.8768, 5.1904, 5.4784, 5.7248, 5.9104, 6.0224, 6.0448, 5.9648, 5.7824,
        5.5264, 5.2448, 4.9792, 4.7648, 4.5888, 4.4288, 4.2624, 4.0704, 3.856,
        3.6256, 3.3824, 3.136, 2.8864, 2.64, 2.3968
    ])
    q = zeros(25)  #set the reactive power to zero at each point
    p = loadprofile[time] * ones(
        25
    )  # set the active power at each grid point to the value in the load profile given the time
    p[0] = 0  # set the load at the transformer to 0
    p[node] = p[
        node] + power * 0.001  # add the power to the node that the agent controlls

    # do the actual power flow simulation
    ppc = casemodul(p, q)
    ppopt = ppoption(PF_ALG=2, VERBOSE=False, OUT_ALL=0)
    ppc_result, y = runpf(
        ppc,
        ppopt)  #run the powerflow simulation gibven the case and the options

    return ppc_result["bus"][node, 7]
def run_pypower(case):
    """
    Executes a PYPOWER power flow for *case* and writes its results back to
    *case*.

    If *case* is a string, :func:`transform` will be called first to create
    a bus/branch model from the CIM file.

    """
    basestring = (str,bytes)
    from pypower.api import ppoption, runpf
    from cim2busbranch import ext_pypower

    if isinstance(case, basestring):
        case = transform(case)

    ppc = ext_pypower.create(case)

    ppo = ppoption(OUT_ALL=0, VERBOSE=0)
    res = runpf(ppc, ppo)

    if not res[1]:
        raise RuntimeError('PYPOWER power flow failed.')

    ext_pypower.write_results_to_case(res[0], case)
def test_pypower_case():

    #ppopt is a dictionary with the details of the optimization routine to run
    ppopt = ppoption(PF_ALG=2)

    #choose DC or AC
    ppopt["PF_DC"] = True

    #ppc is a dictionary with details about the network, including baseMVA, branches and generators
    ppc = case()

    results, success = runpf(ppc, ppopt)

    #store results in a DataFrame for easy access
    results_df = {}

    #branches
    columns = 'bus0, bus1, r, x, b, rateA, rateB, rateC, ratio, angle, status, angmin, angmax, p0, q0, p1, q1'.split(
        ", ")
    results_df['branch'] = pd.DataFrame(data=results["branch"],
                                        columns=columns)

    #buses
    columns = [
        "bus", "type", "Pd", "Qd", "Gs", "Bs", "area", "v_mag_pu_set",
        "v_ang_set", "v_nom", "zone", "Vmax", "Vmin"
    ]
    results_df['bus'] = pd.DataFrame(data=results["bus"],
                                     columns=columns,
                                     index=results["bus"][:, 0])

    #generators
    columns = "bus, p, q, q_max, q_min, Vg, mBase, status, p_max, p_min, Pc1, Pc2, Qc1min, Qc1max, Qc2min, Qc2max, ramp_agc, ramp_10, ramp_30, ramp_q, apf".split(
        ", ")
    results_df['gen'] = pd.DataFrame(data=results["gen"], columns=columns)

    #now compute in PyPSA

    network = pypsa.Network()
    network.import_from_pypower_ppc(ppc)
    network.lpf()

    #compare generator dispatch

    p_pypsa = network.generators_t.p.loc["now"].values
    p_pypower = results_df['gen']["p"].values

    np.testing.assert_array_almost_equal(p_pypsa, p_pypower)

    #compare branch flows
    for item in ["lines", "transformers"]:
        df = getattr(network, item)
        pnl = getattr(network, item + "_t")

        for si in ["p0", "p1"]:
            si_pypsa = getattr(pnl, si).loc["now"].values
            si_pypower = results_df['branch'][si][df.original_index].values
            np.testing.assert_array_almost_equal(si_pypsa, si_pypower)
Beispiel #8
0
	def __init__(self):
		self.ppc = case30()
		self.ppopt = ppoption(PF_ALG=1, RETURN_RAW_DER=True, OPF_FLOW_LIM=0)
		self.ppn = case30_panda()
		self.results = None
		self.sol_opt = None
		self.alg = None
		self.idx_mode = None
		self.res_struct = None
		self.load_list = None
def test_pypower_case():

    #ppopt is a dictionary with the details of the optimization routine to run
    ppopt = ppoption(PF_ALG=2)

    #choose DC or AC
    ppopt["PF_DC"] = True

    #ppc is a dictionary with details about the network, including baseMVA, branches and generators
    ppc = case()

    results,success = runpf(ppc, ppopt)

    #store results in a DataFrame for easy access
    results_df = {}

    #branches
    columns = 'bus0, bus1, r, x, b, rateA, rateB, rateC, ratio, angle, status, angmin, angmax, p0, q0, p1, q1'.split(", ")
    results_df['branch'] = pd.DataFrame(data=results["branch"],columns=columns)

    #buses
    columns = ["bus","type","Pd","Qd","Gs","Bs","area","v_mag_pu_set","v_ang_set","v_nom","zone","Vmax","Vmin"]
    results_df['bus'] = pd.DataFrame(data=results["bus"],columns=columns,index=results["bus"][:,0])

    #generators
    columns = "bus, p, q, q_max, q_min, Vg, mBase, status, p_max, p_min, Pc1, Pc2, Qc1min, Qc1max, Qc2min, Qc2max, ramp_agc, ramp_10, ramp_30, ramp_q, apf".split(", ")
    results_df['gen'] = pd.DataFrame(data=results["gen"],columns=columns)



    #now compute in PyPSA

    network = pypsa.Network()
    network.import_from_pypower_ppc(ppc)
    network.lpf()



    #compare generator dispatch

    p_pypsa = network.generators_t.p.loc["now"].values
    p_pypower = results_df['gen']["p"].values

    np.testing.assert_array_almost_equal(p_pypsa,p_pypower)

    #compare branch flows
    for item in ["lines","transformers"]:
        df = getattr(network,item)
        pnl = getattr(network,item + "_t")

        for si in ["p0","p1"]:
            si_pypsa = getattr(pnl,si).loc["now"].values
            si_pypower = results_df['branch'][si][df.original_index].values
            np.testing.assert_array_almost_equal(si_pypsa,si_pypower)
Beispiel #10
0
def likelihood_ps(measur_vec,bvec):

    # -- modify load buses
    ppc["bus"][ind,2] = bvec

    # -- estimate the transformer measurements
    ppopt   = pypo.ppoption(PF_ALG=2, VERBOSE=0, OUT_ALL=0) 
    r       = pypo.runpf(ppc, ppopt)
    estim   = r[0]['gen'][:,2] 
    
    # -- calculate the likelihood
    sig     = 10.0

    return np.exp(-((estim - measur_vec)**2).sum()/(2*sig**2))
Beispiel #11
0
def main(casefile):

    ppopt = ppoption(PF_ALG=2)

    r = runpf(casedata=casefile,
              ppopt=ppopt)

    output = {'baseMVA': r[0]['baseMVA'],
              'branch': r[0]["branch"].tolist(),
              'bus': r[0]["bus"].tolist(),
              'gen': r[0]["gen"].tolist()
          }
    
    sys.stdout.write(json.dumps(output)+'\n')
Beispiel #12
0
def proportional_sim(grid, a, attack_set, verbose=False, saveIterations=False):
    """Runs a cascading failure simulation, with capacities proportional to
    initial load (i.e. C = (1+a)*L).

    See run_simulation() for more details.
    """
    ppopt = pp.ppoption(VERBOSE=0, OUT_ALL=0)
    initial_grid = pp.rundcpf(grid, ppopt)[0]
    capacities = abs(initial_grid['branch'][:, idx_brch.PF]) * (1 + a)

    return run_simulation(grid,
                          capacities,
                          attack_set,
                          verbose=verbose,
                          saveIterations=saveIterations)
Beispiel #13
0
def iid_sim(grid, dist, attack_set, verbose=False, saveIterations=False):
    """Runs a cascading failure simulation, with capacities given by C = L + S, 
    where S is a random variable drawn from a given distribution.

    See run_simulation() for more details.
    """
    ppopt = pp.ppoption(VERBOSE=0, OUT_ALL=0)
    initial_grid = pp.rundcpf(grid, ppopt)[0]
    capacities = abs(initial_grid['branch'][:, idx_brch.PF]) + dist()

    return run_simulation(grid,
                          capacities,
                          attack_set,
                          verbose=verbose,
                          saveIterations=saveIterations)
Beispiel #14
0
def lnlike(theta, y):

    # -- modify load buses
    ppc["bus"][ind, 2] = theta

    # -- estimate the transformer measurements
    sol = pypo.runpf(ppc, pypo.ppoption(PF_ALG=2, VERBOSE=0, OUT_ALL=0))
    estim = sol[0]["gen"][:, 2]

    # -- calculate the likelihood
    sig = 1.0
    if (theta >= 0.0).all():
        return -((estim - y) ** 2).sum() / (2 * sig ** 2)
    else:
        return -np.inf
def main():
    import sys

    case = sys.argv[1] if len(sys.argv) == 2 else 'a'
    cases = {
        'a': test_case_a,
        'b': test_case_b,
    }

    case = cases[case]()
    ppc = ext_pypower.create(case)

    ppo = ppoption(OUT_ALL=0, VERBOSE=0)
    res = runpf(ppc, ppo)

    ext_pypower.write_results_to_case(res[0], case)
    print(case)
Beispiel #16
0
    def dcpf(self, time=0, mpc=None, save2network=True):
        """ Run DC power flow """

        if type(time) is int:
            time = self.flow_modelled.index[time]
        if mpc is None:
            mpc = self.make_mpc()
        mpc = rundcpf(
            mpc,
            ppoption(VERBOSE=0,
                     OUT_ALL=-1,
                     OUT_BUS=0,
                     OUT_ALL_LIM=0,
                     OUT_BRANCH=0,
                     OUT_SYS_SUM=0))
        self.solved_mpc.append(mpc)

        # AC exchange between areas
        br = mpc[0]['branch']
        ac_flow = pd.DataFrame(0,
                               index=[time],
                               columns=list(self.flow_modelled))
        bid0 = arr(self.bus.loc[br[:, 0], 'bidz'])
        bid1 = arr(self.bus.loc[br[:, 1], 'bidz'])
        for n, a0 in enumerate(self.bidz):
            for a1 in self.bidz[n + 1:]:
                ind0 = (bid0 == a0) & (bid1 == a1)  # find lines between areas
                ind1 = (bid0 == a1) & (bid1 == a0
                                       )  # -"- but reverse flow direction
                if np.sum(ind0) + np.sum(ind1) > 0:
                    exch = -np.sum(br[ind0, 13]) + np.sum(br[ind1, 13])
                    ac_flow.loc[time, '%s-%s' % (a0, a1)] = exch
        for i in list(ac_flow):
            self.flow_modelled.at[time, i] = ac_flow.at[time, i]
        if save2network:
            self.mpc2network(
            )  # add parameters to network (flows, voltage angle etc.)
    def __init__(self, Time):
        '''
        Constructs a pypower case and inits a load profile
        '''
        #data for the power flow 
        self.Time = Time ## might be a useless variable since the laod profile has been moved to the agent
        ##options
        self.ppopt = ppoption(PF_ALG=2, VERBOSE= 0,OUT_ALL=0)
        self.ppc = {"version": '2'}
        
        self.loadprofile = array([2.1632,1.9456,1.7568,1.5968,1.4784 ,1.3952,1.3408,1.3056,1.2832,1.2672,
1.2608,1.2512,1.2416,1.2352,1.2256,
1.2256,1.2288,1.2416,1.2576,1.28,
1.3088,1.3792,1.5264,1.7856,2.176,
2.6496,3.136,3.568,3.8912,4.112,
4.2464,4.3136,4.3328,4.3136,4.2592,
4.1824,4.0864,3.9872,3.888,3.808,
3.7536,3.7184,3.7024,3.7024,3.7152,
3.744,3.7984,3.888,4.0128,4.1472,
4.256,4.3136,4.2944,4.2144,4.096,
3.968,3.8464,3.7376,3.6384,3.5424,
3.4528,3.376,3.312,3.2768,3.2704,
3.3024,3.3792,3.5168,3.712,3.9584,
4.2432,4.5536,4.8768,5.1904,5.4784,
5.7248,5.9104,6.0224,6.0448,5.9648,
5.7824,5.5264,5.2448,4.9792,4.7648,
4.5888,4.4288,4.2624,4.0704,3.856,
3.6256,3.3824,3.136,2.8864,2.64,
2.3968])
        
        ## system MVA base
        self.ppc["baseMVA"] = 0.144
        #self.ppc["baseMVA"] = 7
        
        ## bus data
        # bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin
        self.ppc["bus"] = array([
        [1,3,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [2,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [3,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [4,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [5,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [6,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [7,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [8,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [9,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [10,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [11,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [12,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [13,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [14,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [15,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [16,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [17,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [18,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [19,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [20,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [21,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [22,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [23,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [24,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [25,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [26,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [27,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [28,1,0,0,0,0,0,1,1,0,1,1.1,0.94],
        [29,1,0,0,0,0,0,1,1,0,1,1.1,0.94]
    ])
        self.ppc["bus"][:,12] = 0.96
        #self.ppc["bus"][:,12]=0.90 # relaxes the lower voltage constraint.
        ## generator data
        # bus, Pg, Qg, Qmax, Qmin, Vg, mBase, status, Pmax, Pmin, Pc1, Pc2,
        # Qc1min, Qc1max, Qc2min, Qc2max, ramp_agc, ramp_10, ramp_30, ramp_q, apf
        
        
        self.ppc["branch"] = array([
        [2,1,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [3,2,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [4,3,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [5,4,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [6,5,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [7,6,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [8,7,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [9,1,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [10,9,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [11,10,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [12,11,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [13,12,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [14,13,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [15,14,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [16,1,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [17,16,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [18,17,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [19,18,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [20,19,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [21,20,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [22,21,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [23,1,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [24,23,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [25,24,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [26,25,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [27,26,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [28,27,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360],
        [29,28,0.001590, 0.000814,0,0,0,0,0,0,1,-360,360]
        ])
        self.ppc["branch"][:,2]= (0.494 * 0.097 / 1.5) 
        self.ppc["branch"][:,3]= (0.0883 * 0.097 / 1.5)
        
        ## generator data
        # bus, Pg, Qg, Qmax, Qmin, Vg, mBase, status, Pmax, Pmin, Pc1, Pc2,
        # Qc1min, Qc1max, Qc2min, Qc2max, ramp_agc, ramp_10, ramp_30, ramp_q, apf
        self.ppc["gen"] = array([
        [1, 1, 0, 0,   -1, 1.0,  100, 1, 5,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [2, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [3, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [4, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [5, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [6, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [7, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [8, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [9, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [10, 0, 0,0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [11, 0, 0,0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [12, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [13, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [14, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [15, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [16, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [17, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [18, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [19, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [20, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [21, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [22, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [23, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [24, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [25, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [26, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [27, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [28, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
        [29, 0, 0, 0,   -1, 1.0,  100, 1,0, -20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    ])
        self.ppc["gen"][:,9] = -1
        self.ppc["gen"][:,4]=1
        self.power_slopes = array([-0.00022311,
                                   -0.00044879,
                                   -0.00067714,
                                   -0.00090823,
                                   -0.00114216,
                                   -0.00137904,
                                   -0.00161895]
)
        self.dispatch_load = zeros(29)
Beispiel #18
0
            "case9Q", \
            "case14", \
            "case24_ieee_rts", \
            "case30", \
            "case30pwl", \
            "case30Q",\
             "case39",\
             "case57",\
             "case118"]

cc = 0  #select test case

casea = __import__(testdata[cc])
###########################

ppopt = ppoption(OUT_ALL=0)  #0=do not print output on screen
outage = imout.imout()  #outage data

nbus_out = len(outage["bus"])
ngen_out = len(outage["gen"])
nbr_out = len(outage["branch"])

n_tot = nbus_out + ngen_out + nbr_out  #total number of outages
success = []  #intialize success of load flow

n_out = 1  #initialize outage counter

# simulate bus outages
c = 0  # start counter
while c < nbus_out:
    temp = casea.casef()  # initialize orignal testcase data
Beispiel #19
0
nwalkers = 300
nsteps = 100
cut = 50

# -- intialize the 14-bus system
ppc0 = get_ppc14(1, 0, 1)  # 0 implies no change
ppc = cp.deepcopy(ppc0)
# y     = ppc0['gen'][:,2].copy() # default measured values of transformers
ind = ppc0["bus"][:, 1] == 1  # building indices
# binit = ppc0["bus"][ind,2].copy()

for val in [1.00, 2.00, 5.00, 10.00, 20.00]:
    # -- Initialize sample
    print("initializing sampler...")
    np.random.seed(314)
    ppc["bus"][ind, 2] = val * np.ones(ndim)
    sol = pypo.runpf(ppc, pypo.ppoption(PF_ALG=2, VERBOSE=0, OUT_ALL=0))
    y = sol[0]["gen"][:, 2]
    binit = ppc["bus"][ind, 2].copy()
    sampler = emcee.EnsembleSampler(nwalkers, ndim, lnlike, args=[y])
    pos = np.array([binit * (1.0 + 0.2 * np.random.randn(ndim)) for i in range(nwalkers)]).clip(min=0.0)
    # -- run walkers
    print("running walkers...")
    sampler.run_mcmc(pos, nsteps)
    print("walkers finished...")

    # -- save chain
    oname = "./output/random_test20percent_diffValues" + str(val) + ".npy"
    print("saving chain to {0}".format(oname))
    np.save(oname, sampler.chain)
Beispiel #20
0
def run_simulation(grid,
                   capacities,
                   attack_set,
                   verbose=False,
                   saveIterations=False):
    """Runs a cascading failure simulation.

    addition documentation goes here

    INPUT:  grid: dict (representing a PYPOWER case file),
            capacities: list (of the same length as grid['branch']),
            attack_set: list (of line indices),
            verbose: bool,
            step_limit: int
    OUTPUT: dict (containing data about the simulation)
    """
    # initialization
    if 'areas' in grid:
        del grid['areas']
    ppopt = pp.ppoption(VERBOSE=0, OUT_ALL=0)
    grid = pp.rundcpf(grid, ppopt)[0]
    # record initial data
    initial_power = sum(grid['bus'][:, idx_bus.PD])
    initial_size = len(grid['branch'])
    # initialize data structures
    failed_lines = []
    failure_history = []
    new_failed_lines = attack_set
    components = []
    if saveIterations:
        grid_history = [copy.deepcopy(grid)]

    if verbose:
        counter = 0
        print("Initial system summary:")
        print(system_summary(grid, [grid], capacities))
        print("Lines to fail: %s" % new_failed_lines)

    while len(new_failed_lines) > 0:
        if verbose:
            print()
            temp = input("About to run loop %d. Press enter to continue." %
                         counter)

        # keep track of failed lines
        failure_history.append(new_failed_lines)
        failed_lines.extend(new_failed_lines)

        # fail lines
        for line in new_failed_lines:
            grid['branch'][line][idx_brch.BR_R] = np.inf
            grid['branch'][line][idx_brch.BR_X] = np.inf

        # rescale power and run DC power flow in each component
        components = get_components(grid)
        for i, component in enumerate(components):
            rescale_power_gen(component)
            if len(component['branch']) > 0:
                components[i] = pp.rundcpf(component, ppopt)[0]

        # recombine components back to grid
        grid = combine_components(components, grid)

        # find failed lines
        new_failed_lines = []
        for i in range(len(grid['branch'])):
            if abs(grid['branch'][i][idx_brch.PF]) > capacities[i]:
                new_failed_lines.append(i)

        if verbose:
            print(system_summary(grid, components, capacities))
            print("Lines to fail: %s" % new_failed_lines)
            counter += 1

        if saveIterations:
            grid_history.append(copy.deepcopy(grid))

    # compute power loss
    final_power = sum(grid['bus'][:, idx_bus.PD])
    power_loss = (initial_power - final_power) / initial_power

    #compute system size
    final_size = initial_size - len(failed_lines)
    system_size = final_size / initial_size

    # find isolated (no power generated) components and buses
    isolated_components = []
    isolated_buses = []
    for component in components:
        component_gen = sum(component['gen'][:, idx_gen.PG])
        if component_gen == 0:
            isolated_components.append(component)
            for bus in component['bus']:
                isolated_buses.append(bus)

    output_data = {
        "failure_history": failure_history,
        "failed_lines": failed_lines,
        "system_size": system_size,
        "power_loss": power_loss,
        "components": components,
        "isolated_components": isolated_components,
        "isolated_buses": isolated_buses,
        "grid": grid,
        "capacities": capacities
    }
    if saveIterations:
        output_data["grid_history"] = grid_history

    return output_data
def avg_line_flow(ppc):
    ppc = pp.rundcpf(ppc, pp.ppoption(VERBOSE=0, OUT_ALL=0))[0]
    return np.mean(abs(ppc['branch'][:, idx_brch.PF]))
Beispiel #22
0
fname = "Net1_UKGDS_60_subgrid.m"
fnameWhole = "Net1_UKGDS_60.m"
convert_mcase(fname)
from Net1_UKGDS_60_subgrid import Net1_UKGDS_60_ as net
from Net1_UKGDS_60 import Net1_UKGDS_60_ as netWhole

t_f = 96
# time variation
t_ges = 1440  # all time in min
delta_t = 15  # time intervals in min
time = np.arange(delta_t, t_ges + delta_t, delta_t)

casedataWhole = netWhole()
convert_to_python_indices(casedataWhole)
ppc = casedataWhole
ppopt = ppoption(PF_ALG=2)
ppc = ext2int(ppc)
baseMVA, bus, gen, branch = ppc["baseMVA"], ppc["bus"], ppc["gen"], ppc[
    "branch"]
baseMVA = 1000
Ybus, Yf, Yt = makeYbus(baseMVA, bus, branch)  # nodal admittance matrix Ybus
condition = np.hstack((1, np.arange(16, 27, 1)))
Yws = Ybus[np.ix_(condition, condition)]

#Yws = Y
t_f = 96
slack_idx = 0
p0 = 1e-3
iterstop = 50
accuracy = 1e-9
roundY = None
Beispiel #23
0
              '{:.2f}'.format(unresp), '{:.2f}'.format(resp_max),
              '{:.8f}'.format(c2), '{:.8f}'.format(c1), '{:.1f}'.format(deg))


x = np.array(range(25))
y = np.array(load_shape)
l = len(x)
t = np.linspace(0, 1, l - 2, endpoint=True)
t = np.append([0, 0, 0], t)
t = np.append(t, [1, 1, 1])
tck_load = [t, [x, y], 3]
u3 = np.linspace(0, 1, num=86400 / 300 + 1, endpoint=True)
newpts = ip.splev(u3, tck_load)

ppc = tesp.load_json_case(casename + '.json')
ppopt_market = pp.ppoption(VERBOSE=0, OUT_ALL=0, PF_DC=ppc['opf_dc'])
ppopt_regular = pp.ppoption(VERBOSE=0,
                            OUT_ALL=0,
                            PF_DC=ppc['pf_dc'],
                            PF_MAX_IT=20,
                            PF_ALG=1)
StartTime = ppc['StartTime']
tmax = int(ppc['Tmax'])
period = int(ppc['Period'])
dt = int(ppc['dt'])
swing_bus = int(ppc['swing_bus'])

#period = 300
#dt = 15

# initialize for metrics collection
Beispiel #24
0
from pypower.api import case9, ppoption, runpf
import numpy as np

temp = case9()

temp = case9()
ppopt = ppoption(OUT_ALL=0)

(r, s) = runpf(temp, ppopt)
#(r, s) = runpf(temp)

voltage = r["bus"][:, 7]
angle = r["bus"][:, 8]

real_gen = r["gen"][:, 1]
reactive_gen = r["gen"][:, 2]

real_flow_fr = r["branch"][:, 13]
real_flow_to = r["branch"][:, 15]

reactive_flow_fr = r["branch"][:, 14]
reactive_flow_to = r["branch"][:, 16]

apparent_power_flow_fr = np.sqrt(real_flow_fr**2 + reactive_flow_fr**2)
apparent_power_flow_to = np.sqrt(real_flow_to**2 + reactive_flow_to**2)

print type(r["success"])

print(1 - 10.0 / 100)
Beispiel #25
0
def pypower_loop (casefile, rootname):
  """ Public function to start PYPOWER solutions under control of FNCS

  The time step, maximum time, and other data must be set up in a JSON file.
  This function will run the case under FNCS, manage the FNCS message traffic,
  and shutdown FNCS upon completion. Five files are written:

  - *rootname.csv*; intermediate solution results during simulation
  - *rootname_m_dict.json*; metadata for post-processing
  - *bus_rootname_metrics.json*; bus metrics for GridLAB-D connections, upon completion
  - *gen_rootname_metrics.json*; bulk system generator metrics, upon completion
  - *sys_rootname_metrics.json*; bulk system-level metrics, upon completion

  Args:
    casefile (str): the configuring JSON file name, without extension
    rootname (str): the root filename for metrics output, without extension
  """
#  if len(sys.argv) == 3:
#    rootname = sys.argv[1]
#    casefile = sys.argv[2]
#  else:
#    print ('usage: python fncsPYPOWER.py metrics_rootname casedata.json')
#    sys.exit()

  ppc = load_json_case (casefile)
  StartTime = ppc['StartTime']
  tmax = int(ppc['Tmax'])
  period = int(ppc['Period'])
  dt = int(ppc['dt'])
  make_dictionary (ppc, rootname)

  bus_mp = open ("bus_" + rootname + "_metrics.json", "w")
  gen_mp = open ("gen_" + rootname + "_metrics.json", "w")
  sys_mp = open ("sys_" + rootname + "_metrics.json", "w")
  bus_meta = {'LMP_P':{'units':'USD/kwh','index':0},'LMP_Q':{'units':'USD/kvarh','index':1},
    'PD':{'units':'MW','index':2},'QD':{'units':'MVAR','index':3},'Vang':{'units':'deg','index':4},
    'Vmag':{'units':'pu','index':5},'Vmax':{'units':'pu','index':6},'Vmin':{'units':'pu','index':7}}
  gen_meta = {'Pgen':{'units':'MW','index':0},'Qgen':{'units':'MVAR','index':1},'LMP_P':{'units':'USD/kwh','index':2}}
  sys_meta = {'Ploss':{'units':'MW','index':0},'Converged':{'units':'true/false','index':1}}
  bus_metrics = {'Metadata':bus_meta,'StartTime':StartTime}
  gen_metrics = {'Metadata':gen_meta,'StartTime':StartTime}
  sys_metrics = {'Metadata':sys_meta,'StartTime':StartTime}

  gencost = ppc['gencost']
  fncsBus = ppc['FNCS']
  gen = ppc['gen']
  ppopt_market = pp.ppoption(VERBOSE=0, OUT_ALL=0, PF_DC=ppc['opf_dc'])
  ppopt_regular = pp.ppoption(VERBOSE=0, OUT_ALL=0, PF_DC=ppc['pf_dc'])
  loads = np.loadtxt(ppc['CSVFile'], delimiter=',')

  for row in ppc['UnitsOut']:
    print ('unit  ', row[0], 'off from', row[1], 'to', row[2], flush=True)
  for row in ppc['BranchesOut']:
    print ('branch', row[0], 'out from', row[1], 'to', row[2], flush=True)

  nloads = loads.shape[0]
  ts = 0
  tnext_opf = -dt

  # initializing for metrics collection
  tnext_metrics = 0
  loss_accum = 0
  conv_accum = True
  n_accum = 0
  bus_accum = {}
  gen_accum = {}
  for i in range (fncsBus.shape[0]):
    busnum = int(fncsBus[i,0])
    bus_accum[str(busnum)] = [0,0,0,0,0,0,0,99999.0]
  for i in range (gen.shape[0]):
    gen_accum[str(i+1)] = [0,0,0]

  op = open (rootname + '.csv', 'w')
  print ('t[s],Converged,Pload,P7 (csv),Unresp (opf),P7 (rpf),Resp (opf),GLD Pub,BID?,P7 Min,V7,LMP_P7,LMP_Q7,Pgen1,Pgen2,Pgen3,Pgen4,Pdisp,Deg,c2,c1', file=op, flush=True)
  fncs.initialize()

  # transactive load components
  csv_load = 0     # from the file
  unresp = 0       # unresponsive load estimate from the auction agent
  resp = 0         # will be the responsive load as dispatched by OPF
  resp_deg = 0     # RESPONSIVE_DEG from FNCS
  resp_c1 = 0      # RESPONSIVE_C1 from FNCS
  resp_c2 = 0      # RESPONSIVE_C2 from FNCS
  resp_max = 0     # RESPONSIVE_MAX_MW from FNCS
  feeder_load = 0  # amplified feeder MW

  while ts <= tmax:
    # start by getting the latest inputs from GridLAB-D and the auction
    events = fncs.get_events()
    new_bid = False
    load_scale = float (fncsBus[0][2])
    for topic in events:
      value = fncs.get_value(topic)
      if topic == 'UNRESPONSIVE_MW':
        unresp = load_scale * float(value)
        fncsBus[0][3] = unresp # to poke unresponsive estimate into the bus load slot
        new_bid = True
      elif topic == 'RESPONSIVE_MAX_MW':
        resp_max = load_scale * float(value)
        new_bid = True
      elif topic == 'RESPONSIVE_C2':
        resp_c2 = float(value) / load_scale
        new_bid = True
      elif topic == 'RESPONSIVE_C1':
        resp_c1 = float(value)
        new_bid = True
      elif topic == 'RESPONSIVE_DEG':
        resp_deg = int(value)
        new_bid = True
      else:
        gld_load = parse_mva (value) # actual value, may not match unresp + resp load
        feeder_load = float(gld_load[0]) * load_scale
    if new_bid == True:
      dummy = 2
#      print('**Bid', ts, unresp, resp_max, resp_deg, resp_c2, resp_c1)

    # update the case for bids, outages and CSV loads
    idx = int ((ts + dt) / period) % nloads
    bus = ppc['bus']
    gen = ppc['gen']
    branch = ppc['branch']
    gencost = ppc['gencost']
    csv_load = loads[idx,0]
    bus[4,2] = loads[idx,1]
    bus[8,2] = loads[idx,2]
    # process the generator and branch outages
    for row in ppc['UnitsOut']:
      if ts >= row[1] and ts <= row[2]:
        gen[row[0],7] = 0
      else:
        gen[row[0],7] = 1
    for row in ppc['BranchesOut']:
      if ts >= row[1] and ts <= row[2]:
        branch[row[0],10] = 0
      else:
        branch[row[0],10] = 1

    if resp_deg == 2:
      gencost[4][3] = 3
      gencost[4][4] = -resp_c2
      gencost[4][5] = resp_c1
    elif resp_deg == 1:
      gencost[4][3] = 2
      gencost[4][4] = resp_c1
      gencost[4][5] = 0.0
    else:
      gencost[4][3] = 1
      gencost[4][4] = 999.0
      gencost[4][5] = 0.0
    gencost[4][6] = 0.0

    if ts >= tnext_opf:  # expecting to solve opf one dt before the market clearing period ends, so GridLAB-D has time to use it
      # for OPF, the FNCS bus load is CSV + Unresponsive estimate, with Responsive separately dispatchable
      bus = ppc['bus']
      gen = ppc['gen']
      bus[6,2] = csv_load
      for row in ppc['FNCS']:
        unresp = float(row[3])
        newidx = int(row[0]) - 1
        if unresp >= feeder_load:
          bus[newidx,2] += unresp
        else:
          bus[newidx,2] += feeder_load
      gen[4][9] = -resp_max
      res = pp.runopf(ppc, ppopt_market)
      if res['success'] == False:
        conv_accum = False
      opf_bus = deepcopy (res['bus'])
      opf_gen = deepcopy (res['gen'])
      lmp = opf_bus[6,13]
      resp = -1.0 * opf_gen[4,1]
      fncs.publish('LMP_B7', 0.001 * lmp) # publishing $/kwh
#     print ('  OPF', ts, csv_load, '{:.3f}'.format(unresp), '{:.3f}'.format(resp),
#            '{:.3f}'.format(feeder_load), '{:.3f}'.format(opf_bus[6,2]),
#            '{:.3f}'.format(opf_gen[0,1]), '{:.3f}'.format(opf_gen[1,1]), '{:.3f}'.format(opf_gen[2,1]),
#            '{:.3f}'.format(opf_gen[3,1]), '{:.3f}'.format(opf_gen[4,1]), '{:.3f}'.format(lmp))
      # if unit 2 (the normal swing bus) is dispatched at max, change the swing bus to 9
      if opf_gen[1,1] >= 191.0:
        ppc['bus'][1,1] = 2
        ppc['bus'][8,1] = 3
        print ('  SWING Bus 9')
      else:
        ppc['bus'][1,1] = 3
        ppc['bus'][8,1] = 1
        print ('  SWING Bus 2')
      tnext_opf += period
    
    # always update the electrical quantities with a regular power flow
    bus = ppc['bus']
    gen = ppc['gen']
    bus[6,13] = lmp
    gen[0,1] = opf_gen[0, 1]
    gen[1,1] = opf_gen[1, 1]
    gen[2,1] = opf_gen[2, 1]
    gen[3,1] = opf_gen[3, 1]
    # during regular power flow, we use the actual CSV + feeder load, ignore dispatchable load and use actual
    bus[6,2] = csv_load + feeder_load
    gen[4,1] = 0 # opf_gen[4, 1]
    gen[4,9] = 0
    rpf = pp.runpf(ppc, ppopt_regular)
    if rpf[0]['success'] == False:
      conv_accum = False
    bus = rpf[0]['bus']
    gen = rpf[0]['gen']
    
    Pload = bus[:,2].sum()
    Pgen = gen[:,1].sum()
    Ploss = Pgen - Pload

    # update the metrics
    n_accum += 1
    loss_accum += Ploss
    for i in range (fncsBus.shape[0]):
      busnum = int(fncsBus[i,0])
      busidx = busnum - 1
      row = bus[busidx].tolist()
      # LMP_P, LMP_Q, PD, QD, Vang, Vmag, Vmax, Vmin: row[11] and row[12] are Vmax and Vmin constraints
      PD = row[2] + resp # the ERCOT version shows how to track scaled_resp separately for each FNCS bus
      Vpu = row[7]
      bus_accum[str(busnum)][0] += row[13]*0.001
      bus_accum[str(busnum)][1] += row[14]*0.001
      bus_accum[str(busnum)][2] += PD
      bus_accum[str(busnum)][3] += row[3]
      bus_accum[str(busnum)][4] += row[8]
      bus_accum[str(busnum)][5] += Vpu
      if Vpu > bus_accum[str(busnum)][6]:
        bus_accum[str(busnum)][6] = Vpu
      if Vpu < bus_accum[str(busnum)][7]:
        bus_accum[str(busnum)][7] = Vpu
    for i in range (gen.shape[0]):
      row = gen[i].tolist()
      busidx = int(row[0] - 1)
      # Pgen, Qgen, LMP_P  (includes the responsive load as dispatched by OPF)
      gen_accum[str(i+1)][0] += row[1]
      gen_accum[str(i+1)][1] += row[2]
      gen_accum[str(i+1)][2] += float(opf_bus[busidx,13])*0.001

    # write the metrics
    if ts >= tnext_metrics:
      sys_metrics[str(ts)] = {rootname:[loss_accum / n_accum,conv_accum]}

      bus_metrics[str(ts)] = {}
      for i in range (fncsBus.shape[0]):
        busnum = int(fncsBus[i,0])
        busidx = busnum - 1
        row = bus[busidx].tolist()
        met = bus_accum[str(busnum)]
        bus_metrics[str(ts)][str(busnum)] = [met[0]/n_accum, met[1]/n_accum, met[2]/n_accum, met[3]/n_accum,
                                             met[4]/n_accum, met[5]/n_accum, met[6], met[7]]
        bus_accum[str(busnum)] = [0,0,0,0,0,0,0,99999.0]

      gen_metrics[str(ts)] = {}
      for i in range (gen.shape[0]):
        met = gen_accum[str(i+1)]
        gen_metrics[str(ts)][str(i+1)] = [met[0]/n_accum, met[1]/n_accum, met[2]/n_accum]
        gen_accum[str(i+1)] = [0,0,0]

      tnext_metrics += period
      n_accum = 0
      loss_accum = 0
      conv_accum = True

    volts = 1000.0 * bus[6,7] * bus[6,9] / sqrt(3.0)  # VLN for GridLAB-D
    fncs.publish('three_phase_voltage_B7', volts)

    # CSV file output
    print (ts, res['success'], 
           '{:.3f}'.format(Pload),          # Pload
           '{:.3f}'.format(csv_load),       # P7 (csv)
           '{:.3f}'.format(unresp),         # GLD Unresp
           '{:.3f}'.format(bus[6,2]),       # P7 (rpf)
           '{:.3f}'.format(resp),           # Resp (opf)
           '{:.3f}'.format(feeder_load),    # GLD Pub
           new_bid, 
           '{:.3f}'.format(gen[4,9]),       # P7 Min
           '{:.3f}'.format(bus[6,7]),       # V7
           '{:.3f}'.format(bus[6,13]),      # LMP_P7
           '{:.3f}'.format(bus[6,14]),      # LMP_Q7
           '{:.2f}'.format(gen[0,1]),       # Pgen1
           '{:.2f}'.format(gen[1,1]),       # Pgen2 
           '{:.2f}'.format(gen[2,1]),       # Pgen3
           '{:.2f}'.format(gen[3,1]),       # Pgen4
           '{:.2f}'.format(res['gen'][4, 1]), # Pdisp
           '{:.4f}'.format(resp_deg),       # degree
           '{:.8f}'.format(ppc['gencost'][4, 4]),  # c2
           '{:.8f}'.format(ppc['gencost'][4, 5]),  # c1 
           sep=',', file=op, flush=True)

    # request the next time step, if necessary
    if ts >= tmax:
      print ('breaking out at',ts,flush=True)
      break
    ts = fncs.time_request(min(ts + dt, tmax))

  # ===================================
  print ('writing metrics', flush=True)
  print (json.dumps(sys_metrics), file=sys_mp, flush=True)
  print (json.dumps(bus_metrics), file=bus_mp, flush=True)
  print (json.dumps(gen_metrics), file=gen_mp, flush=True)
  print ('closing files', flush=True)
  bus_mp.close()
  gen_mp.close()
  sys_mp.close()
  op.close()
  print ('finalizing FNCS', flush=True)
  fncs.finalize()

  if sys.platform != 'win32':
    usage = resource.getrusage(resource.RUSAGE_SELF)
    RESOURCES = [
      ('ru_utime', 'User time'),
      ('ru_stime', 'System time'),
      ('ru_maxrss', 'Max. Resident Set Size'),
      ('ru_ixrss', 'Shared Memory Size'),
      ('ru_idrss', 'Unshared Memory Size'),
      ('ru_isrss', 'Stack Size'),
      ('ru_inblock', 'Block inputs'),
      ('ru_oublock', 'Block outputs')]
    print('Resource usage:')
    for name, desc in RESOURCES:
      print('  {:<25} ({:<10}) = {}'.format(desc, name, getattr(usage, name)))
        #############################   Subscribing to Feeder Load from to GridLAB-D ##############################################

        for i in range(0, subkeys_count):
            sub = subid["m{}".format(i)]
            rload, iload = h.helicsInputGetComplex(sub)
        logger.info("Python Federate grantedtime = {}".format(grantedtime))
        logger.info("Load value = {} kW".format(complex(rload, iload) / 1000))
        #print(voltage_plot,real_demand)

        actual_demand = peak_demand * bus_profiles[x, :]
        ppc['bus'][:, 2] = actual_demand
        ppc['bus'][:, 3] = actual_demand * math.tan(math.acos(.85))
        ppc['bus'][cosim_bus, 2] = rload * load_amplification_factor / 1000000
        ppc['bus'][cosim_bus, 3] = iload * load_amplification_factor / 1000000
        ppopt = ppoption(PF_ALG=1)

        print('PF TIme is {} and ACOPF time is {}'.format(
            time_pf[x], time_opf[k]))

        ############################  Running OPF For optimal power flow intervals   ##############################

        if (time_pf[x] == time_opf[k]):
            results_opf = runopf(ppc, ppopt)
            if (results_opf['success']):
                ppc['bus'] = results_opf['bus']
                ppc['gen'] = results_opf['gen']
                if (k == 0):
                    LMP_solved = results_opf['bus'][:, 13]
                else:
                    LMP_solved = numpy.vstack(
Beispiel #27
0
    print('bus #, Pd, Qd, Vm, LMP_P, LMP_Q, MU_VMAX, MU_VMIN')
    for row in bus:
        print(int(row[0]), row[2], row[3], row[7], row[13], row[14], row[15],
              row[16])

    print('gen #, bus, Pg, Qg, MU_PMAX, MU_PMIN, MU_PMAX, MU_PMIN')
    idx = 1
    for row in gen:
        print(idx, int(row[0]), row[1], row[2], row[21], row[22], row[23],
              row[24])
        ++idx


with warnings.catch_warnings():
    ppc = ppcasefile()
    ppopt = pp.ppoption(VERBOSE=0, OUT_ALL=0, PF_DC=1)

    gencost = ppc['gencost']
    bus = ppc['bus']
    gen = ppc['gen']
    fncsBus = ppc['FNCS']
    outage = ppc['UnitsOut'][0]

    bus[4, 2] = 97.124  # column 2, bus loads at 165000 from the TXT file
    bus[8, 2] = 134.89  # column 3
    csv_load = 110.28  # column 1

    #	gen[outage[0],7] = 0 # unit 2 is out

    scale = float(fncsBus[0][2])
    # mimic the FNCS messages coming in at 165000 for MW, prep and scale for OPF
Beispiel #28
0
ppc['branch'][-1, F_BUS] = 30
ppc['branch'][-1, T_BUS] = 33

ppc['branch'] = np.concatenate(
    (ppc['branch'], ppc['branch'][nbrch - 1:nbrch, :]), axis=0)
ppc['branch'][-1, F_BUS] = 22
ppc['branch'][-1, T_BUS] = 32

# from pypower.case24_ieee_rts import case24_ieee_rts
# ppc = case24_ieee_rts()

####
## LF by pypower (Newton-Raphson) using PYPOWER
###
import pypower.api as pypow
ppopt = pypow.ppoption(VERBOSE=0,
                       OUT_ALL=0)  #prevents results printing in each iteration

start_time_LF = timeit.default_timer()

results, success = pypow.runpf(ppc, ppopt=ppopt)  #ppopt=ppopt

time_LF = timeit.default_timer() - start_time_LF

print("\n\t N-R converged in {0} s".format(time_LF))
if not success:
    print("\n powerflow did not converge")

# ####
# Direct load flow solution (a matrix back/fwd sweep)
# ####
start_time = timeit.default_timer()
Beispiel #29
0
        'Ploss': {
            'units': 'MW',
            'index': 0
        },
        'Converged': {
            'units': 'true/false',
            'index': 1
        }
    }
    bus_metrics = {'Metadata': bus_meta, 'StartTime': StartTime}
    gen_metrics = {'Metadata': gen_meta, 'StartTime': StartTime}
    sys_metrics = {'Metadata': sys_meta, 'StartTime': StartTime}

    gencost = ppc['gencost']
    fncsBus = ppc['FNCS']
    ppopt = pp.ppoption(
        VERBOSE=0, OUT_ALL=0)  # TODO - the PF_DC option doesn't seem to work
    loads = np.loadtxt('NonGLDLoad.txt', delimiter=',')

    outage = ppc['UnitsOut'][0]
    print('unit', outage[0], 'off from', outage[1], 'to', outage[2])

    nloads = loads.shape[0]
    ts = 0
    tnext = 0

    op = open(rootname + '.csv', 'w')
    print('t[s],Converged,Pload,P7,V7,LMP_P7,LMP_Q7,Pgen1,Pgen2,Pgen3,Pgen4',
          file=op)
    fncs.initialize()

    #	ts = -dt
Beispiel #30
0
def mainJAPowerFlow(baseMVAName, busName, genName, branchName, splitCharacter,
                    outputBusName, outputBranchName, outputGenName,
                    printOutput, optimal, areasName, genCostName):
    #Variables (by for testing)
    #baseMVAName = "baseMVA.txt"
    #busName = "bus.txt"
    #genName = "gen.txt"
    #branchName = "branch.txt"
    #splitCharacter = ' '
    #outputBusName = "outputBus.txt"
    #outputBranchName = "outputBranch.txt"
    #outputBranchName = "outputGen.txt"
    #printOutput = 0 #printOutput = 0 or 1, 0 for no stdout printed output, 1 if it is wanted. Note that both still output to the text files.
    #optimal = 0 #optimal = 0 or 1, 0 for power flow, 1 for optimal power flow. NOTE: All following inputs are only used in optimal power flow, OPF, analysis (optimal = 1), but some values are still required as inputs, even if they are not used in the event of PF (optimal = 0).
    #areasName = "areas.txt"
    #genCostName = "genCost.txt"

    #Assign ppc
    ppc = readText(baseMVAName, busName, genName, branchName, splitCharacter,
                   optimal, areasName, genCostName)
    #ppc = casetest()

    #Set pf test type
    #ppopt = ppoption(PF_ALG=1) #Includes printing output (of standard pf)
    #ppopt = ppoption(OUT_ALL=0, VERBOSE=0) #These options prevent printing output
    #ppopt = ppoption(PF_ALG=1, OUT_ALL=0, VERBOSE=0)
    if (printOutput == 1):
        ppopt = ppoption(OUT_ALL=1, VERBOSE=1)
    elif (printOutput == 0):
        ppopt = ppoption(OUT_ALL=0, VERBOSE=0)
    else:
        print(
            "printOutput must be 0 or 1, 0 for no stdout printed output, and 1 if that is desired. Both still output to text files."
        )

    #Run pf or opf test
    if (optimal == 0):
        r = runpf(ppc, ppopt)
    elif (optimal == 1):
        r = runopf(ppc, ppopt)
    else:
        print("optimal must be 0 or 1, 0 for pf and 1 for opf.")

    #Now clear the output files (method of writing to them might be altered, so doing this is to be sure
    open(outputBusName, 'w').close()
    open(outputBranchName, 'w').close()
    open(outputGenName, 'w').close()

    #For Optimal Power Flow
    if (optimal == 1):
        #Establish lengths
        busCount = len(r['bus'])
        branchCount = len(r['branch'])
        genCount = len(r['gen'])
        #Find Generator Per Bus Output
        busGenP = numpy.zeros(busCount, dtype=numpy.float)
        busGenQ = numpy.zeros(busCount, dtype=numpy.float)
        f = open(outputGenName, 'w')
        i = 0
        while (i < genCount):
            #For Gen Output
            f.write(
                str(i + 1) + splitCharacter + str(r['gen'][i][1]) +
                splitCharacter + str(r['gen'][i][2]) + '\n')
            #For Bus Output
            busGenP[int(r['gen'][i][0])] += r['gen'][i][1]
            busGenQ[int(r['gen'][i][0])] += r['gen'][i][2]
            i += 1
        f.close()

        #Print Bus Output
        f = open(outputBusName, 'w')
        i = 0
        while (i < busCount):
            f.write(
                str(i + 1) + splitCharacter + str(r['bus'][i][7]) +
                splitCharacter + str(r['bus'][i][8]) + splitCharacter +
                str(busGenP[i]) + splitCharacter + str(busGenQ[i]) +
                splitCharacter + str(r['bus'][i][2]) + splitCharacter +
                str(r['bus'][i][3]) + '\n')
            i += 1
        f.close()

        #Print Branch Output
        f = open(outputBranchName, 'w')
        i = 0
        dic = {}
        while (i < branchCount):
            f.write(
                str(i + 1) + splitCharacter +
                str(absDiff(r['branch'][i][15], r['branch'][i][13])) +
                splitCharacter +
                str(absDiff(r['branch'][i][16], r['branch'][i][14])) + '\n')
            dic[i] = [
                str(absDiff(r['branch'][i][15], r['branch'][i][13])),
                str(absDiff(r['branch'][i][16], r['branch'][i][14]))
            ]
            i += 1
        f.close()
        with open(
                'C:\\Users\\LONG01\\TOMCAT\\webapps\\ROOT\OntoEN\\outputOPF.json',
                'w') as fp:
            json.dump(dic, fp)
    #For Standard Power Flow
    elif (optimal == 0):
        #Establish lengths
        busCount = len(r[0]['bus'])
        branchCount = len(r[0]['branch'])
        #print(branchCount)
        genCount = len(r[0]['gen'])
        #Find Generator Per Bus Output
        busGenP = numpy.zeros(busCount, dtype=numpy.float)
        busGenQ = numpy.zeros(busCount, dtype=numpy.float)
        f = open(outputGenName, 'w')
        i = 0
        while (i < genCount):
            #For Gen Output
            f.write(
                str(i + 1) + splitCharacter + str(r[0]['gen'][i][1]) +
                splitCharacter + str(r[0]['gen'][i][2]) + '\n')
            #For Bus Output
            busGenP[int(r[0]['gen'][i][0])] += r[0]['gen'][i][1]
            busGenQ[int(r[0]['gen'][i][0])] += r[0]['gen'][i][2]
            i += 1
        f.close()

        #Print Bus Output
        f = open(outputBusName, 'w')
        i = 0
        while (i < busCount):
            f.write(
                str(i + 1) + splitCharacter + str(r[0]['bus'][i][7]) +
                splitCharacter + str(r[0]['bus'][i][8]) + splitCharacter +
                str(busGenP[i]) + splitCharacter + str(busGenQ[i]) +
                splitCharacter + str(r[0]['bus'][i][2]) + splitCharacter +
                str(r[0]['bus'][i][3]) + '\n')
            i += 1
        f.close()

        #Print Branch Output
        f = open(outputBranchName, 'w')
        i = 0
        while (i < branchCount):
            #P, Q and S (average)
            PAve = (r[0]['branch'][i][15] + r[0]['branch'][i][13]) / 2.0
            QAve = (r[0]['branch'][i][14] + r[0]['branch'][i][16]) / 2.0
            SAve = numpy.sqrt(((PAve * PAve) + (QAve * QAve)))
            #Print P loss, Q loss, aveP, aveQ and aveS.
            f.write(
                str(i + 1) + splitCharacter +
                str(absDiff(r[0]['branch'][i][15], r[0]['branch'][i][13])) +
                splitCharacter +
                str(absDiff(r[0]['branch'][i][16], r[0]['branch'][i][14])) +
                splitCharacter + str(PAve) + splitCharacter + str(QAve) +
                splitCharacter + str(SAve) + '\n')
            i += 1
        f.close()
    else:
        print("optimal must be 0 or 1, 0 for pf and 1 for opf.")
Beispiel #31
0
"""
Created on Wed Feb 24 15:13:38 2016

@author: saf537
"""

import case14_mod
import pandas as pd
import pypower.api as pypo 
import numpy as np

load_shapes = pd.read_csv('loadShapes1.csv')
sample      = 100*load_shapes.iloc[0][load_shapes.columns[9:]]

ppc0      = case14_mod.case14_mod(busN = 1,dlt = 0, op_change=1) # trivial case: original solutin
ppopt0    = pypo.ppoption(PF_ALG=2,VERBOSE=0, OUT_ALL=0)
r0        = pypo.runpf(ppc0, ppopt0) 
n_trs     = sum(r0[0]['bus'][:,1] == 2)
n_bldgs   = sum(r0[0]['bus'][:,1] == 1)
transfs   = r0[0]['bus'][:,0][r0[0]['bus'][:,1]==2]
bdgs      = r0[0]['bus'][:,0][r0[0]['bus'][:,1]==1]
tm_max    = len(sample)
  # bus 8, power after solution

TS  = np.empty((n_bldgs,n_trs,tm_max))
initial_loads_vec = r0[0]['bus'][:,2]
cont = 0
for i in bdgs:
    tmp = 0
    ini_load = initial_loads_vec[i-1]
    for j in transfs:   
Beispiel #32
0
dlt_vec   = [0.05, -0.05, 0.10, -0.10, 0.50, -0.50]
ppc0      = case14_mod.case14_mod(busN = 1,dlt = 0, op_change=1) # trivial case: original solutin
#ppopt0    = pypo.ppoption(PF_ALG=2, VERBOSE=0,
#                          OUT_ALL      = False,
#                          OUT_ALL_LIM  = False,
#                          OUT_AREA_SUM = False,
#                          OUT_BRANCH   = False,
#                          OUT_BUS      = False,
#                          OUT_GEN      = False,
#                          OUT_LINE_LIM = False,
#                          OUT_PG_LIM   = False,
#                          OUT_QG_LIM   = False,
#                          OUT_SYS_SUM  = False,
#                          OUT_V_LIM    = False) # Careful: have to use Newton Method!!!
ppopt0    = pypo.ppoption(PF_ALG=2, VERBOSE=0, OUT_ALL=0) # Careful: have to use Newton Method!!!
r0        = pypo.runpf(ppc0, ppopt0)       
m1        = r0[0]['gen'][:,2][1:]
p0        = [m1 for i in range(0,8)] 
mtr       = zeros([8,4,len(dlt_vec)]) 

j = 1
for j in range(0,len(dlt_vec)):
    tmp = 0
    for i in range(0,13):        
        if r0[0]['bus'][i,1] == 1:
            ppc          = case14_mod.case14_mod(busN = i,dlt = dlt_vec[j], op_change=1)
            ppopt        = pypo.ppoption(PF_ALG=2, VERBOSE=0, OUT_ALL=0) # Careful: have to use Newton Method!!!
            r            = pypo.runpf(ppc, ppopt)
            #plt.plot(r[0]['bus'][:,2])
            pwr          = r[0]['gen'][:,2][1:] # voltage 7, type 2 
Beispiel #33
0
def parse_options(args, usage, opf=False):
    """Parse command line options.

    @param opf: Include OPF options?
    """
    v = ppver('all')
    parser = OptionParser(
        usage="""usage: %%prog [options] [casedata]

%s

If 'casedata' is provided it specifies the name of the input data file
containing the case data.""" % usage,
        version='PYPOWER (%%prog) Version %s, %s' % (v["Version"], v["Date"])
    )

    parser.add_option("-t", "--test", action="store_true", dest="test",
        default=False, help="run tests and exit")

    parser.add_option("-c", "--testcase", default='case9',
                      choices=list(CASES.keys()),
                      help="built-in test case, choose from: %s" % str(
                          list(CASES.keys()))[1:-1])

    parser.add_option("-o", "--outfile", dest='fname', default='',
        type='string', help="""pretty printed output will be
appended to a file with the name specified. Defaults to stdout.""")

    parser.add_option("-s", "--solvedcase", default='', type='string',
        help="""the solved case will be written
to a case file with the specified name in PYPOWER format. If solvedcase ends
with '.mat' the case is saves  as a MAT-file otherwise it saves it as a Python
file.""")

    ppopt = ppoption()

    if opf:
        opf_options = OptionGroup(parser, 'OPF Options')
        pdipm_options = OptionGroup(parser, 'PDIPM Options')

        opf_options.add_option("-u", "--uopf", action="store_true",
            help="""runs an optimal power flow with the unit-decommitment
heuristic""")

        opf_options.add_option("-r", "--w_res", action="store_true",
            help="""runs an optimal power flow with fixed zonal reserves""")

        add_options(opf_options, OPF_OPTIONS, ppopt)
        add_options(pdipm_options, PDIPM_OPTIONS, ppopt)

        parser.add_option_group(opf_options)
        parser.add_option_group(pdipm_options)
    else:
        pf_options = OptionGroup(parser, 'Power Flow Options')

        add_options(pf_options, PF_OPTIONS, ppopt)

        parser.add_option_group(pf_options)

    output_options = OptionGroup(parser, 'Output Options')

    add_options(output_options, OUTPUT_OPTIONS, ppopt)

    parser.add_option_group(output_options)


    options, args = parser.parse_args(args)

#    casedata, fname, solvedcase = case9(), '', ''  # defaults

    nargs = len(args)
    if nargs > 1:
        stderr.write('Too many arguments')
        parser.print_help()
        sys.exit(2)
    elif nargs == 1:
        casedata = args[0]
    else:
        try:
            casedata = CASES[options.testcase]()
        except KeyError:
            stderr.write("Invalid case choice: %r (choose from %s)\n" % \
                (options.testcase, list(CASES.keys())))
            sys.exit(2)

    return options, casedata, ppopt, options.fname, options.solvedcase
Beispiel #34
0
def mainJAPowerFlow(baseMVAName, busName, genName, branchName, splitCharacter,
                    outputBusName, outputBranchName, outputGenName, optimal,
                    printOutput, areasName, genCostName):
    #Variables (by for testing)
    #baseMVAName = "baseMVA.txt"
    #busName = "bus.txt"
    #genName = "gen.txt"
    #branchName = "branch.txt"
    #splitCharacter = '	'
    #outputBusName = "outputBus.txt"
    #outputBranchName = "outputBranch.txt"
    #outputBranchName = "outputGen.txt"
    #optimal = 0 #optimal = 0 or 1, 0 for power flow, 1 for optimal power flow.
    #printOutput = 0 #printOutput = 0 or 1, 0 for no stdout printed output, 1 if it is wanted. Note that both still output to the text files.
    #areasName = "areas.txt"
    #genCostName = "genCost.txt"

    #Assign ppc
    ppc = readText(baseMVAName, busName, genName, branchName, splitCharacter,
                   optimal, areasName, genCostName)
    #ppc = casetest()

    #Set pf test type
    #ppopt = ppoption(PF_ALG=1) #Includes printing output (of standard pf)
    #ppopt = ppoption(OUT_ALL=0, VERBOSE=0) #These options prevent printing output
    #ppopt = ppoption(PF_ALG=1, OUT_ALL=0, VERBOSE=0)
    if (printOutput == 1):
        ppopt = ppoption(OUT_ALL=1, VERBOSE=1)
    elif (printOutput == 0):
        ppopt = ppoption(OUT_ALL=0, VERBOSE=0)
    else:
        print(
            "printOutput must be 0 or 1, 0 for no stdout printed output, and 1 if that is desired. Both still output to text files."
        )

    #Run pf or opf test
    if (optimal == 0):
        r = runpf(ppc, ppopt)
    elif (optimal == 1):
        r = runopf(ppc, ppopt)
    else:
        print("optimal must be 0 or 1, 0 for pf and 1 for opf.")

    #Now clear the output files (method of writing to them might be altered, so doing this is to be sure
    open(outputBusName, 'w').close()
    open(outputBranchName, 'w').close()
    open(outputGenName, 'w').close()

    #For Optimal Power Flow
    if (optimal == 1):
        #Establish lengths
        busCount = len(r['bus'])
        branchCount = len(r['branch'])
        genCount = len(r['gen'])
        #Find Generator Per Bus Output
        busGenP = numpy.zeros(busCount, dtype=numpy.float)
        busGenQ = numpy.zeros(busCount, dtype=numpy.float)
        f = open(outputGenName, 'w')
        i = 0
        while (i < genCount):
            #For Gen Output
            f.write(
                str(i + 1) + splitCharacter + str(r['gen'][i][1]) +
                splitCharacter + str(r['gen'][i][2]) + '\n')
            #For Bus Output
            busGenP[int(r['gen'][i][0])] += r['gen'][i][1]
            busGenQ[int(r['gen'][i][0])] += r['gen'][i][2]
            i += 1
        f.close()

        #Print Bus Output
        f = open(outputBusName, 'w')
        i = 0
        while (i < busCount):
            f.write(
                str(i + 1) + splitCharacter + str(r['bus'][i][7]) +
                splitCharacter + str(r['bus'][i][8]) + splitCharacter +
                str(busGenP[i]) + splitCharacter + str(busGenQ[i]) +
                splitCharacter + str(r['bus'][i][2]) + splitCharacter +
                str(r['bus'][i][3]) + '\n')
            i += 1
        f.close()

        #Print Branch Output
        f = open(outputBranchName, 'w')
        i = 0
        while (i < branchCount):
            f.write(
                str(i + 1) + splitCharacter +
                str(absDiff(r['branch'][i][15], r['branch'][i][13])) +
                splitCharacter +
                str(absDiff(r['branch'][i][16], r['branch'][i][14])) + '\n')
            i += 1
        f.close()

    #For Standard Power Flow
    elif (optimal == 0):
        #Establish lengths
        busCount = len(r[0]['bus'])
        branchCount = len(r[0]['branch'])
        #print(branchCount)
        genCount = len(r[0]['gen'])
        #Find Generator Per Bus Output
        busGenP = numpy.zeros(busCount, dtype=numpy.float)
        busGenQ = numpy.zeros(busCount, dtype=numpy.float)
        f = open(outputGenName, 'w')
        i = 0
        while (i < genCount):
            #For Gen Output
            f.write(
                str(i + 1) + splitCharacter + str(r[0]['gen'][i][1]) +
                splitCharacter + str(r[0]['gen'][i][2]) + '\n')
            #For Bus Output
            busGenP[int(r[0]['gen'][i][0])] += r[0]['gen'][i][1]
            busGenQ[int(r[0]['gen'][i][0])] += r[0]['gen'][i][2]
            i += 1
        f.close()

        #Print Bus Output
        f = open(outputBusName, 'w')
        i = 0
        while (i < busCount):
            f.write(
                str(i + 1) + splitCharacter + str(r[0]['bus'][i][7]) +
                splitCharacter + str(r[0]['bus'][i][8]) + splitCharacter +
                str(busGenP[i]) + splitCharacter + str(busGenQ[i]) +
                splitCharacter + str(r[0]['bus'][i][2]) + splitCharacter +
                str(r[0]['bus'][i][3]) + '\n')
            i += 1
        f.close()

        #Print Branch Output
        f = open(outputBranchName, 'w')
        i = 0
        while (i < branchCount):
            f.write(
                str(i + 1) + splitCharacter +
                str(absDiff(r[0]['branch'][i][15], r[0]['branch'][i][13])) +
                splitCharacter +
                str(absDiff(r[0]['branch'][i][16], r[0]['branch'][i][14])) +
                '\n')
            i += 1
        f.close()
    else:
        print("optimal must be 0 or 1, 0 for pf and 1 for opf.")
Beispiel #35
0
    def _get_param(self):

        # delect the disturbances not defined in the set_disturb, and renumber the new disturbance set.
        for d_type in {1, 2, 3, 4}:
            i_d_all = list()
            for i_d in range(len(self.casedata['disturbance'][d_type])):
                if (d_type, self.casedata['disturbance'][d_type][i_d, 0]
                    ) in self.set_disturb:
                    i_d_all.append(i_d)
            self.casedata['disturbance'][d_type] = self.casedata[
                'disturbance'][d_type][i_d_all, :]
            for i_d in range(len(self.casedata['disturbance'][d_type])):
                self.casedata['disturbance'][d_type][i_d, 0] = i_d + 1
            if len(self.casedata['disturbance'][d_type]) == 0:
                del self.casedata['disturbance'][d_type]

        # parameters
        if len(self.casedata['bus']) >= 200 or len(self.casedata['bus']) == 59:
            opt = ppoption(PF_TOL=1e-12, PF_MAX_IT=20)
        else:
            opt = ppoption(PF_TOL=1e-13, PF_MAX_IT=20)
        s_pf = runpf(self.casedata, opt)

        pcc_y = ext2int(self.casedata)
        Ybus = makeYbus(pcc_y["baseMVA"], pcc_y["bus"],
                        pcc_y["branch"])[0].toarray()
        n_bus = len(Ybus)
        B_0 = np.imag(Ybus)
        for i in range(len(B_0)):
            B_0[i, i] = 0
        pg_0 = np.zeros(n_bus)
        pg_0[(s_pf[0]['gen'][:, 0] - 1).astype(int)] = s_pf[0]['gen'][:, 1]
        i_gen = self.casedata['gen'][:, 0].astype(int).tolist()
        i_non_0 = (np.where(self.casedata['bus'][:, 2] == 0)[0] + 1).tolist()
        i_non = list(set(i_non_0).difference(set(i_gen)))
        i_load_0 = list(
            set(self.casedata['bus'][:, 0].astype(int).tolist()).difference(
                set(i_gen)))
        i_load = list(set(i_load_0).difference(set(i_non)))

        self.Ybus = Ybus
        self.n_bus = n_bus
        self.B_0 = B_0
        self.v_0 = s_pf[0]['bus'][:, 7]
        self.theta_0 = np.radians(s_pf[0]['bus'][:, 8])
        self.pl_0 = s_pf[0]['bus'][:, 2] / 100.0
        self.pg_0 = pg_0 / 100.0
        self.w_0 = np.zeros(self.n_bus)

        self.i_gen = i_gen
        self.i_non = i_non
        self.i_load = i_load
        self.i_gl = i_gen + i_load
        self.i_all = self.casedata['bus'][:, 0].astype(int).tolist()

        self.theta_gl_0 = self.theta_0[(np.array(self.i_gl) - 1).tolist()]

        # initial values and bounds of optimization variables
        self.m_0, self.m_l, self.m_u = dict(), dict(), dict()
        self.d_0, self.d_l, self.d_u = dict(), dict(), dict()
        self.M = self.casedata['bus'][:, 13].tolist()
        self.D = self.casedata['bus'][:, 14].tolist()

        for i in self.i_gen:
            i_gc = np.where(self.casedata['gencontrol'][:, 0] == i)[0]
            i_bus = np.where(self.casedata['bus'][:, 0] == i)[0][0]
            self.m_0[i] = self.M[i_bus]
            self.m_l[i] = self.casedata['gencontrol'][i_gc, 2][0]
            self.m_u[i] = self.casedata['gencontrol'][i_gc, 3][0]
            self.d_0[i] = self.D[i_bus]
            self.d_l[i] = self.casedata['gencontrol'][i_gc, 4][0]
            self.d_u[i] = self.casedata['gencontrol'][i_gc, 5][0]

        # set of index for each kind of branch, used for computing the objective function
        self.ind_branch = list(
        )  # index set [(ind_bus_from, ind_bus_to)] of all branch
        for i_b in self.casedata['branch'][:, [0, 1]]:
            self.ind_branch.append((int(i_b[0]), int(i_b[1])))

        set_k_i = list()  # list of (k,i) of all disturbances and time elements
        for k0 in self.casedata['disturbance'].keys():
            if k0 != 9:
                for k1 in self.casedata['disturbance'][k0][:, 0]:
                    for i in range(
                            1,
                            self.casedata['param_disc']['time_ele'][k0] + 1):
                        set_k_i.append(((int(k0), int(k1)), i))
        self.set_k_i = set_k_i
Beispiel #36
0
def mainJAPowerFlow(baseMVAName, busName, genName, branchName, splitCharacter,
                    outputBusName, outputBranchName, outputGenName,
                    printOutput, optimal, areasName, genCostName):
    # Variables (by for testing)
    # baseMVAName = "baseMVA.txt"
    # busName = "bus.txt"
    # genName = "gen.txt"
    # branchName = "branch.txt"
    # splitCharacter = '    '
    # outputBusName = "outputBus.txt"
    # outputBranchName = "outputBranch.txt"
    # outputBranchName = "outputGen.txt"

    # printOutput = 0
    ##### printOutput = 0 or 1, 0 for no stdout printed output, 1 if it is wanted.
    ##### Note that both still output to the text files.

    # optimal = 0
    ##### optimal = 0 or 1, 0 for power flow, 1 for optimal power flow.
    ##### NOTE: All following inputs are only used in optimal power flow, OPF, analysis (optimal = 1),
    ##### but some values are still required as inputs, even if they are not used in the event of PF (optimal = 0).

    # areasName = "areas.txt"
    # genCostName = "genCost.txt"

    # Assign ppc
    ppc = readText(baseMVAName, busName, genName, branchName, splitCharacter,
                   optimal, areasName, genCostName)
    #ppc = casetest()

    # Set pf test type
    # ppopt = ppoption(PF_ALG=1)                ---> Power Flow algorithm: 1- NR Method
    # ppopt = ppoption(OUT_ALL=0, VERBOSE=0)    ---> These options prevent printing output
    # ppopt = ppoption(PF_ALG=1, OUT_ALL=0, VERBOSE=0)

    if (printOutput == 1):
        ppopt = ppoption(OUT_ALL=1, VERBOSE=1)
    elif (printOutput == 0):
        ppopt = ppoption(OUT_ALL=0, VERBOSE=0)
    else:
        print(
            "printOutput must be 0 or 1, 0 for no stdout printed output, and 1 if that is desired. Both still output to text files."
        )

    # (A) --pf_alg = PF_ALG  # power flow algorithm :
    # 1 - Newton’s method,
    # 2 - FastDecoupled (XB version),
    # 3 - Fast-Decoupled (BX
    # version),
    # 4 - Gauss Seidel
    # [default: 1]

    # (B) --verbose = VERBOSE # amount of progress info printed:
    # 0 - print no progress info,
    # 1 - print a little progress info,
    # 2 - print a lot of progress info,
    # 3 - print all progress info
    # [default: 1]

    # (C) --out_all = OUT_ALL # controls printing of results:
    # -1 - individual flags control what prints,
    # 0 - don’t print anything
    # (overrides individual flags, except OUT_RAW),
    # 1 - print everything (overrides individual flags, except OUT_RAW)
    # [default: -1]

    # Run pf or opf test
    if (optimal == 0):
        r = runpf(ppc, ppopt)
    elif (optimal == 1):
        r = runopf(ppc, ppopt)
    else:
        print("optimal must be 0 or 1, 0 for pf and 1 for opf.")

# Check if voltage constraints are met?
# Check if solution converged?
    if (optimal == 1):

        genCount = len(r['gen'])  #check no. of generators = 16
        busCount = len(r['bus'])  #check no. of buses = 15
        branchCount = len(r['branch'])  #check no. of branches = 25

        print("\nNo. of gen= ", genCount)
        print("\nbus= ", busCount)
        print("\nbranch=", branchCount)

        busGenP = numpy.zeros(
            genCount, dtype=numpy.float
        )  #create a zero column vector (16x1) for P generation
        busLoadP = numpy.zeros(
            busCount,
            dtype=numpy.float)  #create a zero column vector (15x1) for P load
        branchLoss = numpy.zeros(
            branchCount, dtype=numpy.float
        )  #create a zero column vector (25x1) for branch losses

        i = 0
        while (i < genCount):

            #busGenP[int(r['gen'][i][1])] += r['gen'][i][1]
            busGenP[i] += r['gen'][i][1]
            i += 1

        j = 0
        while (j < busCount):
            busLoadP[j] += r['bus'][j][2]
            j += 1
        k = 0
        while (k < branchCount):
            branchLoss[k] += absDiff(r['branch'][k][15], r['branch'][k][13])
            k += 1

        # print("\nReal power generated= \n",busGenP)
        # print("\nReal power demand= \n", busLoadP)
        # print ("\nBranch Losses= \n", branchLoss)

        sumGen = round(busGenP.sum(), 2)  # round off up to 2 decimal points.
        sumLoad = round(busLoadP.sum(), 2)
        sumLoss = round(branchLoss.sum(), 2)

        print("\n")

        print("\nTotal Real Power Generation= ", sumGen)
        print("\nTotal Real Power Load= ", sumLoad)
        print("\nTotal Real Power Losses= ", sumLoss)
        print("\n")

        # Clears the output files (method of writing to them might be altered, so doing this is to be sure
        open(outputBusName, 'w').close()
        open(outputBranchName, 'w').close()
        open(outputGenName, 'w').close()

        # For Optimal Power Flow

        #Establish lengths
        busCount = len(r['bus'])
        branchCount = len(r['branch'])
        genCount = len(r['gen'])
        #Find Generator Per Bus Output
        busGenP = numpy.zeros(busCount, dtype=numpy.float)
        busGenQ = numpy.zeros(busCount, dtype=numpy.float)
        f = open(outputGenName, 'w')
        i = 0
        while (i < genCount):
            #Print Gen Output
            f.write(
                str(i + 1) + splitCharacter + str(r['gen'][i][1]) +
                splitCharacter + str(r['gen'][i][2]) + '\n')
            #For Bus Output --> assign values for busGenP and busGenQ
            busGenP[int(r['gen'][i][0])] += r['gen'][i][1]
            busGenQ[int(r['gen'][i][0])] += r['gen'][i][2]
            i += 1
        f.close()
        #Print Bus Output
        f = open(outputBusName, 'w')
        i = 0
        while (i < busCount):
            f.write(
                str(i + 1) + splitCharacter + str(r['bus'][i][7]) +
                splitCharacter + str(r['bus'][i][8]) + splitCharacter +
                str(busGenP[i]) + splitCharacter + str(busGenQ[i]) +
                splitCharacter + str(r['bus'][i][2]) + splitCharacter +
                str(r['bus'][i][3]) + '\n')
            i += 1
        f.close()
        #Print Branch Output
        f = open(outputBranchName, 'w')
        i = 0
        while (i < branchCount):
            #P, Q and S (average)
            PAve = (r['branch'][i][15] + r['branch'][i][13]) / 2.0
            QAve = (r['branch'][i][14] + r['branch'][i][16]) / 2.0
            SAve = numpy.sqrt(((PAve * PAve) + (QAve * QAve)))
            f.write(
                str(i + 1) + splitCharacter +
                str(absDiff(r['branch'][i][15], r['branch'][i][13])) +
                splitCharacter +
                str(absDiff(r['branch'][i][16], r['branch'][i][14])) +
                splitCharacter + str(PAve) + splitCharacter + str(QAve) +
                splitCharacter + str(SAve) + '\n')
            i += 1
        f.close()
def test_pypower_case():

    #ppopt is a dictionary with the details of the optimization routine to run
    ppopt = ppoption(PF_ALG=2)

    #choose DC or AC
    ppopt["PF_DC"] = False

    #ppc is a dictionary with details about the network, including baseMVA, branches and generators
    ppc = case()

    results,success = runpf(ppc, ppopt)

    #store results in a DataFrame for easy access
    results_df = {}

    #branches
    columns = 'bus0, bus1, r, x, b, rateA, rateB, rateC, ratio, angle, status, angmin, angmax, p0, q0, p1, q1'.split(", ")
    results_df['branch'] = pd.DataFrame(data=results["branch"],columns=columns)

    #buses
    columns = ["bus","type","Pd","Qd","Gs","Bs","area","v_mag_pu","v_ang","v_nom","zone","Vmax","Vmin"]
    results_df['bus'] = pd.DataFrame(data=results["bus"],columns=columns,index=results["bus"][:,0])

    #generators
    columns = "bus, p, q, q_max, q_min, Vg, mBase, status, p_max, p_min, Pc1, Pc2, Qc1min, Qc1max, Qc2min, Qc2max, ramp_agc, ramp_10, ramp_30, ramp_q, apf".split(", ")
    results_df['gen'] = pd.DataFrame(data=results["gen"],columns=columns)



    #now compute in PyPSA

    network = pypsa.Network()
    network.import_from_pypower_ppc(ppc)

    #PYPOWER uses PI model for transformers, whereas PyPSA defaults to
    #T since version 0.8.0
    network.transformers.model = "pi"

    network.pf()

    #compare branch flows
    for c in network.iterate_components(pypsa.components.passive_branch_components):
        for si in ["p0","p1","q0","q1"]:
            si_pypsa = getattr(c.pnl,si).loc["now"].values
            si_pypower = results_df['branch'][si][c.df.original_index].values
            np.testing.assert_array_almost_equal(si_pypsa,si_pypower)


    #compare generator dispatch
    for s in ["p","q"]:
        s_pypsa = getattr(network.generators_t,s).loc["now"].values
        s_pypower = results_df["gen"][s].values
        np.testing.assert_array_almost_equal(s_pypsa,s_pypower)


    #compare voltages
    v_mag_pypsa = network.buses_t.v_mag_pu.loc["now"]
    v_mag_pypower = results_df["bus"]["v_mag_pu"]

    np.testing.assert_array_almost_equal(v_mag_pypsa,v_mag_pypower)

    v_ang_pypsa = network.buses_t.v_ang.loc["now"]
    pypower_slack_angle = results_df["bus"]["v_ang"][results_df["bus"]["type"] == 3].values[0]
    v_ang_pypower = (results_df["bus"]["v_ang"] - pypower_slack_angle)*np.pi/180.

    np.testing.assert_array_almost_equal(v_ang_pypsa,v_ang_pypower)
Beispiel #38
0
def test_pypower_case():

    #ppopt is a dictionary with the details of the optimization routine to run
    ppopt = ppoption(PF_ALG=2)

    #choose DC or AC
    ppopt["PF_DC"] = False

    #ppc is a dictionary with details about the network, including baseMVA, branches and generators
    ppc = case()

    results, success = runpf(ppc, ppopt)

    #store results in a DataFrame for easy access
    results_df = {}

    #branches
    columns = 'bus0, bus1, r, x, b, rateA, rateB, rateC, ratio, angle, status, angmin, angmax, p0, q0, p1, q1'.split(
        ", ")
    results_df['branch'] = pd.DataFrame(data=results["branch"],
                                        columns=columns)

    #buses
    columns = [
        "bus", "type", "Pd", "Qd", "Gs", "Bs", "area", "v_mag_pu", "v_ang",
        "v_nom", "zone", "Vmax", "Vmin"
    ]
    results_df['bus'] = pd.DataFrame(data=results["bus"],
                                     columns=columns,
                                     index=results["bus"][:, 0])

    #generators
    columns = "bus, p, q, q_max, q_min, Vg, mBase, status, p_max, p_min, Pc1, Pc2, Qc1min, Qc1max, Qc2min, Qc2max, ramp_agc, ramp_10, ramp_30, ramp_q, apf".split(
        ", ")
    results_df['gen'] = pd.DataFrame(data=results["gen"], columns=columns)

    #now compute in PyPSA

    network = pypsa.Network()
    network.import_from_pypower_ppc(ppc)

    #PYPOWER uses PI model for transformers, whereas PyPSA defaults to
    #T since version 0.8.0
    network.transformers.model = "pi"

    network.pf()

    #compare branch flows
    for c in network.iterate_components(network.passive_branch_components):
        for si in ["p0", "p1", "q0", "q1"]:
            si_pypsa = getattr(c.pnl, si).loc["now"].values
            si_pypower = results_df['branch'][si][c.df.original_index].values
            equal(si_pypsa, si_pypower)

    #compare generator dispatch
    for s in ["p", "q"]:
        s_pypsa = getattr(network.generators_t, s).loc["now"].values
        s_pypower = results_df["gen"][s].values
        equal(s_pypsa, s_pypower)

    #compare voltages
    v_mag_pypsa = network.buses_t.v_mag_pu.loc["now"]
    v_mag_pypower = results_df["bus"]["v_mag_pu"]

    equal(v_mag_pypsa, v_mag_pypower)

    v_ang_pypsa = network.buses_t.v_ang.loc["now"]
    pypower_slack_angle = results_df["bus"]["v_ang"][results_df["bus"]["type"]
                                                     == 3].values[0]
    v_ang_pypower = (results_df["bus"]["v_ang"] -
                     pypower_slack_angle) * np.pi / 180.

    equal(v_ang_pypsa, v_ang_pypower)
Beispiel #39
0
def solveOpf(caseName, config):
    bxObj = ptbx.InitCases(caseName)
    sysN, sysopt = opf_args.opf_args2(bxObj.System)
    sysopt = pyp.ppoption(sysopt, VERBOSE=3)
    results = pyp.runopf(bxObj.System, sysopt)
    print("Success")
Beispiel #40
0
def parse_options(args, usage, opf=False):
    """Parse command line options.

    @param opf: Include OPF options?
    """
    v = ppver('all')
    parser = OptionParser(
        usage="""usage: %%prog [options] [casedata]

%s

If 'casedata' is provided it specifies the name of the input data file
containing the case data.""" % usage,
        version='PYPOWER (%%prog) Version %s, %s' % (v["Version"], v["Date"])
    )

    parser.add_option("-t", "--test", action="store_true", dest="test",
        default=False, help="run tests and exit")

    parser.add_option("-c", "--testcase", default='case9', choices=CASES.keys(),
        help="built-in test case, choose from: %s" % str(CASES.keys())[1:-1])

    parser.add_option("-o", "--outfile", dest='fname', default='',
        type='string', help="""pretty printed output will be
appended to a file with the name specified. Defaults to stdout.""")

    parser.add_option("-s", "--solvedcase", default='', type='string',
        help="""the solved case will be written
to a case file with the specified name in PYPOWER format. If solvedcase ends
with '.mat' the case is saves  as a MAT-file otherwise it saves it as a Python
file.""")

    ppopt = ppoption()

    if opf:
        opf_options = OptionGroup(parser, 'OPF Options')
        pdipm_options = OptionGroup(parser, 'PDIPM Options')

        opf_options.add_option("-u", "--uopf", action="store_true",
            help="""runs an optimal power flow with the unit-decommitment
heuristic""")

        opf_options.add_option("-r", "--w_res", action="store_true",
            help="""runs an optimal power flow with fixed zonal reserves""")

        add_options(opf_options, OPF_OPTIONS, ppopt)
        add_options(pdipm_options, PDIPM_OPTIONS, ppopt)

        parser.add_option_group(opf_options)
        parser.add_option_group(pdipm_options)
    else:
        pf_options = OptionGroup(parser, 'Power Flow Options')

        add_options(pf_options, PF_OPTIONS, ppopt)

        parser.add_option_group(pf_options)

    output_options = OptionGroup(parser, 'Output Options')

    add_options(output_options, OUTPUT_OPTIONS, ppopt)

    parser.add_option_group(output_options)


    options, args = parser.parse_args(args)

#    casedata, fname, solvedcase = case9(), '', ''  # defaults

    nargs = len(args)
    if nargs > 1:
        stderr.write('Too many arguments')
        parser.print_help()
        sys.exit(2)
    elif nargs == 1:
        casedata = args[0]
    else:
        try:
            casedata = CASES[options.testcase]()
        except KeyError:
            stderr.write("Invalid case choice: %r (choose from %s)\n" % \
                (options.testcase, CASES.keys()))
            sys.exit(2)

    return options, casedata, ppopt, options.fname, options.solvedcase
Beispiel #41
0
def main_loop():
    if len(sys.argv) == 2:
        rootname = sys.argv[1]
    else:
        print('usage: python fncsPYPOWER.py rootname')
        sys.exit()

    ppc = ppcasefile()
    StartTime = ppc['StartTime']
    tmax = int(ppc['Tmax'])
    period = int(ppc['Period'])
    dt = int(ppc['dt'])
    make_dictionary(ppc, rootname)

    bus_mp = open("bus_" + rootname + "_metrics.json", "w")
    gen_mp = open("gen_" + rootname + "_metrics.json", "w")
    sys_mp = open("sys_" + rootname + "_metrics.json", "w")
    bus_meta = {
        'LMP_P': {
            'units': 'USD/kwh',
            'index': 0
        },
        'LMP_Q': {
            'units': 'USD/kvarh',
            'index': 1
        },
        'PD': {
            'units': 'MW',
            'index': 2
        },
        'QD': {
            'units': 'MVAR',
            'index': 3
        },
        'Vang': {
            'units': 'deg',
            'index': 4
        },
        'Vmag': {
            'units': 'pu',
            'index': 5
        },
        'Vmax': {
            'units': 'pu',
            'index': 6
        },
        'Vmin': {
            'units': 'pu',
            'index': 7
        }
    }
    gen_meta = {
        'Pgen': {
            'units': 'MW',
            'index': 0
        },
        'Qgen': {
            'units': 'MVAR',
            'index': 1
        },
        'LMP_P': {
            'units': 'USD/kwh',
            'index': 2
        }
    }
    sys_meta = {
        'Ploss': {
            'units': 'MW',
            'index': 0
        },
        'Converged': {
            'units': 'true/false',
            'index': 1
        }
    }
    bus_metrics = {'Metadata': bus_meta, 'StartTime': StartTime}
    gen_metrics = {'Metadata': gen_meta, 'StartTime': StartTime}
    sys_metrics = {'Metadata': sys_meta, 'StartTime': StartTime}

    gencost = ppc['gencost']
    fncsBus = ppc['FNCS']
    ppopt = pp.ppoption(VERBOSE=0, OUT_ALL=0, PF_DC=1)
    loads = np.loadtxt('NonGLDLoad.txt', delimiter=',')

    for row in ppc['UnitsOut']:
        print('unit  ', row[0], 'off from', row[1], 'to', row[2], flush=True)
    for row in ppc['BranchesOut']:
        print('branch', row[0], 'out from', row[1], 'to', row[2], flush=True)

    nloads = loads.shape[0]
    ts = 0
    tnext_opf = -dt

    op = open(rootname + '.csv', 'w')
    print(
        't[s],Converged,Pload,P7 (csv), GLD Unresp, P7 (opf), Resp (opf), GLD Pub, BID?, P7 Min, V7,LMP_P7,LMP_Q7,Pgen1,Pgen2,Pgen3,Pgen4,Pdisp, gencost2, gencost1, gencost0',
        file=op,
        flush=True)
    # print ('t[s], ppc-Pd5, ppc-Pd9, ppc-Pd7, bus-Pd7, ppc-Pg1, gen-Pg1, ppc-Pg2, gen-Pg2, ppc-Pg3, gen-Pg3, ppc-Pg4, gen-Pg4, ppc-Pg5, gen-Pg5, ppc-Cost2, gencost-Cost2, ppc-Cost1, gencost-Cost1, ppc-Cost0, gencost-Cost0', file=op, flush=True)
    fncs.initialize()

    # transactive load components
    csv_load = 0
    scaled_unresp = 0
    scaled_resp = 0
    resp_c0 = 0
    resp_c1 = 0
    resp_c2 = 0
    resp_max = 0
    gld_load = 0  # this is the actual
    # ==================================
    # Laurentiu Marinovici - 2017-12-14
    actual_load = 0
    new_bid = False
    #  saveInd = 0
    #  saveDataDict = {}
    # ===================================

    while ts <= tmax:
        if ts >= tnext_opf:  # expecting to solve opf one dt before the market clearing period ends, so GridLAB-D has time to use it
            idx = int((ts + dt) / period) % nloads
            bus = ppc['bus']
            print(
                '<<<<< ts = {}, ppc-Pd5 = {}, bus-Pd5 = {}, ppc-Pd7 = {}, bus-Pd7 = {}, ppc-Pd9 = {}, bus-Pd9 = {} >>>>>>>'
                .format(ts, ppc["bus"][4, 2], bus[4, 2], ppc["bus"][6, 2],
                        bus[6, 2], ppc["bus"][8, 2], bus[8, 2]))
            gen = ppc['gen']
            branch = ppc['branch']
            gencost = ppc['gencost']
            csv_load = loads[idx, 0]
            bus[4, 2] = loads[idx, 1]
            bus[8, 2] = loads[idx, 2]
            print(
                '<<<<< ts = {}, ppc-Pd5 = {}, bus-Pd5 = {}, ppc-Pd7 = {}, bus-Pd7 = {}, ppc-Pd9 = {}, bus-Pd9 = {} >>>>>>>'
                .format(ts, ppc["bus"][4, 2], bus[4, 2], ppc["bus"][6, 2],
                        bus[6, 2], ppc["bus"][8, 2], bus[8, 2]))
            # process the generator and branch outages
            for row in ppc['UnitsOut']:
                if ts >= row[1] and ts <= row[2]:
                    gen[row[0], 7] = 0
                else:
                    gen[row[0], 7] = 1
            for row in ppc['BranchesOut']:
                if ts >= row[1] and ts <= row[2]:
                    branch[row[0], 10] = 0
                else:
                    branch[row[0], 10] = 1
            bus[6, 2] = csv_load
            # =================================
            # Laurentiu Marinovici - 2017-12-14
            # bus[6,2] = csv_load + actual_load
            # =================================
            for row in ppc['FNCS']:
                scaled_unresp = float(row[2]) * float(row[3])
                newidx = int(row[0]) - 1
                bus[newidx, 2] += scaled_unresp
            print(
                '<<<<< ts = {}, ppc-Pd5 = {}, bus-Pd5 = {}, ppc-Pd7 = {}, bus-Pd7 = {}, ppc-Pd9 = {}, bus-Pd9 = {} >>>>>>>'
                .format(ts, ppc["bus"][4, 2], bus[4, 2], ppc["bus"][6, 2],
                        bus[6, 2], ppc["bus"][8, 2], bus[8, 2]))
            gen[4][9] = -resp_max * float(fncsBus[0][2])
            gencost[4][3] = 3
            gencost[4][4] = resp_c2
            gencost[4][5] = resp_c1
            gencost[4][6] = resp_c0

            # =================================
            # Laurentiu Marinovici - 2017-12-14
            # print('Before running OPF:')
            # print('Disp load/neg gen: Pg = ', gen[4][1], ', Pmax = ', gen[4][8], ', Pmin = ', gen[4][9], ', status = ', gen[4][7])
            # print('Disp load/neg gen cost coefficients: ', gencost[4][4], ', ', gencost[4][5], ', ', gencost[4][6])

            # gen[4, 7] = 1 # turn on dispatchable load
            #ppc['gen'] = gen
            #ppc['bus'] = bus
            #ppc['branch'] = branch
            #ppc['gencost'] = gencost
            # print (ts, ppc["bus"][4, 2], ppc["bus"][8, 2], ppc["bus"][6, 2], bus[6, 2], ppc["gen"][0, 1], gen[0, 1], ppc["gen"][1, 1], gen[1, 1], ppc["gen"][2, 1], gen[2, 1], ppc["gen"][3, 1], gen[3, 1], ppc["gen"][4, 1], gen[4, 1], ppc["gencost"][4, 4], gencost[4, 4], ppc["gencost"][4, 5], gencost[4, 5], ppc["gencost"][4, 6], gencost[4, 6], sep=',', file=op, flush=True)
            # =====================================================================================================================

            res = pp.runopf(ppc, ppopt)

            # =================================
            # Laurentiu Marinovici - 2017-12-21
            #      mpcKey = 'mpc' + str(saveInd)
            #      resKey = 'res' + str(saveInd)
            #      saveDataDict[mpcKey] = copy.deepcopy(ppc)
            #      saveDataDict[resKey] = copy.deepcopy(res)
            #      saveInd += 1
            # =================================

            bus = res['bus']
            gen = res['gen']
            Pload = bus[:, 2].sum()
            Pgen = gen[:, 1].sum()
            Ploss = Pgen - Pload
            scaled_resp = -1.0 * gen[4, 1]
            # CSV file output
            print(ts,
                  res['success'],
                  '{:.3f}'.format(bus[:, 2].sum()),
                  '{:.3f}'.format(csv_load),
                  '{:.3f}'.format(scaled_unresp),
                  '{:.3f}'.format(bus[6, 2]),
                  '{:.3f}'.format(scaled_resp),
                  '{:.3f}'.format(actual_load),
                  new_bid,
                  '{:.3f}'.format(gen[4, 9]),
                  '{:.3f}'.format(bus[6, 7]),
                  '{:.3f}'.format(bus[6, 13]),
                  '{:.3f}'.format(bus[6, 14]),
                  '{:.2f}'.format(gen[0, 1]),
                  '{:.2f}'.format(gen[1, 1]),
                  '{:.2f}'.format(gen[2, 1]),
                  '{:.2f}'.format(gen[3, 1]),
                  '{:.2f}'.format(res['gen'][4, 1]),
                  '{:.6f}'.format(ppc['gencost'][4, 4]),
                  '{:.4f}'.format(ppc['gencost'][4, 5]),
                  '{:.4f}'.format(ppc['gencost'][4, 6]),
                  sep=',',
                  file=op,
                  flush=True)
            fncs.publish('LMP_B7', 0.001 * bus[6, 13])
            fncs.publish('three_phase_voltage_B7',
                         1000.0 * bus[6, 7] * bus[6, 9])
            print('**OPF', ts, csv_load, scaled_unresp, gen[4][9], scaled_resp,
                  bus[6, 2], 'LMP', 0.001 * bus[6, 13])
            # update the metrics
            sys_metrics[str(ts)] = {rootname: [Ploss, res['success']]}
            bus_metrics[str(ts)] = {}
            for i in range(fncsBus.shape[0]):
                busnum = int(fncsBus[i, 0])
                busidx = busnum - 1
                row = bus[busidx].tolist()
                bus_metrics[str(ts)][str(busnum)] = [
                    row[13] * 0.001, row[14] * 0.001, row[2], row[3], row[8],
                    row[7], row[11], row[12]
                ]
            gen_metrics[str(ts)] = {}
            for i in range(gen.shape[0]):
                row = gen[i].tolist()
                busidx = int(row[0] - 1)
                gen_metrics[str(ts)][str(i + 1)] = [
                    row[1], row[2],
                    float(bus[busidx, 13]) * 0.001
                ]
            tnext_opf += period
            if tnext_opf > tmax:
                print('breaking out at', tnext_opf, flush=True)
                break
        # apart from the OPF, keep loads updated
        ts = fncs.time_request(ts + dt)
        events = fncs.get_events()
        new_bid = False
        for key in events:
            topic = key.decode()
            # ==================================
            # Laurentiu Marinovici - 2017-12-14l
            # print('The event is: ........ ', key)
            # print('The topic is: ........ ', topic)
            # print('The value is: ........ ', fncs.get_value(key).decode())
            # =============================================================
            if topic == 'UNRESPONSIVE_KW':
                unresp_load = 0.001 * float(fncs.get_value(key).decode())
                fncsBus[0][
                    3] = unresp_load  # poke unresponsive estimate into the bus load slot
                new_bid = True
            elif topic == 'RESPONSIVE_MAX_KW':
                resp_max = 0.001 * float(fncs.get_value(key).decode())  # in MW
                new_bid = True
            elif topic == 'RESPONSIVE_M':
                # resp_c2 = 1000.0 * 0.5 * float(fncs.get_value(key).decode())
                resp_c2 = -1e6 * float(fncs.get_value(key).decode())
                new_bid = True
            elif topic == 'RESPONSIVE_B':
                # resp_c1 = 1000.0 * float(fncs.get_value(key).decode())
                resp_c1 = 1e3 * float(fncs.get_value(key).decode())
                new_bid = True
            # ============================================
            # Laurentiu Marinovici
            elif topic == 'RESPONSIVE_BB':
                resp_c0 = -float(fncs.get_value(key).decode())
                new_bid = True
            # ============================================
            elif topic == 'UNRESPONSIVE_PRICE':  # not actually used
                unresp_price = float(fncs.get_value(key).decode())
                new_bid = True
            else:
                gld_load = parse_mva(fncs.get_value(key).decode(
                ))  # actual value, may not match unresp + resp load
                # ==================================
                # Laurentiu Marinovici - 2017-12-14
                # print('GLD real = ', float(gld_load[0]), '; GLD imag = ', float(gld_load[1]))
                # print('Amp factor = ', float(fncsBus[0][2]))
                # ==================================================================
                actual_load = float(gld_load[0]) * float(fncsBus[0][2])
                print('  Time = ', ts, '; actual load real = ', actual_load)
        if new_bid == True:
            print('**Bid', ts, unresp_load, resp_max, resp_c2, resp_c1,
                  resp_c0)

    # Laurentiu Marinovici - 2017-12-21


#  spio.savemat('matFile.mat', saveDataDict)
# ===================================
    print('writing metrics', flush=True)
    print(json.dumps(bus_metrics), file=bus_mp, flush=True)
    print(json.dumps(gen_metrics), file=gen_mp, flush=True)
    print(json.dumps(sys_metrics), file=sys_mp, flush=True)
    print('closing files', flush=True)
    bus_mp.close()
    gen_mp.close()
    sys_mp.close()
    op.close()
    print('finalizing FNCS', flush=True)
    fncs.finalize()