Source code for Muscat.IO.AnsysWriter

# -*- 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.
#

"""Ansys CDB format writer
"""
from typing import Optional, List
from io import TextIOWrapper


import numpy as np

from Muscat.Types import MuscatIndex
import Muscat.Containers.ElementsDescription as ED
from Muscat.Containers.Mesh import Mesh
from Muscat.Containers.Filters.FilterObjects import ElementFilter
from Muscat.IO.WriterBase import WriterBase


[docs]def WriteMeshToCDB(fileName: str, mesh: Mesh) -> None: """Function API for writing mesh in the CDB format file (Ansys). A file is created using the path and name of fileName Parameters ---------- fileName : str name with path to the file to be created (relative or absolute) mesh : UnstructuredMesh the mesh to be exported """ anWriter = AnsysWriter() anWriter.Open(fileName) anWriter.Write(mesh) anWriter.Close()
[docs]def ExportElementTagsInCDBFormat(mesh: Mesh, tagnames: List[str], filename: Optional[str]=None, filePointer: Optional[TextIOWrapper] =None): """Function to export multiple elements tags to Ansys CDB format Parameters ---------- mesh : Mesh mesh from which elements ids for each tag are searched tagnames : list[str] list of element tags filename : str, optional filename in CDB format where the element ids for each tag are exported, by default None """ ft = False for tname in tagnames: ExportElementTagInCDBFormat(mesh, tname, filename=filename, append=ft, filePointer=filePointer) ft = True
[docs]def ExportElementTagInCDBFormat(mesh: Mesh, tagname: str, filename:Optional[str]=None, append: bool =False, filePointer: Optional[TextIOWrapper]=None): """ Functions to export one element tag as Ansys CDB format. It uses the originals ids Parameters ---------- mesh : Mesh mesh from which elements ids for each tag are searched tagname : str element tag filename : str, optional filename in CDB format where the element ids for the provided tag are exported, by default None append : str, optional selects if the info is appended to the file (a+) or overwritten (w or False), by default False """ lglobal: List[MuscatIndex] = [] ef = ElementFilter(eTag=tagname) for selection in ef(mesh): lglobal.extend(selection.meshOffset + selection.indices) NB_ELEM_DANS_GROUPE = len(lglobal) if NB_ELEM_DANS_GROUPE == 0: # pragma: no cover print(f"Empty tag {tagname}") return if filePointer is None: if filename is None: filename = tagname + ".cdb" if append: mode = "a+" else: mode = "w" fh = open(filename, mode) else: fh = filePointer fh.write("CMBLOCK,{NOM_GROUPE},ELEM,{NB_ELEM_DANS_GROUPE}\n".format(NOM_GROUPE=tagname, NB_ELEM_DANS_GROUPE=NB_ELEM_DANS_GROUPE)) fh.write("(8i10)\n") l = np.asarray(lglobal) stop = 0 for cpt in range(len(l)//8): start = cpt*8 stop = (cpt+1)*8 if stop >= len(l): stop = len(l)-1 np.savetxt(fh, l[start:stop][np.newaxis], fmt="%10i", delimiter="") np.savetxt(fh, l[stop:][np.newaxis], fmt="%10i", delimiter="") if filePointer is None: fh.close()
[docs]class AnsysWriter(WriterBase): """Ansys CDB format writer attributes ---------- AnsysFormulation : ["SOLID3D","SOLID2D"] to export element with a specific physics read the file AnsysTools.py (variable MuscatToAnsysFormulation) for more details """ def __init__(self) -> None: super().__init__() self.canHandleBinaryChange = False self.AnsysFormulation = "SOLID3D"
[docs] def Write(self, mesh: Mesh): mesh.PrepareForOutput() self.filePointer.write("! ****** Written by Muscat package ******\n") self.filePointer.write("! ****** Please Disconnect 'Check Valid Blocked CDB File' ******\n") self.filePointer.write("! ****** Named selections must be read inside mechanical by reimporting the this cdb file' ******\n") dim = mesh.GetPointsDimensionality() numberOfPoints = mesh.GetNumberOfNodes() self.filePointer.write(f"nblock,{dim},,{numberOfPoints}\n") self.filePointer.write("(1i9,3e20.9e3)\n") posn = mesh.GetPosOfNodes() for n in range(numberOfPoints): self.filePointer.write(f"{n+1}".rjust(9)) for d in range(3): self.filePointer.write(f"{posn[n,d]:1.9E}".rjust(20)) self.filePointer.write("\n") self.filePointer.write("-1\n") for tag in mesh.nodesTags: if len(tag) == 0: continue self.filePointer.write(f"CMBLOCK,{tag.name},NODE,{len(tag)}\n") self.filePointer.write(f"(8i10)\n") tagcpt = 0 indices = tag.GetIds() while (tagcpt < len(tag)): icpt = 0 while (tagcpt < len(tag)): self.filePointer.write(f"{indices[tagcpt]}".rjust(9)) tagcpt += 1 self.filePointer.write(f"\n") exportMask = {} exportMask[ED.Hexahedron_8] = [0, 1, 2, 3, 4, 5, 6, 7] exportMask[ED.Wedge_6] = [0, 1, 2, 2, 3, 4, 2, 5] exportMask[ED.Tetrahedron_4] = [0, 1, 2, 2, 3, 3, 3, 3] exportMask[ED.Pyramid_5] = [0, 1, 2, 3, 4, 4, 5, 5] exportMask[ED.Triangle_3] = [0, 1, 2, 2] exportMask[ED.Quadrangle_4] = [0, 1, 2, 3] from Muscat.IO.AnsysTools import MuscatToAnsysFormulation elcpt = 1 elemTypeNumber = 0 for ntype, elems in mesh.elements.items(): elemTypeNumber += 1 numberOfElements = elems.GetNumberOfElements() numberOfNodesPerElement = elems.GetNumberOfNodesPerElement() self.filePointer.write(f"et,{elemTypeNumber},{MuscatToAnsysFormulation[self.AnsysFormulation].get(ntype,0)}\n") mask = exportMask[ntype] if ntype in MuscatToAnsysFormulation[self.AnsysFormulation]: Solkey = "solid" header1 = "1".rjust(9) # 1 The material number header1 += f"{elemTypeNumber}".rjust(9) # 2 The element type number header1 += "1".rjust(9) # 3 The real constant number header1 += "1".rjust(9) # 4 The real constant number header1 += "0".rjust(9) # 5 Element coordinate system number header1 += "0".rjust(9) # 6 the birth/death flag header1 += "0".rjust(9) # 7 the solid model reference number header1 += "0".rjust(9) # 8 the element shape flag header1 += f"{len(mask)}".rjust(9) # 9 number of nodes defining this element if SOLID, otherwise 0 header1 += "0".rjust(9) # 10 Not used (p-elements) header2 = "" else: header1 = "" Solkey = "" header2 = "0".rjust(9) # 2 The type of section ID. header2 += "1".rjust(9) # 3 The real constant number header2 += "1".rjust(9) # 4 The material number header2 += "0".rjust(9) # 5 Element coordinate system number self.filePointer.write(f"eblock,19,{Solkey},,{numberOfElements}\n") self.filePointer.write(f"(19i9)\n") originalelcpt = elcpt for n in range(numberOfElements): self.filePointer.write(header1) # 1 The material number self.filePointer.write(f"{elcpt}".rjust(9)) # 11 the element number self.filePointer.write(header2) # 1 The material number elcpt += 1 if numberOfNodesPerElement <= 8: for i in mask: self.filePointer.write(f"{elems.connectivity[n,i]+1}".rjust(9)) # 12-18 the element number self.filePointer.write("\n") else: for i in range(8): self.filePointer.write(f"{elems.connectivity[n,i]+1}".rjust(9)) # 12-18 the element number self.filePointer.write("\n") for i in range(8, numberOfNodesPerElement): self.filePointer.write(f"{elems.connectivity[n,i]+1}".rjust(9)) # 12-18 the element number self.filePointer.write("\n") self.filePointer.write("-1\n") for tag in elems.tags: if len(tag) == 0: continue self.filePointer.write(f"CMBLOCK,{tag.name},ELEMENT,{len(tag)}\n") self.filePointer.write(f"(8i10)\n") tagcpt = 0 indices = tag.GetIds()+originalelcpt while (tagcpt < len(tag)): icpt = 0 while (tagcpt < len(tag)): self.filePointer.write(f"{indices[tagcpt]}".rjust(9)) tagcpt += 1 self.filePointer.write(f"\n")
# ExportElementTagsInCDBFormat(mesh, mesh.elements.GetTagsNames(), filePointer=self.filePointer)
[docs]def CheckIntegrity(GUI: bool = False) -> str: from Muscat.Containers.MeshCreationTools import CreateCube mesh = CreateCube(dimensions=[3, 2, 2], ofTetras=True) # from Muscat.IO.GmshReader import ReadGmsh # from Muscat.TestData import GetTestDataPath # from Muscat.Containers.MeshInspectionTools import ExtractElementsByElementFilter # from Muscat.Containers.Filters.FilterObjects import ElementFilter # mesh = ReadGmsh(GetTestDataPath() + "dent3D.msh") # mesh = ExtractElementsByElementFilter(mesh, ElementFilter(dimensionality=[3,2]) ) mesh.GenerateManufacturedOriginalIDs() from Muscat.Helpers.IO.TemporaryDirectory import TemporaryDirectory tempdir = TemporaryDirectory.GetTempPath() ExportElementTagsInCDBFormat(mesh, mesh.elements.GetTagsNames(), filename=tempdir+"/AnsysWriterCheckIntegrity_AnsysWriter.cdb") WriteMeshToCDB(tempdir+"/AnsysWriterCheckIntegrity_mesh.cdb", mesh) return "ok"
if __name__ == '__main__': print(CheckIntegrity(True)) # pragma: no cover