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