def _get_compressed_xpoints(Type, xpoints): """ Gets the spoints in sorted, short form. uncompresed: SPOINT,1,3,5 compressed: SPOINT,1,3,5 uncompresed: SPOINT,1,2,3,4,5 compressed: SPOINT,1,THRU,5 uncompresed: SPOINT,1,2,3,4,5,7 compressed: SPOINT,7 SPOINT,1,THRU,5 Type = 'SPOINT' spoints = [1, 2, 3, 4, 5] fields = _get_compressed_xpoints(Type, spoints) >>> fields ['SPOINT', 1, 'THRU', 5] """ spoints = list(xpoints) spoints.sort() singles, doubles = collapse_thru_packs(spoints) lists_fields = [] if singles: list_fields = [Type] + singles lists_fields.append(list_fields) if doubles: for spoint_double in doubles: list_fields = [Type] + spoint_double lists_fields.append(list_fields) return lists_fields
def write_set(value, options, spaces=''): """ writes SET 80 = 3926, 3927, 3928, 4141, 4142, 4143, 4356, 4357, 4358, 4571, 4572, 4573, 3323 THRU 3462, 3464 THRU 3603, 3605 THRU 3683, 3910 THRU 3921, 4125 THRU 4136, 4340 THRU 4351 Parameters ---------- value : List[int] the Set values options : int the Set ID spaces : str; default='' indentation Returns ------- msg : str the string of the set Example ------- value = 80 options = [1, 2, 3, 4, 5, 7] set = write_set(value, options, spaces='') print(set) >>> SET 80 = 1 THRU 5, 7 """ value.sort() starter = 'SET %s = ' % (options) msg2 = spaces + starter msg = '' nchars = len(msg2) is_valid = True for valuei in value: if not isinstance(valuei, integer_types): is_valid = False break if is_valid: singles, doubles = collapse_thru_packs(value) out_value = singles for double in doubles: assert len(double) == 3, double sdouble = '%i THRU %i' % (double[0], double[2]) out_value.append(sdouble) else: out_value = value for i, out_valuei in enumerate(out_value): new_string = '%s, ' % out_valuei if len(msg2 + new_string) > 70: msg += msg2 + '\n' msg2 = ' ' * nchars + new_string else: msg2 += new_string return msg + msg2.rstrip(' \n,') + '\n'
def _write_spc1(card_type: str, cards, unused_ncards: int, op2_file, op2_ascii, endian: bytes) -> int: key = (5481, 58, 12) #sid, components = out[:2] #thru_flag = out[2] #if thru_flag == 0: # repeat 4 to end #nids = out[3:].tolist() #thru_check = False #elif thru_flag == 1: #n1 = out[3] #n2 = out[4] #nids = list(range(n1, n2+1)) #thru_check = True #else: #raise NotImplementedError('SPC1; thru_flag=%s' % thru_flag) max_spc_id = max([spc.conid for spc in cards]) try: nids = [max(spc.node_ids) for spc in cards] except ValueError: for spc in cards: try: max(spc.node_ids) except ValueError: print(spc) raise max_nid = max(nids) if max_spc_id > 99999999: raise SixtyFourBitError(f'64-bit OP2 writing is not supported; max spc_id={max_spc_id}') if max_nid > 99999999: raise SixtyFourBitError(f'64-bit OP2 writing is not supported; max SPC nid={max_nid}') nfields = 0 fields = [] # type: List[int] data = defaultdict(list) # type: Dict[Tuple[int, int], List[int]] for spc in cards: data_key = (spc.conid, int(spc.components)) ids = spc.node_ids data[data_key] += ids for data_key, nodes in data.items(): conid, components = data_key singles, doubles = collapse_thru_packs(nodes) nsingles = len(singles) ndoubles = len(doubles) if nsingles: nfields += 4 + nsingles # conid, components, thru_flag, singles, -1 fields += [conid, components, 0, ] + singles fields.append(-1) if ndoubles: for double in doubles: fields += [conid, components, 1, double[0], double[2], -1] # + doubles nfields += 6 * ndoubles assert len(fields) == nfields nbytes = write_header_nvalues(card_type, nfields, key, op2_file, op2_ascii) op2_file.write(pack(endian + b'%ii' % nfields, *fields)) return nbytes
def _write_xset1(card_type: str, cards, unused_ncards: int, op2, op2_ascii, endian: bytes) -> int: """ Word Name Type Description 1 C I Component numbers 2 THRUFLAG I Thru range flag THRUFLAG=0 No 3 ID I Grid or scalar point identification number Word 3 repeats until End of Record THRUFLAG=1 Yes 3 ID1 I First grid or scalar point identification number 4 ID2 I Second grid or scalar point identification number End THRUFLAG """ if card_type == 'ASET1': key = (5571, 77, 216) elif card_type == 'BSET1': key = (410, 4, 314) elif card_type == 'CSET1': key = (210, 2, 312) elif card_type == 'QSET1': key = (610, 6, 316) elif card_type == 'OMIT1': key = (4951, 63, 92) else: # pragma: no cover raise NotImplementedError(card_type) data = [] # type: List[int] fmt = endian for set_obj in cards: nodes = set_obj.node_ids singles, doubles = collapse_thru_packs(nodes) nsingles = len(singles) ndoubles = len(doubles) if nsingles == 0 and ndoubles == 1: min_node, unused_thru, max_node = doubles[0] data += [int(set_obj.components), 1, min_node, max_node] fmt += b'4i' else: data += [ int(set_obj.components), 0, ] + nodes nnodes = len(nodes) fmt += b'%ii' % (nnodes + 2) nfields = len(data) nbytes = write_header_nvalues(card_type, nfields, key, op2, op2_ascii) op2.write(pack(fmt, *data)) del data, fmt return nbytes
def raw_fields(self): """ Gets the fields in their unmodified form Returns ------- fields : List[varies] the fields that define the card """ lists_fields = [] if isinstance(self.nid, integer_types): list_fields = [self.type, self.nid] lists_fields.append(list_fields) else: singles, doubles = collapse_thru_packs(self.nid) if singles: list_fields = [self.type] + singles if doubles: for spoint_double in doubles: list_fields = [self.type] + spoint_double lists_fields.append(list_fields) return lists_fields
def write_set(set_id: int, values: List[int], spaces: str = '') -> str: """ writes SET 80 = 3926, 3927, 3928, 4141, 4142, 4143, 4356, 4357, 4358, 4571, 4572, 4573, 3323 THRU 3462, 3464 THRU 3603, 3605 THRU 3683, 3910 THRU 3921, 4125 THRU 4136, 4340 THRU 4351 Parameters ---------- set_id : int / str? the Set ID values : List[int] the Set values spaces : str; default='' indentation Returns ------- msg : str the string of the set Examples -------- **Example 1** >>> set_id = 80 >>> values = [1, 2, 3, 4, 5, 7] >>> set = write_set(set_id, values, spaces='') >>> set SET 80 = 1 THRU 5, 7 **Example 2** >>> set_id = '' >>> values = ['ALL'] >>> set = write_set(set_id, values, spaces='') >>> set SET = ALL """ values.sort() starter = f'SET {set_id:d} = ' msg2 = spaces + starter msg = '' nchars = len(msg2) is_valid = True for value in values: if not isinstance(value, integer_types): is_valid = False break if is_valid: singles, doubles = collapse_thru_packs(values) out_values = singles for double in doubles: assert len(double) == 3, double sdouble = '%i THRU %i' % (double[0], double[2]) out_values.append(sdouble) else: out_values = values for out_value in out_values: new_string = '%s, ' % out_value if len(msg2 + new_string) > 70: msg += msg2 + '\n' msg2 = ' ' * nchars + new_string else: msg2 += new_string return msg + msg2.rstrip(' \n,') + '\n'
def write_card(op2, op2_ascii, card_type, cards, endian, nastran_format='nx'): ncards = len(cards) if card_type in ['ASET1', 'BSET1', 'CSET1', 'QSET1', 'OMIT1']: if card_type == 'ASET1': key = (5571, 77, 216) elif card_type == 'BSET1': key = (410, 4, 314) elif card_type == 'CSET1': key = (210, 2, 312) elif card_type == 'QSET1': key = (610, 6, 316) elif card_type == 'OMIT1': key = (4951, 63, 92) else: # pragma: no cover raise NotImplementedError(card_type) #Word Name Type Description #1 C I Component numbers #2 THRUFLAG I Thru range flag #THRUFLAG=0 No # 3 ID I Grid or scalar point identification number # Word 3 repeats until End of Record #THRUFLAG=1 Yes # 3 ID1 I First grid or scalar point identification number # 4 ID2 I Second grid or scalar point identification number #End THRUFLAG data = [] fmt = endian for set_obj in cards: nodes = set_obj.node_ids singles, doubles = collapse_thru_packs(nodes) nsingles = len(singles) ndoubles = len(doubles) if nsingles == 0 and ndoubles == 1: min_node, unused_thru, max_node = doubles[0] data += [int(set_obj.components), 1, min_node, max_node] fmt += b'4i' else: data += [ int(set_obj.components), 0, ] + nodes nnodes = len(nodes) fmt += b'%ii' % (nnodes + 2) nfields = len(data) nbytes = write_header_nvalues(card_type, nfields, key, op2, op2_ascii) op2.write(pack(fmt, *data)) del data, fmt elif card_type in ['ASET', 'BSET', 'CSET', 'OMIT', 'QSET']: #Word Name Type Description #1 ID I Grid or scalar point identification number #2 C I Component numbers if card_type == 'ASET': key = (5561, 76, 215) elif card_type == 'BSET': key = (110, 1, 311) elif card_type == 'CSET': key = (310, 3, 313) elif card_type == 'QSET': key = (510, 5, 315) elif card_type == 'OMIT': key = (5001, 50, 15) else: # pragma: no cover raise NotImplementedError(card_type) data = [] fmt = endian for set_obj in cards: nnodes = len(set_obj.components) fmt += b'%ii' % (nnodes * 2) for nid, comp in zip(set_obj.node_ids, set_obj.components): data += [nid, int(comp)] nfields = len(data) nbytes = write_header_nvalues(card_type, nfields, key, op2, op2_ascii) op2.write(pack(fmt, *data)) del data, fmt elif card_type == 'SUPORT': key = (5601, 56, 14) data = [] fmt = endian for suport in cards: datai = [] nnodes = len(suport.Cs) for nid, ci in zip(suport.node_ids, suport.Cs): assert isinstance(nid, int), suport.get_stats() assert isinstance(ci, str), suport.get_stats() datai.extend([nid, int(ci)]) fmt += b'%ii' % (nnodes * 2) data.extend(datai) op2_ascii.write(' SUPORT data=%s\n' % str(datai)) nfields = len(data) nbytes = write_header_nvalues(card_type, nfields, key, op2, op2_ascii) op2.write(pack(fmt, *data)) del data, fmt elif card_type == 'SUPORT1': key = (10100, 101, 472) data = [] fmt = endian for suport1 in cards: suport1i = [suport1.conid] nnodes = len(suport1.Cs) for nid, ci in zip(suport1.node_ids, suport1.Cs): assert isinstance(nid, int), suport1.get_stats() assert isinstance(ci, int), suport1.get_stats() suport1i.extend([nid, ci]) suport1i.append(-1) op2_ascii.write(' SUPORT1 data=%s\n' % str(suport1i)) fmt += b'%ii' % (2 * nnodes + 2) data.extend(suport1i) nfields = len(data) nbytes = write_header_nvalues(card_type, nfields, key, op2, op2_ascii) op2.write(pack(fmt, *data)) del data, fmt elif card_type == 'MPC': key = (4901, 49, 17) data = [] fmt = endian for mpc in cards: datai = [ mpc.conid, ] fmt += b'i' + b'ifi' * len(mpc.coefficients) + b'3i' for nid, coeff, comp in zip(mpc.node_ids, mpc.coefficients, mpc.components): datai += [nid, coeff, int(comp)] datai += [-1, -1, -1] op2_ascii.write(' MPC data=%s\n' % str(datai)) data += datai nfields = len(data) nbytes = write_header_nvalues(card_type, nfields, key, op2, op2_ascii) op2.write(pack(fmt, *data)) del data, fmt elif card_type == 'RBE1': #""" #RBE1(6801,68,294) - Record 23 #MSC/NX #Word Name Type Description #1 EID I Element identification number #2 GN I Grid point identification number for independent degrees-of-freedom #3 CN I Component numbers of independent degrees-of-freedom #Words 2 through 3 repeat until (-2,-2) occurs #4 GM I Grid point identification number for dependent degrees-of-freedom #5 CM I Component numbers of dependent degreesof-freedom #Words 4 through 5 repeat until (-1,-1) occurs #6 ALPHA RS Thermal expansion coefficient #7 UNDEF none Not used #""" # TODO: neither reader or writer considers alpha; no current examples key = (6801, 68, 294) fields = [] fmt = endian for rbe1 in cards: fieldsi = [rbe1.eid] ngn = len(rbe1.Gni) ngm = len(rbe1.Gmi) #fmt += b'i %if 2i %if 2i fi' % (ngn * 2, ngm * 2) fmt += b'i %if 2i %if 2i' % (ngn * 2, ngm * 2) for gn, cn in zip(rbe1.Gni, rbe1.Cni): fieldsi += [gn, int(cn)] fieldsi += [-2, -2] for gm, cm in zip(rbe1.Gmi, rbe1.Cmi): fieldsi += [gm, int(cm)] #fieldsi += [-1, -1, rbe1.alpha, 0] fieldsi += [-1, -1] fields += fieldsi nfields = len(fields) nbytes = write_header_nvalues(card_type, nfields, key, op2, op2_ascii) op2.write(pack(fmt, *fields)) del fields, fmt elif card_type == 'RBE2': #RBE2(6901,69,295) - Record 24 # #Word Name Type Description #1 EID I Element identification number #2 GN I Grid point identification number for independent degrees-of-freedom #3 CM I Component numbers of dependent degrees of-freedom #4 GM I Grid point identification number for dependent degrees-of-freedom #Word 4 repeats until End of Record #5 ALPHA RS Thermal expansion coefficient # is_alpha = False for rbe2 in cards: if rbe2.alpha != 0.: is_alpha = True break key = (6901, 69, 295) fields = [] fmt = endian if is_alpha: for rbe2 in cards: ngm = len(rbe2.Gmi) fmt += b'3i %ii' % ngm fields += [rbe2.eid, rbe2.gn, int(rbe2.cm)] + rbe2.Gmi else: for rbe2 in cards: ngm = len(rbe2.Gmi) fmt += b'3i %ii f' % ngm fields += [rbe2.eid, rbe2.gn, int(rbe2.cm) ] + rbe2.Gmi + [rbe2.alpha] nfields = len(fields) nbytes = write_header_nvalues(card_type, nfields, key, op2, op2_ascii) op2.write(pack(fmt, *fields)) del fields, fmt elif card_type == 'RBE3': #""" #1 EID I Element identification number #2 REFG I Reference grid point identification number #3 REFC I Component numbers at the reference grid point #4 WT1 RS Weighting factor for components of motion at G #5 C I Component numbers #6 G I Grid point identification number #Word 6 repeats until -1 occurs #Words 4 through 6 repeat until -2 occurs #7 GM I Grid point identification number for dependent degrees-of-freedom #8 CM I Component numbers of dependent degrees-of-freedom #Words 7 through 8 repeat until -3 occurs #""" # TODO: alpha is not supported in the writer key = (7101, 71, 187) fields = [] fmt = endian for rbe3 in cards: fieldsi = [rbe3.eid, rbe3.refgrid, int(rbe3.refc)] fmti = b'3i' for weight, cg, group in rbe3.wt_cg_groups: fieldsi += [weight, int(cg)] + group + [-1] ngroup = len(group) fmti += b'fi %ii i' % ngroup fmti += b'i' fieldsi.append(-2) ngmi = len(rbe3.Gmi) if ngmi: raise RuntimeError('UM is not implemented') fmti += b'i' fieldsi += [-3] fmt += fmti fields += fieldsi nfields = len(fields) nbytes = write_header_nvalues(card_type, nfields, key, op2, op2_ascii) op2.write(pack(fmt, *fields)) del fields, fmt elif card_type == 'RBAR': nbytes = _write_rbar(card_type, cards, ncards, op2, op2_ascii, endian, nastran_format=nastran_format) elif card_type == 'SPC1': key = (5481, 58, 12) #sid, components = out[:2] #thru_flag = out[2] #if thru_flag == 0: # repeat 4 to end #nids = out[3:].tolist() #thru_check = False #elif thru_flag == 1: #n1 = out[3] #n2 = out[4] #nids = list(range(n1, n2+1)) #thru_check = True #else: #raise NotImplementedError('SPC1; thru_flag=%s' % thru_flag) nfields = 0 fields = [] data = defaultdict(list) for spc in cards: data_key = (spc.conid, int(spc.components)) ids = spc.node_ids data[data_key] += ids for data_key, nodes in data.items(): conid, components = data_key singles, doubles = collapse_thru_packs(nodes) nsingles = len(singles) ndoubles = len(doubles) if nsingles: nfields += 4 + nsingles # conid, components, thru_flag, singles, -1 fields += [ conid, components, 0, ] + singles fields.append(-1) if ndoubles: for double in doubles: fields += [conid, components, 1, double[0], double[2], -1] # + doubles nfields += 6 * ndoubles assert len(fields) == nfields nbytes = write_header_nvalues(card_type, nfields, key, op2, op2_ascii) op2.write(pack(endian + b'%ii' % nfields, *fields)) del fields elif card_type in ['SPCADD', 'MPCADD']: if card_type == 'SPCADD': key = (5491, 59, 13) elif card_type == 'MPCADD': key = (4891, 60, 83) else: # pragma: no cover raise NotImplementedError(card_type) #SPCADD(5491,59,13) #MPCADD(4891,60,83) #[2 1 10 -1] #[3 1 -1] data = [] for spcadd in cards: datai = [spcadd.conid] + spcadd.ids + [-1] op2_ascii.write(' %s data=%s\n' % (card_type, str(datai))) data += datai nfields = len(data) nbytes = write_header_nvalues(card_type, nfields, key, op2, op2_ascii) spack = Struct(endian + b'%ii' % nfields) op2.write(spack.pack(*data)) elif card_type == 'SPC': nbytes = _write_spc(card_type, cards, ncards, op2, op2_ascii, endian, nastran_format=nastran_format) #elif card_type == 'TEMPD': #key = (5641, 65, 98) #nfields = 6 #spack = Struct(endian + b'if') #nbytes = write_header(card_type, nfields, ncards, key, op2, op2_ascii) #for load in cards: #print(load.get_stats()) ##sid, T = data #data = [load.sid, load.temperature] #op2_ascii.write(' TEMPD data=%s\n' % str(data)) #op2.write(spack.pack(*data)) else: # pragma: no cover card0 = cards[0] raise NotImplementedError(card0) return nbytes