def write_op2_header(obj, fop2, fop2_ascii, struct_3i, post: int = -1, endian: bytes = b'<'): """writes the op2 header""" if post == -1: #_write_markers(op2, op2_ascii, [3, 0, 7]) fop2.write(struct_3i.pack(*[ 4, 3, 4, ])) tape_code = b'NASTRAN FORT TAPE ID CODE - ' fop2.write( pack(endian + b'7i 28s i', *[4, 1, 4, 4, 7, 4, 28, tape_code, 28])) nastran_version = b'NX8.5 ' if obj.is_nx else b'XXXXXXXX' fop2.write( pack( endian + b'4i 8s i', *[ 4, 2, 4, #4, 2, 4, #4, 1, 4, #4, 8, 4, 8, nastran_version, 8 ])) fop2.write(pack(endian + b'6i', *[ 4, -1, 4, 4, 0, 4, ])) elif post == -2: _write_markers(fop2, fop2_ascii, [2, 4]) else: raise RuntimeError('post = %r; use -1 or -2' % post)
def write_op2_header(model: OP2, op2_file, fop2_ascii, struct_3i: Struct, post: int=-1, endian: bytes=b'<'): """writes the op2 header""" is_nx = model.is_nx is_msc = model.is_msc #is_nasa95 = model.is_nasa95 is_optistruct = model.is_optistruct if model.date == (1, 1, 2000): # (7, 24, 2020) today = datetime.datetime.today() model.date = (today.month, today.day, today.year) if post == -1: #_write_markers(op2_file, op2_ascii, [3, 0, 7]) op2_file.write(struct_3i.pack(*[4, 3, 4,])) tape_code = b'NASTRAN FORT TAPE ID CODE - ' if is_nx: op2_file.write(pack(endian + b'7i 28s i', *[4, 1, 4, 4, 7, 4, 28, tape_code, 28])) nastran_version = b'NX8.5 ' elif is_msc or is_optistruct: day, month, year = model.date op2_file.write(pack(endian + b'9i 28s i', *[12, day, month, year - 2000, 12, 4, 7, 4, 28, tape_code, 28])) nastran_version = b'XXXXXXXX' else: raise NotImplementedError(model._nastran_format) op2_file.write(pack(endian + b'4i 8s i', *[4, 2, 4, #4, 2, 4, #4, 1, 4, #4, 8, 4, 8, nastran_version, 8])) op2_file.write(pack(endian + b'6i', *[4, -1, 4, 4, 0, 4,])) elif post == -2: _write_markers(op2_file, fop2_ascii, [2, 4]) else: raise RuntimeError(f'post = {post:d}; use -1 or -2')
def write_op2(self, op2_outname, obj=None, #is_mag_phase=False, post=-1, endian=b'<'): """ Writes an OP2 file based on the data we have stored in the object Parameters ---------- op2_outname : str the name of the F06 file to write obj : OP2(); default=None -> self the OP2 object if you didn't inherit the class #is_mag_phase : bool; default=False #should complex data be written using Magnitude/Phase #instead of Real/Imaginary (default=False; Real/Imag) #Real objects don't use this parameter. """ #print('writing %s' % op2_outname) struct_3i = Struct(endian + b'3i') if obj is None: obj = self if isinstance(op2_outname, str): fop2 = open(op2_outname, 'wb') #fop2_ascii = open(op2_outname + '.txt', 'w') fop2_ascii = TrashWriter() #print('op2 out = %r' % op2_outname) else: assert isinstance(op2_outname, file), 'type(op2_outname)= %s' % op2_outname fop2 = op2_outname op2_outname = op2_outname.name print('op2_outname =', op2_outname) #op2_ascii.write('writing [3, 7, 0] header\n') #if markers == [3,]: # PARAM, POST, -1 #self.op2_reader.read_markers([3]) #data = self.read_block() #self.op2_reader.read_markers([7]) #data = self.read_block() #data = self._read_record() #self.op2_reader.read_markers([-1, 0]) #elif markers == [2,]: # PARAM, POST, -2 if post == -1: #_write_markers(op2, op2_ascii, [3, 0, 7]) fop2.write(struct_3i.pack(*[4, 3, 4,])) tape_code = b'NASTRAN FORT TAPE ID CODE - ' fop2.write(pack('7i 28s i', *[4, 1, 4, 4, 7, 4, 28, tape_code, 28])) nastran_version = b'NX8.5 ' if obj.is_nx else b'XXXXXXXX' fop2.write(pack(b'4i 8s i', *[4, 2, 4, #4, 2, 4, #4, 1, 4, #4, 8, 4, 8, nastran_version, 8])) fop2.write(pack(b'6i', *[4, -1, 4, 4, 0, 4,])) elif post == -2: _write_markers(fop2, fop2_ascii, [2, 4]) else: raise RuntimeError('post = %r; use -1 or -2' % post) write_geom1(fop2, fop2_ascii, obj) write_geom2(fop2, fop2_ascii, obj) write_geom3(fop2, fop2_ascii, obj) write_geom4(fop2, fop2_ascii, obj) write_ept(fop2, fop2_ascii, obj) write_mpt(fop2, fop2_ascii, obj) #write_dit(fop2, fop2_ascii, obj) #write_dynamic(fop2, fop2_ascii, obj) if obj.grid_point_weight.reference_point is not None: if hasattr(obj.grid_point_weight, 'write_op2'): obj.grid_point_weight.write_op2(fop2, endian=endian) else: raise NotImplementedError("*op2 - grid_point_weight not written") #is_mag_phase = False # we writte all the other tables # nastran puts the tables in order of the Case Control deck, # but we're lazy so we just hardcode the order #if markers == [3,]: # PARAM, POST, -2 #self.op2_reader.read_markers([3]) #data = self.read_block() #self.op2_reader.read_markers([7]) #data = self.read_block() ##self.show(100) #data = self._read_record() case_count = self._write(obj, fop2, fop2_ascii, struct_3i, endian) return case_count
def write_op2(self, op2_outname, obj=None, is_mag_phase=False, delete_objects=True, post=-1, endian=b'<'): """ Writes an OP2 file based on the data we have stored in the object Parameters ---------- op2_outname : str the name of the F06 file to write obj : OP2(); default=None -> self the OP2 object if you didn't inherit the class is_mag_phase : bool; default=False should complex data be written using Magnitude/Phase instead of Real/Imaginary (default=False; Real/Imag) Real objects don't use this parameter. delete_objects : bool; default=True should objects be deleted after they're written to reduce memory (default=True) """ assert op2_outname != 'ctria3.op2' print('writing %s' % op2_outname) if obj is None: obj = self if isinstance(op2_outname, str): fop2 = open(op2_outname, 'wb') fop2_ascii = open(op2_outname + '.txt', 'w') print('op2 out = %r' % op2_outname) else: assert isinstance(op2_outname, file), 'type(op2_outname)= %s' % op2_outname fop2 = op2_outname op2_outname = op2.name print('op2_outname =', op2_outname) #op2_ascii.write('writing [3, 7, 0] header\n') #if markers == [3,]: # PARAM, POST, -1 #self.op2_reader.read_markers([3]) #data = self.read_block() #self.op2_reader.read_markers([7]) #data = self.read_block() #data = self._read_record() #self.op2_reader.read_markers([-1, 0]) #elif markers == [2,]: # PARAM, POST, -2 if post == -1: #_write_markers(op2, op2_ascii, [3, 0, 7]) fop2.write(pack('3i', *[4, 3, 4,])) tape_code = b'NASTRAN FORT TAPE ID CODE - ' fop2.write(pack('7i 28s i', *[4, 1, 4, 4, 7, 4, 28, tape_code, 28])) nastran_version = b'NX8.5 ' if obj.is_nx else b'XXXXXXXX' fop2.write(pack(b'4i 8s i', *[4, 2, 4, #4, 2, 4, #4, 1, 4, #4, 8, 4, 8, nastran_version, 8])) fop2.write(pack(b'6i', *[4, -1, 4, 4, 0, 4,])) elif post == -2: _write_markers(fop2, fop2_ascii, [2, 4]) else: raise RuntimeError('post = %r; use -1 or -2' % post) write_geom1(fop2, fop2_ascii, obj) write_geom2(fop2, fop2_ascii, obj) write_ept(fop2, fop2_ascii, obj) write_mpt(fop2, fop2_ascii, obj) if obj.grid_point_weight.reference_point is not None: if hasattr(result, 'write_op2'): print("grid_point_weight") obj.grid_point_weight.write_op2(fop2, endian=endian) else: print("*op2 - grid_point_weight not written") #is_mag_phase = False # eigenvalues are written first for ikey, result in sorted(obj.eigenvalues.items()): header #print('%-18s SUBCASE=%i' % (result.__class__.__name__, isubcase)) if hasattr(result, 'write_op2'): result.write_op2(fop2, fop2_ascii, endian=endian) if delete_objects: del result else: print("*op2 - %s not written" % result.__class__.__name__) write_op2 # then eigenvectors # has a special header for isubcase, result in sorted(obj.eigenvectors.items()): (subtitle, label) = obj.isubcase_name_map[isubcase] if hasattr(result, 'write_op2'): print('%-18s SUBCASE=%i' % (result.__class__.__name__, isubcase)) result.write_op2(fop2, fop2_ascii, is_mag_phase=is_mag_phase, endian=endian) if delete_objects: del result else: print("*op2 - %s not written" % result.__class__.__name__) write_op2 # finally, we writte all the other tables # nastran puts the tables in order of the Case Control deck, # but we're lazy so we just hardcode the order #if markers == [3,]: # PARAM, POST, -2 #self.op2_reader.read_markers([3]) #data = self.read_block() #self.op2_reader.read_markers([7]) #data = self.read_block() ##self.show(100) #data = self._read_record() oef = [ # OEF - forces # alphabetical order... obj.cbar_force, # beam #obj.cbeam_forces, #obj.cbar100_forces, #obj.cbend_forces, obj.cbeam_force, obj.cbush_force, obj.celas1_force, obj.celas2_force, obj.celas3_force, obj.celas4_force, obj.cdamp1_force, obj.cdamp2_force, obj.cdamp3_force, obj.cdamp4_force, #obj.plateForces, # centroidal elements #obj.plateForces2, # bilinear elements obj.conrod_force, obj.cquad4_force, obj.cquad8_force, obj.crod_force, obj.cshear_force, obj.ctria3_force, obj.ctria6_force, obj.ctube_force, # other #obj.cgap_force, #obj.solidPressureForces, ] oes1x1 = [ # cbars/cbeams obj.cbar_stress, obj.cbeam_stress, # bush obj.cbush_stress, obj.cbush1d_stress_strain, # rods #obj.nonlinearRodStress, obj.celas1_stress, obj.celas2_stress, obj.celas3_stress, obj.celas4_stress, obj.chexa_stress, obj.conrod_stress, obj.cpenta_stress, obj.cquad4_stress, obj.cquad8_stress, obj.cquadr_stress, obj.crod_stress, obj.cshear_stress, obj.ctetra_stress, obj.ctria3_stress, obj.ctria6_stress, obj.ctriar_stress, obj.ctube_stress, ] oes1c = [ obj.cquad4_composite_stress, obj.cquad8_composite_stress, obj.cquadr_composite_stress, obj.ctria3_composite_stress, obj.ctria6_composite_stress, obj.ctriar_composite_stress, #obj.nonlinearPlateStress, obj.ctriax_stress, #obj.hyperelasticPlateStrain, ] #stress = oes1x1 + oes1c strain = [ # bars/beams obj.cbar_strain, obj.cbeam_strain, # springs, obj.celas1_strain, obj.celas2_strain, obj.celas3_strain, obj.celas4_strain, # plates obj.ctria3_strain, obj.cquad4_strain, obj.cshear_strain, obj.cquad4_composite_strain, obj.cquad8_composite_strain, obj.cquadr_composite_strain, obj.ctria3_composite_strain, obj.ctria6_composite_strain, obj.ctriar_composite_strain, #obj.nonlinearPlateStrain, #obj.ctriax_strain, obj.hyperelasticPlateStress, # solids obj.ctetra_strain, obj.cpenta_strain, obj.chexa_strain, # rods #obj.nonlinearRodStrain, # non-vectorized obj.chexa_strain, obj.conrod_strain, obj.cpenta_strain, obj.cquad4_strain, obj.cquad8_strain, obj.cquadr_strain, obj.crod_strain, obj.cshear_strain, obj.ctetra_strain, obj.ctria3_strain, obj.ctria6_strain, obj.ctriar_strain, obj.ctube_strain, # bush obj.cbush_strain, ] oug = [ obj.accelerations, obj.displacements, #obj.displacementsPSD, obj.displacementsATO, obj.displacementsRMS, #obj.scaledDisplacements, # ??? obj.temperatures, obj.velocities, obj.eigenvectors, ] oqg_mpc = [obj.mpc_forces] oqg_spc = [obj.spc_forces] ogs = [ #obj.grid_point_stresses, #obj.grid_point_volume_stresses, ] ogp = [obj.grid_point_forces] other = [ #obj.forceVectors, #obj.loadVectors, obj.thermal_load_vectors, ] isubcases = sorted(obj.isubcase_name_map.keys()) #title = obj.title res_categories = [ ('OUG', oug), ('OQG_SPC', oqg_spc), ('OQG_MPC', oqg_mpc), ('OEF', oef), ('OES1X', oes1x1), ('OES1C', oes1c), ('OSTR', strain), ('OGS', ogs), ('OGP', ogp), ('other', other) ] res_outs = {} # TODO: this may need to be reworked such that all of subcase 1 #is printed before subcase 2 for res_category_name, res_category in res_categories: print("res_category_name = %s" % res_category_name) for res_type in res_category: res_keys = isubcases itable = -1 for res_key in res_keys: isubcase = res_key case_count = 0 if isubcase in res_type: case_count += 1 #(subtitle, label) = obj.isubcase_name_map[isubcase] result = res_type[isubcase] element_name = '' if hasattr(result, 'element_name'): element_name = ' - ' + result.element_name if hasattr(result, 'write_op2'): print(' %s - isubcase=%i%s' % (result.__class__.__name__, isubcase, element_name)) result.write_op2(fop2, fop2_ascii, itable, obj.date, is_mag_phase=False, endian=endian) break else: print(" *op2 - %s not written" % result.__class__.__name__) footer = [4, 0, 4] fop2.write(pack(b'3i', *footer)) itable -= 1 #footer = [4, itable, 4] #op2.write(pack(b'3i', *footer)) #footer = [4, 0, 4] #op2.write(pack(b'3i', *footer)) footer = [4, itable, 4] fop2.write(pack(b'3i', *footer)) #footer = [4, 0, 4] #op2.write(pack(b'3i', *footer)) #if case_count: #footer = [4, 0, 4] #op2.write(pack(b'3i', *footer)) #break # close off the results footer = [4, 0, 4] fop2.write(pack(b'3i', *footer)) fop2_ascii.write('close_a = %s\n' % footer) footer = [4, 0, 4] fop2.write(pack(b'3i', *footer)) fop2_ascii.write('close_b = %s\n' % footer) fop2.close() fop2_ascii.close()
def write_op2_header(obj: OP2, fop2, fop2_ascii, struct_3i, post: int = -1, endian: bytes = b'<'): """writes the op2 header""" is_nx = obj.is_nx if obj.date == (1, 1, 2000): # (7, 24, 2020) today = datetime.datetime.today() obj.date = (today.month, today.day, today.year) if post == -1: #_write_markers(op2, op2_ascii, [3, 0, 7]) fop2.write(struct_3i.pack(*[ 4, 3, 4, ])) tape_code = b'NASTRAN FORT TAPE ID CODE - ' if is_nx: fop2.write( pack(endian + b'7i 28s i', *[4, 1, 4, 4, 7, 4, 28, tape_code, 28])) nastran_version = b'NX8.5 ' else: day, month, year = obj.date fop2.write( pack( endian + b'9i 28s i', *[ 12, day, month, year - 2000, 12, 4, 7, 4, 28, tape_code, 28 ])) nastran_version = b'XXXXXXXX' fop2.write( pack( endian + b'4i 8s i', *[ 4, 2, 4, #4, 2, 4, #4, 1, 4, #4, 8, 4, 8, nastran_version, 8 ])) fop2.write(pack(endian + b'6i', *[ 4, -1, 4, 4, 0, 4, ])) elif post == -2: _write_markers(fop2, fop2_ascii, [2, 4]) else: raise RuntimeError('post = %r; use -1 or -2' % post)
def _write_op2(self, fop2, fop2_ascii, obj, post: int=-1, endian: bytes=b'<', skips=None, nastran_format='nx') -> int: """actually writes the op2""" struct_3i = Struct(endian + b'3i') date = obj.date #op2_ascii.write('writing [3, 7, 0] header\n') #if markers == [3,]: # PARAM, POST, -1 #self.op2_reader.read_markers([3]) #data = self.read_block() #self.op2_reader.read_markers([7]) #data = self.read_block() #data = self._read_record() #self.op2_reader.read_markers([-1, 0]) #elif markers == [2,]: # PARAM, POST, -2 if post == -1: #_write_markers(op2, op2_ascii, [3, 0, 7]) fop2.write(struct_3i.pack(*[4, 3, 4,])) tape_code = b'NASTRAN FORT TAPE ID CODE - ' fop2.write(pack('7i 28s i', *[4, 1, 4, 4, 7, 4, 28, tape_code, 28])) nastran_version = b'NX8.5 ' if obj.is_nx else b'XXXXXXXX' fop2.write(pack(b'4i 8s i', *[4, 2, 4, #4, 2, 4, #4, 1, 4, #4, 8, 4, 8, nastran_version, 8])) fop2.write(pack(b'6i', *[4, -1, 4, 4, 0, 4,])) elif post == -2: _write_markers(fop2, fop2_ascii, [2, 4]) else: raise RuntimeError('post = %r; use -1 or -2' % post) if 'GEOM1' not in skips: write_geom1(fop2, fop2_ascii, obj, endian=endian) if 'GEOM2' not in skips: write_geom2(fop2, fop2_ascii, obj, endian=endian) if 'GEOM3' not in skips: write_geom3(fop2, fop2_ascii, obj, endian=endian, nastran_format=nastran_format) if 'GEOM4' not in skips: write_geom4(fop2, fop2_ascii, obj, endian=endian, nastran_format=nastran_format) if 'EPT' not in skips: write_ept(fop2, fop2_ascii, obj, endian=endian) if 'MPT' not in skips: write_mpt(fop2, fop2_ascii, obj, endian=endian) #if 'DIT' not in skips: #write_dit(fop2, fop2_ascii, obj) #if 'DYNAMIC' not in skips: #write_dynamic(fop2, fop2_ascii, obj) if 'grid_point_weight' not in skips: if obj.grid_point_weight.reference_point is not None: obj.grid_point_weight.write_op2(fop2, fop2_ascii, date, endian=endian) #is_mag_phase = False # we write all the other tables # nastran puts the tables in order of the Case Control deck, # but we're lazy so we just hardcode the order #if markers == [3,]: # PARAM, POST, -2 #self.op2_reader.read_markers([3]) #data = self.read_block() #self.op2_reader.read_markers([7]) #data = self.read_block() ##self.show(100) #data = self._read_record() case_count = self._write(obj, fop2, fop2_ascii, struct_3i, endian, skips) return case_count