def test_cart3d_io_03(self): infile_name = os.path.join(test_path, 'threePlugs.bin.tri') outfile_name = os.path.join(test_path, 'threePlugs_out.tri') outfile_name_bin = os.path.join(test_path, 'threePlugs_bin2.tri') outfile_name_bin_out = os.path.join(test_path, 'threePlugs_bin_out.tri') cart3d = Cart3D(log=None, debug=False) cart3d.read_cart3d(infile_name) cart3d.write_cart3d(outfile_name, is_binary=False) cart3d.write_cart3d(outfile_name_bin, is_binary=True) cart3d_ascii = Cart3D(log=None, debug=False) cart3d_ascii.read_cart3d(outfile_name) check_array(cart3d.points, cart3d_ascii.points) cart3d_bin = Cart3D(log=None, debug=False) cart3d_bin.read_cart3d(outfile_name_bin) check_array(cart3d.points, cart3d_bin.points) os.remove(outfile_name) os.remove(outfile_name_bin) cart3d.write_cart3d(outfile_name_bin_out, is_binary=False) os.remove(outfile_name_bin_out)
def test_nastran_to_cart3d_02(self): log = get_logger(level='warning', encoding='utf-8') lines = ('SOL 101\n' 'CEND\n' 'BEGIN BULK\n' 'GRID,1,,1.0,0.,0.\n' 'GRID,2,,1.0,1.,0.\n' 'GRID,19,,0.0,1.,0.\n' 'CTRIA3,10,100,1,2,19\n' 'PSHELL,100,1000,0.1\n' 'MAT1,1000,3.0e7,,0.3\n' 'ENDDATA\n') bdf_filename = os.path.join(model_path, 'test02.bdf') cart3d_filename = os.path.join(model_path, 'test02.tri') cart3d_filename_out = os.path.join(model_path, 'test02_out.tri') with open(bdf_filename, 'w') as bdf_file: bdf_file.write(lines) nastran_to_cart3d_filename(bdf_filename, cart3d_filename, log=log) model = Cart3D(log=log) model.read_cart3d(cart3d_filename) model.write_cart3d(cart3d_filename_out) test = Cart3dGUI() test.log = log test.model.load_cart3d_geometry(cart3d_filename) os.remove(bdf_filename) os.remove(cart3d_filename) os.remove(cart3d_filename_out)
def test_cart3d_io_01(self): lines = ("7 6\n" "0.000000 0.000000 0.000000\n" "1.000000 0.000000 0.000000\n" "2.000000 0.000000 0.000000\n" "1.000000 1.000000 0.000000\n" "2.000000 1.000000 0.000000\n" "1.000000 -1.000000 0.000000\n" "2.000000 -1.000000 0.000000\n" "1 4 2\n" "2 4 5\n" "2 5 3\n" "2 6 1\n" "5 6 2\n" "5 5 2\n" "1\n" "2\n" "3\n" "2\n" "4\n" "6\n") infile_name = os.path.join(test_path, 'flat_full.tri') with open(infile_name, 'w') as f: f.write(lines) cart3d = Cart3D(log=None, debug=False) cart3d.read_cart3d(infile_name) assert len(cart3d.points) == 7, 'npoints=%s' % len(cart3d.points) assert len(cart3d.elements) == 6, 'nelements=%s' % len(cart3d.elements) assert len(cart3d.regions) == 6, 'nregions=%s' % len(cart3d.regions) assert len(cart3d.loads) == 0, 'nloads=%s' % len(cart3d.loads)
def write_new_cart3d_mesh(cfd_grid_file, cfd_grid_file2, wA): """takes in half model wA, and baseline cart3d model, updates full model grids""" log.info("---starting write_new_cart3d_mesh---") # make half model cart = Cart3D() result_names = ['Cp'] cart.read_cart3d(cfd_grid_file, result_names=result_names) # reading full model points, elements, regions, loads = cart.make_half_model() # adjusting points points2 = {} for (ipoint, point) in sorted(iteritems(points)): wai = wA[ipoint] (x, y, z) = point points2[ipoint] = [x, y, z + wai] # mirroring model points, elements, regions, loads = cart.make_mirror_model( points2, elements, regions, loads) # writing half model; no loads (cleans up leftover parameters) cart.write_cart3d(cfd_grid_file, points, elements, regions) log.info("---finished write_new_cart3d_mesh---") sys.stdout.flush()
def mapDeflectionsStructures_Aero(bdf_model='test_tet10.bdf', op2_filename='test_tet10.op2', tet_filename='geometry.morph.in', cart3d_geom_filename='bJet.a.tri', cart3d_out_filename='bJet.a.tri2', proper_tet_filename='properTets.in', workpath=''): t0 = time() proper_tets = load_proper_tets(proper_tet_filename) #makeGeometryMorphIn(basepath, bdfModel) # loading tetrahedra dr = DelauneyReader(tet_filename) # geometry.morph.in tets, nodes, elements, volume = dr.build_tets() sys.stdout.flush() #print("type(tets) = ",type(tets)) #for i,tet in sorted(tets.items()): #print("tet[%4s]=%s" % (i, tet)) # loading op2 displacements defreader = DeflectionReader(op2_filename) # test_tet10.op2 sys.stdout.flush() #deflections = defreader.convertDisplacements() #deflections = {1:[1.,2.,3.]} #for key, d in deflections.items(): #print("d = ", d) # loading aero nodes cart = Cart3D() # bJet.a.tri cart.read_cart3d(cart3d_geom_filename) #(cartPoints, elements, regions, Cp) = cart.makeHalfModel(cartPoints, elements, regions, Cp) sys.stdout.flush() #cart_outfile = os.path.join(workpath, 'bJet.a.tri_test') # test code #cart.writeInfile(cart_outfile, cart_points, elements, regions) #for point in cart_points: # print("point = ", point) # deflect the aero nodes dmap = DeflectionMapper(cart.points, tets, defreader) t1 = time() log.info("setup time = %g sec" % (t1 - t0)) aero_nodes2, proper_tets = dmap.map_deflections(proper_tets) write_proper_tets(workpath, proper_tets) # write out the deflected aero nodes cart.nodes = aero_nodes2 cart.write_cart3d(cart3d_out_filename) #bJet.a.tri_new log.info("done with deflection mapping!") #for aeroNode in aeroNodes2: # print("aeroNode = ", aeroNode) t2 = time() log.info("total mapDeflections.py time = %g sec" % (t2 - t0))
def tecplot_to_cart3d(tecplot_filename, cart3d_filename=None, debug=True): """ Converts a Tecplot file to Cart3d. It's assumed that quads are actually degenerate triangles """ if isinstance(tecplot_filename, str): model = read_tecplot(tecplot_filename, debug=debug) else: model = tecplot_filename if len(model.tri_elements) and len(model.quad_elements): tris = np.vstack([ model.tri_elements, model.quad_elements[:, :3], ]) elif len(model.tri_elements): tris = model.tri_elements elif len(model.quad_elements): tris = model.quad_elements[:, :3] else: raise NotImplementedError('need quads/tris') npoints = model.xyz.shape[0] nelements = tris.shape[0] assert tris.shape[1] == 3, tris.shape #print('npoints=%s nelements=%s' % (npoints, nelements)) #removed_nodes = False regions = np.zeros(nelements, dtype='int32') ones_float = np.ones(npoints, dtype='float64') cart3d_model = Cart3D() cart3d_model.points = model.xyz cart3d_model.regions = regions cart3d_model.elements = tris + 1 headers_no_xyz = model.variables[3:] # drop the xyz, get what's left if 'cp' in headers_no_xyz: iCp = headers_no_xyz.index('cp') cp = model.results[:, iCp] assert len(cp) == npoints cart3d_model.loads = { 'Cp': cp, # nodal Cp 'rho': ones_float, 'rhoU': ones_float, 'rhoV': ones_float, 'rhoW': ones_float, 'E': ones_float, } else: model.log.debug('skipping Cp') if cart3d_filename is not None: cart3d_model.write_cart3d(cart3d_filename) return cart3d_model
def main(): """tests getting the normal groups""" cart3d = Cart3D(log=None, debug=False) result_names = [] # read the mesh only cart3d.read_cart3d('Cart3d_55000_2.4_10_0_0_0_0.i.triq', result_names=result_names) points = cart3d.points elements = cart3d.elements celements = elements.copy() normals, groups = get_normal_groups(points, celements) tris, quads = normal_groups_to_quads(celements, normals, groups) write_nastran_quads_tris(points, tris, quads, bdf_filename='tris_quads.bdf')
def stl_to_cart3d(stl_filename, cart3d_filename=None, log=None, debug=False, is_binary=False, float_fmt='%6.7f'): """ Converts a Cart3D object to STL format. Parameters ---------- stl_filename : str / STL() str : path to the input STL file STL() : an STL object cart3d_filename : str; default=None str : path to the output Cart3D file (or None to skip) log : log a logger object (or None) debug : bool; default=False True/False (used if log is not defined) is_binary : bool; default=False should the cart3d file be binary float_fmt : str; default='6.7f' the cart3d node precision Returns ------- stl : STL() an STL object """ if isinstance(stl_filename, string_types): stl = read_stl(stl_filename, log=log, debug=debug) elif isinstance(stl_filename, STL): stl = stl_filename else: raise TypeError('stl_filename must be a string or STL; type=%s' % type(stl_filename)) cart3d = Cart3D(log=log, debug=debug) cart3d.nodes = stl.nodes + 1 cart3d.elements = stl.elements + 1 nelements = len(stl.elements) cart3d.regions = np.zeros(nelements, dtype='int32') if cart3d_filename: cart3d.write_cart3d(cart3d_filename, is_binary=is_binary, float_fmt=float_fmt) return cart3d
def run_quad_extraction(cart3d_triq_filename): """tests getting the normal groups""" cart3d = Cart3D(log=None, debug=False) result_names = [] # read the mesh only cart3d.read_cart3d(cart3d_triq_filename, result_names=result_names) points = cart3d.points elements = cart3d.elements celements = elements.copy() normals, groups = get_normal_groups(points, celements) tris, quads = normal_groups_to_quads(celements, normals, groups) write_nastran_quads_tris(points, tris, quads, bdf_filename='tris_quads.bdf')
def cart3d_to_usm3d_bc_filename(cart3d_filename, usm3d_bc_filename, log=None, debug=False): """ Creates a USM3D boundary condtion file from the Cart3d regions. Parameters ---------- cart3d_filename : str path to the input Cart3D file usm3d_bc_filename : str path to the output BC file log : log(); default=None a logger object debug : bool; default=False True/False (used if log is not defined) """ cart3d = Cart3D(log=log, debug=debug) cart3d.read_cart3d(cart3d_filename) cart3d_to_usm3d_bc(cart3d, usm3d_bc_filename)
def test_cart3d_io_02(self): lines = ("5 3 6\n" "0. 0. 0.\n" "1. 0. 0.\n" "2. 0. 0.\n" "1. 1. 0.\n" "2. 1. 0.\n" "1 4 2\n" "2 4 5\n" "2 5 3\n" "1\n" "2\n" "3\n" "1.\n" "1. 1. 1. 1. 1.\n" "2.\n" "2. 2. 2. 2. 2.\n" "3.\n" "3. 3. 3. 3. 3.\n" "4.\n" "4. 4. 4. 4. 4.\n" "5.\n" "5. 5. 5. 5. 5.\n") infile_name = os.path.join(test_path, 'flat.tri') with open(infile_name, 'w') as f: f.write(lines) cart3d = Cart3D(log=None, debug=False) cart3d.read_cart3d(infile_name) assert len(cart3d.points) == 5, 'npoints=%s' % len(cart3d.points) assert len(cart3d.elements) == 3, 'nelements=%s' % len(cart3d.elements) assert len(cart3d.regions) == 3, 'nregions=%s' % len(cart3d.regions) assert len( cart3d.loads) == 14, 'nloads=%s' % len(cart3d.loads) # was 10 assert len(cart3d.loads['Cp']) == 5, 'nCp=%s' % len(cart3d.loads['Cp']) outfile_name = os.path.join(test_path, 'flat.bin.tri') cart3d.loads = None cart3d.write_cart3d(outfile_name, is_binary=True) cnormals = cart3d.get_normals() nnormals = cart3d.get_normals_at_nodes(cnormals)
def test_nastran_to_cart3d_02(self): lines = ('SOL 101\n' 'CEND\n' 'BEGIN BULK\n' 'GRID,1,,1.0,0.,0.\n' 'GRID,2,,1.0,1.,0.\n' 'GRID,19,,0.0,1.,0.\n' 'CTRIA3,10,100,1,2,19\n' 'PSHELL,100,1000,0.1\n' 'MAT1,1000,3.0e7,,0.3\n' 'ENDDATA\n') bdf_filename = os.path.join(model_path, 'test02.bdf') cart3d_filename = os.path.join(model_path, 'test02.tri') cart3d_filename_out = os.path.join(model_path, 'test02_out.tri') with open(bdf_filename, 'w') as f: f.write(lines) nastran_to_cart3d_filename(bdf_filename, cart3d_filename) model = Cart3D() model.read_cart3d(cart3d_filename) model.write_cart3d(cart3d_filename_out) test = Cart3dGUI() test.load_cart3d_geometry(cart3d_filename, dirname=None)
def __init__(self, log=None, debug=False): Cart3D.__init__(self, log=log, debug=debug)
def read_cart3d(self, cart3d_filename, result_names=None): Cart3D.read_cart3d(self, cart3d_filename, result_names=result_names)
def run_map_loads(inputs, cart3d_geom='Components.i.triq', bdf_model='fem.bdf', bdf_model_out='fem.loads.out', configpath='', workpath=''): """ inputs : dict aero_format : str 'cart3d' is the only option skin_property_regions : List[int, int, ...] list of property ids for the skin isubcase : int the SUBCASE number for the load pInf : float the static pressure (psi) qInf : float the dynamic pressure (psi) Sref : float the reference area (in^2) Lref : float the reference length (in) xref : float the reference location (in) cart3d_geom : str; default='Components.i.triq' path to the cart3d model only maps half model loads, so: '_half' on the end : use the +y side of the model without 'half' : cut the model and use the +y half bdf_model : str the path to the input fem bdf_model_out : str the location to save the loads """ t0 = time() print(inputs) aero_format = inputs['aero_format'].lower() property_regions = inputs['skin_property_regions'] isubcase = inputs['isubcase'] pInf = inputs['pInf'] qInf = inputs['qInf'] Sref = inputs['Sref'] Lref = inputs['Lref'] xref = inputs['xref'] force_scale = inputs['force_scale'] moment_scale = inputs['moment_scale'] if isinstance(bdf_model, BDF): pass else: assert os.path.exists(bdf_model), '%r doesnt exist' % bdf_model if aero_format == 'cart3d': cart3d_model = Cart3D(debug=True) result_names = ['Cp', 'rho', 'rhoU', 'rhoV', 'rhoW', 'E', 'Mach'] #result_names = None if not cart3d_geom.endswith('_half'): half_model = cart3d_geom + '_half' cart3d_model.read_cart3d(cart3d_geom, result_names=result_names) (nodes, elements, regions, loads) = cart3d_model.make_half_model(axis='y') cart3d_model.nodes = nodes cart3d_model.elements = elements cart3d_model.regions = regions cart3d_model.loads = loads #(nodes, elements, regions, Cp) = cart3d_model.renumber_mesh( #nodes, elements, regions, Cp) cart3d_model.write_cart3d(half_model) else: cart3d_model.read_cart3d(cart3d_geom, result_names=result_names) elements = cart3d_model.elements Cp = cart3d_model.loads['Cp'] mesh = cart3d_model else: raise NotImplementedError('aero_format=%r' % aero_format) aero_model = AeroModel(inputs, mesh.nodes, mesh.elements, Cp) log.info("elements[1] = %s" % elements[1]) #del elements, nodes, Cp if isinstance(bdf_model, BDF): fem = bdf_model else: assert os.path.exists(bdf_model), '%r doesnt exist' % bdf_model fem = BDF(debug=True, log=log) fem.read_bdf(bdf_model) sys.stdout.flush() structural_model = StructuralModel(fem, property_regions) mapper = LoadMapping(aero_model, structural_model, configpath, workpath) t1 = time() mapper.set_flight_condition(pInf, qInf) mapper.set_reference_quantities(Sref, Lref, xref) mapper.set_scale_factors(force_scale, moment_scale) mapper.set_output(bdffile=bdf_model_out, load_case=isubcase) log.info("setup time = %g sec; %g min" % (t1 - t0, (t1 - t0) / 60.)) mapper.build_mapping_matrix(debug=False) t2 = time() log.info("mapping matrix time = %g sec; %g min" % (t2 - t1, (t2 - t1) / 60.)) mapper.map_loads() t3 = time() log.info("map loads time = %g sec" % (t3 - t2)) log.info("total time = %g min" % ((t3 - t0) / 60.))
def read_cart3d(self, cart3d_filename): Cart3D.read_cart3d(self, cart3d_filename)
def read_half_cart3d_points(cfd_grid_file): """return half model points to shrink xK matrix""" cart = Cart3D() cart.read_cart3d(cfd_grid_file) points, elements, regions, loads = cart.make_half_model() return points
def load_cart3d_geometry(self, cart3d_filename, dirname, name='main', plot=True): skip_reading = self._remove_old_cart3d_geometry(cart3d_filename) if skip_reading: return self.eid_map = {} self.nid_map = {} model = Cart3D(log=self.log, debug=False) self.model_type = 'cart3d' #self.model_type = model.model_type model.read_cart3d(cart3d_filename) nodes = model.nodes elements = model.elements regions = model.regions loads = model.loads self.nNodes = model.npoints self.nElements = model.nelements self.grid.Allocate(self.nElements, 1000) points = vtk.vtkPoints() points.SetNumberOfPoints(self.nNodes) self.nid_map = {} if 0: fraction = 1. / self.nNodes # so you can color the nodes by ID for nid, node in sorted(iteritems(nodes)): points.InsertPoint(nid - 1, *node) self.gridResult.InsertNextValue(nid * fraction) assert nodes is not None nnodes = nodes.shape[0] mmax = nodes.max(axis=0) mmin = nodes.min(axis=0) dim_max = (mmax - mmin).max() xmax, ymax, zmax = mmax xmin, ymin, zmin = mmin self.log_info("xmin=%s xmax=%s dx=%s" % (xmin, xmax, xmax - xmin)) self.log_info("ymin=%s ymax=%s dy=%s" % (ymin, ymax, ymax - ymin)) self.log_info("zmin=%s zmax=%s dz=%s" % (zmin, zmax, zmax - zmin)) self.create_global_axes(dim_max) data_type = vtk.VTK_FLOAT points_array = numpy_to_vtk(num_array=nodes, deep=True, array_type=data_type) points.SetData(points_array) nelements = elements.shape[0] elements -= 1 for eid in range(nelements): elem = vtkTriangle() node_ids = elements[eid, :] elem.GetPointIds().SetId(0, node_ids[0]) elem.GetPointIds().SetId(1, node_ids[1]) elem.GetPointIds().SetId(2, node_ids[2]) self.grid.InsertNextCell( 5, elem.GetPointIds()) #elem.GetCellType() = 5 # vtkTriangle self.grid.SetPoints(points) self.grid.Modified() if hasattr(self.grid, 'Update'): self.grid.Update() self._create_cart3d_free_edegs(model, nodes, elements) # loadCart3dResults - regions/loads self.turn_text_on() self.scalarBar.VisibilityOn() self.scalarBar.Modified() assert loads is not None if 'Mach' in loads: avg_mach = mean(loads['Mach']) note = ': avg(Mach)=%g' % avg_mach else: note = '' self.iSubcaseNameMap = {1: ['Cart3d%s' % note, '']} cases = {} ID = 1 form, cases, icase = self._fill_cart3d_case2(cases, ID, nodes, elements, regions, model) mach, alpha, beta = self._create_box(cart3d_filename, ID, form, cases, icase, regions) self._fill_cart3d_results(cases, form, icase, ID, loads, model, mach) self._finish_results_io2(form, cases)
def load_cart3d_results(self, cart3d_filename, dirname): model = Cart3D(log=self.log, debug=False) self.load_cart3d_geometry(cart3d_filename, dirname)
def nastran_to_cart3d(bdf, log=None, debug=False): """ Converts a Nastran BDF() object to a Cart3D() object. Parameters ---------- bdf : BDF() a BDF object log : log; default=None -> dummyLogger a logger object debug : bool; default=False True/False (used if log is not defined) Returns ------- cart3d : Cart3D() a Cart3D object """ cart3d = Cart3D(log=log, debug=debug) nnodes = len(bdf.nodes) nelements = 0 if 'CTRIA3' in bdf.card_count: nelements += bdf.card_count['CTRIA3'] if 'CQUAD4' in bdf.card_count: nelements += bdf.card_count['CQUAD4'] * 2 nodes = zeros((nnodes, 3), 'float64') elements = zeros((nelements, 3), 'int32') regions = zeros(nelements, 'int32') i = 0 nids = array(list(bdf.nodes.keys()), dtype='int32') nids_expected = arange(1, len(nids) + 1) if array_equal(nids, nids_expected): # we don't need to renumber the nodes # so we don't need to make an nid_map for node_id, node in sorted(iteritems(bdf.nodes)): nodes[i, :] = node.get_position() i += 1 i = 0 for element_id, element in sorted(iteritems(bdf.elements)): if element.type == 'CTRIA3': nids = element.node_ids elements[i, :] = nids regions[i] = element.Mid() #elif element.type == 'CQUAD4': #nids = element.node_ids #elements[i, :] = nids #regions[i] = element.Mid() else: raise NotImplementedError(element.type) i += 1 else: nid_map = {} for node_id, node in sorted(iteritems(bdf.nodes)): nodes[i, :] = node.get_position() i += 1 nid_map[node_id] = i i = 0 for element_id, element in sorted(iteritems(bdf.elements)): if element.type == 'CTRIA3': nids = element.node_ids elements[i, :] = [nid_map[nid] for nid in nids] regions[i] = element.material_ids[0] elif element.type == 'CQUAD4': nids = element.node_ids quad = [nid_map[nid] for nid in nids] mid = element.material_ids[0] # TODO: splits on edge 1-3, not the max angle # since we're just comparing the models, it doesn't matter elements[i, :] = [quad[0], quad[1], quad[2]] regions[i] = mid i += 1 elements[i, :] = [quad[0], quad[2], quad[3]] regions[i] = mid else: raise NotImplementedError(element.type) i += 1 assert elements.min() > 0, elements cart3d.nodes = nodes cart3d.elements = elements - 1 cart3d.regions = regions return cart3d
def tecplot_to_cart3d(tecplot_filename, cart3d_filename=None, remove_degenerate_tris=True, log=None, debug=True): """ Converts a Tecplot file to Cart3d. Parameters ---------- remove_degenerate_tris : bool; default=False removes degenerate triangles (triangles with an area of 0.0) """ if isinstance(tecplot_filename, str): model = read_tecplot(tecplot_filename, log=log, debug=debug) else: model = tecplot_filename assert len(model.zones) == 1, 'only 1 zone is supported' for izone, zone in enumerate(model.zones): #print(zone) tris, xyz = get_zone_tris_xyz(zone) if remove_degenerate_tris: assert tris.shape[0] > 0, tris.shape assert xyz.shape[0] > 0, xyz.shape A = _get_tri_area(tris, xyz) iarea = np.where(A > 0.)[0] tris = tris[iarea, :] npoints = xyz.shape[0] assert npoints > 0, xyz.shape nelements = tris.shape[0] assert nelements > 0, nelements assert tris.shape[1] == 3, tris.shape #print('npoints=%s nelements=%s' % (npoints, nelements)) #removed_nodes = False regions = np.zeros(nelements, dtype='int32') ones_float = np.ones(npoints, dtype='float64') cart3d_model = Cart3D(log=log) cart3d_model.points = xyz cart3d_model.regions = regions cart3d_model.elements = tris # + 1 assert npoints > 0, npoints headers_no_xyz = model.variables[3:] # drop the xyz, get what's left if 'cp' in headers_no_xyz: iCp = headers_no_xyz.index('cp') cp = model.results[:, iCp] assert len(cp) == npoints cart3d_model.loads = { 'Cp': cp, # nodal Cp 'rho': ones_float, 'rhoU': ones_float, 'rhoV': ones_float, 'rhoW': ones_float, 'E': ones_float, } else: model.log.debug('skipping Cp') if cart3d_filename is not None: cart3d_model.write_cart3d(cart3d_filename) return cart3d_model