def get_output_data(self): case_name = self.case_name output_filepath = os.path.join(os.getcwd(), case_name, self.output_filepath) input_filepath = os.path.join(os.getcwd(), case_name, self.input_filepath) pan_cp = [] #Read the output file only if it exists and its last modification date is older than input file one while (not os.path.isfile(output_filepath)): pass while (os.path.getmtime(output_filepath) <= os.path.getmtime(input_filepath)): pass #Read the output file and store Cp and normal vector components with open(output_filepath) as f: lines = f.readlines() lines = [i.split() for i in lines] results_begin = lines.index(['0*b*solution']) results_end = lines.index([ 'full', 'configuration', 'forces', 'and', 'moments', 'summary' ]) for line in lines: #Get panel pressure coefficients if len(line) > 1 and lines.index( line) > results_begin and lines.index( line) < results_end and len( lines[lines.index(line) - 1]) == 0: if isint(line[0]) and isint(line[1]): pan_cp.append([ float(lines[lines.index(line) + 1][10]), float(line[10]), float(line[11]), float(line[12]) ]) #Get full configuration lift and induced drag coefficients if len(line) > 2: if line[0] == 'full' and line[ 1] == 'configuration' and line[2] == 'forces': i = lines.index(line) CL = lines[i + 11][3] CDi = lines[i + 11][4] output_data = {} output_data['pan_cp'] = pan_cp output_data['CL'] = CL output_data['CDi'] = CDi return output_data
def get_aero_dimensions(self): apoints_coord = [] network_info = [] #Write the aerodynamic grid points coordinates into a list with open(self.aero_template) as f: lines = f.readlines() lines = [i.split() for i in lines] points = 0 pans = 0 for line in lines: #Get aerodynamic grid points coordinates if all(isfloat(item) for item in line): if len(line) == 3: apoints_coord.append( [float(line[0]), float(line[1]), float(line[2])]) if len(line) == 6: apoints_coord.append( [float(line[0]), float(line[1]), float(line[2])]) apoints_coord.append( [float(line[3]), float(line[4]), float(line[5])]) #Get network information if len(line) > 1: if isint(line[0]): network_info.append([ int(line[0]), int(line[2]), int(line[1]), int(points), int(pans) ]) points = points + int(line[2]) * int(line[1]) pans = pans + (int(line[2]) - 1) * (int(line[1]) - 1) apoints_coord = np.asarray(apoints_coord) na = len(apoints_coord) apoints_coord_unique = np.unique(apoints_coord, axis=0) na_unique = len(apoints_coord_unique) #Dictionary containing aerodynamic problem data aero_dimensions = {} aero_dimensions['na'] = na aero_dimensions['na_unique'] = na_unique aero_dimensions['network_info'] = network_info return aero_dimensions
def get_output_data(self): #Read the punch and output files only if they exist and their last modification date is older than input file one while(not os.path.isfile(self.output_filepath)): pass while(os.path.getmtime(self.output_filepath) <= os.path.getmtime(self.input_filepath)): pass while(not os.path.isfile(self.output_file)): pass while(os.path.getmtime(self.output_file) <= os.path.getmtime(self.input_filepath)): pass phi = np.zeros((3*self.ns_all,self.M)) eigval = [] gen_mass = [] mass = 0. M = self.M ns_all = self.ns_all free_free = self.free_free #Number of rigid modes (offset) according to the free-free condition if free_free: rigid_num = 6 else: rigid_num = 0 #Total normal mode counter (including rigid ones) total_eig_count = 0 #Normal mode counter (elastic) eig_count = 0 #Boolean that indicates whether a mode is flexible or not flexible = False #Read the Nastran punch file (.pnh) and extract eigenvalues and eigenvectors with open(self.output_filepath) as f: lines = f.readlines() lines = [i.split() for i in lines] for i in range(len(lines)): if len(lines[i]) > 1: if lines[i][0] == '$EIGENVALUE': total_eig_count += 1 #Store the eignevalue if it is a flexible mode and set flexible flag to True if len(eigval) < M and total_eig_count > rigid_num: eigval.append(float(lines[i][2])) eig_count += 1 flexible = True elif len(eigval) >=M: flexible = False break else: flexible = False #Write eigenvectors onto phi if the node belongs to the total node list and the mode is flexible elif lines[i][0] in self.node_id_all and lines[i][1] == 'G' and flexible: j = self.node_id_all.index(lines[i][0]) phi[j][(eig_count-1)] = lines[i][2] phi[j+ns_all][(eig_count-1)] = lines[i][3] phi[j+2*ns_all][(eig_count-1)] = lines[i][4] #Normalize eigenvectors so that the maximum component equals 1 for i in range(M): max_phi = phi[:,i:i+1].max() min_phi = phi[:,i:i+1].min() if abs(max_phi) > abs(min_phi): max_abs_phi = max_phi else: max_abs_phi = min_phi phi[:,i:i+1] = phi[:,i:i+1]/max_abs_phi #Read the Nastran output file (.out) and extract the total mass of the structure (M) and the generalized masses with open(self.output_file) as f: lines = f.readlines() lines = [i.split() for i in lines] #Flag that indicates where the modal results start eigen = False for i in range(len(lines)): if len(lines[i]) > 5: if lines[i][4] == 'MASS' and lines[i][5] == 'X-C.G.': mass = float(lines[i+1][1].replace('D', 'E')) #Set modal results flag to true if lines[i][0] == 'MODE' and lines[i][2] == 'EIGENVALUE': eigen = True #Write the generalized masses into a list if their frequency is greater than 0.01 Hz (not a rigid body mode) if isint(lines[i][0]) and isint(lines[i][1]): if eigen == True and len(gen_mass) < M and np.sqrt(abs(float(lines[i][2])))/(math.pi) > 0.01: gen_mass.append(float(lines[i][5])) elif len(gen_mass) >=M: break #Save the eigenvalues and generalized masses lists as numpy arrays eigval = np.asarray(eigval) gen_mass = np.asarray(gen_mass) output_data = {} output_data['phi'] = phi output_data['eigval'] = eigval output_data['gen_mass'] = gen_mass output_data['mass'] = mass return output_data
with open(pnh) as f: lines = f.readlines() lines = [i.split() for i in lines] for i in range(len(lines)): if len(lines[i]) > 1: #Write nodal displacements onto u if the node belongs to the outer surface if lines[i][1] == 'G': displ[int(lines[i][0])] = [ float(lines[i][2]), float(lines[i][3]), float(lines[i][4]) ] if isint(lines[i][0]) and isfloat(lines[i][1]): #Store stresses only if the element is of shell type: if lines[i + 1][0] == '-CONT-' and lines[ i + 2][0] == '-CONT-' and lines[ i + 3][0] == '-CONT-' and lines[ i + 4][0] == '-CONT-' and lines[i + 5][0] == '-CONT-': #Write shell principal stresses (upper and lower shell faces) principal_stress_1[int(lines[i][0])] = (float( lines[i + 1][3]), float(lines[i + 2][1])) principal_stress_2[int(lines[i][0])] = (float( lines[i + 4][2]), float(lines[i + 4][3])) #Store the maximum von Mises stress between the upper and lower surface for elm_id in elm.keys():
def get_output_data(self): #Read the punch and output files only if they exist and their last modified date is older than input file one while(not os.path.isfile(self.output_filepath)): pass while(os.path.getmtime(self.output_filepath) <= os.path.getmtime(self.input_filepath)): pass while(not os.path.isfile(self.output_file)): pass while(os.path.getmtime(self.output_file) <= os.path.getmtime(self.input_filepath)): pass u = np.zeros((self.ns,3)) shell_stress = [] mass = 0. #Read the Nastran punch file (.pnh) and extract displacement and stress data with open(self.output_filepath) as f: lines = f.readlines() lines = [i.split() for i in lines] for i in range(len(lines)): if len(lines[i]) > 1: #Write nodal displacements onto u if the node belongs to the outer surface if lines[i][0] in self.node_id and lines[i][1] == 'G': u[self.node_id.index(lines[i][0])][0] = lines[i][2] u[self.node_id.index(lines[i][0])][1] = lines[i][3] u[self.node_id.index(lines[i][0])][2] = lines[i][4] if isint(lines[i][0]) and isfloat(lines[i][1]): if lines[i] is not lines[-2]: if lines[i+2][0] == '-CONT-': #Store stresses only if the element is of shell type: if lines[i+1][0] == '-CONT-' and lines[i+2][0] == '-CONT-' and lines[i+3][0] == '-CONT-' and lines[i+4][0] == '-CONT-' and lines[i+5][0] == '-CONT-': #Write shell principal stresses onto a list (upper and lower shell faces) shell_stress.append(((float(lines[i+1][3]), float(lines[i+2][1])), (float(lines[i+4][2]), float(lines[i+4][3])))) #Compute the Von Mises Stress on the structure VM = [] for s in shell_stress: VM.append(np.sqrt(s[0][0]**2 - s[0][0]*s[0][1] + s[0][1]**2)) VM.append(np.sqrt(s[1][0]**2 - s[1][0]*s[1][1] + s[1][1]**2)) VMStress = np.asarray(VM) #Read the Nastran output file (.out) and extract the total mass of the structure (M) with open(self.output_file) as f: lines = f.readlines() lines = [i.split() for i in lines] for i in range(len(lines)): if len(lines[i]) > 4: if lines[i][4] == 'MASS' and lines[i][5] == 'X-C.G.': mass = float(lines[i+1][1].replace('D', 'E')) output_data = {} output_data['u'] = u output_data['VMStress'] = VMStress output_data['mass'] = mass return output_data