def _write_nodes_symmetric(self, outfile, size=8, is_double=False, plane='xz'): """ Writes the NODE-type cards Parameters ---------- self : BDF() the BDF object .. warning :: doesn't consider coordinate systems; it could, but you'd need 20 new coordinate systems .. warning :: doesn't mirror SPOINTs, EPOINTs """ if self.spoints: msg = [] msg.append('$SPOINTS\n') msg.append(self.spoints.write_card(size, is_double)) outfile.write(''.join(msg)) if self.epoints: msg = [] msg.append('$EPOINTS\n') msg.append(self.epoints.write_card(size, is_double)) outfile.write(''.join(msg)) plane = plane.strip().lower() if plane == 'xz': iy = 4 elif plane == 'xy': iy = 5 elif plane == 'yz': iy = 3 else: raise NotImplementedError(plane) if self.nodes: msg = [] msg.append('$NODES\n') if self.gridSet: msg.append(self.gridSet.print_card(size)) nid_offset = max(self.nodes.keys()) if self.is_long_ids: print_card_long = print_card_double if is_double else print_card_16 for (unused_nid, node) in sorted(iteritems(self.nodes)): repr_fields = node.repr_fields() msg.append(print_card_long(repr_fields)) repr_fields = node.repr_fields() # grid, nid, cp, x, y, z repr_fields[1] += nid_offset repr_fields[iy] *= -1.0 msg.append(print_card_long(repr_fields)) else: for (unused_nid, node) in sorted(iteritems(self.nodes)): repr_fields = node.repr_fields() msg.append(print_card_8(repr_fields)) repr_fields = node.repr_fields() # grid, nid, cp, x, y, z repr_fields[1] += nid_offset repr_fields[iy] *= -1.0 msg.append(print_card_8(repr_fields)) outfile.write(''.join(msg))
def write_card(self, size=8, is_double=False): msg = '\n$' + '-' * 80 msg += '\n$ %s Matrix %s\n' % ('DMI', self.name) list_fields = ['DMI', self.name, 0, self.form, self.tin, self.tout, None, self.nRows, self.nCols] if size == 8: msg += print_card_8(list_fields) #elif is_double: #msg += print_card_double(list_fields) else: msg += print_card_16(list_fields) #msg += self.print_card(list_fields,size=16,isD=False) if self.is_complex(): for (gci, gcj, reali, imagi) in zip(self.GCi, self.GCj, self.Real, self.Complex): list_fields = ['DMI', self.name, gcj, gci, reali, imagi] if size == 8: msg += print_card_8(list_fields) elif is_double: msg += print_card_double(list_fields) else: msg += print_card_16(list_fields) else: for (gci, gcj, reali) in zip(self.GCi, self.GCj, self.Real): list_fields = ['DMI', self.name, gcj, gci, reali] if size == 8: msg += print_card_8(list_fields) elif is_double: msg += print_card_double(list_fields) else: msg += print_card_16(list_fields) return msg
def assert_fields(card1, card2): try: fields1 = wipe_empty_fields(card1.repr_fields()) fields2 = wipe_empty_fields(card2.repr_fields()) except: print("card1 = \n%s" % (card1)) print("card2 = \n%s" % (card2)) raise if len(fields1) != len(fields2): msg = ('len(fields1)=%s len(fields2)=%s\n%r\n%r\n%s\n%s' % (len(fields1), len(fields2), fields1, fields2, print_card_8(fields1), print_card_8(fields2))) raise RuntimeError(msg) for (i, field1, field2) in zip(count(), fields1, fields2): value1a = print_field(field1) value2a = print_field(field2) if value1a != value2a: value1 = print_field(interpret_value(value1a)) value2 = print_field(interpret_value(value2a)) if value1 != value2: msg = 'value1 != value2\n' msg += ('cardName=%s ID=%s i=%s field1=%r field2=%r value1=%r ' 'value2=%r\n%r\n%r' % (fields1[0], fields1[1], i, field1, field2, value1, value2, fields1, fields2)) raise RuntimeError(msg)
def cart3d_to_nastran_filename(cart3d_filename, bdf_filename, log=None, debug=False): """ Converts a Cart3D file to Nastran format. Parameters ---------- cart3d_filename : str path to the input Cart3D file bdf_filename : str path to the output BDF file log : log / None log : a logger object None : a log will be defined debug : bool True/False (used if log is not defined) """ cart3d = Cart3D(log=log, debug=debug) cart3d.read_cart3d(cart3d_filename) nodes = cart3d.nodes elements = cart3d.elements regions = cart3d.regions #bdf = BDF() #bdf.nodes = cart3d.nodes #bdf.elements = cart3d.elements #bdf.write_bdf(bdf_filename) #return f = open(bdf_filename, 'wb') f.write('CEND\n') f.write('BEGIN BULK\n') f.write('$Nodes\n') i = 0 nid = 1 cid = 0 for node in nodes: card = print_card_16(['GRID', nid, cid] + list(node)) f.write(card) nid += 1 eid = 1 f.write('$Elements\n') for (n1, n2, n3), pid in zip(elements, regions): card = print_card_8(['CTRIA3', eid, pid, n1, n2, n3]) f.write(card) eid += 1 t = 0.1 E = 1e7 nu = 0.3 f.write('$Properties\n') for pid in unique(regions): mid = pid card = print_card_8(['PSHELL', pid, mid, t]) f.write(card) card = print_card_8(['MAT1', mid, E, None, nu]) f.write(card) f.write('ENDDATA\n') f.close()
def stl_to_nastran_filename(stl_filename, bdf_filename, nnodes_offset=0, nelements_offset=0, pid=100, mid=200, size=8, is_double=False, log=None): model = STLReader(log=log) model.read_stl(stl_filename) nid = nnodes_offset + 1 cid = None load_id = 10 nodal_normals = model.get_normals_at_nodes(model.elements) bdf = open(bdf_filename, 'wb') bdf.write('CEND\n') #bdf.write('LOAD = %s\n' % load_id) bdf.write('BEGIN BULK\n') nid2 = 1 magnitude = 100. if size == 8: print_card = print_card_8 elif size == 16: if is_double: print_card = print_card_16 else: print_card = print_card_double for x, y, z in model.nodes: card = ['GRID', nid, cid, x, y, z] bdf.write(print_card_16(card)) #nx, ny, nz = nodal_normals[nid2 - 1] #card = ['FORCE', load_id, nid, cid, magnitude, nx, ny, nz] #bdf.write(print_card_8(card)) nid += 1 nid2 += 1 eid = nelements_offset + 1 for (n1, n2, n3) in (model.elements + (nnodes_offset + 1)): card = ['CTRIA3', eid, pid, n1, n2, n3] bdf.write(print_card_8(card)) eid += 1 t = 0.1 card = ['PSHELL', pid, mid, t] bdf.write(print_card_8(card)) E = 1e7 G = None nu = 0.3 card = ['MAT1', mid, E, G, nu] bdf.write(print_card_8(card)) bdf.write('ENDDATA\n') bdf.close()
def write_card(self, size=8, is_double=False): """ .. todo:: support double precision """ msg = '\n$' + '-' * 80 msg += '\n$ %s Matrix %s\n' % (self.type, self.name) list_fields = [self.type, self.name, 0, self.ifo, self.tin, self.tout, self.polar, None, self.ncols] if size == 8: msg += print_card_8(list_fields) else: msg += print_card_16(list_fields) if self.is_complex(): if self.is_polar(): for (GCi, GCj, reali, complexi) in zip(self.GCi, self.GCj, self.Real, self.Complex): magi = sqrt(reali**2 + complexi**2) if reali == 0.0: phasei = 0.0 else: phasei = degrees(atan2(complexi, reali)) list_fields = [self.type, self.name, GCj[0], GCj[1], None, GCi[0], GCi[1], magi, phasei] if size == 8: msg += print_card_8(list_fields) elif is_double: msg += print_card_double(list_fields) else: msg += print_card_16(list_fields) else: for (GCi, GCj, reali, complexi) in zip(self.GCi, self.GCj, self.Real, self.Complex): list_fields = [self.type, self.name, GCj[0], GCj[1], None, GCi[0], GCi[1], reali, complexi] if size == 8: msg += print_card_8(list_fields) elif is_double: msg += print_card_double(list_fields) else: msg += print_card_16(list_fields) else: for (GCi, GCj, reali) in zip(self.GCi, self.GCj, self.Real): list_fields = [self.type, self.name, GCj[0], GCj[1], None, GCi[0], GCi[1], reali, None] if size == 8: msg += print_card_8(list_fields) elif is_double: msg += print_card_double(list_fields) else: msg += print_card_16(list_fields) return msg
def __repr__(self): thru_fields = collapse_thru(self.ids) #list_fields = ['SESET', self.seid] cards = [] while 'THRU' in thru_fields: ithru = thru_fields.index('THRU') card = print_card_8(['SESET', self.seid] + thru_fields[ithru - 1:ithru + 2]) cards.append(card) thru_fields = thru_fields[0:ithru - 1]+thru_fields[ithru + 2:] if thru_fields: card = print_card_8(['SESET', self.seid] + thru_fields) cards.append(card) return ''.join(cards)
def convert_ugrid2d_to_nastran(bdf_filename, nodes, tris, quads, cp=2000, pid=2000, mid=2000, axis_order=None, nid_start=1, eid_start=1, punch=True): if axis_order is not None: nodes = deepcopy(nodes[:, axis_order]) with open(bdf_filename, 'wb') as bdf_file: if not punch: bdf_file.write('CEND\n') bdf_file.write('BEGIN BULK\n') cp = None #card = ['CORD2R', cp, 0] + [0., 0., 0.] + [0., 0., 1.] + [1., 0., 0.] #f.write(print_card_8(card)) nid = nid_start for xi, yi, zi in nodes: # yes I'm aware...x is the axial distance # y/z are the x/y plane card = ['GRID', nid, cp, xi, yi, zi] bdf_file.write(print_card_8(card)) nid += 1 t = 0.1 card = ['PSHELL', pid, mid, t] 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)) eid = eid_start for n1, n2, n3 in tris + nid_start: card = ['CTRIA3', eid, pid, n1, n2, n3] bdf_file.write(print_int_card(card)) eid += 1 for n1, n2, n3, n5 in quads + nid_start: card = ['CQUAD4', eid, pid, n1, n2, n3, n5] bdf_file.write(print_int_card(card)) eid += 1 if not punch: bdf_file.write('ENDDATA\n')
def write_card(self, bdf_file, size=8): card = ['SPCADD', self.spc_id] + self.spc_ids #print("card = ", card) if size == 8: bdf_file.write(print_card_8(card)) else: bdf_file.write(print_card_16(card))
def write_card(self, bdf_file, size=8, element_ids=None): if self.n: if element_ids is None: i = arange(self.n) else: i = searchsorted(self.element_id, self.element_id) for (eid, pid, n, is_g0, g0, x, is_offt, offt, bit, pin, wa, wb, sa, sb) in zip( self.element_id[i], self.property_id[i], self.node_ids[i], self.is_g0[i], self.g0[i], self.x[i], self.is_offt[i], self.offt[i], self.bit[i], self.pin_flags[i], self.wa[i], self.wb[i], self.sa[i], self.sb[i]): x1 = g0 if is_g0 else x[0] x2 = 0 if is_g0 else x[1] x3 = 0 if is_g0 else x[2] offt_bit = offt if is_offt else bit #print('is_offt=%s offt=%s bit=%s offt_bit=%s' % (is_offt, offt, bit, offt_bit)) pa = set_blank_if_default(pin[0], 0) pb = set_blank_if_default(pin[1], 0) w1a = set_blank_if_default(wa[0], 0.0) w2a = set_blank_if_default(wa[1], 0.0) w3a = set_blank_if_default(wa[2], 0.0) w1b = set_blank_if_default(wb[0], 0.0) w2b = set_blank_if_default(wb[1], 0.0) w3b = set_blank_if_default(wb[2], 0.0) sa = set_blank_if_default(sa, 0) sb = set_blank_if_default(sb, 0) card = ['CBEAM', eid, pid, n[0], n[1], x1, x2, x3, offt_bit, pa, pb, w1a, w2a, w3a, w1b, w2b, w3b, sa, sb] bdf_file.write(print_card_8(card))
def test_mat11_01(self): lines = [ 'MAT11 1 1.+75000000. 700000. .1 .13 .267000000.+', '+ 9000000.3000000. .1 1.-5 7.-6 8.-6 50.', ] lines_expected = [ 'MAT11 1 1.+75000000. 700000. .1 .13 .267000000.', ' 9000000.3000000. .1 .00001 .000007 .000008 50.' ] card = bdf.process_card(lines) card = BDFCard(card) card2 = MAT11(card) fields = card2.raw_fields() msg = print_card_8(fields) #f = StringIO.StringIO() size = 8 msg = card2.write_card(size, 'dummy') #msg = f.getvalue() #print(msg) lines_actual = msg.rstrip().split('\n') msg = '\n%s\n\n%s' % ('\n'.join(lines_expected), msg) msg += 'nlines_actual=%i nlines_expected=%i' % (len(lines_actual), len(lines_expected)) #print(msg) self.assertEqual(len(lines_actual), len(lines_expected), msg) for actual, expected in zip(lines_actual, lines_expected): msg = '\nactual = %r\n' % actual msg += 'expected = %r' % expected self.assertEqual(actual, expected, msg)
def test_rbe1_02(self): lines = [ 'RBE1 1001 1000 123456', ' UM 1002 123 1003 123 1004 123', ' 1005 123 1006 123 1008 123', ' 1009 123 1010 123 1011 123', ' 1012 123', ] card = bdf.process_card(lines) #print(print_card_8(card)) card = BDFCard(card) rbe = RBE1.add_card(card) fields = rbe.raw_fields() msg = print_card_8(fields).rstrip() lines_expected = [ 'RBE1 1001 1000 123456', ' UM 1002 123 1003 123 1004 123', ' 1005 123 1006 123 1008 123', ' 1009 123 1010 123 1011 123', ' 1012 123', ] lines_actual = msg.rstrip().split('\n') msg = '\n%s\n\n%s\n' % ('\n'.join(lines_expected), msg) msg += 'nlines_actual=%i nlines_expected=%i' % (len(lines_actual), len(lines_expected)) self.assertEqual(len(lines_actual), len(lines_expected), msg) for actual, expected in zip(lines_actual, lines_expected): self.assertEqual(actual, expected, msg)
def write_card(self, bdf_file, size=8): card = ['NLPCI', self.nlpci_id, self.Type, self.minalr, self.maxalr, self.scale, None, self.desiter, self.mxinc] if size == 8: bdf_file.write(print_card_8(card)) else: bdf_file.write(print_card_16(card))
def write_card(self, size=8, is_double=False): card = self.raw_fields() if size == 8: return self.comment + print_card_8(card) if is_double: return self.comment + print_card_double(card) return self.comment + print_card_16(card)
def write_card(self, f, size, is_double, coord_id=None): assert size in [8, 16], size assert is_double in [True, False], is_double if self.n: #if coord_id is None: #i = arange(self.n) #else: #assert len(unique(coord_id))==len(coord_id), unique(coord_id) #i = searchsorted(self.coord_id, coord_id) if size == 8: print_cardi = print_card_8 elif is_double: print_cardi = print_card_double else: print_cardi = print_card_16 for cid, coord in iteritems(self.coords): if cid > 0: if coord.type in ['CORD1R', 'CORD1C', 'CORD1S']: card = [coord.type, cid, coord.g1, coord.g2, coord.g3] else: card = [coord.type, cid, coord.rid] + list(coord.e1) + list(coord.e2) + list(coord.e3) f.write(print_card_8(card))
def write_card(self, size=8, is_double=False): card = wipe_empty_fields(self.repr_fields()) if size == 8 or len(card) == 8: # to last node msg = self.comment + print_card_8(card) else: msg = self.comment + print_card_16(card) return msg
def write_card(self, f, size=8, is_double=False): #.. todo:: collapse the IDs if self.n: spoint = list(self.spoint) spoint.sort() card = ['SPOINT'] + collapse_thru(spoint) f.write(print_card_8(card))
def write_card(self, f, size=8, is_double=True, element_id=None): assert size in [8, 16], size assert is_double in [True, False], is_double if self.n: if element_id is None: i = arange(self.n) else: #assert len(unique(element_id))==len(element_id), unique(element_id) i = searchsorted(self.element_id, element_id) Cid = [cid if cid != 0 else '' for cid in self.coord_id[i]] Nspan = [nspan if nspan != 0 else '' for nspan in self.nspan[i]] Nchord = [nchord if nchord != 0 else '' for nchord in self.nchord[i]] Igid = self.igid[i] Lspan = [lspan if lspan != 0. else '' for lspan in self.lspan[i]] Lchord = [lchord if lchord != 0. else '' for lchord in self.lchord[i]] for (eid, pid, cid, nspan, nchord, lspan, lchord, igid, p1, x12, p4, x43) in zip(self.element_id[i], self.property_id[i], Cid, Nspan, Nchord, Lspan, Lchord, Igid, self.p1[i, :], self.x12[i], self.p4[i, :], self.x43[i]): card = ['CAERO1', eid, pid, cid, nspan, nchord, lspan, lchord, igid, p1[0], p1[1], p1[2], x12, p4[0], p4[1], p4[2], x43,] if size == 8: f.write(print_card_8(card)) else: f.write(print_card_16(card))
def test_rbe1_03(self): lines = [ 'rbe1,46,3,123456, , , , , ,+rbe46', '+rbe46,UM,4,123456,5,123456,2.0-6' ] card = bdf.process_card(lines) #print(print_card_8(card)) card = BDFCard(card) #print(card) card2 = RBE1(card) fields = card2.raw_fields() msg = print_card_8(fields).rstrip() #print(msg) lines_expected = [ 'RBE1 46 3 123456', ' UM 4 123456 5 123456 .000002' ] lines_actual = msg.rstrip().split('\n') msg = '\n%s\n\n%s\n' % ('\n'.join(lines_expected), msg) msg += 'nlines_actual=%i nlines_expected=%i' % (len(lines_actual), len(lines_expected)) self.assertEqual(len(lines_actual), len(lines_expected), msg) for actual, expected in zip(lines_actual, lines_expected): self.assertEqual(actual, expected, msg)
def print_card(fields, size=8, is_double=False): """ Prints a card in 8-character of 16-character Nastran format. Parameters ---------- fields : List[int/float/str/None] all the fields in the BDF card (no trailing Nones) size : int; default=8 the size of the field (8/16) is_double : bool; default=False is the card double precision? Double precision applies to specific cards and turns 1.234E+5 into 1.234D+5. Applies to GRID, CORDx only? Returns ------- card : str string representation of the card .. note:: be careful of using is_double on cards that aren't GRID or CORDx """ if size == 8: return print_card_8(fields) elif is_double: return print_card_double(fields) return print_card_16(fields)
def write_card(self, bdf_file, size=8, property_id=None): if self.n: if property_id is None: i = arange(self.n) else: i = searchsorted(self.property_id, property_id) for (pid, mid, area, I1, I2, J, nsm, c1, c2, d1, d2, e1, e2, f1, f2, k1, k2, i12) in zip(self.property_id[i], self.material_id[i], self.area[i], self.I1[i], self.I2[i], self.J[i], self.nsm[i], self.C1[i], self.C2[i], self.D1[i], self.D2[i], self.E1[i], self.E2[i], self.F1[i], self.F2[i], self.K1[i], self.K2[i], self.i12[i]): if pid in self._comments: bdf_file.write(self._comments[pid]) #card = ['PBAR', pid, mid, area, I1, I2, J] #c1 = set_blank_if_default(self.c1, 0.0) #c2 = set_blank_if_default(self.c2, 0.0) #d1 = set_blank_if_default(self.d1, 0.0) #d2 = set_blank_if_default(self.d2, 0.0) #e1 = set_blank_if_default(self.e1, 0.0) #e2 = set_blank_if_default(self.e2, 0.0) #f1 = set_blank_if_default(self.f1, 0.0) #f2 = set_blank_if_default(self.f2, 0.0) #k1 = set_blank_if_default(self.k1, 1e8) #k2 = set_blank_if_default(self.k2, 1e8) list_fields = ['PBAR', pid, mid, area, I1, I2, J, nsm, None, c1, c2, d1, d2, e1, e2, f1, f2, k1, k2, i12] bdf_file.write(print_card_8(list_fields))
def test_rbe1_01(self): lines = [ 'RBE1 10201 10201 123 10202 456', ' UM 10201 456 10202 123', ] card = bdf.process_card(lines) #print(print_card_8(card)) card = BDFCard(card) #print(card) card2 = RBE1(card) fields = card2.raw_fields() msg = print_card_8(fields).rstrip() #print(msg) lines_expected = [ 'RBE1 10201 10201 123 10202 456', ' UM 10201 456 10202 123' ] lines_actual = msg.rstrip().split('\n') msg = '\n%s\n\n%s\n' % ('\n'.join(lines_expected), msg) msg += 'nlines_actual=%i nlines_expected=%i' % (len(lines_actual), len(lines_expected)) self.assertEqual(len(lines_actual), len(lines_expected), msg) for actual, expected in zip(lines_actual, lines_expected): self.assertEqual(actual, expected, msg)
def write_card(self, f, size=8): card = ['SPCADD', self.spc_id] + self.spc_ids #print "card = ", card if size == 8: f.write(print_card_8(card)) else: f.write(print_card_16(card))
def write_card(self, f, size=8, element_ids=None): if self.n: if element_ids is None: i = arange(self.n) else: i = searchsorted(self.element_id, self.element_id) for (eid, pid, n, is_g0, g0, x, offt, pin, wa, wb) in zip( self.element_id[i], self.property_id[i], self.node_ids[i], self.is_g0[i], self.g0[i], self.x[i], self.offt[i], self.pin_flags[i], self.wa[i], self.wb[i]): pa = set_blank_if_default(pin[0], 0) pb = set_blank_if_default(pin[1], 0) w1a = set_blank_if_default(wa[0], 0.0) w2a = set_blank_if_default(wa[1], 0.0) w3a = set_blank_if_default(wa[2], 0.0) w1b = set_blank_if_default(wb[0], 0.0) w2b = set_blank_if_default(wb[1], 0.0) w3b = set_blank_if_default(wb[2], 0.0) x1 = g0 if is_g0 else x[0] x2 = 0 if is_g0 else x[1] x3 = 0 if is_g0 else x[2] offt = set_string8_blank_if_default(offt, 'GGG') card = ['CBAR', eid, pid, n[0], n[1], x1, x2, x3, offt, pa, pb, w1a, w2a, w3a, w1b, w2b, w3b] if size == 8: f.write(print_card_8(card)) else: f.write(print_card_16(card))
def write_card(self, f, size=8): for comp, nodes in iteritems(self.components): card = ['SPC1', self.constraint_id, comp] + list(nodes) if size == 8: f.write(print_card_8(card)) else: f.write(print_card_16(card))
def write_card(self, f, size=8, is_double=False): if self.n: card = ['GRDSET', None, self.cp, None, None, None, self.cd, self.seid] if size == 8: f.write(print_card_8(card)) else: f.write(print_card_16(card))
def write_card(self, size=8, is_double=False): skin = [] if self.is_skin: skin = ['SKIN'] # checked in NX 2014 / MSC 2005.1 return self.comment + print_card_8(['SET1', self.sid] + skin + self.get_ids())
def write_bdf(self, bdf_filename, nodes, hexas): f = open(bdf_filename, 'wb') f.write('CEND\n') f.write('BEGIN BULK\n') for inode, node in enumerate(nodes): (x, y, z) = node f.write(print_card_8(['GRID', inode + 1, None, float(x), float(y), float(z)])) pid = 1 for ielement, hexa in enumerate(hexas): f.write(print_card_8(['CHEXA', ielement + 1, pid,] + list(hexa))) f.write('PSOLID, 1, 1\n') f.write('MAT1, 1, 1.0,,0.3\n') f.write('ENDDATA\n') f.close()
def write_card(self, f, size=8, property_id=None): #print('PBARL.n = %s' % self.n) if self.n: if property_id is None: i = arange(self.n) else: i = searchsorted(self.property_id, property_id) #print('i = %s' % i) #cid = [cid if cid != 0 else '' for cid in self.coord_id] #group = set_blank_if_default(self.group, 'MSCBMLO') #list_fields = ['PBARL', self.pid, self.Mid(), group, self.Type, None, #None, None, None] + self.dim + [self.nsm] #self.model.log.debug('*pbarl write pids=%s' % self.property_id) for (j, pid, mid, group, Type, nsm) in zip(count(), self.property_id[i], self.material_id[i], self.group[i], self.Type[i], self.nsm[i]): dim = self.dim[j] sgroup = set_blank_if_default(group, 'MSCBMLO') list_fields = ['PBARL', pid, mid, group, Type, None, None, None, None] + dim + [nsm] if size == 8: f.write(print_card_8(list_fields)) else: f.write(print_card_16(list_fields))
def write_card(self, bdf_file, size=8): if self.n: for (nid, constraint, enforced) in zip(self.node_id, self.components, self.enforced_motion): fields = ['SPCD', self.constraint_id, nid, constraint, enforced] if size == 8: bdf_file.write(print_card_8(fields)) else: bdf_file.write(print_card_16(fields))
def export_caero_mesh(model: BDF, caero_bdf_filename: str = 'caero.bdf', is_subpanel_model: bool = True, pid_method: str = 'aesurf') -> None: """write the CAERO cards as CQUAD4s that can be visualized""" inid = 1 mid = 1 model.log.debug('---starting export_caero_model of %s---' % caero_bdf_filename) with open(caero_bdf_filename, 'w') as bdf_file: #bdf_file.write('$ pyNastran: punch=True\n') bdf_file.write('CEND\n') bdf_file.write('BEGIN BULK\n') _write_properties(model, bdf_file, pid_method=pid_method) for caero_eid, caero in sorted(model.caeros.items()): #assert caero_eid != 1, 'CAERO eid=1 is reserved for non-flaps' scaero = str(caero).rstrip().split('\n') if is_subpanel_model: if caero.type == 'CAERO2': continue bdf_file.write('$ ' + '\n$ '.join(scaero) + '\n') #bdf_file.write("$ CAEROID ID XLE YLE ZLE CHORD SPAN\n") points, elements = caero.panel_points_elements() _write_subpanel_strips(bdf_file, model, caero_eid, points, elements) npoints = points.shape[0] #nelements = elements.shape[0] for ipoint, point in enumerate(points): x, y, z = point bdf_file.write( print_card_8(['GRID', inid + ipoint, None, x, y, z])) #pid = caero_eid #mid = caero_eid jeid = 0 for elem in elements + inid: p1, p2, p3, p4 = elem eid2 = jeid + caero_eid pidi = _get_subpanel_property(model, caero_eid, eid2, pid_method=pid_method) fields = ['CQUAD4', eid2, pidi, p1, p2, p3, p4] bdf_file.write(print_card_8(fields)) jeid += 1 else: # macro model if caero.type == 'CAERO2': continue bdf_file.write('$ ' + '\n$ '.join(scaero) + '\n') points = caero.get_points() npoints = 4 for ipoint, point in enumerate(points): x, y, z = point bdf_file.write( print_card_8(['GRID', inid + ipoint, None, x, y, z])) pid = _get_subpanel_property(model, caero_eid, caero_eid, pid_method=pid_method) p1 = inid p2 = inid + 1 p3 = inid + 2 p4 = inid + 3 bdf_file.write( print_card_8(['CQUAD4', caero_eid, pid, p1, p2, p3, p4])) inid += npoints bdf_file.write('MAT1,%s,3.0E7,,0.3\n' % mid) bdf_file.write('ENDDATA\n')
def write_card(self, size=8, is_double=False): list_fields = ['TEMPP1', self.sid, self.eid, self.tbar] + self.t_stress return print_card_8(list_fields)
def write_card(self, size=8, is_double=False): card = self.repr_fields() # this card has integers & strings, so it uses... return self.comment + print_card_8(card)
def _interpolate_bar_to_node(eid_new, nid_new, mid, area, J, fbdf, inid1, inid2, xyz1_local, xyz2_local, xyz1_global, xyz2_global, nodal_result, local_points, global_points, result): """ These edges have crossings. We rework: y = m*x + b into the long form: y = (y2-y1) / (x2-x1) * (x-x1) + y1 to get: y = y2 * (x-x1)/(x2-x1) + y1 * (1 - (x-x1)/(x2-x1)) or: p = (x-x1)/(x2-x1) # percent y = y2 * p + y1 * (1 - p) Then we sub the y for the point (3 floats) and sub out x for the y-coordinate: percent = (y - y1_local) / (y2_local - y1_local) avg_xyz = xyz2 * percent + xyz1 * (1 - percent) Then we just crank the formula where we set the value of "y" to 0.0: percent = (0. - y1_local) / (y2_local - y1_local) """ #print('edge =', edge) y1_local = xyz1_local[1] y2_local = xyz2_local[1] percent = (0. - y1_local) / (y2_local - y1_local) avg_local = xyz2_local * percent + xyz1_local * (1 - percent) avg_global = xyz2_global * percent + xyz1_global * (1 - percent) #print(' nid1=%s nid2=%s edge=%s' % (inid1, inid2, str(edge))) #print(' xyz1_local=%s xyz2_local=%s' % (xyz1_local, xyz2_local)) #print(' avg_local=%s' % avg_local) #print(' avg_global=%s' % avg_global) #if fbdf is not None: out_grid1 = ['GRID', nid_new, None, ] + list(xyz1_local) out_grid2 = ['GRID', nid_new+1, None, ] + list(xyz2_local) conrod = ['CONROD', eid_new, nid_new, nid_new + 1, mid, area, J] #conm2 = ['CONM2', eid_new, nid_new, 0, 100.] #fbdf.write('$ interpolated\n') fbdf.write(print_card_8(out_grid1)) fbdf.write(print_card_8(out_grid2)) fbdf.write(print_card_8(conrod)) #fbdf.write(print_card_8(conm2)) local_points.append(avg_local) global_points.append(avg_global) xl, yl, zl = avg_local xg, yg, zg = avg_global if nodal_result is not None: result1 = nodal_result[inid1] result2 = nodal_result[inid2] resulti = result2 * percent + result1 * (1 - percent) result.append([0, xl, yl, zl, xg, yg, zg, resulti]) else: result.append([0, xl, yl, zl, xg, yg, zg]) nid_new += 2 eid_new += 1 return eid_new, nid_new
def project(self, bdf_filename, x0, growth_rate=1.3, nlayers=10): x = zeros(nlayers, dtype='float64') for i in range(nlayers): x[i] = x0 * growth_rate**i #print(self.nodes.shape) #print(self.elements.shape) nnodes = self.nodes.shape[0] nelements = self.elements.shape[0] nnodes2 = nnodes * (nlayers + 1) npents = nelements * nlayers cnormals = self.get_normals(self.nodes, self.elements) nnormals = self.get_normals_at_nodes(self.nodes, self.elements, cnormals) nodes = zeros((nnodes2, 3), dtype='float64') pents = zeros((npents, 6), dtype='int32') ih1 = 0 in1 = 0 in2 = nnodes nodes[in1:in2, :] = self.nodes in1 += nnodes in2 += nnodes ih1 = 0 ih2 = nelements print('x = %s' % x) for i in range(nlayers): nodes_old = self.nodes dx = nnormals * x[i] nodes_new = self.nodes + dx dn0 = nnodes * i dn1 = nnodes * (i + 1) elements_old = self.elements + nnodes * i elements_new = self.elements + nnodes * (i + 1) pents[ih1:ih2, 0:3] = deepcopy(elements_old) pents[ih1:ih2, 3:6] = deepcopy(elements_new) nodes[in1:in2, :] = deepcopy(nodes_new) in1 += nnodes in2 += nnodes ih1 += nelements ih2 += nelements with open(bdf_filename, 'wb') as f: f.write('CEND\n') f.write('BEGIN BULK\n') pents += 1 cid = None for nid, grid in enumerate(nodes): if nid % 5000 == 0: print('writing nid=%s' % (nid + 1)) card = [ 'GRID', nid + 1, cid, ] + list(grid) f.write(print_card_16(card)) pid = 0 mid = 1 for eid, penta in enumerate(pents): if (eid + 1) % nelements == 1: pid += 1 card = ['PSOLID', pid, mid] f.write(print_card_8(card)) print('bumping pid -> %s' % pid) if eid % 5000 == 0: print('writing eid=%s' % (eid + 1)) card = [ 'CPENTA', eid + 1, pid, ] + list(penta) f.write(print_card_8(card)) card = ['MAT1', mid, 1.0e7, None, 0.3] f.write(print_card_8(card)) f.write('ENDDATA\n')
def test_card_double(self): card = print_card_double(['GRID', 1, None, 120.322, -4.82872, 1.13362]) card_expected = 'GRID* 1 1.2032200000D+02-4.828720000D+00\n' card_expected += '* 1.1336200000D+00\n' self.assertEqual(card, card_expected) #card = print_card_double(['CHEXA', 1, 2, 2, 3, 4, 1, 8, 5, #6, 7]) #card_expected = '' #card_expected += 'CHEXA* 1 2 2 3\n' #card_expected +='* 4 1 8 5\n' #card_expected +='* 6 7\n' #card_expected += '* 1.1336200000D+00\n' #card = print_card_double(['CTETRA',6437,1,14533,5598,1577,9976,42364,5599,42365,42363,30022,12904]) #card_expected = '' #card_expected += 'CTETRA* 6437 1 14533 5598\n' #card_expected += '* 1577 9976 42364 5599\n' #card_expected += '* 42365 42363 30022 12904\n' #card_expected += '* \n' #card_expected +='CTETRA* 6437 1 14533 5598\n' #card_expected +='* 1577 9976 42364 5599\n' #card_expected +='* 42365 42363 30022 12904\n' #card_expected +='* \n' #self.assertEqual(card, card_expected) #============================= # mid E1 E2 nu12 G12 G1z G2z rho card = print_card_8([ 'MAT8', 6, 1.7e+7, 1.7e+7, .98, 340000., 180000., 180000., 0.0001712, # a1 a2 tref None, 71.33 ]) card_expected = '' card_expected += 'MAT8 6 1.7+7 1.7+7 .98 340000. 180000. 180000..0001712\n' card_expected += ' 71.33\n' self.assertEqual(card, card_expected) card = print_card_16([ 'MAT8', 6, 1.7e+7, 1.7e+7, .98, 340000., 180000., 180000., 0.0001712, # a1 a2 tref None, 71.33 ]) card_expected = '' card_expected += 'MAT8* 6 17000000. 17000000. .98\n' card_expected += '* 340000. 180000. 180000. .0001712\n' card_expected += '* 71.33\n' card_expected += '*\n' # bad self.assertEqual(card, card_expected)
def write_card(self, size=8, is_double=False): card = self.raw_fields() return self.comment + print_card_8(card)
def write_card(self, size=8, is_double=False): msg = self.comment for nid, comp, scale in zip(self.node_ids, self.components, self.scales): msg += print_card_8(['DAREA', self.sid, nid, comp, scale]) return msg
def update_with_post(fname, dirname): basename = os.path.basename(fname) base = os.path.splitext(basename)[0] bdf_name2 = os.path.join(dirname, basename) f04_name2 = os.path.join(dirname, base + '.f04') f06_name2 = os.path.join(dirname, base + '.f06') op2_name2 = os.path.join(dirname, base + '.op2') log_name2 = os.path.join(dirname, base + '.log') with open(fname, 'r') as bdf_file: lines = bdf_file.readlines() post = -1 found_post = False lines2 = None for i, line in enumerate(lines): line_upper = line.upper().split('$')[0].rstrip() line_upper = line_upper.replace('\t', ' ').strip() if line_upper.startswith('SOL '): while ' ' in line_upper: line_upper = line_upper.replace(' ', ' ') if ('SOL 1' in line_upper or 'SOL 3' in line_upper or # modal 'SOL 5' in line_upper or 'SOL 7' in line_upper or 'SOL 8' in line_upper or 'SOL 21' in line_upper or 'SOL 24' in line_upper or 'SOL 25' in line_upper or 'SOL 26' in line_upper or 'SOL 27' in line_upper or 'SOL 28' in line_upper or 'SOL 29' in line_upper or 'SOL 47' in line_upper or 'SOL 48' in line_upper or 'SOL 60' in line_upper or 'SOL 61' in line_upper or 'SOL 62' in line_upper or 'SOL 63' in line_upper or 'SOL 64' in line_upper or 'SOL 66' in line_upper or 'SOL 67' in line_upper or 'SOL 68' in line_upper or 'SOL 74' in line_upper or 'SOL 75' in line_upper or 'SOL 76' in line_upper or 'SOL 81' in line_upper or 'SOL 82' in line_upper or 'SOL 83' in line_upper or 'SOL 88' in line_upper or 'SOL 89' in line_upper or 'SOL 91' in line_upper or 'SOL 99' in line_upper or #'SOL 3' in line_upper or 'SOL 100' in line_upper or 'SOL USERDMAP' in line_upper or 'SOL MAIN' in line_upper or 'SOL XXX' in line_upper or 'SOL 101' in line_upper or 'SOL STATIC' in line_upper or 'SOL SESTATIC' in line_upper or 'SOL 103' in line_upper or 'SOL SEMODES' in line_upper or 'SOL 105' in line_upper or 'SOL BUCKLING' in line_upper or 'SOL 106' in line_upper or 'SOL NLSTATIC' in line_upper or # nonlinear static 'SOL 107' in line_upper or 'SOL SEMFREQ' in line_upper or # direct complex frequency response 'SOL 108' in line_upper or 'SOL SEDFREQ' in line_upper or # direct frequency response 'SOL 109' in line_upper or 'SOL SEDTRAN' in line_upper or # time linear? 'SOL 110' in line_upper or 'SOL SEDCEIG' in line_upper or # modal complex eigenvalue 'SOL 111' in line_upper or 'SOL SEMFREQ' in line_upper or # modal frequency response 'SOL 112' in line_upper or 'SOL SEMTRAN' in line_upper or # modal transient response 'SOL 114' in line_upper or # 'SOL 115' in line_upper or # 'SOL 118' in line_upper or # 'SOL 126' in line_upper or 'SOL 129' in line_upper or 'SOL NLTRAN' in line_upper or # time nonlinear #'SOL 112' in line_upper or #'SOL 112' in line_upper or #'SOL 112' in line_upper or 'SOL 144' in line_upper or # static aero 'SOL 145' in line_upper or # flutter 'SOL 146' in line_upper or # gust 'SOL 153' in line_upper or 'SOL NLSCSH' in line_upper or # nonlinear thermal 'SOL 159' in line_upper or # nonlinear transient thermal 'SOL 190' in line_upper or 'SOL DBTRANS' in line_upper or 'SOL 200' in line_upper): # optimization continue print('%r' % line_upper) if '601' in line_upper: # SOL 601 doesn't have a valid license #SOL 601,129 if os.path.exists(bdf_name2): print(f'removing {bdf_name2}') os.remove(bdf_name2) if os.path.exists(f04_name2): os.remove(f04_name2) if os.path.exists(f06_name2): os.remove(f06_name2) if os.path.exists(op2_name2): os.remove(op2_name2) if os.path.exists(log_name2): os.remove(log_name2) return None if line_upper.startswith(('LABEL', 'TITLE', 'SUBTITLE')): pass elif 'PRGPOST' in line_upper or 'POSTEXT' in line_upper: pass elif 'PARAM' in line_upper and 'POST' in line_upper: nlines_extra = 0 if '*' in line_upper: #print(fname) #print(line_upper) nlines_extra = 1 card_lines = [line_upper] param_post_fields = [ field.strip() for field in to_fields(card_lines, 'PARAM')[:3] ] if ' ' in param_post_fields[1].strip(): # PARAM, POST 0 field2 = param_post_fields[1].split()[1] try: unused_found_post_value = int(field2) except ValueError: print(fname) print(line_upper) print(param_post_fields) raise else: try: unused_found_post_value = int(param_post_fields[2]) except ValueError: print(fname) print(line_upper) print(param_post_fields) raise #if post_value == 0: param_post_fields = ['PARAM', 'POST', post] #print(fname) #print(card_lines) line = print_card_8(param_post_fields) #print(f'post {nlines_extra}!') lines2 = lines[:i] + [line] + lines[i + nlines_extra + 1:] found_post = True #if nlines_extra: #print(fname) #print(lines[i-2:i+3]) #print(lines2[i-2:i+3]) elif 'ENDDATA' in line_upper: #print(fname) if not found_post: #print('enddata not found post') lines2 = lines[i:] + [f'PARAM,POST,{post}\n', 'ENDDATA\n' ] + lines[i:] break elif 'ENDATA' in line_upper: print(fname) print('*en_data') raise RuntimeError('ENDATA...') if lines2 is None: lines2 = lines[i:] + [f'PARAM,POST,{post}\n'] + lines[i:] assert lines2 is not None, fname if not RUN_NASTRAN: return None with open(bdf_name2, 'w') as bdf_file: bdf_file.writelines(lines2) return bdf_name2
def __repr__(self): list_fields = self.raw_fields() return self.comment + print_card_8(list_fields)
def write_card(self, bdf_file, size=8): card = ['MPCADD', self.constraint_id] + self.mpc_ids if size == 8: bdf_file.write(print_card_8(card)) else: bdf_file.write(print_card_16(card))
def write_card(self, size: int=8, is_double: bool=False) -> str: list_fields = self.raw_fields() return print_card_8(list_fields)
def slice_edges(xyz_cid0, xyz_cid, edges, nodal_result, plane_atol=1e-5, plane_bdf_filename=None): """ Slices the shell elements Parameters ---------- xyz_cid0 : (nnodes, 3) float ndarray the node xyzs in the model xyz_cid : (nnodes, 3) float ndarray the node xyzs in the model in the local plane edges : ??? the edges of the model nodal_result : (nelements, ) float np.ndarray the result to cut the model with plane_atol : float; default=1e-5 the tolerance for a line that's located on the y=0 local plane plane_bdf_filename : str; default=None optionally write a BDF of the cut Returns ------- local_points_array : (N, 3) float ndarray the xyz points in the cutting plane coordinate system global_points_array : (N, 3) float ndarray the xyz points in the global xyz coordinate system result_array : (N, 7) float ndarray inid, x, y, z, xg, yg, zg, result TODO: split result_array, so we don't have mixed int/float/complex results being all casted to the highest data type """ #plane_bdf_filename = 'plane_edge.bdf' fbdf = StringIO() fbdf.write('$pyNastran: punch=True\n') fbdf.write('MAT1,1,3.0e7,,0.3\n') cid = 0 local_points = [] global_points = [] nid_new = 1 eid_new = 1 mid = 1 area = 1.0 J = 1.0 result = [] for edge in edges: (inid1, inid2) = edge xyz1_local = xyz_cid[inid1] xyz2_local = xyz_cid[inid2] xyz1_global = xyz_cid0[inid1] xyz2_global = xyz_cid0[inid2] y1_local = xyz1_local[1] y2_local = xyz2_local[1] abs_y1_local = np.abs(y1_local) abs_y2_local = np.abs(y2_local) is_same_sign = np.sign(y1_local) == np.sign(y2_local) is_far_from_plane = abs_y1_local > plane_atol and abs_y2_local > plane_atol #print('edge=%s' % (edge)) #print(' xyz1-local=%s xyz2-local=%s' % (xyz1_local, xyz2_local)) #print(' xyz1-global=%s xyz2-global=%s' % (xyz1_global, xyz2_global)) #print(' is_same_sign=%s is_far_from_plane=%s' % (is_same_sign, is_far_from_plane)) if is_far_from_plane and is_same_sign: #print('skip y1_local=%.3f y2_local=%.3f plane_atol=%.e' % ( #y1_local, y2_local, plane_atol)) continue elif np.allclose(y1_local, y2_local, atol=plane_atol): #print(' y-sym; nid1=%s nid2=%s edge=%s' % (nid1, nid2, str(edge))) #print(' xyz1=%s xyz2=%s' % (xyz1_global, xyz2_global)) out_grid1 = ['GRID', nid_new, cid, ] + list(xyz1_local) out_grid2 = ['GRID', nid_new + 1, cid, ] + list(xyz2_local) conrod = ['CONROD', eid_new, nid_new, nid_new + 1, mid, area, J] conm2 = ['CONM2', eid_new+1, nid_new, 0, 100.] if plane_bdf_filename: fbdf.write(print_card_8(out_grid1)) fbdf.write(print_card_8(out_grid2)) fbdf.write(print_card_8(conrod)) fbdf.write(print_card_8(conm2)) local_points.append(xyz1_local) local_points.append(xyz2_local) global_points.append(xyz1_global) global_points.append(xyz2_global) x1, y1, z1 = xyz1_local x2, y2, z2 = xyz2_local x1g, y1g, z1g = xyz1_global x2g, y2g, z2g = xyz2_global if nodal_result is not None: result1 = nodal_result[inid1] result2 = nodal_result[inid2] result.append([inid1, x1, y1, z1, x1g, y1g, z1g, result1]) result.append([inid2, x2, y2, z2, x2g, y2g, z2g, result2]) else: result.append([inid1, x1, y1, z1, x1g, y1g, z1g]) result.append([inid2, x2, y2, z2, x2g, y2g, z2g]) nid_new += 2 eid_new += 2 elif is_same_sign: # Labs == Lpos # same sign, so no crossing #print('*edge =', edge) #print(" xyz1_global=%s xyz2_global=%s" % (xyz1_global, xyz2_global)) #print(" xyz1_local =%s xyz2_local =%s" % (xyz1_local, xyz2_local)) continue else: eid_new, nid_new = _interpolate_bar_to_node( eid_new, nid_new, mid, area, J, fbdf, inid1, inid2, xyz1_local, xyz2_local, xyz1_global, xyz2_global, nodal_result, local_points, global_points, result) assert len(local_points) == len(result) if plane_bdf_filename: fbdf.write('$------\n') if plane_bdf_filename: fbdf.close() if 0: # pragma: no cover plane_bdf_filename = 'plane_edge2.bdf' if plane_bdf_filename: cid = 0 nid_new = 1 eid_new = 1 mid = 1 area = 1.0 J = 1.0 ipoint = 0 with open(plane_bdf_filename, 'w') as fbdf: fbdf.write('$pyNastran: punch=True\n') fbdf.write('MAT1,1,3.0e7,,0.3\n') while ipoint < len(local_points): xyz1_local = local_points[ipoint] #resulti = result[ipoint] print(xyz1_local) nid = xyz1_local[0] if nid == 0: ipoint += 1 continue xyz2_local = local_points[ipoint+1] out_grid1 = ['GRID', nid_new, cid, ] + list(xyz1_local) out_grid2 = ['GRID', nid_new + 1, cid, ] + list(xyz2_local) conrod = ['CONROD', eid_new, nid_new, nid_new + 1, mid, area, J] conm2 = ['CONM2', eid_new+1, nid_new, 0, 100.] fbdf.write(print_card_8(out_grid1)) fbdf.write(print_card_8(out_grid2)) fbdf.write(print_card_8(conrod)) fbdf.write(print_card_8(conm2)) fbdf.write('$------\n') ipoint += 2 nid_new += 2 eid_new += 1 # a hack to avoid making complicated code to sometimes write to the bdf if plane_bdf_filename: with open(plane_bdf_filename, 'w') as bdf_file: bdf_file.write(fbdf.getvalue()) local_points_array = np.array(local_points) global_points_array = np.array(global_points) result_array = np.array(result) return local_points_array, global_points_array, result_array
def stl_to_nastran(stl_filename, bdf_filename, nnodes_offset=0, nelements_offset=0, pid=100, mid=200, size=8, is_double=False, log=None): if isinstance(stl_filename, string_types): model = STL(log=log) model.read_stl(stl_filename) elif isinstance(stl_filename, STL): model = stl_filename else: raise TypeError('stl_filename must be a string or STL; type=%s' % type(stl_filename)) nid = nnodes_offset + 1 cid = None load_id = 10 #nodal_normals = model.get_normals_at_nodes(model.elements) if size == 8: print_card = print_card_8 elif size == 16: if is_double: print_card = print_card_16 else: print_card = print_card_double else: raise RuntimeError('size=%r' % size) with open(bdf_filename, 'w') as bdf: bdf.write('CEND\n') #bdf.write('LOAD = %s\n' % load_id) bdf.write('BEGIN BULK\n') nid2 = 1 magnitude = 100. for x, y, z in model.nodes: card = ['GRID', nid, cid, x, y, z] bdf.write(print_card_16(card)) #nx, ny, nz = nodal_normals[nid2 - 1] #card = ['FORCE', load_id, nid, cid, magnitude, nx, ny, nz] #bdf.write(print_card_8(card)) nid += 1 nid2 += 1 eid = nelements_offset + 1 elements = model.elements + (nnodes_offset + 1) for (n1, n2, n3) in elements: card = ['CTRIA3', eid, pid, n1, n2, n3] bdf.write(print_card_8(card)) eid += 1 t = 0.1 card = ['PSHELL', pid, mid, t] bdf.write(print_card_8(card)) E = 1e7 G = None nu = 0.3 card = ['MAT1', mid, E, G, nu] bdf.write(print_card_8(card)) bdf.write('ENDDATA\n') return bdf
def tecplot_to_nastran(tecplot_filename, bdf_filename, log=None, debug=True): """Converts a Tecplot file to Nastran.""" if isinstance(tecplot_filename, string_types): model = read_tecplot(tecplot_filename, log=log, debug=debug) else: model = tecplot_filename 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(model.xyz): card = [ 'GRID', inode + 1, None, ] + list(node) bdf_file.write(print_card_8(card)) if len(model.tri_elements): # tris only itri = 0 for itri, tri in enumerate(model.tri_elements): card = ['CTRIA3', itri + 1, shell_pid] + list(tri) bdf_file.write(print_card_8(card)) #istart += bdf_model if len(model.quad_elements): if len(model.tri_elements) != 0: # if there are tris, then we assume the quads are good for iquad, quad in enumerate(model.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(model.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(model.tri_elements) + len(model.quad_elements): card = ['PSHELL', shell_pid, mid, 0.1] bdf_file.write(print_card_8(card)) if len(model.tet_elements) + len(model.hexa_elements): card = ['PSOLID', solid_pid, mid] bdf_file.write(print_card_8(card)) if len(model.tet_elements): for itet, tet in enumerate(model.tet_elements): card = ['CTETRA', istart + itet, solid_pid] + list(tet) bdf_file.write(print_card_8(card)) if len(model.hexa_elements): # need to split out the CTETRA and CPENTA elements for ihex, hexa in enumerate(model.hexa_elements): uhexa = unique(hexa) nnodes_unique = len(uhexa) nids = hexa[:nnodes_unique] centroid_y = model.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)
def test_pbar_2(self): """tests the PBAR BDF add""" pid = 1 mid = 2 A = None I1 = I2 = None J = None nsm = None c1 = c2 = d1 = d2 = e1 = e2 = f1 = f2 = None k1 = k2 = None i12 = 3. fields = [ 'PBAR', pid, mid, A, I1, I2, J, nsm, None, c1, c2, d1, d2, e1, e2, f1, f2, k1, k2, i12 ] card = print_card_8(fields) lines = card.split('\n') model = BDF(debug=False) card = model.process_card(lines) cardi = BDFCard(card) pbar = PBAR.add_card(cardi) self.assertEqual(pbar.pid, 1) self.assertEqual(pbar.mid, 2) self.assertEqual(pbar.A, 0.0) self.assertEqual(pbar.i1, 0.0) self.assertEqual(pbar.i2, 0.0) self.assertEqual(pbar.j, 0.0) self.assertEqual(pbar.nsm, 0.0) self.assertEqual(pbar.i12, 3.0) self.assertEqual(pbar.c1, 0.0) self.assertEqual(pbar.c2, 0.0) self.assertEqual(pbar.d1, 0.0) self.assertEqual(pbar.d2, 0.0) self.assertEqual(pbar.e1, 0.0) self.assertEqual(pbar.e2, 0.0) self.assertEqual(pbar.k1, None) self.assertEqual(pbar.k2, None) #-------------------------------------------------------- A = 6. I1 = 5. I2 = 4. J = 3. nsm = 2. c1 = c2 = d1 = d2 = e1 = e2 = f1 = f2 = None k1 = k2 = 1e2 i12 = 0. fields = [ 'PBAR', pid, mid, A, I1, I2, J, nsm, None, c1, c2, d1, d2, e1, e2, f1, f2, k1, k2, i12 ] card = print_card_8(fields) lines = card.split('\n') model = BDF(debug=False) card = model.process_card(lines) cardi = BDFCard(card) pbar = PBAR.add_card(cardi) self.assertEqual(pbar.pid, 1) self.assertEqual(pbar.mid, 2) self.assertEqual(pbar.A, 6.0) self.assertEqual(pbar.i1, 5.0) self.assertEqual(pbar.i2, 4.0) self.assertEqual(pbar.j, 3.0) self.assertEqual(pbar.nsm, 2.0) self.assertEqual(pbar.i12, 0.0) self.assertEqual(pbar.c1, 0.0) self.assertEqual(pbar.c2, 0.0) self.assertEqual(pbar.d1, 0.0) self.assertEqual(pbar.d2, 0.0) self.assertEqual(pbar.e1, 0.0) self.assertEqual(pbar.e2, 0.0) self.assertEqual(pbar.k1, 1e2) self.assertEqual(pbar.k2, 1e2)
def write_card(self, size=8, is_double=False): card = self.repr_fields() if size == 8: return self.comment + print_card_8(card) return self.comment + print_card_16(card)
def write_card(self, size: int = 8, is_double: bool = False) -> str: card = self.repr_fields() msg = self.comment + print_card_8(card) return msg
def write_card(self, size=8, is_double=False): nodes = self.node_ids data = ['CQUADX4', self.eid, self.Pid()] + nodes + [self.theta] return self.comment + print_card_8(data)
def write_card_by_index(self, bdf_file, i, size=8): for (eid, pid, n) in zip(self.element_id[i], self.property_id[i], self.node_ids[i]): card = ['CQUAD4', eid, pid, n[0], n[1], n[2], n[3]] bdf_file.write(print_card_8(card))
def _write_skin_solid_faces(model, skin_filename, face_map, nids_to_write, eids_to_write, mids_to_write, eid_set, eid_shell, pid_shell, mid_shell, write_solids=False, write_shells=True, size=8, is_double=False, encoding=None): """ helper method for ``write_skin_solid_faces`` Parameters ---------- model : BDF() the BDF object skin_filename : str the file to write face_map : dict[sorted_face] : face sorted_face : List[int, int, int] / List[int, int, int, int] face : List[int, int, int] / List[int, int, int, int] nids_to_write : List[int, int, ...] list of node ids to write eids_to_write : List[int, int, ...] list of element ids to write mids_to_write : List[int, int, ...] list of material ids to write eid_set : Set[int] is the type right??? eid_shell : int the next id to use for the shell id pid_shell : int the next id to use for the shell property mid_shell : int the next id to use for the shell material write_solids : bool; default=False write solid elements that have skinned faces write_shells : bool; default=True write shell elements size : int; default=8 the field width is_double : bool; default=False double precision flag encoding : str; default=None -> system default the string encoding """ #encoding = model.get_encoding(encoding) with open(skin_filename, 'w') as bdf_file: bdf_file.write('$ pyNastran: punch=True\n') for nid in sorted(nids_to_write): if nid is None: continue node = model.nodes[nid] bdf_file.write(node.write_card(size=size, is_double=is_double)) for cid, coord in model.coords.items(): if cid == 0: continue bdf_file.write(coord.write_card(size=size, is_double=is_double)) if write_solids: for eid in sorted(eids_to_write): elem = model.elements[eid] bdf_file.write(elem.write_card(size=size)) for pid, prop in model.properties.items(): bdf_file.write(prop.write_card(size=size, is_double=is_double)) for mid in sorted(mids_to_write): material = model.materials[mid] bdf_file.write( material.write_card(size=size, is_double=is_double)) del eid, pid, mid if write_shells: mids_to_write.sort() for imid, mid in enumerate(mids_to_write): card = ['PSHELL', pid_shell + imid, mid_shell + imid, 0.1] bdf_file.write(print_card_8(card)) card = ['MAT1', mid_shell + imid, 3.e7, None, 0.3] #bdf_file.write(model.materials[mid].comment) bdf_file.write(print_card_8(card)) for face, eids in eid_set.items(): face_raw = face_map[face] nface = len(face) #assert len(eids) == 1, eids #for eid in sorted(eids): #elem = model.elements[eid] #print(elem) #break #elem = next(itervalues(model.elements)) # old elem = model.elements[eids[0]] #pid = next(iterkeys(model.properties)) pid = elem.Pid() prop = model.properties[pid] try: mid = prop.Mid() except AttributeError: continue #print('mids_to_write = %s' % mids_to_write) #print('mids = ', model.materials.keys()) imid = mids_to_write.index(mid) if nface == 3: card = ['CTRIA3', eid_shell, pid_shell + imid ] + list(face_raw) elif nface == 4: card = ['CQUAD4', eid_shell, pid_shell + imid ] + list(face_raw) elif nface == 4: card = ['CQUAD4', eid_shell, pid_shell + imid ] + list(face_raw) elif nface == 6: card = ['CTRIA6', eid_shell, pid_shell + imid ] + list(face_raw) elif nface == 8: card = ['CQUAD8', eid_shell, pid_shell + imid ] + list(face_raw) else: raise NotImplementedError('face=%s len(face)=%s' % (face, nface)) bdf_file.write(print_card_8(card)) eid_shell += 1 #elem = model.elements[eid] #bdf_file.write(elem.write_card(size=size)) #for pid, prop in model.properties.items(): #bdf_file.write(prop.write_card(size=size, is_double=is_double)) bdf_file.write('ENDDATA\n')