Source code for BasicTools.IO.GeofWriter

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

"""Geof file writer (Zset mesh files)
"""
from typing import Optional

import numpy as np

import BasicTools.Containers.ElementNames as EN

from BasicTools.IO.WriterBase import WriterBase
from BasicTools.NumpyDefs import  PBasicFloatType, PBasicIndexType
from BasicTools.Containers.UnstructuredMesh import UnstructuredMesh
from BasicTools.IO.GeofReader import PermutationZSetToBasicTools
PermutationBasicToolsToZSet = {key:np.argsort(value) for key, value in PermutationZSetToBasicTools.items() }

GeofName = {}
GeofSetName= {}

#0d
GeofName[EN.Point_1] = "l2d1"

#1d
GeofName[EN.Bar_2] = "l2d2"
GeofSetName[EN.Bar_2] = "line"
GeofSetName[EN.Bar_3] = "quad"

#2d
GeofName[EN.Triangle_3] = "c2d3"
GeofSetName[EN.Triangle_3] = "t3"

GeofName[EN.Triangle_6] = "c2d6"
GeofSetName[EN.Triangle_6] = "t6"
GeofSetName[EN.Quadrangle_4] = "q4"

GeofName[EN.Quadrangle_8] = "c3d8"
GeofSetName[EN.Quadrangle_8] = "q8"

#3d
GeofName[EN.Tetrahedron_4] = "c3d4"
GeofName[EN.Tetrahedron_10] = "c3d10"

GeofName[EN.Quadrangle_4] = "c2d4"
GeofName[EN.Hexaedron_8] = "c3d8"
GeofName[EN.Hexaedron_20] = "c3d20"

GeofName[EN.Wedge_6] = "c3d6"

[docs]def WriteMeshToGeof(fileName :str , mesh:UnstructuredMesh, useOriginalId:Optional[bool]=False,lowerDimElementsAsElsets:bool=False)-> None: """Function API for writing mesh in the geof format file. 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 useOriginalId : Optional[bool], optional use the Original Id for the number of nodes and elements (the user is responsible of the consistency of this data), by default False lowerDimElementsAsElsets : Optional[bool], optional refert to GeofWriter.SetWriteLowerDimElementsAsSets for the documentations """ geofWriter = GeofWriter() geofWriter.Open(fileName) geofWriter.SetWriteLowerDimElementsAsSets(lowerDimElementsAsElsets) geofWriter.Write(mesh,useOriginalId = useOriginalId) geofWriter.Close()
[docs]class GeofWriter(WriterBase): """Class to write Unstructured mesh on disk in the geof format file """ def __init__(self) -> None: super(GeofWriter,self).__init__() self.lowerDimElementsAsElsets= False self.canHandleBinaryChange = False def __str__(self): res = 'GeofWriter : \n' res += ' FileName : '+ str(self.fileName) +'\n' return res
[docs] def SetWriteLowerDimElementsAsSets(self,val:bool) -> None: """ Set the type of export for element of lower dimensionality (1D and 2D element on a 3D mesh) Parameters ---------- val : bool if True all the elements of lower dimensionality are exported in the mesh if False all the element of lower dimensionality are exported as bsets, by default False """ if val is not None: self.lowerDimElementsAsElsets= bool(val)
[docs] def Write(self,meshObject: UnstructuredMesh, useOriginalId:Optional[bool]=False, lowerDimElementsAsElsets:bool=False, PointFieldsNames=None, PointFields=None, CellFieldsNames=None, CellFields=None): """Write mesh to file in Geof format Parameters ---------- meshObject : UnstructuredMesh the mesh to be written useOriginalId : Optional[bool], optional use the Original Id for the number of nodes and elements (the user is responsible of the consistency of this data), by default False lowerDimElementsAsElsets : Optional[bool], optional refert to GeofWriter.SetWriteLowerDimElementsAsSets for the documentations 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 Raises ------ Exception in the case 1D element are presents in the mesh (doset) """ if PointFieldsNames is not None or PointFields is not None or \ CellFieldsNames is not None or CellFields is not None: print("warning GeofWriter only can write the mesh, fields are ignored") self.SetWriteLowerDimElementsAsSets(lowerDimElementsAsElsets) meshObject.PrepareForOutput() self.filePointer.write("% Written by BasicTools package\n") self.filePointer.write("***geometry\n") self.filePointer.write(" **node\n") numberOfPoints = meshObject.GetNumberOfNodes() self.filePointer.write(f"{numberOfPoints} {meshObject.GetDimensionality()} \n" ) # posn = meshObject.GetPosOfNodes() if useOriginalId: for n in range(numberOfPoints): self.filePointer.write(f"{int(meshObject.originalIDNodes[n])} ") posn[n,:].tofile(self.filePointer, sep=" ") self.filePointer.write("\n") else: for n in range(numberOfPoints): self.filePointer.write(f"{n+1} ") posn[np.newaxis,n,:].tofile(self.filePointer, sep=" ") self.filePointer.write("\n") # nbElements = 0 maxDimensionalityOfElements = 0 for ntype,elems in meshObject.elements.items(): maxDimensionalityOfElements = max(EN.dimension[ntype],maxDimensionalityOfElements) for ntype,elems in meshObject.elements.items(): if EN.dimension[ntype] == maxDimensionalityOfElements or self.lowerDimElementsAsElsets is True: nbElements += elems.GetNumberOfElements() self.filePointer.write(" **element\n") self.filePointer.write(f"{nbElements}\n") cpt =0 for ntype, data in meshObject.elements.items(): elemtype = GeofName[ntype] if EN.dimension[ntype] != maxDimensionalityOfElements and self.lowerDimElementsAsElsets is False: continue #npe = data.GetNumberOfNodesPerElement() #if elemtype!="c2d3": for i in range(data.GetNumberOfElements() ): conn = data.connectivity[i,:].ravel() if elemtype in PermutationBasicToolsToZSet: conn = [conn[x] for x in PermutationBasicToolsToZSet[elemtype]] if useOriginalId: self.filePointer.write(f"{data.originalIds[i]} {elemtype} " ) self.filePointer.write(" ".join([str(int(meshObject.originalIDNodes[x])) for x in conn])) else: self.filePointer.write(f"{cpt+1} {elemtype} ") self.filePointer.write(" ".join([str(x+1) for x in conn])) cpt += 1 self.filePointer.write("\n") self.filePointer.write(" ***group \n") for tag in meshObject.nodesTags: if len(tag) == 0: continue self.filePointer.write(f" **nset {tag.name} \n") data = np.zeros((meshObject.GetNumberOfNodes(),1),dtype=PBasicIndexType) if useOriginalId: self.filePointer.write(" ".join([str(int(meshObject.originalIDNodes[x])) for x in tag.GetIds()])) else: self.filePointer.write(" ".join([str(x+1) for x in tag.GetIds()])) self.filePointer.write("\n") meshObject.PrepareForOutput() if self.lowerDimElementsAsElsets is False : celtags = meshObject.GetNamesOfElemTags() for tagname in celtags: idInTag = 0 flag = False for ntype,elems in meshObject.elements.items(): if EN.dimension[ntype] == maxDimensionalityOfElements: if tagname in elems.tags: flag = True idInTag += elems.tags[tagname].cpt self.PrintVerbose(f"Tag {tagname} has {idInTag} elements") # no output if no elements in tag if flag is False : continue #empty tags if idInTag == 0 : continue self.filePointer.write(f" **elset {tagname} \n") cpt =0 for ntype,elems in meshObject.elements.items(): if EN.dimension[ntype] != maxDimensionalityOfElements: continue if tagname in elems.tags: tag = elems.tags[tagname] if tag.cpt : if useOriginalId: self.filePointer.write(" ".join([str(elems.originalIds[x]) for x in tag.GetIds()])) else: self.filePointer.write(" ".join([str(x+1+cpt) for x in tag.GetIds()])) self.filePointer.write(" ") cpt += elems.GetNumberOfElements() self.filePointer.write("\n") else: celtags = meshObject.GetNamesOfElemTags() for tagname in celtags: self.filePointer.write(f" **elset {tagname} \n") data = meshObject.GetElementsInTag(tagname,useOriginalId=useOriginalId) if useOriginalId : self.filePointer.write(" ".join([str(x) for x in data])) self.filePointer.write(" ") else: self.filePointer.write(" ".join([str(x+1) for x in data])) self.filePointer.write(" ") self.filePointer.write("\n") # Dotsets, lisets, facets if self.lowerDimElementsAsElsets is False: for dimToTreat in range(maxDimensionalityOfElements): celtags = meshObject.GetNamesOfElemTags() for tagname in celtags: idInTag = 0 flag = False for ntype,elems in meshObject.elements.items(): if EN.dimension[ntype] == dimToTreat: if tagname in elems.tags: flag = True idInTag += elems.tags[tagname].cpt self.PrintVerbose("Set " + str(tagname) + " has "+ str(idInTag) + " elements") # no output if no elements in tag if flag is False : continue #empty tags if idInTag == 0 : continue if dimToTreat == 0:# pragma: no cover raise Exception("Don't know how to treat the doset, please code me") # self.filePointer.write(" **doset {} \n".format(tagname)) elif dimToTreat == 1: self.filePointer.write(f" **liset {tagname} \n") elif dimToTreat == 2: self.filePointer.write(f" **faset {tagname} \n") for ntype,elems in meshObject.elements.items(): if EN.dimension[ntype] != dimToTreat: continue if tagname in elems.tags: tag = elems.tags[tagname] name = GeofSetName[ntype] ids = tag.GetIds() for e in range(len(tag)): conn = elems.connectivity[ids[e],:] if name in PermutationBasicToolsToZSet: conn = [conn[x] for x in PermutationBasicToolsToZSet[name]] self.filePointer.write(f" {name} ") self.filePointer.write(" ".join([str(x+1) for x in conn ])) self.filePointer.write(" \n") self.filePointer.write("***return \n")
from BasicTools.IO.IOFactory import RegisterWriterClass RegisterWriterClass(".geof",GeofWriter)
[docs]def CheckIntegrity(): import BasicTools.Containers.UnstructuredMesh as UM from BasicTools.Helpers.Tests import TestTempDir tempdir = TestTempDir.GetTempPath() print(tempdir) mymesh = UM.UnstructuredMesh() mymesh.nodes = np.array([[0.00000000001,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) mymesh.nodesTags.CreateTag("coucou").AddToTag(0) mymesh.nodesTags.CreateTag("empty tag") tet = mymesh.GetElementsOfType(EN.Tetrahedron_4) tet.AddNewElement([0,1,2,3],0) tet.tags.CreateTag("TheOnlyTet").AddToTag(0) triangles = mymesh.GetElementsOfType(EN.Triangle_3) triangles.AddNewElement([0,1,2],0) triangles.AddNewElement([2,1,3],3) triangles.originalIds = np.array([3, 5],dtype=PBasicIndexType) bars = mymesh.GetElementsOfType(EN.Bar_2) bars.AddNewElement([0,1],0) bars.AddNewElement([1,3],1) bars.tags.CreateTag("firstBar").AddToTag(0) bars3 = mymesh.GetElementsOfType(EN.Triangle_6) bars3.AddNewElement([0,1,2,4,6,5],0) bars3.tags.CreateTag("Tri6").AddToTag(0) #point = mymesh.GetElementsOfType(EN.Point_1) #point.AddNewElement([0],0) #point.tags.CreateTag("onlyPoint").AddToTag(0) mymesh.AddElementToTagUsingOriginalId(3,"Tag1") mymesh.AddElementToTagUsingOriginalId(5,"Tag3") geofWriter = GeofWriter() print(geofWriter) geofWriter.Open(tempdir+"Test_GeoWriter.geof") geofWriter.Write(mymesh, useOriginalId=True, PointFieldsNames=[], PointFields=[]) geofWriter.Close() WriteMeshToGeof(tempdir+"Test_GeoWriter_II.geof", mymesh,useOriginalId=False ) WriteMeshToGeof(tempdir+"Test_GeoWriter_III.geof", mymesh,useOriginalId=False,lowerDimElementsAsElsets=True ) WriteMeshToGeof(tempdir+"Test_GeoWriter_III.geof", mymesh,useOriginalId=True,lowerDimElementsAsElsets=True ) return "ok"
if __name__ == '__main__': print(CheckIntegrity())# pragma: no cover