def __init__(self, filename): """Loads full header on initialization. See ANSYS programmer's reference manual full header section for definitions of each header. """ self._const = None self._krow = None self._kcol = None self._kdata = None self._mrow = None self._mcol = None self._mdata = None self._k = None self._m = None self._dof_ref = None self.filename = filename self._standard_header = read_standard_header(self.filename) self._header = parse_header(self.read_record(103), SYMBOLIC_FULL_HEADER_KEYS) # if not self._header['fun04'] < 0: # raise NotImplementedError("Unable to read a frontal assembly full file") # Check if lumped (item 11) if self._header['lumpm']: raise NotImplementedError("Unable to read a lumped mass matrix") # Check if arrays are unsymmetric (item 14) if self._header['keyuns']: raise NotImplementedError( "Unable to read an unsymmetric mass/stiffness matrix")
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)
def read_db_header(filename): with open(filename, 'rb') as f: f.seek(103 * 4) return parse_header(read_table(f), DB_HEADER_KEYS)
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
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)