Source code for Muscat.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
"""

from Muscat.IO.IOFactory import RegisterWriterClass
import numpy as np

from Muscat.IO.WriterBase import WriterBase as WriterBase
import Muscat.Containers.ElementsDescription as ED
from Muscat.Types import MuscatIndex
from Muscat.Types import MuscatFloat
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 : Mesh 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[ED.Tetrahedron_4] = [0, 1, 2, 3, 3, 3, 3, 3]
[docs]class KWriter(WriterBase): """Class to write an LSDyna file""" def __init__(self): super().__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 Muscat.Containers.Filters.FilterObjects import ElementFilter from Muscat.Containers.Filters.FilterTools import VerifyExclusiveFilters 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 = ElementFilter(elementType=name) filter.AddETag(tag.name) listOfElFilters.append(filter) assert 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: # pragma: no cover 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("*ED.")
RegisterWriterClass(".k", KWriter)
[docs]def CheckIntegrity(): import Muscat.Containers.Mesh as UM from Muscat.Helpers.IO.TemporaryDirectory import TemporaryDirectory tempdir = TemporaryDirectory.GetTempPath() mymesh = UM.Mesh() 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=MuscatFloat, ) mymesh.originalIDNodes = np.array([1, 3, 4, 5, 6, 7, 8], dtype=MuscatIndex) tet = mymesh.GetElementsOfType(ED.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() print(KW) 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 *ED.""" 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 *ED.""" 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