Ask Your Question
2

Will this generate a QV curve?

asked 2012-07-14 12:28:29 -0600

amaity gravatar image

Hi All!

Please correct/improve this QV curve generating script.

# PSS/E Saved case
CASE = r"C:\Program Files\PTI\PSSE32\EXAMPLE\12TH_PLAN_MAR_2017R1.sav"
psspy.psseinit(12000)
psspy.case(CASE)

def getdata(subsystem_data):
    ierr, values = subsystem_data
    return zip(*values)

#--------------------------------
ierr = psspy.bsys(sid=1, numzone=1, zones=[44])
buses = reduce(tuple.__add__, getdata(psspy.abusint(sid=1, string="NUMBER")))
buskv = reduce(tuple.__add__, getdata(psspy.abusreal(sid=1, string="BASE")))
#print zip(buses, buskv)
selected_buses = []
for bus, voltage in zip(buses, buskv):
    if voltage > 100.0:
        selected_buses.append((bus))
print selected_buses

busno = 44999 # Fictitious generator bus
genid = 1
status = 1
pgen = 0.0 # Fict gen P output
Qlimit = 9999.0 # Fict. gen Q limit
pmax = 0.0 # Fict gen P limit
ireg = 44106 # Regulated bus for which QV curve is to be determined

def add_machine():
    psspy.plant_data(busno, intgar1=ireg)
    psspy.machine_data_2(
        busno,
        str(genid),
        [int(status), 1, 0, 0, 0, 0],
        [pgen, 0.0,
        Qlimit,
        -Qlimit,
        pmax, 0.0, 100.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0])
    return

def get_mvar(i):
    psspy.plant_data(busno, realar1=i)
    psspy.solution_parameters_3(intgar2=60)
    ierr = psspy.fnsl()
    mvar = psspy.macdat(busno, str(genid), 'Q')
    return mvar[1]

psspy.bus_data_2(busno, intgar1=2, name='TEST')
psspy.branch_data(i=busno, j=ireg)
add_machine()

import numpy as np
import matplotlib.pyplot as plt
pu = [x for x in np.arange(.8, 1.2, .05)]
varlist = [get_mvar(v) for v in pu]
print varlist
plt.plot(pu, varlist, '-o')
plt.xlabel('PU')
plt.ylabel('MVar')
plt.grid()
plt.show()
edit retag flag offensive close merge delete

Comments

Nice code, I'll take a look at this soon!

JervisW gravatar imageJervisW ( 2012-07-15 06:41:00 -0600 )edit

3 answers

Sort by ยป oldest newest most voted
1

answered 2012-07-15 12:12:17 -0600

JervisW gravatar image

updated 2012-10-10 18:32:56 -0600

(edit) http://www.youtube.com/watch?v=oveciMGcOt4 Watch this: A live recording of how I rewrote the code

The code looks like it does the job that it advertises. Unfortunately if the case blows up towards the end, you might find that you get some weird looking Q values. Also, because you've arranged the voltages to begin at 0.8 (which is a very low voltage). You may find that it doesn't solve at all and wont produce a Q/V curve except at the strongest buses.

Here are three things I'd do to improve the results you are getting:

  1. Arrange the PU voltages from high to low, rather than from low to high. That way your script will plot more data points before blowing up at the very low voltages.
  2. Check the solution result and stop calculating values once it has blown up.
  3. Split the calculation into two parts. Current PU -> high PU then Current PU -> low PU. This will help you reset the PSSE case so that you can calculate the two parts

Here is a quick attempt at re-writing the code.

# PSS/E Saved case
import numpy as np
import matplotlib.pyplot as plt
import psspy

CASE = r"C:\Program Files\PTI\PSSE32\EXAMPLE\12TH_PLAN_MAR_2017R1.sav"
busno = 44999 # Fictitious generator bus
genid = 1
status = 1
pgen = 0.0 # Fict gen P output
Qlimit = 9999.0 # Fict. gen Q limit
pmax = 0.0 # Fict gen P limit
ireg = 44106 # Regulated bus for which QV curve is to be determined

#--------------------------------

def add_machine():
    psspy.plant_data(busno, intgar1=ireg)
    psspy.machine_data_2(
        busno,
        str(genid),
        intgar1=int(status),
        realar1=pgen,
        realar3=Qlimit,
        realar4=-Qlimit,
        realar5=pmax)

def get_mvar(i):
    """
    Changes the voltage set point at the synchronous machine
    solves the case
    returns the the new reactive power output of the sync machine.
    """
    psspy.plant_data(busno, realar1=i)
    ierr = psspy.fnsl()
    ierr, mvar = psspy.macdat(busno, str(genid), 'Q')
    return mvar

psspy.psseinit(12000)
psspy.case(CASE)
psspy.solution_parameters_3(intgar2=60) # set number of solution iterations.

psspy.bus_data_2(busno, intgar1=2, name='TEST')
psspy.branch_data(i=busno, j=ireg)
add_machine()

pu = [x for x in np.arange(1.2, 0.8, -0.05)]
varlist = [get_mvar(v) for v in pu]

print varlist
plt.plot(pu, varlist, '-o')
plt.xlabel('PU')
plt.ylabel('MVar')
plt.grid()
plt.show()

If I was spending more time on it, i'd even look at ways to pass arguments into add_machine rather than relying on global variables.

edit flag offensive delete link more

Comments

@JervisW is there a way to get the data through the PSSE API?

amaity gravatar imageamaity ( 2012-07-15 20:17:45 -0600 )edit

@amaity yes there is a qv_summary function. It is *very* difficult to use. You first need to create the .mon, .con and .sub files (real files on your computer) which then produce a .dfx file. You then create a .qv file and finally you read this file and get the results. I don't bother.

JervisW gravatar imageJervisW ( 2012-07-15 22:58:06 -0600 )edit

@JervisW I had a hard time trying to make sense of the output obtained from some of the APIs. I guess that is one thing that is lacking in the documentation. By the way, why does psspy.macdat return a tuple of two floats for 'Q'?

amaity gravatar imageamaity ( 2012-07-16 20:18:51 -0600 )edit

@amaity. Agreed, the API in that area is very poorly documented. `ierr, mvar = psspy.macdat(...'Q')` returns an error code, and a float for Q. So it is an integer and a float see http://psspy.org/psse-help-forum/question/90/what-techniques-do-you-use-to-track-down-bugs-in/ for info about ierr

JervisW gravatar imageJervisW ( 2012-07-17 15:34:49 -0600 )edit

I put up ths script for scrutiny to invite feedback on how people obtain a valid solution. This, it seems to me, is the main problem in the above script. In this case the solution has been obtained by increasing the number of iterations. What are the other ways??

amaity gravatar imageamaity ( 2012-07-18 19:41:38 -0600 )edit
0

answered 2017-07-03 15:41:47 -0600

jconto gravatar image

updated 2017-07-03 15:43:12 -0600

Paalang,

The following py code will take very close: https://drive.google.com/open?id=0B7u... [copy the link and download the python file. It is set to use the savnw.sav with sub, con, mon files located at the example folder of the PSSe installation] run it within PSSe 33 (or from a DOS window). It creates a CSV file like:

bus, con, Qmin, Vmin
153,BASE CASE,-329.5418396,0.900000095367
153,TRIP1NUCLEAR,-309.100219727,0.910000085831

Negative values of Qmin represents the bus Q margin, the larger, the better. Positive values of Qmin indicates lack of Q margin at such bus. Vmin is the corresponding V at the Qmin point.

edit flag offensive delete link more

Comments

@jconto I am sorry for the late response. Thank you very much for the code. It was very helpful.

Paalang gravatar imagePaalang ( 2017-07-12 08:26:55 -0600 )edit
0

answered 2017-06-27 10:13:40 -0600

Paalang gravatar image

Hi folks!

I really need to run QV analysis for several buses with contingencies and export all the results for all buses and all contingencies in a spreadsheet as follows,

BUSNumber Contingency MVARReserve VminAtCollapse

There is an script in in forum to generate QV results; but it asks for a governor or something that I did not quit get that. Also, it generates separate workbooks for each bus, that is not my interest. It'd be really appreciated if you can share a python script to generate such a spreadsheet or a similar for me. Thank you.

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

[hide preview]

Question Tools

Stats

Asked: 2012-07-14 12:28:29 -0600

Seen: 4,408 times

Last updated: Jul 03 '17