Source code for pyNastran.converters.tecplot.tecplot_to_nastran

"""
Defines:
 - tecplot_to_nastran(tecplot_filename, bdf_filename, debug=True)
 - tecplot_to_nastran(tecplot_filename, bdf_filename, debug=True)

"""
from __future__ import annotations
from typing import Union, List, Optional, TYPE_CHECKING
import numpy as np
from pyNastran.bdf.bdf import BDF
from pyNastran.bdf.mesh_utils.remove_unused import remove_unused
from pyNastran.bdf.field_writer_8 import print_card_8
from pyNastran.converters.tecplot.tecplot import Tecplot, Zone, read_tecplot
if TYPE_CHECKING:  # pragma: no cover
    from cpylog import SimpleLogger


[docs]def tecplot_to_nastran_filename(tecplot_filename: Union[str, Tecplot], bdf_filename: str, log: Optional[SimpleLogger]=None, debug: bool=True) -> BDF: """Converts a Tecplot file to Nastran.""" return tecplot_to_nastran(tecplot_filename, bdf_filename, log=log, debug=debug)
[docs]def tecplot_to_nastran(tecplot_filename: Union[str, Tecplot], bdf_filename: str, log: Optional[SimpleLogger]=None, debug: bool=True) -> None: """Converts a Tecplot file to Nastran.""" if isinstance(tecplot_filename, str): model = read_tecplot(tecplot_filename, log=log, debug=debug) else: model = tecplot_filename zone = model.zones[0] removed_nodes = False shell_pid = 1 solid_pid = 2 mid = 1 istart = 1 with open(bdf_filename, 'w') as bdf_file: bdf_file.write('$pyNastran : punch=True\n') for inode, node in enumerate(zone.xyz): card = ['GRID', inode + 1, None,] + list(node) bdf_file.write(print_card_8(card)) itri = 0 if len(zone.tri_elements): # tris only for itri, tri in enumerate(zone.tri_elements): card = ['CTRIA3', itri + 1, shell_pid] + list(tri) bdf_file.write(print_card_8(card)) #istart += bdf_model if len(zone.quad_elements): if len(zone.tri_elements) != 0: # if there are tris, then we assume the quads are good for iquad, quad in enumerate(zone.quad_elements): card = ['CQUAD4', iquad + 1, shell_pid] + list(quad) bdf_file.write(print_card_8(card)) else: # need to split out the CQUAD4 elements istart = itri + 1 for iquad, quad in enumerate(zone.quad_elements): if quad[2] == quad[3]: # if it's a tri card = ['CTRIA3', istart + iquad, shell_pid] + list(quad[:3]) else: card = ['CQUAD4', istart + iquad, shell_pid] + list(quad) bdf_file.write(print_card_8(card)) istart += iquad if len(zone.tri_elements) + len(zone.quad_elements): card = ['PSHELL', shell_pid, mid, 0.1] bdf_file.write(print_card_8(card)) if len(zone.tet_elements) + len(zone.hexa_elements): card = ['PSOLID', solid_pid, mid] bdf_file.write(print_card_8(card)) if len(zone.tet_elements): for itet, tet in enumerate(zone.tet_elements): card = ['CTETRA', istart + itet, solid_pid] + list(tet) bdf_file.write(print_card_8(card)) if len(zone.hexa_elements): # need to split out the CTETRA and CPENTA elements for ihex, hexa in enumerate(zone.hexa_elements): uhexa = np.unique(hexa) nnodes_unique = len(uhexa) nids = hexa[:nnodes_unique] centroid_y = zone.xyz[nids, 1].max() if centroid_y < 0: removed_nodes = True continue if nnodes_unique == 4: card = ['CTETRA', istart + ihex, solid_pid] + list(nids) assert len(card) == 7, len(card) elif nnodes_unique == 5: card = ['CPYRAM', istart + ihex, solid_pid] + list(nids) assert len(card) == 8, len(card) elif nnodes_unique == 6: card = ['CPENTA', istart + ihex, solid_pid] + list(nids) assert len(card) == 9, len(card) elif nnodes_unique == 8: card = ['CHEXA', istart + ihex, solid_pid] + list(hexa) bdf_file.write(print_card_8(card)) E = 3.0e7 G = None nu = 0.3 card = ['MAT1', mid, E, G, nu] bdf_file.write(print_card_8(card)) if removed_nodes: bdf_model = BDF(debug=debug) bdf_model.read_bdf(bdf_filename) remove_unused(bdf_model)
[docs]def nastran_table_to_tecplot(bdf_model: BDF, case, variables: List[str]) -> Tecplot: """assumes only triangles""" xyz = [] tris = [] nid_map = {} for inid, (nid, node) in enumerate(sorted(bdf_model.nodes.items())): xyz.append(node.get_position()) nid_map[nid] = inid for eid, elem in sorted(bdf_model.elements.items()): tris.append([nid_map[nid] for nid in elem.node_ids]) tecplot_model = Tecplot(log=bdf_model.log, debug=bdf_model.debug) zone = Zone(bdf_model.log) zone.xyz = np.array(xyz, dtype='float64') zone.tri_elements = tris = np.array(tris, dtype='int32') + 1 tecplot_model.title = ('%s; %s' % (case.title, case.subtitle)).strip(' ;') zone.headers_dict['VARIABLES'] = variables zone.variables = variables tecplot_model.zones = [zone] return tecplot_model
[docs]def nastran_tables_to_tecplot_filenames(tecplot_filename_base: str, bdf_model: BDF, case, variables: Optional[List[str]]=None, ivars: Optional[List[int]]=None) -> None: if variables is None: variables = case.headers if ivars is None: ivars = np.arange(0, len(variables)) tecplot_model = nastran_table_to_tecplot(bdf_model, case, variables) zone = tecplot_model.zones[0] for itime, time in enumerate(case._times): if '%' in tecplot_filename_base: tecplot_filename = tecplot_filename_base % time else: tecplot_filename = tecplot_filename_base # you can't combine the two lines or it transposes it... nodal_results = case.data[itime, :, :] zone.nodal_results = nodal_results[:, ivars] tecplot_model.write_tecplot( tecplot_filename, res_types=None, adjust_nids=False)