def get_aero_refs(self): xa_ref_c = [] xa_ref_2 = [] #Write the aerodynamic grid points coordinates into a list with open(self.inflight_ref_shape_c) as f: lines = f.readlines() lines = [i.split() for i in lines] for line in lines: if all(isfloat(item) for item in line): if len(line) == 3: xa_ref_c.append( [float(line[0]), float(line[1]), float(line[2])]) if len(line) == 6: xa_ref_c.append( [float(line[0]), float(line[1]), float(line[2])]) xa_ref_c.append( [float(line[3]), float(line[4]), float(line[5])]) #Write the aerodynamic grid points coordinates into a list (excluding the root section) with open(self.inflight_ref_shape_2) as f: lines = f.readlines() lines = [i.split() for i in lines] for line in lines: if all(isfloat(item) for item in line): if len(line) == 3: xa_ref_2.append( [float(line[0]), float(line[1]), float(line[2])]) if len(line) == 6: xa_ref_2.append( [float(line[0]), float(line[1]), float(line[2])]) xa_ref_2.append( [float(line[3]), float(line[4]), float(line[5])]) xa_ref_c = np.asarray(xa_ref_c) xa_ref_2 = np.asarray(xa_ref_2) aero_refs = {} aero_refs['xa_ref_c'] = xa_ref_c aero_refs['xa_ref_2'] = xa_ref_2 return aero_refs
def get_aero_params(self): apoints_coord = [] #Write the aerodynamic grid points coordinates into a list (excluding the root section) with open(self.jig_shape) as f: lines = f.readlines() lines = [i.split() for i in lines] for line in lines: 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])]) apoints_coord = np.asarray(apoints_coord) aero_params = {} aero_params['apoints_coord'] = apoints_coord return aero_params
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 create_current_geom(self, params): sym_plane_index = self.sym_plane_index #Compute the coordinates of the displaced points jig_coord = params['apoints_coord'] new_coord = jig_coord + params['delta'] #Enforce symmetry condition, if existing if sym_plane_index is not None: j = sym_plane_index - 1 for i in range(len(jig_coord)): if jig_coord[i][j] == 0.: new_coord[i][j] = 0. with open(self.aero_template) as f: lines = f.readlines() split_lines = [i.split() for i in lines] #Replace the old grid coordinates with the new ones #Total aerodynamic grid point counter j = 0 for l in range(len(split_lines)): if all(isfloat(item) for item in split_lines[l]): if len(split_lines[l]) == 3: lines[l] = str(new_coord[j, 0]) + ' ' + str( new_coord[j, 1]) + ' ' + str(new_coord[j, 2]) + '\n' j += 1 if len(split_lines[l]) == 6: lines[l] = str(new_coord[j, 0]) + ' ' + str( new_coord[j, 1]) + ' ' + str( new_coord[j, 2]) + ' ' + str( new_coord[j + 1, 0]) + ' ' + str( new_coord[j + 1, 1]) + ' ' + str( new_coord[j + 1, 2]) + '\n' j += 2 case_name = self.case_name #Panin auxiliary file in a subdirectory for each case current_shape = os.path.join(os.getcwd(), case_name, self.current_shape) #Create subdirectory if it does not exist if not os.path.exists(os.path.dirname(current_shape)): try: os.makedirs(os.path.dirname(current_shape)) except OSError as exc: # Guard against race condition if exc.errno != errno.EEXIST: raise #Write the new geometry file with open(current_shape, 'w') as f: for line in lines: f.write(line)
def create_current_geom(self, params): a=params['alpha'] print(a) sym_plane_index = self.sym_plane_index #Compute the coordinates of the displaced points jig_coord = params['apoints_coord'] new_coord = jig_coord + params['delta'] #Enforce symmetry condition, if existing if sym_plane_index is not None: j = sym_plane_index - 1 for i in range(len(jig_coord)): if jig_coord[i][j] == 0.: new_coord[i][j] = 0. with open(self.aero_template) as f: lines = f.readlines() split_lines = [i.split() for i in lines] #Replace the old grid coordinates with the new ones #Total aerodynamic grid point counter j = 0 for l in range(len(split_lines)): if all(isfloat(item) for item in split_lines[l]): if len(split_lines[l]) == 3: lines[l] = str(new_coord[j, 0])+' '+str(new_coord[j, 1])+' '+str(new_coord[j, 2])+'\n' j += 1 if len(split_lines[l]) == 6: lines[l] = str(new_coord[j, 0])+' '+str(new_coord[j, 1])+' '+str(new_coord[j, 2])+' '+str(new_coord[j+1, 0])+' '+str(new_coord[j+1, 1])+' '+str(new_coord[j+1, 2])+'\n' j += 2 #Write the new geometry file with open(self.current_shape, 'w') as f: for line in lines: f.write(line)
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