# select time step ############################################################## ierr = psspy.dynamics_solution_params( [_i, _i, _i, _i, _i, _i, _i, _i], [_f, _f, 0.00833333333333333, _f, _f, _f, _f, _f], 'out_file') # the number here is the time step ################################################################################ ##### select channels ierr = psspy.delete_all_plot_channels() # clear channels BusDataDict = getBusData(rawFile) # get all the bus voltages, angles and frequencies for bus in BusDataDict: bus = int(bus) ierr = psspy.voltage_and_angle_channel([-1, -1, -1, bus]) ierr = psspy.bus_frequency_channel([-1, bus]) print 'Event: {}'.format(event) # get the nominal voltages as well as the fault impedance in ohms FaultBusNomVolt = float(BusDataDict[str(FaultBus)].NominalVolt) Zbase = FaultBusNomVolt**2 / Sbase # float since Sbase is a float Rohm = FaultRpu * Zbase # fault impedance in ohms # run simulation till just before the fault ResultsDict = {} # get the line params line1Elements = linesOutage.split(';')[0].strip() line2Elements = linesOutage.split(';')[1].strip()
def main(): try: ''' Drives a PSS/E Dynamic simulation and returns values ''' ##### Get everything set up on the PSSE side redirect.psse2py() #output = StringIO.StringIO() with silence(): psspy.psseinit(buses=80000) _i = psspy.getdefaultint() _f = psspy.getdefaultreal() _s = psspy.getdefaultchar() """ # Redirect any psse outputs to psse_log psspy.report_output(2,psse_log,[0,0]) psspy.progress_output(2,psse_log,[0,0]) #ignored psspy.alert_output(2,psse_log,[0,0]) #ignored psspy.prompt_output(2,psse_log,[0,0]) #ignored """ k = 1 for rawFile in RawFileList: # get the percentage loading from the raw file name if rawFile == 'savnw_conp.raw': PL = '100' else: rawFileName = rawFile.replace('.raw', '') PL = rawFileName[-3:] #Parameters. CONFIGURE THIS settings = { # use the same raw data in PSS/E and TS3ph ##################################### 'filename': rawFile, #use the same raw data in PSS/E and TS3ph ################################################################################ 'dyr_file': dyrFile, 'out_file': 'output2.out', 'pf_options': [ 0, #disable taps 0, #disable area exchange 0, #disable phase-shift 0, #disable dc-tap 0, #disable switched shunts 0, #do not flat start 0, #apply var limits immediately 0, #disable non-div solution ] } ##### Load Raw Datafile and do power flow print "\n Reading raw file:", settings['filename'] # " Reading raw file: {0:s}".format('text') FaultRpu = 1e-06 Sbase = 100.0 #FaultBusNomVolt = float(BusDataDict[FaultBus].NominalVolt) #Zbase = FaultBusNomVolt**2/Sbase # float since Sbase is a float #Rohm = FaultRpu*Zbase # fault impedance in ohms ########################## # run nested loops to see if there are any abnormal low voltages simCount = 0 # to keep track of how many simulations are already done croppedHVLineSet = list(HVLineSet) for line1 in croppedHVLineSet: for line2 in croppedHVLineSet: # stability_indicator = 1 # Bus_issues = [] # list of buses where issues (low voltage or high dv_dt) are reported # the lines cannot be the same if line1 == line2: continue # part to ensure there is no duplication of events currentSet = line1 + ';' + line2 currentSetReverse = line2 + ';' + line1 # if case causes topology inconsistencies, continue if currentSet in topology_inconsistent_set or currentSetReverse in topology_inconsistent_set: continue line1Elements = line1.split(',') line2Elements = line2.split(',') # Line 1 params L1Bus1 = int(line1Elements[0]) L1Bus2 = int(line1Elements[1]) L1cktID = line1Elements[2].strip("'").strip() # Line 2 params L2Bus1 = int(line2Elements[0]) L2Bus2 = int(line2Elements[1]) L2cktID = line2Elements[2].strip("'").strip() FaultBusList = [L2Bus1, L2Bus2] # apply faults at both buses for FaultBus in FaultBusList: output = StringIO.StringIO() with silence(): ierr = psspy.read(0, settings['filename']) #This is for the power flow. I'll use the solved case instead ierr = psspy.fnsl(settings['pf_options']) ##### Prepare case for dynamic simulation # Load conversion (multiple-step) psspy.conl(_i, _i, 1, [0, _i], [_f, _f, _f, _f]) # all constant power load to constant current, constant reactive power load to constant admittance # standard practice for dynamic simulations, constant MVA load is not acceptable psspy.conl(1, 1, 2, [_i, _i], [100.0, 0.0, 0.0, 100.0]) psspy.conl(_i, _i, 3, [_i, _i], [_f, _f, _f, _f]) ierr = psspy.cong(0) #converting generators ierr = psspy.ordr( 0 ) #order the network nodes to maintain sparsity ierr = psspy.fact( ) #factorise the network admittance matrix ierr = psspy.tysl(0) #solving the converted case ierr = psspy.dynamicsmode(0) #enter dynamics mode print "\n Reading dyr file:", settings['dyr_file'] ierr = psspy.dyre_new([1, 1, 1, 1], settings['dyr_file']) ierr = psspy.docu(0, 1, [ 0, 3, 1 ]) #print the starting point of state variables # select time step ############################################################## ierr = psspy.dynamics_solution_params( [_i, _i, _i, _i, _i, _i, _i, _i], [ _f, _f, 0.00833333333333333, _f, _f, _f, _f, _f ], 'out_file') # the number here is the time step ################################################################################ ##### select channels ierr = psspy.delete_all_plot_channels( ) # clear channels # get all the bus voltages, angles and frequencies for bus in BusDataDict: bus = int(bus) ierr = psspy.voltage_and_angle_channel( [-1, -1, -1, bus]) ierr = psspy.bus_frequency_channel([-1, bus]) eventStr = PL + '/' + line1 + ';' + line2 + '/F' + str( FaultBus) print 'Event: {}'.format(eventStr) # get the nominal voltages as well as the fault impedance in ohms FaultBusNomVolt = float( BusDataDict[str(FaultBus)].NominalVolt) Zbase = FaultBusNomVolt**2 / Sbase # float since Sbase is a float Rohm = FaultRpu * Zbase # fault impedance in ohms # run simulation till just before the fault ResultsDict = {} #output = StringIO.StringIO() with silence(output): ierr = psspy.strt(0, settings['out_file']) ierr = psspy.run(0, 0.1, 1, 1, 1) ierr = psspy.dist_branch_trip( L1Bus1, L1Bus2, L1cktID) #output = StringIO.StringIO() with silence(output): ierr = psspy.run(0, 0.2, 1, 1, 1) #fault on time outputStr = output.getvalue() if "Network not converged" in outputStr: print 'For ' + eventStr + ':' print 'Network did not converge between branch 1 trip and fault application, skipping...' continue ####### # check for convergence during fault #output = StringIO.StringIO() with silence(output): ierr = psspy.dist_bus_fault( FaultBus, 3, 0.0, [Rohm, 0.0]) ierr = psspy.run(0, 0.3, 1, 1, 1) #fault off time ierr = psspy.dist_clear_fault(1) outputStr = output.getvalue() if "Network not converged" in outputStr: print 'For ' + eventStr + ':' print 'Network did not converge during fault, skipping...' continue # check for convergence between fault clearance and second branch trip #output = StringIO.StringIO() with silence(output): ierr = psspy.run(0, 0.31, 1, 1, 1) #fault off time ierr = psspy.dist_branch_trip( L2Bus1, L2Bus2, L2cktID) ierr = psspy.run(0, 0.35, 1, 1, 1) #fault off time # check for non-convergence #output = StringIO.StringIO() outputStr = output.getvalue() if "Network not converged" in outputStr: print 'For ' + eventStr + ':' print 'Network did not converge between fault clearance and branch 2 trip, skipping...' continue # select run time ############################################################## output = StringIO.StringIO() with silence(output): ierr = psspy.run( 0, 10.0, 1, 1, 1 ) #exit time (second argument is the end time) ################################################################################ # check for non-convergence outputStr = output.getvalue() if "Network not converged" in outputStr: print 'For ' + eventStr + ':' print 'Network did not converge sometime after 2nd branch trip, skipping...' continue outputData = dyntools.CHNF(settings['out_file']) data = outputData.get_data() channelDict = data[ 1] # dictionary where the value is the channel description valueDict = data[ 2] # dictionary where the values are the signal values, keys match that of channelDict tme = valueDict['time'] # get time ResultsDict['time'] = tme for key in channelDict: if key == 'time': continue signalDescr = channelDict[key] words = signalDescr.split() signalType = words[0].strip() bus = words[1].strip() #print Bus + ' ' + signalType if bus not in ResultsDict: ResultsDict[bus] = Results() if signalType == 'VOLT': ResultsDict[bus].volt = valueDict[key] elif signalType == 'ANGL': ResultsDict[bus].angle = valueDict[key] elif signalType == 'FREQ': ResultsDict[bus].freq = valueDict[key] EventsDict[eventStr] = ResultsDict simCount += 1 print 'Simulation ' + str(simCount) + ' out of ' + str( totalSims) # Uncomment next two lines if you want to see the output #with open('output'+str(k) + '.txt','w') as f: # f.write(outputStr) k += 1 save_obj(EventsDict, 'EventData') except Exception: traceback.print_exc(file=logfile) sys.exit(0)
psspy.dynamics_solution_param_2([n_iteration, _i, _i, _i, _i, _i, _i, _i], [acceleration, tolerance, integration_step, _f, _f, _f, _f, _f]) psspy.fdns([0, 0, 1, 1, 0, 0, 99, 0]) # convert load , do not change psspy.cong(0) psspy.conl(0, 1, 1, [0, 0], [100.0, 0.0, 0.0, 100.0]) psspy.conl(0, 1, 2, [0, 0], [100.0, 0.0, 0.0, 100.0]) psspy.conl(0, 1, 3, [0, 0], [100.0, 0.0, 0.0, 100.0]) psspy.ordr(0) # ! Order the matrix: ORDR psspy.fact() # ! Factorize the matrix: FACT psspy.tysl(0) # ! TYSL psspy.bus_frequency_channel([1, 969], r"""System frequency""") psspy.voltage_channel([2, -1, -1, 969], r"""IB_Voltage""") psspy.voltage_and_angle_channel([3, -1, -1, 100], [r"""UUT_Voltage""", r"""UUT_Angle"""]) psspy.voltage_and_angle_channel([5, -1, -1, 106], [r"""POC_Voltage""", r"""POC_Angle"""]) psspy.machine_array_channel([7, 2, 100], r"""1""", r"""UUT_Pelec""") psspy.machine_array_channel([8, 3, 100], r"""1""", r"""UUT_Qelec""") psspy.branch_p_and_q_channel([9, -1, -1, 105, 106], r"""1""", [r"""POC_Flow""", ""]) psspy.machine_array_channel([11, 9, 100], r"""1""", r"""UUT_IDcmd""") psspy.machine_array_channel([12, 12, 100], r"""1""", r"""UUT_IQcmd""") psspy.machine_array_channel([13, 8, 100], r"""1""", r"""PPC_Pcmd""") psspy.machine_array_channel([14, 5, 100], r"""1""", r"""PPC_Qcmd""") psspy.strt_2([0, 0], OutputFilePath) psspy.run(0, 1.0, 1000, 5, 5) psspy.two_winding_data_3(bus_flt, bus_IDTRF, r"""1""", realari6=20) psspy.run(0, 6.0, 1000, 5, 5) psspy.two_winding_data_3(bus_flt, bus_IDTRF, r"""1""", realari6=0) psspy.run(0, 11.0, 1000, 5, 5)
def runPSSESimBatches(simList, dyrFile, objName): import sys, os # add psspy to the system path sys.path.append(r"C:\Program Files (x86)\PTI\PSSE33\PSSBIN") os.environ['PATH'] = (r"C:\Program Files (x86)\PTI\PSSE33\PSSBIN;" + os.environ['PATH']) from contextlib import contextmanager import StringIO from getBusDataFn import getBusData @contextmanager def silence(file_object=None): #Discard stdout (i.e. write to null device) or #optionally write to given file-like object. if file_object is None: file_object = open(os.devnull, 'w') old_stdout = sys.stdout try: sys.stdout = file_object yield finally: sys.stdout = old_stdout if file_object is None: file_object.close() # Local imports import redirect import psspy import dyntools # getting the raw file ##### Get everything set up on the PSSE side redirect.psse2py() #output = StringIO.StringIO() with silence(): psspy.psseinit(buses=80000) _i = psspy.getdefaultint() _f = psspy.getdefaultreal() _s = psspy.getdefaultchar() # some important parameters FaultRpu = 1e-06 Sbase = 100.0 EventsDict = {} for event in simList: eventWords = event.split('/') RawFileIndicator = eventWords[0].strip() linesOutage = eventWords[1].strip() FaultBus = eventWords[2].strip()[ 1:] # exclude the 'F' at the beginning # get the raw file if RawFileIndicator == '100': rawFile = 'savnw_conp.raw' else: rawFile = 'savnw_conp{}.raw'.format(RawFileIndicator) #Parameters. CONFIGURE THIS settings = { # use the same raw data in PSS/E and TS3ph ##################################### 'filename': rawFile, #use the same raw data in PSS/E and TS3ph ################################################################################ 'dyr_file': dyrFile, 'out_file': 'output2.out', 'pf_options': [ 0, #disable taps 0, #disable area exchange 0, #disable phase-shift 0, #disable dc-tap 0, #disable switched shunts 0, #do not flat start 0, #apply var limits immediately 0, #disable non-div solution ] } output = StringIO.StringIO() with silence(output): ierr = psspy.read(0, settings['filename']) #This is for the power flow. I'll use the solved case instead ierr = psspy.fnsl(settings['pf_options']) ##### Prepare case for dynamic simulation # Load conversion (multiple-step) psspy.conl(_i, _i, 1, [0, _i], [_f, _f, _f, _f]) # all constant power load to constant current, constant reactive power load to constant admittance # standard practice for dynamic simulations, constant MVA load is not acceptable psspy.conl(1, 1, 2, [_i, _i], [100.0, 0.0, 0.0, 100.0]) psspy.conl(_i, _i, 3, [_i, _i], [_f, _f, _f, _f]) ierr = psspy.cong(0) #converting generators ierr = psspy.ordr(0) #order the network nodes to maintain sparsity ierr = psspy.fact() #factorise the network admittance matrix ierr = psspy.tysl(0) #solving the converted case ierr = psspy.dynamicsmode(0) #enter dynamics mode print "\n Reading dyr file:", settings['dyr_file'] ierr = psspy.dyre_new([1, 1, 1, 1], settings['dyr_file']) ierr = psspy.docu( 0, 1, [0, 3, 1]) #print the starting point of state variables # select time step ############################################################## ierr = psspy.dynamics_solution_params( [_i, _i, _i, _i, _i, _i, _i, _i], [_f, _f, 0.00833333333333333, _f, _f, _f, _f, _f], 'out_file') # the number here is the time step ################################################################################ ##### select channels ierr = psspy.delete_all_plot_channels() # clear channels BusDataDict = getBusData(rawFile) # get all the bus voltages, angles and frequencies for bus in BusDataDict: bus = int(bus) ierr = psspy.voltage_and_angle_channel([-1, -1, -1, bus]) ierr = psspy.bus_frequency_channel([-1, bus]) print 'Event: {}'.format(event) # get the nominal voltages as well as the fault impedance in ohms FaultBusNomVolt = float(BusDataDict[str(FaultBus)].NominalVolt) Zbase = FaultBusNomVolt**2 / Sbase # float since Sbase is a float Rohm = FaultRpu * Zbase # fault impedance in ohms # run simulation till just before the fault ResultsDict = {} # get the line params line1Elements = linesOutage.split(';')[0].strip() line2Elements = linesOutage.split(';')[1].strip() # Line 1 params line1 = line1Elements.split(',') L1Bus1 = int(line1[0].strip()) L1Bus2 = int(line1[1].strip()) L1cktID = line1[2].strip("'").strip() #print L1Bus1 #print L1Bus2 #print L1cktID # Line 2 params line2 = line2Elements.split(',') L2Bus1 = int(line2[0].strip()) L2Bus2 = int(line2[1].strip()) L2cktID = line2[2].strip("'").strip() #print L2Bus1 #print L2Bus2 #print L2cktID #output = StringIO.StringIO() with silence(output): ierr = psspy.strt(0, settings['out_file']) ierr = psspy.run(0, 0.1, 1, 1, 1) ierr = psspy.dist_branch_trip(L1Bus1, L1Bus2, L1cktID) #output = StringIO.StringIO() with silence(output): ierr = psspy.run(0, 0.2, 1, 1, 1) #fault on time outputStr = output.getvalue() if "Network not converged" in outputStr: print 'For ' + event + ':' print 'Network did not converge between branch 1 trip and fault application, skipping...' continue ####### # check for convergence during fault #output = StringIO.StringIO() with silence(output): ierr = psspy.dist_bus_fault(int(FaultBus), 3, 0.0, [Rohm, 0.0]) ierr = psspy.run(0, 0.3, 1, 1, 1) #fault off time ierr = psspy.dist_clear_fault(1) outputStr = output.getvalue() if "Network not converged" in outputStr: print 'For ' + event + ':' print 'Network did not converge during fault, skipping...' continue # check for convergence between fault clearance and second branch trip #output = StringIO.StringIO() with silence(output): ierr = psspy.run(0, 0.31, 1, 1, 1) #fault off time ierr = psspy.dist_branch_trip(L2Bus1, L2Bus2, L2cktID) ierr = psspy.run(0, 0.35, 1, 1, 1) #fault off time # check for non-convergence #output = StringIO.StringIO() outputStr = output.getvalue() if "Network not converged" in outputStr: print 'For ' + event + ':' print 'Network did not converge between fault clearance and branch 2 trip, skipping...' continue # select run time ############################################################## #output = StringIO.StringIO() with silence(output): ierr = psspy.run(0, 10.0, 1, 1, 1) #exit time (second argument is the end time) ################################################################################ # check for non-convergence outputStr = output.getvalue() if "Network not converged" in outputStr: print 'For ' + event + ':' print 'Network did not converge sometime after 2nd branch trip, skipping...' continue # write to output file #with open('outputTmp.txt','w') as f: # f.write(outputStr) outputData = dyntools.CHNF(settings['out_file']) data = outputData.get_data() channelDict = data[ 1] # dictionary where the value is the channel description valueDict = data[ 2] # dictionary where the values are the signal values, keys match that of channelDict tme = valueDict['time'] # get time ResultsDict['time'] = tme for key in channelDict: if key == 'time': continue signalDescr = channelDict[key] words = signalDescr.split() signalType = words[0].strip() bus = words[1].strip() #print Bus + ' ' + signalType if bus not in ResultsDict: ResultsDict[bus] = Results() if signalType == 'VOLT': ResultsDict[bus].volt = valueDict[key] elif signalType == 'ANGL': ResultsDict[bus].angle = valueDict[key] elif signalType == 'FREQ': ResultsDict[bus].freq = valueDict[key] EventsDict[event] = ResultsDict return EventsDict
psspy.branch_chng_3( 400, 46660, r"""1""", [_i, _i, _i, _i, _i, _i], [r_g[test_no], x_g[test_no], _f, _f, _f, _f, _f, _f, _f, _f, _f, _f], [_f, _f, _f, _f, _f, _f, _f, _f, _f, _f, _f, _f], "") psspy.fdns([1, 0, 0, 1, 1, 1, 0, 0]) psspy.bus_frequency_channel([1, 400], r"""System frequency""") # psspy.voltage_channel([2, -1, -1, 101], r"""Inverter Voltage Mag.""") # psspy.voltage_channel([3, -1, -1, 400], r"""WD SF POC Voltage Mag.""") psspy.branch_p_and_q_channel([2, -1, -1, 400, 46660], r"""1""", [r"""P Injection""", r"""Q Injection"""]) # ierr = psspy.machine_array_channel([4, 2, 101], r"""1""", r"""Pelec 101""") # ierr = psspy.machine_array_channel([5, 3, 101], r"""1""", r"""Qelec 101""") psspy.branch_p_and_q_channel([4, -1, -1, 101, 201], r"""1""", [r"""101_P""", r"""101_Q"""]) psspy.voltage_and_angle_channel( [6, -1, -1, 101], [r"""Inverter Voltage Mag""", r"""Inverter Voltage Ang"""]) psspy.voltage_and_angle_channel( [8, -1, -1, 400], [r"""POC_Voltage Mag""", r"""POC Voltage Ang"""]) psspy.cong(0) psspy.conl(0, 1, 1, [0, 0], [0.0, 0.0, 0.1, 0.0]) psspy.conl(0, 1, 2, [0, 0], [0.0, 0.0, 0.1, 0.0]) psspy.conl(0, 1, 3, [0, 0], [0.0, 0.0, 0.1, 0.0]) psspy.ordr(1) psspy.fact() psspy.tysl(1) #psspy.change_plmod_con(600, r"""1""", r"""GENCLS""", 1, 8.0) OutputFilePath = ProgramPath + ClauseName + str( test_no) + "_Simulation.outx" # start simulation
# Factorize Admittance maatrix psspy.fact() # Solve switching study network solutions psspy.tysl() # Save sav file after conversion trans_file = raw_file[0:raw_file.find(".")] + "_trans.sav" psspy.save(trans_file) # Select Channels psspy.delete_all_plot_channels() psspy.chsb(0, 1, [-1, -1, -1, 1, 1, 0]) psspy.chsb(0, 1, [-1, -1, -1, 1, 2, 0]) psspy.voltage_and_angle_channel([-1, -1, -1, 6], ["", ""]) psspy.voltage_and_angle_channel([-1, -1, -1, 7], ["", ""]) psspy.voltage_and_angle_channel([-1, -1, -1, 9], ["", ""]) psspy.voltage_and_angle_channel([-1, -1, -1, 13], ["", ""]) psspy.voltage_and_angle_channel([-1, -1, -1, 14], ["", ""]) psspy.voltage_and_angle_channel([-1, -1, -1, 39], ["", ""]) psspy.branch_p_channel([-1, -1, -1, 6, 7], r"""1""", "") psspy.branch_p_channel([-1, -1, -1, 13, 14], r"""1""", "") psspy.branch_p_channel([-1, -1, -1, 39, 9], r"""1""", "") psspy.branch_mva_channel([-1, -1, -1, 5, 8], r"""1""", "") psspy.branch_mva_channel([-1, -1, -1, 6, 5], r"""1""", "") psspy.branch_mva_channel([-1, -1, -1, 4, 5], r"""1""", "") psspy.load_array_channel([-1, 1, 71], r"""1""", "") psspy.load_array_channel([-1, 2, 71], r"""1""", "") psspy.load_array_channel([-1, 1, 8], r"""1""", "") psspy.load_array_channel([-1, 2, 8], r"""1""", "")