Beispiel #1
0
    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)
Beispiel #2
0
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")
Beispiel #3
0
 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
Beispiel #4
0
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
Beispiel #5
0
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
Beispiel #6
0
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
Beispiel #7
0
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