def report(self, x_name=None, **kwargs): """ Save eigenvalue analysis reports. Returns ------- None """ if x_name is None: x_name = self.x_name text, header, rowname, data = list(), list(), list(), list() neig = len(self.mu) mu_real = self.mu.real() mu_imag = self.mu.imag() n_positive = sum(1 for x in mu_real if x > 0) n_zeros = sum(1 for x in mu_real if x == 0) n_negative = sum(1 for x in mu_real if x < 0) numeral = [] for idx, item in enumerate(range(neig)): if mu_real[idx] == 0: marker = '*' elif mu_real[idx] > 0: marker = '**' else: marker = '' numeral.append('#' + str(idx + 1) + marker) # compute frequency, un-damped frequency and damping freq = [0] * neig ufreq = [0] * neig damping = [0] * neig for idx, item in enumerate(self.mu): if item.imag == 0: freq[idx] = 0 ufreq[idx] = 0 damping[idx] = 0 else: ufreq[idx] = abs(item) / 2 / pi freq[idx] = abs(item.imag / 2 / pi) damping[idx] = -div(item.real, abs(item)) * 100 # obtain most associated variables var_assoc = [] for prow in range(neig): temp_row = self.part_fact[prow, :] name_idx = list(temp_row).index(max(temp_row)) var_assoc.append(x_name[name_idx]) pf = [] for prow in range(neig): temp_row = [] for pcol in range(neig): temp_row.append(round(self.part_fact[prow, pcol], 5)) pf.append(temp_row) # opening info section text.append(report_info(self.system)) header.append(None) rowname.append(None) data.append(None) text.append('') header.append(['']) rowname.append(['EIGENVALUE ANALYSIS REPORT']) data.append('') text.append('STATISTICS\n') header.append(['']) rowname.append(['Positives', 'Zeros', 'Negatives']) data.append([n_positive, n_zeros, n_negative]) text.append('EIGENVALUE DATA\n') header.append([ 'Most Associated', 'Real', 'Imag.', 'Damped Freq.', 'Frequency', 'Damping [%]' ]) rowname.append(numeral) data.append( [var_assoc, list(mu_real), list(mu_imag), freq, ufreq, damping]) n_cols = 7 # columns per block n_block = int(ceil(neig / n_cols)) if n_block <= 100: for idx in range(n_block): start = n_cols * idx end = n_cols * (idx + 1) text.append('PARTICIPATION FACTORS [{}/{}]\n'.format( idx + 1, n_block)) header.append(numeral[start:end]) rowname.append(x_name) data.append(pf[start:end]) dump_data(text, header, rowname, data, self.system.files.eig) logger.info('Report saved to "%s".', self.system.files.eig)
def dump_results(self): """ Save eigenvalue analysis reports Returns ------- None """ system = self.system mu = self.mu partfact = self.part_fact if system.files.no_output: return text = [] header = [] rowname = [] data = [] neig = len(mu) mu_real = mu.real() mu_imag = mu.imag() npositive = sum(1 for x in mu_real if x > 0) nzero = sum(1 for x in mu_real if x == 0) nnegative = sum(1 for x in mu_real if x < 0) numeral = [] for idx, item in enumerate(range(neig)): if mu_real[idx] == 0: marker = '*' elif mu_real[idx] > 0: marker = '**' else: marker = '' numeral.append('#' + str(idx + 1) + marker) # compute frequency, undamped frequency and damping freq = [0] * neig ufreq = [0] * neig damping = [0] * neig for idx, item in enumerate(mu): if item.imag == 0: freq[idx] = 0 ufreq[idx] = 0 damping[idx] = 0 else: freq[idx] = abs(item) / 2 / pi ufreq[idx] = abs(item.imag / 2 / pi) damping[idx] = -div(item.real, abs(item)) * 100 # obtain most associated variables var_assoc = [] for prow in range(neig): temp_row = partfact[prow, :] name_idx = list(temp_row).index(max(temp_row)) var_assoc.append(system.dae.x_name[name_idx]) pf = [] for prow in range(neig): temp_row = [] for pcol in range(neig): temp_row.append(round(partfact[prow, pcol], 5)) pf.append(temp_row) text.append('') header.append(['']) rowname.append(['EIGENVALUE ANALYSIS REPORT']) data.append('') text.append('STATISTICS\n') header.append(['']) rowname.append(['Positives', 'Zeros', 'Negatives']) data.append([npositive, nzero, nnegative]) text.append('EIGENVALUE DATA\n') header.append([ 'Most Associated', 'Real', 'Imag', 'Damped Freq.', 'Frequency', 'Damping [%]' ]) rowname.append(numeral) data.append( [var_assoc, list(mu_real), list(mu_imag), ufreq, freq, damping]) cpb = 7 # columns per block nblock = int(ceil(neig / cpb)) if nblock <= 100: for idx in range(nblock): start = cpb * idx end = cpb * (idx + 1) text.append('PARTICIPATION FACTORS [{}/{}]\n'.format( idx + 1, nblock)) header.append(numeral[start:end]) rowname.append(system.dae.x_name) data.append(pf[start:end]) dump_data(text, header, rowname, data, system.files.eig) logger.info(f'Report saved to <{system.files.eig}>.')
def write(self): """ Write report to file. """ system = self.system if system.files.no_output is True: return text = list() header = list() row_name = list() data = list() self.update() t, _ = elapsed() # ---------------------------------------- # info section text.append(self.info) header.append(None) row_name.append(None) data.append(None) # ---------------------------------------- # ---------------------------------------- # summary section text.append(['Statistics:\n']) header.append(None) row_name.append(self.basic.keys()) data.append(list(self.basic.values())) # ---------------------------------------- if len(self.extended): text.append(['EXTENDED SUMMARY:\n']) header.append(['P (pu)', 'Q (pu)']) row_name.append(['Generation', 'Load']) Pcol = [ self.extended['Pg'], self.extended['Pl'], ] Qcol = [ self.extended['Qg'], self.extended['Ql'], ] data.append([Pcol, Qcol]) if system.PFlow.converged: # ---------------------------------------- # Bus data angle_unit = 'deg.' if system.PFlow.config.degree else 'rad.' angles = np.rad2deg(system.Bus.a.v) \ if system.PFlow.config.degree == 1 else system.Bus.a.v text.append(['BUS DATA:\n']) header.append(['Bus Name', 'Vm(pu)', f'Va({angle_unit})']) row_name.append(system.Bus.idx.v) data.append([system.Bus.name.v, system.Bus.v.v, angles]) # ---------------------------------------- # ---------------------------------------- # Node data if hasattr(system, 'Node') and system.Node.n: text.append(['NODE DATA:\n']) header.append(['Node Name', 'V(pu)']) row_name.append(system.Node.idx.v) data.append([system.Node.name.v, system.Node.v.v]) # ---------------------------------------- # ---------------------------------------- # Line data text.append(['LINE DATA:\n']) header.append([ 'Line Name', 'Fr. Bus (idx)', 'To Bus (idx)', 'P From (pu)', 'Q From (pu)', 'P To (pu)', 'Q To (pu)' ]) row_name.append(system.Line.idx.v) data.append([ system.Line.name.v, system.Line.bus1.v, system.Line.bus2.v, system.Line.a1.e, system.Line.v1.e, system.Line.a2.e, system.Line.v2.e ]) # ---------------------------------------- # ---------------------------------------- # Additional Algebraic data text.append(['OTHER ALGEBRAIC VARIABLES:\n']) header.append(['']) row_name.append(system.dae.y_name[2 * system.Bus.n:system.dae.m]) data.append([round(i, 6) for i in system.dae.y[2 * system.Bus.n:]]) # Additional State variable data if system.dae.n: text.append(['OTHER STATE VARIABLES:\n']) header.append(['']) row_name.append(system.dae.x_name[:]) data.append([round(i, 6) for i in system.dae.x[:]]) dump_data(text, header, row_name, data, system.files.txt) _, s = elapsed(t) logger.info(f'Report saved to "{system.files.txt}" in {s}.')
def report(self, x_name=None, **kwargs): """ Save eigenvalue analysis reports. Returns ------- None """ if x_name is None: x_name = self.x_name n_states = len(self.mu) mu_real = self.mu.real mu_imag = self.mu.imag freq, ufreq, damping, numeral = self.post_process() # obtain most associated variables var_assoc = [] for prow in range(n_states): temp_row = self.pfactors[prow, :] name_idx = list(temp_row).index(max(temp_row)) var_assoc.append(x_name[name_idx]) text, header, rowname, data = list(), list(), list(), list() # opening info section text.append(report_info(self.system)) header.append(None) rowname.append(None) data.append(None) text.append('') text.append('EIGENVALUE ANALYSIS REPORT') header.append([]) rowname.append([]) data.append([]) text.append('STATISTICS\n') header.append(['']) rowname.append(['Positives', 'Zeros', 'Negatives']) data.append((self.n_positive, self.n_zeros, self.n_negative)) text.append('EIGENVALUE DATA\n') header.append([ 'Most Associated', 'Real', 'Imag.', 'Damped Freq.', 'Frequency', 'Damping [%]' ]) rowname.append(numeral) data.append( [var_assoc, list(mu_real), list(mu_imag), freq, ufreq, damping]) n_cols = 7 # columns per block n_block = int(ceil(n_states / n_cols)) if n_block <= 100: for idx in range(n_block): start = n_cols * idx end = n_cols * (idx + 1) text.append('PARTICIPATION FACTORS [{}/{}]\n'.format( idx + 1, n_block)) header.append(numeral[start:end]) rowname.append(x_name) data.append(self.pfactors[start:end, :]) dump_data(text, header, rowname, data, self.system.files.eig) logger.info('Report saved to "%s".', self.system.files.eig)