Source code for pyNastran.converters.nastran.nastran_to_cart3d

"""
defines:
 - cart3d = nastran_to_cart3d(bdf, log=None, debug=False)
 - nastran_to_cart3d_filename(bdf_filename, cart3d_filename,
                              log=None, debug=False)

"""
import numpy as np

from pyNastran.converters.cart3d.cart3d import Cart3D

LINE_ELEMENTS = ['CBAR', 'CBEAM', 'CROD', 'CELAS1', 'CELAS2', 'CELAS3', 'CELAS4']
from pyNastran.bdf.bdf import BDF


[docs] def nastran_to_cart3d(bdf: BDF, log=None, debug: bool=False) -> Cart3D: """ Converts a Nastran BDF() object to a Cart3D() object. Parameters ---------- bdf : BDF() a BDF object log : log; default=None -> dummyLogger a logger object debug : bool; default=False True/False (used if log is not defined) Returns ------- cart3d : Cart3D() a Cart3D object """ cart3d = Cart3D(log=log, debug=debug) nnodes, nelements = nnodes_nelements(bdf) nodes = np.zeros((nnodes, 3), 'float64') elements = np.zeros((nelements, 3), 'int32') regions = np.zeros(nelements, 'int32') nids = np.array(list(bdf.nodes.keys()), dtype='int32') nids_expected = np.arange(1, len(nids) + 1) if np.array_equal(nids, nids_expected): _store_sequential_nodes(bdf, nodes, elements, regions) else: #print('not equal...') #i = 0 nid_map = {} for node_id, node in sorted(bdf.nodes.items()): i = np.where(nids == node_id)[0][0] nodes[i, :] = node.get_position() nid_map[node_id] = i + 1 #print('nid_map =', nid_map) i = 0 for unused_element_id, element in sorted(bdf.elements.items()): if element.type in {'CTRIA3', 'CTRIAR'}: nids = element.node_ids elements[i, :] = [nid_map[nid] for nid in nids] regions[i] = element.pid elif element.type in {'CQUAD4', 'CQUADR'}: nids = element.node_ids quad = [nid_map[nid] for nid in nids] pid = element.pid # TODO: splits on edge 1-3, not the max angle # since we're just comparing the models, it doesn't matter elements[i, :] = [quad[0], quad[1], quad[2]] regions[i] = pid i += 1 elements[i, :] = [quad[0], quad[2], quad[3]] regions[i] = pid elif element.type in LINE_ELEMENTS: continue else: raise NotImplementedError(element.type) i += 1 assert elements.min() > 0, elements cart3d.nodes = nodes cart3d.elements = elements - 1 cart3d.regions = regions return cart3d
def _store_sequential_nodes(bdf: BDF, nodes, elements, regions) -> None: # we don't need to renumber the nodes # so we don't need to make an nid_map i = 0 for node_id, node in sorted(bdf.nodes.items()): nodes[i, :] = node.get_position() i += 1 j = 0 for unused_element_id, element in sorted(bdf.elements.items()): if element.type in {'CTRIA3', 'CTRIAR'}: nids = element.node_ids elements[j, :] = nids regions[j] = element.Pid() elif element.type in LINE_ELEMENTS: pass elif element.type in {'CQUAD4', 'CQUADR'}: nids = element.node_ids pid = element.Pid() elements[j, :] = nids[:-1] regions[j] = pid elements[j+1, :] = [nids[0], nids[2], nids[3]] regions[j+1] = pid j += 1 else: raise NotImplementedError(element.type) j += 1
[docs] def nastran_to_cart3d_filename(bdf_filename: str, cart3d_filename: str, log=None, debug: bool=False) -> None: """ Creates a Nastran BDF from a Cart3D file. Parameters ---------- bdf_filename : str the path to the bdf file cart3d_filename : str the path to the cart3d output file log : log; default=None -> dummyLogger a logger object debug : bool; default=False True/False (used if log is not defined) """ model = BDF(log=log, debug=debug) model.read_bdf(bdf_filename) nnodes, nelements = nnodes_nelements(model) log = model.log with open(cart3d_filename, 'w', encoding='utf8') as cart3d: cart3d.write('%s %s\n' % (nnodes, nelements)) node_id_shift = {} i = 1 for node_id, node in sorted(model.nodes.items()): node_id_shift[node_id] = i x, y, z = node.get_position() cart3d.write('%s %s %s\n' % (x, y, z)) i += 1 pids = '' j = 0 for unused_element_id, element in sorted(model.elements.items()): if element.type in ['CONM2']: continue card_type = element.type if card_type in {'CQUADR', 'CQUAD4'}: out = element.node_ids #print('element type=%s is not supported' % element.type) n1, n2, n3, n4 = out n1 = node_id_shift[n1] n2 = node_id_shift[n2] n3 = node_id_shift[n3] n4 = node_id_shift[n4] pid = element.pid cart3d.write('%i %i %i\n' % (n1, n2, n3)) cart3d.write('%i %i %i\n' % (n1, n3, n4)) pids += '%i ' % pid if j != 0 and j % 20 == 0: pids += '\n' j += 1 pids += '%i ' % pid if j != 0 and j % 20 == 0: pids += '\n' j += 1 elif card_type in {'CTRIA3', 'CTRIAR'}: out = element.node_ids n1, n2, n3 = out n1 = node_id_shift[n1] n2 = node_id_shift[n2] n3 = node_id_shift[n3] pid = element.pid cart3d.write('%i %i %i\n' % (n1, n2, n3)) pids += '%i ' % pid if j != 0 and j % 20 == 0: pids += '\n' j += 1 elif element.type in LINE_ELEMENTS: continue else: # pragma: no cover log.error(f'card_type={card_type} is not supported') raise NotImplementedError(element.type) #continue cart3d.write(pids + '\n')
[docs] def nnodes_nelements(bdf: BDF) -> tuple[int, int]: nnodes = len(bdf.nodes) nelements = 0 if 'CTRIA3' in bdf.card_count: nelements += bdf.card_count['CTRIA3'] if 'CTRIAR' in bdf.card_count: nelements += bdf.card_count['CTRIAR'] if 'CQUAD4' in bdf.card_count: nelements += bdf.card_count['CQUAD4'] * 2 if 'CQUADR' in bdf.card_count: nelements += bdf.card_count['CQUADR'] * 2 assert nelements > 0, bdf.card_count return nnodes, nelements