Source code for BasicTools.IO.LSDynaWriter

# -*- 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 writer.
    Documentation of the format:
    http://ftp.lstc.com/anonymous/outgoing/jday/manuals/DRAFT_Vol_I.pdf
"""

import numpy as np

from BasicTools.IO.WriterBase import WriterBase as WriterBase
import BasicTools.Containers.ElementNames as EN
from BasicTools.NumpyDefs import PBasicIndexType
from BasicTools.NumpyDefs import PBasicFloatType
import os

[docs]def WriteMeshToK(fileName, mesh, useOriginalId = False): """Function API for writing data into a LSDyna file Parameters ---------- fileName : str name of the file to be written mesh : UnstructuredMesh support of the data to be written useOriginalId : bool, optional If True, Original Id for the number of nodes and elements are used (the user is responsible of the consistency of this data), by default False """ KW = KWriter() KW.Open(fileName) KW.Write(mesh, useOriginalId = useOriginalId) KW.Close()
BasicToolToLSDyna = dict() BasicToolToLSDyna[EN.Tetrahedron_4] = [0,1,2,3,3,3,3,3]
[docs]class KWriter(WriterBase): """Class to write an LSDyna file """ def __init__(self): super(KWriter,self).__init__() def __str__(self): res = 'KWriter : \n' res += ' FileName : '+str(self.fileName)+'\n' return res
[docs] def Write(self, meshObject, useOriginalId = False, PointFieldsNames = None, PointFields = None, CellFieldsNames = None, CellFields = None, GridFieldsNames = None, GridFields = None): """Write data to a LSDyna file Parameters ---------- meshObject : _type_ _description_ useOriginalId : bool, optional _description_, by default False PointFieldsNames : None Not Used, by default None PointFields : None Not Used, by default None CellFieldsNames : None Not Used, by default None CellFields : None Not Used, by default None GridFieldsNames : None Not Used, by default None GridFields : None Not Used, by default None """ #Header self.writeText("$# LS-DYNA Keyword file\n*KEYWORD\n*TITLE\n"+str(os.path.basename(self.fileName))+"\n") #Node tags for i, tag in enumerate(meshObject.nodesTags): if len(tag.GetIds())>0: self.writeText("*SET_NODE_LIST\n") self.writeText("$# sid\n") self.writeText(str(i+1).rjust(10)+"\n")# i+1 is the number of the node tag among the list of nodesTags self.writeText("$# nid1 nid2 nid3 nid4 nid5 nid6 nid7 nid8\n") listOfIds = [tag.GetIds()[j:j+8] for j in range(0, len(tag.GetIds()), 8)] for line in listOfIds: node_line = "" if useOriginalId: for n in range(len(line)): node_line += str(meshObject.originalIDNodes[line[n]]).rjust(10) else: for ind in line: node_line += str(ind+1).rjust(10) self.writeText(node_line + "\n") #Elements from BasicTools.Containers import Filters as F from BasicTools.Containers import FiltersTools as FT for name, data in meshObject.elements.items(): listOfElFilters = [] tags = [tag for tag in data.tags if tag.name[:10] == "canonical:"] for tag in tags: filter = F.ElementFilter(meshObject, elementType=name) filter.AddTag(tag.name) listOfElFilters.append(filter) assert FT.VerifyExclusiveFilters(listOfElFilters, meshObject) == True, "more than 1 canonical tag defined in elementType "+name self.writeText("*ELEMENT_SOLID\n") elementHeader = "$# eid pid" try: BTtoDynaConv = BasicToolToLSDyna[name] except KeyError: raise("Element "+name+" not compatible with writer") for i in range(len(BTtoDynaConv)): elementHeader += " n"+str(i+1) self.writeText(elementHeader + "\n") for i, conn in enumerate(data.connectivity): if useOriginalId: elem_line = str(data.originalIds[i]).rjust(8) else: elem_line = str(i+1).rjust(8) tagName = None for tag in tags: if i in tag.GetIds(): tagName = tag.name[10:] if tagName == None: tagName = str(1) elem_line += tagName.rjust(8) indices = conn[BTtoDynaConv] if useOriginalId: indices = meshObject.originalIDNodes[indices] else: indices += 1 for ind in indices: elem_line += str(ind).rjust(8) self.writeText(elem_line+"\n") #Nodes numberofpoints = meshObject.GetNumberOfNodes() posn = meshObject.GetPosOfNodes() self.writeText("*NODE\n") self.writeText("$# nid x y z tc rc\n") for n in range(numberofpoints): node_line = "" if useOriginalId: node_line += str(meshObject.originalIDNodes[n]).rjust(8) else: node_line += str(n+1).rjust(8) for pos in posn[n]: node_line += str(round(pos, 10)).rjust(16) # rc tc always 0 node_line += str(0).rjust(8) + str(0).rjust(8) + "\n" self.writeText(node_line) self.writeText("*END")
from BasicTools.IO.IOFactory import RegisterWriterClass RegisterWriterClass(".k",KWriter)
[docs]def CheckIntegrity(): import BasicTools.Containers.UnstructuredMesh as UM from BasicTools.Helpers.Tests import TestTempDir tempdir = TestTempDir.GetTempPath() mymesh = UM.UnstructuredMesh() mymesh.nodes = np.array([[0.1,0,0], [1,0,0], [0,1,0], [1,1,0], [0.5,0,0.1], [0,0.5,0.1], [0.5,0.5,0.1], ],dtype=PBasicFloatType) mymesh.originalIDNodes = np.array([1, 3, 4, 5, 6, 7, 8],dtype=PBasicIndexType) tet = mymesh.GetElementsOfType(EN.Tetrahedron_4) tet.AddNewElement([0,1,2,3],0) tet.AddNewElement([1,2,3,4],1) tet.AddNewElement([2,3,4,5],3) mymesh.AddNodeToTagUsingOriginalId(1,"NodeTest") mymesh.AddNodeToTagUsingOriginalId(3,"NodeTest") mymesh.AddNodeToTagUsingOriginalId(8,"NodeTest") mymesh.AddElementToTagUsingOriginalId(0,"canonical:4") mymesh.AddElementToTagUsingOriginalId(3,"canonical:6") KW = KWriter() KW.Open(tempdir+"Test_LSDynaWriter.k") KW.Write(mymesh) KW.Close() res = open(tempdir+"Test_LSDynaWriter.k").read() ref = """$# LS-DYNA Keyword file *KEYWORD *TITLE Test_LSDynaWriter.k *SET_NODE_LIST $# sid 1 $# nid1 nid2 nid3 nid4 nid5 nid6 nid7 nid8 1 2 7 *ELEMENT_SOLID $# eid pid n1 n2 n3 n4 n5 n6 n7 n8 1 4 1 2 3 4 4 4 4 4 2 1 2 3 4 5 5 5 5 5 3 6 3 4 5 6 6 6 6 6 *NODE $# nid x y z tc rc 1 0.1 0.0 0.0 0 0 2 1.0 0.0 0.0 0 0 3 0.0 1.0 0.0 0 0 4 1.0 1.0 0.0 0 0 5 0.5 0.0 0.1 0 0 6 0.0 0.5 0.1 0 0 7 0.5 0.5 0.1 0 0 *END""" assert(res == ref) ref = """$# LS-DYNA Keyword file *KEYWORD *TITLE Test_LSDynaWriter2.k *SET_NODE_LIST $# sid 1 $# nid1 nid2 nid3 nid4 nid5 nid6 nid7 nid8 1 3 8 *ELEMENT_SOLID $# eid pid n1 n2 n3 n4 n5 n6 n7 n8 0 4 1 3 4 5 5 5 5 5 1 1 3 4 5 6 6 6 6 6 3 6 4 5 6 7 7 7 7 7 *NODE $# nid x y z tc rc 1 0.1 0.0 0.0 0 0 3 1.0 0.0 0.0 0 0 4 0.0 1.0 0.0 0 0 5 1.0 1.0 0.0 0 0 6 0.5 0.0 0.1 0 0 7 0.0 0.5 0.1 0 0 8 0.5 0.5 0.1 0 0 *END""" WriteMeshToK(tempdir+"Test_LSDynaWriter2.k", mymesh, useOriginalId = True) res = open(tempdir+"Test_LSDynaWriter2.k").read() assert(res == ref) return "ok"
if __name__ == '__main__': print(CheckIntegrity())# pragma: no cover