Skip to content

Commit

Permalink
removed f06 make_alt; forces units are closer
Browse files Browse the repository at this point in the history
redoing the way units are handled
  • Loading branch information
SteveDoyle2 committed Nov 30, 2024
1 parent 9e05821 commit 1b904bc
Show file tree
Hide file tree
Showing 7 changed files with 171 additions and 110 deletions.
88 changes: 58 additions & 30 deletions pyNastran/f06/flutter_response.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ def __repr__(self) -> str:
#imach : 3
#iq : 10
#ivelocity : 4
#make_alt : False
#method : 'PKNL'
#modes : array([1, 2])
#names : ['kfreq', '1/kfreq', 'density', 'velocity', 'damping', 'freq', 'eigr', 'eigi', 'eas', 'q', 'alt']
Expand Down Expand Up @@ -74,7 +73,6 @@ def __repr__(self) -> str:
#ieigr : 5
#ifreq : 4
#mach : 0.0
#make_alt : False
)
return msg

Expand Down Expand Up @@ -185,8 +183,7 @@ def __init__(self, subcase: int, configuration: str,
mach: float, density_ratio: float, method: str,
modes: list[int], results: Any,
f06_units: None | str | dict[str, str]=None,
out_units: None | str | dict[str, str]=None,
make_alt: bool=False) -> None:
out_units: None | str | dict[str, str]=None) -> None:
"""
Parameters
----------
Expand Down Expand Up @@ -244,7 +241,6 @@ def __init__(self, subcase: int, configuration: str,
unused
"""
self.make_alt = make_alt
self.f06_units = f06_units
self.out_units = out_units
required_keys = ['altitude', 'velocity', 'eas', 'density', 'dynamic_pressure']
Expand Down Expand Up @@ -300,7 +296,7 @@ def __init__(self, subcase: int, configuration: str,
raise NotImplementedError(method)

self.results = results
self.convert_units(self.f06_units, self.out_units)
self._set_data(self.f06_units, self.out_units)

# c - cyan
# b - black
Expand Down Expand Up @@ -329,9 +325,9 @@ def __init__(self, subcase: int, configuration: str,
self._colors: list[str] = []
self.generate_symbols()

def convert_units(self,
in_units: Optional[str | dict[str, str]],
out_units: Optional[str | dict[str, str]]) -> None:
def _set_data(self,
in_units: Optional[str | dict[str, str]],
out_units: Optional[str | dict[str, str]]) -> None:
in_units2 = get_flutter_units(in_units)
out_units2 = get_flutter_units(out_units)
results = self.results
Expand All @@ -345,6 +341,27 @@ def convert_units(self,
raise NotImplementedError(self.method)
self.results = results

def convert_units(self, out_units: Optional[str | dict[str, str]]) -> None:

out_units2 = get_flutter_units(out_units)
kvel = _get_unit_factor(self.out_units, out_units2, 'velocity')[0]
keas = _get_unit_factor(self.out_units, out_units2, 'eas')[0]
kdensity = _get_unit_factor(self.out_units, out_units2, 'density')[0]
kpressure = _get_unit_factor(self.out_units, out_units2, 'dynamic_pressure')[0]
kalt = _get_unit_factor(self.out_units, out_units2, 'altitude')[0]

self.results[:, :, self.ivelocity] *= kvel
if self.method in ['PK', 'KE']:
pass
elif self.method == 'PKNL':
self.results[:, :, self.idensity] *= kdensity
self.results[:, :, self.iq] *= kpressure
self.results[:, :, self.ieas] *= keas
self.results[:, :, self.ialt] *= kalt
else: # pragma: no cover
raise NotImplementedError(self.method)
self.out_units = out_units2

def _set_pknl_results(self,
in_units: dict[str, str],
out_units: dict[str, str],
Expand All @@ -362,12 +379,17 @@ def _set_pknl_results(self,
rho_ref = atm_density(0., R=1716., alt_units='ft',
density_units=density_units_in)

q = 0.5 * rho * vel**2
#eas = (2 * q / rho_ref)**0.5
rho_units_in = in_units['density']
vel_units_in = in_units['velocity']
q_units_in = in_units['dynamic_pressure']
if _is_q_units_consistent(rho_units_in, vel_units_in, q_units_in):
q = 0.5 * rho * vel**2
else: # pragma: no cover
raise NotImplementedError((rho_units_in, vel_units_in, q_units_in))

#eas = (2 * q / rho_ref)**0.5
# eas = V * sqrt(rho / rhoSL)
keas = _get_unit_factor(
in_units, out_units, 'eas')[0]
keas = _get_unit_factor(in_units, out_units, 'eas')[0]
eas = vel * np.sqrt(rho / rho_ref) * keas
#density_units2 = self.out_units['density']

Expand All @@ -382,21 +404,17 @@ def _set_pknl_results(self,
vel *= kvel
resultsi = results[:, :, :9]
assert resultsi.shape[2] == 9, resultsi.shape
if self.make_alt:
rho_in_slug_ft3 = rho * kdensityi
alt_ft = [get_alt_for_density(densityi, density_units='slug/ft^3',
alt_units='ft', nmax=20)
for densityi in rho_in_slug_ft3.ravel()]

ft_to_alt_unit = convert_altitude(1., 'ft', altitude_units)
alt = np.array(alt_ft, dtype='float64').reshape(vel.shape) * ft_to_alt_unit
rho_in_slug_ft3 = rho * kdensityi
alt_ft = [get_alt_for_density(densityi, density_units='slug/ft^3',
alt_units='ft', nmax=20)
for densityi in rho_in_slug_ft3.ravel()]

rho *= kdensity
results2 = np.dstack([resultsi, eas, q * kpressure, alt])
else:
#kpressure = 1.
rho *= kdensity
results2 = np.dstack([resultsi, eas, q * kpressure])
ft_to_alt_unit = convert_altitude(1., 'ft', altitude_units)
alt = np.array(alt_ft, dtype='float64').reshape(vel.shape) * ft_to_alt_unit

rho *= kdensity
results2 = np.dstack([resultsi, eas, q * kpressure, alt])

results2[:, :, self.idensity] = rho
results2[:, :, self.ivelocity] = vel
Expand Down Expand Up @@ -1584,24 +1602,23 @@ def _increment_jcolor(jcolor: int, color: str,

Limit = tuple[Optional[float], Optional[float]] | None
def set_xlim(axes: plt.Axes, xlim: Limit) -> None:
#print(f'xlim = {xlim}')
if xlim == [None, None]:# or xlim == (None, None):
xlim = None
if xlim is not None:
axes.set_xlim(xlim)

def set_ylim(axes: plt.Axes, ylim: Limit) -> None:
#print(f'ylim = {ylim}')
if ylim == [None, None]:# or ylim == (None, None):
ylim = None
if ylim is not None:
axes.set_ylim(ylim)


def _get_unit_factor(in_units, out_units,
def _get_unit_factor(in_units: dict[str, str],
out_units: dict[str, str],
name: str) -> tuple[float, str]:
if not in_units or not out_units:
msg = 'name=%r f06_units=%s out_units=%s' % (name, in_units, out_units)
msg = f'name={name!r} in_units={in_units} out_units={out_units}'
raise RuntimeError(msg)
unit_f06 = in_units[name]
unit_out = out_units[name]
Expand Down Expand Up @@ -1634,3 +1651,14 @@ def get_legend_kwargs(legend_kwargs: Optional[dict[str, Any]],
for key in legend_kwargs:
assert key in legend_kwargs_check, key
return legend_kwargs

def _is_q_units_consistent(rho_units: str, vel_units: str,
q_units: str) -> bool:
units = [
('kg/m^3', 'm/s', 'Pa'),
('Mg/mm^3', 'mm/s', 'MPa'),
('slug/ft^3', 'ft/s', 'psf'),
('slinch/in^3', 'in/s', 'psi'),
]
is_consistent = (rho_units, vel_units, q_units) in units
return is_consistent
16 changes: 7 additions & 9 deletions pyNastran/f06/gui_flutter.py
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ def on_browse_f06(self) -> None:
fname, wildcard_level = getopenfilename(
self, caption=title, basedir=basedir, filters=qt_wildcard,)
self.f06_filename_edit.setText(fname)
self.ok_button.setEnabled(False)

# @dontcrash
def on_load_settings(self) -> None:
Expand Down Expand Up @@ -676,14 +677,12 @@ def on_load_f06(self) -> None:
self.log.error(f"can't find {f06_filename}")
return
self.f06_filename_edit.setStyleSheet(QLINEEDIT_WHITE)
self.f06_filename = f06_filename
f06_units = self.units_in_pulldown.currentText()
out_units = self.units_out_pulldown.currentText()
try:
self.responses: FlutterResponse = make_flutter_response(
f06_filename,
f06_units=f06_units, out_units=out_units,
make_alt=True,
log=self.log)
except Exception as e:
self.log.error(str(e))
Expand All @@ -693,6 +692,7 @@ def on_load_f06(self) -> None:
if len(subcases) == 0:
self.log.error('No subcases found')
return
self.f06_filename = f06_filename
self._units_in = f06_units
self._units_out = out_units
self.add_recent_file(f06_filename)
Expand Down Expand Up @@ -759,6 +759,7 @@ def update_subcases(self, subcases: list[int]) -> None:
def update_modes_table(self, modes: list[int]) -> None:
self.modes = modes
self._set_modes_table(self.modes_widget, modes)
self.ok_button.setEnabled(True)
self.log.info(f'modes = {self.modes}')

def on_modes(self) -> None:
Expand Down Expand Up @@ -854,12 +855,9 @@ def plot(self, modes: list[int]) -> None:
response = self.responses[self.subcase]

# you can change the output units without reloading
if self._units_in != self.units_in or self._units_out != self.units_out:
# go back to the nominal units
# _units_in was corrected to units_in
# and then we go to units_out
response.convert_units(self._units_out, self._units_in)
response.convert_units(self.units_in, self.units_out)
if self._units_out != self.units_out:
response.convert_units(self.units_out)
self._units_out = self.units_out

response.noline = noline
response.nopoints = nopoints
Expand Down Expand Up @@ -920,7 +918,7 @@ def plot(self, modes: list[int]) -> None:
response.export_to_csv(csv_filename, modes=modes)
if export_to_zona:
self.log.debug(f'writing {veas_filename}')
response.export_to_veas(veas_filename, modes=modes)
response.export_to_veas(veas_filename, modes=modes, xlim=None)
if export_to_f06:
self.log.debug(f'writing {f06_filename}')
response.export_to_f06(f06_filename, modes=modes)
Expand Down
13 changes: 3 additions & 10 deletions pyNastran/f06/parse_flutter.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@

def make_flutter_response(f06_filename: PathLike,
f06_units=None, out_units=None,
make_alt: bool=False,
log: Optional[SimpleLogger]=None) -> dict[int, FlutterResponse]:
"""
Creates the FlutterResponse object
Expand Down Expand Up @@ -105,8 +104,7 @@ def make_flutter_response(f06_filename: PathLike,
flutter = FlutterResponse(subcase, configuration, xysym, xzsym,
mach, density_ratio, method,
modes, results,
f06_units=f06_units, out_units=out_units,
make_alt=make_alt)
f06_units=f06_units, out_units=out_units)
#_remove_neutrinos(flutter, log)
flutters[subcase] = flutter
modes = []
Expand Down Expand Up @@ -260,15 +258,13 @@ def make_flutter_response(f06_filename: PathLike,
flutter = FlutterResponse(subcase, configuration, xysym, xzsym,
mach, density_ratio, method,
modes, results,
f06_units=f06_units, out_units=out_units,
make_alt=make_alt)
f06_units=f06_units, out_units=out_units)
flutters[subcase] = flutter
return flutters

def plot_flutter_f06(f06_filename: PathLike,
f06_units: Optional[dict[str, str]]=None,
out_units: Optional[dict[str, str]]=None,
make_alt: bool=False,
plot_type: str='tas',
modes: Optional[list[int]]=None,
plot_vg: bool=False,
Expand Down Expand Up @@ -366,11 +362,8 @@ def plot_flutter_f06(f06_filename: PathLike,
"""
assert vd_limit is None or isinstance(vd_limit, float_types), vd_limit
assert damping_limit is None or isinstance(damping_limit, float_types), damping_limit
if plot_type == 'alt':
make_alt = True

flutters = make_flutter_response(
f06_filename, f06_units=f06_units, out_units=out_units, make_alt=make_alt, log=log)
f06_filename, f06_units=f06_units, out_units=out_units, log=log)

if plot:
make_flutter_plots(modes, flutters, xlim, ylim_damping, ylim_freq, ylim_kfreq,
Expand Down
30 changes: 16 additions & 14 deletions pyNastran/f06/test/test_f06_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
- plot sol_145
"""
import os
from pathlib import Path
import unittest

import numpy as np
Expand Down Expand Up @@ -42,8 +43,9 @@


DIRNAME = os.path.dirname(__file__)
PKG_PATH = pyNastran.__path__[0]
MODEL_PATH = os.path.join(PKG_PATH, '..', 'models')
PKG_PATH = Path(pyNastran.__path__[0])
MODEL_PATH = PKG_PATH / '..' / 'models'
AERO_PATH = MODEL_PATH / 'aero'


class TestF06Flutter(unittest.TestCase):
Expand Down Expand Up @@ -78,22 +80,22 @@ def test_make_grid_point_singularity_table(self):
def test_f06_pt145(self):
"""tests read_f06_trim"""
log = get_logger2(log=None, debug=None, encoding='utf-8')
f06_filename = os.path.join(MODEL_PATH, 'aero', 'pt145.f06')
f06_filename = AERO_PATH / 'pt145.f06'
#trim_results = read_f06_trim(f06_filename,
# log=None, nlines_max=1_000_000, debug=None)
#assert len(trim_results.aero_force.keys()) == 0
#assert len(trim_results.aero_pressure.keys()) == 0
#assert len(trim_results.controller_state.keys()) == 0
#assert len(trim_results.trim_variables.keys()) == 0
#assert len(trim_results.structural_monitor_loads.keys()) == 4
argv = ['f06', 'plot_145', f06_filename, '--tas',
argv = ['f06', 'plot_145', str(f06_filename), '--tas',
'--out_units', 'english_in']
cmd_line_plot_flutter(argv=argv, plot=IS_MATPLOTLIB,
show=False, log=log)

def test_plot_flutter_bah(self):
"""tests plot_flutter_f06"""
f06_filename = os.path.join(MODEL_PATH, 'aero', 'bah_plane', 'bah_plane.f06')
f06_filename = AERO_PATH / 'bah_plane' / 'bah_plane.f06'
log = get_logger2(log=None, debug=None, encoding='utf-8')
flutters = plot_flutter_f06(
f06_filename, show=False, close=True,
Expand All @@ -114,10 +116,10 @@ def test_plot_flutter_0012(self):
has issues with writing the subcase...
"""
f06_filename = os.path.join(MODEL_PATH, 'aero', '2_mode_flutter', '0012_flutter.f06')
f06_filename = AERO_PATH / '2_mode_flutter' / '0012_flutter.f06'
log = get_logger2(log=None, debug=None, encoding='utf-8')
plot_flutter_f06(
f06_filename, make_alt=True,
f06_filename,
modes=[2],
plot_type='alt',
f06_units='si', out_units='english_ft',
Expand All @@ -129,7 +131,7 @@ def test_plot_flutter_0012(self):

flutters = plot_flutter_f06(
f06_filename,
f06_units=None, out_units=None,
f06_units='si', out_units=None,
plot_vg=True, plot_vg_vf=True, plot_root_locus=True,
plot_kfreq_damping=True,
export_csv_filename='nastran.csv',
Expand Down Expand Up @@ -258,8 +260,8 @@ def test_plot_flutter_0012(self):

def test_cmd_line_plot_flutter_0012(self):
log = get_logger2(log=None, debug=None, encoding='utf-8')
f06_filename = os.path.join(MODEL_PATH, 'aero', '2_mode_flutter', '0012_flutter.f06')
argv = ['f06', 'plot_145', f06_filename, '--eas',
f06_filename = AERO_PATH / '2_mode_flutter' / '0012_flutter.f06'
argv = ['f06', 'plot_145', str(f06_filename), '--eas',
'--in_units', 'si', '--out_units', 'english_in',
'--modes', '1:', '--ylimdamp', '-.3:', '--export_csv', '--ncol', '2']
cmd_line_plot_flutter(argv=argv, plot=IS_MATPLOTLIB, show=False, log=log)
Expand All @@ -268,16 +270,16 @@ def test_cmd_line_plot_flutter_0012(self):
def test_cmd_line_plot_flutter_no_input_0012(self):
"""no input???"""
log = get_logger2(log=None, debug=None, encoding='utf-8')
f06_filename = os.path.join(MODEL_PATH, 'aero', '2_mode_flutter', '0012_flutter.f06')
argv = ['f06', 'plot_145', f06_filename, '--eas',
f06_filename = AERO_PATH / '2_mode_flutter' / '0012_flutter.f06'
argv = ['f06', 'plot_145', str(f06_filename), '--eas',
'--out_units', 'english_in']
flutters = cmd_line_plot_flutter(argv=argv, plot=IS_MATPLOTLIB, show=False, log=log)
cmd_line_f06(argv=argv, plot=IS_MATPLOTLIB, show=False, log=log)

def test_fix_modes_0012(self):
log = SimpleLogger(level='warning')
f06_filename = os.path.join(MODEL_PATH, 'aero', '2_mode_flutter', '0012_flutter.f06')
flutter = make_flutter_response(f06_filename, log=log)[1]
f06_filename = AERO_PATH / '2_mode_flutter' / '0012_flutter.f06'
flutter = make_flutter_response(f06_filename, f06_units='si', log=log)[1]
fix_modes_2024(flutter)

def test_fix_modes_constant(self):
Expand Down
Loading

0 comments on commit 1b904bc

Please sign in to comment.