def process_ugrid(ugrid_filename, fmt2, fname2, log, data=None, quiet=False): """ Converts UGRID to Nastran/Cart3d/STL/Tecplot """ assert fmt2 in ['stl', 'nastran', 'cart3d', 'tecplot'], 'format2=%s' % fmt2 read_shells = True read_solids = True if fmt2 in ['stl', 'cart3d']: read_shells = True read_solids = False from pyNastran.converters.aflr.ugrid.ugrid_reader import UGRID model = UGRID(read_shells=read_shells, read_solids=read_solids, log=log) model.read_ugrid(ugrid_filename) if fmt2 == 'nastran': # ugrid_to_nastran(model, fname2 include_shells = True include_solids = True bdf_filename = fname2 model.write_bdf(bdf_filename, include_shells=include_shells, include_solids=include_solids) elif fmt2 == 'cart3d': include_shells = True include_solids = False bdf_filename = fname2 + '.bdf' model.write_bdf(bdf_filename, include_shells=include_shells, include_solids=include_solids) # ugrid_to_cart3d(model, fname2) process_nastran(bdf_filename, 'cart3d', fname2, data=None) elif fmt2 == 'stl': include_shells = True include_solids = False bdf_filename = fname2 + '.bdf' model.write_bdf(bdf_filename, include_shells=include_shells, include_solids=include_solids) process_nastran(bdf_filename, 'cart3d', fname2, data=None) # ugrid_to_stl(model, fname2) elif fmt2 == 'tecplot': from pyNastran.converters.aflr.ugrid.ugrid3d_to_tecplot import ugrid_to_tecplot # ugrid_to_tecplot(model, fname2) tecplot, unused_zone = ugrid_to_tecplot(model) element_slice(tecplot, data) tecplot_filename = fname2 tecplot.write_tecplot(tecplot_filename) else: raise NotImplementedError('fmt2=%s is not supported by process_ugrid' % fmt2)
def ugrid3d_to_tecplot_filename(ugrid_filename, tecplot_filename, log=None, debug=False): """ Converts a UGRID to a Tecplot ASCII file. Parameters ---------- ugrid_filename : varies str : the input UGRID filename UGRID : the UGRID object tecplot_filename : str the output Tecplot filename log : logger; default=None a logger object debug : bool; default=False developer debug """ if isinstance(ugrid_filename, str): #assert os.path.exists(ugrid_filename), '%r doesnt exist' % ugrid_filename model = UGRID(log=log, debug=debug) model.read_ugrid(ugrid_filename) else: model = ugrid_filename model.write_tecplot(tecplot_filename)
def get_ugrid_model(ugrid_filename, read_solids, log): """helper method for UGRID_IO""" if read_solids or is_binary_file(ugrid_filename): model = UGRID(log=log, debug=True, read_solids=read_solids) ext = os.path.basename(ugrid_filename).split('.')[2] # base, fmt, ext is_2d = False else: ext = os.path.basename(ugrid_filename).split('.')[1] # base, ext model = UGRID2D_Reader(log=log, debug=True) is_2d = True is_3d = not is_2d assert ext == 'ugrid', ugrid_filename return model, is_2d, is_3d
def ugrid3d_to_nastran(ugrid_filename, bdf_filename, include_shells=True, include_solids=True, convert_pyram_to_penta=False, encoding=None, size=16, is_double=False, log=None): """ Converts a UGRID to a BDF. Parameters ---------- ugrid_filename : str the input UGRID filename bdf_filename : str the output BDF filename include_shells : bool; default=True should the shells be written include_solids : bool; default=True should the solids be written convert_pyram_to_penta : bool; default=False False : NX Nastran True : MSC Nastran size : int; {8, 16}; default=16 the bdf write precision is_double : bool; default=False the field precision to write log : logger; default=None a logger object Returns ------- ugrid_model : UGRID() the ugrid model """ model = UGRID(log=log, debug=False) check_path(ugrid_filename, 'ugrid_filename') model.read_ugrid(ugrid_filename) model.write_bdf(bdf_filename, include_shells=include_shells, include_solids=include_solids, convert_pyram_to_penta=convert_pyram_to_penta, encoding=encoding, size=size, is_double=is_double) return model
def nastran_to_ugrid(bdf_filename, ugrid_filename_out=None, properties=None, check_shells=True, check_solids=True, log=None): """ set xref=False Parameters ---------- bdf_filename : varies str : a bdf filename BDF() : a BDF object ugrid_filename_out : str (default=None -> ???) the path to the ugrid_filename properties : Dict[pid_old]=pid_new??? ??? check_shells : bool (default=True) verify that there is at least one shell element check_solids : bool (default=True) verify that there is at least one solid element log : Logger() a Python logging object """ if isinstance(bdf_filename, str): bdf_model = read_bdf(bdf_filename, log=log) else: bdf_model = bdf_filename log = bdf_model.log # pids_to_inlcude = [] # for pid, prop in model.properties.items(): # if prop.type == 'PSHELL': # pids_to_include.append(pid) if properties is not None: for pid, pid_new in properties.items(): bdf_model.properties[pid].pid = pid_new card_types = [ 'CQUAD4', 'CTRIA3', 'CTETRA', 'CHEXA', 'GRID', 'CPENTA', 'CPYRAM' ] out = bdf_model.get_card_ids_by_card_types(card_types) node_ids = out['GRID'] ctria3 = out['CTRIA3'] cquad4 = out['CQUAD4'] ctetra = out['CTETRA'] cpyram = out['CPYRAM'] cpenta = out['CPENTA'] chexa = out['CHEXA'] nnodes = len(node_ids) ntris = len(ctria3) nquads = len(cquad4) nshells = ntris + nquads ntetra = len(ctetra) npyram = len(cpyram) npenta = len(cpenta) nhexa = len(chexa) nsolids = ntetra + npyram + npenta + nhexa msg = '' if nnodes == 0: msg += 'nnodes=0, ' if nshells == 0 and check_shells: msg += 'nshells=0, ' if nsolids == 0 and check_solids: msg += 'nsolids=0' if msg: msg2 = 'ERROR: ' + msg.strip( ' ,') + '\nnnodes=%i nshells=%i nsolids=%i' % (nnodes, nshells, nsolids) raise RuntimeError(msg2) nodes = bdf_model.nodes elements = bdf_model.elements xyz_cid0 = array([nodes[nid].xyz for nid in node_ids], dtype='float64') pids = [] model = UGRID(log=log) model.nodes = xyz_cid0 if ntris: model.tris = array([elements[eid].node_ids for eid in ctria3], dtype='int32') ptris = array([elements[eid].Pid() for eid in ctria3], dtype='int32') pids.append(ptris) if nquads: model.quads = array([elements[eid].node_ids for eid in cquad4], dtype='int32') pquads = array([elements[eid].Pid() for eid in cquad4], dtype='int32') pids.append(pquads) if check_shells: if len(pids) == 1: model.pids = pids[0] elif len(pids) == 2: model.pids = hstack(pids) else: raise RuntimeError(pids) if ntetra: model.tets = array([elements[eid].node_ids for eid in ctetra], dtype='int32') if npyram: model.penta5s = array([elements[eid].node_ids for eid in cpyram], dtype='int32') if nhexa: model.penta6s = array([elements[eid].node_ids for eid in cpenta], dtype='int32') if nhexa: model.hexas = array([elements[eid].node_ids for eid in chexa], dtype='int32') model.log.debug('ugrid_filename_out = %r' % ugrid_filename_out) if ugrid_filename_out is not None: model.write_ugrid(ugrid_filename_out, check_shells=check_shells, check_solids=check_solids) return model
def load_ugrid_geometry(self, ugrid_filename, name='main', plot=True): #skip_reading = self.remove_old_openfoam_geometry(openfoam_filename) #if skip_reading: # return if is_binary_file(ugrid_filename): model = UGRID(log=self.log, debug=True) base, fmt, ext = os.path.basename(ugrid_filename).split('.') is_2d = False else: base, ext = os.path.basename(ugrid_filename).split('.') model = UGRID2D_Reader(log=self.log, debug=True) is_2d = True self.model_type = 'ugrid' self.log.debug('ugrid_filename = %s' % ugrid_filename) assert ext == 'ugrid', ugrid_filename model.read_ugrid(ugrid_filename) if is_2d: tris = model.tris quads = model.quads else: tris = model.tris - 1 quads = model.quads - 1 #self.nodes = nodes #self.tris = tris #self.quads = quads #self.pids = pids #self.tets = tets #self.penta5s = penta5s #self.penta6s = penta6s #self.hexas = hexas nnodes = model.nodes.shape[0] ntris = model.tris.shape[0] nquads = model.quads.shape[0] nelements = ntris + nquads nodes = model.nodes self.nElements = nelements self.nNodes = nnodes self.log.info("nnodes=%s nelements=%s" % (self.nNodes, self.nElements)) assert nelements > 0, nelements self.grid.Allocate(self.nElements, 1000) mmax = amax(nodes, axis=0) mmin = amin(nodes, axis=0) dim_max = (mmax - mmin).max() self.create_global_axes(dim_max) self.log.info('max = %s' % mmax) self.log.info('min = %s' % mmin) diff_node_ids = model.check_hanging_nodes(stop_on_diff=False) if len(diff_node_ids): red = (1., 0., 0.) self.create_alternate_vtk_grid('hanging_nodes', color=red, line_width=5, opacity=1., point_size=10, representation='point') self._add_ugrid_nodes_to_grid('hanging_nodes', diff_node_ids, nodes) self._add_alt_actors(self.alt_grids) points = self.numpy_to_vtk_points(nodes) if ntris: for eid, element in enumerate(tris): elem = vtkTriangle() elem.GetPointIds().SetId(0, element[0]) elem.GetPointIds().SetId(1, element[1]) elem.GetPointIds().SetId(2, element[2]) self.grid.InsertNextCell(elem.GetCellType(), elem.GetPointIds()) if nquads: for eid, element in enumerate(quads): elem = vtkQuad() elem.GetPointIds().SetId(0, element[0]) elem.GetPointIds().SetId(1, element[1]) elem.GetPointIds().SetId(2, element[2]) elem.GetPointIds().SetId(3, element[3]) self.grid.InsertNextCell(elem.GetCellType(), elem.GetPointIds()) self.nElements = nelements self.grid.SetPoints(points) self.grid.Modified() self.log.info('update...') if hasattr(self.grid, 'Update'): self.grid.Update() #self.log.info("updated grid") # loadCart3dResults - regions/loads self.scalarBar.VisibilityOn() self.scalarBar.Modified() self.isubcase_name_map = {1: ['AFLR UGRID Surface', '']} cases = {} ID = 1 if hasattr(model, 'pids'): form, cases = self._fill_ugrid3d_case(ugrid_filename, cases, ID, nnodes, nelements, model) else: form, cases = self._fill_ugrid2d_case(ugrid_filename, cases, ID, nnodes, nelements, model) if plot: self._finish_results_io2(form, cases)
def load_ugrid_geometry(self, ugrid_filename, name='main', plot=True): """ The entry point for UGRID geometry loading. Parameters ---------- ugrid_filename : str the ugrid filename to load name : str the name of the "main" actor for the GUI plot : bool; default=True should the model be generated or should we wait until after the results are loaded """ #skip_reading = self.remove_old_openfoam_geometry(openfoam_filename) #if skip_reading: # return read_solids = False if is_binary_file(ugrid_filename): model = UGRID(log=self.log, debug=True, read_solids=read_solids) ext = os.path.basename(ugrid_filename).split('.')[ 2] # base, fmt, ext is_2d = False else: ext = os.path.basename(ugrid_filename).split('.')[1] # base, ext model = UGRID2D_Reader(log=self.log, debug=True) is_2d = True is_3d = not is_2d self.model_type = 'ugrid' self.log.debug('ugrid_filename = %s' % ugrid_filename) assert ext == 'ugrid', ugrid_filename model.read_ugrid(ugrid_filename) self.model = model nnodes = model.nodes.shape[0] ntris = model.tris.shape[0] nquads = model.quads.shape[0] ntets = 0 npenta5s = 0 npenta6s = 0 nhexas = 0 if is_2d: tris = model.tris quads = model.quads nelements = ntris + nquads else: if read_solids: ntets = model.tets.shape[0] npenta5s = model.penta5s.shape[0] npenta6s = model.penta6s.shape[0] nhexas = model.hexas.shape[0] tets = model.tets - 1 penta5s = model.penta5s - 1 penta6s = model.penta6s - 1 hexas = model.hexas - 1 nelements = ntets + npenta5s + npenta6s + nhexas else: tris = model.tris - 1 quads = model.quads - 1 nelements = ntris + nquads #self.nodes = nodes #self.tris = tris #self.quads = quads #self.pids = pids #self.tets = tets #self.penta5s = penta5s #self.penta6s = penta6s #self.hexas = hexas nodes = model.nodes self.nelements = nelements self.nnodes = nnodes self.log.info("nnodes=%s nelements=%s" % (self.nnodes, self.nelements)) assert nelements > 0, nelements grid = self.grid grid.Allocate(self.nelements, 1000) mmax = amax(nodes, axis=0) mmin = amin(nodes, axis=0) dim_max = (mmax - mmin).max() self.create_global_axes(dim_max) self.log.info('max = %s' % mmax) self.log.info('min = %s' % mmin) if is_3d and read_solids: diff_node_ids = model.check_hanging_nodes(stop_on_diff=False) if len(diff_node_ids): red = (1., 0., 0.) self.create_alternate_vtk_grid('hanging_nodes', color=red, line_width=5, opacity=1., point_size=10, representation='point') self._add_ugrid_nodes_to_grid('hanging_nodes', diff_node_ids, nodes) self._add_alt_actors(self.alt_grids) points = numpy_to_vtk_points(nodes) elements = [] etypes = [] if is_2d or not read_solids: if ntris: elements.append(tris) etypes.append(5) # vtkTriangle().GetCellType() if nquads: elements.append(quads) etypes.append(9) # vtkQuad().GetCellType() elif is_3d: if ntets: elements.append(tets) etypes.append(10) # VTK_TETRA().GetCellType() if npenta5s: elements.append(penta5s) etypes.append(14) # vtk.vtkPyramid().GetCellType() if npenta6s: elements.append(penta6s) etypes.append(13) # VTK_WEDGE().GetCellType() if nhexas: elements.append(tetras) etypes.append(12) # VTK_HEXAHEDRON().GetCellType() self.model.elements = elements self.model.etypes = etypes create_vtk_cells_of_constant_element_types(grid, elements, etypes) self.nelements = nelements grid.SetPoints(points) grid.Modified() if hasattr(grid, 'Update'): # pragma: no cover grid.Update() # loadCart3dResults - regions/loads self.scalarBar.VisibilityOn() self.scalarBar.Modified() self.isubcase_name_map = {1: ['AFLR UGRID Surface', '']} cases = OrderedDict() ID = 1 if hasattr(model, 'pids'): form, cases = self._fill_ugrid3d_case(ugrid_filename, cases, ID, nnodes, nelements, model, read_solids) else: form, cases = self._fill_ugrid2d_case(cases, ID, nnodes, nelements) if plot: self._finish_results_io2(form, cases)
def _update_merge(ugrid_filename: str, bdf_filename: str, pshell_pids_to_remove: List[int], tol: float, log: Optional[SimpleLogger] = None) -> BDF: ugrid_model = UGRID(log=log, debug=False) ugrid_model.read_ugrid(ugrid_filename) bdf_model = read_bdf(bdf_filename, xref=False, log=log) #bdf_model.write_bdf(bdf_merged_filename, interspersed=False, enddata=False) nid0 = max(bdf_model.nodes) + 1 # new node ids start at max+1 nid_offset = nid0 - 1 # node_ids are 1-based, so we must offset them eid = max(bdf_model.elements) + 1 cp = None for nid, node in enumerate(ugrid_model.nodes): #assert len(node) == 3, node card = ['GRID', nid + nid0, cp] + list(node) bdf_model.add_card(card, 'GRID', is_list=True) #f.write(print_card_double(card)) pid_solid = 100 mid = 1 pids = unique(ugrid_model.pids) for pidi in pids: if pidi not in pshell_pids_to_remove: card = ['PSHELL', pidi, mid, 0.1] bdf_model.add_card(card, 'PSHELL', is_list=True) card = ['PSOLID', pid_solid, mid] bdf_model.add_card(card, 'PSOLID', is_list=True) card = ['MAT1', mid, 3.0e7, None, 0.3] bdf_model.add_card(card, 'MAT1', is_list=True) shells = [ ('CQUAD4', ugrid_model.quads), ('CTRIA3', ugrid_model.tris), ] for card_type, card_nodes in shells: if card_nodes.shape[0]: for pid, nodes in zip(ugrid_model.pids, card_nodes + nid_offset): if pid not in pshell_pids_to_remove: card = [ card_type, eid, pid, ] + list(nodes) bdf_model.add_card(card, card_type, is_list=True) eid += 1 solids = [ ('CTETRA', ugrid_model.tets), ('CPYRAM', ugrid_model.penta5s), ('CPENTA', ugrid_model.penta6s), ('CHEXA', ugrid_model.hexas), ] for card_type, card_nodes in solids: if card_nodes.shape[0]: for nodes in card_nodes + nid_offset: card = [ card_type, eid, pid_solid, ] + list(nodes) bdf_model.add_card(card, card_type, is_list=True) eid += 1 # tol = min_edge_length / 2.0 # TODO: remove this... bdf_model.write_bdf('model_join.bdf', interspersed=False) bdf_model.cross_reference() return bdf_model
def equivalence_ugrid3d_and_bdf_to_bdf(ugrid_filename, bdf_filename, pshell_pids_to_remove, tol=0.01, renumber=True): """ Merges a UGRID3D (*.ugrid) with a BDF and exports a BDF that is equivalenced and renumbered. Parameters ---------- ugrid_filename : str the AFLR3/UGrid3d filename bdf_filename : str the BDF filename pshell_pids_to_remove : List[int, ...] tol : float; default=0.01 the equivalence tolerance renumber : bool; default=True calls ``bdf_renumber`` to renumber the output BDF model Returns ------- out_bdf_filename : str the output BDF filename """ print('equivalence_ugrid3d_and_bdf_to_bdf - bdf_filename=%s' % bdf_filename) print('equivalence_ugrid3d_and_bdf_to_bdf - ugrid_filename=%s' % ugrid_filename) check_path(ugrid_filename, 'ugrid_filename') base = os.path.splitext(bdf_filename)[0] #bdf_merged_filename = base + '_merged.bdf' bdf_equivalence_filename = base + '_equivalence.bdf' bdf_renumber_filename = base + '_renumber.bdf' update_merge = True if update_merge: ugrid_model = UGRID(log=None, debug=False) ugrid_model.read_ugrid(ugrid_filename) bdf_model = read_bdf(bdf_filename, xref=False) #bdf_model.write_bdf(bdf_merged_filename, interspersed=False, enddata=False) tol = 0.01 nid0 = max(bdf_model.nodes) + 1 # new node ids start at max+1 nid_offset = nid0 - 1 # node_ids are 1-based, so we must offset them eid = max(bdf_model.elements) + 1 cp = None for nid, node in enumerate(ugrid_model.nodes): #assert len(node) == 3, node card = ['GRID', nid + nid0, cp] + list(node) bdf_model.add_card(card, 'GRID', is_list=True) #f.write(print_card_double(card)) pid_solid = 100 mid = 1 pids = unique(ugrid_model.pids) for pidi in pids: if pidi not in pshell_pids_to_remove: card = ['PSHELL', pidi, mid, 0.1] bdf_model.add_card(card, 'PSHELL', is_list=True) card = ['PSOLID', pid_solid, mid] bdf_model.add_card(card, 'PSOLID', is_list=True) card = ['MAT1', mid, 3.0e7, None, 0.3] bdf_model.add_card(card, 'MAT1', is_list=True) shells = [ ('CQUAD4', ugrid_model.quads), ('CTRIA3', ugrid_model.tris), ] for card_type, card_nodes in shells: if card_nodes.shape[0]: for pid, nodes in zip(ugrid_model.pids, card_nodes + nid_offset): if pid not in pshell_pids_to_remove: card = [ card_type, eid, pid, ] + list(nodes) bdf_model.add_card(card, card_type, is_list=True) eid += 1 solids = [ ('CTETRA', ugrid_model.tets), ('CPYRAM', ugrid_model.penta5s), ('CPENTA', ugrid_model.penta6s), ('CHEXA', ugrid_model.hexas), ] for card_type, card_nodes in solids: if card_nodes.shape[0]: for nodes in card_nodes + nid_offset: card = [ card_type, eid, pid_solid, ] + list(nodes) bdf_model.add_card(card, card_type, is_list=True) eid += 1 # tol = min_edge_length / 2.0 # TODO: remove this... bdf_model.write_bdf('model_join.bdf', interspersed=False) bdf_model.cross_reference() bdf_equivalence_nodes(bdf_model, bdf_equivalence_filename, tol, renumber_nodes=False, neq_max=10, xref=False) if renumber: starting_ids_dict = { 'cid': 1, 'nid': 1, 'eid': 1, 'pid': 1, 'mid': 1, } bdf_renumber(bdf_equivalence_filename, bdf_renumber_filename, size=16, is_double=False, starting_id_dict=starting_ids_dict) #os.remove(bdf_equivalence_filename) out_bdf_filename = bdf_renumber_filename else: out_bdf_filename = bdf_equivalence_filename #os.remove(bdf_merged_filename) #os.remove(bdf_renumber_filename) return out_bdf_filename