Source code for pyNastran.converters.abaqus.abaqus

"""Defines the Abaqus class"""
import os
from io import StringIO
from typing import Union, Optional, Any

import numpy as np
from cpylog import SimpleLogger, get_logger2
from pyNastran.converters.abaqus.abaqus_cards import (
    Assembly, Part, Elements, Step, cast_nodes,
    ShellSection, SolidSection, Surface, BeamSection,
    Mass, Boundary, Material)
import pyNastran.converters.abaqus.reader as reader
from pyNastran.converters.abaqus.reader_utils import print_data, clean_lines


[docs] def read_abaqus(abaqus_inp_filename, encoding=None, log=None, debug=False): """reads an abaqus model""" model = Abaqus(log=log, debug=debug) model.read_abaqus_inp(abaqus_inp_filename, encoding=encoding) return model
[docs] class Abaqus: """defines the abaqus reader""" def __init__(self, log: Optional[SimpleLogger]=None, debug: Union[str, bool, None]=True): self.debug = debug self.parts: dict[str, Part] = {} self.boundaries: dict[str, Boundary] = {} self.materials: dict[str, Material] = {} self.amplitudes: dict[str, Any] = {} self.assembly: Optional[Assembly] = None self.initial_conditions: dict[str, Any] = {} self.steps: list[Step] = [] self.heading: list[str] = [] self.preprint = None self.node_sets: dict[str, np.ndarray] = {} self.element_sets: dict[str, np.ndarray] = {} self.shell_sections: list[ShellSection] = [] self.solid_sections: list[SolidSection] = [] self.log = get_logger2(log, debug)
[docs] def read_abaqus_inp(self, abaqus_inp_filename: str, encoding: Optional[str]=None): """reads an abaqus model""" if isinstance(abaqus_inp_filename, str): with open(abaqus_inp_filename, 'r', encoding=encoding) as abaqus_inp: lines = abaqus_inp.readlines() elif isinstance(abaqus_inp_filename, list): lines = abaqus_inp_filename elif isinstance(abaqus_inp_filename, StringIO): lines = abaqus_inp_filename.readlines() else: msg = 'abaqus_inp_filename=%s type=%r' % ( abaqus_inp_filename, type(abaqus_inp_filename)) raise NotImplementedError(msg) lines = clean_lines(lines) write_clean_lines = False if write_clean_lines: # pragma: no cover dirname = os.path.dirname(abaqus_inp_filename) with open(os.path.join(dirname, 'spike.out'), 'w') as file_obj: for line in lines: file_obj.write(line) unused_ilines = [] iline = 0 nlines = len(lines) nassembly = 0 istep = 1 heading: list[str] = [] nids = [] nodes = [] node_sets = {} element_types = {} element_sets = {} orientations = {} beam_sections: dict[str, BeamSection] = {} solid_sections = [] shell_sections = [] boundaries = [] surfaces: dict[str, Surface] = {} steps: list[Step] = [] ties = [] masses: dict[str, Mass] = {} #for ii, linei in enumerate(lines): #assert isinstance(linei, str), linei log = self.log while iline < nlines: # not handling comments right now line0 = lines[iline].strip().lower() log.debug('%s: %r' % (iline, line0)) #sline = line.split('**', 1) #if len(sline) == 1: #line0 = sline[0] #comment = '' #else: #line0, comment = sline #if not line0: #iline += 1 #continue if '*' in line0[0]: word = line0.strip('*').lower() log.debug('main: word = %r' % word) if word == 'heading': assert len(heading) == 0, heading iline, line0, heading = reader.read_heading(iline, line0, lines, log) elif word.startswith('preprint'): pass elif word == 'boundary': iline += 1 iline, line0, boundary = reader.read_boundary(iline, line0, lines) if boundary: boundaries.append(boundary) iline -= 1 line0 = lines[iline].strip().lower() elif word.startswith('assembly'): if nassembly != 0: raise RuntimeError('only one assembly can be defined...') iline, line0, assembly = self.read_assembly(iline, line0, lines, word) self.assembly = assembly nassembly += 1 elif word.startswith('part'): iline, line0, part_name, part = reader.read_part( lines, iline, line0, word, self.log, self.debug) self.parts[part_name] = part #print('part_name', part_name) if self.debug: self.log.debug('-------------------------------------') elif 'section controls' in word: # TODO: skips header parsing iline, line0, data_lines = reader.read_star_block(iline, line0, lines, log) #elif word.startswith('amplitude'): #amplitude #param_map = reader.get_param_map(iline, word) #name = param_map['name'] #if name in self.amplitudes: #raise RuntimeError(f'name={name!r} is already defined...') ## TODO: skips header parsing #iline += 1 #line0 = lines[iline].strip().lower() #data_lines = [] #while not line0.startswith('*'): #data_lines.append(line0.split(',')) #iline += 1 #line0 = lines[iline].strip().lower() #amplitude = [] #for sline in data_lines[:-1]: #assert len(sline) == 8, sline #amplitude += sline #assert len(data_lines[-1]) <= 8, sline #amplitude += data_lines[-1] #self.amplitudes[name] = np.array(amplitude) #continue #elif 'include' in word: #pass elif word.startswith('material'): log.debug('start of material...') iline, line0, word, material = reader.read_material(iline, word, lines, log) if material.name in self.materials: msg = 'material.name=%r is already defined...\n' % material.name msg += 'old %s' % self.materials[material.name] msg += 'new %s' % material raise RuntimeError(msg) self.materials[material.name] = material log.debug('end of material') #elif word.startswith('spring'): #log.debug('start of spring...') #iline, line0, material = read_spring(lines, iline, word, log) #asdf #if material.name in self.materials: #msg = 'material.name=%r is already defined...\n' % material.name #msg += 'old %s' % self.materials[material.name] #msg += 'new %s' % material #raise RuntimeError(msg) #self.materials[material.name] = material #log.debug('end of spring') elif word.startswith('step'): #print('step!!!!!!!') iline, line0, step = reader.read_step(lines, iline, line0, istep, log) steps.append(step) istep += 1 #elif word.startswith('initial conditions'): ##initial_conditions #data_lines, iline, line0 = reader.read_star_block(lines, iline, line0, log) #for line in data_lines: #log.debug(line) #log.debug(f'line_end_of_IC = {line0!r}') #elif word.startswith('surface interaction'): #unused_key = 'surface interaction' ##surface_interaction #unused_data = [] #while '*' not in line0: #sline = line0.split(',') #iline += 1 #line0 = lines[iline].strip().lower() #self.log.debug(line0) #elif word.startswith('friction'): #unused_key = 'friction' ##friction #unused_data = [] #while '*' not in line0: #sline = line0.split(',') #iline += 1 #line0 = lines[iline].strip().lower() #self.log.debug(line0) #elif word.startswith('surface behavior'): #unused_key = 'surface behavior' ##surface_behavior #unused_data = [] #while '*' not in line0: #sline = line0.split(',') #iline += 1 #line0 = lines[iline].strip().lower() #self.log.debug(line0) #elif word.startswith('contact damping'): #unused_key = 'contact damping' ##contact_damping #unused_data = [] #while '*' not in line0: #sline = line0.split(',') #iline += 1 #line0 = lines[iline].strip().lower() #self.log.debug(line0) #elif word.startswith('contact pair'): #unused_key = 'contact pair' ##contact_pair #unused_data = [] #while '*' not in line0: #sline = line0.split(',') #iline += 1 #line0 = lines[iline].strip().lower() #self.log.debug(line0) #elif word.startswith('contact output'): #key = 'contact output' #data = [] #while '*' not in line0: #sline = line0.split(',') #iline += 1 #line0 = lines[iline].strip().lower() #log.debug(line0) # part... elif word.startswith('node'): iline, line0, nidsi, nodesi = reader.read_node( iline, lines, log, skip_star=True) nids.append(nidsi) nodes.append(nodesi) #print(f'end of node; iline={iline}') iline -= 1 line0 = lines[iline].strip().lower() #print(line0) elif '*element' in line0: # line0: *ELEMENT,TYPE=C3D4 # iline: doesn't start on *element line # 1,263,288,298,265 #print(f'start of element; iline={iline}') iline0 = iline line0 = lines[iline].strip().lower() iline, line0, etype, elset, elements = reader.read_element( iline+1, line0, lines, log, self.debug) element_types[etype] = (elements, elset) #iline -= 1 #line0 = lines[iline].strip().lower() #print(f'end of element; iline={iline}') #print(line0) assert iline > iline0 #print(line0) elif word.startswith('nset'): self.log.debug('reading nset') iline += 1 self.log.debug(line0) iline, line0, set_name, set_ids = reader.read_nset( iline, line0, lines, log, is_instance=False) node_sets[set_name] = set_ids log.debug(f'{iline}: end of nset; line={line0}') #assert iline > iline0 elif word.startswith('elset'): self.log.debug('reading elset') iline += 1 #iline0 = iline #self.log.debug(line0) iline, line0, set_name, set_ids = reader.read_elset( iline, line0, lines, log, is_instance=False) element_sets[set_name] = set_ids log.debug(f'{iline}: end of elset {set_name!r}; line={line0}') #assert iline > iline0 elif '*solid section' in line0: iline += 1 iline, solid_section = reader.read_solid_section( iline, line0, lines, log) log.debug(f'solid_section = {solid_section}') solid_sections.append(solid_section) line0 = line0.strip().lower() elif '*shell section' in line0: iline += 1 iline, shell_section = reader.read_shell_section(iline, line0, lines, log) #print(shell_section) shell_sections.append(shell_section) line0 = line0.strip().lower() elif '*surface' in line0: iline, line0, surface = reader.read_surface(iline, line0, lines, log) surfaces[surface.name] = surface #elif '*hourglass stiffness' in line0: #iline, hourglass_stiffness = reader.read_hourglass_stiffness(iline, line0, lines, log) elif '*orientation' in line0: iline += 1 iline, line0, orientation = reader.read_orientation(iline, line0, lines, log) orientations[orientation.name] = orientation elif '*system' in line0: iline, line0, system = reader.read_system(iline, line0, lines, log) elif '*transform' in line0: iline, line0, transform = reader.read_transform(iline, line0, lines, log) elif '*tie' in line0: iline += 1 iline, line0, tie = reader.read_tie(iline, line0, lines, log) ties.append(tie) #iline += 1 #iline, line0, flags, section = reader.read_generic_section(line0, lines, iline, log) #log.warning('skipping tie section') elif '*beam section' in line0: iline += 1 iline, line0, beam_section = reader.read_beam_section(iline, line0, lines, log) beam_sections[beam_section.elset] = beam_section elif '*mass' in line0: iline += 1 iline, line0, mass = reader.read_mass(iline, line0, lines, log) masses[mass.elset] = mass del mass else: raise NotImplementedError(f'word={word!r} line0={line0!r}') assert isinstance(iline, int), word wordi = word.split(',')[0] log.debug(f'end of main {wordi!r}; line={line0!r} iline={iline}') else: # pass raise NotImplementedError(f'this should not happen; last_word={word!r} line={line0!r}') iline += 1 #if self.debug: #log.debug('') self.nids = None self.nodes = None if nids or nodes: self.nids, self.nodes = cast_nodes(nids[0], nodes[0], log) self.heading = heading self.elements = Elements(element_types, self.log) for etype, elset_name in self.elements.element_type_to_elset_name.items(): if elset_name == '': continue eids = getattr(self.elements, f'{etype}_eids') element_sets[elset_name] = eids del eids self.ties = ties self.masses = masses self.beam_sections = beam_sections self.shell_sections = shell_sections self.solid_sections = solid_sections self.node_sets = node_sets self.element_sets = element_sets self.orientations = orientations self.boundaries = boundaries self.surfaces = surfaces self.steps = steps log.debug('nassembly = %s' % nassembly) for part_name, part in sorted(self.parts.items()): log.info(str(part)) part.check_materials(self.materials) for unused_mat_name, mat in sorted(self.materials.items()): log.debug(str(mat))
[docs] def read_assembly(self, iline: int, line0: str, lines: list[str], word: str) -> tuple[int, str, Assembly]: """reads an Assembly object""" assert isinstance(iline, int), iline assert isinstance(line0, str), line0 log = self.log # TODO: skips header parsing iline += 1 nlines = len(lines) line0 = lines[iline].strip().lower() element_types = {} node_sets = {} element_sets = {} debug = self.debug while not line0.startswith('*end assembly') and iline < nlines: log.debug('line0 assembly = %s' % line0) word = line0.strip('*').lower() log.info('assembly: %s' % word) if '*instance' in line0: # TODO: skips header parsing iline += 1 line0 = lines[iline].strip().lower() data_lines = [] while not line0.startswith('*'): data_lines.append(line0.split(',')) iline += 1 line0 = lines[iline].strip().lower() assert line0.startswith('*end instance'), line0 iline += 1 line0 = lines[iline].strip().lower() elif (word.startswith('surface') or word.startswith('rigid body') or word.startswith('mpc') or word.startswith('tie')): # TODO: skips header parsing iline += 1 line0 = lines[iline].strip().lower() data_lines = [] while not line0.startswith('*'): data_lines.append(line0.split(',')) iline += 1 line0 = lines[iline].strip().lower() elif word.startswith('nset'): iline += 1 iline, line0, set_name, set_ids = reader.read_nset( iline, line0, lines, log, is_instance=True) node_sets[set_name] = set_ids iline += 1 elif word.startswith('elset'): iline += 1 iline, line0, set_name, set_ids = reader.read_elset( iline, line0, lines, log, is_instance=True) element_sets[set_name] = set_ids iline += 1 elif word == 'node': iline, line0, nids, nodes = reader.read_node( iline, lines, log, skip_star=True) elif '*element' in line0: # doesn't actually start on *element line # 1,263,288,298,265 iline, line0, etype, elset, elements = reader.read_element(iline, line0, lines, log, debug) element_types[etype] = (elements, elset) iline += 1 line0 = lines[iline].strip().lower() #print('line_end =', line0) else: raise NotImplementedError('\nword=%r\nline=%r' % (word, line0)) assert isinstance(iline, int), iline assert isinstance(line0, str), line0 assembly = Assembly(element_types, node_sets, element_sets) return iline, line0, assembly
[docs] def write(self, abaqus_filename_out, is_2d=False): self.log.info('writing %r' % abaqus_filename_out) assert isinstance(self.steps, list), self.steps #self.parts = {} #self.boundaries = {} #self.materials = {} #self.amplitudes = {} #self.assembly = None #self.initial_conditions = {} #self.steps = {} #self.heading = None #self.preprint = None with open(abaqus_filename_out, 'w') as abq_file: self.log.debug(f' nparts = {len(self.parts):d}') self.log.debug(f' nmaterials = {len(self.materials):d}') if self.assembly is not None: self.assembly.write(abq_file) for unused_part_name, part in self.parts.items(): part.write(abq_file, is_2d=is_2d) for unused_part_name, initial_conditions in self.initial_conditions.items(): initial_conditions.write(abq_file) for unused_part_name, amplitude in self.amplitudes.items(): amplitude.write(abq_file) for unused_mat_name, mat in self.materials.items(): mat.write(abq_file) for set_name, seti in self.node_sets.items(): raise NotImplementedError(('node_set', set_name, seti)) for set_name, seti in self.element_sets.items(): raise NotImplementedError(('element_set', set_name, seti)) for step in self.steps: #print(step) #print(abq_file) step.write(abq_file)
def __repr__(self) -> str: msg = ( 'Abaqus:\n' f' parts={self.parts}\n' f' boundaries={self.boundaries}\n' f' materials={self.materials}\n' f' amplitudes={self.amplitudes}\n' f' assembly={self.assembly}\n' f' initial_conditions={self.initial_conditions}\n' f' steps={self.steps}\n' f' # Sections:\n' f' beam_sections={self.beam_sections}\n' f' shell_sections={self.shell_sections}\n' f' solid_sections={self.solid_sections}\n' f' # Sets:\n' f' node_sets={list(self.node_sets.keys())}\n' f' element_sets={list(self.element_sets.keys())}\n' ) return msg
[docs] def get_nodes_nnodes_nelements(model: Abaqus, stop_for_no_elements: bool=True): """helper method""" nnodes = 0 nelements = 0 nids = [] all_nodes = [] #if model.nodes and model.elements: if model.nids is not None and len(model.nids): nidsi = model.nids nodes = model.nodes elements = model.elements nnodes += nodes.shape[0] nelements += elements.nelements nids.append(nidsi) all_nodes.append(nodes) for unused_part_name, part in model.parts.items(): nidsi = nnodes + part.nids nodes = part.nodes elements = part.elements nnodes += nodes.shape[0] nelements += elements.nelements nids.append(nidsi) all_nodes.append(nodes) if nelements == 0 and stop_for_no_elements: raise RuntimeError('nelements=0') if len(all_nodes) == 1: nids = nids[0] nodes = all_nodes[0] else: nids = np.hstack(nids) nodes = np.vstack(all_nodes) assert len(nodes) == len(nids) return nnodes, nids, nodes, nelements
[docs] def main(): # pragma: no cover """tests a simple abaqus model""" abaqus_inp_filename = 'mesh.inp' part_name = 'part-spec' eid = 3707 model = read_abaqus(abaqus_inp_filename) part = model.parts[part_name] print(part) etype, ieid, elem = part.element(eid) print(f'etype={etype} ieid={ieid:d} elem={elem}') #return unused_nids = part.nids - 1 nodes = part.nodes cohesive_elements = part.coh2d4 assert cohesive_elements is not None, cohesive_elements n1 = cohesive_elements[:, 1] - 1 n2 = cohesive_elements[:, 2] - 1 #print('n1 =', n1) #print('n2 =', n2) #print('nodes =', nodes) #ix = np.unique(np.hstack([n2, n1])) ix = np.append(n2, n1[-1]) eids = cohesive_elements[:, 0] #- cohesive_elements[0, 0] x = nodes[ix, 0] edge_length_21 = np.abs(nodes[n2, 0] - nodes[n1, 0]) edge_length_max = edge_length_21.max() edge_length_min = edge_length_21.min() dedge = edge_length_max - edge_length_min #print('edge_length_21 =\n%s' % edge_length_21) import matplotlib.pyplot as plt plt.figure(1) plt.suptitle(abaqus_inp_filename) plt.plot(eids, edge_length_21 * 1000., 'b-o') if dedge < 1e-6: plt.ylim(0.98 * edge_length_min * 1000., 1.02 * edge_length_min * 1000.) plt.ylabel('edge length (mm)') plt.xlabel('element id') plt.grid() plt.figure(2) plt.suptitle(abaqus_inp_filename) plt.plot(x[:-1] * 1000., edge_length_21 * 1000., 'b-o') if dedge < 1e-6: plt.ylim(0.98 * edge_length_min * 1000., 1.02 * edge_length_min * 1000.) plt.grid() plt.ylabel('edge length (mm)') plt.xlabel('x location (mm)') plt.show()
if __name__ == '__main__': # pragma: no cover main()