def get_free_edges(bdf_filename, eids=None, maps=None): """ assumes no solids/bars Parameters ---------- bdf_filename : str, BDF() a BDF object or filename maps : List[...] (default=None -> calculate) the output from _get_maps(eids, map_names=None, consider_0d=False, consider_0d_rigid=False, consider_1d=False, consider_2d=True, consider_3d=False) Returns ------- free_edges : List[(int nid1, int nid2), ...] the free edges """ if isinstance(bdf_filename, string_types): model = BDF(debug=False) model.read_bdf(bdf_filename) else: model = bdf_filename free_edges = [] if maps is None: maps = model._get_maps(eids, map_names=None, consider_0d=False, consider_0d_rigid=False, consider_1d=False, consider_2d=True, consider_3d=False) edge_to_eid_map = maps[0] for edge, eids in iteritems(edge_to_eid_map): if len(eids) == 2: continue free_edges.append(edge) return free_edges
def get_free_edges(bdf_filename, eids=None): """ assumes no solids/bars """ if isinstance(bdf_filename, string_types): model = BDF() model.read_bdf(bdf_filename) else: model = bdf_filename free_edges = [] out = model._get_maps(eids, map_names=None) (edge_to_eid_map, eid_to_edge_map, nid_to_edge_map) = out for edge, eids in iteritems(edge_to_eid_map): if len(eids) == 2: continue free_edges.append(edge) return free_edges
def get_free_edges(bdf_filename, eids=None, maps=None): """ assumes no solids/bars Parameters ---------- bdf_filename : str, BDF() a BDF object or filename maps : List[...] (default=None -> calculate) the output from _get_maps(eids, map_names=None, consider_0d=False, consider_0d_rigid=False, consider_1d=False, consider_2d=True, consider_3d=False) Returns ------- free_edges : List[(int nid1, int nid2), ...] the free edges """ if isinstance(bdf_filename, string_types): model = BDF(debug=False) model.read_bdf(bdf_filename) else: model = bdf_filename free_edges = [] if maps is None: maps = model._get_maps(eids, map_names=None, consider_0d=False, consider_0d_rigid=False, consider_1d=False, consider_2d=True, consider_3d=False) edge_to_eid_map = maps[0] for edge, eids in iteritems(edge_to_eid_map): if len(eids) == 2: continue free_edges.append(edge) return free_edges
def extract_surface_patches(bdf_filename, starting_eids, theta_tols=40.): """ Extracts the unique patches of a model based on a list of starting element ids and surface curvature. Parameters ---------- bdf_filename : str the bdf_filename starting_eids : List[int] a list of starting element ids theta_tols : List[float] a list of tolerances for each element id (e.g. the nose has a different tolerance than the base) Returns ------- model : BDF() the BDF object groups : List[Set[int]] the list of element ids in each group .. warning:: only supports CTRIA3 & CQUAD4 """ if isinstance(theta_tols, (float, float32)): theta_tols = [theta_tols] * len(starting_eids) model = BDF(debug=False) model.read_bdf(bdf_filename) # get data for all shell elemenst card_types = ['CTRIA3', 'CQUAD4'] out = model.get_card_ids_by_card_types(card_types, reset_type_to_slot_map=False, stop_on_missing_card=False) shell_eids = hstack([out[card_type] for card_type in card_types]) shell_eids.sort() # set_shell_eids = set(shell_eids) neids = len(shell_eids) assert neids > 0, neids normals = np.zeros((neids, 3), dtype='float32') for i, eid in enumerate(shell_eids): element = model.elements[eid] normal = element.Normal() normals[i, :] = normal #print('shell_eids = %s' % shell_eids) # get neighboring shell elements out_map = model._get_maps(eids=shell_eids, map_names='edge_to_eid_map') edge_to_eid_map = out_map['edge_to_eid_map'] eid_to_eid_map = defaultdict(set) #if 1: for edge, eids in edge_to_eid_map.items(): for eid_a in eids: for eid_b in eids: eid_to_eid_map[eid_a].add(eid_b) # else: # for edge, eids in edge_to_eid_map.items(): # for eid_a in eids: # for eid_b in eids: # if eid_a < eid_b: # eid_to_eid_map[eid_a].add(eid_b) # eid_to_eid_map[eid_b].add(eid_a) #print('\neid_to_eid_map:') #for eid, eids in eid_to_eid_map.items(): #print('%-6s %s' % (eid, eids)) groups = [] # now trace the model for starting_eid, theta_tol in zip(starting_eids, theta_tols): print('starting_eid = %s' % starting_eid) group = set() check = set([starting_eid]) while check: eid = next(iter(check)) #print(' eid = %s' % eid) neighboring_eids = eid_to_eid_map[eid] #print(' neighbors = %s' % neighboring_eids) # don't double check eids neigboring_eids_to_check = array(list(neighboring_eids - group), dtype='int32') nneighbors = len(neigboring_eids_to_check) if nneighbors == 0: check.remove(eid) continue assert nneighbors > 0, neigboring_eids_to_check i = searchsorted(shell_eids, eid) #assert len(i) > 0, 'eid=%s cant be found' % eid local_normal = normals[i, :] # find the normals i = searchsorted(shell_eids, neigboring_eids_to_check) assert len(i) > 0, 'eid=%s cant be found' % eid normal = normals[i, :] # a * b = |a| |b| cos(theta) # |a| = |b| = 1 # cos^-1(a*b) = theta # we flip the dimensions because matrix shapes are stupid #theta = degrees(arccos(dot(local_normal, normal))) theta = degrees(arccos(dot(local_normal, normal.T).T)) #print(' theta[eid=%s] = %s; n=%s' % (eid, theta, nneighbors)) assert len(theta) == nneighbors, len(theta) itol = where(theta <= theta_tol)[0] eids_within_tol = neigboring_eids_to_check[itol] group.update(eids_within_tol) check.update(eids_within_tol) check.remove(eid) groups.append(group) return model, groups
def extract_surface_patches(bdf_filename, starting_eids, theta_tols=40.): """ Extracts the unique patches of a model based on a list of starting element ids and surface curvature. Parameters ---------- bdf_filename : str the bdf_filename starting_eids : List[int] a list of starting element ids theta_tols : List[float] a list of tolerances for each element id (e.g. the nose has a different tolerance than the base) Returns ------- model : BDF() the BDF object groups : List[Set[int]] the list of element ids in each group .. warning:: only supports CTRIA3 & CQUAD4 """ if isinstance(theta_tols, (float, float32)): theta_tols = [theta_tols] * len(starting_eids) model = BDF(debug=False) model.read_bdf(bdf_filename) # get data for all shell elemenst card_types = ['CTRIA3', 'CQUAD4'] out = model.get_card_ids_by_card_types(card_types, reset_type_to_slot_map=False, stop_on_missing_card=False) shell_eids = hstack([out[card_type] for card_type in card_types]) shell_eids.sort() # set_shell_eids = set(shell_eids) neids = len(shell_eids) assert neids > 0, neids normals = np.zeros((neids, 3), dtype='float32') for i, eid in enumerate(shell_eids): element = model.elements[eid] normal = element.Normal() normals[i, :] = normal #print('shell_eids = %s' % shell_eids) # get neighboring shell elements out_map = model._get_maps(eids=shell_eids) edge_to_eid_map = out_map[0] eid_to_eid_map = defaultdict(set) #if 1: for edge, eids in iteritems(edge_to_eid_map): for eid_a in eids: for eid_b in eids: eid_to_eid_map[eid_a].add(eid_b) # else: # for edge, eids in iteritems(edge_to_eid_map): # for eid_a in eids: # for eid_b in eids: # if eid_a < eid_b: # eid_to_eid_map[eid_a].add(eid_b) # eid_to_eid_map[eid_b].add(eid_a) #print('\neid_to_eid_map:') #for eid, eids in iteritems(eid_to_eid_map): #print('%-6s %s' % (eid, eids)) groups = [] # now trace the model for starting_eid, theta_tol in zip(starting_eids, theta_tols): print('starting_eid = %s' % starting_eid) group = set([]) check = set([starting_eid]) while check: eid = next(iter(check)) #print(' eid = %s' % eid) neighboring_eids = eid_to_eid_map[eid] #print(' neighbors = %s' % neighboring_eids) # don't double check eids neigboring_eids_to_check = array(list(neighboring_eids - group), dtype='int32') nneighbors = len(neigboring_eids_to_check) if nneighbors == 0: check.remove(eid) continue assert nneighbors > 0, neigboring_eids_to_check i = searchsorted(shell_eids, eid) #assert len(i) > 0, 'eid=%s cant be found' % eid local_normal = normals[i, :] # find the normals i = searchsorted(shell_eids, neigboring_eids_to_check) assert len(i) > 0, 'eid=%s cant be found' % eid normal = normals[i, :] # a * b = |a| |b| cos(theta) # |a| = |b| = 1 # cos^-1(a*b) = theta # we flip the dimensions because matrix shapes are stupid #theta = degrees(arccos(dot(local_normal, normal))) theta = degrees(arccos(dot(local_normal, normal.T).T)) #print(' theta[eid=%s] = %s; n=%s' % (eid, theta, nneighbors)) assert len(theta) == nneighbors, len(theta) itol = where(theta <= theta_tol)[0] eids_within_tol = neigboring_eids_to_check[itol] group.update(eids_within_tol) check.update(eids_within_tol) check.remove(eid) groups.append(group) return model, groups
def run_fem1(fem1, bdf_model, mesh_form, xref, punch, sum_load, size, is_double, cid, encoding=None): """ Reads/writes the BDF Parameters ---------- fem1 : BDF() The BDF object bdf_model : str The root path of the bdf filename mesh_form : str {combined, separate} 'combined' : interspersed=True 'separate' : interspersed=False xref : bool The xref mode punch : bool punch flag sum_load : bool static load sum flag size : int, {8, 16} size flag is_double : bool double flag cid : int / None cid flag """ assert os.path.exists(bdf_model), print_bad_path(bdf_model) try: if '.pch' in bdf_model: fem1.read_bdf(bdf_model, xref=False, punch=True, encoding=encoding) else: fem1.read_bdf(bdf_model, xref=False, punch=punch, encoding=encoding) #fem1.geom_check(geom_check=True, xref=False) fem1.write_skin_solid_faces('skin_file.bdf', size=16, is_double=False) if xref: #fem1.uncross_reference() fem1.cross_reference() fem1._xref = True spike_fem = read_bdf(fem1.bdf_filename, encoding=encoding) remake = False if remake: log = fem1.log fem1.save('model.obj') fem1.save('model.obj', unxref=False) fem1.write_bdf('spike_out.bdf') fem1.get_bdf_stats() fem1 = BDF() fem1.load('model.obj') fem1.write_bdf('spike_in.bdf') fem1.log = log fem1.get_bdf_stats() fem1.cross_reference() #fem1.get_bdf_stats() fem1._xref = True #fem1.geom_check(geom_check=True, xref=True) #fem1.uncross_reference() #fem1.cross_reference() except: print("failed reading %r" % bdf_model) raise #fem1.sumForces() if fem1._auto_reject: out_model = bdf_model + '.rej' else: out_model = bdf_model + '_out' if cid is not None and xref: fem1.resolve_grids(cid=cid) if mesh_form == 'combined': fem1.write_bdf(out_model, interspersed=False, size=size, is_double=is_double) elif mesh_form == 'separate': fem1.write_bdf(out_model, interspersed=False, size=size, is_double=is_double) else: msg = "mesh_form=%r; allowedForms=['combined','separate']" % mesh_form raise NotImplementedError(msg) #fem1.writeAsCTRIA3(out_model) fem1._get_maps() return out_model, fem1