import Muscat.Containers.ElementsDescription as ED
from Muscat.IO.WriterBase import WriterBase
from Muscat.IO.IOFactory import RegisterWriterClass
[docs]
def WriteMeshToRadioss(filename, mesh, shellObjects=True):
"""Function API for writing data into a radioss include (.inc) file
Parameters
----------
fileName : str
name of the file to be written
mesh : Mesh
the mesh to be written
shellObject : bool, optional
If True, triangles and quandrangles are casted to thin plate elements, by default True
"""
RW = RadiossWriter()
RW.Open(filename)
RW.Write(mesh, shellObjects=shellObjects)
RW.Close()
[docs]
class RadiossWriter(WriterBase):
def __init__(self):
"""RadiossWriter
Writer copied from the GMSH radioss writer for a mesh
Implemented for P1 Triangles, Quadrangles, Tetrahedrons, Hexahedrons
"""
super().__init__()
def __str__(self):
return f"RadiossWriter : \n FileName : {str(self.fileName)}"
[docs]
def Write(self, meshObject,shellObjects=True):
MuscatToRadiossDict = {}
if shellObjects:
# If we want shell elements in the radioss include file (GMSH default behavior)
MuscatToRadiossDict[ED.Triangle_3] = "SH3N"
MuscatToRadiossDict[ED.Quadrangle_4] = "SHELL"
else:
# If we want 2D elements
MuscatToRadiossDict[ED.Triangle_3] = "TRIA"
MuscatToRadiossDict[ED.Quadrangle_4] = "QUAD"
MuscatToRadiossDict[ED.Tetrahedron_4] = "TETRA4"
MuscatToRadiossDict[ED.Hexahedron_8] = "BRICK"
marker_bar = "#---1----|----2----|----3----|----4----|----5----|----6----|----7----|----8----|----9----|---10----|"
file_lines = []
## File Header
file_lines.extend(["#RADIOSS STARTER",
marker_bar,
"# Created by Muscat",
marker_bar,
"/BEGIN"])
file_lines.append(str(self.fileName))
## Writing units and version of Radioss
file_lines.extend([" 2022 0",
" Mg mm s",
" Mg mm s",
marker_bar])
## Writing Nodes
file_lines.extend(["#- 1. NODES:",
marker_bar,
"/NODE"])
nodes = meshObject.nodes
# For each node:
for i in range(meshObject.GetNumberOfNodes()):
index_node= i + 1 # Reindexing from 1
x_coord,y_coord = nodes[i,0],nodes[i,1]
# If mesh is 2D z_coord = 0
z_coord = nodes[i,2] if nodes.shape[1]==3 else 0.
# Writing node
file_lines.append(f"{index_node:10} {x_coord:10.5} {y_coord:10.5} {z_coord:10.5}")
# Writing Elements
element_index = 1
part_index = 2000001 # Default Value taken from GMSH
## Looping on element types
for name, data in meshObject.elements.items():
# If the element is within the element that we can translate
if name in MuscatToRadiossDict:
title = MuscatToRadiossDict[name]
# Beginning part definition
file_lines.extend([marker_bar,
f"# {title} elements of /PART/{part_index}/{title}:",
marker_bar,
f"/{title}/{part_index}"])
# Getting the node of all elements
conn = data.connectivity
# Looping on all elements from 1 type
for elemIndex in range(conn.shape[0]):
connectivityElem = conn[elemIndex]
# indexing line
element_line = f"{element_index:10}"
# adding nodes (with reindexing of the nodes from 1)
element_line += ''.join([f"{(node+1):10}" for node in connectivityElem])
file_lines.append(element_line)
element_index+=1
part_index+=1
# End of file
file_lines.extend([marker_bar,
"#enddata",
"/END",
marker_bar,
])
self.writeText("\n".join(file_lines))
RegisterWriterClass(".inc", RadiossWriter)
[docs]
def CheckIntegrity(GUI: bool = False):
from Muscat.Containers.ConstantRectilinearMeshTools import CreateConstantRectilinearMesh
from Muscat.Containers.MeshTetrahedrization import Tetrahedrization
from Muscat.Helpers.IO.TemporaryDirectory import TemporaryDirectory
from pathlib import Path
tempdir = Path(TemporaryDirectory.GetTempPath())
size=10
mesh = CreateConstantRectilinearMesh([size+1,size+1], [0,0], [1/size, 1/size])
WriteMeshToRadioss(tempdir / "Test_Radioss_shell.inc", mesh, shellObjects=True)
WriteMeshToRadioss(tempdir / "Test_Radioss_thin.inc", mesh, shellObjects=False)
mesh = Tetrahedrization(mesh)
WriteMeshToRadioss(tempdir / "Test_Radioss_shell.inc", mesh, shellObjects=True)
WriteMeshToRadioss(tempdir / "Test_Radioss_thin.inc", mesh, shellObjects=False)
return "ok"
if __name__ == "__main__":
print(CheckIntegrity()) # pragma: no cover