def test_time_type_check(self): """this tests what the best way to do type checking is""" g = GRID(4, [0., 0., 0.]) s = SPOINT(4) import time time0 = time.time() for unused_i in range(5000000): if g.type == 'GRID': pass if s.type == 'GRID': pass dt_type = time.time() - time0 time1 = time.time() for unused_i in range(5000000): if isinstance(g, GRID): pass if isinstance(s, GRID): pass dt_instance = time.time() - time1 #print('dt_type=%.4f dt_instance=%.4f' % (dt_type, dt_instance)) log = SimpleLogger(level='debug', encoding='utf-8', log_func=None) msg = ( "flip the way you do type checking; card.type == 'GRID' " "is faster than isinstance(card, GRID); dt_instance=%s dt_type=%s" % (dt_instance, dt_type)) if dt_instance < dt_type: log.warning(msg)
def remove_unsupported_cards(card_dict: Dict[str, Any], card_types: List[str], log: SimpleLogger): for card_type in list(card_dict): if card_type not in card_types: del card_dict[card_type] log.warning(f"removing {card_type} in OP2 writer because it's unsupported")
def test_simple_logger(self): """tests all the logging levels""" log = SimpleLogger(level='critical') log.info('info') log.warning('warning') log.error('error') log.debug('debug') log.exception('exception') out = log.critical('critical') assert out is None
def _eq_nodes_build_tree_new( kdt: scipy.spatial.cKDTree, nodes_xyz: NDArrayN3float, nids: NDArrayNint, all_node_set: NDArrayNint, nnodes: int, is_not_node_set: bool, tol: float, log: SimpleLogger, inew=None, node_set=None, neq_max: int = 4, msg: str = '', debug: float = False) -> Tuple[Any, List[Tuple[int, int]]]: assert isinstance(nnodes, int), nnodes deq, ieq = kdt.query(nodes_xyz[inew, :], k=neq_max, distance_upper_bound=tol) slots = np.where(ieq[:, :] < nnodes) nid_pairs_expected = _eq_nodes_find_pairs(nids, slots, ieq, log, all_node_set, node_set=node_set) if is_not_node_set: nid_pairs = _nodes_xyz_nids_to_nid_pairs_new(kdt, nids, all_node_set, node_set, tol) else: raise NotImplementedError(f'node_set = {node_set}') snid_pairs = set(nid_pairs) snid_pairs_expected = set(nid_pairs_expected) diff_bad = snid_pairs - snid_pairs_expected diff_missed = snid_pairs - snid_pairs_expected if debug and len(diff_bad) or len(diff_missed): # pragma: no cover #log.warning(f'nid_pairs = {nid_pairs}') #log.warning(f'nid_pairs_expected = {nid_pairs_expected}') log.warning(f'diff_bad = {diff_bad}') log.warning(f'diff_missed = {diff_missed}') return kdt, nid_pairs
def _eq_nodes_find_pairs( nids: NDArrayNint, slots, ieq, log: SimpleLogger, all_node_set: NDArrayNint, node_set: Optional[List[NDArrayNint]] = None) -> List[Tuple[int, int]]: """helper function for `bdf_equivalence_nodes`""" irows, icols = slots all_node_set = get_all_node_set(node_set) if node_set is not None and len(node_set) > 1: log.warning(f'multi node_sets; n={len(node_set)}') #replacer = unique(ieq[slots]) ## TODO: turn this back on? #skip_nodes = [] nid_pairs = [] if node_set is None: for (irow, icol) in zip(irows, icols): inid2 = ieq[irow, icol] nid1 = nids[irow] nid2 = nids[inid2] if nid1 == nid2: continue nid_pairs.append((nid1, nid2)) return nid_pairs for (irow, icol) in zip(irows, icols): inid2 = ieq[irow, icol] nid1 = nids[irow] nid2 = nids[inid2] if nid1 == nid2: continue if node_set is not None: if nid1 not in all_node_set and nid2 not in all_node_set: continue for seti in node_set: if nid1 in seti and nid2 in seti: nid_pairs.append((nid1, nid2)) #print(f'({nid1}, {nid2})') break return nid_pairs
def _eq_nodes_build_tree( nodes_xyz: NDArrayN3float, nids: NDArrayNint, all_node_set: NDArrayNint, tol: float, log: SimpleLogger, inew=None, node_set: Optional[NDArrayNint] = None, neq_max: int = 4, method: str = 'new', msg: str = '', debug: bool = False ) -> Tuple[scipy.spatial.cKDTree, List[Tuple[int, int]]]: """ helper function for `bdf_equivalence_nodes` Parameters ---------- nodes_xyz : (nnodes, 3) float ndarray the xyzs to equivalence nids : (nnodes,) int ndarray the node ids tol : float the spherical equivalence tolerance inew : int ndarray; default=None -> slice(None) a slice on nodes_xyz to exclude some nodes from the equivalencing node_set : List[int] / (n, ) ndarray; default=None the list/array of nodes to consider neq_max : int; default=4 the number of nodes to consider for equivalencing msg : str; default='' custom message used for errors Returns ------- kdt : cKDTree() the kdtree object nid_pairs : List[Tuple[int, int]] a series of (nid1, nid2) pairs """ nnodes = len(nids) if inew is None: inew = slice(None) assert isinstance(tol, float), 'tol=%r' % tol kdt = _get_tree(nodes_xyz, msg=msg) is_not_node_set = inew is None or inew == slice(None) # check the closest 10 nodes for equality if method == 'new' and is_not_node_set: kdt, nid_pairs = _eq_nodes_build_tree_new(kdt, nodes_xyz, nids, all_node_set, nnodes, is_not_node_set, tol, log, inew=inew, node_set=node_set, neq_max=neq_max, msg=msg, debug=debug) else: if method == 'new': log.warning( f'setting method to "old" because node_set is specified') #ieq : (nnodes, neq) int ndarray # the node indices that are close #slots : (nnodes, neq) int ndarray # the location of where deq, ieq = kdt.query(nodes_xyz[inew, :], k=neq_max, distance_upper_bound=tol) if node_set is not None: assert len(deq) == len(nids) # get the ids of the duplicate nodes slots = np.where(ieq[:, :] < nnodes) if ieq[:, -1].max() == nnodes: log.warning(f'neq_max={neq_max} and should be increased') nid_pairs = _eq_nodes_find_pairs(nids, slots, ieq, log, all_node_set, node_set=node_set) assert isinstance(nid_pairs, list), nid_pairs return kdt, nid_pairs
def _cast_matrix_matpool(table_name: str, real_imag_array, col_nids_array, col_dofs_array, row_nids_array, row_dofs_array, matrix_shape: Tuple[int, int], dtype: str, is_symmetric: bool, log: SimpleLogger, apply_symmetry: bool = False) -> Matrix: """helper method for _read_matpool_matrix""" #op2 = self.op2 make_matrix_symmetric = apply_symmetry and matrix_shape == 'symmetric' # TODO: this is way slower than it should be # because we didn't preallocate the data and the # grids_comp_array_to_index function needs work grids1 = col_nids_array comps1 = col_dofs_array grids2 = row_nids_array comps2 = row_dofs_array assert len(grids1) == len(comps1), 'ngrids1=%s ncomps1=%s' % (len(grids1), len(comps1)) assert len(grids1) == len(grids2), 'ngrids1=%s ngrids2=%s' % (len(grids1), len(grids2)) assert len(comps1) == len(comps2), 'ncomps1=%s ncomps2=%s' % (len(comps1), len(comps2)) j1, j2, nj1, nj2, nj = grids_comp_array_to_index(grids1, comps1, grids2, comps2, make_matrix_symmetric, idtype='int32') assert len(j1) == len(j2), 'nj1=%s nj2=%s' % (len(j1), len(j2)) assert len(grids1) == len(real_imag_array), 'ngrids1=%s nreals=%s' % ( len(j1), len(real_imag_array)) # not 100% on these, they might be flipped #ncols = len(np.unique(j1)) #mrows = len(np.unique(j2)) if is_symmetric and make_matrix_symmetric: mrows = nj ncols = nj #print(' j1 =', j1) #print(' j2 =', j2) else: ncols = nj1 mrows = nj2 # C:\MSC.Software\simcenter_nastran_2019.2\tpl_post2\tr1071x.op2 #print(real_imag_array) #print(j1) #print(j2) #print(mrows, ncols) try: matrix = scipy.sparse.coo_matrix((real_imag_array, (j2, j1)), shape=(mrows, ncols), dtype=dtype) except ValueError: print('gc1', grids1, comps1) print('gc2', grids2, comps2) print(f'j1={j1}') print(f'j2={j2}') print(f'shape=({mrows}, {ncols})') msg = 'Passed all the checks; cannot build MATPOOL sparse matrix...\n' spaces = ' ' msg += '%sname=%s dtype=%s nrows=%s ncols=%s nj1=%s nj2=%s nj=%s' % ( spaces, table_name, dtype, mrows, ncols, nj1, nj2, nj) log.error(msg) raise # enforce symmetry if necessary if make_matrix_symmetric: # get the upper and lower triangular matrices upper_tri = scipy.sparse.triu(matrix) lower_tri = scipy.sparse.tril(matrix) # extracts a [1, 2, 3, ..., n] off the diagonal of the matrix # and make it a diagonal matrix diagi = scipy.sparse.diags(scipy.sparse.diagional(upper_tri)) # Check to see which triangle is populated. # If they both are, make sure they're equal # or average them and throw a warning lnnz = (lower_tri - diagi).nnz unnz = (upper_tri - diagi).nnz assert isinstance(lnnz, int), type(lnnz) assert isinstance(unnz, int), type(unnz) # both upper and lower triangle are populated if lnnz > 0 and unnz > 0: upper_tri_t = upper_tri.T if lower_tri == upper_tri_t: matrix = upper_tri + upper_tri_t - diagi else: log.warning( f'Matrix {table_name!r} marked as symmetric does not contain ' 'symmetric data. Data will be symmetrized by averaging.') matrix = (matrix + matrix.T) / 2. elif lnnz > 0: # lower triangle is populated matrix = lower_tri + lower_tri.T - diagi elif unnz > 0: # upper triangle is populated matrix = upper_tri + upper_tri_t - diagi else: # matrix is diagonal (or null) matrix = diagi data = matrix # matrix is symmetric, but is not stored as symmetric matrix_shape = 'rectangular' m = Matrix(table_name, is_matpool=True, form=matrix_shape) m.data = matrix m.col_nid = col_nids_array m.col_dof = col_dofs_array m.row_nid = row_nids_array m.row_dof = row_dofs_array m.form = matrix_shape #print(m) log.debug(m) return m