def __init__(self): self.path_pss() import psspy import redirect self._i = psspy.getdefaultint() self._f = psspy.getdefaultreal() self._s = psspy.getdefaultchar()
def _increaseLoadAtBuses(self,load_buses,percent_change): #define the bus subsystem psspy.bsys(1,0,[0.0,0.0],0,[],len(load_buses),load_buses,1,[1],0,[]) #prepare the load increase #in first array #1st zero = include all buses in the subsystem both interruptible and uninterrupted #5th zero = loads of all types (1,2 and 3) psspy.scal_2(1,0,1,[0,0,0,0,0],[0.0,0.0,0.0,0.0,0.0,0.0,0.0]) #increase the loads #in first array #2nd number = percent change #3rd number = ignore machine limits #4th number = increase the reactive load equally (in percents) #in second array #1st number load increase _i = psspy.getdefaultint() psspy.scal_2(0,0,2,[_i,2,0,3,0],[ percent_change,0.0,0.0,0.0,0.0,0.0,0.0])
os.environ['PATH'] = (r"C:\Program Files (x86)\PTI\PSSE34\PSSBIN;" + os.environ['PATH']) sys.path.append(r"""C:\Program Files (x86)\PTI\PSSE34\PSSPY27""") os.environ['PATH'] = (r"C:\Program Files (x86)\PTI\PSSE34\PSSPY27;" + os.environ['PATH']) import psse34 import psspy import redirect import numpy import math import matplotlib as mpl import matplotlib.pyplot as plt import dyntools # OPEN PSS _i = psspy.getdefaultint() _f = psspy.getdefaultreal() _s = psspy.getdefaultchar() redirect.psse2py() psspy.psseinit(50000) ierr = psspy.progress_output(6, ' ', [0, 0]) # disable output ierr = psspy.prompt_output(6, ' ', [0, 0]) # disable output ierr = psspy.report_output(6, ' ', [0, 0]) # disable output # Set Simulation Path. LoadScenario = "SimplifiedSystem" ClauseName = "5.2.5.1 Reactive Power Capability" ProgramPath = "F:/PosDoc Projects/11_Industrial Projects/NEOEN_HW/P_SimulationProgram/" GridInfoPath = "F:/PosDoc Projects/11_Industrial Projects/NEOEN_HW/NEM_files/" + LoadScenario + "/" HuaweiModelPath = "F:/PosDoc Projects/11_Industrial Projects/NEOEN_HW/D_HuaweiModels/34"
#!C:/Python25/python import os,sys sys.path.append(r"C:\Program Files (x86)\PTI\PSSE32\PSSBIN") os.environ['PATH'] = (r"C:\Program Files (x86)\PTI\PSSE32\PSSBIN;" + os.environ['PATH']) #add the the above line #Here is the macro script import psspy import redirect _i=psspy.getdefaultint() _f=psspy.getdefaultreal() _s=psspy.getdefaultchar() redirect.psse2py() import pssdb psspy.psseinit(80000) psspy.case(r"""psse.sav""") psspy.resq(r""" psse.seq""") psspy.lines_per_page_one_device(1,60) psspy.report_output(2,r"""report.txt""",[0,0]) psspy.flat([1,1,1,0],[0.0,0.0]) psspy.seqd([0,0]) psspy.sequence_network_setup(0) psspy.scmu(1,[0,0,0,0,0,0,0],[0.0,0.0,0.0,0.0,0.0],"") psspy.scmu(2,[7,1082,0,0,0,0,0],[0.0,0.0,0.0,0.0,0.0],"") psspy.scmu(3,[7,1082,0,0,0,0,0],[0.0,0.0,0.0,0.0,0.0],"") psspy.sequence_network_setup(0) #end of script
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)
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
def changeLoad(raw, start, end, step, newdir): """ New raw files are created for each percentage step in [start,end]. The current step defines the percentage scaling up (or down) factor for load and generation """ # convert the raw file to another one where all the load is constant power raw_conp = raw.replace('.raw', '') + '_conp.raw' redirect.psse2py() psspy.psseinit(buses=80000) # ignore the output psspy.report_output(6, '', [0, 0]) psspy.progress_output(6, '', [0, 0]) psspy.alert_output(6, '', [0, 0]) psspy.prompt_output(6, '', [0, 0]) # read the raw file and convert all the loads to constant power ierr = psspy.read(0, raw) # multi-line command to convert the loads to 100% constant power psspy.conl(0, 1, 1, [1, 0], [0.0, 0.0, 0.0, 0.0]) psspy.conl(0, 1, 2, [1, 0], [0.0, 0.0, 0.0, 0.0]) psspy.conl(0, 1, 3, [1, 0], [0.0, 0.0, 0.0, 0.0]) ierr = psspy.rawd_2(0, 1, [1, 1, 1, 0, 0, 0, 0], 0, raw_conp) # run change Load on the constant power load raw file rawBusDataDict = getBusData(raw_conp) # create a new directory to put the files in currentdir = os.getcwd() if not os.path.exists(newdir): os.mkdir(newdir) output_dir = currentdir + '/' + newdir #genDiscount = 0.90 # ratio of the actual increase in generation genDiscount = 1.0 lossRatio = 0.0 # gen scale-up factor: (scalePercent + (scalePercent-100)*lossRatio)/100 ############################################ # create new raw files with scaled up loads and generation for scalePercent in range(start, end + step, step): scalePercent = float( scalePercent) # float is needed, otherwise 101/100 returns 1 scalePercentInt = int( scalePercent) # integer value needed to append to filename scalePercentStr = str(scalePercentInt) # variables to store load data loadBusList = [] # list of load buses (string) loadPList = [] # list of Pload values (string) loadQList = [] # list of Qload values (string) loadPListInt = [] # list of Pload values (float) loadQListInt = [] # list of Qload values (float) #loadBusListInt = [] # list of load buses (int) # variables to store gen data genBusList = [] #genBusListInt = [] genPList = [] genMVAList = [] genMVAListInt = [] genPListInt = [] raw_name = raw_conp.replace('.raw', '') out_file = raw_name + scalePercentStr + '.raw' # output file out_path = output_dir + '/' + out_file impLoadBuses = [ ] # enter specified load buses to scale, if empty all loads are scaled incLoss = ( scalePercent - 100 ) * lossRatio # Additional percentage increase in Pgen (to account for losses) ############################################# #Read raw file with open(raw_conp, 'r') as f: filecontent = f.read() filelines = filecontent.split('\n') ## Get start and end indices of load and gen info ######################################### loadStartIndex = filelines.index( '0 / END OF BUS DATA, BEGIN LOAD DATA') + 1 loadEndIndex = filelines.index( '0 / END OF LOAD DATA, BEGIN FIXED SHUNT DATA') genStartIndex = filelines.index( '0 / END OF FIXED SHUNT DATA, BEGIN GENERATOR DATA') + 1 genEndIndex = filelines.index( '0 / END OF GENERATOR DATA, BEGIN BRANCH DATA') ############################################################################## totalPincr = 0.0 totalQincr = 0.0 percentIncr = (scalePercent - 100.0) / 100 # increment in percentage newPConList = [] newQConList = [] newIPList = [] newIQList = [] newZPList = [] newZQList = [] # Extract load info for i in range(loadStartIndex, loadEndIndex): words = filelines[i].split(',') loadBus = words[0].strip() #loadBusList.append(words[0].strip()) loadPCon = float(words[5].strip()) loadQCon = float(words[6].strip()) loadIP = float(words[7].strip()) loadIQ = float(words[8].strip()) loadZP = float(words[9].strip()) loadZQ = float(words[10].strip()) # calculate the total MW (MVAr) increase in load loadBusVolt = float(rawBusDataDict[loadBus].voltpu) Pincr = percentIncr * ( loadPCon + loadIP * loadBusVolt + loadZP * loadBusVolt**2 ) # this equation is provided in PAGV1 page 293 Qincr = percentIncr * (loadQCon + loadIQ * loadBusVolt + loadZQ * loadBusVolt**2) totalPincr += Pincr totalQincr += Qincr ### # new load values newPConList.append(loadPCon * scalePercent / 100) newQConList.append(loadQCon * scalePercent / 100) newIPList.append(loadIP * scalePercent / 100) newIQList.append(loadIQ * scalePercent / 100) newZPList.append(loadZP * scalePercent / 100) newZQList.append(loadZQ * scalePercent / 100) """ loadPList.append(words[5].strip()) # adding P value (constant power) loadQList.append(words[6].strip()) # adding Q value (constant power) loadIPList.append(words[7].strip()) # constant current P loadIQList.append(words[7].strip()) # constant current Q loadZPList.append(words[9].strip()) # adding P value (constant admittance) loadZQList.append(words[10].strip()) # adding Q value (constant admittance) """ # get total MW gen totalGenMW = 0.0 # total generation excluding the swing bus for i in range(genStartIndex, genEndIndex): words = filelines[i].split(',') GenBus = words[0].strip() if rawBusDataDict[GenBus].type == '3': continue PGen = float(words[2].strip()) totalGenMW += PGen # get new MW Gen GenMWDict = {} # dictionary to hold new PGen values for i in range(genStartIndex, genEndIndex): words = filelines[i].split(',') Bus = words[0].strip() if rawBusDataDict[Bus].type == '3': continue macID = words[1].strip() key = Bus + macID PGen = float(words[2].strip()) genIncr = PGen / totalGenMW * totalPincr newPGen = (PGen + genIncr) * genDiscount GenMVA = float(words[8].strip()) if newPGen < GenMVA: GenMWDict[key] = newPGen else: GenMWDict[key] = GenMVA # generate the new raw file with open(out_path, 'w') as f: # copy everything before load data for i in range(loadStartIndex): f.write(filelines[i]) f.write('\n') # modify the load data j = 0 for i in range(loadStartIndex, loadEndIndex): words = filelines[i].split(',') # change the constant MVA values words[5] = '%.3f' % newPConList[j] words[6] = '%.3f' % newQConList[j] words[5] = words[5].rjust(10) words[6] = words[6].rjust(10) # change the constant current values words[7] = '%.3f' % newIPList[j] words[8] = '%.3f' % newIQList[j] words[7] = words[7].rjust(10) words[8] = words[8].rjust(10) # change the constant impedance values words[9] = '%.3f' % newZPList[j] words[10] = '%.3f' % newZQList[j] words[9] = words[9].rjust(10) words[10] = words[10].rjust(10) # construct a whole string by inserting commas between the words list filelines[i] = reconstructLine2(words) f.write(filelines[i]) f.write('\n') # increment the load list index j += 1 # copy the shunt data, which is in between the load and gen data for i in range(loadEndIndex, genStartIndex): f.write(filelines[i]) f.write('\n') # update and write the gen data for i in range(genStartIndex, genEndIndex): words = filelines[i].split(',') Bus = words[0].strip() if rawBusDataDict[Bus].type == '3': f.write(filelines[i]) f.write('\n') continue macID = words[1].strip() key = Bus + macID newPGen = GenMWDict[key] words[2] = '%.3f' % newPGen words[2] = words[2].rjust(10) # construct a whole string by inserting commas between the words list filelines[i] = reconstructLine2(words) f.write(filelines[i]) f.write('\n') # copy the rest of the raw data for i in range(genEndIndex, len(filelines)): f.write(filelines[i]) f.write('\n') # solves each of the newly generated raw files and saves them output_dir = currentdir + '/' + newdir NewRawFiles = os.listdir(output_dir) PathList = [(output_dir + '/' + f) for f in NewRawFiles] redirect.psse2py() psspy.psseinit(buses=80000) _i = psspy.getdefaultint() _f = psspy.getdefaultreal() _s = psspy.getdefaultchar() for i in range(len(PathList)): #Settings. CONFIGURE THIS settings = { # use the same raw data in PSS/E and TS3ph ##################################### 'filename': PathList[i], #use the same raw data in PSS/E and TS3ph ################################################################################ 'dyr_file': '', '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 ] } psse_log = output_dir + '/' + 'log' + NewRawFiles[i].replace( '.raw', '.txt') psspy.report_output(2, psse_log, [0, 0]) psspy.progress_output(2, psse_log, [0, 0]) psspy.alert_output(2, psse_log, [0, 0]) psspy.prompt_output(2, psse_log, [0, 0]) print "\n Reading raw file:", settings['filename'] ierr = psspy.read(0, settings['filename']) ierr = psspy.fnsl(settings['pf_options']) converge = psspy.solved() if converge == 0: ierr = psspy.rawd_2(0, 1, [1, 1, 1, 0, 0, 0, 0], 0, PathList[i]) else: # file does not converge, remove raw file, keep log file os.remove(PathList[i]) """
def run_savnw_simulation(datapath, outfile1, outfile2, outfile3, prgfile): _F1_start=100 _F1_end=100+70*1/60.0; _F2_start = 300 _F2_end = 400; _runto=300; import psspy psspy.psseinit() savfile = 'IEEE 9 Bus_modifiedj4ab.sav' snpfile = 'IEEE 9 Bus_modifiedj4ab.snp' _i = psspy.getdefaultint() _f = psspy.getdefaultreal() _s = psspy.getdefaultchar() INTGAR = [_i] * 7 REALAR = [_f] * 8 if datapath: savfile = os.path.join(datapath, savfile) snpfile = os.path.join(datapath, snpfile) psspy.lines_per_page_one_device(1,90) psspy.progress_output(2,prgfile,[0,0]) #Use this API to specify the progress output device. ierr = psspy.case(savfile) #Use this API to open a PSSE Saved Case file and transfers its data into the PSSE working case if ierr: psspy.progress_output(1,"",[0,0]) print(" psspy.case Error") return ierr = psspy.rstr(snpfile)#Use this API to read a dynamics Snapshot File into PSSE working memory (activity RSTR). if ierr: psspy.progress_output(1,"",[0,0]) print(" psspy.rstr Error") return psspy.strt(0,outfile1) #strt(option, outfile) #Use this API to initialize a PSSE dynamic simulation for state-space simulations (i.e., in preparation for activity RUN) and to specify the Channel Output File into which the output channel values are to be recorded during the dynamic simulation (activity STRT). psspy.run(0, _F1_start,5000,1,0) #Use this API to calculate PSSE state-space dynamic simulations (activity RUN). #psspy.dist_bus_fault(8,1, 230.0,[0.0,-0.2E+10]) #Use this API routine to apply a fault at a bus during dynamic simulations. (Note: use DIST_BUS_FAULT_2 if phase voltages are to be calculated during the simulation.) businfo = subsystem_info('bus', ['NUMBER', 'NAME', 'PU'], sid=-1) print businfo psspy.dist_branch_fault(8,9, '1',3,0.0,[0.0,0.000001]) ##psspy.dist_branch_trip(8, 7, '1') ##psspy.load_chng_5(11, r"""1""", [0, _i, _i, _i, _i, _i, _i], [_f, _f, _f, _f, _f, _f, _f, _f]) businfo = subsystem_info('bus', ['NUMBER', 'NAME', 'PU'], sid=-1) print businfo psspy.run(0, _F1_end+1.5*1/60,5000,1,0) businfo = subsystem_info('bus', ['NUMBER', 'NAME', 'PU'], sid=-1) print businfo #psspy.dist_branch_close(8,7,'1') ## psspy.load_chng_5(11, r"""1""", [1, _i, _i, _i, _i, _i, _i], [_f, _f, _f, _f, _f, _f, _f, _f]) psspy.dist_clear_fault(1) psspy.run(0, _F1_end+2.0, 5000, 1, 0) businfo = subsystem_info('bus', ['NUMBER', 'NAME', 'PU'], sid=-1) print businfo #psspy.dist_clear_fault(1) #Use this API to clear a fault during dynamic simulations. The fault must have previously been applied using one of the following APIs: psspy.run(0, _runto,5000,1,0) #trigger machine # psspy.case(savfile) #Use this API to open a PSSE Saved Case file and transfers its data into the PSSE working case # psspy.rstr(snpfile) #Use this API to read a dynamics Snapshot File into PSSE working memory (activity RSTR). # psspy.strt(0,outfile2) # psspy.run(0, 1.0,1000,1,0) # psspy.dist_machine_trip(2,'1') # psspy.run(0, 10.0,1000,1,0) #trigger line # psspy.case(savfile) # psspy.rstr(snpfile) # psspy.strt(0,outfile3) # psspy.run(0, 1.0,1000,1,0) # psspy.dist_branch_trip(7,8,'1') # psspy.run(0, 10.0,1000,1,0) psspy.lines_per_page_one_device(2,10000000) psspy.progress_output(1,"",[0,0])