def calcSCR(sizes, ret_params=False): ''' ARGS: sizes : list of sizes of Sync. Conds RETURNS: scr : list of short circuit ratios Calculation: scr=sqrt(3)*i_sym*v_pu*v_kv*_UNIT_FACTOR/pmax _UNIT_FACTOR=1e-3 ''' # params pmax = [] i_sym = [] v_kv = [] v_pu = [] # non-verbose execution with silence(): for idx in range(len(SC_IDS)): psspy.machine_data_2(i=SC_IDS[idx], id='1', intgar=[1, 0, 0, 0, 0, 0], realar=[ 0, 0, 500, -200, 0, 0, sizes[idx], 0, 0.17, 0, 0, 1, 1, 1, 1, 1, 1 ]) # full newton-rafsan psspy.fnsl(options4=1, options5=1, options6=1) # get symmetric 3-phase fault currents all_currents = pssarrays.iecs_currents(all=1, flt3ph=1, optnftrc=2, vfactorc=1.0) # all bus pu voltage _, (__v_pu, ) = psspy.abusreal(sid=-1, string=["PU"]) # all bus kv voltage _, (__v_kv, ) = psspy.abusreal(sid=-1, string=["BASE"]) # get pmax for _id in MACHINE_IDS: _, _pmax = psspy.macdat(ibus=_id, id='1', string='PMAX') # find power of machine pmax.append(_pmax) # get v_pu,v_kv,i_sym for _id in BUS_IDS: v_pu.append(__v_pu[_id - 1]) v_kv.append(__v_kv[_id - 1]) i_sym.append(all_currents.flt3ph[_id - 1].ibsym.real) total_bus = len(pmax) scr = [] _UNIT_FACTOR = 1e-3 #LOG_INFO('Calculating SCR') for idx in range(total_bus): scr.append( math.sqrt(3) * i_sym[idx] * v_pu[idx] * v_kv[idx] * _UNIT_FACTOR / pmax[idx]) if ret_params: return pmax, i_sym, v_kv, v_pu, scr else: return scr
def Solve_Steady(): Ok_Solution = 1 psspy.fnsl([0,0,0,1,1,0,99,0]) #Full newton solution ierr, rarray = psspy.abusreal(-1, 2, 'PU') #Get all bus voltages #Check if voltage is above/below a threshold if min(rarray[0]) < 0.95 or max(rarray[0]) > 1.05: Ok_Solution = 0 return rarray, Ok_Solution
def Solve_Steady(): Ok_Solution = 1 psspy.fnsl([0,0,0,1,1,0,99,0]) #Perform Solution ierr, rarray = psspy.abusreal(-1, 2, 'PU') #Returm P.U. voltages of buses after solution #print rarray if min(rarray[0]) < 0.95 or max(rarray[0]) > 1.051: #Find if voltages fall within OK operating ranges (1.051 due to some voltage held buses being specified to 1.05) Ok_Solution = 0 return rarray, Ok_Solution, min(rarray[0]), max(rarray[0])
def openRaw(self, filepath): ''' Reads and opens a raw file Runs a power flow for the current raw file ''' ierr = psspy.readrawversion(0, '33.0', filepath) (folder, file) = os.path.split(filepath) self.caseName = file[:-4] psspy.fnsl([1,2,0,0,1,0,0,0]) assert ierr == 0, 'Raw file cannot be opened'
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() val = psspy.solved() if val == 0: ierr, mvar = psspy.macdat(busno, str(genid), 'Q') return mvar else: return None
def randdist(argin): filename=argin[0] percentage=argin[1] mode=argin[2] shuntctrlmode=0 if mode!='arbitrary': shuntctrlmode=argin[3] psspy.case(filename) ierr, Qload=psspy.aloadcplx(-1, string="MVAACT") Qload=[x.imag for x in Qload[0]] ierr, tlbuses = psspy.aloadint(string='NUMBER') nbus=len(tlbuses[0]) if mode=='random': zoseq=[0,1]*nbus sb=random.sample(zoseq,nbus) elif mode=='arbitrary': abus=argin[3] # argin[3] in this case is the arbitrary buses to apply the disturbance sb=[0]*nbus for i in range(len(abus)): sb[tlbuses[0].index(abus[i])]=1 else: sb=[1]*nbus for j in range(nbus): if sb[j]==1: Qd=Qload[j]+percentage/100.0*abs(Qload[j]) ierr=psspy.load_data_3(i=tlbuses[0][j],REALAR2=Qd) if shuntctrlmode==1: for i in tlbuses[0]: ierr = psspy.switched_shunt_data_3(i, intgar9=1) psspy.fnsl(options1=0,options5=0) ierr, voltd = psspy.abusreal(-1, string="PU") #voltage at buses after disturbance argout=[] argout.append(voltd) argout.append(Qload) argout.append(tlbuses) return argout;
def do_simulation(sav_path, dyr_path): global num_sample_id # set Samples Path sample_path = r'./Sample_14bus_' + input('请输入样本集编号:') if os.path.exists(sample_path): print('该样本集已存在,请重新输入...\n') sample_path = r'./Sample_14bus_' + input('请重新输入样本集编号:') else: os.makedirs(sample_path) # # 1 母线故障——样本编号:1~12*num_bus -> [1, 168] # for i in range(num_bus): # # for i in range(1): # for j in range(len(clear_time)): # # init # psspy.psseinit(50) # psspy.case(sav_path) # psspy.fnsl([0, 0, 0, 1, 1, 0, 99, 0]) # 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.fact() # psspy.tysl(0) # psspy.dyre_new([1, 1, 1, 1], dyr_path, "", "", "") # # # perform Dynamic Simulation # # 1) set "Channal Setup Wizard" # psspy.chsb(0, 1, [-1, -1, -1, 1, 1, 0]) # Angle -> 发电机功角 # psspy.chsb(0, 1, [-1, -1, -1, 1, 14, 0]) # Volt & Angle -> 电压&相角 # psspy.chsb(0, 1, [-1, -1, -1, 1, 16, 0]) # Flow (P & Q) -> 潮流 # # # 2) name output file # psspy.set_chnfil_type(0) # 1 for OUTX format, 0 for (old) OUT format # psspy.strt_2([0, 1], sample_path + '\\t14Bus-PY-00' + str(num_sample_id) + '.out') # num_sample_id += 1 # # # 3) in normal stat, run network to 1 seconds # psspy.run(0, 1.0, 0, 1, 1) # # # 4) set Balanced_bus_fault; Default with R,X -> [0, -2e+009] # psspy.dist_bus_fault(bus_id[i], 1, bus_kv[i], [0.0, -2E9]) # -------- ! important # # # bus5 unbalanced fault with [R-LL, X-LL, R-LG, X-LG], 是单相故障 !!!!!!! # # 事实证明设置LL的RX对稳定毫无影响!! # # psspy.dist_scmu_fault_2([0, 0, 2, bus_id[i], ], [2E5, 3E5, 0, 0]) # # # 5) set fault run time # psspy.run(0, 1 + clear_time[j], 0, 1, 1) # # # 5) clear fault, and run net to 10 seconds # psspy.dist_clear_fault(1) # psspy.run(0, 10.0, 0, 1, 1) # 2 非变压器支路故障——样本编号: [bus_id ,bus_id + 960] # 根据本循环写的嵌套次序,故障时间每12条仿真为一个循环 # for i in range(num_notrans_brch): for i in range(1): # for k in range(len(fault_position)): for k in range(3): # for j in range(len(clear_time)): for j in range(12): print('\n\n\n\n----------------我是分割线--------------\n\n\n\n\n') print('已仿真第 ' + str(num_sample_id) + ' 条样本') # init psspy.psseinit(10) psspy.case(sav_path) psspy.fnsl([0, 0, 0, 1, 1, 0, 99, 0]) 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.fact() psspy.tysl(0) psspy.dyre_new([1, 1, 1, 1], dyr_path, "", "", "") # perform Dynamic Simulation # 1) set "Channal Setup Wizard" psspy.chsb(0, 1, [-1, -1, -1, 1, 1, 0]) # Angle -> 发电机功角 psspy.chsb(0, 1, [-1, -1, -1, 1, 14, 0]) # Volt & Angle -> 电压&相角 psspy.chsb(0, 1, [-1, -1, -1, 1, 16, 0]) # Flow (P & Q) -> 潮流 # 2) name output file psspy.set_chnfil_type( 0) # 1 for OUTX format, 0 for (old) OUT format psspy.strt_2([0, 1], sample_path + '\\t14Bus-PY-00' + str(num_sample_id) + '.out') num_sample_id += 1 # 3) in normal stat, run network to 1 seconds psspy.run(0, 1.0, 0, 1, 1) # 4) set unbalanced_Branch_fault -- 3 Phase -- with R,X -> [0, 0] psspy.dist_spcb_fault_2( notrans_brch[i][0], notrans_brch[i][1], r"""1""", [3, 0, 3, 1, 0, 0, 1], [fault_position[k], 0.0, 0.0, 0.0, 0.0 ]) # -------- ! important # 5) set fault run time psspy.run(0, 1 + clear_time[j], 0, 1, 1) # 6) clear fault, and run net to 10 seconds psspy.dist_clear_fault(1) psspy.run(0, 10.0, 0, 1, 1) # 7) 关闭本次仿真相关的文件, importaant !!!!!!!!!!!!!!!!!!!!!! psspy.pssehalt_2()
psspy.load_chng_4(4, '1', realar1=sheet.cell(row=i, column=4).value, realar2=0.01 * sheet.cell(row=i, column=4).value) psspy.load_chng_4(5, '1', realar1=sheet.cell(row=i, column=5).value, realar2=0.01 * sheet.cell(row=i, column=5).value) print('Changes completed...') psspy.rawd_2( 0, 1, [0, 0, 1, 0, 0, 0, 0], 0, "Snap_before_PF.raw") #save the raw file to convert to CIM b = 'h' + str(i - 2) + '_before_PF.raw' os.rename("Snap_before_PF.raw", b) psspy.fnsl([1, 0, 0, 0, 0, 0, 0, 0]) #solve the power flow ival = psspy.solved() #flag to check power flow convergence if ival == 0: print('Convergence') sheet.cell(row=i, column=7).value = 'Convergence' psspy.save('temp.sav') #save temporarily the solved case psspy.case('temp.sav') #set the saved case as current case psspy.rawd_2( 0, 1, [0, 0, 1, 0, 0, 0, 0], 0, "Snap_after_PF.raw") #save the raw file to convert to CIM b = 'h' + str((i - 2)) + '_after_PF.raw' os.rename("Snap_after_PF.raw", b) else: print('No convergence') sheet.cell(row=i, column=7).value = 'Non-convergence'
import dyntools import csv 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 ] # Inputs and outputs filename = 'tmpv2.raw' # old raw file raw_new = 'tmpv2_island.raw' # new raw file created after disconnecting all the islands psse_log = 'psse_log.txt' ###### redirect.psse2py() psspy.psseinit(buses=80000) # Redirect any psse outputs to psse_log psspy.report_output(2, psse_log, [0, 0]) psspy.progress_output(6, psse_log, [0, 0]) #ignored psspy.alert_output(6, psse_log, [0, 0]) #ignored psspy.prompt_output(6, psse_log, [0, 0]) #ignored ############################## ierr = psspy.read(0, filename) ierr = psspy.fnsl(pf_options) # solve power flow
def main(): # set output path outpath = r"""TpeOut\\""" # TPE reduction TPE_list = r"""TPE_list.xlsx""" rootbus1_list, bus_red_list, d1bus_list, rootbus2_list, retdbus_list, N_tpe = read_bus_TPE(TPE_list) for instance_i in range(N_tpe): bus_root1 = rootbus1_list[instance_i] bus_root2 = rootbus2_list[instance_i] bus_ret = retdbus_list[instance_i] bus_red = bus_red_list[instance_i] bus_d1 = d1bus_list[instance_i] # read power flow model before reduction step i psspy.psseinit(50000) if instance_i == 0: psspy.read(0, r"""FullModel\wecc179_v33.raw""") else: pass psspy.fnsl([1, 0, 0, 1, 1, 0, 0, 0]) # get power flow data pfd = PFData() pfd.getdata(psspy) # count elements in full model if instance_i == 0: n_gen_bf, n_load_bf, n_bus_bf, n_line_bf, n_xfmr_bf, n_shunt_bf = CountEle(pfd) # prepare data for two-port equivalent P1, Q1, Vm1, Va1, PrateA1, PrateB1, P3, Q3, Vm3, Va3, PrateA3, PrateB3, PL, QL, PG, QG, MW_ll, MW_ul, Mvar_ll,\ Mvar_ul, MVA_base, PS, QS, load_bus, gen_bus, shunt_bus = read_subsys_TPE(pfd, bus_root1, bus_red, bus_d1, bus_root2, bus_ret) # calculate TPE equivalent Vm2, Va2, r1, x1, r2, x2 = CalcTwoPortEqui(pfd, P1, Q1, Vm1, Va1, P3, Q3, Vm3, Va3, PL, QL, PG, QG, PS, QS) # Implement two-port equivalent in PSSE DoTpeInPsse(psspy, pfd, bus_root1, bus_root2, bus_ret, bus_red, bus_d1, PL, QL, PG, QG, PS, QS, PrateA1, PrateB1, PrateA3, PrateB3, MW_ll, MW_ul, Mvar_ll, Mvar_ul, MVA_base, Vm2, Va2, r1, x1, r2, x2) # save new power flow data psspy.rawd_2(0, 1, [0, 0, 1, 0, 0, 0, 0], 0, outpath + "tpe_step_" + str(instance_i + 1)) # calc a summary for TPE reduction pfd.getdata(psspy) n_gen_af, n_load_af, n_bus_af, n_line_af, n_xfmr_af, n_shunt_af = CountEle(pfd) # print("\nTPE reduction summary:") print("(# of elements, Before, After, Reduction %)") print("-----------------------------------------------") print(" Buses: ", n_bus_bf, n_bus_af, str(float((n_bus_bf - n_bus_af))/n_bus_bf*100)[0:5] + "%") print(" Generations: ", n_gen_bf, n_gen_af, str(float((n_gen_bf - n_gen_af))/n_gen_bf*100)[0:5] + "%") print(" Loads: ", n_load_bf, n_load_af, str(float((n_load_bf - n_load_af))/n_load_bf*100)[0:5] + "%") print(" Lines: ", n_line_bf, n_line_af, str(float((n_line_bf - n_line_af))/n_line_bf*100)[0:5] + "%") print("Transformers: ", n_xfmr_bf + 1, n_xfmr_af + 1, str(float((n_xfmr_bf - n_xfmr_af))/(n_xfmr_bf+1)*100)[0:5] + "%") print(" Shunts: ", n_shunt_bf, n_shunt_af, str(float((n_shunt_bf - n_shunt_af)) / (n_shunt_bf + 1) * 100)[0:5] + "%")
os.environ['PATH'] = (pssbin_path + ';' + os.environ['PATH']) import psspy, redirect, dyntools, pssplot # Import PSS/E default _i = psspy.getdefaultint() _f = psspy.getdefaultreal() _s = psspy.getdefaultchar() redirect.psse2py() # -------------------------------------------------- # # initiate psspy.psseinit(2000) # 2000 bus at most, this number can be changed # Load and solve the powerflow case psspy.case(sav_case) # configure the solver psspy.fnsl(options1=0, options5=0) # sikve the power flow case iVal = psspy.solved() if iVal == 0: print "Met convergence tolerance" elif iVal == 1: print "The iteration limit exceeded" elif iVal > 1: print "Blown up or others" # ------------------------------------------------- # # Dynamic Simulation # Convert gen & load # convert generators ierr = psspy.cong(0)
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
def update_raw_files(self, to_excel=True, out_dir=None): """Function for updating the psse case file. Args: to_excel(default=True): If a summary should be written to excel out_dir: The directory where the results are stored """ if not out_dir: out_dir = os.getcwd() redirect.psse2py() psspy.throwPsseExceptions = True nbuses = 50000 # max no of buses ierr = psspy.psseinit(nbuses) psspy.case(self.basecase) if to_excel: self.create_excel_sheet() self.to_excel = True else: self.sheet = None for i, col in zip(range(0, 24), range(2, 2 + 24 * 3, 3)): # Represent HVDC links as load and some other exchanges as well print('Changing additional loads...') row = 15 for load in self.ex_as_load: self.load_change(load, i, to_excel, row, col) row = row + 1 print('Changing interarea exchanges...') row = 3 for area, info in self.area_info.items(): country = area[0:2] # Changing interarea exchanges exchange = self.calculate_exchange(info, area, i) self.area_data(info.number, info.bus, exchange, area, row, col + 2) # Changing areas production and consumption self.change_prod_con(info.number, self.data[country]["PS"][area][i], self.data[country]["FB"][area][i], info.pf, tol=4, row=row, column=col) row = row + 1 print('Changes completed...') # Save the raw file to convert to CIM psspy.rawd_2(0, 1, [0, 0, 1, 0, 0, 0, 0], 0, "Snap_before_PF.raw") b = os.path.join(out_dir, 'h' + str( (col - 1) / 3) + '_before_PF.raw') os.rename("Snap_before_PF.raw", b) # Solve the power flow psspy.fnsl([1, 2, 0, 0, 1, 0, 0, 0]) ival = psspy.solved() # flag to check power flow convergence if ival == 0: print('Convergence') if self.to_excel: self.sheet.cell(row=42, column=col).value = 'Convergence' temp_fname = os.path.join(out_dir, "temp.sav") print(temp_fname) psspy.save(temp_fname) # save temporarily the solved case psspy.case(temp_fname) # set the saved case as current case # save the raw file to convert to CIM raw_fname = os.path.join(out_dir, "Snap_after_PF.raw") psspy.rawd_2(0, 1, [0, 0, 1, 0, 0, 0, 0], 0, raw_fname) b = os.path.join(out_dir, 'h' + str(i) + '_after_PF.raw') os.rename(raw_fname, b) if self.to_excel: # Merge cells self.sheet.merge_cells(start_row=1, start_column=col, end_row=1, end_column=col + 2) self.sheet.cell( row=2, column=col).alignment = (Alignment(wrapText=True)) self.sheet.cell(row=2, column=col + 1).alignment = (Alignment(wrapText=True)) self.sheet.cell(row=2, column=col + 2).alignment = (Alignment(wrapText=True)) self.sheet.cell( row=14, column=col).alignment = (Alignment(wrapText=True)) self.sheet.cell(row=14, column=col + 1).alignment = (Alignment(wrapText=True)) self.sheet.cell( row=30, column=col).alignment = (Alignment(wrapText=True)) self.sheet.cell(row=30, column=col + 1).alignment = (Alignment(wrapText=True)) # Headers for data from nordpool self.sheet.cell(row=1, column=col).value = ('hour ' + str(i)) self.sheet.cell( row=2, column=col).value = ('Scheduled\nProduction\n[MWh]') self.sheet.cell( row=2, column=col + 1).value = ('Scheduled\nConsumption\n[MWh]') self.sheet.cell(row=2, column=col + 2).value = ('Scheduled\nExchange\n[MWh]') # Headers for exchanges represented as loads self.sheet.cell(row=14, column=col).value = ('Active Power\n[MW]') self.sheet.cell(row=14, column=col + 1).value = ('Reactive Power\n[MW]') # Headers for results after PSS/E self.sheet.cell( row=30, column=col).value = ('PSSE\nProduction\n[MWh]') self.sheet.cell(row=30, column=col + 1).value = ('PSSE\nConsumption\n[MWh]') self.sheet.cell(row=30, column=col + 2).value = ('PSSE\nExchange\n[MWh]') row = 31 for _, info in self.area_info.items(): # to get the area production complex power ierr = psspy.ardat(info.number, 'GEN') self.sheet.cell(row=row, column=col).value = (round( ierr[1].real, 0)) # to get the area consumption complex power ierr = psspy.ardat(info.number, 'LOAD') self.sheet.cell(row=row, column=col + 1).value = (round( ierr[1].real, 0)) row += 1 # to get the value of the areas active power interchange ierr, intch = psspy.aareareal(-1, 1, 'PINT') for r in range(0, len(intch[0])): self.sheet.cell(row=31 + r, column=col + 2).value = round( intch[0][r].real, 0) # limits check ierr, busvoltages = psspy.abusreal(sid=-1, string="PU") if any(x < 0.95 or x > 1.05 for x in busvoltages[0]): self.sheet.cell( row=43, column=col).value = ('Bus voltage problem') ierr, machPGen = psspy.amachreal(sid=-1, string="PGEN") ierr, machPMax = psspy.amachreal(sid=-1, string="PMAX") ierr, machPMin = psspy.amachreal(sid=-1, string="PMIN") ierr, machQGen = psspy.amachreal(sid=-1, string="QGEN") ierr, machQMax = psspy.amachreal(sid=-1, string="QMAX") ierr, machQMin = psspy.amachreal(sid=-1, string="QMIN") ierr, machS = psspy.amachreal(sid=-1, string="MVA") ierr, machMbase = psspy.amachreal(sid=-1, string="MBASE") for l in range(0, len(machPGen[0])): if (machPGen[0][l] <= machPMin[0][l] or machPGen[0][l] >= machPMax[0][l]): self.sheet.cell(row=45, column=col).value = ( 'Generator active power output problem') for m in range(0, len(machQGen[0])): if (machQGen[0][m] <= machQMin[0][m] or machQGen[0][m] >= machQMax[0][m]): self.sheet.cell(row=46, column=col).value = ( 'Generator reactive power output problem') break for n in range(0, len(machS[0])): if machS[0][n] >= machMbase[0][n]: self.sheet.cell(row=47, column=col).value = ( 'Generator overloading problem') break ierr, brflowA = psspy.aflowreal(sid=-1, string="PCTCORPRATEA") if any(x >= 100 for x in brflowA[0]): self.sheet.cell(row=48, column=col).value = ( 'Branch overloading problem (Rate A)') ierr, brflowB = psspy.aflowreal(sid=-1, string="PCTCORPRATEB") if any(x >= 100 for x in brflowB[0]): self.sheet.cell(row=48, column=col).value = ( 'Branch overloading problem (Rate B)') ierr, brflowC = psspy.aflowreal(sid=-1, string="PCTCORPRATEC") if any(x >= 100 for x in brflowC[0]): self.sheet.cell(row=48, column=col).value = ( 'Branch overloading problem (Rate C)') else: print('No convergence') self.sheet.cell(row=43, column=col).value = 'No convergence' psspy.close_powerflow() # save the Excel file with all data self.wb.save(os.path.join(out_dir, 'PSSE_in_out.xlsx')) os.remove(temp_fname)
PSSE_LOCATION = r"C:\Program Files (x86)\PTI\PSSE33\PSSBIN" sys.path.append(PSSE_LOCATION) os.environ['PATH'] = os.environ['PATH'] + ';' + PSSE_LOCATION import psspy _f = psspy.getdefaultreal() _i = psspy.getdefaultint() _s = psspy.getdefaultchar() psspy.psseinit(0) psspy.case(PSSE_model_sav) #Start of process psspy.fnsl(powerflow_settings[powerflow_normal] ) #lahendus (Full Newton-Raphson/Lock taps/Lock shunts) #Get inital data for areas area_parameters = ["LOAD", "GEN", "LOSS", "INT"] list_of_area_data = [] for area in areas: area_row = [] area_row.append(area[0]) for parameter in area_parameters: error, result = psspy.ardat(int(area[1]), parameter) area_row.extend([int(result.real)]) list_of_area_data.append(area_row)
def main(): # set output path outpath = r"""SpeOut\\""" # SPE reduction SPE_list = r"""SPE_list.xlsx""" rootbus_list, redbus_list, d1bus_list, N_spe = read_bus(SPE_list) for instance_i in range(N_spe): bus_root = rootbus_list[instance_i] bus_red = redbus_list[instance_i] bus_d1 = d1bus_list[instance_i] # read power flow model before reduction step i psspy.psseinit(50000) if instance_i == 0: # psspy.readrawversion(0, r"""30""", r"""FullModel\wecc179.raw""") # reading .raw file # psspy.case(r"""FullModel\Maui2022dm_v4_wHydro_step0""") # reading .sav file psspy.read(0, r"""FullModel\wecc179_v33.raw""") else: pass psspy.fnsl([1, 0, 0, 1, 1, 0, 0, 0]) # get power flow data pfd = PFData() pfd.getdata(psspy) # count elements in full model if instance_i == 0: n_gen_bf, n_load_bf, n_bus_bf, n_line_bf, n_xfmr_bf, n_shunt_bf = CountEle(pfd) # prepare data for single-port equivalent Pin, Qin, PL, QL, PG, QG, PS, QS, Vm, Va, Ve, PrateA, PrateB, MW_ll, MW_ul, Mvar_ll, Mvar_ul, MVA_base, \ red_load_bus, red_gen_bus, red_shunt_bus = read_subsys(pfd, bus_root, bus_red, bus_d1) # calculate SPE equivalent k, Vae, r, x = CalcSinglePortEqui(pfd, Pin, Qin, PL, QL, PG, QG, PS, QS, Vm, Va, Ve) # Implement single-port equivalent in PSSE DoSpeInPsse(psspy, bus_root, bus_red, bus_d1, pfd, PL, QL, PG, QG, PS, QS, Ve, PrateA, PrateB, MW_ll, MW_ul, Mvar_ll, Mvar_ul, MVA_base, k, r, x) # save new power flow data psspy.rawd_2(0, 1, [0, 0, 1, 0, 0, 0, 0], 0, outpath + "spe_step_" + str(instance_i + 1)) # calc a summary for SPE reduction pfd.getdata(psspy) n_gen_af, n_load_af, n_bus_af, n_line_af, n_xfmr_af, n_shunt_af = CountEle(pfd) # print("\nSPE reduction summary:") print("(# of elements, Before, After, Reduction %)") print("-----------------------------------------------") print(" Buses: ", n_bus_bf, n_bus_af, str(float((n_bus_bf - n_bus_af))/n_bus_bf*100)[0:5] + "%") print(" Generations: ", n_gen_bf, n_gen_af, str(float((n_gen_bf - n_gen_af))/n_gen_bf*100)[0:5] + "%") print(" Loads: ", n_load_bf, n_load_af, str(float((n_load_bf - n_load_af))/n_load_bf*100)[0:5] + "%") print(" Lines: ", n_line_bf, n_line_af, str(float((n_line_bf - n_line_af))/n_line_bf*100)[0:5] + "%") print("Transformers: ", n_xfmr_bf + 1, n_xfmr_af + 1, str(float((n_xfmr_bf - n_xfmr_af))/(n_xfmr_bf+1)*100)[0:5] + "%") print(" Shunts: ", n_shunt_bf, n_shunt_af, str(float((n_shunt_bf - n_shunt_af)) / (n_shunt_bf + 1) * 100)[0:5] + "%")
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]) """
_i = psspy.getdefaultint() _f = psspy.getdefaultreal() _s = psspy.getdefaultchar() psspy.psseinit() # initialise PSSE so psspy commands can be called psspy.throwPsseExceptions = True SAV_File = 'ModelAcceptanceSystem.sav' ierr = psspy.case(ProgramPath + SAV_File) # Add a branch between the DUMMY node and the Infinite bus Thevenin_R = 0.0000 Thevenin_X = 0.0001 psspy.branch_chng_3(107, 969, r'1', [_i, _i, _i, _i, _i, _i], [Thevenin_R, Thevenin_X, _f, _f, _f, _f, _f, _f, _f, _f, _f, _f], [_f, _f, _f, _f, _f, _f, _f, _f, _f, _f, _f, _f], "") psspy.fnsl([1, 0, 0, 1, 1, 0, 0, 0]) MBASE = 83.6 # MBASE = 83.6 MVA SBASE = 100.0 # SBASE = 100 MVA bus_inf = 969 # infinite bus bus_gen = 100 # inverter bus bus_poc = 106 # point of connection bus_dummy = 107 # dummy transformer poc_p_max = 65 # active power at poc poc_p_min = poc_p_max*0.05 # active power at poc poc_q = 0.3*poc_p_max # reactive power at poc POC_VCtrl_Tgt = 1.0 # controlled voltage at poc Vinf_MisMatch_Tol = 0.0001 PQMisMatch_Tol = Vinf_MisMatch_Tol*1 QAdjust_Step = Vinf_MisMatch_Tol*1 P_factor = 2
# loop to simulate all line outages for line in list(HVLineSet): lineElements = line.split(',') Bus1 = int(lineElements[0]) Bus2 = int(lineElements[1]) cktID = lineElements[2] # read the original raw file and try to solve power flow ierr = psspy.read(0, settings['filename']) ierr = psspy.branch_chng( Bus1, Bus2, cktID, [0, _i, _i, _i, _i, _i], [_f, _f, _f, _f, _f, _f, _f, _f, _f, _f, _f, _f, _f, _f, _f ]) # disconnect branch 1 #ierr = psspy.branch_chng(Bus2,toBus2,cktID2,[0,_i,_i,_i,_i,_i],[_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f,_f]) # disconnect branch 2 ierr = psspy.fnsl(settings['pf_options']) # solve power flow # check for topology inconsistencies converge = psspy.solved() if converge != 0: # topology inconsistencies, skip continue # get the buses and voltages from psse itself ierr, buslist = psspy.abusint( -1, 1, 'NUMBER') # getting bus numbers from raw file buslist = buslist[0] ierr, vpulist = psspy.abusreal(-1, 1, 'PU') vpulist = vpulist[0] # gather the voltage data in a dictionary after the event is applied VoltageDict = { } # key: Bus, value: per unit voltage after the event has been applied and power flow solved
##ierr = psspy.branch_data(44403, 45400, "2", intgar1=0) ##ierr = psspy.branch_data(44404, 45404, "1", intgar1=0) #DSTPS - paruliaPG line ##ierr = psspy.branch_data(44404, 45404, "2", intgar1=0) ##ierr = psspy.branch_data(44404, 44403, "1", intgar1=1) #DSTPS - RTPS line ##ierr = psspy.branch_data(44404, 44403, "2", intgar1=1) #---------------------------- psspy.solution_parameters_2(intgar1=150) psspy.fdns(option1=0, #tap adjustment disabled option2=0, #area interchange disables option3=0, #phase shift option disabled option4=0, #dc tap adjustment option disabled option5=0, #switched shunt adjustment option disabled ) psspy.fnsl() psspy.inibus(0) #ierr = psspy.pout(sid=1, all=0) #n = psspy.totbus() ierr = psspy.bsys(sid=1, numzone=1, zones=44) businfo = subsystem_info('bus', ['NUMBER', 'BASE', 'NAME'], sid=-1) #print businfo mybuslst = subsystem_info('bus', ['NUMBER', 'BASE', 'NAME'], sid=1) #print mybuslst mygeninfo = subsystem_info('mach', ['NUMBER', 'PGEN', 'NAME'], sid=1) #print mygeninfo myloadinfo = subsystem_info('load', ['NUMBER', 'MVAACT', 'NAME'], sid=1) #print myloadinfo branchinfo = subsystem_info('brn', ['FROMNUMBER', 'TONUMBER', 'MVA', 'P'], sid=1) #print branchinfo
status, scalval = [0, 1, 4, 0], [] ierr, totals, moto = psspy.scal(sid=1, all=0, apiopt=1, status=status, scalval=scalval) scalval = [0., 0., totals[2], totals[3], totals[4], totals[5], 0.98] ierr, totals, moto = psspy.scal(sid=1, all=0, apiopt=2, status=status, scalval=scalval) psspy.solution_parameters_3(intgar2=70) #psspy.fdns() psspy.fnsl((1, 0, 1, 0, 0, 0, 99, 1)) psspy.inibus(0) #ierr = psspy.pout(sid=1, all=0) #n = psspy.totbus() #ierr = psspy.bsys(sid=1, numzone=1, zones=44) businfo = subsystem_info('bus', ['NUMBER', 'BASE', 'NAME'], sid=-1) #print businfo mybuslst = subsystem_info('bus', ['NUMBER', 'BASE', 'NAME'], sid=1) #print mybuslst mygeninfo = subsystem_info('mach', ['NUMBER', 'PGEN', 'NAME'], sid=1) #print mygeninfo myloadinfo = subsystem_info('load', ['NUMBER', 'MVAACT', 'NAME'], sid=1) #print myloadinfo branchinfo = subsystem_info('brn', ['FROMNUMBER', 'TONUMBER', 'MVA', 'P'], sid=1)
title2 = 'flatstart' conl = 'Conl.idv' channels = 'channels.idv' mylog = '%s.log'%study # psspy.progress_output(2,mylog,[0,0]) psspy.report_output(2,mylog,[0,0]) psspy.progress(' \n') psspy.progress('***************************************\n') psspy.progress('* MakeCnvSnp %s \n'%study) psspy.progress('*\n') psspy.progress('***************************************\n') psspy.case(mysav) #psspy.runrspnsfile(re_add) #adds RE topology psspy.runrspnsfile(conl) psspy.fnsl((_i,0,_i,_i,_i,_i,_i,0)) psspy.cong(0) psspy.ordr(0) psspy.fact() psspy.tysl(0) psspy.tysl(0) psspy.save('%s_cnv'%study) psspy.dyre_new([1,1,1,1], mydyr, r"""conec.flx""", r"""conet.flx""", r"""compile.bat""") psspy.snap([-1,-1,-1,-1,-1],'%s'%study) psspy.progress_output(1)
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
##ierr, in_trfs = psspy.atrnint(sid=2, string=['FROMNUMBER', 'TONUMBER'], ## flag=1) ##for i in range(len(in_trfs[0])): ## psspy.two_winding_data(in_trfs[0][i], in_trfs[1][i], intgar1=0) ###------------------------ status, scalval = [0,1,4,0], [] ierr, totals, moto = psspy.scal(sid=1, all=0, apiopt=1, status=status, scalval=scalval) scalval = [0.,0.,totals[2],totals[3],totals[4],totals[5],0.98] ierr, totals, moto = psspy.scal(sid=1, all=0, apiopt=2, status=status, scalval=scalval) psspy.solution_parameters_3(intgar2=70) #psspy.fdns() psspy.fnsl((1,0,1,0,0,0,99,1)) psspy.inibus(0) #ierr = psspy.pout(sid=1, all=0) #n = psspy.totbus() #ierr = psspy.bsys(sid=1, numzone=1, zones=44) businfo = subsystem_info('bus', ['NUMBER', 'BASE', 'NAME'], sid=-1) #print businfo mybuslst = subsystem_info('bus', ['NUMBER', 'BASE', 'NAME'], sid=1) #print mybuslst mygeninfo = subsystem_info('mach', ['NUMBER', 'PGEN', 'NAME'], sid=1) #print mygeninfo myloadinfo = subsystem_info('load', ['NUMBER', 'MVAACT', 'NAME'], sid=1) #print myloadinfo branchinfo = subsystem_info('brn', ['FROMNUMBER', 'TONUMBER', 'MVA', 'P'], sid=1) #print branchinfo
def do_simulation(): global num_sample_id # set Samples Path sample_path = r'./Sample_9bus_' + input('请输入样本集编号:') if os.path.exists(sample_path): print('该样本集已存在,请重新输入...\n') sample_path = r'./Sample_9bus_' + input('请重新输入样本集编号:') else: os.makedirs(sample_path) # # 1 母线故障——样本编号:1~12*num_bus -> [1, 108] # for i in range(num_bus): # # for i in range(1): # for j in range(len(clear_time)): # # init # psspy.psseinit(50) # psspy.case(r""".\Models\9Bus-test\ieee9bus_v32.sav""") # psspy.fnsl([0, 0, 0, 1, 1, 0, 99, 0]) # 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.fact() # psspy.tysl(0) # psspy.dyre_new([1, 1, 1, 1], r""".\Models\9Bus-test\ieee9bus.dyr""", "", "", "") # # # perform Dynamic Simulation # # 1) set "Channal Setup Wizard" # psspy.chsb(0, 1, [-1, -1, -1, 1, 1, 0]) # Angle # psspy.chsb(0, 1, [-1, -1, -1, 1, 7, 0]) # # psspy.chsb(0, 1, [-1, -1, -1, 1, 13, 0]) # # # # 2) name output file # psspy.set_chnfil_type(0) # 1 for OUTX format, 0 for (old) OUT format # psspy.strt_2([0, 1], sample_path + '\\t9Bus-PY-00' + str(num_sample_id) + '.out') # num_sample_id += 1 # # # 3) in normal stat, run network to 1 seconds # psspy.run(0, 1.0, 0, 1, 1) # # # 4) set Balanced_bus_fault with R,X -> [0, 0] # psspy.dist_bus_fault(bus_id[i], 1, bus_kv[i], [0.0, -2E+2]) # -------- ! important # # # 5) set fault run time # psspy.run(0, 1 + clear_time[j], 0, 1, 1) # # # 6) clear fault, and run net to 10 seconds # psspy.dist_clear_fault(1) # psspy.run(0, 10.0, 0, 1, 1) # # # 7) 关闭本次仿真相关的文件, importaant !!!!!!!!!!!!!!!!!!!!!! # psspy.pssehalt_2() # 2 非变压器支路故障——样本编号: [108+1, 108+360] for i in range(num_notrans_brch): # for i in range(1): for k in range(len(fault_position)): # for k in range(1): for j in range(len(clear_time)): print('\n\n\n\n----------------我是分割线--------------\n') print('已仿真第 ' + str(num_sample_id) + ' 条样本\n\n\n\n') # init psspy.psseinit(50) psspy.case(r""".\Models\9Bus-test\ieee9bus_v32.sav""") psspy.fnsl([0, 0, 0, 1, 1, 0, 99, 0]) 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.fact() psspy.tysl(0) psspy.dyre_new([1, 1, 1, 1], r""".\Models\9Bus-test\ieee9bus.dyr""", "", "", "") # perform Dynamic Simulation # 1) set "Channal Setup Wizard" psspy.chsb(0, 1, [-1, -1, -1, 1, 1, 0]) # Angle psspy.chsb(0, 1, [-1, -1, -1, 1, 7, 0]) # psspy.chsb(0, 1, [-1, -1, -1, 1, 13, 0]) # # 1.1) set Relative Machine Angle psspy.set_relang(1, 1, r"""1""") # 2) name output file psspy.set_chnfil_type( 0) # 1 for OUTX format, 0 for (old) OUT format psspy.strt_2([0, 1], sample_path + '//t9Bus-PY-00' + str(num_sample_id) + '.out') num_sample_id += 1 # 3) in normal stat, run network to 1 seconds psspy.run(0, 1.0, 0, 1, 1) # 4) set unbalanced_Branch_fault -- 3 Phase -- with R,X -> [0, 0] psspy.dist_spcb_fault_2( notrans_brch[i][0], notrans_brch[i][1], r"""1""", [3, 0, 3, 1, 0, 0, 1], [fault_position[k], 0.0, 0.0, 0.0, 0.0 ]) # -------- ! important # 5) set fault run time psspy.run(0, 1 + clear_time[j], 0, 1, 1) # 6) clear fault, and run net to 10 seconds psspy.dist_clear_fault(1) psspy.run(0, 10.0, 0, 1, 1) # 7) 关闭本次仿真相关的文件, importaant !!!!!!!!!!!!!!!!!!!!!! psspy.pssehalt_2()
OutputFilePath = ProgramPath + str(fault_type) + "SimulationOutput4.outx" TimeShift = 0 psspy.case(GridInfoPath + file_name + ".sav") # psspy.rstr(GridInfoPath+file_name+".snp") psspy.resq(GridInfoPath + "/" + file_name + ".seq") psspy.dyre_new([1, 1, 1, 1], GridInfoPath + "/" + file_name + ".dyr", "", "", "") psspy.addmodellibrary(HuaweiModelPath + 'HWS2000_psse34.dll') psspy.addmodellibrary(HuaweiModelPath + 'MOD_GPM_PPC_V13_34.dll') psspy.addmodellibrary(HuaweiModelPath + 'MOD_GPM_SB_V7.dll') psspy.dynamics_solution_param_2([_i, _i, _i, _i, _i, _i, _i, _i], [0.300, _f, 0.001, 0.004, _f, _f, _f, _f]) psspy.machine_data_2( 500, r"""1""", [_i, _i, _i, _i, _i, _i], [90, _f, _f, _f, 96.8, _f, _f, _f, _f, _f, _f, _f, _f, _f, _f, _f, _f]) psspy.fnsl([0, 0, 0, 1, 1, 1, 99, 0]) psspy.bus_frequency_channel([1, 1000], r"""System frequency""") psspy.voltage_channel([2, -1, -1, 500], r"""Inverter Voltage Mag.""") psspy.voltage_channel([3, -1, -1, 800], r"""WISF POC Voltage Mag.""") psspy.branch_p_and_q_channel([4, -1, -1, 800, 900], r"""1""", [r"""P Injection""", r"""Q Injection"""]) ierr = psspy.machine_array_channel([6, 2, 500], r"""1""", r"""Pelec Inverter""") ierr = psspy.machine_array_channel([7, 3, 500], r"""1""", r"""Qelec Inverter""") [ierr, var_ppc_conp] = psspy.mdlind(500, '1', 'EXC', 'CON') [ierr, var_ppc_setp] = psspy.mdlind(500, '1', 'EXC', 'VAR') [ierr, var_ppc_mode] = psspy.mdlind(500, '1', 'EXC', 'ICON') [ierr, var_inv1_con] = psspy.mdlind(500, '1', 'GEN', 'CON')
xscopf.write("A" + str(Row), 'Case') xscopf.write("B" + str(Row), 'err_code') Row = Row + 1 psspy.psseinit(100000) _i = psspy.getdefaultint() _f = psspy.getdefaultreal() _s = psspy.getdefaultchar() print('start SCOPF analysis for case: ' + case) psspy.psseinit(1000000) #psspy.case(case) #this is for sav file psspy.read(0, case + '.raw') #this is for raw file psspy.fnsl([0, 0, 0, 1, 1, 0, 0, 0]) # Change remote voltage set point if 1: print( '------------------ change remote bus for all generators to self (0) ---------' ) ierr, iarray = psspy.amachint(-1, 1, 'NUMBER') MachBus = iarray[0] for imach in range(0, len(MachBus)): ierr = psspy.plant_chng(MachBus[imach], intgar1=0) print( '------------------ finished change remote bus for all generators to self (0) ---------' )
load_change_region3) change_load(load_bus_region[0], load_change_region1) change_load(load_bus_region[1], load_change_region2) change_load(load_bus_region[2], load_change_region3) change_gen(gen_bus_region[0], loadIncrement_region1) change_gen(gen_bus_region[1], loadIncrement_region2) change_gen(gen_bus_region[2], loadIncrement_region3) savecase = 'ieee118bus_divided_temp.sav' psspy.save(savecase) # secure or not psspy.case(savecase) psspy.fnsl() # check convergency N = psspy.solved() [bus_voltage, bus_angle] = powerlib.getMeasurements(response_buses) # check voltage violation if N == 0: # get bus measurements number [bus_voltage, bus_angle] = powerlib.getMeasurements(response_buses) voltage_violation = 0 for vol_index in range(0, len(bus_voltage)): if bus_voltage[vol_index] <= 0.844: voltage_violation = 1
def calculate_nr(self, model_path, logger): """ PSS/E funkce vyuzivajici Newton-Raphson metodu pro vypocet chodu site. Kombinuje ruzne nastaveni metody, aby se pokusila najit reseni. @return: Vraci jednotku v pripade chyby. Pro detail chyby je potreba proverit API dokumentaci PSS/E """ # Automaticke aplikovani mezi jaloviny s non diverge solution psspy.save(model_path[:-4] + '.sav') psspy.case(model_path[:-4] + '.sav') with redirected_stdout() as fake_stdout: ierr = psspy.fnsl([0, 0, 0, 0, 0, 1, 99, 1]) if ierr != 0: logger.error( "Chyba modelu pri vypoctu chodu site. PSS/E chyba: {}".format( ierr)) return 1 ierr, ibus, cmpval = psspy.maxmsm() bestsol = [(cmpval.real**2 + cmpval.imag**2)**0.5, 1, 99] if (cmpval.real**2 + cmpval.imag**2)**0.5 < 0.1 and ierr == 0: logger.info( "Newton Raphson Load Flow reseni nalezeno. Flatstart: 1," " meze jaloveho vykonu aplikovany automaticky, non-divergent solution 1." ) return 0 # Automaticke aplikovani mezi jaloviny bez non-divergent reseni. psspy.case(model_path[:-4] + '.sav') with redirected_stdout() as fake_stdout: ierr = psspy.fnsl([0, 0, 0, 0, 0, 1, 99, 0]) if ierr != 0: logger.error( "Chyba modelu pri vypoctu chodu site. PSS/E chyba: {}".format( ierr)) return 1 ierr, ibus, cmpval = psspy.maxmsm() if (cmpval.real**2 + cmpval.imag**2)**0.5 < bestsol[0]: bestsol = [(cmpval.real**2 + cmpval.imag**2)**0.5, 1, 99] if (cmpval.real**2 + cmpval.imag**2)**0.5 < 0.1 and ierr == 0: logger.info( "Newton Raphson Load Flow reseni nalezeno. Flatstart: 1," " meze jaloveho vykonu aplikovany automaticky, non-divergent solution 0." ) return 0 with redirected_stdout() as fake_stdout: ierr = psspy.fnsl([0, 0, 0, 0, 0, 0, 99, 1]) if ierr != 0: logger.error( "Chyba modelu pri vypoctu chodu site. PSS/E chyba: {}".format( ierr)) return 1 ierr, ibus, cmpval = psspy.maxmsm() bestsol = [(cmpval.real**2 + cmpval.imag**2)**0.5, 1, 99] if (cmpval.real**2 + cmpval.imag**2)**0.5 < 0.1 and ierr == 0: logger.info( "Newton Raphson Load Flow reseni nalezeno. Flatstart: 0," " meze jaloveho vykonu aplikovany automaticky, non-divergent solution 1." ) return 0 # Automaticke aplikovani mezi jaloviny bez non-divergent reseni. psspy.case(model_path[:-4] + '.sav') with redirected_stdout() as fake_stdout: ierr = psspy.fnsl([0, 0, 0, 0, 0, 0, 99, 0]) if ierr != 0: logger.error( "Chyba modelu pri vypoctu chodu site. PSS/E chyba: {}".format( ierr)) return 1 ierr, ibus, cmpval = psspy.maxmsm() if (cmpval.real**2 + cmpval.imag**2)**0.5 < bestsol[0]: bestsol = [(cmpval.real**2 + cmpval.imag**2)**0.5, 1, 99] if (cmpval.real**2 + cmpval.imag**2)**0.5 < 0.1 and ierr == 0: logger.info( "Newton Raphson Load Flow reseni nalezeno. Flatstart: 0," " meze jaloveho vykonu aplikovany automaticky, non-divergent solution 0." ) return 0 # Aplikovani mezi jaloviny pri ruznych iteracich iteration = range(20) for flatstart in [0, 1]: for nondivergentsolution in [0, 1]: for varlimits in iteration: psspy.case(model_path[:-4] + '.sav') with redirected_stdout() as fake_stdout: ierr = psspy.fnsl([ 0, 0, 0, 0, 0, flatstart, varlimits, nondivergentsolution ]) if ierr != 0: logger.error( "Chyba modelu pri vypoctu chodu site. PSS/E chyba: {}" .format(ierr)) return 1 ierr, ibus, cmpval = psspy.maxmsm() if (cmpval.real**2 + cmpval.imag**2)**0.5 < bestsol[0]: bestsol = [(cmpval.real**2 + cmpval.imag**2)**0.5, flatstart, varlimits] if (cmpval.real**2 + cmpval.imag**2)**0.5 < 0.1 and ierr == 0: logger.info( "Newton Raphson Load Flow reseni nalezeno. Flatstart: {}," " Aplikace mezi Q pri iteraci: {}, , non-divergent solution {}." .format(flatstart, varlimits, nondivergentsolution)) return 0 psspy.case(model_path[:-4] + '.sav') with redirected_stdout() as fake_stdout: ierr = psspy.fnsl([0, 0, 0, 0, 0, 1, -1, 0]) if ierr != 0: logger.error( "Chyba modelu pri vypoctu chodu site. PSS/E chyba: {}".format( ierr)) return 1 ierr, ibus, cmpval = psspy.maxmsm() if (cmpval.real**2 + cmpval.imag**2)**0.5 < bestsol[0]: bestsol = [(cmpval.real**2 + cmpval.imag**2)**0.5, 1, -1] if (cmpval.real**2 + cmpval.imag**2)**0.5 < 0.1 and ierr == 0: logger.info( "Newton Raphson Load Flow reseni nalezeno. Flatstart: {}," " meze jaloveho vykonu ignorovany, non-divergent solution 0.". format(flatstart)) return 0 psspy.case(model_path[:-4] + '.sav') with redirected_stdout() as fake_stdout: ierr = psspy.fnsl([0, 0, 0, 0, 0, bestsol[1], bestsol[2], 0]) if ierr != 0: logger.error( "Chyba modelu pri vypoctu chodu site. PSS/E chyba: {}".format( ierr)) return 1 ierr, ibus, cmpval = psspy.maxmsm() logger.error("Newton Raphson Load Flow reseni modelu nebylo nalezeno. " "Maximalni meziiteracni chyba: {}".format( (cmpval.real**2 + cmpval.imag**2)**0.5)) return 1