diff --git a/pyNastran/bdf/test/test_bdf.py b/pyNastran/bdf/test/test_bdf.py index 89b3b60f9..52c920f79 100644 --- a/pyNastran/bdf/test/test_bdf.py +++ b/pyNastran/bdf/test/test_bdf.py @@ -441,6 +441,7 @@ def run_and_compare_fems( """runs two fem models and compares them""" assert os.path.exists(bdf_model), f'{bdf_model!r} doesnt exist\n%s' % print_bad_path(bdf_model) fem1 = BDF(debug=debug, log=log) + is_lax_parser = True if is_lax_parser: fem1.log.warning('using lax card parser') fem1.is_strict_card_parser = False diff --git a/pyNastran/f06/dev/flutter/gui_flutter.py b/pyNastran/f06/dev/flutter/gui_flutter.py index 58ff5be2c..27da9a46e 100644 --- a/pyNastran/f06/dev/flutter/gui_flutter.py +++ b/pyNastran/f06/dev/flutter/gui_flutter.py @@ -4,6 +4,7 @@ import warnings import traceback from pathlib import Path +from functools import wraps from typing import Optional, Any #TYPE_CHECKING ICON_PATH = Path('') @@ -193,10 +194,23 @@ def setup_toolbar(self): #self.toolbar.setObjectName('main_toolbar') self.statusbar = self.statusBar() + def dont_crash(func): + @wraps(func) + def wrapper(self, *args, **kwargs): + # do something before `sum` + try: + result = func(self, *args, **kwargs) + except Exception as e: + self.log_error(str(traceback.format_exc())) + result = None + # do something after `sum` + return result + return wrapper + def set_f06(self, ifile: int) -> None: f06_filename = self.recent_files[ifile] self.f06_filename_edit.setText(f06_filename) - self.on_load_f06() + self.on_load_f06(None) def setup_modes(self): self.modes_widget = QListWidget(self) @@ -1071,8 +1085,8 @@ def on_set_font_size(self, font_size: int) -> None: font = make_font(font_size, is_bold=False) self.setFont(font) - # @dontcrash - def on_load_f06(self) -> None: + @dont_crash + def on_load_f06(self, event) -> None: f06_filename = os.path.abspath(self.f06_filename_edit.text()) if not os.path.exists(f06_filename) or not os.path.isfile(f06_filename): self.f06_filename_edit.setStyleSheet(QLINEEDIT_RED) @@ -1228,19 +1242,20 @@ def on_ok(self) -> None: #self.log.warning('on_ok; _save') self._save(self.save_filename) - # @dontcrash + @dont_crash def plot(self, modes: list[int]) -> None: - self.log.info(f'plot; modes = {modes}\n') + log = self.log + log.info(f'plot; modes = {modes}\n') if not self.is_valid: - self.log.warning(f'not valid\n') + log.warning(f'not valid\n') return if len(self.responses) == 0: - self.log.warning(f'no subcases\n') + log.warning(f'no subcases\n') return x_plot_type = self.x_plot_type plot_type = self.plot_type - self.log.info(f'plot_type = {plot_type}\n') + log.info(f'plot_type = {plot_type}\n') noline = not self.show_lines nopoints = not self.show_points @@ -1248,7 +1263,7 @@ def plot(self, modes: list[int]) -> None: freq_tol = self.freq_tol freq_tol_remove = self.freq_tol_remove mag_tol = self.mag_tol - self.log.info(f'freq_tol = {freq_tol}\n') + log.info(f'freq_tol = {freq_tol}\n') if noline and nopoints: noline = False nopoints = True @@ -1264,14 +1279,14 @@ def plot(self, modes: list[int]) -> None: elif x_plot_type == 'q': xlim = self.q_lim else: # pragma: no cover - self.log.error(f'x_plot_type={x_plot_type!r} is not supported') + log.error(f'x_plot_type={x_plot_type!r} is not supported') #raise RuntimeError(x_plot_type) xlim = self.xlim - #self.log.info(f'xlim={xlim}\n') + #log.info(f'xlim={xlim}\n') assert xlim[0] != '' and xlim[1] != '', (xlim, x_plot_type) v_lines = [] - #self.log.info(f'vf={self.vf!r}; vl={self.vl!r}\n') + #log.info(f'vf={self.vf!r}; vl={self.vl!r}\n') if isinstance(self.vf, float) and self.vf > 0.: # name, velocity, color, linestyle v_lines.append(('VF', self.vf, 'r', '-')) @@ -1284,19 +1299,19 @@ def plot(self, modes: list[int]) -> None: v_lines.append(('VL', self.vl, 'k', '--')) v_lines.append(('1.15*VL', 1.15*self.vl, 'k', '-')) - #self.log.info(f'v_lines={v_lines}\n') - #self.log.info(f'kfreq_lim={self.kfreq_lim}\n') - #self.log.info(f'ydamp_lim={self.ydamp_lim}\n') - #self.log.info(f'freq_lim={self.freq_lim}\n') - #self.log.info(f'damping={self.damping}\n') + #log.info(f'v_lines={v_lines}\n') + #log.info(f'kfreq_lim={self.kfreq_lim}\n') + #log.info(f'ydamp_lim={self.ydamp_lim}\n') + #log.info(f'freq_lim={self.freq_lim}\n') + #log.info(f'damping={self.damping}\n') xlim_kfreq = self.kfreq_lim ylim_damping = self.ydamp_lim ylim_freq = self.freq_lim damping_limit = self.damping # % damping # changing directory so we don't make a long filename - # in teh plot header - #self.log.info(f'damping_limit = {damping_limit}\n') + # in the plot header + #log.info(f'damping_limit = {damping_limit}\n') dirname = os.path.abspath(os.path.dirname(self.f06_filename)) basename = os.path.basename(self.f06_filename) @@ -1307,7 +1322,7 @@ def plot(self, modes: list[int]) -> None: fig = plt.figure(1) fig.clear() - self.log.info(f'cleared plot\n') + log.info(f'cleared plot\n') if plot_type not in {'root-locus', 'modal-participation'}: gridspeci = gridspec.GridSpec(2, 4) damp_axes = fig.add_subplot(gridspeci[0, :3]) @@ -1318,21 +1333,22 @@ def plot(self, modes: list[int]) -> None: # you can change the output units without reloading if self._units_out != self.units_out: response.convert_units(self.units_out) - self._units_out = self.units_out + self._units_out = self.units_out response.noline = noline response.set_symbol_settings( nopoints, self.show_mode_number, self.point_spacing) + log.info(f'self.plot_font_size = {self.plot_font_size}') response.set_font_settings(self.plot_font_size) - response.log = self.log + response.log = log #print('trying plots...') - self.log.info(f'getting logs\n') + log.info(f'getting logs\n') log_scale_x = self.data['log_scale_x'] log_scale_y1 = self.data['log_scale_y1'] log_scale_y2 = self.data['log_scale_y2'] print(f'log_scale_x={log_scale_x}; log_scale_y1={log_scale_y1}; log_scale_y2={log_scale_y2}') - print(f'export_to_png={self.export_to_png}') + #print(f'export_to_png={self.export_to_png}') self.export_to_png = False png_filename0, png_filename = get_png_filename( @@ -1342,8 +1358,8 @@ def plot(self, modes: list[int]) -> None: try: if plot_type == 'root-locus': axes = fig.add_subplot(111) - #self.log.info(f'modes={modes}; eigr_lim={self.eigr_lim}; eigi_lim={self.eigi_lim}; freq_tol={freq_tol}') - #self.log.info(f'png_filename={png_filename}') + #log.info(f'modes={modes}; eigr_lim={self.eigr_lim}; eigi_lim={self.eigi_lim}; freq_tol={freq_tol}') + #log.info(f'png_filename={png_filename}') response.plot_root_locus( fig=fig, axes=axes, modes=modes, eigr_lim=self.eigr_lim, eigi_lim=self.eigi_lim, @@ -1356,7 +1372,7 @@ def plot(self, modes: list[int]) -> None: axes = fig.add_subplot(111) mode = self.mode_edit.value() ivel = self.velocity_edit.currentIndex() - print(f'ivel={ivel}; mode={mode}') + #print(f'ivel={ivel}; mode={mode}') response.plot_modal_participation( ivel, mode, fig=fig, axes=axes, @@ -1385,10 +1401,10 @@ def plot(self, modes: list[int]) -> None: else: assert plot_type in 'x-damp-freq', plot_type #print('plot_vg_vf') - #self.log.info(f'png_filename={png_filename!r}') - #self.log.info(f'modes={modes!r}') - #self.log.info(f'freq_tol={freq_tol!r}') - #self.log.info(f'v_lines={v_lines!r}') + #log.info(f'png_filename={png_filename!r}') + #log.info(f'modes={modes!r}') + #log.info(f'freq_tol={freq_tol!r}') + #log.info(f'v_lines={v_lines!r}') response.plot_vg_vf( fig=fig, damp_axes=damp_axes, freq_axes=freq_axes, plot_type=x_plot_type, @@ -1404,9 +1420,10 @@ def plot(self, modes: list[int]) -> None: png_filename=png_filename, ) update_ylog_style(fig, log_scale_x, log_scale_y1, log_scale_y2) + fig.canvas.draw() except Exception as e: # pragma: no cover - self.log.error(f'plot_type={plot_type}') - self.log.error(str(e)) + log.error(f'plot_type={plot_type}') + log.error(str(e)) print(traceback.format_exc()) #print(traceback.print_tb()) print(traceback.print_exception(e)) @@ -1417,16 +1434,19 @@ def plot(self, modes: list[int]) -> None: veas_filename = base2 + '.export.veas' f06_filename = base2 + '.export.f06' if self.export_to_csv: - self.log.debug(f'writing {csv_filename}') + log.debug(f'writing {csv_filename}') response.export_to_csv(csv_filename, modes=modes) if self.export_to_zona: - self.log.debug(f'writing {veas_filename}') + log.debug(f'writing {veas_filename}') response.export_to_veas(veas_filename, modes=modes, xlim=None) if self.export_to_f06: - self.log.debug(f'writing {f06_filename}') + log.debug(f'writing {f06_filename}') response.export_to_f06(f06_filename, modes=modes) os.chdir(current_directory) - self.log.info(f'saved {png_filename}') + if png_filename: + log.info(f'saved {png_filename}') + else: + log.info(f'did not write file because export_to_png=False') def get_xlim(self) -> tuple[Limit, Limit, Limit, Limit, Limit, Limit, Limit, Limit, Limit, diff --git a/pyNastran/f06/dev/flutter/utils.py b/pyNastran/f06/dev/flutter/utils.py index 6eef1140c..4185bacaf 100644 --- a/pyNastran/f06/dev/flutter/utils.py +++ b/pyNastran/f06/dev/flutter/utils.py @@ -15,16 +15,26 @@ def load_f06_op2(f06_filename: str, log: SimpleLogger, in_units: str, out_units: str, use_rhoref: bool) -> tuple[OP2, dict[int, FlutterResponse]]: - if not os.path.exists(f06_filename): - log.error(f'Cant find {f06_filename}') - return + """ + load a Vg-Vf plot from: + - OP2 / F06 + - dict[subcase: int, FlutterResponse] + From an OP2, load: + - eigenvectors, vg_vf_response + From an F06, load: + - vg_vf_response + """ model = None responses = {} + if not os.path.exists(f06_filename): + log.error(f'Cant find {f06_filename}') + return model, responses + in_units_dict = get_flutter_units(in_units) out_units_dict = get_flutter_units(out_units) ext = os.path.splitext(f06_filename)[1].lower() - print(f'use_rhoref={use_rhoref}') + #print(f'use_rhoref={use_rhoref}') if ext == '.f06': try: responses: FlutterResponse = make_flutter_response( diff --git a/pyNastran/f06/flutter_response.py b/pyNastran/f06/flutter_response.py index 425af3816..4023f2499 100644 --- a/pyNastran/f06/flutter_response.py +++ b/pyNastran/f06/flutter_response.py @@ -1,3 +1,9 @@ +""" +TODO: + - more control of font sizes + - control over point size / text annotation size + - +""" from __future__ import annotations from copy import deepcopy import warnings @@ -8,6 +14,7 @@ import scipy import scipy.interpolate try: + import matplotlib import matplotlib.pyplot as plt import matplotlib.gridspec as gridspec from matplotlib.lines import Line2D @@ -386,7 +393,7 @@ def __init__(self, subcase: int, configuration: str, self._colors: list[str] = [] self.generate_symbols() self.set_symbol_settings() - self.set_font_settings() + self.set_font_settings(font_size=None) def set_symbol_settings(self, nopoints: bool=False, show_mode_number: bool=False, @@ -395,8 +402,18 @@ def set_symbol_settings(self, nopoints: bool=False, self.show_mode_number = show_mode_number self.point_spacing = point_spacing - def set_font_settings(self, font_size: int=13) -> None: + def set_font_settings(self, font_size: Optional[int]=13) -> None: # TODO: split label, title, tic_marks, legend + if font_size is None: + font_size = plt.rcParams['font.size'] + + #print(f'font_size = {font_size}') + font = { + #'family': 'normal', + #'weight': 'bold', + 'size': font_size, + } + matplotlib.rc('font', **font) self.font_size = font_size def set_out_units(self, out_units: str | dict[str, str]) -> None: @@ -549,8 +566,8 @@ def plot_complex_modes(self): ax22.plot(self.eigenvector[:, imode2].imag, label=f'iMode2={imode2+1}') plt.legend() - ax11.set_ylabel('Real', fontsize=self.font_size) - ax12.set_ylabel('Imaginary', fontsize=self.font_size) + ax11.set_ylabel('Real') #, fontsize=self.font_size) + ax12.set_ylabel('Imaginary') #, fontsize=self.font_size) for ax in axes.ravel(): ax.grid(True) ax.set_xlim([0, nmodes]) @@ -815,11 +832,11 @@ def plot_modal_participation(self, ivel: int, mode: int, if np.isfinite(velocityi): title += f' V={velocityi:.1f}' #print(title) - axes.set_title(title, fontsize=self.font_size) + axes.set_title(title) #, fontsize=self.font_size) axes.grid(True) - axes.set_xlabel(xlabel, fontsize=self.font_size) - axes.set_ylabel(ylabel, fontsize=self.font_size) - axes.tick_params(axis='both', which='major', labelsize=self.font_size) + axes.set_xlabel(xlabel) #, fontsize=self.font_size) + axes.set_ylabel(ylabel) #, fontsize=self.font_size) + axes.tick_params(axis='both', which='major') #, labelsize=self.font_size) #print(f'eigr_eigi_velocity:\n{self.eigr_eigi_velocity}') #print(f'eigenvector:\n{self.eigenvector}') @@ -884,8 +901,8 @@ def plot_modal_participation(self, ivel: int, mode: int, #print(label) axes.scatter(reali, imagi, label=label, alpha=0.7) #print(f'{i}: {reali}, {imagi}, {text!r}') - axes.text(reali, imagi, text, ha='center', va='center', - fontsize=self.font_size) + axes.text(reali, imagi, text, ha='center', va='center') + #fontsize=self.font_size) if legend: # bbox_to_anchor=(1.125, 1.), ncol=ncol, @@ -965,6 +982,7 @@ def _plot_x_y(self, ix: int, iy: int, linestyle=linestyle2, markersize=0) if ivelocity and symbol2 and ivelocity < len(xs): + # single point selected for modes plotting corresponding to ivelocity markersize = 10 plot_kwargs = { 'color': 'k', 'marker': 'o', @@ -972,6 +990,8 @@ def _plot_x_y(self, ix: int, iy: int, axes.scatter(xs[ivelocity], ys[ivelocity], **plot_kwargs) if scatter: + # used for the root locus + # velocity increases driving an incrase in the point size scatteri = np.linspace(.75, 50., len(xs)) #assert symbol[2] == '-', symbol #axes.scatter(xs[iplot], ys[iplot], s=scatteri, color=symbol[0], marker=symbol[1]) @@ -980,9 +1000,9 @@ def _plot_x_y(self, ix: int, iy: int, #print(f'setting grid...') axes.grid(True) #axes.set_xlabel(xlabel + '; _plot_x_y', fontsize=self.font_size) - axes.set_xlabel(xlabel, fontsize=self.font_size) - axes.set_ylabel(ylabel, fontsize=self.font_size) - axes.tick_params(axis='both', which='major', labelsize=self.font_size) + axes.set_xlabel(xlabel) #, fontsize=self.font_size) + axes.set_ylabel(ylabel) #, fontsize=self.font_size) + axes.tick_params(axis='both', which='major') #, labelsize=self.font_size) set_xlim(axes, xlim) set_ylim(axes, ylim) @@ -1012,7 +1032,10 @@ def _plot_x_y2(self, ix: int, iy1: int, iy2: int, png_filename=None, **legend_kwargs): """ - Builds the plot + Builds the plot with 2 subplots for: + - Vg, Vf + - Vg, Vk + - kg, kf Parameters ---------- @@ -1072,7 +1095,8 @@ def _plot_x_y2(self, ix: int, iy1: int, iy2: int, # plot the line label = _get_mode_freq_label(mode, freq[0]) - legend_element = Line2D([0], [0], color=color2, marker=symbol2, label=label, linestyle=linestyle2) + legend_element = Line2D([0], [0], color=color2, + marker=symbol2, label=label, linestyle=linestyle2) if self.nopoints: symbol2 = 'None' @@ -1081,6 +1105,7 @@ def _plot_x_y2(self, ix: int, iy1: int, iy2: int, # self.log.info(f'y1s={y1s[iplot]}') # self.log.info(f'y2s={y2s[iplot]}') if scatter: + # when velocity increases, point size increases scatteri = np.linspace(.75, 50., len(xs)) #assert symbol[2] == '-', symbol axes1.scatter(xs[iplot], y1s[iplot], @@ -1107,15 +1132,15 @@ def _plot_x_y2(self, ix: int, iy1: int, iy2: int, legend_elements.append(legend_element) axes1.grid(True) - axes1.set_xlabel(xlabel, fontsize=self.font_size) + axes1.set_xlabel(xlabel) #, fontsize=self.font_size) #axes1.set_xlabel(xlabel + '; _plot_x_y2', fontsize=self.font_size) - axes1.set_ylabel(ylabel1, fontsize=self.font_size) + axes1.set_ylabel(ylabel1) #, fontsize=self.font_size) axes2.grid(True) - axes2.set_xlabel(xlabel, fontsize=self.font_size) - axes2.set_ylabel(ylabel2, fontsize=self.font_size) - axes1.tick_params(axis='both', which='major', labelsize=self.font_size) - axes2.tick_params(axis='both', which='major', labelsize=self.font_size) + axes2.set_xlabel(xlabel) #, fontsize=self.font_size) + axes2.set_ylabel(ylabel2) #, fontsize=self.font_size) + axes1.tick_params(axis='both', which='major') #, labelsize=self.font_size) + axes2.tick_params(axis='both', which='major') #, labelsize=self.font_size) title = f'Subcase {self.subcase:d}' if png_filename: @@ -1369,27 +1394,27 @@ def plot_vg_vf(self, fig=None, damp_axes=None, freq_axes=None, modes=None, imodes_crossing, xcrossing_dict, colors_show, symbols_show) - damp_axes.set_xlabel(xlabel, size=self.font_size) - freq_axes.set_xlabel(xlabel, size=self.font_size) - damp_axes.set_ylabel(r'Structural Damping; $g = 2 \gamma $', fontsize=self.font_size) + damp_axes.set_xlabel(xlabel) #, size=self.font_size) + freq_axes.set_xlabel(xlabel) #, size=self.font_size) + damp_axes.set_ylabel(r'Structural Damping; $g = 2 \gamma $') #, fontsize=self.font_size) freq_axes.set_ybound(lower=0.) damp_axes.grid(True) set_xlim(damp_axes, xlim) set_ylim(damp_axes, ylim_damping) - freq_axes.set_ylabel('Frequency [Hz]', fontsize=self.font_size) + freq_axes.set_ylabel('Frequency [Hz]') #, fontsize=self.font_size) freq_axes.grid(True) set_xlim(freq_axes, xlim) set_ylim(freq_axes, ylim_freq) - freq_axes.tick_params(axis='both', which='major', labelsize=self.font_size) - damp_axes.tick_params(axis='both', which='major', labelsize=self.font_size) + freq_axes.tick_params(axis='both', which='major') #, labelsize=self.font_size) + damp_axes.tick_params(axis='both', which='major') #, labelsize=self.font_size) title = f'Subcase {self.subcase}' if png_filename: title += '\n%s' % png_filename - damp_axes.set_title(title, fontsize=self.font_size) + damp_axes.set_title(title) #, fontsize=self.font_size) #plt.suptitle(title) _add_damping_limit(plot_type, damp_axes, damping_limit) @@ -2200,8 +2225,8 @@ def get_legend_kwargs(font_size: int, #if 'prop' not in legend_kwargs: #legend_kwargs['prop'] = {'size': font_size} - if 'fontsize' not in legend_kwargs: - legend_kwargs['fontsize'] = font_size + #if 'fontsize' not in legend_kwargs: + #legend_kwargs['fontsize'] = font_size return legend_kwargs @@ -2285,33 +2310,35 @@ def _plot_two_axes(damp_axes: plt.Axes, freq_axes: plt.Axes, label: str, text: str, point_spacing: int, markersize=None) -> None: #point_spacing2 = None if point_spacing == 0 else point_spacing + 1 + + # setup for plotting every Nth point point_spacing2 = point_spacing + 1 if point_spacing2 == 1: point_spacing2 = None vel2 = vel[::point_spacing2] damping2 = damping[::point_spacing2] freq2 = freq[::point_spacing2] - # assert len(vel2) > 0, point_spacing - # assert len(damping2) > 0, point_spacing - # assert len(freq2) > 0, point_spacing - # print('point_spacing = ', point_spacing) - # print(f'symbol, text = {symbol!r}, {text!r}') + if point_spacing2 is None: + # plot all points and lines (default) damp_axes.plot(vel, damping, color=color, marker=symbol, markersize=markersize, linestyle=linestyle, label=label) freq_axes.plot(vel, freq, color=color, marker=symbol, markersize=markersize, linestyle=linestyle) elif symbol or text or linestyle: - print(point_spacing2, symbol, text, linestyle) + # draw lines with all points damp_axes.plot(vel, damping, color=color, linestyle=linestyle, label=label) freq_axes.plot(vel, freq, color=color, linestyle=linestyle) + if symbol: + # plot every other point (for reduced clutter) damp_axes.scatter(vel2, damping2, color=color, marker=symbol, s=markersize, label=label) - freq_axes.scatter(vel2, freq2, color=color, marker=symbol, s=markersize, ) + freq_axes.scatter(vel2, freq2, color=color, marker=symbol, s=markersize) #else: # pragma: no cover # raise NotImplementedError(f'point_spacing={point_spacing}; symbol={symbol!r}; text={text!r}') if text: + # annotate the mode number for xi, y1i, y2i in zip(vel2, damping2, freq2): - damp_axes.text(xi, y1i, text, color=color) - freq_axes.text(xi, y2i, text, color=color) + damp_axes.text(xi, y1i, text, color=color, clip_on=True) + freq_axes.text(xi, y2i, text, color=color, clip_on=True) def _show_save_clear_close(fig: plt.Figure, show: bool, diff --git a/pyNastran/op2/op2_interface/op2_scalar.py b/pyNastran/op2/op2_interface/op2_scalar.py index 672a95b2e..71fd07427 100644 --- a/pyNastran/op2/op2_interface/op2_scalar.py +++ b/pyNastran/op2/op2_interface/op2_scalar.py @@ -60,6 +60,7 @@ def log_exc(*args, **kwargs): from pyNastran import is_release, __version__ +from pyNastran.utils import PathLike, is_binary_file from pyNastran.f06.errors import FatalError from pyNastran.op2.errors import EmptyRecordError from pyNastran.op2.op2_interface.op2_reader import OP2Reader, reshape_bytes_block @@ -74,7 +75,6 @@ def log_exc(*args, **kwargs): from pyNastran.op2.op2_interface.read_matrix import read_matrix from pyNastran.op2.fortran_format import FortranFormat -from pyNastran.utils import is_binary_file from pyNastran.op2.result_objects.grid_point_weight import GridPointWeight """ ftp://161.24.15.247/Nastran2011/seminar/SEC04-DMAP_MODULES.pdf @@ -427,7 +427,7 @@ def log_exc(*args, **kwargs): # vbaop2_test b'STABFEM', } -def _check_unique_sets(*sets: list[set[str]]): +def _check_unique_sets(*sets: list[set[str]]) -> None: """verifies that the sets are unique""" for i, seti in enumerate(sets): for unused_j, setj in enumerate(sets[i+1:]): @@ -478,7 +478,7 @@ def modal_effective_weight(self): def matrix_tables(self): return MATRIX_TABLES - def set_as_nx(self): + def set_as_nx(self) -> None: self.is_nx = True self.is_msc = False self.is_autodesk = False @@ -486,7 +486,7 @@ def set_as_nx(self): self.is_optistruct = False self._nastran_format = 'nx' - def set_as_msc(self): + def set_as_msc(self) -> None: self.is_nx = False self.is_msc = True self.is_autodesk = False @@ -494,7 +494,7 @@ def set_as_msc(self): self.is_optistruct = False self._nastran_format = 'msc' - def set_as_autodesk(self): + def set_as_autodesk(self) -> None: self.is_nx = False self.is_msc = False self.is_autodesk = True @@ -502,7 +502,7 @@ def set_as_autodesk(self): self.is_optistruct = False self._nastran_format = 'autodesk' - def set_as_nasa95(self): + def set_as_nasa95(self) -> None: self.is_nx = False self.is_msc = False self.is_autodesk = False @@ -515,7 +515,7 @@ def set_as_nasa95(self): if hasattr(self, 'reader_geom2') and hasattr(self.reader_geom2, '_read_cquad4_nasa95'): self.reader_geom2.geom2_map[(5408, 54, 261)] = ['CQUAD4', self.reader_geom2._read_cquad4_nasa95] - def set_as_optistruct(self): + def set_as_optistruct(self) -> None: self.is_nx = False self.is_msc = False self.is_autodesk = False @@ -523,7 +523,7 @@ def set_as_optistruct(self): self.is_optistruct = True self._nastran_format = 'optistruct' - def __init__(self, debug=False, log=None, debug_file=None): + def __init__(self, debug: bool=False, log=None, debug_file=None): """ Initializes the OP2_Scalar object @@ -579,7 +579,7 @@ def __init__(self, debug=False, log=None, debug_file=None): self.op2_reader = OP2Reader(self) - def set_subcases(self, subcases=None): + def set_subcases(self, subcases=None) -> None: """ Allows you to read only the subcases in the list of isubcases @@ -606,7 +606,7 @@ def set_subcases(self, subcases=None): self.valid_subcases = set(subcases) self.log.debug(f'set_subcases - subcases = {self.valid_subcases}') - def set_transient_times(self, times): # TODO this name sucks... + def set_transient_times(self, times) -> None: # TODO this name sucks... """ Takes a dictionary of list of times in a transient case and gets the output closest to those times. @@ -1596,9 +1596,9 @@ def _read_mpf_3(self, data, ndata: int) -> int: self._read_title(data) self._write_debug_bits() - def _read_mpf_4(self, data: bytes, ndata: int): + def _read_mpf_4(self, data: bytes, ndata: int) -> int: """unused""" - if self.read_mode == 1: # or self.table_name_str not in ['OFMPF2M']: + if self.read_mode == 1: # or self.table_name_str not in ['OFMPF2M']: return ndata #print(self.table_name_str, ndata, self.num_wide) # 176 #self.show_ndata(100, types='ifs') @@ -1826,27 +1826,27 @@ def _read_pvto_4_helper(self, data: bytes, ndata: int) -> int: #print(param.rstrip()) return nvalues - def _not_available(self, data: bytes, ndata: int): + def _not_available(self, data: bytes, ndata: int) -> None: """testing function""" if ndata > 0: raise RuntimeError('this should never be called...' f'table_name={self.table_name!r} len(data)={ndata}') - def _table_crasher(self, data: bytes, ndata: int): + def _table_crasher(self, data: bytes, ndata: int) -> int: """auto-table crasher""" if self.is_debug_file: self.binary_debug.write(f' crashing table = {self.table_name}\n') raise NotImplementedError(self.table_name) return ndata - def _nx_table_passer(self, data, ndata: int): + def _nx_table_passer(self, data, ndata: int) -> int: """auto-table skipper""" desc = self.op2_reader.desc_map.get(self.table_name, '???') #assert desc != '???', self.table_name self.to_nx(f' because table_name={self.table_name} ({desc}) was found') self._table_passer(data, ndata) - def _table_passer(self, data, ndata: int): + def _table_passer(self, data, ndata: int) -> int: """auto-table skipper""" if self.is_debug_file: self.binary_debug.write(f' skipping table = {self.table_name}\n') @@ -1888,7 +1888,7 @@ def _validate_op2_filename(self, op2_filename: Optional[str]) -> str: assert op2_filename is not None, op2_filename return op2_filename - def _create_binary_debug(self): + def _create_binary_debug(self) -> None: """Instatiates the ``self.binary_debug`` variable/file""" if hasattr(self, 'binary_debug') and self.binary_debug is not None: self.binary_debug.close() @@ -1897,7 +1897,8 @@ def _create_binary_debug(self): self.is_debug_file, self.binary_debug = create_binary_debug( self.op2_filename, self.debug_file, self.log) - def _setup_filenames(self, op2_filename: Optional[str], force: bool=True): + def _setup_filenames(self, op2_filename: Optional[str], + force: bool=True) -> None: if op2_filename: fname = os.path.splitext(op2_filename)[0] self.op2_filename = op2_filename @@ -1906,7 +1907,7 @@ def _setup_filenames(self, op2_filename: Optional[str], force: bool=True): self.des_filename = fname + '.des' self.h5_filename = fname + '.h5' - def read_op2(self, op2_filename=None, + def read_op2(self, op2_filename: Optional[PathLike]=None, combine: bool=False, load_as_h5: bool=False, h5_file=None, @@ -1962,7 +1963,7 @@ def read_op2(self, op2_filename=None, if self.read_mode != 2: op2_filename = self._validate_op2_filename(op2_filename) - self.log.info(f'op2_filename = {op2_filename!r}') + self.log.info(f'op2_filename = {str(op2_filename)!r}') self._setup_filenames(op2_filename, force=True) if not is_binary_file(op2_filename): if os.path.getsize(op2_filename) == 0: @@ -2014,7 +2015,7 @@ def read_op2(self, op2_filename=None, #self.remove_unpickable_data() return table_names - def close_op2(self, force=True): + def close_op2(self, force: bool=True) -> None: """closes the OP2 and debug file""" if self.is_debug_file: self.binary_debug.write('-' * 80 + '\n') @@ -2032,7 +2033,7 @@ def close_op2(self, force=True): self._cleanup_words() #self.op2_reader.h5_file.close() - def _cleanup_words(self): + def _cleanup_words(self) -> None: """ Remove internal parameters that are not useful and just clutter the object attributes. @@ -2068,7 +2069,7 @@ def _cleanup_words(self): if hasattr(self, word): delattr(self, word) - def _setup_op2(self): + def _setup_op2(self) -> None: """ Does preliminary op2 tasks like: - open the file @@ -2124,7 +2125,7 @@ def _setup_op2(self): if self.read_mode == 1: self._set_structs(size) - def _make_tables(self): + def _make_tables(self) -> None: return #global RESULT_TABLES, NX_RESULT_TABLES, MSC_RESULT_TABLES #table_mapper = self._get_table_mapper()