Example #1
0
 def element_matrices_index_table(self):
     """Return element matrices index table"""
     if self._element_matrices_index_table is None:
         with open(self.filename, 'rb') as f:
             f.seek(self.header['ptrIDX'] * 4)
             self._element_matrices_index_table = read_table(f)
     return self._element_matrices_index_table
Example #2
0
def get_n_comp(filename):
    """Get the number of node and element components"""
    with open(filename, 'rb') as f:
        f.seek(103 * 4)

        for _ in range(200):
            tablesize = read_table(f, skip=True)
            # print(tablesize)
            if tablesize == 1240:
                break

        if tablesize == 1240:
            for _ in range(6):
                read_table(f, skip=True)

        return read_table(f, nread=2)

    raise Exception('Can not find node and element component length table')
Example #3
0
 def eeqv(self):
     """Element equivalence table.  This table equates the number used
     for storage to the actual element number.
     """
     if self._eeqv is None:
         with open(self.filename, 'rb') as f:
             f.seek(self.header['ptrELM'] * 4)
             self._eeqv = read_table(f)
     return self._eeqv
Example #4
0
 def neqv(self):
     """Nodal equivalence table. This table equates the number used
     for storage to the actual node number.
     """
     if self._neqv is None:
         with open(self.filename, 'rb') as f:
             f.seek(self.header['ptrBAC'] * 4)
             self._neqv = read_table(f)
     return self._neqv
Example #5
0
    def element_equivalence_table(self):
        """Element equivalence table

        The ANSYS program stores all element data in the numerical
        order that the SOLUTION processor solves the elements.  This
        table equates the order number used to the actual element
        number.
        """
        if self._element_equivalence_table is None:
            with open(self.filename, 'rb') as f:
                f.seek(self.header['ptrIDX'] * 4)
                self._element_matrices_index_table = read_table(f)
        return self._element_equivalence_table
Example #6
0
    def read_element_matrix_header(self, f_index):
        """Read element matrix header

        Parameters
        ----------
        f_indes : int
            Fortran index to the start of the element matrix header.

        Notes
        -----
        stkey - stiffness matrix key 
            0 - matrix not present
            1 - matrix present

        mkey - mass matrix key 
            0 - matirx not present
            1 - matrix present

        dkey - damping matrix key 
            0 - matrix not present
            1 - matrix present

        sskey - stress stiffening matrix key 
            0 - matrix not present
            1 - matrix present

        akey - applied load vector key 
            0 - vector not used
            1 - vector used

        nrkey - newton-raphson(restoring) load 
            0 - vector not used
            1 - vector used

        ikey - imaginary load vector key (for complex analyses)
            0 - vector not used
            1 - vector used 

        nmrow - numbers/columns in matrices. 
            If the number is negative, the matrices will be written in
            lower triangular form.

        """
        with open(self.filename, 'rb') as f:
            f.seek(4 * f_index)
            return parse_header(read_table(f), ELEMENT_HEADER_KEYS)
Example #7
0
def read_db_header(filename):
    with open(filename, 'rb') as f:
        f.seek(103 * 4)
        return parse_header(read_table(f), DB_HEADER_KEYS)
Example #8
0
    def read_element(self,
                     index,
                     stress=True,
                     mass=True,
                     damping=True,
                     stress_stiff=True,
                     applied_force=True,
                     newton_raphson=True,
                     imaginary_load=True):
        """Read element by index

        Parameters
        ----------
        index : int
            Element index.  This is not the element number.  Reference
            the element equivalency table for the actual element
            number.

        stress : bool, optional
            Return the stress matrix entries if available.

        mass : bool, optional
            Return the mass matrix entries if available.

        damping : bool, optional
            Return the damping matrix entries if available.

        stress_stiff : bool, optional
            Return the stress stiffening entries if available.

        newton_raphson : bool, optional
            Return the newton raphson load entries if available.

        applied_force : bool, optional
            Return the applied load vector if available.

        imaginary_load : bool, optional
            Return the imaginary load vector if available.

        Returns
        -------
        dof_idx : np.ndarray
            DOF index table. This record specifies the DOF locations
            of this element matrix in relation to the global
            matrix. The index is calculated as (N-1)*NUMDOF+DOF, where
            N is the position number of the node in the nodal
            equivalence table and DOF is the DOF reference number
            given above

        element_data : dict
            Dictionary containing the following entries for each of
            the corresponding inputs when the item is True.
            - 'stress' : stress matrix entries
            - 'mass' : mass matrix entries
            - 'damping' : damping matrix entries
            - 'stress_stiff' : stress stiffening matrix entries
            - 'newton_raphson' : newton rapson load vector
            - 'applied_force' : applied force vector
            - 'imaginary_load' : imaginary load vector

        Notes
        -----
        If the matrix is diagonal, the length of the records will be
        nmrow.  If the matrix is unsymmetric, the length of the
        records will be nmrow*nmrow. If the matrix is symmetric, only
        the lower triangular terms are written and the length of the
        records will be ``(nmrow)*(nmrow+1)/2``

        Records are written relative to the dof_idx.  The index is
        calculated as (N-1)*NUMDOF+DOF, where N is the position number
        of the node in the nodal equivalence table and DOF is the DOF
        reference number given by ``dof_idx``.
        """
        element_data = {}
        with open(self.filename, 'rb') as fobj:
            # seek to the position of the element table in the file
            fobj.seek(self.element_matrices_index_table[index] * 4)

            # matrix header
            element_header = parse_header(read_table(fobj),
                                          ELEMENT_HEADER_KEYS)
            nmrow = abs(element_header['nmrow'])
            lower_tri = element_header['nmrow'] < 0
            if lower_tri:
                nread = nmrow * (nmrow + 1) // 2
            else:
                nread = nmrow * nmrow

            # Read DOF index table. This record specifies the DOF locations
            # of this element matrix in relation to the global
            # matrix. The index is calculated as (N-1)*NUMDOF+DOF,
            # where N is the position number of the node in the nodal
            # equivalence table and DOF is the DOF reference number
            # given above
            dof_idx = read_table(fobj) - 1  # adj one based indexing

            # read stress matrix
            if element_header['stkey']:  # if entry even exists
                if stress:
                    stress_entries = read_table(fobj, 'd', nread)
                    element_data['stress'] = stress_entries
                else:  # skip
                    fobj.seek(nread * 8 + 12, 1)

            # read mass matrix
            if element_header['mkey']:  # if entry even exists
                if mass:
                    mass_entries = read_table(fobj, 'd', nread)
                    element_data['mass'] = mass_entries
                else:  # skip
                    fobj.seek(nread * 8 + 12, 1)

            if element_header['dkey']:
                if damping:
                    damping_entries = read_table(fobj, 'd', nread)
                    element_data['damping'] = damping_entries
                else:  # skip
                    fobj.seek(nread * 8 + 12, 1)

            if element_header['sskey']:
                if stress_stiff:
                    stress_stiff_entries = read_table(fobj, 'd', nread)
                    element_data['stress_stiff'] = stress_stiff_entries
                else:  # skip
                    fobj.seek(nread * 8 + 12, 1)

            if element_header['akey']:
                if applied_force:
                    applied_force_vector = read_table(fobj, 'd', nmrow)
                    element_data['applied_force'] = applied_force_vector
                else:  # skip
                    fobj.seek(nmrow * 8 + 12, 1)

            if element_header['nrkey']:
                if newton_raphson:
                    newton_raphson_vector = read_table(fobj, 'd', nmrow)
                    element_data['newton_raphson'] = newton_raphson_vector
                else:  # skip
                    fobj.seek(nmrow * 8 + 12, 1)

            if element_header['ikey']:
                if imaginary_load:
                    imaginary_load_vector = read_table(fobj, 'd', nmrow)
                    element_data['imaginary_load'] = imaginary_load_vector
                else:  # skip
                    fobj.seek(nmrow * 8 + 12, 1)

        return dof_idx, element_data
Example #9
0
 def read_header(self):
     """Read standard emat file header"""
     with open(self.filename, 'rb') as f:
         f.seek(103 * 4)
         self.header = parse_header(read_table(f), EMAT_HEADER_KEYS)
Example #10
0
    def load_km(self, as_sparse=True, sort=False):
        """Load and construct mass and stiffness matrices from an
        ANSYS full file.

        Parameters
        ----------
        as_sparse : bool, optional
            Outputs the mass and stiffness matrices as scipy csc
            sparse arrays when True by default.

        sort : bool, optional
            Rearranges the k and m matrices such that the rows
            correspond to to the sorted rows and columns in dor_ref.
            Also sorts dor_ref.

        Returns
        -------
        dof_ref : (n x 2) np.int32 array
            This array contains the node and degree corresponding to
            each row and column in the mass and stiffness matrices.
            In a 3 DOF analysis the dof integers will correspond to:
            0 - x
            1 - y
            2 - z
            Sort these values by node number and DOF by enabling the
            sort parameter.

        k : (n x n) np.float or scipy.csc array
            Stiffness array

        m : (n x n) np.float or scipy.csc array
            Mass array

        Examples
        --------
        >>> import pyansys
        >>> full = pyansys.read_binary('file.rst')
        >>> dof_ref, k, m = full.load_km()
        >>> print(k)
        (0, 0)       163408119.6581276
        (0, 1)               0.0423270
        (1, 1)       163408119.6581276
        :	:
        (342, 344)     6590544.8717949
        (343, 344)    -6590544.8717950
        (344, 344)    20426014.9572689

        Notes
        -----
        Constrained entries are removed from the mass and stiffness
        matrices.

        Constrained DOF can be accessed from ``const``, which returns
        the node number and DOF constrained in ANSYS.
        """
        if not os.path.isfile(self.filename):
            raise Exception('%s not found' % self.filename)

        if as_sparse:
            try:
                from scipy.sparse import csc_matrix, coo_matrix
            except ImportError:
                raise ImportError('Unable to load scipy, use ``load_km`` with '
                                  '``as_sparse=False``')

        # Get header details
        neqn = self._header['neqn']  # Number of equations

        # number of terms in stiffness matrix
        ntermK = two_ints_to_long(self._header['ntermKl'],
                                  self._header['ntermKh'])

        ptrSTF = self._header['ptrSTF']  # Location of stiffness matrix
        ptrMAS = self._header['ptrMAS']  # Location in file to mass matrix

        # number of terms in mass matrix
        ntermM = two_ints_to_long(self._header['ntermMl'],
                                  self._header['ntermMh'])
        ptrDOF = self._header['ptrDOF']  # pointer to DOF info

        # DOF information
        with open(self.filename, 'rb') as f:
            read_table(f, skip=True)  # standard header
            read_table(f, skip=True)  # full header
            read_table(f, skip=True)  # number of degrees of freedom

            # Nodal equivalence table
            neqv = read_table(f, cython=True)

            # read number of degrees of freedom for each node and constant tables
            f.seek(ptrDOF * 4)
            ndof = read_table(f, cython=True)
            const = read_table(f, cython=True)

        # degree of freedom reference and number of degress of freedom per node
        dof_ref = [ndof, neqv]
        self.ndof = ndof

        # Read k and m blocks (see help(ReadArray) for block description)
        if ntermK:
            krow, kcol, kdata = _binary_reader.read_array(
                self.filename, ptrSTF, ntermK, neqn, const)
        else:
            warnings.warn('Missing stiffness matrix')
            kdata = None

        if ntermM:
            mrow, mcol, mdata = _binary_reader.read_array(
                self.filename, ptrMAS, ntermM, neqn, const)
        else:
            warnings.warn('Missing mass matrix')
            mdata = None

        # remove constrained entries
        if np.any(const < 0):
            if kdata is not None:
                remove = np.nonzero(const < 0)[0]
                mask = ~np.logical_or(np.in1d(krow, remove),
                                      np.in1d(kcol, remove))
                krow = krow[mask]
                kcol = kcol[mask]
                kdata = kdata[mask]

            if mdata is not None:
                mask = ~np.logical_or(np.in1d(mrow, remove),
                                      np.in1d(mcol, remove))
                mrow = mrow[mask]
                mcol = mcol[mask]
                mdata = mdata[mask]

        # sort nodal equivalence
        dof_ref, index, nref, dref = _binary_reader.sort_nodal_eqlv(
            neqn, neqv, ndof)

        # store constrained dof information
        unsort_dof_ref = np.vstack((nref, dref)).T
        self._const = unsort_dof_ref[const < 0]

        if sort:  # make sorting the same as ANSYS rdfull would output
            # resort to make in upper triangle
            krow = index[krow]
            kcol = index[kcol]
            krow, kcol = np.sort(np.vstack((krow, kcol)), 0)

            if mdata is not None:
                mrow = index[mrow]
                mcol = index[mcol]
                mrow, mcol = np.sort(np.vstack((mrow, mcol)), 0)

        else:
            dof_ref = unsort_dof_ref

        # store data for later reference
        if kdata is not None:
            self._krow = krow
            self._kcol = kcol
            self._kdata = kdata
        if mdata is not None:
            self._mrow = mrow
            self._mcol = mcol
            self._mdata = mdata

        # output as a sparse matrix
        if as_sparse:

            if kdata is not None:
                k = coo_matrix((neqn, ) * 2)
                k.data = kdata  # data has to be set first
                k.row = krow
                k.col = kcol

                # convert to csc matrix (generally faster for sparse solvers)
                k = csc_matrix(k)
            else:
                k = None

            if mdata is not None:
                m = coo_matrix((neqn, ) * 2)
                m.data = mdata
                m.row = mrow
                m.col = mcol

                # convert to csc matrix (generally faster for sparse solvers)
                m = csc_matrix(m)
            else:
                m = None

        else:
            if kdata is not None:
                k = np.zeros((neqn, ) * 2)
                k[krow, kcol] = kdata
            else:
                k = None

            if mdata is not None:
                m = np.zeros((neqn, ) * 2)
                m[mrow, mcol] = mdata
            else:
                m = None

        return dof_ref, k, m
Example #11
0
    def load_km(self, as_sparse=True, sort=False):
        """Load and construct mass and stiffness matrices from an
        ANSYS full file.

        Parameters
        ----------
        as_sparse : bool, optional
            Outputs the mass and stiffness matrices as scipy csc
            sparse arrays when True by default.

        sort : bool, optional
            Rearranges the k and m matrices such that the rows
            correspond to to the sorted rows and columns in dor_ref.
            Also sorts dor_ref.

        Returns
        -------
        dof_ref : (n x 2) np.int32 array
            This array contains the node and degree corresponding to
            each row and column in the mass and stiffness matrices.
            In a 3 DOF analysis the dof intergers will correspond to:
            0 - x
            1 - y
            2 - z
            Sort these values by node number and DOF by enabling the
            sort parameter.

        k : (n x n) np.float or scipy.csc array
            Stiffness array

        m : (n x n) np.float or scipy.csc array
            Mass array

        Notes
        -----
        Constrained entries are removed from the mass and stiffness
        matrices.

        Constrained DOF can be accessed with self.const, which returns
        the node number and DOF constrained in ANSYS.
        """
        if not os.path.isfile(self.filename):
            raise Exception('%s not found' % self.filename)

        # see if
        if as_sparse:
            try:
                from scipy.sparse import csc_matrix, coo_matrix
            except BaseException:
                raise Exception('Unable to load scipy, matricies will be full')
                as_sparse = False

        # Get header details
        neqn = self.header[2]  # Number of equations
        ntermK = self.header[9]  # number of terms in stiffness matrix
        ptrSTF = self.header[19]  # Location of stiffness matrix
        ptrMAS = self.header[27]  # Location in file to mass matrix
        ntermM = self.header[34]  # number of terms in mass matrix
        ptrDOF = self.header[36]  # pointer to DOF info

        # DOF information
        ptrDOF = self.header[36]  # pointer to DOF info
        with open(self.filename, 'rb') as f:
            read_table(f, skip=True)  # standard header
            read_table(f, skip=True)  # full header
            read_table(f, skip=True)  # number of degrees of freedom
            neqv = read_table(f)  # Nodal equivalence table

            f.seek(ptrDOF * 4)
            ndof = read_table(f)
            const = read_table(f)

        # degree of freedom reference and number of degress of freedom per node
        dof_ref = [ndof, neqv]
        self.ndof = ndof

        # Read k and m blocks (see help(ReadArray) for block description)
        if ntermK:
            krow, kcol, kdata = _binary_reader.ReadArray(
                self.filename, ptrSTF, ntermK, neqn, const)
        else:
            warnings.warn('Missing stiffness matrix')
            kdata = None

        if ntermM:
            mrow, mcol, mdata = _binary_reader.ReadArray(
                self.filename, ptrMAS, ntermM, neqn, const)
        else:
            warnings.warn('Missing mass matrix')
            mdata = None

        # remove constrained entries
        if np.any(const < 0):
            if kdata is not None:
                remove = np.nonzero(const < 0)[0]
                mask = ~np.logical_or(np.in1d(krow, remove),
                                      np.in1d(kcol, remove))
                krow = krow[mask]
                kcol = kcol[mask]
                kdata = kdata[mask]

            if mdata is not None:
                mask = ~np.logical_or(np.in1d(mrow, remove),
                                      np.in1d(mcol, remove))
                mrow = mrow[mask]
                mcol = mcol[mask]
                mdata = mdata[mask]

        # sort nodal equivalence
        dof_ref, index, nref, dref = _binary_reader.SortNodalEqlv(
            neqn, neqv, ndof)

        # store constrained dof information
        unsort_dof_ref = np.vstack((nref, dref)).T
        self.const = unsort_dof_ref[const < 0]

        if sort:  # make sorting the same as ANSYS rdfull would output
            # resort to make in upper triangle
            krow = index[krow]
            kcol = index[kcol]
            krow, kcol = np.sort(np.vstack((krow, kcol)), 0)

            if mdata is not None:
                mrow = index[mrow]
                mcol = index[mcol]
                mrow, mcol = np.sort(np.vstack((mrow, mcol)), 0)

        else:
            dof_ref = unsort_dof_ref

        # store data for later reference
        if kdata is not None:
            self.krow = krow
            self.kcol = kcol
            self.kdata = kdata
        if mdata is not None:
            self.mrow = mrow
            self.mcol = mcol
            self.mdata = mdata

        # output as a sparse matrix
        if as_sparse:

            if kdata is not None:
                k = coo_matrix((neqn, ) * 2)
                k.data = kdata  # data has to be set first
                k.row = krow
                k.col = kcol

                # convert to csc matrix (generally faster for sparse solvers)
                k = csc_matrix(k)
            else:
                k = None

            if mdata is not None:
                m = coo_matrix((neqn, ) * 2)
                m.data = mdata
                m.row = mrow
                m.col = mcol

                # convert to csc matrix (generally faster for sparse solvers)
                m = csc_matrix(m)
            else:
                m = None

        else:
            if kdata is not None:
                k = np.zeros((neqn, ) * 2)
                k[krow, kcol] = kdata
            else:
                k = None

            if mdata is not None:
                m = np.zeros((neqn, ) * 2)
                m[mrow, mcol] = mdata
            else:
                m = None

        return dof_ref, k, m