def update_grid_function(unused_nid_map, ugrid, points, nodes): # pragma: no cover """custom function to update the 3d bars""" if not gui.settings.nastran_is_3d_bars_update: return points_list = [] node0b = 0 for eid in bar_beam_eids: elem = self.model.elements[eid] pid_ref = elem.pid_ref if pid_ref is None: pid_ref = self.model.Property(elem.pid) assert not isinstance(pid_ref, integer_types), elem ptype = pid_ref.type bar_type = _get_bar_type(ptype, pid_ref) #nids = elem.nodes (nid1, nid2) = elem.node_ids node1 = model.nodes[nid1] node2 = model.nodes[nid2] i1, i2 = np.searchsorted(self.node_ids, [nid1, nid2]) n1 = nodes[i1, :] n2 = nodes[i2, :] #centroid = (n1 + n2) / 2. i = n2 - n1 Li = norm(i) ihat = i / Li unused_v, wa, wb, xform = rotate_v_wa_wb( model, elem, n1, n2, node1, node2, ihat, i, eid, Li, model.log) if wb is None: # one or more of v, wa, wb are bad continue ugridi = None node0b = add_3d_bar_element( bar_type, ptype, pid_ref, n1+wa, n2+wb, xform, ugridi, node0b, points_list, add_to_ugrid=False) points_array = _make_points_array(points_list) points_array2 = numpy_to_vtk( num_array=points_array, deep=1, array_type=vtk.VTK_FLOAT, ) points.SetData(points_array2) ugrid.SetPoints(points) points.Modified() ugrid.Modified() return
def get_axes(self, model): """ Gets the axes of a CBAR/CBEAM, while respecting the OFFT flag. See --- ``_rotate_v_wa_wb`` for a description of the OFFT flag. TODO: not integrated with CBAR yet... """ is_failed = True ihat = None yhat = None zhat = None eid = self.eid (nid1, nid2) = self.node_ids node1 = model.nodes[nid1] node2 = model.nodes[nid2] n1 = node1.get_position() n2 = node2.get_position() #centroid = (n1 + n2) / 2. #i = n2 - n1 #Li = norm(i) #ihat = i / Li elem = model.elements[eid] pid_ref = elem.pid_ref if pid_ref is None: pid_ref = model.Property(elem.pid) assert not isinstance(pid_ref, integer_types), elem (nid1, nid2) = elem.node_ids node1 = model.nodes[nid1] node2 = model.nodes[nid2] n1 = node1.get_position() n2 = node2.get_position() # wa/wb are not considered in i_offset # they are considered in ihat i = n2 - n1 Li = norm(i) i_offset = i / Li unused_v, wa, wb, xform = rotate_v_wa_wb(model, elem, n1, n2, node1, node2, i_offset, i, eid, Li) if wb is None: # one or more of v, wa, wb are bad return is_failed, (wa, wb, ihat, yhat, zhat) ihat = xform[0, :] yhat = xform[1, :] zhat = xform[2, :] is_failed = False return is_failed, (wa, wb, ihat, yhat, zhat)
def get_axes_by_nodes(self, model: BDF, pid_ref, node1, node2, xyz1, xyz2, log): """ Gets the axes of a CBAR/CBEAM, while respecting the OFFT flag. Notes ----- :func:`pyNastran.bdf.cards.elements.bars.rotate_v_wa_wb` for a description of the OFFT flag. """ #TODO: not integrated with CBAR yet... is_failed = True eid = self.eid #centroid = (n1 + n2) / 2. #i = n2 - n1 #Li = norm(i) #ihat = i / Li elem = self #(nid1, nid2) = elem.node_ids #node1 = model.nodes[nid1] #node2 = model.nodes[nid2] #xyz1 = node1.get_position() #xyz2 = node2.get_position() # wa/wb are not considered in i_offset # they are considered in ihat i = xyz2 - xyz1 ihat_norm = norm(i) if ihat_norm== 0.: msg = 'xyz1=%s xyz2=%s\n%s' % (xyz1, xyz2, self) raise ValueError(msg) i_offset = i / ihat_norm unused_v, wa, wb, xform = rotate_v_wa_wb( model, elem, xyz1, xyz2, node1, node2, i_offset, i, eid, ihat_norm, log) if wb is None: # one or more of v, wa, wb are bad # xform is xform_offset...assuming None ihat = None yhat = None zhat = None return is_failed, (wa, wb, ihat, yhat, zhat) ihat = xform[0, :] yhat = xform[1, :] zhat = xform[2, :] is_failed = False return is_failed, (wa, wb, ihat, yhat, zhat)
def get_axes_by_nodes(self, model, pid_ref, node1, node2, xyz1, xyz2, log): """ Gets the axes of a CBAR/CBEAM, while respecting the OFFT flag. See --- ``_rotate_v_wa_wb`` for a description of the OFFT flag. TODO: not integrated with CBAR yet... """ is_failed = True eid = self.eid #centroid = (n1 + n2) / 2. #i = n2 - n1 #Li = norm(i) #ihat = i / Li elem = self #(nid1, nid2) = elem.node_ids #node1 = model.nodes[nid1] #node2 = model.nodes[nid2] #xyz1 = node1.get_position() #xyz2 = node2.get_position() # wa/wb are not considered in i_offset # they are considered in ihat i = xyz2 - xyz1 Li = norm(i) i_offset = i / Li unused_v, wa, wb, xform = rotate_v_wa_wb( model, elem, xyz1, xyz2, node1, node2, i_offset, i, eid, Li, log) if wb is None: # one or more of v, wa, wb are bad # xform is xform_offset...assuming None ihat = None yhat = None zhat = None return is_failed, (wa, wb, ihat, yhat, zhat) ihat = xform[0, :] yhat = xform[1, :] zhat = xform[2, :] is_failed = False return is_failed, (wa, wb, ihat, yhat, zhat)
def update_3d_beams(ugrid, model: BDF, bar_pid_to_eids: Dict[int, List[int]]) -> Any: node0 = 0 points_list = [] for pid, eids in bar_pid_to_eids.items(): pid_ref = model.properties[pid] ptype = pid_ref.type bar_type = pid_ref.bar_type #if bar_type == {'BAR', 'TUBE', 'TUBE2', 'ROD'}: #continue if ptype == 'PBARL': dim1 = dim2 = pid_ref.dim elif ptype == 'PBEAML': dim1 = pid_ref.dim[0, :] dim2 = pid_ref.dim[-1, :] else: raise NotImplementedError(pid_ref) #dim1 = dim2 = None #return node0 try: func = BEAM_SETUP_MAP[bar_type] except KeyError: raise NotImplementedError(pid_ref) #print('skipping 3d bar_type = %r' % bar_type) #return node0 faces, points1, points2 = func(dim1, dim2) del faces for eid in eids: elem = model.elements[eid] (nid1, nid2) = elem.node_ids #bar_nids.update([nid1, nid2]) node1 = model.nodes[nid1] node2 = model.nodes[nid2] n1 = node1.get_position() n2 = node2.get_position() # wa/wb are not considered in i_offset # they are considered in ihat i = n2 - n1 Li = norm(i) ihat = i / Li unused_v, wa, wb, xform = rotate_v_wa_wb( model, elem, n1, n2, node1, node2, ihat, i, eid, Li, model.log) if wb is None: # one or more of v, wa, wb are bad continue pointsi = transform_points(n1+wa, n2+wb, points1, points2, xform) dnode = points1.shape[0] * 2 node0 += dnode points_list.append(pointsi) if node0: points = _create_vtk_points_from_list(points_list) ugrid.SetPoints(points) ugrid.Modified() return
def create_3d_beams(model: BDF, bar_pid_to_eids: Dict[int, List[int]]) -> Optional[vtk.vtkUnstructuredGrid]: if len(bar_pid_to_eids) == 0: return None ugrid = vtk.vtkUnstructuredGrid() node0 = 0 points_list = [] eids_bad = [] for pid, eids in bar_pid_to_eids.items(): pid_ref = model.properties[pid] ptype = pid_ref.type bar_type = pid_ref.beam_type if bar_type == {'BAR', 'TUBE', 'TUBE2', 'ROD', 'DBOX', 'HAT1', 'BOX1'}: continue if ptype == 'PBARL': dim1 = dim2 = pid_ref.dim elif ptype == 'PBEAML': dim1 = pid_ref.dim[0, :] dim2 = pid_ref.dim[-1, :] else: raise NotImplementedError(pid_ref) #dim1 = dim2 = None #return node0 try: func = BEAM_SETUP_MAP[bar_type] except KeyError: raise NotImplementedError(pid_ref) #print('skipping 3d bar_type = %r' % bar_type) #return node0 faces, points1, points2 = func(dim1, dim2) for eid in eids: elem = model.elements[eid] (nid1, nid2) = elem.node_ids #bar_nids.update([nid1, nid2]) node1 = model.nodes[nid1] node2 = model.nodes[nid2] n1 = node1.get_position() n2 = node2.get_position() # wa/wb are not considered in i_offset # they are considered in ihat i = n2 - n1 Li = norm(i) ihat = i / Li #if elem.pa != 0: #nid_release_map[nid1].append((eid, elem.pa)) #if elem.pb != 0: #nid_release_map[nid2].append((eid, elem.pb)) unused_v, wa, wb, xform = rotate_v_wa_wb( model, elem, n1, n2, node1, node2, ihat, i, eid, Li, model.log) if wb is None: # one or more of v, wa, wb are bad eids_bad.append(eid) continue yhat = xform[1, :] zhat = xform[2, :] pointsi = transform_points(n1+wa, n2+wb, points1, points2, xform) face_idlist = faces_to_element_facelist(faces, node0) ugrid.InsertNextCell(vtk.VTK_POLYHEDRON, face_idlist) dnode = points1.shape[0] * 2 node0 += dnode points_list.append(pointsi) #-------------------------------------------- #bar_typei = get_bar_type(ptype, pid_ref) #centroid = (n1 + n2) / 2. #bar_types[bar_typei][0].append(eid) #bar_types[bar_typei][1].append((centroid, centroid + yhat * Li * scale)) #bar_types[bar_typei][2].append((centroid, centroid + zhat * Li * scale)) if eids_bad: eids_bad.sort() model.log.warning(f'failed transform PBARL/PBEAML for eids={eids_bad}') points = _create_vtk_points_from_list(points_list) ugrid.SetPoints(points) ugrid.Modified() return ugrid
def _get_bar_yz_arrays(self, model, bar_beam_eids, scale, debug): lines_bar_y = [] lines_bar_z = [] points_list = [] bar_types = { # PBAR 'bar' : [], # PBEAML/PBARL "ROD": [], "TUBE": [], "TUBE2" : [], "I": [], "CHAN": [], "T": [], "BOX": [], "BAR": [], "CROSS": [], "H": [], "T1": [], "I1": [], "CHAN1": [], "Z": [], "CHAN2": [], "T2": [], "BOX1": [], "HEXA": [], "HAT": [], "HAT1": [], "DBOX": [], # was 12 # PBEAM 'beam' : [], # PBEAML specfic "L" : [], } # for GROUP="MSCBML0" allowed_types = [ 'BAR', 'BOX', 'BOX1', 'CHAN', 'CHAN1', 'CHAN2', 'CROSS', 'DBOX', 'H', 'HAT', 'HAT1', 'HEXA', 'I', 'I1', 'L', 'ROD', 'T', 'T1', 'T2', 'TUBE', 'TUBE2', 'Z', 'bar', 'beam', ] # bar_types['bar'] = [ [...], [...], [...] ] #bar_types = defaultdict(lambda : defaultdict(list)) found_bar_types = set([]) #neids = len(self.element_ids) for bar_type, data in iteritems(bar_types): eids = [] lines_bar_y = [] lines_bar_z = [] bar_types[bar_type] = (eids, lines_bar_y, lines_bar_z) #bar_types[bar_type] = [eids, lines_bar_y, lines_bar_z] ugrid = vtk.vtkUnstructuredGrid() node0 = 0 nid_release_map = defaultdict(list) #debug = True bar_nids = set([]) #print('bar_beam_eids = %s' % bar_beam_eids) for eid in bar_beam_eids: if eid not in self.eid_map: self.log.error('eid=%s is not a valid bar/beam element...' % eid) if debug: # pragma: no cover print('eid=%s is not a valid bar/beam element...' % eid) continue #unused_ieid = self.eid_map[eid] elem = model.elements[eid] pid_ref = elem.pid_ref if pid_ref is None: pid_ref = model.Property(elem.pid) assert not isinstance(pid_ref, integer_types), elem ptype = pid_ref.type bar_type = _get_bar_type(ptype, pid_ref) if debug: # pragma: no cover print('%s' % elem) print(' bar_type =', bar_type) found_bar_types.add(bar_type) (nid1, nid2) = elem.node_ids bar_nids.update([nid1, nid2]) node1 = model.nodes[nid1] node2 = model.nodes[nid2] n1 = node1.get_position() n2 = node2.get_position() # wa/wb are not considered in i_offset # they are considered in ihat i = n2 - n1 Li = norm(i) ihat = i / Li if elem.pa != 0: nid_release_map[nid1].append((eid, elem.pa)) if elem.pb != 0: nid_release_map[nid2].append((eid, elem.pb)) unused_v, wa, wb, xform = rotate_v_wa_wb( model, elem, n1, n2, node1, node2, ihat, i, eid, Li) if wb is None: # one or more of v, wa, wb are bad continue yhat = xform[1, :] zhat = xform[2, :] ## concept has a GOO #if debug: # pragma: no cover #print(' centroid = %s' % centroid) #print(' ihat = %s' % ihat) #print(' yhat = %s' % yhat) #print(' zhat = %s' % zhat) #print(' scale = %s' % scale) #if eid == 616211: #print(' check - eid=%s yhat=%s zhat=%s v=%s i=%s n%s=%s n%s=%s' % ( #eid, yhat, zhat, v, i, nid1, n1, nid2, n2)) #print('adding bar %s' % bar_type) #print(' centroid=%s' % centroid) #print(' yhat=%s len=%s' % (yhat, np.linalg.norm(yhat))) #print(' zhat=%s len=%s' % (zhat, np.linalg.norm(zhat))) #print(' Li=%s scale=%s' % (Li, scale)) if bar_type not in allowed_types: msg = 'bar_type=%r allowed=[%s]' % (bar_type, ', '.join(allowed_types)) raise RuntimeError(msg) if bar_type in BEAM_GEOM_TYPES: node0 = add_3d_bar_element( bar_type, ptype, pid_ref, n1+wa, n2+wb, xform, ugrid, node0, points_list) centroid = (n1 + n2) / 2. bar_types[bar_type][0].append(eid) bar_types[bar_type][1].append((centroid, centroid + yhat * Li * scale)) bar_types[bar_type][2].append((centroid, centroid + zhat * Li * scale)) if node0: # and '3d_bars' not in self.alt_grids: def update_grid_function(unused_nid_map, ugrid, points, nodes): # pragma: no cover """custom function to update the 3d bars""" points_list = [] node0b = 0 for eid in bar_beam_eids: elem = self.model.elements[eid] pid_ref = elem.pid_ref if pid_ref is None: pid_ref = self.model.Property(elem.pid) assert not isinstance(pid_ref, integer_types), elem ptype = pid_ref.type bar_type = _get_bar_type(ptype, pid_ref) #nids = elem.nodes (nid1, nid2) = elem.node_ids node1 = model.nodes[nid1] node2 = model.nodes[nid2] i1, i2 = np.searchsorted(self.node_ids, [nid1, nid2]) n1 = nodes[i1, :] n2 = nodes[i2, :] #centroid = (n1 + n2) / 2. i = n2 - n1 Li = norm(i) ihat = i / Li unused_v, wa, wb, xform = rotate_v_wa_wb( model, elem, n1, n2, node1, node2, ihat, i, eid, Li) if wb is None: # one or more of v, wa, wb are bad continue ugridi = None node0b = add_3d_bar_element( bar_type, ptype, pid_ref, n1+wa, n2+wb, xform, ugridi, node0b, points_list, add_to_ugrid=False) points_array = _make_points_array(points_list) points_array2 = numpy_to_vtk( num_array=points_array, deep=1, array_type=vtk.VTK_FLOAT, ) points.SetData(points_array2) ugrid.SetPoints(points) points.Modified() ugrid.Modified() return if points_list: if not sys.argv[0].startswith('test_'): update_grid_function = None self.gui.create_alternate_vtk_grid( '3d_bars', color=BLUE, opacity=0.2, representation='surface', is_visible=True, follower_function=update_grid_function, ugrid=ugrid, ) points_array = _make_points_array(points_list) points = numpy_to_vtk_points(points_array) ugrid.SetPoints(points) #print('bar_types =', bar_types) for bar_type in list(bar_types): bars = bar_types[bar_type] if len(bars[0]) == 0: del bar_types[bar_type] continue #bar_types[bar_type][1] = np.array(bars[1], dtype='float32') # lines_bar_y #bar_types[bar_type][2] = np.array(bars[2], dtype='float32') # lines_bar_z debug = False if debug: # pragma: no cover #np.set_printoptions(formatter={'float': '{: 0.3f}'.format}) for bar_type, data in sorted(iteritems(bar_types)): eids, lines_bar_y, lines_bar_z = data if len(eids): #print('barsi =', barsi) #print('bar_type = %r' % bar_type) for eid, line_y, line_z in zip(eids, lines_bar_y, lines_bar_z): print('eid=%s centroid=%s cy=%s cz=%s' % ( eid, line_y[0], line_y[1], line_z[1])) #print('found_bar_types =', found_bar_types) #no_axial_torsion = (no_axial, no_torsion) #no_shear_bending = (no_shear_y, no_shear_z, no_bending_y, no_bending_z) #no_dofs = (no_bending, no_bending_bad, no_6_16, no_0_456, #no_0_56, no_56_456, no_0_6, no_0_16) return bar_nids, bar_types, nid_release_map
def _create_bar_types_dict(model: BDF, bar_types: Dict[str, List[List[int], List[Any], List[Any]]], bar_beam_eids: List[int], eid_map, log: SimpleLogger, scale: float, debug: bool = False): node0 = 0 found_bar_types = set() nid_release_map = defaultdict(list) ugrid = vtk.vtkUnstructuredGrid() points_list = [] allowed_types = [ 'BAR', 'BOX', 'BOX1', 'CHAN', 'CHAN1', 'CHAN2', 'CROSS', 'DBOX', 'H', 'HAT', 'HAT1', 'HEXA', 'I', 'I1', 'L', 'ROD', 'T', 'T1', 'T2', 'TUBE', 'TUBE2', 'Z', 'bar', 'beam', 'pbcomp', ] #debug = True bar_nids = set() #print('bar_beam_eids = %s' % bar_beam_eids) for eid in bar_beam_eids: if eid not in eid_map: log.error('eid=%s is not a valid bar/beam element...' % eid) if debug: # pragma: no cover print('eid=%s is not a valid bar/beam element...' % eid) continue #unused_ieid = self.eid_map[eid] elem = model.elements[eid] pid_ref = elem.pid_ref if pid_ref is None: pid_ref = model.Property(elem.pid) assert not isinstance(pid_ref, integer_types), elem ptype = pid_ref.type bar_type = get_bar_type(ptype, pid_ref) if debug: # pragma: no cover print('%s' % elem) print(' bar_type = %s' % bar_type) found_bar_types.add(bar_type) (nid1, nid2) = elem.node_ids bar_nids.update([nid1, nid2]) node1 = model.nodes[nid1] node2 = model.nodes[nid2] n1 = node1.get_position() n2 = node2.get_position() # wa/wb are not considered in i_offset # they are considered in ihat i = n2 - n1 Li = norm(i) ihat = i / Li if elem.pa != 0: nid_release_map[nid1].append((eid, elem.pa)) if elem.pb != 0: nid_release_map[nid2].append((eid, elem.pb)) if isinstance(elem.offt, int): continue unused_v, wa, wb, xform = rotate_v_wa_wb(model, elem, n1, n2, node1, node2, ihat, i, eid, Li, model.log) if wb is None: # one or more of v, wa, wb are bad continue yhat = xform[1, :] zhat = xform[2, :] ## concept has a GOO #if debug: # pragma: no cover #print(' centroid = %s' % centroid) #print(' ihat = %s' % ihat) #print(' yhat = %s' % yhat) #print(' zhat = %s' % zhat) #print(' scale = %s' % scale) #if eid == 616211: #print(' check - eid=%s yhat=%s zhat=%s v=%s i=%s n%s=%s n%s=%s' % ( #eid, yhat, zhat, v, i, nid1, n1, nid2, n2)) #print('adding bar %s' % bar_type) #print(' centroid=%s' % centroid) #print(' yhat=%s len=%s' % (yhat, np.linalg.norm(yhat))) #print(' zhat=%s len=%s' % (zhat, np.linalg.norm(zhat))) #print(' Li=%s scale=%s' % (Li, scale)) if bar_type not in allowed_types: allowed_types_str = ', '.join(allowed_types) msg = f'bar_type={bar_type!r} allowed=[{allowed_types_str}]' raise RuntimeError(msg) if bar_type in BEAM_GEOM_TYPES: node0 = add_3d_bar_element(bar_type, ptype, pid_ref, n1 + wa, n2 + wb, xform, ugrid, node0, points_list) centroid = (n1 + n2) / 2. bar_types[bar_type][0].append(eid) bar_types[bar_type][1].append((centroid, centroid + yhat * Li * scale)) bar_types[bar_type][2].append((centroid, centroid + zhat * Li * scale)) return node0, ugrid, points_list, bar_nids, nid_release_map