Source code for BasicTools.IO.LSDynaReader

# -*- coding: utf-8 -*-
#
# This file is subject to the terms and conditions defined in
# file 'LICENSE.txt', which is part of this source code package.
#

""" LSDyna file reader.
    Documentation of the format:
    http://ftp.lstc.com/anonymous/outgoing/jday/manuals/DRAFT_Vol_I.pdf
"""
import numpy as np

from BasicTools.IO.ReaderBase import ReaderBase

from BasicTools.NumpyDefs import PBasicIndexType, PBasicFloatType


LSDynaNumber = {
    4:'tet4' # 4-point tetraedron
}


[docs]def ReadLSDyna(fileName=None,string=None,out=None,printNotRead=True): """Function API for reading a LSDyna mesh file Parameters ---------- fileName : str, optional name of the file to be read, by default None string : str, optional data to be read as a string instead of a file, by default None out : UnstructuredMesh, optional output unstructured mesh object containing reading result, by default None printNotRead : bool, optional if True, prints in console the lines dot understood by the reader, by default True Returns ------- UnstructuredMesh output unstructured mesh object containing reading result """ reader = LSDynaReader() reader.SetFileName(fileName) reader.SetStringToRead(string) return reader.Read(fileName=fileName, string=string,out=out,printNotRead=printNotRead)
[docs]def LineToListNoQuote(text): return [s.strip() for s in text.split()]
[docs]def ListToNumber(list): """hack where the element type is defined by inspecting the number of identical columns at the end of the connectivity list. """ l = len(list) val = list[-1] for i in range(l-2, -1, -1): if list[i] != val: break return i+2
[docs]class LSDynaReader(ReaderBase): """LSDyna Reader class """ def __init__(self): super(LSDynaReader,self).__init__() self.commentChar= "$" self.readFormat = 'r'
[docs] def Read(self, fileName=None,string=None,out=None,printNotRead=True): """Function that performs the reading of a LSDyna mesh file Parameters ---------- fileName : str, optional name of the file to be read, by default None string : str, optional data to be read as a string instead of a file, by default None out : UnstructuredMesh, optional output unstructured mesh object containing reading result, by default None printNotRead : bool, optional if True, prints in console the lines dot understood by the reader, by default True Returns ------- UnstructuredMesh output unstructured mesh object containing reading result """ import BasicTools.Containers.UnstructuredMesh as UM if fileName is not None: self.SetFileName(fileName) if string is not None: self.SetStringToRead(string) self.StartReading() if out is None: res = UM.UnstructuredMesh() else: res = out filetointernalid = {} oidToElementContainer = {} oidToLocalElementNumber = {} l = self.ReadCleanLine() originalIds = [] nodes= [] nodeSetCounter = 0 while(True): #premature EOF if l is None: print("ERROR premature EOF: please check the integrity of your .k file") # pragma: no cover break # pragma: no cover #if len(l) == 0: l = string.readline().strip('\n').lstrip().rstrip(); continue if l.find("*ELEMENT")>-1: while(True): l = self.ReadCleanLine() if l.find("*") > -1: break s = LineToListNoQuote(l) n = ListToNumber(s[2:]) try: nametype = LSDynaNumber[n] except KeyError: raise("Elements with "+str(n)+"vertices not compatible with reader") conn = [x for x in map(int,s[2:6])] elements = res.GetElementsOfType(nametype) oid = int(s[0]) cpt = elements.AddNewElement(conn,oid) oidToElementContainer[oid] = elements oidToLocalElementNumber[oid] = cpt elTag = "canonical:"+s[1] elements.tags.CreateTag(elTag,False).AddToTag(cpt-1) continue if l.find("*NODE")>-1: dim = 3 s = None cpt = 0 while(True): l = self.ReadCleanLine() if l.find("*") > -1: break s = LineToListNoQuote(l) oid = int(s[0]) filetointernalid[oid] = cpt originalIds.append(oid) nodes.append(list(map(float,s[1:dim+1]))) cpt += 1 continue if l.find("*SET_NODE_LIST")>-1: tag = res.GetNodalTag(str(nodeSetCounter)) nodeSetCounter += 1 self.ReadCleanLine() while(True): l = self.ReadCleanLine() if l.find("*") > -1: break s = np.array(l.split(), dtype=int) for oid in s[s>0]: tag.AddToTag(int(oid)) continue if l.find("*END")>-1: self.PrintDebug("End file") break # case not treated if printNotRead == True: self.PrintDebug("line starting with <<"+l[:20]+">> not considered in the reader") l = self.ReadCleanLine() continue self.EndReading() res.nodes = np.array(nodes,dtype=PBasicFloatType) res.nodes.shape = (cpt,dim) res.originalIDNodes = np.array(originalIds,dtype=PBasicIndexType) updateIDsFunc = lambda x: filetointernalid[x] for tag in res.nodesTags: tag.SetIds(np.vectorize(updateIDsFunc)(tag.GetIds())) for _, data in res.elements.items(): data.tighten() data.connectivity = np.vectorize(updateIDsFunc)(data.connectivity) res.PrepareForOutput() return res
from BasicTools.IO.IOFactory import RegisterReaderClass RegisterReaderClass(".k",LSDynaReader)
[docs]def CheckIntegrity(): data = u""" $# LS-DYNA Keyword file created by LS-PrePost(R) V4.5.0 *KEYWORD *TITLE *ELEMENT_SOLID $# eid pid n1 n2 n3 n4 n5 n6 n7 n8 1 3000001 1 2 3 4 4 4 4 4 *SET_NODE_LIST $# sid da1 da2 da3 da4 solver 1 0.0 0.0 0.0 0.0MECH $# nid1 nid2 nid3 nid4 nid5 nid6 nid7 nid8 1 2 3 4 0 0 0 0 *SET_NODE_LIST $# sid da1 da2 da3 da4 solver 1 0.0 0.0 0.0 0.0MECH $# nid1 nid2 nid3 nid4 nid5 nid6 nid7 nid8 1 3 0 0 0 0 0 0 *NODE $# nid x y z tc rc 1 0.0 0.0 0.0 0 0 2 0.6 0.0 0.0 0 0 3 0.6 0.7 0.0 0 0 4 0.2 0.2 0.3 0 0 5 0.3 0.0 0.1 0 0 *END """ res = ReadLSDyna(string=data) print(res) return 'ok'
if __name__ == '__main__': print(CheckIntegrity())# pragma: no cover